赞
踩
主要在PowerManagerService.java,根据系统状态更新下次update的时间,遍历wakelock状态更新显示状态等
根据MDRTY中记录的脏位更新全局电源状态。这是执行电源状态转换的主要功能。我们将它们集中在这里,这样每当重要的事情发生变化时,我们就可以完全重新计算权力状态,并确保每次都以同样的方式进行。重点是在这里收集所有的转换逻辑。
- /**
- * Updates the global power state based on dirty bits recorded in mDirty.
- *
- * This is the main function that performs power state transitions.
- * We centralize them here so that we can recompute the power state completely
- * each time something important changes, and ensure that we do it the same
- * way each time. The point is to gather all of the transition logic here.
- */
- private void updatePowerStateLocked() {
- if (!mSystemReady || mDirty == 0) {
- return;
- }
- if (!Thread.holdsLock(mLock)) {
- Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
- try {
- // Phase 0: Basic state updates.
- updateIsPoweredLocked(mDirty);
- updateStayOnLocked(mDirty);
- updateScreenBrightnessBoostLocked(mDirty);
-
- // Phase 1: Update wakefulness.
- // Loop because the wake lock and user activity computations are influenced
- // by changes in wakefulness.
- final long now = mClock.uptimeMillis();
- int dirtyPhase2 = 0;
- for (;;) {
- int dirtyPhase1 = mDirty;
- dirtyPhase2 |= dirtyPhase1;
- mDirty = 0;
-
- updateWakeLockSummaryLocked(dirtyPhase1);
- updateUserActivitySummaryLocked(now, dirtyPhase1);
- updateAttentiveStateLocked(now, dirtyPhase1);
- if (!updateWakefulnessLocked(dirtyPhase1)) {
- break;
- }
- }
-
- // Phase 2: Lock profiles that became inactive/not kept awake.
- updateProfilesLocked(now);
-
- // Phase 3: Update display power state.
- final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
-
- // Phase 4: Update dream state (depends on display ready signal).
- updateDreamLocked(dirtyPhase2, displayBecameReady);
-
- // Phase 5: Send notifications, if needed.
- finishWakefulnessChangeIfNeededLocked();
-
- // Phase 6: Update suspend blocker.
- // Because we might release the last suspend blocker here, we need to make sure
- // we finished everything else first!
- updateSuspendBlockerLocked();
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }

a、函数updateIsPoweredLocked
有需要时更新电池状态 DIRTY_BATTERY_STATE
b、函数updateStayOnLocked
DIRTY_STAY_ON
c、函数updateScreenBrightnessBoostLocked
DIRTY_SCREEN_BRIGHTNESS_BOOST
a、函数updateWakeLockSummaryLocked
更新mWakeLockSummary的值,以汇总所有活动唤醒锁的状态。请注意,当系统处于睡眠状态时,大多数唤醒锁都会被忽略。DIRTY_WAKE_LOCKS
b、函数updateUserActivitySummaryLocked
更新mUserActivitySummary的值,以总结用户请求的系统状态,例如屏幕是亮还是暗。 请注意,当系统处于睡眠状态时,用户活动将被忽略 DIRTY_USER_ACTIVITY
c、函数updateAttentiveStateLocked
d、函数updateWakefulnessLocked
该功能根据当前唤醒锁和用户活动状态决定设备是否应该开始做梦。如果清醒状态发生变化,它可能会修改MDRTY。如果唤醒状态发生变化,需要重新启动电源状态计算,则返回true
函数updateProfilesLocked
检查配置文件超时并通知应锁定的配置文件
函数updateDisplayPowerStateLocked
异步更新显示电源状态。更新完成后,mDisplayReady将设置为true。显示控制器会发布一条消息,告诉我们实际的显示电源状态何时已更新,所以我们回到这里再次检查并完成。此函数每次都会重新计算显示电源状态。
return True,如果显示就绪。
函数updateDreamLocked
确定是否向sandman发布消息以更新梦境状态。
函数finishWakefulnessChangeIfNeededLocked
因为我们可能会在这里释放最后一个暂停阻止程序,所以我们需要确保先完成其他所有操作!
函数updateSuspendBlockerLocked
主要在DisplayPowerController.java中更新设备状态,在LightsService.java中为实际的操作
获取从PowerManagerService传来的DisplayPowerRequest状态,实时更新背光状态,显示屏状态。
主要包括使用POLICY决定显示状态和拨打电话时距离传感器影响显示状态
- int state;
- float brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- 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) {
- brightnessState = mPowerRequest.dozeScreenBrightness;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
- }
- break;
- case DisplayPowerRequest.POLICY_VR:
- state = Display.STATE_VR;
- 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) {
- // At this point the policy says that the screen should be on, but we've been
- // asked to listen to the prox sensor to adjust the display state, so lets make
- // sure the sensor is on.
- setProximitySensorEnabled(true);
- if (!mScreenOffBecauseOfProximity
- && mProximity == PROXIMITY_POSITIVE
- && !mIgnoreProximityUntilChanged) {
- // Prox sensor already reporting "near" so we should turn off the screen.
- // Also checked that we aren't currently set to ignore the proximity sensor
- // temporarily.
- mScreenOffBecauseOfProximity = true;
- sendOnProximityPositiveWithWakelock();
- }
- } else if (mWaitingForNegativeProximity
- && mScreenOffBecauseOfProximity
- && mProximity == PROXIMITY_POSITIVE
- && state != Display.STATE_OFF) {
- // The policy says that we should have the screen on, but it's off due to the prox
- // and we've been asked to wait until the screen is far from the user to turn it
- // back on. Let keep the prox sensor on so we can tell when it's far again.
- setProximitySensorEnabled(true);
- } else {
- // We haven't been asked to use the prox sensor and we're not waiting on the screen
- // to turn back on...so lets shut down the prox sensor.
- setProximitySensorEnabled(false);
- mWaitingForNegativeProximity = false;
- }
-
- if (mScreenOffBecauseOfProximity
- && (mProximity != PROXIMITY_POSITIVE || mIgnoreProximityUntilChanged)) {
- // The screen *was* off due to prox being near, but now it's "far" so lets turn
- // the screen back on. Also turn it back on if we've been asked to ignore the
- // prox sensor temporarily.
- mScreenOffBecauseOfProximity = false;
- sendOnProximityNegativeWithWakelock();
- }
- } else {
- mWaitingForNegativeProximity = false;
- mIgnoreProximityUntilChanged = 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.
- final int oldState = mPowerState.getScreenState();
- animateScreenStateChange(state, performScreenOffTransition);
- state = mPowerState.getScreenState();
-
- if (state == Display.STATE_OFF) {
- brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
- }
-
- // Always use the VR brightness when in the VR state.
- if (state == Display.STATE_VR) {
- brightnessState = mScreenBrightnessForVr;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
- }

主要包括正常情况下的亮度、光传感器自动调节时的亮度、DIM下的亮度、低电量下的亮度等等
- if ((Float.isNaN(brightnessState))
- && isValidBrightnessValue(mPowerRequest.screenBrightnessOverride)) {
- brightnessState = mPowerRequest.screenBrightnessOverride;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
- mAppliedScreenBrightnessOverride = true;
- } else {
- mAppliedScreenBrightnessOverride = false;
- }
-
- final boolean autoBrightnessEnabledInDoze =
- mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
- final boolean autoBrightnessEnabled = mPowerRequest.useAutoBrightness
- && (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
- && Float.isNaN(brightnessState)
- && mAutomaticBrightnessController != null;
-
- final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
-
- // Use the temporary screen brightness if there isn't an override, either from
- // WindowManager or based on the display state.
- if (isValidBrightnessValue(mTemporaryScreenBrightness)) {
- brightnessState = mTemporaryScreenBrightness;
- mAppliedTemporaryBrightness = true;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
- } else {
- mAppliedTemporaryBrightness = false;
- }
-
- final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment();
- if (autoBrightnessAdjustmentChanged) {
- mTemporaryAutoBrightnessAdjustment = Float.NaN;
- }
-
- // Use the autobrightness adjustment override if set.
- final float autoBrightnessAdjustment;
- if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
- autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
- brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
- mAppliedTemporaryAutoBrightnessAdjustment = true;
- } else {
- autoBrightnessAdjustment = mAutoBrightnessAdjustment;
- brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
- mAppliedTemporaryAutoBrightnessAdjustment = false;
- }
- // Apply brightness boost.
- // We do this here after deciding whether auto-brightness is enabled 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
- && brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT) {
- brightnessState = PowerManager.BRIGHTNESS_MAX;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
- mAppliedBrightnessBoost = true;
- } else {
- mAppliedBrightnessBoost = false;
- }
-
- // If the brightness is already set then it's been overridden by something other than the
- // user, or is a temporary adjustment.
- boolean userInitiatedChange = (Float.isNaN(brightnessState))
- && (autoBrightnessAdjustmentChanged || userSetBrightnessChanged);
- boolean hadUserBrightnessPoint = false;
- // Configure auto-brightness.
- if (mAutomaticBrightnessController != null) {
- hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints();
- mAutomaticBrightnessController.configure(autoBrightnessEnabled,
- mBrightnessConfiguration,
- mLastUserSetScreenBrightness,
- userSetBrightnessChanged, autoBrightnessAdjustment,
- autoBrightnessAdjustmentChanged, mPowerRequest.policy);
- }
-
- if (mBrightnessTracker != null) {
- mBrightnessTracker.setBrightnessConfiguration(mBrightnessConfiguration);
- }
-
- // Apply auto-brightness.
- boolean slowChange = false;
- if (Float.isNaN(brightnessState)) {
- float newAutoBrightnessAdjustment = autoBrightnessAdjustment;
- if (autoBrightnessEnabled) {
- brightnessState = mAutomaticBrightnessController.getAutomaticScreenBrightness();
- newAutoBrightnessAdjustment =
- mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment();
- }
- if (isValidBrightnessValue(brightnessState)
- || brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT) {
- // Use current auto-brightness value and slowly adjust to changes.
- brightnessState = clampScreenBrightness(brightnessState);
- if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) {
- slowChange = true; // slowly adapt to auto-brightness
- }
- // Tell the rest of the system about the new brightness. Note that we do this
- // before applying the low power or dim transformations so that the slider
- // accurately represents the full possible range, even if they range changes what
- // it means in absolute terms.
- putScreenBrightnessSetting(brightnessState);
- mAppliedAutoBrightness = true;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
- } else {
- mAppliedAutoBrightness = false;
- }
- if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) {
- // If the autobrightness controller has decided to change the adjustment value
- // used, make sure that's reflected in settings.
- putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
- } else {
- // Adjustment values resulted in no change
- brightnessAdjustmentFlags = 0;
- }
- } else {
- mAppliedAutoBrightness = false;
- brightnessAdjustmentFlags = 0;
- }
- // Use default brightness when dozing unless overridden.
- if ((Float.isNaN(brightnessState))
- && Display.isDozeState(state)) {
- brightnessState = mScreenBrightnessDozeConfig;
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
- }
-
- // Apply manual brightness.
- if (Float.isNaN(brightnessState)) {
- brightnessState = clampScreenBrightness(mCurrentScreenBrightnessSetting);
- mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
- }
-
- // Apply dimming by at least some minimum amount when user activity
- // timeout is about to expire.
- if (mPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- if (brightnessState > mScreenBrightnessRangeMinimum) {
- brightnessState = Math.max(Math.min(brightnessState
- - SCREEN_DIM_MINIMUM_REDUCTION_FLOAT,
- mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
- }
- if (!mAppliedDimming) {
- slowChange = false;
- }
- mAppliedDimming = true;
- } else if (mAppliedDimming) {
- slowChange = false;
- mAppliedDimming = false;
- }
- // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor
- // as long as it is above the minimum threshold.
- if (mPowerRequest.lowPowerMode) {
- if (brightnessState > mScreenBrightnessRangeMinimum) {
- final float brightnessFactor =
- Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
- final float lowPowerBrightnessFloat = (brightnessState * brightnessFactor);
- brightnessState = Math.max(lowPowerBrightnessFloat,
- mScreenBrightnessRangeMinimum);
- mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
- }
- if (!mAppliedLowPower) {
- slowChange = false;
- }
- mAppliedLowPower = true;
- } else if (mAppliedLowPower) {
- slowChange = false;
- mAppliedLowPower = false;
- }

- // Animate the screen brightness when the screen is on or dozing.
- // Skip the animation when the screen is off or suspended or transition to/from VR.
- if (!mPendingScreenOff) {
- if (mSkipScreenOnBrightnessRamp) {
- if (state == Display.STATE_ON) {
- if (mSkipRampState == RAMP_STATE_SKIP_NONE && mDozing) {
- mInitialAutoBrightness = brightnessState;
- mSkipRampState = RAMP_STATE_SKIP_INITIAL;
- } else if (mSkipRampState == RAMP_STATE_SKIP_INITIAL
- && mUseSoftwareAutoBrightnessConfig
- && !BrightnessSynchronizer.floatEquals(brightnessState,
- mInitialAutoBrightness)) {
- mSkipRampState = RAMP_STATE_SKIP_AUTOBRIGHT;
- } else if (mSkipRampState == RAMP_STATE_SKIP_AUTOBRIGHT) {
- mSkipRampState = RAMP_STATE_SKIP_NONE;
- }
- } else {
- mSkipRampState = RAMP_STATE_SKIP_NONE;
- }
- }
-
- final boolean wasOrWillBeInVr =
- (state == Display.STATE_VR || oldState == Display.STATE_VR);
- final boolean initialRampSkip =
- state == Display.STATE_ON && mSkipRampState != RAMP_STATE_SKIP_NONE;
- // While dozing, sometimes the brightness is split into buckets. Rather than animating
- // through the buckets, which is unlikely to be smooth in the first place, just jump
- // right to the suggested brightness.
- final boolean hasBrightnessBuckets =
- Display.isDozeState(state) && mBrightnessBucketsInDozeConfig;
- // If the color fade is totally covering the screen then we can change the backlight
- // level without it being a noticeable jump since any actual content isn't yet visible.
- final boolean isDisplayContentVisible =
- mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f;
- final boolean brightnessIsTemporary =
- mAppliedTemporaryBrightness || mAppliedTemporaryAutoBrightnessAdjustment;
- // We only want to animate the brightness if it is between 0.0f and 1.0f.
- // brightnessState can contain the values -1.0f and NaN, which we do not want to
- // animate to. To avoid this, we check the value first.
- // If the brightnessState is off (-1.0f) we still want to animate to the minimum
- // brightness (0.0f) to accommodate for LED displays, which can appear bright to the
- // user even when the display is all black.
- float animateValue = brightnessState == PowerManager.BRIGHTNESS_OFF_FLOAT
- ? PowerManager.BRIGHTNESS_MIN : brightnessState;
- if (isValidBrightnessValue(animateValue)) {
- if (initialRampSkip || hasBrightnessBuckets
- || wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
- animateScreenBrightness(animateValue, SCREEN_ANIMATION_RATE_MINIMUM);
- } else {
- animateScreenBrightness(animateValue,
- slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
- }
- }
-
- if (!brightnessIsTemporary) {
- if (userInitiatedChange && (mAutomaticBrightnessController == null
- || !mAutomaticBrightnessController.hasValidAmbientLux())) {
- // If we don't have a valid lux reading we can't report a valid
- // slider event so notify as if the system changed the brightness.
- userInitiatedChange = false;
- }
- notifyBrightnessChanged(
- BrightnessSynchronizer.brightnessFloatToInt(mContext, brightnessState),
- userInitiatedChange, hadUserBrightnessPoint);
- }
-
- }
-
- // Log any changes to what is currently driving the brightness setting.
- if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
- Slog.v(TAG, "Brightness [" + brightnessState + "] reason changing to: '"
- + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
- + "', previous reason: '" + mBrightnessReason + "'.");
- mBrightnessReason.set(mBrightnessReasonTemp);
- }

setBrightness会决定走一下那个流程:
方式1:system_server->SF->HWC HAL->设备节点->背光驱动
方式2:system_server->Light HAL->设备节点->背光驱动
- @Override
- public void setBrightness(float brightness) {
- setBrightness(brightness, BRIGHTNESS_MODE_USER);
- }
-
- @Override
- public void setBrightness(float brightness, int brightnessMode) {
- if (Float.isNaN(brightness)) {
- Slog.w(TAG, "Brightness is not valid: " + brightness);
- return;
- }
- synchronized (this) {
- // LOW_PERSISTENCE cannot be manually set
- if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
- Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mHwLight.id
- + ": brightness=" + brightness);
- return;
- }
- // Ideally, we'd like to set the brightness mode through the SF/HWC as well, but
- // right now we just fall back to the old path through Lights brightessMode is
- // anything but USER or the device shouldBeInLowPersistenceMode().
- if (brightnessMode == BRIGHTNESS_MODE_USER && !shouldBeInLowPersistenceMode()
- && mSurfaceControlMaximumBrightness == 255) {
- // New system
- // TODO: the last check should be mSurfaceControlMaximumBrightness != 0; the
- // reason we enforce 255 right now is to stay consistent with the old path. In
- // the future, the framework should be refactored so that brightness is a float
- // between 0.0f and 1.0f, and the actual number of supported brightness levels
- // is determined in the device-specific implementation.
- if (DEBUG) {
- Slog.d(TAG, "Using new setBrightness path!");
- }
- SurfaceControl.setDisplayBrightness(mDisplayToken, brightness);
- } else {
- // Old system
- int brightnessInt = BrightnessSynchronizer.brightnessFloatToInt(
- getContext(), brightness);
- int color = brightnessInt & 0x000000ff;
- color = 0xff000000 | (color << 16) | (color << 8) | color;
- setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
- }
- }
- }

此方法的流程为:system_server->SF->HWC HAL->设备节点->背光驱动
通过 android.hardware.light.ILights/default获取Light HAL,走流程:
方式2:system_server->Light HAL->设备节点->背光驱动
- private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
- if (shouldBeInLowPersistenceMode()) {
- brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE;
- } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
- brightnessMode = mLastBrightnessMode;
- }
-
- if (!mInitialized || color != mColor || mode != mMode || onMS != mOnMS ||
- offMS != mOffMS || mBrightnessMode != brightnessMode) {
- if (DEBUG) {
- Slog.v(TAG, "setLight #" + mHwLight.id + ": color=#"
- + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
- }
- mInitialized = true;
- mLastColor = mColor;
- mColor = color;
- mMode = mode;
- mOnMS = onMS;
- mOffMS = offMS;
- mBrightnessMode = brightnessMode;
- setLightUnchecked(color, mode, onMS, offMS, brightnessMode);
- }
- }
-
- private void setLightUnchecked(int color, int mode, int onMS, int offMS,
- int brightnessMode) {
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLightState(" + mHwLight.id + ", 0x"
- + Integer.toHexString(color) + ")");
- try {
- if (mVintfLights != null) {
- HwLightState lightState = new HwLightState();
- lightState.color = color;
- lightState.flashMode = (byte) mode;
- lightState.flashOnMs = onMS;
- lightState.flashOffMs = offMS;
- lightState.brightnessMode = (byte) brightnessMode;
- mVintfLights.get().setLightState(mHwLight.id, lightState);
- } else {
- setLight_native(mHwLight.id, color, mode, onMS, offMS, brightnessMode);
- }
- } catch (RemoteException | UnsupportedOperationException ex) {
- Slog.e(TAG, "Failed issuing setLightState", ex);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。