summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java16
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackController.java21
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java56
4 files changed, 93 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 00b2a58dbe8f..7f03778ab1c7 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -819,6 +819,22 @@ class ActivityStack extends Task {
mRootWindowContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
mRootWindowContainer.resumeFocusedStacksTopActivities();
+
+ final boolean pinnedToFullscreen = currentMode == WINDOWING_MODE_PINNED
+ && windowingMode == WINDOWING_MODE_FULLSCREEN;
+ if (pinnedToFullscreen && topActivity != null && !isForceHidden()) {
+ mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(true);
+ try {
+ // Report orientation as soon as possible so that the display can freeze earlier if
+ // the display orientation will be changed. Because the surface bounds of activity
+ // may have been set to fullscreen but the activity hasn't redrawn its content yet,
+ // the rotation animation needs to capture snapshot earlier to avoid animating from
+ // an intermediate state.
+ topActivity.reportDescendantOrientationChangeIfNeeded();
+ } finally {
+ mDisplayContent.getPinnedStackController().setPipWindowingModeChanging(false);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 8903776469db..59181a64f423 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1481,6 +1481,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
// has it own policy for bounds, the activity bounds based on parent is unknown.
return false;
}
+ if (mPinnedStackControllerLocked.isPipActiveOrWindowingModeChanging()) {
+ // Use normal rotation animation because seamless PiP rotation is not supported yet.
+ return false;
+ }
setFixedRotationLaunchingApp(r, rotation);
return true;
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 56312aa1b0b8..52ada472f0aa 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -23,7 +23,6 @@ import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
@@ -33,8 +32,6 @@ import android.view.DisplayInfo;
import android.view.IPinnedStackController;
import android.view.IPinnedStackListener;
-import com.android.server.UiThread;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -61,7 +58,6 @@ class PinnedStackController {
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
- private final Handler mHandler = UiThread.getHandler();
private IPinnedStackListener mPinnedStackListener;
private final PinnedStackListenerDeathHandler mPinnedStackListenerDeathHandler =
@@ -69,6 +65,9 @@ class PinnedStackController {
private final PinnedStackControllerCallback mCallbacks = new PinnedStackControllerCallback();
+ /** Whether the PiP is entering or leaving. */
+ private boolean mIsPipWindowingModeChanging;
+
private boolean mIsImeShowing;
private int mImeHeight;
@@ -161,6 +160,20 @@ class PinnedStackController {
Float.compare(aspectRatio, mMaxAspectRatio) <= 0;
}
+ /** Returns {@code true} if the PiP is on screen or is changing windowing mode. */
+ boolean isPipActiveOrWindowingModeChanging() {
+ if (mIsPipWindowingModeChanging) {
+ return true;
+ }
+ final Task pinnedTask = mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask();
+ return pinnedTask != null && pinnedTask.hasChild();
+ }
+
+ /** Sets whether a visible stack is changing from or to pinned mode. */
+ void setPipWindowingModeChanging(boolean isPipWindowingModeChanging) {
+ mIsPipWindowingModeChanging = isPipWindowingModeChanging;
+ }
+
/**
* Activity is hidden (either stopped or removed), resets the last saved snap fraction
* so that the default bounds will be returned for the next session.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 7197ce9c22aa..4ad7dff87072 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -16,7 +16,10 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
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.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -73,6 +76,8 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import android.annotation.SuppressLint;
@@ -1168,6 +1173,57 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
+ public void testNoFixedRotationWithPip() {
+ mWm.mIsFixedRotationTransformEnabled = true;
+ // Make resume-top really update the activity state.
+ doReturn(false).when(mWm.mAtmService).isBooting();
+ doReturn(true).when(mWm.mAtmService).isBooted();
+ // Speed up the test by a few seconds.
+ mWm.mAtmService.deferWindowLayout();
+ doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+
+ final DisplayContent displayContent = mWm.mRoot.getDefaultDisplay();
+ final Configuration displayConfig = displayContent.getConfiguration();
+ final ActivityRecord pinnedActivity = createActivityRecord(displayContent,
+ WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
+ final Task pinnedTask = pinnedActivity.getRootTask();
+ final ActivityRecord homeActivity = WindowTestUtils.createTestActivityRecord(
+ displayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask());
+ if (displayConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
+ homeActivity.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ pinnedActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ } else {
+ homeActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ pinnedActivity.setOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ }
+ final int homeConfigOrientation = homeActivity.getRequestedConfigurationOrientation();
+ final int pinnedConfigOrientation = pinnedActivity.getRequestedConfigurationOrientation();
+
+ assertEquals(homeConfigOrientation, displayConfig.orientation);
+
+ clearInvocations(mWm);
+ // Leave PiP to fullscreen. The orientation can be updated from
+ // ActivityRecord#reportDescendantOrientationChangeIfNeeded.
+ pinnedTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ homeActivity.setState(ActivityStack.ActivityState.STOPPED, "test");
+
+ assertFalse(displayContent.hasTopFixedRotationLaunchingApp());
+ verify(mWm, atLeastOnce()).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+ assertEquals(pinnedConfigOrientation, displayConfig.orientation);
+ assertFalse(displayContent.getPinnedStackController().isPipActiveOrWindowingModeChanging());
+
+ clearInvocations(mWm);
+ // Enter PiP from fullscreen. The orientation can be updated from
+ // ensure-visibility/resume-focused-stack -> ActivityRecord#makeActiveIfNeeded -> resume.
+ pinnedTask.setWindowingMode(WINDOWING_MODE_PINNED);
+
+ assertFalse(displayContent.hasTopFixedRotationLaunchingApp());
+ verify(mWm, atLeastOnce()).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
+ assertEquals(homeConfigOrientation, displayConfig.orientation);
+ assertTrue(displayContent.getPinnedStackController().isPipActiveOrWindowingModeChanging());
+ }
+
+ @Test
public void testRemoteRotation() {
DisplayContent dc = createNewDisplay();