贯穿流程中,PowerManagerService 中用到的几个关键变量:
// Indicates whether the device is awake or asleep or somewhere in between.
327 // This is distinct from the screen power state, which is managed separately.
328 // Do not access directly; always use {@link #setWakefulness} and {@link getWakefulness}.
329 private int mWakefulnessRaw;
mWakefulnessRaw:表示全局设备唤醒状态,区别于屏幕电源组内的的设备状态。
/frameworks/base/core/java/android/os/PowerManagerInternal.java
29 public abstract class PowerManagerInternal {
30 /**
31 * Wakefulness: The device is asleep. It can only be awoken by a call to wakeUp().
32 * The screen should be off or in the process of being turned off by the display controller.
33 * The device typically passes through the dozing state first.
34 */
35 public static final int WAKEFULNESS_ASLEEP = 0;
36
37 /**
38 * Wakefulness: The device is fully awake. It can be put to sleep by a call to goToSleep().
39 * When the user activity timeout expires, the device may start dreaming or go to sleep.
40 */
41 public static final int WAKEFULNESS_AWAKE = 1;
42
43 /**
44 * Wakefulness: The device is dreaming. It can be awoken by a call to wakeUp(),
45 * which ends the dream. The device goes to sleep when goToSleep() is called, when
46 * the dream ends or when unplugged.
47 * User activity may brighten the screen but does not end the dream.
48 */
49 public static final int WAKEFULNESS_DREAMING = 2;
50
51 /**
52 * Wakefulness: The device is dozing. It is almost asleep but is allowing a special
53 * low-power "doze" dream to run which keeps the display on but lets the application
54 * processor be suspended. It can be awoken by a call to wakeUp() which ends the dream.
55 * The device fully goes to sleep if the dream cannot be started or ends on its own.
56 */
57 public static final int WAKEFULNESS_DOZING = 3;
...
}
/frameworks/base/services/core/java/com/android/server/power/PowerGroup.java
2190 @GuardedBy("mLock")
2191 int getGlobalWakefulnessLocked() {
2192 return mWakefulnessRaw;
2193 }
mUserActivitySummary: 描述用户请求的屏幕状态,这个是和设备的状态是分开的,每个电源组都拥有独立的这个状态。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
214 // Summarizes the user activity state.
215 static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
216 static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
217 static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
PowerGroup: 对于每个DisplayGroup,存在一个PowerGroup。用于存储DisplayGroup中每个屏幕相关的电源请求
/frameworks/base/services/core/java/com/android/server/power/PowerGroup.java
44 /**
45 * Used to store power related requests to every display in a
46 * {@link com.android.server.display.DisplayGroup}.
47 * For each {@link com.android.server.display.DisplayGroup} there exists a {@link PowerGroup}.
48 * The mapping is tracked in {@link PowerManagerService}.
49 * <p><b>Note:</b> Methods with the {@code *Locked} suffix require the
50 * {@code PowerManagerService#mLock} to be held by the caller.
51 */
52 public class PowerGroup {
53 private static final String TAG = PowerGroup.class.getSimpleName();
54 private static final boolean DEBUG = false;
55
56 @VisibleForTesting
57 final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
58 private final PowerGroupListener mWakefulnessListener;
59 private final Notifier mNotifier;
60 private final DisplayManagerInternal mDisplayManagerInternal;
61 private final boolean mSupportsSandman;
62 private final int mGroupId;
63 /** True if DisplayManagerService has applied all the latest display states that were requested
64 * for this group. */
65 private boolean mReady;
66 /** True if this group is in the process of powering on */
67 private boolean mPoweringOn;
68 /** True if this group is about to dream */
69 private boolean mIsSandmanSummoned;
70 private int mUserActivitySummary;
71 /** The current wakefulness of this group */
72 private int mWakefulness;
73 private int mWakeLockSummary;
74 private long mLastPowerOnTime;
75 private long mLastUserActivityTime;
76 private long mLastUserActivityTimeNoChangeLights;
77 /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/
78 private long mLastWakeTime;
79 /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */
80 private long mLastSleepTime;
...
}
DisplayGroup: 存储逻辑屏幕的集合
/frameworks/base/services/core/java/com/android/server/display/DisplayGroup.java
22 /**
23 * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
24 * operations; particularly display-state.
25 *
26 * @hide
27 */
28 public class DisplayGroup {
29
30 private final List<LogicalDisplay> mDisplays = new ArrayList<>();
31 private final int mGroupId;
32
33 private int mChangeCount;
...
}
PMS核心方法updatePowerStateLocked
用来更新整个电源状态的改变,并进行重新计算。PMS中使用一个int值mDirty作为标志位判断电源状态是否发生变化,当电源状态发生改变时,如亮灭屏、电池状态改变、暗屏都会调用该方法。整个逻辑就是建立在一个大的状态机(基于上面描述的几个变量)上,通过某些条件去触发电源状态的改变,然后再去调用这个方法去监听状态的改变后再去触发对应的操作。
/**
2322 * Updates the global power state based on dirty bits recorded in mDirty.
2323 *
2324 * This is the main function that performs power state transitions.
2325 * We centralize them here so that we can recompute the power state completely
2326 * each time something important changes, and ensure that we do it the same
2327 * way each time. The point is to gather all of the transition logic here.
2328 */
2329 @GuardedBy("mLock")
2330 private void updatePowerStateLocked() {
2331 if (!mSystemReady || mDirty == 0 || mUpdatePowerStateInProgress) {
2332 return;
2333 }
2334 if (!Thread.holdsLock(mLock)) {
2335 Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
2336 }
2337
2338 Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
2339 mUpdatePowerStateInProgress = true;
2340 try {
2341 // Phase 0: Basic state updates.
// 收集(更新)充电以及电池状态更新
2342 updateIsPoweredLocked(mDirty);
2343 updateStayOnLocked(mDirty);
// 收集(更新)屏幕亮度状态
2344 updateScreenBrightnessBoostLocked(mDirty);
2345
2346 // Phase 1: Update wakefulness.
2347 // Loop because the wake lock and user activity computations are influenced
2348 // by changes in wakefulness.
2349 final long now = mClock.uptimeMillis();
2350 int dirtyPhase2 = 0;
2351 for (;;) {
2352 int dirtyPhase1 = mDirty;
2353 dirtyPhase2 |= dirtyPhase1;
2354 mDirty = 0;
2355 // 收集(更新)app设置的wakelock数据
2356 updateWakeLockSummaryLocked(dirtyPhase1);
// 收集(更新)用户操作所带来的屏幕状态的改变
2357 updateUserActivitySummaryLocked(now, dirtyPhase1);
2358 updateAttentiveStateLocked(now, dirtyPhase1);
// 根据收集到的数据更新设备的最终状态
2359 if (!updateWakefulnessLocked(dirtyPhase1)) {
2360 break;
2361 }
2362 }
2363
2364 // Phase 2: Lock profiles that became inactive/not kept awake.
2365 updateProfilesLocked(now);
2366
2367 // Phase 3: Update power state of all PowerGroups.
2368 final boolean powerGroupsBecameReady = updatePowerGroupsLocked(dirtyPhase2);
2369
2370 // Phase 4: Update dream state (depends on power group ready signal).
//具体执行屏保相关操作
2371 updateDreamLocked(dirtyPhase2, powerGroupsBecameReady);
2372
2373 // Phase 5: Send notifications, if needed.
2374 finishWakefulnessChangeIfNeededLocked();
2375
2376 // Phase 6: Update suspend blocker.
2377 // Because we might release the last suspend blocker here, we need to make sure
2378 // we finished everything else first!
2379 updateSuspendBlockerLocked();
2380 } finally {
2381 Trace.traceEnd(Trace.TRACE_TAG_POWER);
2382 mUpdatePowerStateInProgress = false;
2383 }
2384 }
2385
updateWakefulnessLocked(),这个方法是退出循环的关键。如果这个方法返回false,则循环结束,如果返回true,则进行下一次循环。
updateIsPoweredLocked: 更新设备电量状态
2411 /**
2412 * Updates the value of mIsPowered.
2413 * Sets DIRTY_IS_POWERED if a change occurred.
2414 */
2415 @GuardedBy("mLock")
2416 private void updateIsPoweredLocked(int dirty) {
2417 if ((dirty & DIRTY_BATTERY_STATE) != 0) {
2418 final boolean wasPowered = mIsPowered;
2419 final int oldPlugType = mPlugType;
2420 mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
2421 mPlugType = mBatteryManagerInternal.getPlugType();
2422 mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
2423 mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();
2424
2425 if (DEBUG_SPEW) {
2426 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
2427 + ", mIsPowered=" + mIsPowered
2428 + ", oldPlugType=" + oldPlugType
2429 + ", mPlugType=" + mPlugType
2430 + ", mBatteryLevel=" + mBatteryLevel);
2431 }
2432
2433 if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
2434 mDirty |= DIRTY_IS_POWERED;
2435
2436 // Update wireless dock detection state.
2437 final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
2438 mIsPowered, mPlugType);
2439
2440 // Treat plugging and unplugging the devices as a user activity.
2441 // Users find it disconcerting when they plug or unplug the device
2442 // and it shuts off right away.
2443 // Some devices also wake the device when plugged or unplugged because
2444 // they don't have a charging LED.
2445 final long now = mClock.uptimeMillis();
2446 if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
2447 dockedOnWirelessCharger)) {
2448
// 唤醒电源组
wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
2449 now, PowerManager.WAKE_REASON_PLUGGED_IN,
2450 "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
2451 mContext.getOpPackageName(), Process.SYSTEM_UID);
2452 }
2453
2454 userActivityNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), now,
2455 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
2456
2457 // only play charging sounds if boot is completed so charging sounds don't play
2458 // with potential notification sounds
2459 if (mBootCompleted) {
2460 if (mIsPowered && !BatteryManager.isPlugWired(oldPlugType)
2461 && BatteryManager.isPlugWired(mPlugType)) {
2462 mNotifier.onWiredChargingStarted(mUserId);
2463 } else if (dockedOnWirelessCharger) {
2464 mNotifier.onWirelessChargingStarted(mBatteryLevel, mUserId);
2465 }
2466 }
2467 }
2468
2469 mBatterySaverStateMachine.setBatteryStatus(mIsPowered, mBatteryLevel, mBatteryLevelLow);
2470 }
2471 }
/frameworks/base/services/core/java/com/android/server/power/PowerGroup.java
204 void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid,
205 String opPackageName, int opUid, LatencyTracker latencyTracker) {
206 if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) {
207 return;
208 }
209
210 Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId);
211 try {
212 Slog.i(TAG, "Waking up power group from "
213 + PowerManagerInternal.wakefulnessToString(mWakefulness)
214 + " (groupId=" + mGroupId
215 + ", uid=" + uid
216 + ", reason=" + PowerManager.wakeReasonToString(reason)
217 + ", details=" + details
218 + ")...");
219 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId);
220 // The instrument will be timed out automatically after 2 seconds.
221 latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId));
222 // 设置该电源组的 Wakefulness状态
223 setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
224 opPackageName, details);
225 } finally {
226 Trace.traceEnd(Trace.TRACE_TAG_POWER);
227 }
228 }
125 /**
126 * Sets the {@code wakefulness} value for this {@link PowerGroup}.
127 *
128 * @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
129 */
130 boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid,
131 String opPackageName, String details) {
132 if (mWakefulness != newWakefulness) {
133 if (newWakefulness == WAKEFULNESS_AWAKE) {
134 setLastPowerOnTimeLocked(eventTime);
135 setIsPoweringOnLocked(true);
136 mLastWakeTime = eventTime;
137 } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) {
138 mLastSleepTime = eventTime;
139 }
140 mWakefulness = newWakefulness;
141 mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime,
142 reason, uid, opUid, opPackageName, details);
143 return true;
144 }
145 return false;
146 }
updateUserActivitySummaryLocked
用户过段时间没有操作屏幕或按键, 屏幕会关闭,检测超时时间是否需要重新计算或者时间已经过去,通过updateUserActivitySummaryLocked来更新,只有当屏幕是亮的时候,才需要计算。总结:根据用户最后的活动来决定当前屏幕的状态。
2727 * Updates the value of mUserActivitySummary to summarize the user requested
2728 * state of the system such as whether the screen should be bright or dim.
2729 * Note that user activity is ignored when the system is asleep.
2730 *
2731 * This function must have no other side-effects.
// 这里似乎google忘了修改mUserActivitySummary变量的注释
2732 */
2733 @GuardedBy("mLock")
2734 private void updateUserActivitySummaryLocked(long now, int dirty) {
2735 // Update the status of the user activity timeout timer.
2736 if ((dirty & (DIRTY_DISPLAY_GROUP_WAKEFULNESS | DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
2737 | DIRTY_WAKEFULNESS | DIRTY_SETTINGS | DIRTY_ATTENTIVE)) == 0) {
2738 return;
2739 }
2740 mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
2741
2742 final long attentiveTimeout = getAttentiveTimeoutLocked();
// 获取进入休眠状态的时间sleepTimeout
// getSleepTimeoutLocked中会判断休眠时间和屏幕熄灭时间的关系
// 如果休眠时间sleepTimeout小于屏幕熄灭时间screenOfftime,
// 则休眠时间被调整为屏幕熄灭时间,因为屏幕亮屏状态下,终端不能进入休眠(休眠时间要大于 熄灭时间,这也符合直觉)
2743 final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
2744 long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
2745 attentiveTimeout);
2746 final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
2747 screenOffTimeout =
2748 getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
2749 final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
2750 long nextTimeout = -1;
2751 boolean hasUserActivitySummary = false;
// 遍历电源组,开始更新每个电源组的屏幕状态,区别于旧版本的更新全局屏幕状态
2752 for (int idx = 0; idx < mPowerGroups.size(); idx++) {
2753 int groupUserActivitySummary = 0;
2754 long groupNextTimeout = 0;
2755 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
2756 final int wakefulness = powerGroup.getWakefulnessLocked();
2757 if (wakefulness != WAKEFULNESS_ASLEEP) {
// 最后一次操作屏幕时间
2758 final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked();
// 最后一次操作屏幕并且不会改变灯光的时间
2759 final long lastUserActivityTimeNoChangeLights =
2760 powerGroup.getLastUserActivityTimeNoChangeLightsLocked();
// 在唤醒的状态下,发生过用户事件
2761 if (lastUserActivityTime >= powerGroup.getLastWakeTimeLocked()) {
2762 // 重新计算出屏幕开始变暗的时间
groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration;
2763 if (now < groupNextTimeout) {
// 得出当前属于亮光状态
2764 groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
2765 } else {
// 如果当前屏幕已经是属于变暗区间,就计算灭屏时间
2766 groupNextTimeout = lastUserActivityTime + screenOffTimeout;
2767 if (now < groupNextTimeout) {
// 得出当前属于变暗状态
2768 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
2769 }
2770 }
2771 }
// 如果在唤醒状态发生过没导致屏幕亮度变化的事件
2772 if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights
2773 >= powerGroup.getLastWakeTimeLocked()) {
// 跳过变暗阶段,直接计算灭屏时间
2774 groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout;
// 如果还没到达灭屏时间,就根据电源组策略控制亮暗
2775 if (now < groupNextTimeout) {
//
2776 if (powerGroup.isPolicyBrightLocked() || powerGroup.isPolicyVrLocked()) {
2777 groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
2778 } else if (powerGroup.isPolicyDimLocked()) {
2779 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
2780 }
2781 }
2782 }
2783
// 如果在唤醒状态下什么用户事件都没发生过,之前可能有发生过
2784 if (groupUserActivitySummary == 0) {
// 若定义了有效的休眠时间,这值根据setting设置
2785 if (sleepTimeout >= 0) {
2786 final long anyUserActivity = Math.max(lastUserActivityTime,
2787 lastUserActivityTimeNoChangeLights);
// 这里我也不明白什么情况下会进来(灭屏后操作设备?)
// 只有在唤醒状态下,进行了用户活动,才会重新更新休眠时间 (此时,应该是有过用户活动,但过了息屏时间了)
2788 if (anyUserActivity >= powerGroup.getLastWakeTimeLocked()) {
2789 groupNextTimeout = anyUserActivity + sleepTimeout;
2790 if (now < groupNextTimeout) {
2791 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
2792 }
2793 }
2794 } else {
// 直接进入屏保
2795 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
2796 groupNextTimeout = -1;
2797 }
2798 }
2799 // 如果屏幕未进入dream态,但WindowManager判定用户inactive,进入下面分支
2800 if (groupUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM
2801 && userInactiveOverride) {
// 如果屏幕没熄灭
2802 if ((groupUserActivitySummary &
2803 (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
2804 // Device is being kept awake by recent user activity
2805 if (mOverriddenTimeout == -1) {
2806 // Save when the next timeout would have occurred
2807 mOverriddenTimeout = groupNextTimeout;
2808 }
2809 }
//Window Manager的权限很大,如果它判断用户inactive,直接进入dream态
2810 groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
2811 groupNextTimeout = -1;
2812 }
2813
2814 if ((groupUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
2815 && (powerGroup.getWakeLockSummaryLocked()
2816 & WAKE_LOCK_STAY_AWAKE) == 0) {
2817 groupNextTimeout = mAttentionDetector.updateUserActivity(groupNextTimeout,
2818 screenDimDuration);
2819 }
2820
2821 if (isAttentiveTimeoutExpired(powerGroup, now)) {
2822 groupUserActivitySummary = 0;
2823 groupNextTimeout = -1;
2824 }
2825
2826 hasUserActivitySummary |= groupUserActivitySummary != 0;
2827
2828 if (nextTimeout == -1) {
2829 nextTimeout = groupNextTimeout;
2830 } else if (groupNextTimeout != -1) {
2831 nextTimeout = Math.min(nextTimeout, groupNextTimeout);
2832 }
2833 }
2834
2835 powerGroup.setUserActivitySummaryLocked(groupUserActivitySummary);
2836
2837 if (DEBUG_SPEW) {
2838 Slog.d(TAG, "updateUserActivitySummaryLocked: groupId=" + powerGroup.getGroupId()
2839 + ", mWakefulness=" + wakefulnessToString(wakefulness)
2840 + ", mUserActivitySummary=0x" + Integer.toHexString(
2841 groupUserActivitySummary)
2842 + ", nextTimeout=" + TimeUtils.formatUptime(groupNextTimeout));
2843 }
2844 }
2845
2846 final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
2847 if (nextProfileTimeout > 0) {
2848 nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
2849 }
2850
2851 if (hasUserActivitySummary && nextTimeout >= 0) {
// 根据nextTimeOut延迟发送信息,信息被处理后,将重新调用updatePowerStateLocked, 于是再次进入到该方法,通过不断进入该方法,不断评估是否根据用户动作亮、熄屏等
2852 scheduleUserInactivityTimeout(nextTimeout);
2853 }
2854 }
2957 /**
2958 * Called when a user activity timeout has occurred.
2959 * Simply indicates that something about user activity has changed so that the new
2960 * state can be recomputed when the power state is updated.
2961 *
2962 * This function must have no other side-effects besides setting the dirty
2963 * bit and calling update power state. Wakefulness transitions are handled elsewhere.
2964 */
2965 private void handleUserActivityTimeout() { // runs on handler thread
2966 synchronized (mLock) {
2967 if (DEBUG_SPEW) {
2968 Slog.d(TAG, "handleUserActivityTimeout");
2969 }
2970
2971 mDirty |= DIRTY_USER_ACTIVITY;
2972 updatePowerStateLocked();
2973 }
2974 }
updateWakefulnessLocked
根据上面dirty的标志位去判断状态改变,去更新powerGroup当中的状态值
3044 /**
3045 * Updates the wakefulness of the device.
3046 *
3047 * This is the function that decides whether the device should start dreaming
3048 * based on the current wake locks and user activity state. It may modify mDirty
3049 * if the wakefulness changes.
3050 *
3051 * Returns true if the wakefulness changed and we need to restart power state calculation.
3052 */
3053 @GuardedBy("mLock")
3054 private boolean updateWakefulnessLocked(int dirty) {
3055 boolean changed = false;
3056 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
3057 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
3058 | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS
3059 | DIRTY_SCREEN_BRIGHTNESS_BOOST)) == 0) {
3060 return changed;
3061 }
3062 final long time = mClock.uptimeMillis();
3063 for (int idx = 0; idx < mPowerGroups.size(); idx++) {
3064 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
3065 if (!(powerGroup.getWakefulnessLocked() == WAKEFULNESS_AWAKE
3066 && isItBedTimeYetLocked(powerGroup))) {
3067 continue;
3068 }
3069 if (DEBUG_SPEW) {
3070 Slog.d(TAG, "updateWakefulnessLocked: Bed time for group "
3071 + powerGroup.getGroupId());
3072 }
3073 if (isAttentiveTimeoutExpired(powerGroup, time)) {
3074 if (DEBUG) {
3075 Slog.i(TAG, "Going to sleep now due to long user inactivity");
3076 }
3077 changed = sleepPowerGroupLocked(powerGroup, time,
3078 PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, Process.SYSTEM_UID);
// 是不是打开dream配置
3079 } else if (shouldNapAtBedTimeLocked()) {
3080 changed = dreamPowerGroupLocked(powerGroup, time, Process.SYSTEM_UID);
3081 } else {
3082 changed = dozePowerGroupLocked(powerGroup, time,
3083 PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
3084 }
3085 }
3086 return changed;
3087 }
3089 /**
3090 * Returns true if the device should automatically nap and start dreaming when the user
3091 * activity timeout has expired and it's bedtime.
3092 */
3093 @GuardedBy("mLock")
3094 private boolean shouldNapAtBedTimeLocked() {
3095 return mDreamsActivateOnSleepSetting
3096 || (mDreamsActivateOnDockSetting
3097 && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
3098 }
2031 @GuardedBy("mLock")
2032 private boolean dreamPowerGroupLocked(PowerGroup powerGroup, long eventTime, int uid) {
2033 if (DEBUG_SPEW) {
2034 Slog.d(TAG, "dreamPowerGroup: groupId=" + powerGroup.getGroupId() + ", eventTime="
2035 + eventTime + ", uid=" + uid);
2036 }
2037 if (!mBootCompleted || !mSystemReady) {
2038 return false;
2039 }
2040 return powerGroup.dreamLocked(eventTime, uid);
2041 }
230 boolean dreamLocked(long eventTime, int uid) {
231 if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
232 return false;
233 }
234
235 Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId());
236 try {
237 Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
// 设置SandmanSummoned = true
238 setSandmanSummonedLocked(true);
// 设置电源组WakefulnessLocked = WAKEFULNESS_DREAMING
239 setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0,
240 /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
241 } finally {
242 Trace.traceEnd(Trace.TRACE_TAG_POWER);
243 }
244 return true;
245 }
updateDreamLocked
根据上面收集的状态具体执行屏保流程
3147 /**
3148 * Determines whether to post a message to the sandman to update the dream state.
3149 */
3150 @GuardedBy("mLock")
3151 private void updateDreamLocked(int dirty, boolean powerGroupBecameReady) {
3152 if ((dirty & (DIRTY_WAKEFULNESS
3153 | DIRTY_USER_ACTIVITY
3154 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED
3155 | DIRTY_ATTENTIVE
3156 | DIRTY_WAKE_LOCKS
3157 | DIRTY_BOOT_COMPLETED
3158 | DIRTY_SETTINGS
3159 | DIRTY_IS_POWERED
3160 | DIRTY_STAY_ON
3161 | DIRTY_PROXIMITY_POSITIVE
3162 | DIRTY_BATTERY_STATE)) != 0 || powerGroupBecameReady) {
3163 if (areAllPowerGroupsReadyLocked()) {
3164 scheduleSandmanLocked();
3165 }
3166 }
3167 }
3169 @GuardedBy("mLock")
3170 private void scheduleSandmanLocked() {
3171 if (!mSandmanScheduled) {
3172 mSandmanScheduled = true;
3173 for (int idx = 0; idx < mPowerGroups.size(); idx++) {
3174 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
3175 if (powerGroup.supportsSandmanLocked()) {
3176 Message msg = mHandler.obtainMessage(MSG_SANDMAN);
3177 msg.arg1 = powerGroup.getGroupId();
// 异步消息
3178 msg.setAsynchronous(true);
3179 mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
3180 }
3181 }
3182 }
3183 }
3186 * Called when the device enters or exits a dreaming or dozing state.
3187 *
3188 * We do this asynchronously because we must call out of the power manager to start
3189 * the dream and we don't want to hold our lock while doing so. There is a risk that
3190 * the device will wake or go to sleep in the meantime so we have to handle that case.
3191 */
3192 private void handleSandman(int groupId) { // runs on handler thread
3193 // Handle preconditions.
3194 final boolean startDreaming;
3195 final int wakefulness;
3196 synchronized (mLock) {
3197 mSandmanScheduled = false;
3198 if (!mPowerGroups.contains(groupId)) {
3199 // Group has been removed.
3200 return;
3201 }
3202 final PowerGroup powerGroup = mPowerGroups.get(groupId);
3203 wakefulness = powerGroup.getWakefulnessLocked();
// 这里判断上面的设置
3204 if ((wakefulness == WAKEFULNESS_DREAMING || wakefulness == WAKEFULNESS_DOZING) &&
3205 powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) {
3206 startDreaming = canDreamLocked(powerGroup) || canDozeLocked(powerGroup);
3207 powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ false);
3208 } else {
3209 startDreaming = false;
3210 }
3211 }
3212
3213 // Start dreaming if needed.
3214 // We only control the dream on the handler thread, so we don't need to worry about
3215 // concurrent attempts to start or stop the dream.
3216 final boolean isDreaming;
3217 if (mDreamManager != null) {
3218 // Restart the dream whenever the sandman is summoned.
3219 if (startDreaming) {
3220 mDreamManager.stopDream(/* immediate= */ false);
3221 mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
3222 }
3223 isDreaming = mDreamManager.isDreaming();
3224 } else {
3225 isDreaming = false;
3226 }
3227
3228 // At this point, we either attempted to start the dream or no attempt will be made,
3229 // so stop holding the display suspend blocker for Doze.
3230 mDozeStartInProgress = false;
....
3308 }
3310 /**
3311 * Returns true if the {@code groupId} is allowed to dream in its current state.
3312 */
3313 @GuardedBy("mLock")
3314 private boolean canDreamLocked(final PowerGroup powerGroup) {
3315 if (!mBootCompleted
3316 || getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
3317 || !mDreamsSupportedConfig
3318 || !mDreamsEnabledSetting
3319 || !(powerGroup.isBrightOrDimLocked())
3320 || powerGroup.isPolicyVrLocked()
3321 || (powerGroup.getUserActivitySummaryLocked() & (USER_ACTIVITY_SCREEN_BRIGHT
3322 | USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0) {
3323 return false;
3324 }
// 当前电源组是不是强制唤醒的状态
3325 if (!isBeingKeptAwakeLocked(powerGroup)) {
3326 if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
3327 return false;
3328 }
3329 if (!mIsPowered
3330 && mDreamsBatteryLevelMinimumWhenNotPoweredConfig >= 0
3331 && mBatteryLevel < mDreamsBatteryLevelMinimumWhenNotPoweredConfig) {
3332 return false;
3333 }
3334 return !mIsPowered
3335 || mDreamsBatteryLevelMinimumWhenPoweredConfig < 0
3336 || mBatteryLevel >= mDreamsBatteryLevelMinimumWhenPoweredConfig;
3337 }
3338 return true;
3339 }
updateWakeLockSummaryLocked
收集更新wakelock状态
2536 /**
2537 * Updates the value of mWakeLockSummary to summarize the state of all active wake locks.
2538 * Note that most wake-locks are ignored when the system is asleep.
2539 *
2540 * This function must have no other side effects.
2541 */
2542 @GuardedBy("mLock")
2543 private void updateWakeLockSummaryLocked(int dirty) {
2544 if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS | DIRTY_DISPLAY_GROUP_WAKEFULNESS))
2545 != 0) {
2546
2547 mWakeLockSummary = 0;
2548
2549 final int numProfiles = mProfilePowerState.size();
2550 for (int i = 0; i < numProfiles; i++) {
2551 mProfilePowerState.valueAt(i).mWakeLockSummary = 0;
2552 }
2553
2554 for (int idx = 0; idx < mPowerGroups.size(); idx++) {
2555 mPowerGroups.valueAt(idx).setWakeLockSummaryLocked(0);
2556 }
2557
2558 int invalidGroupWakeLockSummary = 0;
2559 final int numWakeLocks = mWakeLocks.size();
2560 for (int i = 0; i < numWakeLocks; i++) {
2561 final WakeLock wakeLock = mWakeLocks.get(i);
// 为了后续设置每个电源组的设备唤醒状态
2562 final Integer groupId = wakeLock.getPowerGroupId();
2563 // a wakelock with an invalid group ID should affect all groups
2564 if (groupId == null || (groupId != Display.INVALID_DISPLAY_GROUP
2565 && !mPowerGroups.contains(groupId))) {
2566 continue;
2567 }
2568
2569 final PowerGroup powerGroup = mPowerGroups.get(groupId);
2570 final int wakeLockFlags = getWakeLockSummaryFlags(wakeLock);
2571 mWakeLockSummary |= wakeLockFlags;
2572
2573 if (groupId != Display.INVALID_DISPLAY_GROUP) {
2574 int wakeLockSummary = powerGroup.getWakeLockSummaryLocked();
2575 wakeLockSummary |= wakeLockFlags;
2576 powerGroup.setWakeLockSummaryLocked(wakeLockSummary);
2577 } else {
2578 invalidGroupWakeLockSummary |= wakeLockFlags;
2579 }
2580
2581 for (int j = 0; j < numProfiles; j++) {
2582 final ProfilePowerState profile = mProfilePowerState.valueAt(j);
2583 if (wakeLockAffectsUser(wakeLock, profile.mUserId)) {
2584 profile.mWakeLockSummary |= wakeLockFlags;
2585 }
2586 }
2587 }
2588
2589 for (int idx = 0; idx < mPowerGroups.size(); idx++) {
2590 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
2591 final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(),
2592 invalidGroupWakeLockSummary | powerGroup.getWakeLockSummaryLocked());
2593 powerGroup.setWakeLockSummaryLocked(wakeLockSummary);
2594 }
2595
//还会调整全局wakelock
2596 mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
2597 mWakeLockSummary);
2598
2599 for (int i = 0; i < numProfiles; i++) {
2600 final ProfilePowerState profile = mProfilePowerState.valueAt(i);
2601 profile.mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
2602 profile.mWakeLockSummary);
2603 }
2604
2605 if (DEBUG_SPEW) {
2606 Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
2607 + PowerManagerInternal.wakefulnessToString(getGlobalWakefulnessLocked())
2608 + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
2609 }
2610 }
2611 }
通过adjustWakeLockSummary更新对应的wakeLockSummary
2613 private static int adjustWakeLockSummary(int wakefulness, int wakeLockSummary) {
2614 // Cancel wake locks that make no sense based on the current state.
2615 if (wakefulness != WAKEFULNESS_DOZING) {
2616 wakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
2617 }
2618 if (wakefulness == WAKEFULNESS_ASLEEP
2619 || (wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
2620 wakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
2621 | WAKE_LOCK_BUTTON_BRIGHT);
2622 if (wakefulness == WAKEFULNESS_ASLEEP) {
2623 wakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
2624 }
2625 }
2626
2627 // Infer implied wake locks where necessary based on the current state.
2628 if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
2629 if (wakefulness == WAKEFULNESS_AWAKE) {
2630 wakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
2631 } else if (wakefulness == WAKEFULNESS_DREAMING) {
2632 wakeLockSummary |= WAKE_LOCK_CPU;
2633 }
2634 }
2635 if ((wakeLockSummary & WAKE_LOCK_DRAW) != 0) {
2636 wakeLockSummary |= WAKE_LOCK_CPU;
2637 }
2638
2639 return wakeLockSummary;
2640 }
调试相关:
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
4310 @NeverCompile // Avoid size overhead of debugging code.
4311 private void dumpInternal(PrintWriter pw) {
4312 pw.println("POWER MANAGER (dumpsys power)\n");
4313 ...
现在还有很多不明白的地方就是全局的Wakefulness 和 power group内置的Wakefulness关系,还有后续怎么启动dream梦境具体组件的等,等后续更新。
参考[]:
https://blog.csdn.net/he980725866/article/details/113747765
https://www.cnblogs.com/crushgirl/p/13668452.html
https://www.jb51.net/article/266133.htm