Do not affect WindowContainer#getOrientation by animation
If an activity is launched with ActivityOptions# makeSceneTransitionAnimation, it will invoke convertToTranslucent/ convertFromTranslucent to change mOccludesParent temporally for showing shared elements above the previous activity. And because WindowContainer#getOrientation() skips the requested orientation if fillsParent() returns false. if fillsParent() uses mOccludesParent, the activity may lose the orientation during the transition which may cause unexpected display orientation change. Fixes: 228937289 Test: ActivityRecordTests#testShouldStartWhenMakeClientActive Change-Id: I03f70af26d49fdbdcba498b975bc65fcd7bf7c47
This commit is contained in:
@@ -661,10 +661,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
|
||||
/**
|
||||
* The activity is opaque and fills the entire space of this task.
|
||||
* @see WindowContainer#fillsParent()
|
||||
* @see #occludesParent()
|
||||
*/
|
||||
private boolean mOccludesParent;
|
||||
|
||||
/**
|
||||
* Unlike {@link #mOccludesParent} which can be changed at runtime. This is a static attribute
|
||||
* from the style of activity. Because we don't want {@link WindowContainer#getOrientation()}
|
||||
* to be affected by the temporal state of {@link ActivityClientController#convertToTranslucent}
|
||||
* when running ANIM_SCENE_TRANSITION.
|
||||
* @see WindowContainer#fillsParent()
|
||||
*/
|
||||
private final boolean mFillsParent;
|
||||
|
||||
// The input dispatching timeout for this application token in milliseconds.
|
||||
long mInputDispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||
|
||||
@@ -1956,8 +1965,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
// This style is propagated to the main window attributes with
|
||||
// FLAG_SHOW_WALLPAPER from PhoneWindow#generateLayout.
|
||||
|| ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
|
||||
mFillsParent = mOccludesParent;
|
||||
noDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false);
|
||||
} else {
|
||||
mFillsParent = mOccludesParent = true;
|
||||
noDisplay = false;
|
||||
}
|
||||
|
||||
@@ -2852,7 +2863,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
|
||||
@Override
|
||||
boolean fillsParent() {
|
||||
return occludesParent(true /* includingFinishing */);
|
||||
return mFillsParent;
|
||||
}
|
||||
|
||||
/** Returns true if this activity is not finishing, is opaque and fills the entire space of
|
||||
|
||||
@@ -757,6 +757,8 @@ public class ActivityRecordTests extends WindowTestsBase {
|
||||
final ActivityRecord activity = createActivityWithTask();
|
||||
ActivityRecord topActivity = new ActivityBuilder(mAtm).setTask(activity.getTask()).build();
|
||||
topActivity.setOccludesParent(false);
|
||||
// The requested occluding state doesn't affect whether it fills parent.
|
||||
assertTrue(topActivity.fillsParent());
|
||||
activity.setState(STOPPED, "Testing");
|
||||
activity.setVisibility(true);
|
||||
activity.makeActiveIfNeeded(null /* activeActivity */);
|
||||
@@ -1218,7 +1220,7 @@ public class ActivityRecordTests extends WindowTestsBase {
|
||||
task.setPausingActivity(currentTop);
|
||||
currentTop.finishing = true;
|
||||
currentTop.setState(PAUSED, "test");
|
||||
currentTop.completeFinishing("completePauseLocked");
|
||||
currentTop.completeFinishing(false /* updateVisibility */, "completePause");
|
||||
|
||||
// Current top becomes stopping because it is visible and the next is invisible.
|
||||
assertEquals(STOPPING, currentTop.getState());
|
||||
|
||||
@@ -46,7 +46,6 @@ import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -89,14 +88,6 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
||||
mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, int activityType) {
|
||||
final ActivityRecord r = super.createActivityRecord(dc, windowingMode, activityType);
|
||||
// Ensure that ActivityRecord#setOccludesParent takes effect.
|
||||
doCallRealMethod().when(r).fillsParent();
|
||||
return r;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipOccludedActivityCloseTransition() {
|
||||
final ActivityRecord behind = createActivityRecord(mDisplayContent,
|
||||
@@ -135,7 +126,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
final ActivityRecord translucentOpening = createActivityRecord(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
translucentOpening.setOccludesParent(false);
|
||||
doReturn(false).when(translucentOpening).fillsParent();
|
||||
translucentOpening.setVisible(false);
|
||||
mDisplayContent.prepareAppTransition(TRANSIT_OPEN);
|
||||
mDisplayContent.mOpeningApps.add(behind);
|
||||
@@ -153,7 +144,7 @@ public class AppTransitionControllerTest extends WindowTestsBase {
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
final ActivityRecord translucentClosing = createActivityRecord(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
translucentClosing.setOccludesParent(false);
|
||||
doReturn(false).when(translucentClosing).fillsParent();
|
||||
mDisplayContent.prepareAppTransition(TRANSIT_CLOSE);
|
||||
mDisplayContent.mClosingApps.add(translucentClosing);
|
||||
assertEquals(WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE,
|
||||
|
||||
@@ -1156,10 +1156,6 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
|
||||
spyOn(activity);
|
||||
if (mTask != null) {
|
||||
// fullscreen value is normally read from resources in ctor, so for testing we need
|
||||
// to set it somewhere else since we can't mock resources.
|
||||
doReturn(true).when(activity).occludesParent();
|
||||
doReturn(true).when(activity).fillsParent();
|
||||
mTask.addChild(activity);
|
||||
if (mOnTop) {
|
||||
// Move the task to front after activity is added.
|
||||
|
||||
Reference in New Issue
Block a user