Android 6.0 PowerManagerService 之 Display
2016-12-07 16:38
267 查看
继续updatePowerStateLocked函数
systemReady
首先先看systemReady函数中与display相关的,
在DisplayManagerService中有一个内部LocalService类,而在PMS的systemReady方法中的mDisplayManagerInternal 也正是这个内部类LocalService,其将mDisplayPowerCallbacks、mHandler、SensorManager传给了DisplayPowerController
DisplayManagerService.java文件中的内部类LocalService
在上一篇PMS的博客我们,我们分析到updateDisplayPowerStateLocked函数mDisplayManagerInternal.requestPowerState,这里requestPowerState就调用了上面的方法,最后调用了DisplayPowerController里的requestPowerState方法
updateDisplayPowerStateLocked
DisplayPowerController构造函数
发送消息,那么requestPowerState就直接返回mDisplayReadyLocked了。也就是说PMS第一次调用mDisplayManagerInternal.requestPowerState,mDisplayReady 肯定为false
PMS updateDisplayPowerStateLocked 函数中
处理MSG_UPDATE_POWER_STATE消息
updatePowerState
先看这个mCallbacks,是PMS传进来的回调 systemReady
继续分析,根据传进来的mPowerRequest.policy不同,走不同的case
看看PMS这个mPowerRequest.policy值,在updateDisplayPowerStateLocked函数中
getDesiredScreenPolicyLocked
setScreenState
再看看 setScreenState
再看看sendOnStateChangedWithWakelock函数
sendOnStateChangedWithWakelock
而PMS里的mDisplayPowerCallbacks 的onStateChanged如下
会重新调用到PMS的updateDisplayPowerStateLocked函数,再调用下面。
由于changed没有变化,最后返回true
然后 DisplayManagerService.java 文件的localService
继续分析updatePowerStateLocked
先看updateDreamLocked函数,mDisplayReady为false,所以跳出
再看 updateSuspendBlockerLocked函数
needDisplaySuspendBlockerLocked函数mDisplayReady为false,直接返回true
这样PMS刚调mDisplayManagerInternal.requestPowerState的时候,返回mDisplayReady为false,最后也就会持Display的锁,
直到Display准备好,回调函数直接又调用updatePowerStateLocked函数,再调用updateDisplayPowerStateLocked函数,返回mDisplayReady为true。
那我们继续分析updatePowerStateLocked函数
updateDreamLocked函数发送消息,消息最后处理的函数是handleSandman,goToSleepNoUpdateLocked和napNoUpdateLocked函数才会把mSandmanSummoned = true
继续分析PMS中的updatePowerStateLocked函数
Display完成后,屏幕在灭屏之前通知PhoneWindowManager,电池统计等。updateSuspendBlockerLocked函数持有一个锁,和调JNI设置cpu频率,还有一个autoSuspend是自动让系统睡眠,如果开启就设true。
// Phase 2: Update display power state. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//第一次返回false
systemReady
首先先看systemReady函数中与display相关的,mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); ....... // Initialize display power management. mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager);
在DisplayManagerService中有一个内部LocalService类,而在PMS的systemReady方法中的mDisplayManagerInternal 也正是这个内部类LocalService,其将mDisplayPowerCallbacks、mHandler、SensorManager传给了DisplayPowerController
DisplayManagerService.java文件中的内部类LocalService
private final class LocalService extends DisplayManagerInternal { @Override public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager) { synchronized (mSyncRoot) { DisplayBlanker blanker = new DisplayBlanker() { @Override public void requestDisplayState(int state, int brightness) { // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); } callbacks.onDisplayStateChange(state); if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state, brightness); } } }; mDisplayPowerController = new DisplayPowerController( mContext, callbacks, handler, sensorManager, blanker); } } @Override public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity); } @Override public boolean isProximitySensorAvailable() { return mDisplayPowerController.isProximitySensorAvailable(); } @Override public DisplayInfo getDisplayInfo(int displayId) { return getDisplayInfoInternal(displayId, Process.myUid()); } @Override public void registerDisplayTransactionListener(DisplayTransactionListener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } registerDisplayTransactionListenerInternal(listener); } @Override public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); } unregisterDisplayTransactionListenerInternal(listener); } @Override public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); } @Override public void performTraversalInTransactionFromWindowManager() { performTraversalInTransactionFromWindowManagerInternal(); } @Override public void setDisplayProperties(int displayId, boolean hasContent, float requestedRefreshRate, int requestedMode, boolean inTraversal) { setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, requestedMode, inTraversal); } @Override public void setDisplayOffsets(int displayId, int x, int y) { setDisplayOffsetsInternal(displayId, x, y); } }
在上一篇PMS的博客我们,我们分析到updateDisplayPowerStateLocked函数mDisplayManagerInternal.requestPowerState,这里requestPowerState就调用了上面的方法,最后调用了DisplayPowerController里的requestPowerState方法
updateDisplayPowerStateLocked
/** * Updates the display power state asynchronously. * When the update is finished, mDisplayReady will be set to true. The display * controller posts a message to tell us when the actual display power state * has been updated so we come back here to double-check and finish up. * * This function recalculates the display power state each time. * * @return True if the display became ready. */ private boolean updateDisplayPowerStateLocked(int dirty) { final boolean oldDisplayReady = mDisplayReady; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) { mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(); // Determine appropriate screen brightness and auto-brightness adjustments. boolean brightnessSetByUser = true; int screenBrightness = mScreenBrightnessSettingDefault; float screenAutoBrightnessAdjustment = 0.0f; boolean autoBrightness = (mScreenBrightnessModeSetting == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) { screenBrightness = mScreenBrightnessOverrideFromWindowManager; autoBrightness = false; brightnessSetByUser = false; } else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) { screenBrightness = mTemporaryScreenBrightnessSettingOverride; } else if (isValidBrightness(mScreenBrightnessSetting)) { screenBrightness = mScreenBrightnessSetting; } if (autoBrightness) { screenBrightness = mScreenBrightnessSettingDefault; if (isValidAutoBrightnessAdjustment( mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) { screenAutoBrightnessAdjustment = mTemporaryScreenAutoBrightnessAdjustmentSettingOverride; } else if (isValidAutoBrightnessAdjustment( mScreenAutoBrightnessAdjustmentSetting)) { screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting; } } screenBrightness = Math.max(Math.min(screenBrightness, mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum); screenAutoBrightnessAdjustment = Math.max(Math.min( screenAutoBrightnessAdjustment, 1.0f), -1.0f); // Update display power request. mDisplayPowerRequest.screenBrightness = screenBrightness; mDisplayPowerRequest.screenAutoBrightnessAdjustment = screenAutoBrightnessAdjustment; mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress; if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND && (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) { mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE; } mDisplayPowerRequest.dozeScreenBrightness = mDozeScreenBrightnessOverrideFromDreamManager; } else { mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); mRequestWaitForNegativeProximity = false; if (DEBUG_SPEW) { Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady + ", policy=" + mDisplayPowerRequest.policy + ", mWakefulness=" + mWakefulness + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary) + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary) + ", mBootCompleted=" + mBootCompleted + ", mScreenBrightnessBoostInProgress=" + mScreenBrightnessBoostInProgress); } } return mDisplayReady && !oldDisplayReady; }
DisplayPowerController.java
DisplayPowerController构造函数
/** * Creates the display power controller. */ public DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker) { mHandler = new DisplayControllerHandler(handler.getLooper()); mCallbacks = callbacks; mBatteryStats = BatteryStatsService.getService(); mSensorManager = sensorManager; mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); mBlanker = blanker; mContext = context; final Resources resources = context.getResources(); final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger( com.android.internal.R.integer.config_screenBrightnessSettingMinimum)); mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger( com.android.internal.R.integer.config_screenBrightnessDoze)); mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger( com.android.internal.R.integer.config_screenBrightnessDim)); mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger( com.android.internal.R.integer.config_screenBrightnessDark)); if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) { Slog.w(TAG, "Expected config_screenBrightnessDark (" + mScreenBrightnessDarkConfig + ") to be less than or equal to " + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ")."); } if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) { Slog.w(TAG, "Expected config_screenBrightnessDark (" + mScreenBrightnessDarkConfig + ") to be less than or equal to " + "config_screenBrightnessSettingMinimum (" + screenBrightnessSettingMinimum + ")."); } int screenBrightnessRangeMinimum = Math.min(Math.min( screenBrightnessSettingMinimum, mScreenBrightnessDimConfig), mScreenBrightnessDarkConfig); mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON; mUseSoftwareAutoBrightnessConfig = resources.getBoolean( com.android.internal.R.bool.config_automatic_brightness_available); mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean( com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing); int lightSensorRate = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessLightSensorRate); long brighteningLightDebounce = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce); long darkeningLightDebounce = resources.getInteger( com.android.internal.R.integer.config_autoBrightnessDarkeningLightDebounce); boolean autoBrightnessResetAmbientLuxAfterWarmUp = resources.getBoolean( com.android.internal.R.bool.config_autoBrightnessResetAmbientLuxAfterWarmUp); if (mUseSoftwareAutoBrightnessConfig) { int[] lux = resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevels); int[] screenBrightness = resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLcdBacklightValues); int lightSensorWarmUpTimeConfig = resources.getInteger( com.android.internal.R.integer.config_lightSensorWarmupTime); final float dozeScaleFactor = resources.getFraction( com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor, 1, 1); Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness); if (screenAutoBrightnessSpline == null) { Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues " + "(size " + screenBrightness.length + ") " + "must be monotic and have exactly one more entry than " + "config_autoBrightnessLevels (size " + lux.length + ") " + "which must be strictly increasing. " + "Auto-brightness will be disabled."); mUseSoftwareAutoBrightnessConfig = false; } else { int bottom = clampAbsoluteBrightness(screenBrightness[0]); if (mScreenBrightnessDarkConfig > bottom) { Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig + ") should be less than or equal to the first value of " + "config_autoBrightnessLcdBacklightValues (" + bottom + ")."); } if (bottom < screenBrightnessRangeMinimum) { screenBrightnessRangeMinimum = bottom; } mAutomaticBrightnessController = new AutomaticBrightnessController(this, handler.getLooper(), sensorManager, screenAutoBrightnessSpline, lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum, dozeScaleFactor, lightSensorRate, brighteningLightDebounce, darkeningLightDebounce, autoBrightnessResetAmbientLuxAfterWarmUp); } } mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum; mColorFadeFadesConfig = resources.getBoolean( com.android.internal.R.bool.config_animateScreenLights); if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) { mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); if (mProximitySensor != null) { mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(), TYPICAL_PROXIMITY_THRESHOLD); } } }
requestPowerState
/** * Requests a new power state. * The controller makes a copy of the provided object and then * begins adjusting the power state to match what was requested. * * @param request The requested power state. * @param waitForNegativeProximity If true, issues a request to wait for * negative proximity before turning the screen back on, assuming the screen * was turned off by the proximity sensor. * @return True if display is ready, false if there are important changes that must * be made asynchronously (such as turning the screen on), in which case the caller * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()} * then try the request again later until the state converges. */ public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { if (DEBUG) { Slog.d(TAG, "requestPowerState: " + request + ", waitForNegativeProximity=" + waitForNegativeProximity); } synchronized (mLock) { boolean changed = false; if (waitForNegativeProximity && !mPendingWaitForNegativeProximityLocked) { mPendingWaitForNegativeProximityLocked = true; changed = true; } if (mPendingRequestLocked == null) {//第一次进来 mPendingRequestLocked = new DisplayPowerRequest(request); changed = true; } else if (!mPendingRequestLocked.equals(request)) { mPendingRequestLocked.copyFrom(request); changed = true; } if (changed) { mDisplayReadyLocked = false;//第一次进来mDisplayReadyLocked 为false } if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true;//第一次进来,肯定走进 sendUpdatePowerStateLocked(); } return mDisplayReadyLocked;//第一次进来返回false } }
sendUpdatePowerStateLocked
private void sendUpdatePowerStateLocked() { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }
发送消息,那么requestPowerState就直接返回mDisplayReadyLocked了。也就是说PMS第一次调用mDisplayManagerInternal.requestPowerState,mDisplayReady 肯定为false
PMS updateDisplayPowerStateLocked 函数中
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity);
处理MSG_UPDATE_POWER_STATE消息
@Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: updatePowerState(); break; case MSG_PROXIMITY_SENSOR_DEBOUNCED: debounceProximitySensor(); break; case MSG_SCREEN_ON_UNBLOCKED: if (mPendingScreenOnUnblocker == msg.obj) { unblockScreenOn(); updatePowerState(); } break; } }
updatePowerState
private void updatePowerState() { // Update the power state request. final boolean mustNotify; boolean mustInitialize = false; boolean autoBrightnessAdjustmentChanged = false; synchronized (mLock) { mPendingUpdatePowerStateLocked = false; if (mPendingRequestLocked == null) { return; // wait until first actual power request } if (mPowerRequest == null) {//第一次调用必走 mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; mPendingWaitForNegativeProximityLocked = false; mPendingRequestChangedLocked = false; mustInitialize = true; } else if (mPendingRequestChangedLocked) { autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment != mPendingRequestLocked.screenAutoBrightnessAdjustment); mPowerRequest.copyFrom(mPendingRequestLocked); mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; mPendingWaitForNegativeProximityLocked = false; mPendingRequestChangedLocked = false; mDisplayReadyLocked = false; } mustNotify = !mDisplayReadyLocked; } // Initialize things the first time the power state is changed. if (mustInitialize) {//第一必走 initialize(); } // Compute the basic display state using the policy. // We might override this below based on other factors. int state; int brightness = PowerManager.BRIGHTNESS_DEFAULT; boolean performScreenOffTransition = false; switch (mPowerRequest.policy) {//一会分析 case DisplayPowerRequest.POLICY_OFF: state = Display.STATE_OFF; performScreenOffTransition = true; break; case DisplayPowerRequest.POLICY_DOZE: if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) { state = mPowerRequest.dozeScreenState; } else { state = Display.STATE_DOZE; } if (!mAllowAutoBrightnessWhileDozingConfig) { brightness = mPowerRequest.dozeScreenBrightness; } break; case DisplayPowerRequest.POLICY_DIM: case DisplayPowerRequest.POLICY_BRIGHT: default: state = Display.STATE_ON; break; } assert(state != Display.STATE_UNKNOWN); // Apply the proximity sensor. if (mProximitySensor != null) { if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) { setProximitySensorEnabled(true); if (!mScreenOffBecauseOfProximity && mProximity == PROXIMITY_POSITIVE) { mScreenOffBecauseOfProximity = true; sendOnProximityPositiveWithWakelock(); } } else if (mWaitingForNegativeProximity && mScreenOffBecauseOfProximity && mProximity == PROXIMITY_POSITIVE && state != Display.STATE_OFF) { setProximitySensorEnabled(true); } else { setProximitySensorEnabled(false); mWaitingForNegativeProximity = false; } if (mScreenOffBecauseOfProximity && mProximity != PROXIMITY_POSITIVE) { mScreenOffBecauseOfProximity = false; sendOnProximityNegativeWithWakelock(); } } else { mWaitingForNegativeProximity = false; } if (mScreenOffBecauseOfProximity) { state = Display.STATE_OFF; } // Animate the screen state change unless already animating. // The transition may be deferred, so after this point we will use the // actual state instead of the desired one. animateScreenStateChange(state, performScreenOffTransition); state = mPowerState.getScreenState(); // Use zero brightness when screen is off. if (state == Display.STATE_OFF) { brightness = PowerManager.BRIGHTNESS_OFF; } // Configure auto-brightness. boolean autoBrightnessEnabled = false; if (mAutomaticBrightnessController != null) { final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND); autoBrightnessEnabled = mPowerRequest.useAutoBrightness && (state == Display.STATE_ON || autoBrightnessEnabledInDoze) && brightness < 0; final boolean userInitiatedChange = autoBrightnessAdjustmentChanged && mPowerRequest.brightnessSetByUser; mAutomaticBrightnessController.configure(autoBrightnessEnabled, mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON, userInitiatedChange); } // Apply brightness boost. // We do this here after configuring auto-brightness so that we don't // disable the light sensor during this temporary state. That way when // boost ends we will be able to resume normal auto-brightness behavior // without any delay. if (mPowerRequest.boostScreenBrightness && brightness != PowerManager.BRIGHTNESS_OFF) { brightness = PowerManager.BRIGHTNESS_ON; } // Apply auto-brightness. boolean slowChange = false; if (brightness < 0) { if (autoBrightnessEnabled) { brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); } if (brightness >= 0) { // Use current auto-brightness value and slowly adjust to changes. brightness = clampScreenBrightness(brightness); if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { slowChange = true; // slowly adapt to auto-brightness } mAppliedAutoBrightness = true; } else { mAppliedAutoBrightness = false; } } else { mAppliedAutoBrightness = false; } // Use default brightness when dozing unless overridden. if (brightness < 0 && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND)) { brightness = mScreenBrightnessDozeConfig; } // Apply manual brightness. // Use the current brightness setting from the request, which is expected // provide a nominal default value for the case where auto-brightness // is not ready yet. if (brightness < 0) { brightness = clampScreenBrightness(mPowerRequest.screenBrightness); } // Apply dimming by at least some minimum amount when user activity // timeout is about to expire. if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) { if (brightness > mScreenBrightnessRangeMinimum) { brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION, mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum); } if (!mAppliedDimming) { slowChange = false; } mAppliedDimming = true; } // If low power mode is enabled, cut the brightness level by half // as long as it is above the minimum threshold. if (mPowerRequest.lowPowerMode) { if (brightness > mScreenBrightnessRangeMinimum) { brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum); } if (!mAppliedLowPower) { slowChange = false; } mAppliedLowPower = true; } // Animate the screen brightness when the screen is on or dozing. // Skip the animation when the screen is off or suspended. if (!mPendingScreenOff) {//这个时候没有灭屏动画 if (state == Display.STATE_ON || state == Display.STATE_DOZE) { animateScreenBrightness(brightness,// 这个函数也是在DisplayPowerState设置亮度,待会详细分析 slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST); } else { animateScreenBrightness(brightness, 0); } } // Determine whether the display is ready for use in the newly requested state. // Note that we do not wait for the brightness ramp animation to complete before // reporting the display is ready because we only need to ensure the screen is in the // right power state even as it continues to converge on the desired brightness. final boolean ready = mPendingScreenOnUnblocker == null && !mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted() && mPowerState.waitUntilClean(mCleanListener); final boolean finished = ready && !mScreenBrightnessRampAnimator.isAnimating(); // Notify policy about screen turned on. if (ready && state != Display.STATE_OFF && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) { mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON; mWindowManagerPolicy.screenTurnedOn(); } // Grab a wake lock if we have unfinished business. if (!finished && !mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Unfinished business..."); } mCallbacks.acquireSuspendBlocker(); mUnfinishedBusiness = true; } // Notify the power manager when ready. if (ready && mustNotify) { // Send state change. synchronized (mLock) { if (!mPendingRequestChangedLocked) { mDisplayReadyLocked = true; if (DEBUG) { Slog.d(TAG, "Display ready!"); } } } sendOnStateChangedWithWakelock();//完成工作后通知PMS } // Release the wake lock when we have no unfinished business. if (finished && mUnfinishedBusiness) { if (DEBUG) { Slog.d(TAG, "Finished business..."); } mUnfinishedBusiness = false; mCallbacks.releaseSuspendBlocker(); } }
先看这个mCallbacks,是PMS传进来的回调 systemReady
// Initialize display power management. mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager);
initialize
private void initialize() { // Initialize the power state object for the default display. // In the future, we might manage multiple displays independently. mPowerState = new DisplayPowerState(mBlanker, new ColorFade(Display.DEFAULT_DISPLAY)); mColorFadeOnAnimator = ObjectAnimator.ofFloat( mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f); mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS); mColorFadeOnAnimator.addListener(mAnimatorListener); mColorFadeOffAnimator = ObjectAnimator.ofFloat( mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f); mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS); mColorFadeOffAnimator.addListener(mAnimatorListener); mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>( mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS); mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener); // Initialize screen state for battery stats. try { mBatteryStats.noteScreenState(mPowerState.getScreenState()); mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness()); } catch (RemoteException ex) { // same process } }
继续分析,根据传进来的mPowerRequest.policy不同,走不同的case
// Compute the basic display state using the policy. // We might override this below based on other factors. int state; int brightness = PowerManager.BRIGHTNESS_DEFAULT; boolean performScreenOffTransition = false; switch (mPowerRequest.policy) { case DisplayPowerRequest.POLICY_OFF: state = Display.STATE_OFF; performScreenOffTransition = true; break; case DisplayPowerRequest.POLICY_DOZE: if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) { state = mPowerRequest.dozeScreenState; } else { state = Display.STATE_DOZE; } if (!mAllowAutoBrightnessWhileDozingConfig) { brightness = mPowerRequest.dozeScreenBrightness; } break; case DisplayPowerRequest.POLICY_DIM: case DisplayPowerRequest.POLICY_BRIGHT: default: state = Display.STATE_ON; break; }
看看PMS这个mPowerRequest.policy值,在updateDisplayPowerStateLocked函数中
private boolean updateDisplayPowerStateLocked(int dirty) { final boolean oldDisplayReady = mDisplayReady; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) { mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
getDesiredScreenPolicyLocked
private int getDesiredScreenPolicyLocked() { if (mWakefulness == WAKEFULNESS_ASLEEP) { return DisplayPowerRequest.POLICY_OFF; } if (mWakefulness == WAKEFULNESS_DOZING) { if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) { return DisplayPowerRequest.POLICY_DOZE; } if (mDozeAfterScreenOffConfig) { return DisplayPowerRequest.POLICY_OFF; } // Fall through and preserve the current screen policy if not configured to // doze after screen off. This causes the screen off transition to be skipped. } if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0 || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0 || !mBootCompleted || mScreenBrightnessBoostInProgress) { return DisplayPowerRequest.POLICY_BRIGHT; } return DisplayPowerRequest.POLICY_DIM; }
animateScreenStateChange
继续分析animateScreenStateChangeprivate void animateScreenStateChange(int target, boolean performScreenOffTransition) { // If there is already an animation in progress, don't interfere with it. if (mColorFadeOnAnimator.isStarted() || mColorFadeOffAnimator.isStarted()) { return; } // If we were in the process of turning off the screen but didn't quite // finish. Then finish up now to prevent a jarring transition back // to screen on if we skipped blocking screen on as usual. if (mPendingScreenOff && target != Display.STATE_OFF) {//灭屏动画 setScreenState(Display.STATE_OFF); mPendingScreenOff = false; mPowerState.dismissColorFadeResources(); } if (target == Display.STATE_ON) { // Want screen on. The contents of the screen may not yet // be visible if the color fade has not been dismissed because // its last frame of animation is solid black. if (!setScreenState(Display.STATE_ON)) { return; // screen on blocked } if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) { // Perform screen on animation. if (mPowerState.getColorFadeLevel() == 1.0f) { mPowerState.dismissColorFade(); } else if (mPowerState.prepareColorFade(mContext, mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_WARM_UP)) { mColorFadeOnAnimator.start(); } else { mColorFadeOnAnimator.end(); } } else { // Skip screen on animation. mPowerState.setColorFadeLevel(1.0f); mPowerState.dismissColorFade(); } } else if (target == Display.STATE_DOZE) { // Want screen dozing. // Wait for brightness animation to complete beforehand when entering doze // from screen on to prevent a perceptible jump because brightness may operate // differently when the display is configured for dozing. if (mScreenBrightnessRampAnimator.isAnimating() && mPowerState.getScreenState() == Display.STATE_ON) { return; } // Set screen state. if (!setScreenState(Display.STATE_DOZE)) { return; // screen on blocked } // Dismiss the black surface without fanfare. mPowerState.setColorFadeLevel(1.0f); mPowerState.dismissColorFade(); } else if (target == Display.STATE_DOZE_SUSPEND) { // Want screen dozing and suspended. // Wait for brightness animation to complete beforehand unless already // suspended because we may not be able to change it after suspension. if (mScreenBrightnessRampAnimator.isAnimating() && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { return; } // If not already suspending, temporarily set the state to doze until the // screen on is unblocked, then suspend. if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) { if (!setScreenState(Display.STATE_DOZE)) { return; // screen on blocked } setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block } // Dismiss the black surface without fanfare. mPowerState.setColorFadeLevel(1.0f); mPowerState.dismissColorFade(); } else { // Want screen off. mPendingScreenOff = true; if (mPowerState.getColorFadeLevel() == 0.0f) { // Turn the screen off. // A black surface is already hiding the contents of the screen. setScreenState(Display.STATE_OFF); mPendingScreenOff = false; mPowerState.dismissColorFadeResources(); } else if (performScreenOffTransition && mPowerState.prepareColorFade(mContext, mColorFadeFadesConfig ? ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN) && mPowerState.getScreenState() != Display.STATE_OFF) { // Perform the screen off animation. mColorFadeOffAnimator.start(); } else { // Skip the screen off animation and add a black surface to hide the // contents of the screen. mColorFadeOffAnimator.end(); } } }
setScreenState
再看看 setScreenState
private boolean setScreenState(int state) { if (mPowerState.getScreenState() != state) { final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF); mPowerState.setScreenState(state);//调用DisplayPowerState的setScreenState函数,后面再分析 // Tell battery stats about the transition. try { mBatteryStats.noteScreenState(state);//电池记录 } catch (RemoteException ex) { // same process } } // Tell the window manager policy when the screen is turned off or on unless it's due // to the proximity sensor. We temporarily block turning the screen on until the // window manager is ready by leaving a black surface covering the screen. // This surface is essentially the final state of the color fade animation and // it is only removed once the window manager tells us that the activity has // finished drawing underneath. final boolean isOff = (state == Display.STATE_OFF); if (isOff && mReportedScreenStateToPolicy != REPORTED_TO_POLICY_SCREEN_OFF && !mScreenOffBecauseOfProximity) { mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_OFF; unblockScreenOn(); mWindowManagerPolicy.screenTurnedOff();//通知phonewindowManager } else if (!isOff && mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_OFF) { mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_TURNING_ON; if (mPowerState.getColorFadeLevel() == 0.0f) { blockScreenOn(); } else { unblockScreenOn(); } mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); } // Return true if the screen isn't blocked. return mPendingScreenOnUnblocker == null; }
再看看sendOnStateChangedWithWakelock函数
sendOnStateChangedWithWakelock
private void sendOnStateChangedWithWakelock() { mCallbacks.acquireSuspendBlocker(); mHandler.post(mOnStateChangedRunnable); } private final Runnable mOnStateChangedRunnable = new Runnable() { @Override public void run() { mCallbacks.onStateChanged(); mCallbacks.releaseSuspendBlocker(); } };
而PMS里的mDisplayPowerCallbacks 的onStateChanged如下
// Initialize display power management. mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager);
private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks = new DisplayManagerInternal.DisplayPowerCallbacks() { private int mDisplayState = Display.STATE_UNKNOWN; @Override public void onStateChanged() { synchronized (mLock) { mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED; updatePowerStateLocked();//更新状态 } }
会重新调用到PMS的updateDisplayPowerStateLocked函数,再调用下面。
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
由于changed没有变化,最后返回true
然后 DisplayManagerService.java 文件的localService
@Override public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity); }
继续分析updatePowerStateLocked
// Phase 2: Update display power state. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2); // Phase 3: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 4: Send notifications, if needed. finishWakefulnessChangeIfNeededLocked(); // Phase 5: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); }
先看updateDreamLocked函数,mDisplayReady为false,所以跳出
/** * Determines whether to post a message to the sandman to update the dream state. */ private void updateDreamLocked(int dirty, boolean displayBecameReady) { if ((dirty & (DIRTY_WAKEFULNESS | DIRTY_USER_ACTIVITY | DIRTY_WAKE_LOCKS | DIRTY_BOOT_COMPLETED | DIRTY_SETTINGS | DIRTY_IS_POWERED | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) { if (mDisplayReady) { scheduleSandmanLocked(); } } }
再看 updateSuspendBlockerLocked函数
/** * Updates the suspend blocker that keeps the CPU alive. * * This function must have no other side-effects. */ private void updateSuspendBlockerLocked() { final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//看cpu是否要持锁 final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();//现在Display没好,需要持Display的锁 final boolean autoSuspend = !needDisplaySuspendBlocker; final boolean interactive = mDisplayPowerRequest.isBrightOrDim(); // Disable auto-suspend if needed. // FIXME We should consider just leaving auto-suspend enabled forever since // we already hold the necessary wakelocks. if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(false); } // First acquire suspend blockers if needed. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.acquire(); mHoldingWakeLockSuspendBlocker = true; } if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true; } // Inform the power HAL about interactive mode. // Although we could set interactive strictly based on the wakefulness // as reported by isInteractive(), it is actually more desirable to track // the display policy state instead so that the interactive state observed // by the HAL more accurately tracks transitions between AWAKE and DOZING. // Refer to getDesiredScreenPolicyLocked() for details. if (mDecoupleHalInteractiveModeFromDisplayConfig) { // When becoming non-interactive, we want to defer sending this signal // until the display is actually ready so that all transitions have // completed. This is probably a good sign that things have gotten // too tangled over here... if (interactive || mDisplayReady) { setHalInteractiveModeLocked(interactive);//修改cpu频率等 } } // Then release suspend blockers if needed. if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.release(); mHoldingWakeLockSuspendBlocker = false; } if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.release(); mHoldingDisplaySuspendBlocker = false; } // Enable auto-suspend if needed. if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true);//设置true,让系统可以自动睡眠 } }
needDisplaySuspendBlockerLocked函数mDisplayReady为false,直接返回true
/** * Return true if we must keep a suspend blocker active on behalf of the display. * We do so if the screen is on or is in transition between states. */ private boolean needDisplaySuspendBlockerLocked() { if (!mDisplayReady) { return true; } if (mDisplayPowerRequest.isBrightOrDim()) { // If we asked for the screen to be on but it is off due to the proximity // sensor then we may suspend but only if the configuration allows it. // On some hardware it may not be safe to suspend because the proximity // sensor may not be correctly configured as a wake-up source. if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive || !mSuspendWhenScreenOffDueToProximityConfig) { return true; } } if (mScreenBrightnessBoostInProgress) { return true; } // Let the system suspend if the screen is off or dozing. return false; }
这样PMS刚调mDisplayManagerInternal.requestPowerState的时候,返回mDisplayReady为false,最后也就会持Display的锁,
直到Display准备好,回调函数直接又调用updatePowerStateLocked函数,再调用updateDisplayPowerStateLocked函数,返回mDisplayReady为true。
那我们继续分析updatePowerStateLocked函数
// Phase 3: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 4: Send notifications, if needed. finishWakefulnessChangeIfNeededLocked(); // Phase 5: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); }
updateDreamLocked函数发送消息,消息最后处理的函数是handleSandman,goToSleepNoUpdateLocked和napNoUpdateLocked函数才会把mSandmanSummoned = true
private void scheduleSandmanLocked() { if (!mSandmanScheduled) { mSandmanScheduled = true; Message msg = mHandler.obtainMessage(MSG_SANDMAN); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }
/** * Called when the device enters or exits a dreaming or dozing state. * * We do this asynchronously because we must call out of the power manager to start * the dream and we don't want to hold our lock while doing so. There is a risk that * the device will wake or go to sleep in the meantime so we have to handle that case. */ private void handleSandman() { // runs on handler thread // Handle preconditions. final boolean startDreaming; final int wakefulness; synchronized (mLock) { mSandmanScheduled = false; wakefulness = mWakefulness; if (mSandmanSummoned && mDisplayReady) {//mSandmanSummoned为donzing状态和dreaming状态的时候才为true startDreaming = canDreamLocked() || canDozeLocked();//canDozeLocked函数只要wakefulness == WAKEFULNESS_DOZING就true mSandmanSummoned = false; } else { startDreaming = false; } } // Start dreaming if needed. // We only control the dream on the handler thread, so we don't need to worry about // concurrent attempts to start or stop the dream. final boolean isDreaming; if (mDreamManager != null) { // Restart the dream whenever the sandman is summoned. if (startDreaming) { mDreamManager.stopDream(false /*immediate*/); mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING); } isDreaming = mDreamManager.isDreaming(); } else { isDreaming = false; } // Update dream state. synchronized (mLock) { // Remember the initial battery level when the dream started. if (startDreaming && isDreaming) { mBatteryLevelWhenDreamStarted = mBatteryLevel; if (wakefulness == WAKEFULNESS_DOZING) { Slog.i(TAG, "Dozing..."); } else { Slog.i(TAG, "Dreaming..."); } } // If preconditions changed, wait for the next iteration to determine // whether the dream should continue (or be restarted). if (mSandmanSummoned || mWakefulness != wakefulness) { return; // wait for next cycle } // Determine whether the dream should continue. if (wakefulness == WAKEFULNESS_DREAMING) { if (isDreaming && canDreamLocked()) { if (mDreamsBatteryLevelDrainCutoffConfig >= 0 && mBatteryLevel < mBatteryLevelWhenDreamStarted - mDreamsBatteryLevelDrainCutoffConfig && !isBeingKeptAwakeLocked()) { // If the user activity timeout expired and the battery appears // to be draining faster than it is charging then stop dreaming // and go to sleep. Slog.i(TAG, "Stopping dream because the battery appears to " + "be draining faster than it is charging. " + "Battery level when dream started: " + mBatteryLevelWhenDreamStarted + "%. " + "Battery level now: " + mBatteryLevel + "%."); } else { return; // continue dreaming } } // Dream has ended or will be stopped. Update the power state. if (isItBedTimeYetLocked()) {//dream 停止,开始sleep goToSleepNoUpdateLocked(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); updatePowerStateLocked(); } else { wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), "android.server.power:DREAM", Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID); updatePowerStateLocked(); } } else if (wakefulness == WAKEFULNESS_DOZING) {//WAKEFULNESS_DOZING和WAKEFULNESS_DREAMING都可以做梦 if (isDreaming) { return; // continue dozing } // Doze has ended or will be stopped. Update the power state. reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);//直接sleep updatePowerStateLocked(); } } // Stop dream. if (isDreaming) { mDreamManager.stopDream(false /*immediate*/); } }
继续分析PMS中的updatePowerStateLocked函数
// Phase 4: Send notifications, if needed. finishWakefulnessChangeIfNeededLocked(); // Phase 5: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); }
Display完成后,屏幕在灭屏之前通知PhoneWindowManager,电池统计等。updateSuspendBlockerLocked函数持有一个锁,和调JNI设置cpu频率,还有一个autoSuspend是自动让系统睡眠,如果开启就设true。
亮度调节的时序图
相关文章推荐
- Android 6.0 PowerManagerService 之 updatePowerStateLocked函数
- Android 6.0 PowerManagerService 一
- Android 6.0 PowerManagerService状态分析
- Android5.1 PowerManagerService深入分析
- android6.0 power显示(亮度等)深入分析(一)PowerManagerService & DisplayPowerController
- 浅谈Android system_service 注册Service、APP获取并访问服务(PMS:PowerManagerService)为例
- (OK) Android 5 SystemServer 各个系统Manager-startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
- Android7.0 PowerManagerService 之亮灭屏(二) PMS 电源状态管理updatePowerStateLocked()
- android6.0 power显示(亮度等)深入分析(一)PowerManagerService & DisplayPowerController
- android 6.0 activitymanagerservice keyword
- android PowerManagerService分析
- android6.0 power显示(亮度等)深入分析(二)DisplayManagerService
- Android7.0 PowerManagerService(2) WakeLock的使用及流程
- android6.0 power显示(亮度等)深入分析(二)DisplayManagerService
- Android 6.0 之AlarmManagerService源码分析
- android6.0 power显示(亮度等)深入分析(二)DisplayManagerService
- android5.1 PowerManagerService和DisplayPowerControler、DisplayPowerState关系
- android PowerManagerService分析
- android6.0 power显示(亮度等)深入分析(一)PowerManagerService & DisplayPowerController