Merge "Prevents activity being stopped while folding/unfolding device" into tm-qpr-dev

This commit is contained in:
Andrii Kulian
2023-04-27 01:34:10 +00:00
committed by Android (Google) Code Review
9 changed files with 73 additions and 13 deletions

View File

@@ -2094,14 +2094,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
&& !mScreenOffBecauseOfProximity) {
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
unblockScreenOn();
mWindowManagerPolicy.screenTurnedOff(mDisplayId);
mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
} else if (!isOff
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_OFF) {
// We told policy already that screen was turning off, but now we changed our minds.
// Complete the full state transition on -> turningOff -> off.
unblockScreenOff();
mWindowManagerPolicy.screenTurnedOff(mDisplayId);
mWindowManagerPolicy.screenTurnedOff(mDisplayId, mIsInTransition);
setReportedScreenState(REPORTED_TO_POLICY_SCREEN_OFF);
}
if (!isOff

View File

@@ -4756,11 +4756,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Called on the DisplayManager's DisplayPowerController thread.
@Override
public void screenTurnedOff(int displayId) {
public void screenTurnedOff(int displayId, boolean isSwappingDisplay) {
if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off...");
if (displayId == DEFAULT_DISPLAY) {
updateScreenOffSleepToken(true);
updateScreenOffSleepToken(true, isSwappingDisplay);
mRequestedOrSleepingDefaultDisplay = false;
mDefaultDisplayPolicy.screenTurnedOff();
synchronized (mLock) {
@@ -4811,7 +4811,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (displayId == DEFAULT_DISPLAY) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
0 /* cookie */);
updateScreenOffSleepToken(false);
updateScreenOffSleepToken(false /* acquire */, false /* isSwappingDisplay */);
mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
mBootAnimationDismissable = false;
@@ -5330,9 +5330,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
// TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
private void updateScreenOffSleepToken(boolean acquire) {
private void updateScreenOffSleepToken(boolean acquire, boolean isSwappingDisplay) {
if (acquire) {
mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY);
mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY, isSwappingDisplay);
} else {
mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY);
}

View File

@@ -829,8 +829,10 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
/**
* Called when the display has turned off.
* @param displayId The display to apply to.
* @param isSwappingDisplay Whether the display is swapping to another physical display.
*/
public void screenTurnedOff(int displayId);
void screenTurnedOff(int displayId, boolean isSwappingDisplay);
public interface ScreenOnListener {
void onScreenOn();

View File

@@ -8417,6 +8417,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return inTransitionSelfOrParent();
}
boolean isDisplaySleepingAndSwapping() {
for (int i = mDisplayContent.mAllSleepTokens.size() - 1; i >= 0; i--) {
RootWindowContainer.SleepToken sleepToken = mDisplayContent.mAllSleepTokens.get(i);
if (sleepToken.isDisplaySwapping()) {
return true;
}
}
return false;
}
/**
* Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
* orientation then aspect ratio restrictions are also already respected.

View File

@@ -140,6 +140,13 @@ public abstract class ActivityTaskManagerInternal {
*/
void acquire(int displayId);
/**
* Acquires a sleep token.
* @param displayId The display to apply to.
* @param isSwappingDisplay Whether the display is swapping to another physical display.
*/
void acquire(int displayId, boolean isSwappingDisplay);
/**
* Releases the sleep token.
* @param displayId The display to apply to.

View File

@@ -4747,10 +4747,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void acquire(int displayId) {
acquire(displayId, false /* isSwappingDisplay */);
}
@Override
public void acquire(int displayId, boolean isSwappingDisplay) {
synchronized (mGlobalLock) {
if (!mSleepTokens.contains(displayId)) {
mSleepTokens.append(displayId,
mRootWindowContainer.createSleepToken(mTag, displayId));
mRootWindowContainer.createSleepToken(mTag, displayId,
isSwappingDisplay));
updateSleepIfNeededLocked();
}
}

View File

@@ -179,6 +179,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// How long we can hold the launch wake lock before giving up.
private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
// How long we delay processing the stopping and finishing activities.
private static final int SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS = 200;
/** How long we wait until giving up on the activity telling us it released the top state. */
private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
@@ -1933,13 +1936,15 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
boolean processPausingActivities, String reason) {
// Stop any activities that are scheduled to do so but have been waiting for the transition
// animation to finish.
boolean displaySwapping = false;
ArrayList<ActivityRecord> readyToStopActivities = null;
for (int i = mStoppingActivities.size() - 1; i >= 0; --i) {
final ActivityRecord s = mStoppingActivities.get(i);
final boolean animating = s.isInTransition();
displaySwapping |= s.isDisplaySleepingAndSwapping();
ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
+ "finishing=%s", s, s.nowVisible, animating, s.finishing);
if (!animating || mService.mShuttingDown) {
if ((!animating && !displaySwapping) || mService.mShuttingDown) {
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
// a delayed idle to reprocess it again
@@ -1958,6 +1963,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
}
// Stopping activities are deferred processing if the display is swapping. Check again
// later to ensure the stopping activities can be stopped after display swapped.
if (displaySwapping) {
mHandler.postDelayed(() -> {
synchronized (mService.mGlobalLock) {
scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
}
}, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
}
final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
for (int i = 0; i < numReadyStops; i++) {
final ActivityRecord r = readyToStopActivities.get(i);

View File

@@ -2569,6 +2569,10 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
SleepToken createSleepToken(String tag, int displayId) {
return createSleepToken(tag, displayId, false /* isSwappingDisplay */);
}
SleepToken createSleepToken(String tag, int displayId, boolean isSwappingDisplay) {
final DisplayContent display = getDisplayContent(displayId);
if (display == null) {
throw new IllegalArgumentException("Invalid display: " + displayId);
@@ -2577,7 +2581,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
final int tokenKey = makeSleepTokenKey(tag, displayId);
SleepToken token = mSleepTokens.get(tokenKey);
if (token == null) {
token = new SleepToken(tag, displayId);
token = new SleepToken(tag, displayId, isSwappingDisplay);
mSleepTokens.put(tokenKey, token);
display.mAllSleepTokens.add(token);
ProtoLog.d(WM_DEBUG_STATES, "Create sleep token: tag=%s, displayId=%d", tag, displayId);
@@ -3526,18 +3530,34 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
private final String mTag;
private final long mAcquireTime;
private final int mDisplayId;
private final boolean mIsSwappingDisplay;
final int mHashKey;
SleepToken(String tag, int displayId) {
// The display could remain in sleep after the physical display swapped, adding a 1
// seconds display swap timeout to prevent activities staying in PAUSED state.
// Otherwise, the sleep token should be removed once display turns back on after swapped.
private static final long DISPLAY_SWAP_TIMEOUT = 1000;
SleepToken(String tag, int displayId, boolean isSwappingDisplay) {
mTag = tag;
mDisplayId = displayId;
mAcquireTime = SystemClock.uptimeMillis();
mIsSwappingDisplay = isSwappingDisplay;
mHashKey = makeSleepTokenKey(mTag, mDisplayId);
}
public boolean isDisplaySwapping() {
long now = SystemClock.uptimeMillis();
if (now - mAcquireTime > DISPLAY_SWAP_TIMEOUT) {
return false;
}
return mIsSwappingDisplay;
}
@Override
public String toString() {
return "{\"" + mTag + "\", display " + mDisplayId
+ (mIsSwappingDisplay ? " is swapping " : "")
+ ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
}

View File

@@ -147,7 +147,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
public void screenTurnedOff(int displayId) {
public void screenTurnedOff(int displayId, boolean isSwappingDisplay) {
}
@Override