Merge "Handle orientation behind for fixed rotation" into tm-qpr-dev
This commit is contained in:
@@ -1575,8 +1575,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
mAtmService.getTaskChangeNotificationController()
|
||||
.notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
|
||||
}
|
||||
// Currently there is no use case from non-activity.
|
||||
if (handleTopActivityLaunchingInDifferentOrientation(r, true /* checkOpening */)) {
|
||||
// The orientation source may not be the top if it uses SCREEN_ORIENTATION_BEHIND.
|
||||
final ActivityRecord topCandidate = !r.mVisibleRequested ? topRunningActivity() : r;
|
||||
if (handleTopActivityLaunchingInDifferentOrientation(
|
||||
topCandidate, r, true /* checkOpening */)) {
|
||||
// Display orientation should be deferred until the top fixed rotation is finished.
|
||||
return false;
|
||||
}
|
||||
@@ -1593,7 +1595,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
|
||||
/**
|
||||
* Returns a valid rotation if the activity can use different orientation than the display.
|
||||
* Otherwise {@link #ROTATION_UNDEFINED}.
|
||||
* Otherwise {@link android.app.WindowConfiguration#ROTATION_UNDEFINED}.
|
||||
*/
|
||||
@Rotation
|
||||
int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
|
||||
@@ -1603,6 +1605,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
|
||||
return ROTATION_UNDEFINED;
|
||||
}
|
||||
if (r.mOrientation == ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
|
||||
final ActivityRecord nextCandidate = getActivity(
|
||||
a -> a.mOrientation != SCREEN_ORIENTATION_UNSET
|
||||
&& a.mOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND,
|
||||
r, false /* includeBoundary */, true /* traverseTopToBottom */);
|
||||
if (nextCandidate != null) {
|
||||
r = nextCandidate;
|
||||
}
|
||||
}
|
||||
if (r.inMultiWindowMode() || r.getRequestedConfigurationOrientation(true /* forDisplay */)
|
||||
== getConfiguration().orientation) {
|
||||
return ROTATION_UNDEFINED;
|
||||
@@ -1616,18 +1627,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return rotation;
|
||||
}
|
||||
|
||||
boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
|
||||
boolean checkOpening) {
|
||||
return handleTopActivityLaunchingInDifferentOrientation(r, r, checkOpening);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to keep display rotation fixed for a while when the activity in different orientation
|
||||
* is launching until the launch animation is done to avoid showing the previous activity
|
||||
* inadvertently in a wrong orientation.
|
||||
*
|
||||
* @param r The launching activity which may change display orientation.
|
||||
* @param orientationSrc It may be different from {@param r} if the launching activity uses
|
||||
* "behind" orientation.
|
||||
* @param checkOpening Whether to check if the activity is animating by transition. Set to
|
||||
* {@code true} if the caller is not sure whether the activity is launching.
|
||||
* @return {@code true} if the fixed rotation is started.
|
||||
*/
|
||||
boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
|
||||
boolean checkOpening) {
|
||||
private boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
|
||||
@NonNull ActivityRecord orientationSrc, boolean checkOpening) {
|
||||
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
|
||||
return false;
|
||||
}
|
||||
@@ -1676,7 +1694,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
// animation is not running (it may be swiping to home).
|
||||
return false;
|
||||
}
|
||||
final int rotation = rotationForActivityInDifferentOrientation(r);
|
||||
final int rotation = rotationForActivityInDifferentOrientation(orientationSrc);
|
||||
if (rotation == ROTATION_UNDEFINED) {
|
||||
// The display rotation won't be changed by current top activity. The client side
|
||||
// adjustments of previous rotated activity should be cleared earlier. Otherwise if
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
@@ -1092,6 +1093,25 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
assertEquals(ROTATION_180, dc.getRotation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrientationBehind() {
|
||||
final ActivityRecord prev = new ActivityBuilder(mAtm).setCreateTask(true)
|
||||
.setScreenOrientation(getRotatedOrientation(mDisplayContent)).build();
|
||||
prev.mVisibleRequested = false;
|
||||
final ActivityRecord top = new ActivityBuilder(mAtm).setCreateTask(true)
|
||||
.setScreenOrientation(SCREEN_ORIENTATION_BEHIND).build();
|
||||
assertNotEquals(WindowConfiguration.ROTATION_UNDEFINED,
|
||||
mDisplayContent.rotationForActivityInDifferentOrientation(top));
|
||||
|
||||
mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0);
|
||||
top.setVisibility(true);
|
||||
mDisplayContent.updateOrientation();
|
||||
// The top uses "behind", so the orientation is decided by the previous.
|
||||
assertEquals(prev, mDisplayContent.getLastOrientationSource());
|
||||
// The top will use the rotation from "prev" with fixed rotation.
|
||||
assertTrue(top.hasFixedRotationTransform());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFixedToUserRotationChanged() {
|
||||
final DisplayContent dc = createNewDisplay();
|
||||
@@ -1650,8 +1670,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
// The condition should reject using fixed rotation because the resumed client in real case
|
||||
// might get display info immediately. And the fixed rotation adjustments haven't arrived
|
||||
// client side so the info may be inconsistent with the requested orientation.
|
||||
verify(mDisplayContent).handleTopActivityLaunchingInDifferentOrientation(eq(app),
|
||||
eq(true) /* checkOpening */);
|
||||
verify(mDisplayContent).updateOrientation(eq(app), anyBoolean());
|
||||
assertFalse(app.isFixedRotationTransforming());
|
||||
assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user