Merge changes I244b3cb8,I194673d6
* changes: Fixed rotation: rotate wallpaper Fixed rotation: home and recents animation
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.
|
||||
*
|
||||
|
||||
@@ -34,6 +34,7 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
|
||||
import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager.TaskSnapshot;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.graphics.Point;
|
||||
@@ -423,6 +424,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 +701,9 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(
|
||||
mTargetActivityRecord.token);
|
||||
}
|
||||
if (mTargetActivityRecord.hasFixedRotationTransform()) {
|
||||
mTargetActivityRecord.clearFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
|
||||
// Notify that the animation has ended
|
||||
@@ -828,6 +837,19 @@ public class RecentsAnimationController implements DeathRecipient {
|
||||
return task != null && isAnimatingTask(task) && !isTargetApp(windowState.mActivityRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the animation target ActivityRecord has a fixed rotation ({@link
|
||||
* WindowToken#hasFixedRotationTransform()}, the provided wallpaper will be rotated accordingly.
|
||||
*
|
||||
* This avoids any screen rotation animation when animating to the Recents view.
|
||||
*/
|
||||
void applyFixedRotationTransformIfNeeded(@NonNull WindowToken wallpaper) {
|
||||
if (mTargetActivityRecord == null) {
|
||||
return;
|
||||
}
|
||||
wallpaper.applyFixedRotationTransform(mTargetActivityRecord);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
class TaskAnimationAdapter implements AnimationAdapter {
|
||||
|
||||
|
||||
@@ -122,10 +122,37 @@ class WallpaperWindowToken extends WindowToken {
|
||||
mDisplayContent.setLayoutNeeded();
|
||||
}
|
||||
|
||||
final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
|
||||
final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
|
||||
|
||||
if (visible) {
|
||||
final WindowState wallpaperTarget = wallpaperController.getWallpaperTarget();
|
||||
final RecentsAnimationController recentsAnimationController =
|
||||
mWmService.getRecentsAnimationController();
|
||||
if (wallpaperTarget != null
|
||||
&& recentsAnimationController != null
|
||||
&& recentsAnimationController.isAnimatingTask(wallpaperTarget.getTask())) {
|
||||
// If the Recents animation is running, and the wallpaper target is the animating
|
||||
// task we want the wallpaper to be rotated in the same orientation as the
|
||||
// RecentsAnimation's target (e.g the launcher)
|
||||
recentsAnimationController.applyFixedRotationTransformIfNeeded(this);
|
||||
} else if (wallpaperTarget != null
|
||||
&& wallpaperTarget.mToken.hasFixedRotationTransform()) {
|
||||
// If the wallpaper target has a fixed rotation, we want the wallpaper to follow its
|
||||
// rotation
|
||||
applyFixedRotationTransform(wallpaperTarget.mToken);
|
||||
} else if (hasFixedRotationTransform()) {
|
||||
clearFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
|
||||
DisplayInfo displayInfo = getFixedRotationTransformDisplayInfo();
|
||||
if (displayInfo == null) {
|
||||
displayInfo = mDisplayContent.getDisplayInfo();
|
||||
}
|
||||
|
||||
final int dw = displayInfo.logicalWidth;
|
||||
final int dh = displayInfo.logicalHeight;
|
||||
final WallpaperController wallpaperController = mDisplayContent.mWallpaperController;
|
||||
|
||||
for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
|
||||
final WindowState wallpaper = mChildren.get(wallpaperNdx);
|
||||
|
||||
|
||||
@@ -377,6 +377,19 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the {@link FixedRotationTransformState} (if any) from the other WindowToken to this
|
||||
* one.
|
||||
*/
|
||||
void applyFixedRotationTransform(WindowToken other) {
|
||||
final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
|
||||
if (fixedRotationState != null) {
|
||||
applyFixedRotationTransform(fixedRotationState.mDisplayInfo,
|
||||
fixedRotationState.mDisplayFrames,
|
||||
fixedRotationState.mRotatedOverrideConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears the transformation and continue updating the orientation change of display. */
|
||||
void clearFixedRotationTransform() {
|
||||
if (mFixedRotationTransformState == null) {
|
||||
|
||||
@@ -20,7 +20,9 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
|
||||
@@ -53,6 +55,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;
|
||||
@@ -65,12 +69,16 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
|
||||
|
||||
import com.google.common.truth.Truth;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Build/Install/Run:
|
||||
* atest WmTests:RecentsAnimationControllerTest
|
||||
@@ -330,6 +338,107 @@ 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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWallpaperHasFixedRotationApplied() {
|
||||
mWm.mIsFixedRotationTransformEnabled = true;
|
||||
mWm.setRecentsAnimationController(mController);
|
||||
|
||||
// Create a portrait home stack, a wallpaper and a landscape application displayed on top.
|
||||
|
||||
// Home stack
|
||||
final ActivityStack homeStack = mDisplayContent.getOrCreateStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
|
||||
final ActivityRecord homeActivity =
|
||||
new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
|
||||
.setStack(homeStack)
|
||||
.setCreateTask(true)
|
||||
.build();
|
||||
homeActivity.setOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
|
||||
final WindowState homeWindow = createWindow(null, TYPE_BASE_APPLICATION, homeActivity,
|
||||
"homeWindow");
|
||||
homeActivity.addWindow(homeWindow);
|
||||
homeWindow.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
|
||||
|
||||
// Landscape application
|
||||
final ActivityRecord activity = createActivityRecord(mDisplayContent,
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
|
||||
final WindowState applicationWindow = createWindow(null, TYPE_BASE_APPLICATION, activity,
|
||||
"applicationWindow");
|
||||
activity.addWindow(applicationWindow);
|
||||
activity.setOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
|
||||
|
||||
// Wallpaper
|
||||
final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm,
|
||||
mock(IBinder.class), true, mDisplayContent, true /* ownerCanManageAppTokens */);
|
||||
final WindowState wallpaperWindow = createWindow(null, TYPE_WALLPAPER, wallpaperWindowToken,
|
||||
"wallpaperWindow");
|
||||
|
||||
// Make sure the landscape activity is on top and the display is in landscape
|
||||
activity.moveFocusableActivityToTop("test");
|
||||
mDisplayContent.getConfiguration().windowConfiguration.setRotation(
|
||||
mDisplayContent.getRotation());
|
||||
|
||||
|
||||
spyOn(mDisplayContent.mWallpaperController);
|
||||
doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible();
|
||||
|
||||
// Start the recents animation
|
||||
mController
|
||||
.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray(), homeActivity);
|
||||
|
||||
mDisplayContent.mWallpaperController.adjustWallpaperWindows();
|
||||
|
||||
// Check preconditions
|
||||
ArrayList<WallpaperWindowToken> wallpapers = new ArrayList<>(1);
|
||||
mDisplayContent.forAllWallpaperWindows(wallpapers::add);
|
||||
|
||||
Truth.assertThat(wallpapers).hasSize(1);
|
||||
Truth.assertThat(wallpapers.get(0).getTopChild()).isEqualTo(wallpaperWindow);
|
||||
|
||||
// Actual check
|
||||
assertEquals(Configuration.ORIENTATION_PORTRAIT,
|
||||
wallpapers.get(0).getConfiguration().orientation);
|
||||
}
|
||||
|
||||
private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
|
||||
verify(binder, atLeast(0)).asBinder();
|
||||
verifyNoMoreInteractions(binder);
|
||||
|
||||
Reference in New Issue
Block a user