Fixed rotation: home and recents animation
Add support for home and recents animations using the fixed
orientation transform.
When the recent animation is started, the target ActivityRecord is
rotated before being displayed.
Bug: 143053092, 146416687, 147469164
Test: atest WmTests:RecentsAnimationControllerTest
#testRecentViewInFixedPortraitWhenTopAppInLandscape
Change-Id: I194673d621e8c0e8222306915a60f69e4de53b75
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
@@ -84,9 +83,6 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
|
||||
import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
|
||||
|
||||
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
|
||||
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
|
||||
import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
|
||||
@@ -105,12 +101,15 @@ import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
|
||||
import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
|
||||
import static com.android.server.wm.DisplayContentProto.DPI;
|
||||
import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
|
||||
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
|
||||
import static com.android.server.wm.DisplayContentProto.ID;
|
||||
import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
|
||||
import static com.android.server.wm.DisplayContentProto.OVERLAY_WINDOWS;
|
||||
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
|
||||
import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
|
||||
import static com.android.server.wm.DisplayContentProto.ROTATION;
|
||||
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
|
||||
import static com.android.server.wm.DisplayContentProto.SINGLE_TASK_INSTANCE;
|
||||
import static com.android.server.wm.DisplayContentProto.TASKS;
|
||||
import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
|
||||
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
|
||||
@@ -1552,6 +1551,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
token.applyFixedRotationTransform(info, displayFrames, mTmpConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the provided {@link ActivityRecord} can be displayed in an orientation different from the
|
||||
* display's, it will be rotated to match its requested orientation.
|
||||
*
|
||||
* @see #rotationForActivityInDifferentOrientation(ActivityRecord).
|
||||
* @see WindowToken#applyFixedRotationTransform(DisplayInfo, DisplayFrames, Configuration)
|
||||
*/
|
||||
void rotateInDifferentOrientationIfNeeded(ActivityRecord activityRecord) {
|
||||
int rotation = rotationForActivityInDifferentOrientation(activityRecord);
|
||||
if (rotation != NO_ROTATION) {
|
||||
startFixedRotationTransform(activityRecord, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rotation of the display.
|
||||
*
|
||||
|
||||
@@ -423,6 +423,11 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
|
||||
mService.mWindowPlacerLocked.performSurfacePlacement();
|
||||
|
||||
// If the target activity has a fixed orientation which is different from the current top
|
||||
// activity, it will be rotated before being shown so we avoid a screen rotation
|
||||
// animation when showing the Recents view.
|
||||
mDisplayContent.rotateInDifferentOrientationIfNeeded(mTargetActivityRecord);
|
||||
|
||||
// Notify that the animation has started
|
||||
if (mStatusBar != null) {
|
||||
mStatusBar.onRecentsAnimationStateChanged(true /* running */);
|
||||
@@ -695,6 +700,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(
|
||||
mTargetActivityRecord.token);
|
||||
}
|
||||
if (mTargetActivityRecord.hasFixedRotationTransform()) {
|
||||
mTargetActivityRecord.clearFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
|
||||
// Notify that the animation has ended
|
||||
|
||||
@@ -53,6 +53,8 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
||||
import android.app.ActivityManager.TaskSnapshot;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
@@ -330,6 +332,44 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
||||
assertTrue(activity.shouldAnimate(TRANSIT_ACTIVITY_CLOSE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
|
||||
mWm.mIsFixedRotationTransformEnabled = true;
|
||||
mWm.setRecentsAnimationController(mController);
|
||||
|
||||
final ActivityStack homeStack = mDisplayContent.getOrCreateStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
|
||||
final ActivityRecord homeAppWindow =
|
||||
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
|
||||
.setStack(homeStack)
|
||||
.setCreateTask(true)
|
||||
.build();
|
||||
final ActivityRecord appWindow = createActivityRecord(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
final WindowState win0 = createWindow(null, TYPE_BASE_APPLICATION, appWindow, "win1");
|
||||
appWindow.addWindow(win0);
|
||||
|
||||
final ActivityRecord landActivity = createActivityRecord(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
landActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, landActivity, "win1");
|
||||
landActivity.addWindow(win1);
|
||||
|
||||
assertEquals(landActivity.getTask().getTopVisibleActivity(), landActivity);
|
||||
assertEquals(landActivity.findMainWindow(), win1);
|
||||
|
||||
// Ensure that the display is in Landscape
|
||||
landActivity.onDescendantOrientationChanged(landActivity.token, landActivity);
|
||||
assertEquals(Configuration.ORIENTATION_LANDSCAPE,
|
||||
mDisplayContent.getConfiguration().orientation);
|
||||
|
||||
mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeAppWindow);
|
||||
|
||||
// Check that the home app is in portrait
|
||||
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
||||
homeAppWindow.getConfiguration().orientation);
|
||||
}
|
||||
|
||||
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
|
||||
verify(binder, atLeast(0)).asBinder();
|
||||
verifyNoMoreInteractions(binder);
|
||||
|
||||
Reference in New Issue
Block a user