Avoid getting crashed by slow transition
This avoids extreme cases when the device is slow or the load of
system/systemui is heavy.
SystemUI crashes:
1. OPEN transition T1
2. Swipe up, queued transition T2
3. T1 timed out, moveToPlaying
(added to mPlayingTransitions)
4. T2 starts collecting
5. startTransition of T1
(STATE_PLAYING -> STATE_STARTED)
6. finishTransition from RemoteTransitionHandler
7. Got crash by "Can't finish a non-playing transition"
(in mPlayingTransitions but with STATE_STARTED)
System server crashes:
When executing a non-CHANGE transition with a display change,
(open an activity and request to change display orientation)
if IDisplayChangeWindowCallback#continueDisplayChange is called
from remote after transition timeout, the exception "Trying to
rotate outside a transition" will throw at display thread.
Bug: 265852118
Bug: 261645736
Test: Set break point at WindowOrganizerController#startTransition
to simulate the slowness. Launch app, swipe up, rotate.
The device still works normally after resuming the break point.
Test: CtsWindowManagerDeviceTestCases
Change-Id: Ia0d97823886eff1c935a0cd7f6f6ac6abf3659d5
This commit is contained in:
@@ -605,11 +605,16 @@ public class ActivityStartController {
|
||||
final Task task = r.getTask();
|
||||
mService.deferWindowLayout();
|
||||
try {
|
||||
r.mTransitionController.requestStartTransition(transition,
|
||||
task, remoteTransition, null /* displayChange */);
|
||||
r.mTransitionController.collect(task);
|
||||
r.mTransitionController.setTransientLaunch(r,
|
||||
TaskDisplayArea.getRootTaskAbove(rootTask));
|
||||
final TransitionController controller = r.mTransitionController;
|
||||
if (controller.getTransitionPlayer() != null) {
|
||||
controller.requestStartTransition(transition, task, remoteTransition,
|
||||
null /* displayChange */);
|
||||
controller.collect(task);
|
||||
controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
|
||||
} else {
|
||||
// The transition player might be died when executing the queued transition.
|
||||
transition.abort();
|
||||
}
|
||||
task.moveToFront("startExistingRecents");
|
||||
task.mInResumeTopActivity = true;
|
||||
task.resumeTopActivity(null /* prev */, options, true /* deferPause */);
|
||||
|
||||
@@ -635,7 +635,8 @@ public class DisplayRotation {
|
||||
|
||||
if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
|
||||
if (!mDisplayContent.mTransitionController.isCollecting()) {
|
||||
throw new IllegalStateException("Trying to rotate outside a transition");
|
||||
// The remote may be too slow to response before transition timeout.
|
||||
Slog.e(TAG, "Trying to continue rotation outside a transition");
|
||||
}
|
||||
mDisplayContent.mTransitionController.collect(mDisplayContent);
|
||||
}
|
||||
|
||||
@@ -418,7 +418,10 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
if (mState < STATE_COLLECTING) {
|
||||
throw new IllegalStateException("Can't start Transition which isn't collecting.");
|
||||
} else if (mState >= STATE_STARTED) {
|
||||
Slog.w(TAG, "Transition already started: " + mSyncId);
|
||||
Slog.w(TAG, "Transition already started id=" + mSyncId + " state=" + mState);
|
||||
// The transition may be aborted (STATE_ABORT) or timed out (STATE_PLAYING by
|
||||
// SyncGroup#finishNow), so do not revert the state to STATE_STARTED.
|
||||
return;
|
||||
}
|
||||
mState = STATE_STARTED;
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
|
||||
|
||||
Reference in New Issue
Block a user