Merge "Ensure we use the fullscreen stack bounds when expanding PiP."
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7a3326b..30b267f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7694,7 +7694,7 @@
aspectRatio);
mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode",
bounds, true /* moveHomeStackToFront */);
- final ActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
+ final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
stack.setPictureInPictureAspectRatio(aspectRatio);
stack.setPictureInPictureActions(actions);
@@ -7748,9 +7748,9 @@
// Only update the saved args from the args that are set
r.pictureInPictureArgs.copyOnlySet(args);
- final ActivityStack stack = r.getStack();
- if (stack.getStackId() == PINNED_STACK_ID) {
+ if (r.getStack().getStackId() == PINNED_STACK_ID) {
// If the activity is already in picture-in-picture, update the pinned stack now
+ final PinnedActivityStack stack = r.getStack();
stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio());
stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
}
@@ -10312,7 +10312,7 @@
synchronized (this) {
if (animate) {
if (stackId == PINNED_STACK_ID) {
- final ActivityStack pinnedStack =
+ final PinnedActivityStack pinnedStack =
mStackSupervisor.getStack(PINNED_STACK_ID);
pinnedStack.animateResizePinnedStack(bounds, animationDuration);
} else {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 6f89cf2..aef429e 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -880,8 +880,8 @@
/**
* @return Stack value from current task, null if there is no task.
*/
- ActivityStack getStack() {
- return task != null ? task.getStack() : null;
+ <T extends ActivityStack> T getStack() {
+ return task != null ? (T) task.getStack() : null;
}
boolean changeWindowTranslucency(boolean toOpaque) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index b948c15..7f7caff 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -84,7 +84,6 @@
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityController;
-import android.app.RemoteAction;
import android.app.ResultInfo;
import android.content.ComponentName;
import android.content.Intent;
@@ -135,7 +134,8 @@
/**
* State and management of a single stack of activities.
*/
-final class ActivityStack extends ConfigurationContainer implements StackWindowListener {
+class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
+ implements StackWindowListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
@@ -247,7 +247,7 @@
final ActivityManagerService mService;
private final WindowManagerService mWindowManager;
- private StackWindowController mWindowContainerController;
+ T mWindowContainerController;
private final RecentTasks mRecentTasks;
/**
@@ -462,14 +462,18 @@
? new LaunchingTaskPositioner() : null;
final ActivityStackSupervisor.ActivityDisplay display = mActivityContainer.mActivityDisplay;
mTmpRect2.setEmpty();
- mWindowContainerController = new StackWindowController(mStackId, this,
- display.mDisplayId, onTop, mTmpRect2);
+ mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
+ mTmpRect2);
activityContainer.mStack = this;
mStackSupervisor.mActivityContainers.put(mStackId, activityContainer);
postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
}
- StackWindowController getWindowContainerController() {
+ T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
+ return (T) new StackWindowController(mStackId, this, displayId, onTop, outBounds);
+ }
+
+ T getWindowContainerController() {
return mWindowContainerController;
}
@@ -540,18 +544,6 @@
mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
}
- void animateResizePinnedStack(Rect bounds, int animationDuration) {
- mWindowContainerController.animateResizePinnedStack(bounds, animationDuration);
- }
-
- void setPictureInPictureAspectRatio(float aspectRatio) {
- mWindowContainerController.setPictureInPictureAspectRatio(aspectRatio);
- }
-
- void setPictureInPictureActions(List<RemoteAction> actions) {
- mWindowContainerController.setPictureInPictureActions(actions);
- }
-
void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds, Rect outTempInsetBounds,
boolean ignoreVisibility) {
mWindowContainerController.getStackDockedModeBounds(outBounds, outTempBounds,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7ceeff8..1e33bb9 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -120,7 +120,6 @@
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
-import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
@@ -153,7 +152,6 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.ArrayMap;
import android.util.ArraySet;
-import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.IntArray;
import android.util.Slog;
@@ -2037,19 +2035,20 @@
|| mService.mSupportsFreeformWindowManagement;
}
- ActivityStack getStack(int stackId) {
+ protected <T extends ActivityStack> T getStack(int stackId) {
return getStack(stackId, !CREATE_IF_NEEDED, !ON_TOP);
}
- ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) {
+ protected <T extends ActivityStack> T getStack(int stackId, boolean createStaticStackIfNeeded,
+ boolean createOnTop) {
final ActivityContainer activityContainer = mActivityContainers.get(stackId);
if (activityContainer != null) {
- return activityContainer.mStack;
+ return (T) activityContainer.mStack;
}
if (!createStaticStackIfNeeded || !StackId.isStaticStack(stackId)) {
return null;
}
- return createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
+ return (T) createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
}
/**
@@ -2856,7 +2855,7 @@
mWindowManager.deferSurfaceLayout();
// Need to make sure the pinned stack exist so we can resize it below...
- final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
+ final PinnedActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
try {
final TaskRecord task = r.task;
@@ -2906,7 +2905,7 @@
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
- stack.animateResizePinnedStack(bounds, -1);
+ stack.animateResizePinnedStack(bounds, -1 /* animationDuration */);
mService.mTaskChangeNotificationController.notifyActivityPinned();
}
@@ -4367,7 +4366,14 @@
synchronized (mService) {
mStackId = stackId;
mActivityDisplay = activityDisplay;
- new ActivityStack(this, mRecentTasks, onTop);
+ switch (mStackId) {
+ case PINNED_STACK_ID:
+ new PinnedActivityStack(this, mRecentTasks, onTop);
+ break;
+ default:
+ new ActivityStack(this, mRecentTasks, onTop);
+ break;
+ }
mIdString = "ActivtyContainer{" + mStackId + "}";
if (DEBUG_STACK) Slog.d(TAG_STACK, "Creating " + this);
}
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
new file mode 100644
index 0000000..aa7ab15
--- /dev/null
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.RemoteAction;
+import android.graphics.Rect;
+
+import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
+import com.android.server.wm.PinnedStackWindowController;
+import com.android.server.wm.StackWindowController;
+
+import java.util.List;
+
+/**
+ * State and management of the pinned stack of activities.
+ */
+class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> {
+
+ PinnedActivityStack(ActivityContainer activityContainer,
+ RecentTasks recentTasks, boolean onTop) {
+ super(activityContainer, recentTasks, onTop);
+ }
+
+ @Override
+ PinnedStackWindowController createStackWindowController(int displayId, boolean onTop,
+ Rect outBounds) {
+ return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
+ }
+
+ void animateResizePinnedStack(Rect bounds, int animationDuration) {
+ getWindowContainerController().animateResizePinnedStack(bounds, animationDuration);
+ }
+
+ void setPictureInPictureAspectRatio(float aspectRatio) {
+ getWindowContainerController().setPictureInPictureAspectRatio(aspectRatio);
+ }
+
+ void setPictureInPictureActions(List<RemoteAction> actions) {
+ getWindowContainerController().setPictureInPictureActions(actions);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 01bd86d..837b69e 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -272,18 +272,10 @@
void onAnimationEnd();
void moveToFullscreen();
-
- void getFullScreenBounds(Rect bounds);
}
- void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration) {
- boolean moveToFullscreen = false;
- if (to == null) {
- to = new Rect();
- target.getFullScreenBounds(to);
- moveToFullscreen = true;
- }
-
+ void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration,
+ boolean moveToFullscreen) {
final BoundsAnimator existing = mRunningAnimations.get(target);
final boolean replacing = existing != null;
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index cfeb198..5f41187 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -230,28 +230,6 @@
}
/**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds) {
- return getMovementBounds(stackBounds, true /* adjustForIme */);
- }
-
- /**
- * @return the movement bounds for the given {@param stackBounds} and the current state of the
- * controller.
- */
- private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
- final Rect movementBounds = new Rect();
- getInsetBounds(movementBounds);
-
- // Apply the movement bounds adjustments based on the current state
- mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
- (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
- return movementBounds;
- }
-
- /**
* @param preChangeTargetBounds The final bounds of the stack if it is currently animating
* @return the repositioned PIP bounds given it's pre-change bounds, and the new display
* content.
@@ -387,6 +365,28 @@
}
/**
+ * @return the movement bounds for the given {@param stackBounds} and the current state of the
+ * controller.
+ */
+ private Rect getMovementBounds(Rect stackBounds) {
+ return getMovementBounds(stackBounds, true /* adjustForIme */);
+ }
+
+ /**
+ * @return the movement bounds for the given {@param stackBounds} and the current state of the
+ * controller.
+ */
+ private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+ final Rect movementBounds = new Rect();
+ getInsetBounds(movementBounds);
+
+ // Apply the movement bounds adjustments based on the current state
+ mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
+ (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+ return movementBounds;
+ }
+
+ /**
* Applies the minimized offsets to the given stack bounds.
*/
private void applyMinimizedOffset(Rect stackBounds, Rect movementBounds) {
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
new file mode 100644
index 0000000..71f88de
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+
+import android.app.RemoteAction;
+import android.graphics.Rect;
+
+import com.android.server.UiThread;
+
+import java.util.List;
+
+/**
+ * Controller for the pinned stack container. See {@link StackWindowController}.
+ */
+public class PinnedStackWindowController extends StackWindowController {
+
+ private Rect mTmpBoundsRect = new Rect();
+
+ public PinnedStackWindowController(int stackId, StackWindowListener listener, int displayId,
+ boolean onTop, Rect outBounds) {
+ super(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
+ }
+
+ /**
+ * Animates the pinned stack.
+ */
+ public void animateResizePinnedStack(Rect bounds, int animationDuration) {
+ synchronized (mWindowMap) {
+ if (mContainer == null) {
+ throw new IllegalArgumentException("Pinned stack container not found :(");
+ }
+
+ // Get non-null fullscreen bounds if the bounds are null
+ final boolean moveToFullscreen = bounds == null;
+ bounds = getPinnedStackAnimationBounds(bounds);
+
+ // If the bounds are truly null, then there was no fullscreen stack at this time, so
+ // animate this to the full display bounds
+ final Rect toBounds;
+ if (bounds == null) {
+ toBounds = new Rect();
+ mContainer.getDisplayContent().getLogicalDisplayRect(toBounds);
+ } else {
+ toBounds = bounds;
+ }
+
+ final Rect originalBounds = new Rect();
+ mContainer.getBounds(originalBounds);
+ mContainer.setAnimatingBounds(toBounds);
+ UiThread.getHandler().post(() -> {
+ mService.mBoundsAnimationController.animateBounds(mContainer, originalBounds,
+ toBounds, animationDuration, moveToFullscreen);
+ });
+ }
+ }
+
+ /**
+ * Sets the current picture-in-picture aspect ratio.
+ */
+ public void setPictureInPictureAspectRatio(float aspectRatio) {
+ synchronized (mWindowMap) {
+ if (!mService.mSupportsPictureInPicture || mContainer == null) {
+ return;
+ }
+
+ final int displayId = mContainer.getDisplayContent().getDisplayId();
+ final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio);
+ final Rect targetBounds = new Rect();
+ mContainer.getAnimatingBounds(targetBounds);
+ if (!toBounds.equals(targetBounds)) {
+ animateResizePinnedStack(toBounds, -1 /* duration */);
+ }
+
+ final PinnedStackController pinnedStackController =
+ mContainer.getDisplayContent().getPinnedStackController();
+ pinnedStackController.setAspectRatio(
+ pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
+ ? aspectRatio : -1f);
+ }
+ }
+
+ /**
+ * Sets the current picture-in-picture actions.
+ */
+ public void setPictureInPictureActions(List<RemoteAction> actions) {
+ synchronized (mWindowMap) {
+ if (!mService.mSupportsPictureInPicture || mContainer == null) {
+ return;
+ }
+
+ mContainer.getDisplayContent().getPinnedStackController().setActions(actions);
+ }
+ }
+
+ /**
+ * Checks the {@param bounds} and retirms non-null fullscreen bounds for the pinned stack
+ * animation if necessary.
+ */
+ private Rect getPinnedStackAnimationBounds(Rect bounds) {
+ mService.getStackBounds(FULLSCREEN_WORKSPACE_STACK_ID, mTmpBoundsRect);
+ if (bounds == null && !mTmpBoundsRect.isEmpty()) {
+ bounds = new Rect(mTmpBoundsRect);
+ }
+ return bounds;
+ }
+}
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 142f69a..b0e115b 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -199,59 +199,6 @@
}
}
- // TODO: This and similar methods should be separated into PinnedStackWindowContainerController
- public void animateResizePinnedStack(final Rect bounds, final int animationDuration) {
- synchronized (mWindowMap) {
- if (mContainer == null) {
- throw new IllegalArgumentException("Pinned stack container not found :(");
- }
- final Rect originalBounds = new Rect();
- mContainer.getBounds(originalBounds);
- mContainer.setAnimatingBounds(bounds);
- UiThread.getHandler().post(new Runnable() {
- @Override
- public void run() {
- mService.mBoundsAnimationController.animateBounds(
- mContainer, originalBounds, bounds, animationDuration);
- }
- });
- }
- }
-
- /** Sets the current picture-in-picture aspect ratio. */
- public void setPictureInPictureAspectRatio(float aspectRatio) {
- synchronized (mWindowMap) {
- if (!mService.mSupportsPictureInPicture || mContainer == null) {
- return;
- }
-
- final int displayId = mContainer.getDisplayContent().getDisplayId();
- final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio);
- final Rect targetBounds = new Rect();
- mContainer.getAnimatingBounds(targetBounds);
- if (!toBounds.equals(targetBounds)) {
- animateResizePinnedStack(toBounds, -1 /* duration */);
- }
-
- final PinnedStackController pinnedStackController =
- mContainer.getDisplayContent().getPinnedStackController();
- pinnedStackController.setAspectRatio(
- pinnedStackController.isValidPictureInPictureAspectRatio(aspectRatio)
- ? aspectRatio : -1f);
- }
- }
-
- /** Sets the current picture-in-picture actions. */
- public void setPictureInPictureActions(List<RemoteAction> actions) {
- synchronized (mWindowMap) {
- if (!mService.mSupportsPictureInPicture || mContainer == null) {
- return;
- }
-
- mContainer.getDisplayContent().getPinnedStackController().setActions(actions);
- }
- }
-
public void getStackDockedModeBounds(Rect outBounds, Rect outTempBounds,
Rect outTempInsetBounds, boolean ignoreVisibility) {
synchronized (mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 5f8b694..c7532ac 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
@@ -1476,14 +1477,6 @@
}
}
- @Override
- public void getFullScreenBounds(Rect bounds) {
- // This is currently only used for the pinned stack animation when leaving PiP
- // (see {@link BoundsAnimationController}), and in that case we need to animate this back
- // to the full bounds to match the fullscreen stack
- getDisplayContent().getLogicalDisplayRect(bounds);
- }
-
public boolean hasMovementAnimations() {
return StackId.hasMovementAnimations(mStackId);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9397c9e..474610b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7267,10 +7267,6 @@
return mRoot.getDisplayContentOrCreate(DEFAULT_DISPLAY);
}
- private DisplayInfo getDefaultDisplayInfoLocked() {
- return getDefaultDisplayContentLocked().getDisplayInfo();
- }
-
public void onDisplayAdded(int displayId) {
mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
}