PMS与Display模块的交互在之前的一篇博客也写过,但不是写的很详细。
在PMS的systemReady方法中,有如下两段代码:
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager);
在DisplayManagerService中有一个内部LocalService类,而在PMS的systemReady方法中的mDisplayManagerInternal 也正是这个内部类LocalService,其将mDisplayPowerCallbacks、mHandler、SensorManager传给了DisplayPowerController
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) { // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state); } callbacks.onDisplayStateChange(state); if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state); } } }; mDisplayPowerController = new DisplayPowerController(//新建了一个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, boolean inTraversal) { setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal); }
而在上一篇PMS的博客我们,我们分析到updateDisplayPowerStateLocked函数mDisplayManagerInternal.requestPowerState,这里requestPowerState就调用了上面的方法,最后调用了DisplayPowerController里的requestPowerState方法。
public DisplayPowerController(Context context, DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager, DisplayBlanker blanker) { mHandler = new DisplayControllerHandler(handler.getLooper()); mCallbacks = callbacks; mBatteryStats = BatteryStatsService.getService(); mLights = LocalServices.getService(LightsManager.class);//获取各种manager等 mSensorManager = sensorManager; mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class); mBlanker = blanker; mContext = context; mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 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); 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); } } 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函数:
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);//new 一个mPendingRequestLocked 对象 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。
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity);
那我们继续分析前面的消息
@Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: 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);//建一个mPowerRequest mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; mPendingWaitForNegativeProximityLocked = false; mPendingRequestChangedLocked = false; mustInitialize = true;//置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();
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,//新建DisplayPowerState,将mBlanker传入,传了一个背光的light mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT), 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不同,给state
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);再来看看PMS这个mPowerRequest.policy值
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这个函数
private 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; } 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; } 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函数
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 what's happening. // 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. boolean isOn = (state != Display.STATE_OFF); if (wasOn && !isOn) { unblockScreenOn(); mWindowManagerPolicy.screenTurnedOff();//通知phonewindowManager } else if (!wasOn && isOn) { if (mPowerState.getColorFadeLevel() == 0.0f) { blockScreenOn(); } else { unblockScreenOn(); } mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); } } return mPendingScreenOnUnblocker == null; }
继续分析updatePowerState函数
animateScreenStateChange(state, performScreenOffTransition);// 设置到mPowerState状态 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; mAutomaticBrightnessController.configure(autoBrightnessEnabled, mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON); } // 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;//boostScreenBrightness为最亮255 } // 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); } }
继续分析updatePowerState函数
final boolean ready = mPendingScreenOnUnblocker == null && !mColorFadeOnAnimator.isStarted() && !mColorFadeOffAnimator.isStarted() && mPowerState.waitUntilClean(mCleanListener); final boolean finished = ready && !mScreenBrightnessRampAnimator.isAnimating(); // 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传进来的回调。
mDisplayManagerInternal.initPowerManagement( mDisplayPowerCallbacks, mHandler, sensorManager);
@Override public void acquireSuspendBlocker() {// 持锁 mDisplaySuspendBlocker.acquire(); } @Override public void releaseSuspendBlocker() {//释放锁 mDisplaySuspendBlocker.release(); }
再看看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如下
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);
现在我们再来看,由于changed没有变化,最后返回true。
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; } if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true; sendUpdatePowerStateLocked(); } return mDisplayReadyLocked;//changed没有变化直接返回,updatePowerState函数中已经将mDisplayReadyLocked置为true } }
先来看下DisplayPowerController里的setScreenState函数,其中调用了DisplayPowerState的setScreenState函数
private boolean setScreenState(int state) { if (mPowerState.getScreenState() != state) { final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF); mPowerState.setScreenState(state); // Tell battery stats about the transition. try { mBatteryStats.noteScreenState(state); } catch (RemoteException ex) { // same process } // Tell the window manager what's happening. // 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. boolean isOn = (state != Display.STATE_OFF); if (wasOn && !isOn) { unblockScreenOn(); mWindowManagerPolicy.screenTurnedOff(); } else if (!wasOn && isOn) { if (mPowerState.getColorFadeLevel() == 0.0f) { blockScreenOn(); } else { unblockScreenOn(); } mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); } } return mPendingScreenOnUnblocker == null; }
DisplayPowerController中调用DisplayPowerState的setScreenBrightness函数不是直接调用的,而是通过泛型技术调用的,这里就不讲了,感兴趣可以自己去细看。
private void animateScreenBrightness(int target, int rate) { if (DEBUG) { Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate); } if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {//泛型技术,最后调用了DisplayPowerState的setScreenBrightness函数 try { mBatteryStats.noteScreenBrightness(target); } catch (RemoteException ex) { // same process } } }
再来看看DisplayPowerState的setScreenState函数,和setScreenBrightness
public void setScreenBrightness(int brightness) { if (mScreenBrightness != brightness) { if (DEBUG) { Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); } mScreenBrightness = brightness; if (mScreenState != Display.STATE_OFF) { mScreenReady = false; scheduleScreenUpdate(); } } }
setScreenState函数,两者后面都是调用了scheduleScreenUpdate函数
public void setScreenState(int state) { if (mScreenState != state) { if (DEBUG) { Slog.d(TAG, "setScreenState: state=" + state); } mScreenState = state; mScreenReady = false; scheduleScreenUpdate(); } }
private void scheduleScreenUpdate() { if (!mScreenUpdatePending) { mScreenUpdatePending = true; postScreenUpdateThreadSafe(); } } private void postScreenUpdateThreadSafe() { mHandler.removeCallbacks(mScreenUpdateRunnable); mHandler.post(mScreenUpdateRunnable); }
利用消息机制的post函数
private final Runnable mScreenUpdateRunnable = new Runnable() { @Override public void run() { mScreenUpdatePending = false; int brightness = mScreenState != Display.STATE_OFF && mColorFadeLevel > 0f ? mScreenBrightness : 0; if (mPhotonicModulator.setState(mScreenState, brightness)) {//下面主要分析这个 if (DEBUG) { Slog.d(TAG, "Screen ready"); } mScreenReady = true; invokeCleanListenerIfNeeded(); } else { if (DEBUG) { Slog.d(TAG, "Screen not ready"); } } } };
下面就是PhotonicModulator的setState函数,这个类是一个线程,在构造函数里面start
public boolean setState(int state, int backlight) { synchronized (mLock) { if (state != mPendingState || backlight != mPendingBacklight) { if (DEBUG) { Slog.d(TAG, "Requesting new screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); } mPendingState = state; mPendingBacklight = backlight; if (!mChangeInProgress) { mChangeInProgress = true; mLock.notifyAll();//通知 } } return !mChangeInProgress; } }
下面是DisplayPowerState的构造函数,其实例在DisplayPowerController中新建
public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) { mHandler = new Handler(true /*async*/); mChoreographer = Choreographer.getInstance(); mBlanker = blanker; mBacklight = backlight; mColorFade = electronBeam; mPhotonicModulator = new PhotonicModulator(); mPhotonicModulator.start();//开启线程 // At boot time, we know that the screen is on and the electron beam // animation is not playing. We don't know the screen's brightness though, // so prepare to set it to a known state when the state is next applied. // Although we set the brightness to full on here, the display power controller // will reset the brightness to a new level immediately before the changes // actually have a chance to be applied. mScreenState = Display.STATE_ON; mScreenBrightness = PowerManager.BRIGHTNESS_ON; scheduleScreenUpdate(); mColorFadePrepared = false; mColorFadeLevel = 1.0f; mColorFadeReady = true; }我们再来分析下PhotonicModulator的run函数
@Override public void run() { for (;;) { // Get pending change. final int state; final boolean stateChanged; final int backlight; final boolean backlightChanged; synchronized (mLock) { state = mPendingState; stateChanged = (state != mActualState); backlight = mPendingBacklight; backlightChanged = (backlight != mActualBacklight); if (!stateChanged && !backlightChanged) { // All changed applied, notify outer class and wait for more. mChangeInProgress = false; postScreenUpdateThreadSafe(); try { mLock.wait();//一直等待,直到setState有改变会notifyAll } catch (InterruptedException ex) { } continue; } mActualState = state; mActualBacklight = backlight; } // Apply pending change. if (DEBUG) { Slog.d(TAG, "Updating screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); } boolean suspending = Display.isSuspendedState(state); if (stateChanged && !suspending) { Slog.d(TAG, "Updating screen state: state = " + Display.stateToString(state)); requestDisplayState(state);//下面详细分析 } if (backlightChanged) { Slog.d(TAG, "Updating screen backlight = " + backlight); setBrightness(backlight); } if (stateChanged && suspending) { Slog.d(TAG, "Updating screen state: state = " + Display.stateToString(state)); requestDisplayState(state); } } }requestDisplayState函数
private void requestDisplayState(int state) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState(" + Display.stateToString(state) + ")"); try { mBlanker.requestDisplayState(state); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }是DisplayManagerService中的blanker的requestDisplayState函数,然后将这个blanker传给了DisplayPowerController,再传给DisplayPowerState
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) { // The order of operations is important for legacy reasons. if (state == Display.STATE_OFF) { requestGlobalDisplayStateInternal(state); } callbacks.onDisplayStateChange(state);//回调到PMS中的onDisplayStateChange if (state != Display.STATE_OFF) { requestGlobalDisplayStateInternal(state); } } }; mDisplayPowerController = new DisplayPowerController( mContext, callbacks, handler, sensorManager, blanker); } }
PMS的DisplayManagerInternal.DisplayPowerCallbacks的onDisplayStateChange函数
@Override public void onDisplayStateChange(int state) { // This method is only needed to support legacy display blanking behavior // where the display's power state is coupled to suspend or to the power HAL. // The order of operations matters here. synchronized (mLock) { if (mDisplayState != state) { mDisplayState = state; if (state == Display.STATE_OFF) { if (!mDecoupleHalInteractiveModeFromDisplayConfig) { setHalInteractiveModeLocked(false);//JNI处理cpu频率等 } if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true);//设置为true,让系统自动休眠。 } } else { if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(false); } if (!mDecoupleHalInteractiveModeFromDisplayConfig) { setHalInteractiveModeLocked(true); } } } }
再来看看DisplayPowerState的setBrightness函数
private void setBrightness(int backlight) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")"); try { mBacklight.setBrightness(backlight);//mBckLight是DisplayPowerController传进来的 } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }
DisplayPowerController新建DisplayPowerState对象
mPowerState = new DisplayPowerState(mBlanker, mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),//传入mBacklight new ColorFade(Display.DEFAULT_DISPLAY));
getLight函数是从light数组里面选一个light
private final LightsManager mService = new LightsManager() { @Override public com.android.server.lights.Light getLight(int id) { if (id < LIGHT_ID_COUNT) { return mLights[id]; } else { return null; } } };
light类,设置亮度会把自己的一个id号,传下去
private final class LightImpl extends Light { private LightImpl(int id) { mId = id; } @Override public void setBrightness(int brightness) { setBrightness(brightness, BRIGHTNESS_MODE_USER); } @Override public void setBrightness(int brightness, int brightnessMode) { synchronized (this) { int color = brightness & 0x000000ff; color = 0xff000000 | (color << 16) | (color << 8) | color; setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode); } }
最后调用setLightLocked,会将该light的id传下去,最后调用setLight_native来完成最后的设置亮度。
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) { if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" + Integer.toHexString(color)); mColor = color; mMode = mode; mOnMS = onMS; mOffMS = offMS; Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", " + color + ")"); try { setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }
// Phase 2: Update display power state. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//第一次返回为false // Phase 3: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 4: Send notifications, if needed. if (mDisplayReady) { finishWakefulnessChangeLocked(); } // 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();
先看updateDreamLocked函数,mDisplayReady为false,所以跳出
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
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);//调用JNI,具体还要分析 } // First acquire suspend blockers if needed. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.acquire();//持cpu锁 mHoldingWakeLockSuspendBlocker = true; } if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.acquire();//持Display锁 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);//JNI,修改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
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函数:
updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 4: Send notifications, if needed. if (mDisplayReady) { finishWakefulnessChangeLocked(); } // 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();updateDreamLocked函数发送消息
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(); } } } private void scheduleSandmanLocked() { if (!mSandmanScheduled) { mSandmanScheduled = true; Message msg = mHandler.obtainMessage(MSG_SANDMAN); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }消息最后处理的函数是handleSandman,goToSleepNoUpdateLocked和napNoUpdateLocked函数才会把mSandmanSummoned = true;
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) {//为true才开始做梦 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()) {//该睡觉了 goToSleepNoUpdateLocked(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); updatePowerStateLocked(); } else {//否则直接唤醒 wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), 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*/); } }
继续分析updatePowerStateLocked函数
if (mDisplayReady) { finishWakefulnessChangeLocked(); } // 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完成后,可以finishWakefulnessChangeLocked函数,在之前的PMS的博客分析过了。这里是屏幕灭屏之前通知PhoneWindowManager,电池统计等。
updateSuspendBlockerLocked函数之前分析过了,就不再分析了就是一个持锁,和调JNI设置cpu频率,还有一个autoSuspend是自动让系统睡眠,如果开启就设true。