and5.1PowerManagerService深入分析(四)PMS与Display模块

转自:http://blog.csdn.net/kc58236582/article/details/48007945

PMS与Display模块的交互在之前的一篇博客也写过,但不是写的很详细。

在PMS的systemReady方法中,有如下两段代码:

[java] view plaincopy
  1. mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
[java] view plaincopy
  1. mDisplayManagerInternal.initPowerManagement(
  2. mDisplayPowerCallbacks, mHandler, sensorManager);

在DisplayManagerService中有一个内部LocalService类,而在PMS的systemReady方法中的mDisplayManagerInternal 也正是这个内部类LocalService,其将mDisplayPowerCallbacks、mHandler、SensorManager传给了DisplayPowerController

[java] view plaincopy
  1. private final class LocalService extends DisplayManagerInternal {
  2. @Override
  3. public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
  4. SensorManager sensorManager) {
  5. synchronized (mSyncRoot) {
  6. DisplayBlanker blanker = new DisplayBlanker() {
  7. @Override
  8. public void requestDisplayState(int state) {
  9. // The order of operations is important for legacy reasons.
  10. if (state == Display.STATE_OFF) {
  11. requestGlobalDisplayStateInternal(state);
  12. }
  13. callbacks.onDisplayStateChange(state);
  14. if (state != Display.STATE_OFF) {
  15. requestGlobalDisplayStateInternal(state);
  16. }
  17. }
  18. };
  19. mDisplayPowerController = new DisplayPowerController(//新建了一个DisplayPowerController对象
  20. mContext, callbacks, handler, sensorManager, blanker);
  21. }
  22. }
  23. @Override
  24. public boolean requestPowerState(DisplayPowerRequest request,
  25. boolean waitForNegativeProximity) {
  26. return mDisplayPowerController.requestPowerState(request,
  27. waitForNegativeProximity);
  28. }
  29. @Override
  30. public boolean isProximitySensorAvailable() {
  31. return mDisplayPowerController.isProximitySensorAvailable();
  32. }
  33. @Override
  34. public DisplayInfo getDisplayInfo(int displayId) {
  35. return getDisplayInfoInternal(displayId, Process.myUid());
  36. }
  37. @Override
  38. public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
  39. if (listener == null) {
  40. throw new IllegalArgumentException("listener must not be null");
  41. }
  42. registerDisplayTransactionListenerInternal(listener);
  43. }
  44. @Override
  45. public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
  46. if (listener == null) {
  47. throw new IllegalArgumentException("listener must not be null");
  48. }
  49. unregisterDisplayTransactionListenerInternal(listener);
  50. }
  51. @Override
  52. public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
  53. setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
  54. }
  55. @Override
  56. public void performTraversalInTransactionFromWindowManager() {
  57. performTraversalInTransactionFromWindowManagerInternal();
  58. }
  59. @Override
  60. public void setDisplayProperties(int displayId, boolean hasContent,
  61. float requestedRefreshRate, boolean inTraversal) {
  62. setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
  63. }

而在上一篇PMS的博客我们,我们分析到updateDisplayPowerStateLocked函数mDisplayManagerInternal.requestPowerState,这里requestPowerState就调用了上面的方法,最后调用了DisplayPowerController里的requestPowerState方法。

我们先来看下DisplayPowerController类的构造函数

[java] view plaincopy
  1. public DisplayPowerController(Context context,
  2. DisplayPowerCallbacks callbacks, Handler handler,
  3. SensorManager sensorManager, DisplayBlanker blanker) {
  4. mHandler = new DisplayControllerHandler(handler.getLooper());
  5. mCallbacks = callbacks;
  6. mBatteryStats = BatteryStatsService.getService();
  7. mLights = LocalServices.getService(LightsManager.class);//获取各种manager等
  8. mSensorManager = sensorManager;
  9. mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
  10. mBlanker = blanker;
  11. mContext = context;
  12. mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
  13. final Resources resources = context.getResources();//获取各种资源
  14. final int screenBrightnessSettingMinimum = clampAbsoluteBrightness(resources.getInteger(
  15. com.android.internal.R.integer.config_screenBrightnessSettingMinimum));
  16. mScreenBrightnessDozeConfig = clampAbsoluteBrightness(resources.getInteger(
  17. com.android.internal.R.integer.config_screenBrightnessDoze));
  18. mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
  19. com.android.internal.R.integer.config_screenBrightnessDim));
  20. mScreenBrightnessDarkConfig = clampAbsoluteBrightness(resources.getInteger(
  21. com.android.internal.R.integer.config_screenBrightnessDark));
  22. if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
  23. Slog.w(TAG, "Expected config_screenBrightnessDark ("
  24. + mScreenBrightnessDarkConfig + ") to be less than or equal to "
  25. + "config_screenBrightnessDim (" + mScreenBrightnessDimConfig + ").");
  26. }
  27. if (mScreenBrightnessDarkConfig > mScreenBrightnessDimConfig) {
  28. Slog.w(TAG, "Expected config_screenBrightnessDark ("
  29. + mScreenBrightnessDarkConfig + ") to be less than or equal to "
  30. + "config_screenBrightnessSettingMinimum ("
  31. + screenBrightnessSettingMinimum + ").");
  32. }
  33. int screenBrightnessRangeMinimum = Math.min(Math.min(
  34. screenBrightnessSettingMinimum, mScreenBrightnessDimConfig),
  35. mScreenBrightnessDarkConfig);
  36. mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
  37. mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
  38. com.android.internal.R.bool.config_automatic_brightness_available);
  39. mAllowAutoBrightnessWhileDozingConfig = resources.getBoolean(
  40. com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing);
  41. if (mUseSoftwareAutoBrightnessConfig) {
  42. int[] lux = resources.getIntArray(
  43. com.android.internal.R.array.config_autoBrightnessLevels);
  44. int[] screenBrightness = resources.getIntArray(
  45. com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
  46. int lightSensorWarmUpTimeConfig = resources.getInteger(
  47. com.android.internal.R.integer.config_lightSensorWarmupTime);
  48. final float dozeScaleFactor = resources.getFraction(
  49. com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,
  50. 1, 1);
  51. Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
  52. if (screenAutoBrightnessSpline == null) {
  53. Slog.e(TAG, "Error in config.xml.  config_autoBrightnessLcdBacklightValues "
  54. + "(size " + screenBrightness.length + ") "
  55. + "must be monotic and have exactly one more entry than "
  56. + "config_autoBrightnessLevels (size " + lux.length + ") "
  57. + "which must be strictly increasing.  "
  58. + "Auto-brightness will be disabled.");
  59. mUseSoftwareAutoBrightnessConfig = false;
  60. } else {
  61. int bottom = clampAbsoluteBrightness(screenBrightness[0]);
  62. if (mScreenBrightnessDarkConfig > bottom) {
  63. Slog.w(TAG, "config_screenBrightnessDark (" + mScreenBrightnessDarkConfig
  64. + ") should be less than or equal to the first value of "
  65. + "config_autoBrightnessLcdBacklightValues ("
  66. + bottom + ").");
  67. }
  68. if (bottom < screenBrightnessRangeMinimum) {
  69. screenBrightnessRangeMinimum = bottom;
  70. }
  71. mAutomaticBrightnessController = new AutomaticBrightnessController(this,
  72. handler.getLooper(), sensorManager, screenAutoBrightnessSpline,
  73. lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
  74. mScreenBrightnessRangeMaximum, dozeScaleFactor);
  75. }
  76. }
  77. mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
  78. mColorFadeFadesConfig = resources.getBoolean(
  79. com.android.internal.R.bool.config_animateScreenLights);
  80. if (!DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT) {
  81. mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
  82. if (mProximitySensor != null) {
  83. mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
  84. TYPICAL_PROXIMITY_THRESHOLD);
  85. }
  86. }
  87. }

下面我们就来分析下requestPowerState函数:

[java] view plaincopy
  1. public boolean requestPowerState(DisplayPowerRequest request,
  2. boolean waitForNegativeProximity) {
  3. if (DEBUG) {
  4. Slog.d(TAG, "requestPowerState: "
  5. + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
  6. }
  7. synchronized (mLock) {
  8. boolean changed = false;
  9. if (waitForNegativeProximity//先不分析距离传感器那块
  10. && !mPendingWaitForNegativeProximityLocked) {
  11. mPendingWaitForNegativeProximityLocked = true;
  12. changed = true;
  13. }
  14. if (mPendingRequestLocked == null) {//第一次进来
  15. mPendingRequestLocked = new DisplayPowerRequest(request);//new 一个mPendingRequestLocked 对象
  16. changed = true;
  17. } else if (!mPendingRequestLocked.equals(request)) {
  18. mPendingRequestLocked.copyFrom(request);
  19. changed = true;
  20. }
  21. if (changed) {
  22. mDisplayReadyLocked = false;//第一次进来mDisplayReadyLocked 为false
  23. }
  24. if (changed && !mPendingRequestChangedLocked) {
  25. mPendingRequestChangedLocked = true;//第一次进来,肯定走进
  26. sendUpdatePowerStateLocked();
  27. }
  28. return mDisplayReadyLocked;//返回false
  29. }
  30. }

再来看下sendUpdatePowerStateLocked函数

[java] view plaincopy
  1. private void sendUpdatePowerStateLocked() {
  2. if (!mPendingUpdatePowerStateLocked) {
  3. mPendingUpdatePowerStateLocked = true;
  4. Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
  5. msg.setAsynchronous(true);
  6. mHandler.sendMessage(msg);
  7. }
  8. }

既然这边是发送消息,那么requestPowerState就直接返回mDisplayReadyLocked了。也就是说PMS第一次调用mDisplayManagerInternal.requestPowerState,mDisplayReady 肯定为false。

[java] view plaincopy
  1. mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
  2. mRequestWaitForNegativeProximity);

那我们继续分析前面的消息

[java] view plaincopy
  1. @Override
  2. public void handleMessage(Message msg) {
  3. switch (msg.what) {
  4. case MSG_UPDATE_POWER_STATE:
  5. updatePowerState();
  6. break;

那我们接下来分析下updatePowerState函数:

[java] view plaincopy
  1. private void updatePowerState() {
  2. // Update the power state request.
  3. final boolean mustNotify;
  4. boolean mustInitialize = false;
  5. boolean autoBrightnessAdjustmentChanged = false;
  6. synchronized (mLock) {
  7. mPendingUpdatePowerStateLocked = false;
  8. if (mPendingRequestLocked == null) {
  9. return; // wait until first actual power request
  10. }
  11. if (mPowerRequest == null) {//第一次调用肯定走这
  12. mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);//建一个mPowerRequest
  13. mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
  14. mPendingWaitForNegativeProximityLocked = false;
  15. mPendingRequestChangedLocked = false;
  16. mustInitialize = true;//置true
  17. } else if (mPendingRequestChangedLocked) {
  18. autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
  19. != mPendingRequestLocked.screenAutoBrightnessAdjustment);
  20. mPowerRequest.copyFrom(mPendingRequestLocked);
  21. mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
  22. mPendingWaitForNegativeProximityLocked = false;
  23. mPendingRequestChangedLocked = false;
  24. mDisplayReadyLocked = false;
  25. }
  26. mustNotify = !mDisplayReadyLocked;
  27. }
  28. // Initialize things the first time the power state is changed.
  29. if (mustInitialize) {//第一次走必须调用
  30. initialize();
  31. }
  32. // Compute the basic display state using the policy.
  33. // We might override this below based on other factors.
  34. int state;
  35. int brightness = PowerManager.BRIGHTNESS_DEFAULT;
  36. boolean performScreenOffTransition = false;
  37. switch (mPowerRequest.policy) {// 下面分析
  38. case DisplayPowerRequest.POLICY_OFF:
  39. state = Display.STATE_OFF;
  40. performScreenOffTransition = true;
  41. break;
  42. case DisplayPowerRequest.POLICY_DOZE:
  43. if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
  44. state = mPowerRequest.dozeScreenState;
  45. } else {
  46. state = Display.STATE_DOZE;
  47. }
  48. if (!mAllowAutoBrightnessWhileDozingConfig) {
  49. brightness = mPowerRequest.dozeScreenBrightness;
  50. }
  51. break;
  52. case DisplayPowerRequest.POLICY_DIM:
  53. case DisplayPowerRequest.POLICY_BRIGHT:
  54. default:
  55. state = Display.STATE_ON;
  56. break;
  57. }
  58. assert(state != Display.STATE_UNKNOWN);
  59. // Apply the proximity sensor.
  60. if (mProximitySensor != null) {
  61. if (mPowerRequest.useProximitySensor && state != Display.STATE_OFF) {
  62. setProximitySensorEnabled(true);
  63. if (!mScreenOffBecauseOfProximity
  64. && mProximity == PROXIMITY_POSITIVE) {
  65. mScreenOffBecauseOfProximity = true;
  66. sendOnProximityPositiveWithWakelock();
  67. }
  68. } else if (mWaitingForNegativeProximity
  69. && mScreenOffBecauseOfProximity
  70. && mProximity == PROXIMITY_POSITIVE
  71. && state != Display.STATE_OFF) {
  72. setProximitySensorEnabled(true);
  73. } else {
  74. setProximitySensorEnabled(false);
  75. //mWaitingForNegativeProximity = false;
  76. }
  77. if (mScreenOffBecauseOfProximity
  78. && mProximity != PROXIMITY_POSITIVE) {
  79. mScreenOffBecauseOfProximity = false;
  80. sendOnProximityNegativeWithWakelock();
  81. }
  82. } else {
  83. mWaitingForNegativeProximity = false;
  84. }
  85. if (mScreenOffBecauseOfProximity) {
  86. state = Display.STATE_OFF;
  87. }
  88. // Animate the screen state change unless already animating.
  89. // The transition may be deferred, so after this point we will use the
  90. // actual state instead of the desired one.
  91. animateScreenStateChange(state, performScreenOffTransition);
  92. state = mPowerState.getScreenState();

initialize函数

[java] view plaincopy
  1. private void initialize() {
  2. // Initialize the power state object for the default display.
  3. // In the future, we might manage multiple displays independently.
  4. mPowerState = new DisplayPowerState(mBlanker,//新建DisplayPowerState,将mBlanker传入,传了一个背光的light
  5. mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),
  6. new ColorFade(Display.DEFAULT_DISPLAY));
  7. mColorFadeOnAnimator = ObjectAnimator.ofFloat(
  8. mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
  9. mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
  10. mColorFadeOnAnimator.addListener(mAnimatorListener);
  11. mColorFadeOffAnimator = ObjectAnimator.ofFloat(
  12. mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
  13. mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
  14. mColorFadeOffAnimator.addListener(mAnimatorListener);
  15. mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
  16. mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
  17. mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
  18. // Initialize screen state for battery stats.
  19. try {
  20. mBatteryStats.noteScreenState(mPowerState.getScreenState());
  21. mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
  22. } catch (RemoteException ex) {
  23. // same process
  24. }
  25. }

继续分析,根据传进来的mPowerRequest.policy不同,给state

[java] view plaincopy
  1. int state;
  2. int brightness = PowerManager.BRIGHTNESS_DEFAULT;
  3. boolean performScreenOffTransition = false;
  4. switch (mPowerRequest.policy) {
  5. case DisplayPowerRequest.POLICY_OFF:
  6. state = Display.STATE_OFF;
  7. performScreenOffTransition = true;
  8. break;
  9. case DisplayPowerRequest.POLICY_DOZE:
  10. if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
  11. state = mPowerRequest.dozeScreenState;
  12. } else {
  13. state = Display.STATE_DOZE;
  14. }
  15. if (!mAllowAutoBrightnessWhileDozingConfig) {
  16. brightness = mPowerRequest.dozeScreenBrightness;
  17. }
  18. break;
  19. case DisplayPowerRequest.POLICY_DIM:
  20. case DisplayPowerRequest.POLICY_BRIGHT:
  21. default:
  22. state = Display.STATE_ON;
  23. break;
  24. }
  25. assert(state != Display.STATE_UNKNOWN);

再来看看PMS这个mPowerRequest.policy值

[java] view plaincopy
  1. private boolean updateDisplayPowerStateLocked(int dirty) {
  2. final boolean oldDisplayReady = mDisplayReady;
  3. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
  4. | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
  5. | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
  6. mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();

而getDesiredScreenPolicyLocked函数如下:

[java] view plaincopy
  1. private int getDesiredScreenPolicyLocked() {
  2. if (mWakefulness == WAKEFULNESS_ASLEEP) {
  3. return DisplayPowerRequest.POLICY_OFF;
  4. }
  5. if (mWakefulness == WAKEFULNESS_DOZING) {
  6. if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
  7. return DisplayPowerRequest.POLICY_DOZE;
  8. }
  9. if (mDozeAfterScreenOffConfig) {
  10. return DisplayPowerRequest.POLICY_OFF;
  11. }
  12. // Fall through and preserve the current screen policy if not configured to
  13. // doze after screen off.  This causes the screen off transition to be skipped.
  14. }
  15. if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
  16. || (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
  17. || !mBootCompleted
  18. || mScreenBrightnessBoostInProgress) {
  19. return DisplayPowerRequest.POLICY_BRIGHT;
  20. }
  21. return DisplayPowerRequest.POLICY_DIM;
  22. }

我们再来看看animateScreenStateChange这个函数

[java] view plaincopy
  1. private void animateScreenStateChange(int target, boolean performScreenOffTransition) {
  2. // If there is already an animation in progress, don't interfere with it.
  3. if (mColorFadeOnAnimator.isStarted()
  4. || mColorFadeOffAnimator.isStarted()) {
  5. return;
  6. }
  7. // If we were in the process of turning off the screen but didn't quite
  8. // finish.  Then finish up now to prevent a jarring transition back
  9. // to screen on if we skipped blocking screen on as usual.
  10. if (mPendingScreenOff && target != Display.STATE_OFF) {// 这是灭屏动画
  11. setScreenState(Display.STATE_OFF);
  12. mPendingScreenOff = false;
  13. }
  14. if (target == Display.STATE_ON) {
  15. // Want screen on.  The contents of the screen may not yet
  16. // be visible if the color fade has not been dismissed because
  17. // its last frame of animation is solid black.
  18. if (!setScreenState(Display.STATE_ON)) {
  19. return; // screen on blocked
  20. }
  21. if (USE_COLOR_FADE_ON_ANIMATION && mPowerRequest.isBrightOrDim()) {
  22. // Perform screen on animation.
  23. if (mPowerState.getColorFadeLevel() == 1.0f) {
  24. mPowerState.dismissColorFade();
  25. } else if (mPowerState.prepareColorFade(mContext,
  26. mColorFadeFadesConfig ?
  27. ColorFade.MODE_FADE :
  28. ColorFade.MODE_WARM_UP)) {
  29. mColorFadeOnAnimator.start();
  30. } else {
  31. mColorFadeOnAnimator.end();
  32. }
  33. } else {// 这里有很多动画的东西,就不看了
  34. // Skip screen on animation.
  35. mPowerState.setColorFadeLevel(1.0f);
  36. mPowerState.dismissColorFade();
  37. }
  38. } else if (target == Display.STATE_DOZE) {
  39. // Want screen dozing.
  40. // Wait for brightness animation to complete beforehand when entering doze
  41. // from screen on to prevent a perceptible jump because brightness may operate
  42. // differently when the display is configured for dozing.
  43. if (mScreenBrightnessRampAnimator.isAnimating()
  44. && mPowerState.getScreenState() == Display.STATE_ON) {
  45. return;
  46. }
  47. // Set screen state.
  48. if (!setScreenState(Display.STATE_DOZE)) {
  49. return; // screen on blocked
  50. }
  51. // Dismiss the black surface without fanfare.
  52. mPowerState.setColorFadeLevel(1.0f);
  53. mPowerState.dismissColorFade();
  54. } else if (target == Display.STATE_DOZE_SUSPEND) {
  55. // Want screen dozing and suspended.
  56. // Wait for brightness animation to complete beforehand unless already
  57. // suspended because we may not be able to change it after suspension.
  58. if (mScreenBrightnessRampAnimator.isAnimating()
  59. && mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
  60. return;
  61. }
  62. // If not already suspending, temporarily set the state to doze until the
  63. // screen on is unblocked, then suspend.
  64. if (mPowerState.getScreenState() != Display.STATE_DOZE_SUSPEND) {
  65. if (!setScreenState(Display.STATE_DOZE)) {
  66. return; // screen on blocked
  67. }
  68. setScreenState(Display.STATE_DOZE_SUSPEND); // already on so can't block
  69. }
  70. // Dismiss the black surface without fanfare.
  71. mPowerState.setColorFadeLevel(1.0f);
  72. mPowerState.dismissColorFade();
  73. } else {
  74. // Want screen off.
  75. mPendingScreenOff = true;
  76. if (mPowerState.getColorFadeLevel() == 0.0f) {
  77. // Turn the screen off.
  78. // A black surface is already hiding the contents of the screen.
  79. setScreenState(Display.STATE_OFF);
  80. mPendingScreenOff = false;
  81. } else if (performScreenOffTransition
  82. && mPowerState.prepareColorFade(mContext,
  83. mColorFadeFadesConfig ?
  84. ColorFade.MODE_FADE : ColorFade.MODE_COOL_DOWN)
  85. && mPowerState.getScreenState() != Display.STATE_OFF) {
  86. // Perform the screen off animation.
  87. mColorFadeOffAnimator.start();
  88. } else {
  89. // Skip the screen off animation and add a black surface to hide the
  90. // contents of the screen.
  91. mColorFadeOffAnimator.end();
  92. }
  93. }
  94. }

再来看看setScreenState函数

[java] view plaincopy
  1. private boolean setScreenState(int state) {
  2. if (mPowerState.getScreenState() != state) {
  3. final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
  4. mPowerState.setScreenState(state);//调用DisplayPowerState的setScreenState函数,后面再分析
  5. // Tell battery stats about the transition.
  6. try {
  7. mBatteryStats.noteScreenState(state);//电池统计
  8. } catch (RemoteException ex) {
  9. // same process
  10. }
  11. // Tell the window manager what's happening.
  12. // Temporarily block turning the screen on until the window manager is ready
  13. // by leaving a black surface covering the screen.  This surface is essentially
  14. // the final state of the color fade animation.
  15. boolean isOn = (state != Display.STATE_OFF);
  16. if (wasOn && !isOn) {
  17. unblockScreenOn();
  18. mWindowManagerPolicy.screenTurnedOff();//通知phonewindowManager
  19. } else if (!wasOn && isOn) {
  20. if (mPowerState.getColorFadeLevel() == 0.0f) {
  21. blockScreenOn();
  22. } else {
  23. unblockScreenOn();
  24. }
  25. mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
  26. }
  27. }
  28. return mPendingScreenOnUnblocker == null;
  29. }

继续分析updatePowerState函数

[java] view plaincopy
  1. animateScreenStateChange(state, performScreenOffTransition);// 设置到mPowerState状态
  2. state = mPowerState.getScreenState();//再获取
  3. // Use zero brightness when screen is off.
  4. if (state == Display.STATE_OFF) {
  5. brightness = PowerManager.BRIGHTNESS_OFF;//根据状态,亮度设置
  6. }
  7. // Configure auto-brightness.
  8. boolean autoBrightnessEnabled = false;
  9. if (mAutomaticBrightnessController != null) {
  10. final boolean autoBrightnessEnabledInDoze = mAllowAutoBrightnessWhileDozingConfig
  11. && (state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND);
  12. autoBrightnessEnabled = mPowerRequest.useAutoBrightness
  13. && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
  14. && brightness < 0;
  15. mAutomaticBrightnessController.configure(autoBrightnessEnabled,
  16. mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
  17. }
  18. // Apply brightness boost.
  19. // We do this here after configuring auto-brightness so that we don't
  20. // disable the light sensor during this temporary state.  That way when
  21. // boost ends we will be able to resume normal auto-brightness behavior
  22. // without any delay.
  23. if (mPowerRequest.boostScreenBrightness
  24. && brightness != PowerManager.BRIGHTNESS_OFF) {
  25. brightness = PowerManager.BRIGHTNESS_ON;//boostScreenBrightness为最亮255
  26. }
  27. // Apply auto-brightness.
  28. boolean slowChange = false;
  29. if (brightness < 0) {
  30. if (autoBrightnessEnabled) {
  31. brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness();
  32. }
  33. if (brightness >= 0) {
  34. // Use current auto-brightness value and slowly adjust to changes.
  35. brightness = clampScreenBrightness(brightness);
  36. if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
  37. slowChange = true; // slowly adapt to auto-brightness
  38. }
  39. mAppliedAutoBrightness = true;
  40. } else {
  41. mAppliedAutoBrightness = false;
  42. }
  43. } else {
  44. mAppliedAutoBrightness = false;
  45. }
  46. // Use default brightness when dozing unless overridden.
  47. if (brightness < 0 && (state == Display.STATE_DOZE
  48. || state == Display.STATE_DOZE_SUSPEND)) {
  49. brightness = mScreenBrightnessDozeConfig;
  50. }
  51. // Apply manual brightness.
  52. // Use the current brightness setting from the request, which is expected
  53. // provide a nominal default value for the case where auto-brightness
  54. // is not ready yet.
  55. if (brightness < 0) {
  56. brightness = clampScreenBrightness(mPowerRequest.screenBrightness);
  57. }
  58. // Apply dimming by at least some minimum amount when user activity
  59. // timeout is about to expire.
  60. if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
  61. if (brightness > mScreenBrightnessRangeMinimum) {
  62. brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
  63. mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
  64. }
  65. if (!mAppliedDimming) {
  66. slowChange = false;
  67. }
  68. mAppliedDimming = true;
  69. }
  70. // If low power mode is enabled, cut the brightness level by half
  71. // as long as it is above the minimum threshold.
  72. if (mPowerRequest.lowPowerMode) {//低功耗模式
  73. if (brightness > mScreenBrightnessRangeMinimum) {//最小值或者当前值一半取大
  74. brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum);
  75. }
  76. if (!mAppliedLowPower) {
  77. slowChange = false;
  78. }
  79. mAppliedLowPower = true;
  80. }
  81. // Animate the screen brightness when the screen is on or dozing.
  82. // Skip the animation when the screen is off or suspended.
  83. if (!mPendingScreenOff) {//这个时候没有灭屏动画
  84. if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
  85. animateScreenBrightness(brightness,// 这个函数也是在DisplayPowerState设置亮度,待会详细分析
  86. slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
  87. } else {
  88. animateScreenBrightness(brightness, 0);
  89. }
  90. }

继续分析updatePowerState函数

[java] view plaincopy
  1. final boolean ready = mPendingScreenOnUnblocker == null
  2. && !mColorFadeOnAnimator.isStarted()
  3. && !mColorFadeOffAnimator.isStarted()
  4. && mPowerState.waitUntilClean(mCleanListener);
  5. final boolean finished = ready
  6. && !mScreenBrightnessRampAnimator.isAnimating();
  7. // Grab a wake lock if we have unfinished business.
  8. if (!finished && !mUnfinishedBusiness) {//我们这工作没有完成,持锁
  9. if (DEBUG) {
  10. Slog.d(TAG, "Unfinished business...");
  11. }
  12. mCallbacks.acquireSuspendBlocker();
  13. mUnfinishedBusiness = true;
  14. }
  15. // Notify the power manager when ready.
  16. if (ready && mustNotify) {
  17. // Send state change.
  18. synchronized (mLock) {
  19. if (!mPendingRequestChangedLocked) {
  20. mDisplayReadyLocked = true;
  21. if (DEBUG) {
  22. Slog.d(TAG, "Display ready!");
  23. }
  24. }
  25. }
  26. sendOnStateChangedWithWakelock();//完成工作后通知PMS
  27. }
  28. // Release the wake lock when we have no unfinished business.
  29. if (finished && mUnfinishedBusiness) {//完成释放锁
  30. if (DEBUG) {
  31. Slog.d(TAG, "Finished business...");
  32. }
  33. mUnfinishedBusiness = false;
  34. mCallbacks.releaseSuspendBlocker();
  35. }

先看这个mCallbacks,是PMS传进来的回调。

[java] view plaincopy
  1. mDisplayManagerInternal.initPowerManagement(
  2. mDisplayPowerCallbacks, mHandler, sensorManager);
[java] view plaincopy
  1. @Override
  2. public void acquireSuspendBlocker() {// 持锁
  3. mDisplaySuspendBlocker.acquire();
  4. }
  5. @Override
  6. public void releaseSuspendBlocker() {//释放锁
  7. mDisplaySuspendBlocker.release();
  8. }

再看看sendOnStateChangedWithWakelock函数

[java] view plaincopy
  1. private void sendOnStateChangedWithWakelock() {
  2. mCallbacks.acquireSuspendBlocker();
  3. mHandler.post(mOnStateChangedRunnable);
  4. }
[java] view plaincopy
  1. private final Runnable mOnStateChangedRunnable = new Runnable() {
  2. @Override
  3. public void run() {
  4. mCallbacks.onStateChanged();
  5. mCallbacks.releaseSuspendBlocker();
  6. }
  7. };

而PMS里的mDisplayPowerCallbacks 的onStateChanged如下

[java] view plaincopy
  1. private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
  2. new DisplayManagerInternal.DisplayPowerCallbacks() {
  3. private int mDisplayState = Display.STATE_UNKNOWN;
  4. @Override
  5. public void onStateChanged() {
  6. synchronized (mLock) {
  7. mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
  8. updatePowerStateLocked();//更新状态
  9. }
  10. }

那会重新调用到PMS的updateDisplayPowerStateLocked函数,再调用下面。

[java] view plaincopy
  1. mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
  2. mRequestWaitForNegativeProximity);

现在我们再来看,由于changed没有变化,最后返回true。

[java] view plaincopy
  1. public boolean requestPowerState(DisplayPowerRequest request,
  2. boolean waitForNegativeProximity) {
  3. if (DEBUG) {
  4. Slog.d(TAG, "requestPowerState: "
  5. + request + ", waitForNegativeProximity=" + waitForNegativeProximity);
  6. }
  7. synchronized (mLock) {
  8. boolean changed = false;
  9. if (waitForNegativeProximity
  10. && !mPendingWaitForNegativeProximityLocked) {
  11. mPendingWaitForNegativeProximityLocked = true;
  12. changed = true;
  13. }
  14. if (mPendingRequestLocked == null) {
  15. mPendingRequestLocked = new DisplayPowerRequest(request);
  16. changed = true;
  17. } else if (!mPendingRequestLocked.equals(request)) {
  18. mPendingRequestLocked.copyFrom(request);
  19. changed = true;
  20. }
  21. if (changed) {
  22. mDisplayReadyLocked = false;
  23. }
  24. if (changed && !mPendingRequestChangedLocked) {
  25. mPendingRequestChangedLocked = true;
  26. sendUpdatePowerStateLocked();
  27. }
  28. return mDisplayReadyLocked;//changed没有变化直接返回,updatePowerState函数中已经将mDisplayReadyLocked置为true
  29. }
  30. }

那我们现在分析下,DisplayPowerController与DisplayPowerState的交互:

先来看下DisplayPowerController里的setScreenState函数,其中调用了DisplayPowerState的setScreenState函数

[java] view plaincopy
  1. private boolean setScreenState(int state) {
  2. if (mPowerState.getScreenState() != state) {
  3. final boolean wasOn = (mPowerState.getScreenState() != Display.STATE_OFF);
  4. mPowerState.setScreenState(state);
  5. // Tell battery stats about the transition.
  6. try {
  7. mBatteryStats.noteScreenState(state);
  8. } catch (RemoteException ex) {
  9. // same process
  10. }
  11. // Tell the window manager what's happening.
  12. // Temporarily block turning the screen on until the window manager is ready
  13. // by leaving a black surface covering the screen.  This surface is essentially
  14. // the final state of the color fade animation.
  15. boolean isOn = (state != Display.STATE_OFF);
  16. if (wasOn && !isOn) {
  17. unblockScreenOn();
  18. mWindowManagerPolicy.screenTurnedOff();
  19. } else if (!wasOn && isOn) {
  20. if (mPowerState.getColorFadeLevel() == 0.0f) {
  21. blockScreenOn();
  22. } else {
  23. unblockScreenOn();
  24. }
  25. mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker);
  26. }
  27. }
  28. return mPendingScreenOnUnblocker == null;
  29. }

DisplayPowerController中调用DisplayPowerState的setScreenBrightness函数不是直接调用的,而是通过泛型技术调用的,这里就不讲了,感兴趣可以自己去细看。

[java] view plaincopy
  1. private void animateScreenBrightness(int target, int rate) {
  2. if (DEBUG) {
  3. Slog.d(TAG, "Animating brightness: target=" + target +", rate=" + rate);
  4. }
  5. if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {//泛型技术,最后调用了DisplayPowerState的setScreenBrightness函数
  6. try {
  7. mBatteryStats.noteScreenBrightness(target);
  8. } catch (RemoteException ex) {
  9. // same process
  10. }
  11. }
  12. }

再来看看DisplayPowerState的setScreenState函数,和setScreenBrightness

[java] view plaincopy
  1. public void setScreenBrightness(int brightness) {
  2. if (mScreenBrightness != brightness) {
  3. if (DEBUG) {
  4. Slog.d(TAG, "setScreenBrightness: brightness=" + brightness);
  5. }
  6. mScreenBrightness = brightness;
  7. if (mScreenState != Display.STATE_OFF) {
  8. mScreenReady = false;
  9. scheduleScreenUpdate();
  10. }
  11. }
  12. }

setScreenState函数,两者后面都是调用了scheduleScreenUpdate函数

[java] view plaincopy
  1. public void setScreenState(int state) {
  2. if (mScreenState != state) {
  3. if (DEBUG) {
  4. Slog.d(TAG, "setScreenState: state=" + state);
  5. }
  6. mScreenState = state;
  7. mScreenReady = false;
  8. scheduleScreenUpdate();
  9. }
  10. }
[java] view plaincopy
  1. private void scheduleScreenUpdate() {
  2. if (!mScreenUpdatePending) {
  3. mScreenUpdatePending = true;
  4. postScreenUpdateThreadSafe();
  5. }
  6. }
  7. private void postScreenUpdateThreadSafe() {
  8. mHandler.removeCallbacks(mScreenUpdateRunnable);
  9. mHandler.post(mScreenUpdateRunnable);
  10. }

利用消息机制的post函数

[java] view plaincopy
  1. private final Runnable mScreenUpdateRunnable = new Runnable() {
  2. @Override
  3. public void run() {
  4. mScreenUpdatePending = false;
  5. int brightness = mScreenState != Display.STATE_OFF
  6. && mColorFadeLevel > 0f ? mScreenBrightness : 0;
  7. if (mPhotonicModulator.setState(mScreenState, brightness)) {//下面主要分析这个
  8. if (DEBUG) {
  9. Slog.d(TAG, "Screen ready");
  10. }
  11. mScreenReady = true;
  12. invokeCleanListenerIfNeeded();
  13. } else {
  14. if (DEBUG) {
  15. Slog.d(TAG, "Screen not ready");
  16. }
  17. }
  18. }
  19. };

下面就是PhotonicModulator的setState函数,这个类是一个线程,在构造函数里面start

[java] view plaincopy
  1. public boolean setState(int state, int backlight) {
  2. synchronized (mLock) {
  3. if (state != mPendingState || backlight != mPendingBacklight) {
  4. if (DEBUG) {
  5. Slog.d(TAG, "Requesting new screen state: state="
  6. + Display.stateToString(state) + ", backlight=" + backlight);
  7. }
  8. mPendingState = state;
  9. mPendingBacklight = backlight;
  10. if (!mChangeInProgress) {
  11. mChangeInProgress = true;
  12. mLock.notifyAll();//通知
  13. }
  14. }
  15. return !mChangeInProgress;
  16. }
  17. }

下面是DisplayPowerState的构造函数,其实例在DisplayPowerController中新建

[java] view plaincopy
  1. public DisplayPowerState(DisplayBlanker blanker, Light backlight, ColorFade electronBeam) {
  2. mHandler = new Handler(true /*async*/);
  3. mChoreographer = Choreographer.getInstance();
  4. mBlanker = blanker;
  5. mBacklight = backlight;
  6. mColorFade = electronBeam;
  7. mPhotonicModulator = new PhotonicModulator();
  8. mPhotonicModulator.start();//开启线程
  9. // At boot time, we know that the screen is on and the electron beam
  10. // animation is not playing.  We don't know the screen's brightness though,
  11. // so prepare to set it to a known state when the state is next applied.
  12. // Although we set the brightness to full on here, the display power controller
  13. // will reset the brightness to a new level immediately before the changes
  14. // actually have a chance to be applied.
  15. mScreenState = Display.STATE_ON;
  16. mScreenBrightness = PowerManager.BRIGHTNESS_ON;
  17. scheduleScreenUpdate();
  18. mColorFadePrepared = false;
  19. mColorFadeLevel = 1.0f;
  20. mColorFadeReady = true;
  21. }

我们再来分析下PhotonicModulator的run函数

[java] view plaincopy
  1. @Override
  2. public void run() {
  3. for (;;) {
  4. // Get pending change.
  5. final int state;
  6. final boolean stateChanged;
  7. final int backlight;
  8. final boolean backlightChanged;
  9. synchronized (mLock) {
  10. state = mPendingState;
  11. stateChanged = (state != mActualState);
  12. backlight = mPendingBacklight;
  13. backlightChanged = (backlight != mActualBacklight);
  14. if (!stateChanged && !backlightChanged) {
  15. // All changed applied, notify outer class and wait for more.
  16. mChangeInProgress = false;
  17. postScreenUpdateThreadSafe();
  18. try {
  19. mLock.wait();//一直等待,直到setState有改变会notifyAll
  20. } catch (InterruptedException ex) { }
  21. continue;
  22. }
  23. mActualState = state;
  24. mActualBacklight = backlight;
  25. }
  26. // Apply pending change.
  27. if (DEBUG) {
  28. Slog.d(TAG, "Updating screen state: state="
  29. + Display.stateToString(state) + ", backlight=" + backlight);
  30. }
  31. boolean suspending = Display.isSuspendedState(state);
  32. if (stateChanged && !suspending) {
  33. Slog.d(TAG, "Updating screen state: state = " + Display.stateToString(state));
  34. requestDisplayState(state);//下面详细分析
  35. }
  36. if (backlightChanged) {
  37. Slog.d(TAG, "Updating screen backlight = " + backlight);
  38. setBrightness(backlight);
  39. }
  40. if (stateChanged && suspending) {
  41. Slog.d(TAG, "Updating screen state: state = " + Display.stateToString(state));
  42. requestDisplayState(state);
  43. }
  44. }
  45. }

requestDisplayState函数

[java] view plaincopy
  1. private void requestDisplayState(int state) {
  2. Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
  3. + Display.stateToString(state) + ")");
  4. try {
  5. mBlanker.requestDisplayState(state);
  6. } finally {
  7. Trace.traceEnd(Trace.TRACE_TAG_POWER);
  8. }
  9. }

是DisplayManagerService中的blanker的requestDisplayState函数,然后将这个blanker传给了DisplayPowerController,再传给DisplayPowerState

[java] view plaincopy
  1. private final class LocalService extends DisplayManagerInternal {
  2. @Override
  3. public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
  4. SensorManager sensorManager) {
  5. synchronized (mSyncRoot) {
  6. DisplayBlanker blanker = new DisplayBlanker() {
  7. @Override
  8. public void requestDisplayState(int state) {
  9. // The order of operations is important for legacy reasons.
  10. if (state == Display.STATE_OFF) {
  11. requestGlobalDisplayStateInternal(state);
  12. }
  13. callbacks.onDisplayStateChange(state);//回调到PMS中的onDisplayStateChange
  14. if (state != Display.STATE_OFF) {
  15. requestGlobalDisplayStateInternal(state);
  16. }
  17. }
  18. };
  19. mDisplayPowerController = new DisplayPowerController(
  20. mContext, callbacks, handler, sensorManager, blanker);
  21. }
  22. }

PMS的DisplayManagerInternal.DisplayPowerCallbacks的onDisplayStateChange函数

[java] view plaincopy
  1. @Override
  2. public void onDisplayStateChange(int state) {
  3. // This method is only needed to support legacy display blanking behavior
  4. // where the display's power state is coupled to suspend or to the power HAL.
  5. // The order of operations matters here.
  6. synchronized (mLock) {
  7. if (mDisplayState != state) {
  8. mDisplayState = state;
  9. if (state == Display.STATE_OFF) {
  10. if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
  11. setHalInteractiveModeLocked(false);//JNI处理cpu频率等
  12. }
  13. if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
  14. setHalAutoSuspendModeLocked(true);//设置为true,让系统自动休眠。
  15. }
  16. } else {
  17. if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
  18. setHalAutoSuspendModeLocked(false);
  19. }
  20. if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
  21. setHalInteractiveModeLocked(true);
  22. }
  23. }
  24. }
  25. }

再来看看DisplayPowerState的setBrightness函数

[java] view plaincopy
  1. private void setBrightness(int backlight) {
  2. Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")");
  3. try {
  4. mBacklight.setBrightness(backlight);//mBckLight是DisplayPowerController传进来的
  5. } finally {
  6. Trace.traceEnd(Trace.TRACE_TAG_POWER);
  7. }
  8. }

DisplayPowerController新建DisplayPowerState对象

[java] view plaincopy
  1. mPowerState = new DisplayPowerState(mBlanker,
  2. mLights.getLight(LightsManager.LIGHT_ID_BACKLIGHT),//传入mBacklight
  3. new ColorFade(Display.DEFAULT_DISPLAY));

getLight函数是从light数组里面选一个light

[java] view plaincopy
  1. private final LightsManager mService = new LightsManager() {
  2. @Override
  3. public com.android.server.lights.Light getLight(int id) {
  4. if (id < LIGHT_ID_COUNT) {
  5. return mLights[id];
  6. } else {
  7. return null;
  8. }
  9. }
  10. };

light类,设置亮度会把自己的一个id号,传下去

[java] view plaincopy
  1. private final class LightImpl extends Light {
  2. private LightImpl(int id) {
  3. mId = id;
  4. }
  5. @Override
  6. public void setBrightness(int brightness) {
  7. setBrightness(brightness, BRIGHTNESS_MODE_USER);
  8. }
  9. @Override
  10. public void setBrightness(int brightness, int brightnessMode) {
  11. synchronized (this) {
  12. int color = brightness & 0x000000ff;
  13. color = 0xff000000 | (color << 16) | (color << 8) | color;
  14. setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
  15. }
  16. }

最后调用setLightLocked,会将该light的id传下去,最后调用setLight_native来完成最后的设置亮度。

[java] view plaincopy
  1. private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
  2. if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
  3. if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
  4. + Integer.toHexString(color));
  5. mColor = color;
  6. mMode = mode;
  7. mOnMS = onMS;
  8. mOffMS = offMS;
  9. Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", " + color + ")");
  10. try {
  11. setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
  12. } finally {
  13. Trace.traceEnd(Trace.TRACE_TAG_POWER);
  14. }
  15. }
  16. }

接下来我们继续分析上一篇博客的PMS里的updatePowerStateLocked函数

[java] view plaincopy
  1. // Phase 2: Update display power state.
  2. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//第一次返回为false
  3. // Phase 3: Update dream state (depends on display ready signal).
  4. updateDreamLocked(dirtyPhase2, displayBecameReady);
  5. // Phase 4: Send notifications, if needed.
  6. if (mDisplayReady) {
  7. finishWakefulnessChangeLocked();
  8. }
  9. // Phase 5: Update suspend blocker.
  10. // Because we might release the last suspend blocker here, we need to make sure
  11. // we finished everything else first!
  12. updateSuspendBlockerLocked();

先看updateDreamLocked函数,mDisplayReady为false,所以跳出

[java] view plaincopy
  1. private void updateDreamLocked(int dirty, boolean displayBecameReady) {
  2. if ((dirty & (DIRTY_WAKEFULNESS
  3. | DIRTY_USER_ACTIVITY
  4. | DIRTY_WAKE_LOCKS
  5. | DIRTY_BOOT_COMPLETED
  6. | DIRTY_SETTINGS
  7. | DIRTY_IS_POWERED
  8. | DIRTY_STAY_ON
  9. | DIRTY_PROXIMITY_POSITIVE
  10. | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
  11. if (mDisplayReady) {
  12. scheduleSandmanLocked();
  13. }
  14. }
  15. }

这样我们直接分析updateSuspendBlockerLocked

[java] view plaincopy
  1. private void updateSuspendBlockerLocked() {
  2. final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//看cpu是否要持锁
  3. final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();//现在Display没好,需要持Display的锁
  4. final boolean autoSuspend = !needDisplaySuspendBlocker;
  5. final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
  6. // Disable auto-suspend if needed.
  7. // FIXME We should consider just leaving auto-suspend enabled forever since
  8. // we already hold the necessary wakelocks.
  9. if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
  10. setHalAutoSuspendModeLocked(false);//调用JNI,具体还要分析
  11. }
  12. // First acquire suspend blockers if needed.
  13. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
  14. mWakeLockSuspendBlocker.acquire();//持cpu锁
  15. mHoldingWakeLockSuspendBlocker = true;
  16. }
  17. if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
  18. mDisplaySuspendBlocker.acquire();//持Display锁
  19. mHoldingDisplaySuspendBlocker = true;
  20. }
  21. // Inform the power HAL about interactive mode.
  22. // Although we could set interactive strictly based on the wakefulness
  23. // as reported by isInteractive(), it is actually more desirable to track
  24. // the display policy state instead so that the interactive state observed
  25. // by the HAL more accurately tracks transitions between AWAKE and DOZING.
  26. // Refer to getDesiredScreenPolicyLocked() for details.
  27. if (mDecoupleHalInteractiveModeFromDisplayConfig) {
  28. // When becoming non-interactive, we want to defer sending this signal
  29. // until the display is actually ready so that all transitions have
  30. // completed.  This is probably a good sign that things have gotten
  31. // too tangled over here...
  32. if (interactive || mDisplayReady) {
  33. setHalInteractiveModeLocked(interactive);//JNI,修改cpu频率等
  34. }
  35. }
  36. // Then release suspend blockers if needed.
  37. if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
  38. mWakeLockSuspendBlocker.release();//解锁
  39. mHoldingWakeLockSuspendBlocker = false;
  40. }
  41. if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
  42. mDisplaySuspendBlocker.release();
  43. mHoldingDisplaySuspendBlocker = false;
  44. }
  45. // Enable auto-suspend if needed.
  46. if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
  47. setHalAutoSuspendModeLocked(true);//设置true,让系统可以自动睡眠。
  48. }
  49. }

needDisplaySuspendBlockerLocked函数mDisplayReady为false,直接返回true

[java] view plaincopy
  1. private boolean needDisplaySuspendBlockerLocked() {
  2. if (!mDisplayReady) {
  3. return true;
  4. }
  5. if (mDisplayPowerRequest.isBrightOrDim()) {
  6. // If we asked for the screen to be on but it is off due to the proximity
  7. // sensor then we may suspend but only if the configuration allows it.
  8. // On some hardware it may not be safe to suspend because the proximity
  9. // sensor may not be correctly configured as a wake-up source.
  10. if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
  11. || !mSuspendWhenScreenOffDueToProximityConfig) {
  12. return true;
  13. }
  14. }
  15. if (mScreenBrightnessBoostInProgress) {
  16. return true;
  17. }
  18. // Let the system suspend if the screen is off or dozing.
  19. return false;
  20. }

这样PMS刚调mDisplayManagerInternal.requestPowerState的时候,返回mDisplayReady为false,最后也就会持Display的锁,其它也没有别的了。

直到Display准备好,回调函数直接又调用updatePowerStateLocked函数,再调用updateDisplayPowerStateLocked函数,返回mDisplayReady为true。

那我们继续分析updatePowerStateLocked函数:

[java] view plaincopy
  1. updateDreamLocked(dirtyPhase2, displayBecameReady);
  2. // Phase 4: Send notifications, if needed.
  3. if (mDisplayReady) {
  4. finishWakefulnessChangeLocked();
  5. }
  6. // Phase 5: Update suspend blocker.
  7. // Because we might release the last suspend blocker here, we need to make sure
  8. // we finished everything else first!
  9. updateSuspendBlockerLocked();

updateDreamLocked函数发送消息

[java] view plaincopy
  1. private void updateDreamLocked(int dirty, boolean displayBecameReady) {
  2. if ((dirty & (DIRTY_WAKEFULNESS
  3. | DIRTY_USER_ACTIVITY
  4. | DIRTY_WAKE_LOCKS
  5. | DIRTY_BOOT_COMPLETED
  6. | DIRTY_SETTINGS
  7. | DIRTY_IS_POWERED
  8. | DIRTY_STAY_ON
  9. | DIRTY_PROXIMITY_POSITIVE
  10. | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
  11. if (mDisplayReady) {
  12. scheduleSandmanLocked();
  13. }
  14. }
  15. }
  16. private void scheduleSandmanLocked() {
  17. if (!mSandmanScheduled) {
  18. mSandmanScheduled = true;
  19. Message msg = mHandler.obtainMessage(MSG_SANDMAN);
  20. msg.setAsynchronous(true);
  21. mHandler.sendMessage(msg);
  22. }
  23. }

消息最后处理的函数是handleSandman,goToSleepNoUpdateLocked和napNoUpdateLocked函数才会把mSandmanSummoned = true;

[java] view plaincopy
  1. private void handleSandman() { // runs on handler thread
  2. // Handle preconditions.
  3. final boolean startDreaming;
  4. final int wakefulness;
  5. synchronized (mLock) {
  6. mSandmanScheduled = false;
  7. wakefulness = mWakefulness;
  8. if (mSandmanSummoned && mDisplayReady) {//mSandmanSummoned为donzing状态和dreaming状态的时候才为true
  9. startDreaming = canDreamLocked() || canDozeLocked();//canDozeLocked函数只要wakefulness == WAKEFULNESS_DOZING就true
  10. mSandmanSummoned = false;
  11. } else {
  12. startDreaming = false;
  13. }
  14. }
  15. // Start dreaming if needed.
  16. // We only control the dream on the handler thread, so we don't need to worry about
  17. // concurrent attempts to start or stop the dream.
  18. final boolean isDreaming;
  19. if (mDreamManager != null) {
  20. // Restart the dream whenever the sandman is summoned.
  21. if (startDreaming) {//为true才开始做梦
  22. mDreamManager.stopDream(false /*immediate*/);
  23. mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
  24. }
  25. isDreaming = mDreamManager.isDreaming();
  26. } else {
  27. isDreaming = false;
  28. }
  29. // Update dream state.
  30. synchronized (mLock) {
  31. // Remember the initial battery level when the dream started.
  32. if (startDreaming && isDreaming) {
  33. mBatteryLevelWhenDreamStarted = mBatteryLevel;
  34. if (wakefulness == WAKEFULNESS_DOZING) {
  35. Slog.i(TAG, "Dozing...");
  36. } else {
  37. Slog.i(TAG, "Dreaming...");
  38. }
  39. }
  40. // If preconditions changed, wait for the next iteration to determine
  41. // whether the dream should continue (or be restarted).
  42. if (mSandmanSummoned || mWakefulness != wakefulness) {
  43. return; // wait for next cycle
  44. }
  45. // Determine whether the dream should continue.
  46. if (wakefulness == WAKEFULNESS_DREAMING) {
  47. if (isDreaming && canDreamLocked()) {//正在做梦
  48. if (mDreamsBatteryLevelDrainCutoffConfig >= 0
  49. && mBatteryLevel < mBatteryLevelWhenDreamStarted
  50. - mDreamsBatteryLevelDrainCutoffConfig
  51. && !isBeingKeptAwakeLocked()) {//满足条件,做梦结束
  52. // If the user activity timeout expired and the battery appears
  53. // to be draining faster than it is charging then stop dreaming
  54. // and go to sleep.
  55. Slog.i(TAG, "Stopping dream because the battery appears to "
  56. + "be draining faster than it is charging.  "
  57. + "Battery level when dream started: "
  58. + mBatteryLevelWhenDreamStarted + "%.  "
  59. + "Battery level now: " + mBatteryLevel + "%.");
  60. } else {//继续做梦
  61. return; // continue dreaming
  62. }
  63. }
  64. // Dream has ended or will be stopped.  Update the power state.
  65. if (isItBedTimeYetLocked()) {//该睡觉了
  66. goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
  67. PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
  68. updatePowerStateLocked();
  69. } else {//否则直接唤醒
  70. wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
  71. updatePowerStateLocked();
  72. }
  73. } else if (wakefulness == WAKEFULNESS_DOZING) {//WAKEFULNESS_DOZING和WAKEFULNESS_DREAMING都可以做梦
  74. if (isDreaming) {
  75. return; // continue dozing
  76. }
  77. // Doze has ended or will be stopped.  Update the power state.
  78. reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);//直接到sleep状态
  79. updatePowerStateLocked();
  80. }
  81. }
  82. // Stop dream.
  83. if (isDreaming) {
  84. mDreamManager.stopDream(false /*immediate*/);
  85. }
  86. }

继续分析updatePowerStateLocked函数

[java] view plaincopy
  1. if (mDisplayReady) {
  2. finishWakefulnessChangeLocked();
  3. }
  4. // Phase 5: Update suspend blocker.
  5. // Because we might release the last suspend blocker here, we need to make sure
  6. // we finished everything else first!
  7. updateSuspendBlockerLocked();

Display完成后,可以finishWakefulnessChangeLocked函数,在之前的PMS的博客分析过了。这里是屏幕灭屏之前通知PhoneWindowManager,电池统计等。

updateSuspendBlockerLocked函数之前分析过了,就不再分析了就是一个持锁,和调JNI设置cpu频率,还有一个autoSuspend是自动让系统睡眠,如果开启就设true。

and5.1PowerManagerService深入分析(四)PMS与Display模块相关推荐

  1. and5.1PowerManagerService深入分析(三)updatePowerStateLocked函数

    PMS更新各个状态,最终都会调用updatePowerStateLocked函数,下面我们来分析下 private void updatePowerStateLocked() {if (!mSyste ...

  2. Pygame详解(二):display 模块

    pygame.display Pygame 中用于控制窗口和屏幕显示的模块. 注:为了适应语境,display 在该文档中有时翻译为"显示",有时翻译为"显示界面&quo ...

  3. Stduino学习(二十四)敲击传感器模块

    37种传感器(二十四)敲击传感器模块+Stduino Nano&UNO 本文转载自:http://www.stduino.com/forum.php?mod=viewthread&ti ...

  4. Pygame详解(四):event 模块(有USEREVENT事件)

    pygame.event 用于处理事件与事件队列的 Pygame 模块. 函数 pygame.event.pump()  -  让 Pygame 内部自动处理事件 pygame.event.get() ...

  5. 凯云水利水电工程造价系统 (四) 配合比单价模块

    凯云水利水电工程造价系统  (四) 配合比单价模块 3.6-1功能实现 配合比单价的数据处理有:添加.批量修改.从定额导入.删除.复制.粘贴.导入.导出. 配合比单价的添加.批量修改.删除:点击添加会 ...

  6. pygame中display模块方法详解

    目录 pygame.display.init() pygame.display.quit() pygame.display.get_init() pygame.display.set_mode() p ...

  7. 四、Ansible文件模块库与模板

    一.Ansible描述文件模块 files模块库的引入 模块库:根据文档中的功能以及系统上的安装时间进行分组后的模块的集合 Files模块库包含的模块允许您完成与Linux文件管理相关的大多数任务,如 ...

  8. python第四十九天--paramiko模块安装大作战

    准备开始学习:paramiko模块,发现这个模块十分难搞 安装不上 搞了半天,win10 64下 pytyon 3.6 的 paramiko模块 死活安不上,在网上不断的找资料,可是没有用,没有用啊 ...

  9. 网络协议栈深入分析(四)--套接字内核初始化和创建过程

    1.系统初始化过程中会调用sock_init函数进行套接字的初始化,主要是进行缓存的初始化 [cpp] view plaincopy static int __init sock_init(void) ...

最新文章

  1. Sublime text3 快捷方式(windows平台)
  2. [CTSC2018]混合果汁 二分 套 主席树上二分
  3. React入门:从零搭建一个React项目
  4. MySQL教程(三)—— MySQL的安装与配置
  5. archlinux yaourt安装 以及出错细节 database file for archlinuxfr does not exist.
  6. 从外包月薪5K到阿里月薪15K,原理+实战+视频+源码
  7. Kubernetes端到端解决方案Part3:如何正确部署Kubernetes
  8. Matlab--max,min函数的用法
  9. PHP目前比较常见的五大运行模式
  10. v-for 循环 绑定对象 和数组
  11. unity中的rigibody 和 collider 讲解
  12. PHP异步调用实现方式
  13. 《树莓派开发实战(第2版)》——1.2 封装树莓派
  14. 【BIEE】14_开发流程介绍
  15. Mybatis框架源码笔记(一)之编译Mybatis源码和源码调试环境准备
  16. 以太坊中的GHOST协议
  17. 怎么设置html z值,正态分布1.96 统计学,Z=1.96怎么来的
  18. 中国GDP与百姓收入
  19. 让机器人更安全——(5.总结与展望)
  20. php网络图片拼接,图片处理 - PHP图片拼接如何高效的实现

热门文章

  1. 接 嵌入式设备上的Linux系统开发
  2. python求无序列表中位数_详解Python如何获取列表(List)的中位数
  3. python爬取网页停止_Python爬虫之爬取静态网页
  4. Vue学习笔记之06-响应式的数组方法
  5. html页面画一个矩形,使用HTML5 canvas绘制一个矩形的方法
  6. 果园机器人的写作思路_《果园机器人》三年级教学设计
  7. Android图片完整性检验,Android安全测试之应用完整性校验检测
  8. cjuiautocomplete ajax,Yii CJuiAutoComplete小部件:空响应消息事件
  9. 冰原服务器维护,12月2日服务器公告 冰原旅途进发
  10. 用户名登陆时如何在后面加一个小红*_最后一个登陆框引起的血案