Merge "Improve PowerGroup event notification" into udc-dev

This commit is contained in:
Antony Sargent
2023-04-26 23:22:08 +00:00
committed by Android (Google) Code Review
7 changed files with 342 additions and 137 deletions

View File

@@ -1004,7 +1004,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return;
}
final boolean interactive = Display.isOnState(mDefaultDisplay.getState());
final boolean interactive = mDefaultDisplayPolicy.isAwake();
Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
+ " count=" + count + " beganFromNonInteractive=" + beganFromNonInteractive
@@ -2201,8 +2201,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Match current screen state.
if (!mPowerManager.isInteractive()) {
startedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
finishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
startedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
finishedGoingToSleep(Display.DEFAULT_DISPLAY_GROUP,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
}
mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@@ -4095,7 +4097,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// This could prevent some wrong state in multi-displays environment,
// the default display may turned off but interactive is true.
final boolean isDefaultDisplayOn = Display.isOnState(mDefaultDisplay.getState());
final boolean isDefaultDisplayOn = mDefaultDisplayPolicy.isAwake();
final boolean interactiveAndOn = interactive && isDefaultDisplayOn;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
handleKeyGesture(event, interactiveAndOn);
@@ -4795,17 +4797,40 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
@Override
public void startedWakingUpGlobal(@WakeReason int reason) {
}
@Override
public void finishedWakingUpGlobal(@WakeReason int reason) {
}
@Override
public void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
mDeviceGoingToSleep = true;
}
@Override
public void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason) {
mDeviceGoingToSleep = false;
}
// Called on the PowerManager's Notifier thread.
@Override
public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
public void startedGoingToSleep(int displayGroupId,
@PowerManager.GoToSleepReason int pmSleepReason) {
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Started going to sleep... (why="
Slog.i(TAG, "Started going to sleep... (groupId=" + displayGroupId + " why="
+ WindowManagerPolicyConstants.offReasonToString(
WindowManagerPolicyConstants.translateSleepReasonToOffReason(
pmSleepReason)) + ")");
}
if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
return;
}
mDeviceGoingToSleep = true;
mRequestedOrSleepingDefaultDisplay = true;
if (mKeyguardDelegate != null) {
@@ -4815,17 +4840,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the PowerManager's Notifier thread.
@Override
public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
public void finishedGoingToSleep(int displayGroupId,
@PowerManager.GoToSleepReason int pmSleepReason) {
if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
return;
}
EventLogTags.writeScreenToggled(0);
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Finished going to sleep... (why="
Slog.i(TAG, "Finished going to sleep... (groupId=" + displayGroupId + " why="
+ WindowManagerPolicyConstants.offReasonToString(
WindowManagerPolicyConstants.translateSleepReasonToOffReason(
pmSleepReason)) + ")");
}
MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
mDeviceGoingToSleep = false;
mRequestedOrSleepingDefaultDisplay = false;
mDefaultDisplayPolicy.setAwake(false);
@@ -4850,26 +4878,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the PowerManager's Notifier thread.
@Override
public void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
@PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness) {
if (wakefulness != globalWakefulness
&& wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE
&& groupId == Display.DEFAULT_DISPLAY_GROUP
&& mKeyguardDelegate != null) {
mKeyguardDelegate.doKeyguardTimeout(null);
}
}
// Called on the PowerManager's Notifier thread.
@Override
public void startedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
EventLogTags.writeScreenToggled(1);
public void startedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Started waking up... (why="
Slog.i(TAG, "Started waking up... (groupId=" + displayGroupId + " why="
+ WindowManagerPolicyConstants.onReasonToString(
WindowManagerPolicyConstants.translateWakeReasonToOnReason(
pmWakeReason)) + ")");
WindowManagerPolicyConstants.translateWakeReasonToOnReason(
pmWakeReason)) + ")");
}
if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
return;
}
EventLogTags.writeScreenToggled(1);
mDefaultDisplayPolicy.setAwake(true);
@@ -4892,13 +4912,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the PowerManager's Notifier thread.
@Override
public void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
public void finishedWakingUp(int displayGroupId, @WakeReason int pmWakeReason) {
if (DEBUG_WAKEUP) {
Slog.i(TAG, "Finished waking up... (why="
Slog.i(TAG, "Finished waking up... (groupId=" + displayGroupId + " why="
+ WindowManagerPolicyConstants.onReasonToString(
WindowManagerPolicyConstants.translateWakeReasonToOnReason(
pmWakeReason)) + ")");
}
if (displayGroupId != Display.DEFAULT_DISPLAY_GROUP) {
return;
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedWakingUp();
@@ -5378,8 +5401,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
mSideFpsEventHandler.onFingerprintSensorReady();
startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
startedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
finishedWakingUp(Display.DEFAULT_DISPLAY_GROUP, PowerManager.WAKE_REASON_UNKNOWN);
int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;

View File

@@ -67,10 +67,12 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.companion.virtual.VirtualDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.VirtualDisplay;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
@@ -761,51 +763,85 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
*/
void setAllowLockscreenWhenOn(int displayId, boolean allow);
/**
* Called when the global wakefulness is becoming awake.
*
* @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
*/
void startedWakingUpGlobal(@PowerManager.WakeReason int reason);
/**
* Called when the global wakefulness has finished becoming awake.
*
* @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
*/
void finishedWakingUpGlobal(@PowerManager.WakeReason int reason);
/**
* Called when the global wakefulness has started going to sleep.
*
* @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
*/
void startedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);
/**
* Called when the global wakefulness has finished going to sleep.
*
* @param reason One of PowerManager.WAKE_REASON_*, detailing the reason for the change.
*/
void finishedGoingToSleepGlobal(@PowerManager.GoToSleepReason int reason);
/**
* Called when the device has started waking up.
*
* @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
* waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
* @param displayGroupId The id of the display group that has started waking up. This will often
* be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
* display groups to exist, for example when there is a
* {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
* @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
* display group is waking up, such as WAKE_REASON_POWER_BUTTON or
* WAKE_REASON_GESTURE.
*/
void startedWakingUp(@PowerManager.WakeReason int pmWakeReason);
void startedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);
/**
* Called when the device has finished waking up.
*
* @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason we're
* waking up, such as WAKE_REASON_POWER_BUTTON or WAKE_REASON_GESTURE.
* @param displayGroupId The id of the display group that has finished waking. This will often
* be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is possible for other
* display groups to exist, for example when there is a
* {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
* @param pmWakeReason One of PowerManager.WAKE_REASON_*, detailing the specific reason this
* display group is waking up, such as WAKE_REASON_POWER_BUTTON or
* WAKE_REASON_GESTURE.
*/
void finishedWakingUp(@PowerManager.WakeReason int pmWakeReason);
void finishedWakingUp(int displayGroupId, @PowerManager.WakeReason int pmWakeReason);
/**
* Called when the device has started going to sleep.
*
* @param displayGroupId The id of the display group that has started going to sleep. This
* will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
* possible for other display groups to exist, for example when there is a
* {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
* @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
* we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
* this display group is going to sleep, such as
* GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
*/
public void startedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);
void startedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);
/**
* Called when the device has finished going to sleep.
*
* @param displayGroupId The id of the display group that has finished going to sleep. This
* will often be {@link Display#DEFAULT_DISPLAY_GROUP}, but it is
* possible for other display groups to exist, for example when there is a
* {@link VirtualDevice} with one or more {@link VirtualDisplay}s.
* @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the specific reason
* we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or GO_TO_SLEEP_REASON_TIMEOUT.
* we're going to sleep, such as GO_TO_SLEEP_REASON_POWER_BUTTON or
* GO_TO_SLEEP_REASON_TIMEOUT.
*/
public void finishedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason);
/**
* Called when a particular PowerGroup has changed wakefulness.
*
* @param groupId The id of the PowerGroup.
* @param wakefulness One of PowerManagerInternal.WAKEFULNESS_* indicating the wake state for
* the group
* @param pmSleepReason One of PowerManager.GO_TO_SLEEP_REASON_*, detailing the reason this
* group is going to sleep.
* @param globalWakefulness The global wakefulness, which may or may not match that of this
* group. One of PowerManagerInternal.WAKEFULNESS_*
*/
void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
@PowerManager.GoToSleepReason int pmSleepReason, int globalWakefulness);
void finishedGoingToSleep(int displayGroupId, @PowerManager.GoToSleepReason int pmSleepReason);
/**
* Called when the display is about to turn on to show content.

View File

@@ -51,6 +51,7 @@ import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;
import android.view.WindowManagerPolicyConstants;
import com.android.internal.annotations.VisibleForTesting;
@@ -87,7 +88,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
* tell the system when we go to sleep so that it can lock the keyguard if needed.
* </p>
*/
@VisibleForTesting
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
public class Notifier {
private static final String TAG = "PowerManagerNotifier";
@@ -150,14 +151,21 @@ public class Notifier {
// begins charging wirelessly
private final boolean mShowWirelessChargingAnimationConfig;
// The current interactive state. This is set as soon as an interactive state
// Encapsulates interactivity information about a particular display group.
private static class Interactivity {
public boolean isInteractive = true;
public int changeReason;
public long changeStartTime; // In SystemClock.uptimeMillis()
public boolean isChanging;
}
private final SparseArray<Interactivity> mInteractivityByGroupId = new SparseArray<>();
// The current global interactive state. This is set as soon as an interactive state
// transition begins so as to capture the reason that it happened. At some point
// this state will propagate to the pending state then eventually to the
// broadcasted state over the course of reporting the transition asynchronously.
private boolean mInteractive = true;
private int mInteractiveChangeReason;
private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
private boolean mInteractiveChanging;
private Interactivity mGlobalInteractivity = new Interactivity();
// The pending interactive state that we will eventually want to broadcast.
// This is designed so that we can collapse redundant sequences of awake/sleep
@@ -438,7 +446,8 @@ public class Notifier {
* which case it will assume that the state did not fully converge before the
* next transition began and will recover accordingly.
*/
public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
public void onGlobalWakefulnessChangeStarted(final int wakefulness, int reason,
long eventTime) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
@@ -456,10 +465,10 @@ public class Notifier {
// Handle any early interactive state changes.
// Finish pending incomplete ones from a previous cycle.
if (mInteractive != interactive) {
if (mGlobalInteractivity.isInteractive != interactive) {
// Finish up late behaviors if needed.
if (mInteractiveChanging) {
handleLateInteractiveChange();
if (mGlobalInteractivity.isChanging) {
handleLateGlobalInteractiveChange();
}
// Start input as soon as we start waking up or going to sleep.
@@ -475,11 +484,11 @@ public class Notifier {
FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
// Handle early behaviors.
mInteractive = interactive;
mInteractiveChangeReason = reason;
mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
mGlobalInteractivity.isInteractive = interactive;
mGlobalInteractivity.isChanging = true;
mGlobalInteractivity.changeReason = reason;
mGlobalInteractivity.changeStartTime = eventTime;
handleEarlyGlobalInteractiveChange();
}
}
@@ -490,10 +499,34 @@ public class Notifier {
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeFinished");
}
for (int i = 0; i < mInteractivityByGroupId.size(); i++) {
int groupId = mInteractivityByGroupId.keyAt(i);
Interactivity interactivity = mInteractivityByGroupId.valueAt(i);
if (interactivity.isChanging) {
interactivity.isChanging = false;
handleLateInteractiveChange(groupId);
}
}
if (mGlobalInteractivity.isChanging) {
mGlobalInteractivity.isChanging = false;
handleLateGlobalInteractiveChange();
}
}
if (mInteractiveChanging) {
mInteractiveChanging = false;
handleLateInteractiveChange();
private void handleEarlyInteractiveChange(int groupId) {
synchronized (mLock) {
Interactivity interactivity = mInteractivityByGroupId.get(groupId);
if (interactivity == null) {
Slog.e(TAG, "no Interactivity entry for groupId:" + groupId);
return;
}
final int changeReason = interactivity.changeReason;
if (interactivity.isInteractive) {
mHandler.post(() -> mPolicy.startedWakingUp(groupId, changeReason));
} else {
mHandler.post(() -> mPolicy.startedGoingToSleep(groupId, changeReason));
}
}
}
@@ -501,13 +534,13 @@ public class Notifier {
* Handle early interactive state changes such as getting applications or the lock
* screen running and ready for the user to see (such as when turning on the screen).
*/
private void handleEarlyInteractiveChange() {
private void handleEarlyGlobalInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
if (mGlobalInteractivity.isInteractive) {
// Waking up...
mHandler.post(() -> {
mPolicy.startedWakingUp(mInteractiveChangeReason);
mDisplayManagerInternal.onEarlyInteractivityChange(true /*isInteractive*/);
mPolicy.startedWakingUpGlobal(mGlobalInteractivity.changeReason);
});
// Send interactive broadcast.
@@ -516,37 +549,36 @@ public class Notifier {
updatePendingBroadcastLocked();
} else {
// Going to sleep...
// Tell the policy that we started going to sleep.
mHandler.post(() -> {
mPolicy.startedGoingToSleep(mInteractiveChangeReason);
mDisplayManagerInternal.onEarlyInteractivityChange(false /*isInteractive*/);
mPolicy.startedGoingToSleepGlobal(mGlobalInteractivity.changeReason);
});
}
}
}
/**
* Handle late interactive state changes once they are finished so that the system can
* finish pending transitions (such as turning the screen off) before causing
* applications to change state visibly.
* Handle late global interactive state changes. Also see
* {@link #handleLateInteractiveChange(int)}.
*/
private void handleLateInteractiveChange() {
private void handleLateGlobalInteractiveChange() {
synchronized (mLock) {
final int interactiveChangeLatency =
(int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
(int) (SystemClock.uptimeMillis() - mGlobalInteractivity.changeStartTime);
if (mGlobalInteractivity.isInteractive) {
// Finished waking up...
mHandler.post(() -> {
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_OPEN);
log.setSubtype(WindowManagerPolicyConstants.translateWakeReasonToOnReason(
mInteractiveChangeReason));
mGlobalInteractivity.changeReason));
log.setLatency(interactiveChangeLatency);
log.addTaggedData(
MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason);
log.addTaggedData(MetricsEvent.FIELD_SCREEN_WAKE_REASON,
mGlobalInteractivity.changeReason);
MetricsLogger.action(log);
EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
mPolicy.finishedWakingUp(mInteractiveChangeReason);
mPolicy.finishedWakingUpGlobal(mGlobalInteractivity.changeReason);
});
} else {
// Finished going to sleep...
@@ -563,18 +595,19 @@ public class Notifier {
// Tell the policy we finished going to sleep.
final int offReason = WindowManagerPolicyConstants.translateSleepReasonToOffReason(
mInteractiveChangeReason);
mGlobalInteractivity.changeReason);
mHandler.post(() -> {
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_CLOSE);
log.setSubtype(offReason);
log.setLatency(interactiveChangeLatency);
log.addTaggedData(
MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason);
log.addTaggedData(MetricsEvent.FIELD_SCREEN_SLEEP_REASON,
mGlobalInteractivity.changeReason);
MetricsLogger.action(log);
EventLogTags.writePowerScreenState(
0, offReason, 0, 0, interactiveChangeLatency);
mPolicy.finishedGoingToSleep(mInteractiveChangeReason);
mPolicy.finishedGoingToSleepGlobal(mGlobalInteractivity.changeReason);
});
// Send non-interactive broadcast.
@@ -585,13 +618,63 @@ public class Notifier {
}
}
/**
* Handle late interactive state changes once they are finished so that the system can
* finish pending transitions (such as turning the screen off) before causing
* applications to change state visibly.
*/
private void handleLateInteractiveChange(int groupId) {
synchronized (mLock) {
Interactivity interactivity = mInteractivityByGroupId.get(groupId);
if (interactivity == null) {
Slog.e(TAG, "no Interactivity entry for groupId:" + groupId);
return;
}
final int changeReason = interactivity.changeReason;
if (interactivity.isInteractive) {
mHandler.post(() -> mPolicy.finishedWakingUp(groupId, changeReason));
} else {
mHandler.post(() -> mPolicy.finishedGoingToSleep(groupId, changeReason));
}
}
}
/**
* Called when an individual PowerGroup changes wakefulness.
*/
public void onPowerGroupWakefulnessChanged(int groupId, int groupWakefulness, int changeReason,
int globalWakefulness) {
mHandler.post(() -> mPolicy.onPowerGroupWakefulnessChanged(groupId, groupWakefulness,
changeReason, globalWakefulness));
public void onGroupWakefulnessChangeStarted(int groupId, int wakefulness, int changeReason,
long eventTime) {
final boolean isInteractive = PowerManagerInternal.isInteractive(wakefulness);
boolean isNewGroup = false;
Interactivity interactivity = mInteractivityByGroupId.get(groupId);
if (interactivity == null) {
isNewGroup = true;
interactivity = new Interactivity();
mInteractivityByGroupId.put(groupId, interactivity);
}
if (isNewGroup || interactivity.isInteractive != isInteractive) {
// Finish up late behaviors if needed.
if (interactivity.isChanging) {
handleLateInteractiveChange(groupId);
}
// Handle early behaviors.
interactivity.isInteractive = isInteractive;
interactivity.changeReason = changeReason;
interactivity.changeStartTime = eventTime;
interactivity.isChanging = true;
handleEarlyInteractiveChange(groupId);
}
}
/**
* Called when a PowerGroup has been removed.
*
* @param groupId which group was removed
*/
public void onGroupRemoved(int groupId) {
mInteractivityByGroupId.remove(groupId);
}
/**

View File

@@ -686,6 +686,8 @@ public final class PowerManagerService extends SystemService
@Override
public void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime,
int reason, int uid, int opUid, String opPackageName, String details) {
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
if (wakefulness == WAKEFULNESS_AWAKE) {
// Kick user activity to prevent newly awake group from timing out instantly.
// The dream may end without user activity if the dream app crashes / is updated,
@@ -696,9 +698,8 @@ public final class PowerManagerService extends SystemService
PowerManager.USER_ACTIVITY_EVENT_OTHER, flags, uid);
}
mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
mNotifier.onGroupWakefulnessChangeStarted(groupId, wakefulness, reason, eventTime);
updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
mNotifier.onPowerGroupWakefulnessChanged(groupId, wakefulness, reason,
getGlobalWakefulnessLocked());
updatePowerStateLocked();
}
}
@@ -2152,7 +2153,7 @@ public final class PowerManagerService extends SystemService
mDozeStartInProgress &= (newWakefulness == WAKEFULNESS_DOZING);
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(newWakefulness, reason, eventTime);
mNotifier.onGlobalWakefulnessChangeStarted(newWakefulness, reason, eventTime);
}
mAttentionDetector.onWakefulnessChangeStarted(newWakefulness);
@@ -2163,15 +2164,6 @@ public final class PowerManagerService extends SystemService
if (sQuiescent) {
mDirty |= DIRTY_QUIESCENT;
}
PowerGroup defaultGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
if (defaultGroup.getWakefulnessLocked() == WAKEFULNESS_DOZING) {
// Workaround for b/187231320 where the AOD can get stuck in a "half on /
// half off" state when a non-default-group VirtualDisplay causes the global
// wakefulness to change to awake, even though the default display is
// dozing. We set sandman summoned to restart dreaming to get it unstuck.
// TODO(b/255688811) - fix this so that AOD never gets interrupted at all.
defaultGroup.setSandmanSummonedLocked(true);
}
break;
case WAKEFULNESS_ASLEEP:
@@ -2248,6 +2240,8 @@ public final class PowerManagerService extends SystemService
@GuardedBy("mLock")
void onPowerGroupEventLocked(int event, PowerGroup powerGroup) {
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
final int groupId = powerGroup.getGroupId();
if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
mPowerGroups.delete(groupId);
@@ -2260,6 +2254,11 @@ public final class PowerManagerService extends SystemService
// Kick user activity to prevent newly added group from timing out instantly.
userActivityNoUpdateLocked(powerGroup, mClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_OTHER, /* flags= */ 0, Process.SYSTEM_UID);
mNotifier.onGroupWakefulnessChangeStarted(groupId,
powerGroup.getWakefulnessLocked(), WAKE_REASON_DISPLAY_GROUP_ADDED,
mClock.uptimeMillis());
} else if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
mNotifier.onGroupRemoved(groupId);
}
if (oldWakefulness != newWakefulness) {

View File

@@ -40,6 +40,7 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -1611,7 +1612,8 @@ public class PowerManagerServiceTest {
startSystem();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(anyInt(), anyInt(),
anyLong());
}
@Test
@@ -1630,7 +1632,7 @@ public class PowerManagerServiceTest {
startSystem();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
anyLong());
}
@@ -2112,7 +2114,7 @@ public class PowerManagerServiceTest {
}
@Test
public void testMultiDisplay_defaultDozing_addNewDisplayDefaultGoesBackToDoze() {
public void testMultiDisplay_addNewDisplay_becomeGloballyAwakeButDefaultRemainsDozing() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2142,6 +2144,7 @@ public class PowerManagerServiceTest {
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_DOZING);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
verify(mDreamManagerInternalMock).stopDream(anyBoolean(), anyString());
verify(mDreamManagerInternalMock).startDream(eq(true), anyString());
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
@@ -2152,7 +2155,10 @@ public class PowerManagerServiceTest {
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_DOZING);
verify(mDreamManagerInternalMock, times(2)).startDream(eq(true), anyString());
// Make sure there were no additional calls to stopDream or startDream
verify(mDreamManagerInternalMock, atMost(1)).stopDream(anyBoolean(), anyString());
verify(mDreamManagerInternalMock, atMost(1)).startDream(eq(true), anyString());
}
@Test
@@ -2169,7 +2175,7 @@ public class PowerManagerServiceTest {
}
@Test
public void testMultiDisplay_onlyOneDisplaySleeps_onWakefulnessChangedEventFires() {
public void testMultiDisplay_onlyOneDisplaySleeps_onWakefulnessChangedEventsFire() {
createService();
startSystem();
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
@@ -2177,12 +2183,14 @@ public class PowerManagerServiceTest {
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_ASLEEP);
verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_ASLEEP));
verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
}
@Test
public void testMultiDisplay_bothDisplaysSleep_onWakefulnessChangedEventFiresCorrectly() {
public void testMultiDisplay_bothDisplaysSleep_onWakefulnessChangedEventsFireCorrectly() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2201,10 +2209,10 @@ public class PowerManagerServiceTest {
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0,
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0,
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
@@ -2212,14 +2220,16 @@ public class PowerManagerServiceTest {
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_ASLEEP);
verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(nonDefaultDisplayGroupId),
eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_AWAKE));
verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_ASLEEP));
verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(nonDefaultDisplayGroupId),
eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
verify(mNotifierMock).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
}
@Test
public void testMultiDisplay_separateWakeStates_onWakefulnessChangedEventFiresCorrectly() {
public void testMultiDisplay_separateWakeStates_onWakefulnessChangedEventsFireCorrectly() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
@@ -2255,10 +2265,53 @@ public class PowerManagerServiceTest {
WAKEFULNESS_ASLEEP);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_AWAKE);
verify(mNotifierMock).onPowerGroupWakefulnessChanged(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), anyInt(), eq(WAKEFULNESS_AWAKE));
verify(mNotifierMock, never()).onPowerGroupWakefulnessChanged(
eq(nonDefaultDisplayGroupId), anyInt(), anyInt(), anyInt());
verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(nonDefaultDisplayGroupId),
eq(WAKEFULNESS_AWAKE), eq(PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED), anyLong());
verify(mNotifierMock).onGroupWakefulnessChangeStarted(eq(Display.DEFAULT_DISPLAY_GROUP),
eq(WAKEFULNESS_ASLEEP), eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), anyLong());
verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP),
anyInt(), anyLong());
}
@Test
public void testMultiDisplay_oneDisplayGroupChanges_globalDoesNotChange() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
final int nonDefaultDisplay = Display.DEFAULT_DISPLAY + 1;
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
new AtomicReference<>();
doAnswer((Answer<Void>) invocation -> {
listener.set(invocation.getArgument(0));
return null;
}).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
final DisplayInfo info = new DisplayInfo();
info.displayGroupId = nonDefaultDisplayGroupId;
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
createService();
startSystem();
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
long eventTime = mClock.now();
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, eventTime, 0,
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_ASLEEP);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
verify(mNotifierMock, never()).onGlobalWakefulnessChangeStarted(anyInt(), anyInt(),
anyLong());
verify(mNotifierMock, atMost(1)).onGroupWakefulnessChangeStarted(
eq(nonDefaultDisplayGroupId), eq(WAKEFULNESS_ASLEEP),
eq(PowerManager.GO_TO_SLEEP_REASON_APPLICATION), eq(eventTime));
}
@Test

View File

@@ -233,8 +233,8 @@ class TestPhoneWindowManager {
doNothing().when(mPhoneWindowManager).updateSettings();
doNothing().when(mPhoneWindowManager).screenTurningOn(anyInt(), any());
doNothing().when(mPhoneWindowManager).screenTurnedOn(anyInt());
doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt());
doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt());
doNothing().when(mPhoneWindowManager).startedWakingUp(anyInt(), anyInt());
doNothing().when(mPhoneWindowManager).finishedWakingUp(anyInt(), anyInt());
mPhoneWindowManager.init(new TestInjector(mContext, mWindowManagerFuncsImpl));
mPhoneWindowManager.systemReady();

View File

@@ -114,24 +114,35 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
public void startedWakingUp(@WakeReason int wakeReason) {
public void startedWakingUpGlobal(@WakeReason int reason) {
}
@Override
public void finishedWakingUp(@WakeReason int wakeReason) {
public void finishedWakingUpGlobal(@WakeReason int reason) {
}
@Override
public void startedGoingToSleep(@GoToSleepReason int sleepReason) {
public void startedGoingToSleepGlobal(@GoToSleepReason int reason) {
}
@Override
public void finishedGoingToSleep(@GoToSleepReason int sleepReason) {
public void finishedGoingToSleepGlobal(@GoToSleepReason int reason) {
}
@Override
public void onPowerGroupWakefulnessChanged(int groupId, int wakefulness,
@GoToSleepReason int pmSleepReason, int globalWakefulness) {
public void startedWakingUp(int displayGroupId, @WakeReason int wakeReason) {
}
@Override
public void finishedWakingUp(int displayGroupId, @WakeReason int wakeReason) {
}
@Override
public void startedGoingToSleep(int displayGroupId, @GoToSleepReason int sleepReason) {
}
@Override
public void finishedGoingToSleep(int displayGroupId, @GoToSleepReason int sleepReason) {
}
@Override