aosp 13 PowerManagerService 相关变更研究

贯穿流程中,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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值