• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.power;
18 
19 import static android.os.PowerManager.SCREEN_TIMEOUT_KEEP_DISPLAY_ON;
20 import static android.os.PowerManager.SCREEN_TIMEOUT_ACTIVE;
21 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
22 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
23 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
24 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
25 import static android.os.PowerManagerInternal.isInteractive;
26 
27 import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
28 import static com.android.server.power.PowerManagerService.TRACE_SCREEN_ON;
29 import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT;
30 import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
31 import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW;
32 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
33 import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM;
34 import static com.android.server.power.PowerManagerService.WAKE_LOCK_STAY_AWAKE;
35 
36 import android.hardware.display.DisplayManagerInternal;
37 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
38 import android.os.PowerManager;
39 import android.os.PowerManager.ScreenTimeoutPolicy;
40 import android.os.PowerManagerInternal;
41 import android.os.PowerSaveState;
42 import android.os.Trace;
43 import android.util.Slog;
44 import android.view.Display;
45 
46 import com.android.internal.annotations.VisibleForTesting;
47 import com.android.internal.util.LatencyTracker;
48 import com.android.server.LocalServices;
49 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
50 import com.android.server.power.feature.PowerManagerFlags;
51 
52 /**
53  * Used to store power related requests to every display in a
54  * {@link com.android.server.display.DisplayGroup}.
55  * For each {@link com.android.server.display.DisplayGroup} there exists a {@link PowerGroup}.
56  * The mapping is tracked in {@link PowerManagerService}.
57  * <p><b>Note:</b> Methods with the {@code *Locked} suffix require the
58  * {@code PowerManagerService#mLock} to be held by the caller.
59  */
60 public class PowerGroup {
61     private static final String TAG = PowerGroup.class.getSimpleName();
62     private static final boolean DEBUG = false;
63 
64     /**
65      * Indicates that the default dim/sleep timeouts should be used.
66      */
67     private static final long INVALID_TIMEOUT = -1;
68 
69     @VisibleForTesting
70     final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
71     private final PowerGroupListener mWakefulnessListener;
72     private final Notifier mNotifier;
73     private final DisplayManagerInternal mDisplayManagerInternal;
74     private final boolean mSupportsSandman;
75     private final int mGroupId;
76     private final PowerManagerFlags mFeatureFlags;
77 
78     /** True if DisplayManagerService has applied all the latest display states that were requested
79      *  for this group. */
80     private boolean mReady;
81     /** True if this group is in the process of powering on */
82     private boolean mPoweringOn;
83     /** True if this group is about to dream */
84     private boolean mIsSandmanSummoned;
85     private int mUserActivitySummary;
86     /** The current wakefulness of this group */
87     private int mWakefulness;
88     private int mWakeLockSummary;
89     private long mLastPowerOnTime;
90     private long mLastUserActivityTime;
91     private long mLastUserActivityTimeNoChangeLights;
92     @PowerManager.UserActivityEvent
93     private int mLastUserActivityEvent;
94     /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/
95     private long mLastWakeTime;
96     /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */
97     private long mLastSleepTime;
98     /** The last reason that woke the power group. */
99     private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
100     /** The last reason that put the power group to sleep. */
101     private @PowerManager.GoToSleepReason int mLastSleepReason =
102             PowerManager.GO_TO_SLEEP_REASON_UNKNOWN;
103 
104     private final long mDimDuration;
105     private final long mScreenOffTimeout;
106 
PowerGroup(int groupId, PowerGroupListener wakefulnessListener, Notifier notifier, DisplayManagerInternal displayManagerInternal, int wakefulness, boolean ready, boolean supportsSandman, long eventTime, PowerManagerFlags featureFlags)107     PowerGroup(int groupId, PowerGroupListener wakefulnessListener, Notifier notifier,
108             DisplayManagerInternal displayManagerInternal, int wakefulness, boolean ready,
109             boolean supportsSandman, long eventTime, PowerManagerFlags featureFlags) {
110         mGroupId = groupId;
111         mWakefulnessListener = wakefulnessListener;
112         mNotifier = notifier;
113         mDisplayManagerInternal = displayManagerInternal;
114         mWakefulness = wakefulness;
115         mReady = ready;
116         mSupportsSandman = supportsSandman;
117         mLastWakeTime = eventTime;
118         mLastSleepTime = eventTime;
119         mFeatureFlags = featureFlags;
120 
121         long dimDuration = INVALID_TIMEOUT;
122         long screenOffTimeout = INVALID_TIMEOUT;
123         if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower()
124                 && mGroupId != Display.DEFAULT_DISPLAY_GROUP) {
125             VirtualDeviceManagerInternal vdm =
126                     LocalServices.getService(VirtualDeviceManagerInternal.class);
127             if (vdm != null) {
128                 int[] displayIds = mDisplayManagerInternal.getDisplayIdsForGroup(mGroupId);
129                 if (displayIds != null && displayIds.length > 0) {
130                     int deviceId = vdm.getDeviceIdForDisplayId(displayIds[0]);
131                     if (vdm.isValidVirtualDeviceId(deviceId)) {
132                         dimDuration = vdm.getDimDurationMillisForDeviceId(deviceId);
133                         screenOffTimeout = vdm.getScreenOffTimeoutMillisForDeviceId(deviceId);
134                         if (dimDuration > 0 && dimDuration > screenOffTimeout) {
135                             // If the dim duration is set, cap it to the screen off timeout.
136                             dimDuration = screenOffTimeout;
137                         }
138                     }
139                 }
140             }
141         }
142         mDimDuration = dimDuration;
143         mScreenOffTimeout = screenOffTimeout;
144     }
145 
PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, Notifier notifier, DisplayManagerInternal displayManagerInternal, long eventTime, PowerManagerFlags featureFlags)146     PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, Notifier notifier,
147             DisplayManagerInternal displayManagerInternal, long eventTime,
148             PowerManagerFlags featureFlags) {
149         mGroupId = Display.DEFAULT_DISPLAY_GROUP;
150         mWakefulnessListener = wakefulnessListener;
151         mNotifier = notifier;
152         mDisplayManagerInternal = displayManagerInternal;
153         mWakefulness = wakefulness;
154         mReady = false;
155         mSupportsSandman = true;
156         mLastWakeTime = eventTime;
157         mLastSleepTime = eventTime;
158         mFeatureFlags = featureFlags;
159         mDimDuration = INVALID_TIMEOUT;
160         mScreenOffTimeout = INVALID_TIMEOUT;
161     }
162 
getScreenOffTimeoutOverrideLocked(long defaultScreenOffTimeout)163     long getScreenOffTimeoutOverrideLocked(long defaultScreenOffTimeout) {
164         return mScreenOffTimeout == INVALID_TIMEOUT ? defaultScreenOffTimeout : mScreenOffTimeout;
165     }
166 
getScreenDimDurationOverrideLocked(long defaultScreenDimDuration)167     long getScreenDimDurationOverrideLocked(long defaultScreenDimDuration) {
168         return mDimDuration == INVALID_TIMEOUT ? defaultScreenDimDuration : mDimDuration;
169     }
170 
getLastWakeTimeLocked()171     long getLastWakeTimeLocked() {
172         return mLastWakeTime;
173     }
174 
getLastSleepTimeLocked()175     long getLastSleepTimeLocked() {
176         return mLastSleepTime;
177     }
178 
getWakefulnessLocked()179     int getWakefulnessLocked() {
180         return mWakefulness;
181     }
182 
getGroupId()183     int getGroupId() {
184         return mGroupId;
185     }
186 
187     /**
188      * Sets the {@code wakefulness} value for this {@link PowerGroup}.
189      *
190      * @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
191      */
setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid, String opPackageName, String details)192     boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid,
193             String opPackageName, String details) {
194         if (mWakefulness != newWakefulness) {
195             if (newWakefulness == WAKEFULNESS_AWAKE) {
196                 setLastPowerOnTimeLocked(eventTime);
197                 setIsPoweringOnLocked(true);
198                 mLastWakeTime = eventTime;
199                 if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) {
200                     mLastWakeReason = reason;
201                 }
202             } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) {
203                 mLastSleepTime = eventTime;
204                 if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) {
205                     mLastSleepReason = reason;
206                 }
207             }
208             mWakefulness = newWakefulness;
209             mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime,
210                     reason, uid, opUid, opPackageName, details);
211             return true;
212         }
213         return false;
214     }
215 
216     /**
217      * Returns {@code true} if every display in this group has its requested state matching
218      * its actual state.
219      */
isReadyLocked()220     boolean isReadyLocked() {
221         return mReady;
222     }
223 
224     /**
225      * Sets whether the displays of this group are all ready.
226      *
227      * <p>A display is ready if its reported
228      * {@link android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged()
229      * actual state} matches its
230      * {@link android.hardware.display.DisplayManagerInternal#requestPowerState requested state}.
231      *
232      * @param isReady {@code true} if every display in the group is ready; otherwise {@code false}.
233      * @return {@code true} if the ready state changed; otherwise {@code false}.
234      */
setReadyLocked(boolean isReady)235     boolean setReadyLocked(boolean isReady) {
236         if (mReady != isReady) {
237             mReady = isReady;
238             return true;
239         }
240         return false;
241     }
242 
getLastPowerOnTimeLocked()243     long getLastPowerOnTimeLocked() {
244         return mLastPowerOnTime;
245     }
246 
setLastPowerOnTimeLocked(long time)247     void setLastPowerOnTimeLocked(long time) {
248         mLastPowerOnTime = time;
249     }
250 
isPoweringOnLocked()251     boolean isPoweringOnLocked() {
252         return mPoweringOn;
253     }
254 
setIsPoweringOnLocked(boolean isPoweringOnNew)255     void setIsPoweringOnLocked(boolean isPoweringOnNew) {
256         mPoweringOn = isPoweringOnNew;
257     }
258 
isSandmanSummonedLocked()259     boolean isSandmanSummonedLocked() {
260         return mIsSandmanSummoned;
261     }
262 
263     /**
264      * Sets whether or not the sandman is summoned for this {@link PowerGroup}.
265      *
266      * @param isSandmanSummoned {@code true} to summon the sandman; {@code false} to unsummon.
267      */
setSandmanSummonedLocked(boolean isSandmanSummoned)268     void setSandmanSummonedLocked(boolean isSandmanSummoned) {
269         mIsSandmanSummoned = isSandmanSummoned;
270     }
271 
wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid, String opPackageName, int opUid, LatencyTracker latencyTracker)272     void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid,
273             String opPackageName, int opUid, LatencyTracker latencyTracker) {
274         if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) {
275             return;
276         }
277 
278         Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId);
279         try {
280             Slog.i(TAG, "Waking up power group from "
281                     + PowerManagerInternal.wakefulnessToString(mWakefulness)
282                     + " (groupId=" + mGroupId
283                     + ", uid=" + uid
284                     + ", reason=" + PowerManager.wakeReasonToString(reason)
285                     + ", details=" + details
286                     + ")...");
287             Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId);
288             // The instrument will be timed out automatically after 2 seconds.
289             latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId));
290 
291             setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
292                     opPackageName, details);
293         } finally {
294             Trace.traceEnd(Trace.TRACE_TAG_POWER);
295         }
296     }
297 
dreamLocked(long eventTime, int uid, boolean allowWake)298     boolean dreamLocked(long eventTime, int uid, boolean allowWake) {
299         if (eventTime < mLastWakeTime || (!allowWake && mWakefulness != WAKEFULNESS_AWAKE)) {
300             return false;
301         }
302 
303         Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId());
304         try {
305             Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
306             setSandmanSummonedLocked(true);
307             setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0,
308                     /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
309         } finally {
310             Trace.traceEnd(Trace.TRACE_TAG_POWER);
311         }
312         return true;
313     }
314 
dozeLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason)315     boolean dozeLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason) {
316         if (eventTime < getLastWakeTimeLocked() || !isInteractive(mWakefulness)) {
317             return false;
318         }
319 
320         Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay");
321         try {
322             reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
323                     Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
324             long millisSinceLastUserActivity = eventTime - Math.max(
325                     mLastUserActivityTimeNoChangeLights, mLastUserActivityTime);
326             Slog.i(TAG, "Powering off display group due to "
327                     + PowerManager.sleepReasonToString(reason)
328                     + " (groupId= " + getGroupId() + ", uid= " + uid
329                     + ", millisSinceLastUserActivity=" + millisSinceLastUserActivity
330                     + ", lastUserActivityEvent=" + PowerManager.userActivityEventToString(
331                     mLastUserActivityEvent) + ")...");
332 
333             setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
334             setWakefulnessLocked(WAKEFULNESS_DOZING, eventTime, uid, reason, /* opUid= */ 0,
335                     /* opPackageName= */ null, /* details= */ null);
336         } finally {
337             Trace.traceEnd(Trace.TRACE_TAG_POWER);
338         }
339         return true;
340     }
341 
sleepLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason)342     boolean sleepLocked(long eventTime, int uid, @PowerManager.GoToSleepReason int reason) {
343         if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
344             return false;
345         }
346 
347         Trace.traceBegin(Trace.TRACE_TAG_POWER, "sleepPowerGroup");
348         try {
349             Slog.i(TAG,
350                     "Sleeping power group (groupId=" + getGroupId() + ", uid=" + uid + ", reason="
351                             + PowerManager.sleepReasonToString(reason) + ")...");
352             setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
353             setWakefulnessLocked(WAKEFULNESS_ASLEEP, eventTime, uid, reason, /* opUid= */0,
354                     /* opPackageName= */ null, /* details= */ null);
355         } finally {
356             Trace.traceEnd(Trace.TRACE_TAG_POWER);
357         }
358         return true;
359     }
360 
getLastUserActivityTimeLocked()361     long getLastUserActivityTimeLocked() {
362         return mLastUserActivityTime;
363     }
364 
setLastUserActivityTimeLocked(long lastUserActivityTime, @PowerManager.UserActivityEvent int event)365     void setLastUserActivityTimeLocked(long lastUserActivityTime,
366             @PowerManager.UserActivityEvent int event) {
367         mLastUserActivityTime = lastUserActivityTime;
368         mLastUserActivityEvent = event;
369     }
370 
getLastUserActivityTimeNoChangeLightsLocked()371     public long getLastUserActivityTimeNoChangeLightsLocked() {
372         return mLastUserActivityTimeNoChangeLights;
373     }
374 
setLastUserActivityTimeNoChangeLightsLocked(long time, @PowerManager.UserActivityEvent int event)375     public void setLastUserActivityTimeNoChangeLightsLocked(long time,
376             @PowerManager.UserActivityEvent int event) {
377         mLastUserActivityTimeNoChangeLights = time;
378         mLastUserActivityEvent = event;
379     }
380 
getUserActivitySummaryLocked()381     public int getUserActivitySummaryLocked() {
382         return mUserActivitySummary;
383     }
384 
isPolicyBrightLocked()385     public boolean isPolicyBrightLocked() {
386         return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT;
387     }
388 
isPolicyDimLocked()389     public boolean isPolicyDimLocked() {
390         return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM;
391     }
392 
isBrightOrDimLocked()393     public boolean isBrightOrDimLocked() {
394         return mDisplayPowerRequest.isBrightOrDim();
395     }
396 
setUserActivitySummaryLocked(int summary)397     public void setUserActivitySummaryLocked(int summary) {
398         mUserActivitySummary = summary;
399     }
400 
getWakeLockSummaryLocked()401     public int getWakeLockSummaryLocked() {
402         return mWakeLockSummary;
403     }
404 
405     /**
406      * Query whether a wake lock is at least partially responsible for keeping the device awake.
407      *
408      * This does not necessarily mean the wake lock is the sole reason the device is awake; there
409      * could also be user activity keeping the device awake, for example. It just means a wake lock
410      * is being held that would keep the device awake even if nothing else was.
411      *
412      * @return whether the PowerGroup is being kept awake at least in part because a wake lock is
413      *         being held.
414      */
hasWakeLockKeepingScreenOnLocked()415     public boolean hasWakeLockKeepingScreenOnLocked() {
416         final int screenOnWakeLockMask =
417                 WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM | WAKE_LOCK_STAY_AWAKE;
418         return (mWakeLockSummary & (screenOnWakeLockMask)) != 0;
419     }
420 
421     @ScreenTimeoutPolicy
getScreenTimeoutPolicy()422     public int getScreenTimeoutPolicy() {
423         return hasWakeLockKeepingScreenOnLocked() ? SCREEN_TIMEOUT_KEEP_DISPLAY_ON
424                 : SCREEN_TIMEOUT_ACTIVE;
425     }
426 
setWakeLockSummaryLocked(int summary)427     public void setWakeLockSummaryLocked(int summary) {
428         mWakeLockSummary = summary;
429     }
430 
431     /**
432      * Whether or not this DisplayGroup supports dreaming.
433      * @return {@code true} if this DisplayGroup supports dreaming; otherwise {@code false}.
434      */
supportsSandmanLocked()435     public boolean supportsSandmanLocked() {
436         return mSupportsSandman;
437     }
438 
439     /**
440      * Return true if we must keep a suspend blocker active on behalf of a power group.
441      * We do so if the screen is on or is in transition between states.
442      */
needSuspendBlockerLocked(boolean proximityPositive, boolean suspendWhenScreenOffDueToProximityConfig)443     boolean needSuspendBlockerLocked(boolean proximityPositive,
444             boolean suspendWhenScreenOffDueToProximityConfig) {
445         if (isBrightOrDimLocked()) {
446             // If we asked for the screen to be on but it is off due to the proximity
447             // sensor then we may suspend but only if the configuration allows it.
448             // On some hardware it may not be safe to suspend because the proximity
449             // sensor may not be correctly configured as a wake-up source.
450             if (!mDisplayPowerRequest.useProximitySensor || !proximityPositive
451                     || !suspendWhenScreenOffDueToProximityConfig) {
452                 return true;
453             }
454         }
455 
456         if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
457                 && mDisplayPowerRequest.dozeScreenState == Display.STATE_ON) {
458             // Although we are in DOZE and would normally allow the device to suspend,
459             // the doze service has explicitly requested the display to remain in the ON
460             // state which means we should hold the display suspend blocker.
461             return true;
462         }
463         return false;
464     }
465 
466     // TODO: create and use more specific policy reasons, beyond the ones that correlate to
467     // interactivity state
updateScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff, boolean bootCompleted, boolean screenBrightnessBoostInProgress, boolean brightWhenDozing)468     private void updateScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff,
469             boolean bootCompleted, boolean screenBrightnessBoostInProgress,
470             boolean brightWhenDozing) {
471         final int wakefulness = getWakefulnessLocked();
472         final int wakeLockSummary = getWakeLockSummaryLocked();
473         int policyReason = Display.STATE_REASON_DEFAULT_POLICY;
474         int policy = Integer.MAX_VALUE; // do not set to real policy to start with.
475         if (quiescent) {
476             policy = DisplayPowerRequest.POLICY_OFF;
477         } else if (wakefulness == WAKEFULNESS_ASLEEP) {
478             policy = DisplayPowerRequest.POLICY_OFF;
479             policyReason = sleepReasonToDisplayStateReason(mLastSleepReason);
480         } else if (wakefulness == WAKEFULNESS_DOZING) {
481             if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
482                 policy = DisplayPowerRequest.POLICY_DOZE;
483             } else if (dozeAfterScreenOff) {
484                 policy = DisplayPowerRequest.POLICY_OFF;
485             } else if (brightWhenDozing) {
486                 policy = DisplayPowerRequest.POLICY_BRIGHT;
487             }
488             // Fall through and preserve the current screen policy if not configured to
489             // bright when dozing or doze after screen off.  This causes the screen off transition
490             // to be skipped.
491         }
492 
493         if (policy == Integer.MAX_VALUE) { // policy is not set yet.
494             if (isInteractive(wakefulness)) {
495                 policyReason = wakeReasonToDisplayStateReason(mLastWakeReason);
496             }
497             if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
498                     || !bootCompleted
499                     || (getUserActivitySummaryLocked() & USER_ACTIVITY_SCREEN_BRIGHT) != 0
500                     || screenBrightnessBoostInProgress) {
501                 policy = DisplayPowerRequest.POLICY_BRIGHT;
502             } else {
503                 policy = DisplayPowerRequest.POLICY_DIM;
504             }
505         }
506 
507         if (mFeatureFlags.isPolicyReasonInDisplayPowerRequestEnabled()) {
508             mDisplayPowerRequest.policyReason = policyReason;
509         }
510         mDisplayPowerRequest.policy = policy;
511     }
512 
getPolicyLocked()513     int getPolicyLocked() {
514         return mDisplayPowerRequest.policy;
515     }
516 
updateLocked(float screenBrightnessOverride, CharSequence overrideTag, boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState, @Display.StateReason int dozeScreenStateReason, float dozeScreenBrightness, boolean useNormalBrightnessForDoze, boolean overrideDrawWakeLock, PowerSaveState powerSaverState, boolean quiescent, boolean dozeAfterScreenOff, boolean bootCompleted, boolean screenBrightnessBoostInProgress, boolean waitForNegativeProximity, boolean brightWhenDozing)517     boolean updateLocked(float screenBrightnessOverride, CharSequence overrideTag,
518             boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState,
519             @Display.StateReason int dozeScreenStateReason,
520             float dozeScreenBrightness, boolean useNormalBrightnessForDoze,
521             boolean overrideDrawWakeLock,
522             PowerSaveState powerSaverState, boolean quiescent,
523             boolean dozeAfterScreenOff, boolean bootCompleted,
524             boolean screenBrightnessBoostInProgress, boolean waitForNegativeProximity,
525             boolean brightWhenDozing) {
526         updateScreenPolicyLocked(quiescent, dozeAfterScreenOff,
527                 bootCompleted, screenBrightnessBoostInProgress, brightWhenDozing);
528         mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
529         mDisplayPowerRequest.screenBrightnessOverrideTag = overrideTag;
530         mDisplayPowerRequest.useProximitySensor = useProximitySensor;
531         mDisplayPowerRequest.boostScreenBrightness = boostScreenBrightness;
532 
533         if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
534             mDisplayPowerRequest.dozeScreenState = dozeScreenState;
535             mDisplayPowerRequest.dozeScreenStateReason = dozeScreenStateReason;
536             if ((getWakeLockSummaryLocked() & WAKE_LOCK_DRAW) != 0 && !overrideDrawWakeLock) {
537                 if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
538                     mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
539                     mDisplayPowerRequest.dozeScreenStateReason =
540                             Display.STATE_REASON_DRAW_WAKE_LOCK;
541                 }
542                 if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
543                     mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;
544                     mDisplayPowerRequest.dozeScreenStateReason =
545                             Display.STATE_REASON_DRAW_WAKE_LOCK;
546                 }
547             }
548             mDisplayPowerRequest.dozeScreenBrightness = dozeScreenBrightness;
549             mDisplayPowerRequest.useNormalBrightnessForDoze = useNormalBrightnessForDoze;
550         } else {
551             mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
552             mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
553             mDisplayPowerRequest.dozeScreenStateReason =
554                     Display.STATE_REASON_DEFAULT_POLICY;
555             mDisplayPowerRequest.useNormalBrightnessForDoze = false;
556         }
557         mDisplayPowerRequest.lowPowerMode = powerSaverState.batterySaverEnabled;
558         mDisplayPowerRequest.screenLowPowerBrightnessFactor = powerSaverState.brightnessFactor;
559         boolean ready = mDisplayManagerInternal.requestPowerState(mGroupId, mDisplayPowerRequest,
560                 waitForNegativeProximity);
561         mNotifier.onScreenPolicyUpdate(mGroupId, mDisplayPowerRequest.policy);
562         return ready;
563     }
564 
565     /** Determines the respective display state reason for a given PowerManager WakeReason. */
wakeReasonToDisplayStateReason(@owerManager.WakeReason int wakeReason)566     private static int wakeReasonToDisplayStateReason(@PowerManager.WakeReason int wakeReason) {
567         switch (wakeReason) {
568             case PowerManager.WAKE_REASON_POWER_BUTTON:
569             case PowerManager.WAKE_REASON_WAKE_KEY:
570                 return Display.STATE_REASON_KEY;
571             case PowerManager.WAKE_REASON_WAKE_MOTION:
572                 return Display.STATE_REASON_MOTION;
573             case PowerManager.WAKE_REASON_TILT:
574                 return Display.STATE_REASON_TILT;
575             default:
576                 return Display.STATE_REASON_DEFAULT_POLICY;
577         }
578     }
579 
580     /** Determines the respective display state reason for a given PowerManager GoToSleepReason. */
sleepReasonToDisplayStateReason( @owerManager.GoToSleepReason int sleepReason)581     private static int sleepReasonToDisplayStateReason(
582             @PowerManager.GoToSleepReason int sleepReason) {
583         switch (sleepReason) {
584             case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
585             case PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON:
586                 return Display.STATE_REASON_KEY;
587             default:
588                 return Display.STATE_REASON_DEFAULT_POLICY;
589         }
590     }
591 
592     protected interface PowerGroupListener {
593         /**
594          * Informs the recipient about a wakefulness change of a {@link PowerGroup}.
595          *
596          * @param groupId The PowerGroup's id for which the wakefulness has changed.
597          * @param wakefulness The new wakefulness.
598          * @param eventTime The time of the event.
599          * @param reason The reason, any of {@link android.os.PowerManager.WakeReason} or
600          *               {@link android.os.PowerManager.GoToSleepReason}.
601          * @param uid The uid which caused the wakefulness change.
602          * @param opUid The uid used for AppOps.
603          * @param opPackageName The Package name used for AppOps.
604          * @param details Details about the event.
605          */
onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason, int uid, int opUid, String opPackageName, String details)606         void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason,
607                 int uid, int opUid, String opPackageName, String details);
608     }
609 }
610