Fixed rotation: rotate wallpaper
The wallpaper should be rotated if its target WindowState is rotated. The fixed rotation is applied to the WallpaperWindowToken and the offsets are computed using the overriden DisplayInfo contained in the WindowToken.ForcedRotationState. Test: atest WmTests:RecentsAnimationControllerTest#testWallpaperHasFixedRotationApplied Bug: 143053092, 148000485, 147999946 Change-Id: I244b3cb81dd29995a1a9181949e4f3f973816825
This commit is contained in:
@@ -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;
|
||||
@@ -836,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;
|
||||
@@ -67,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
|
||||
@@ -370,6 +376,69 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
|
||||
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