From 221fe3d9059802c6a97eec035dcb4d074edef356 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Thu, 26 Mar 2020 13:13:04 -0700 Subject: [PATCH] Save reentry bounds from SysUI On the other hand, since we won't be able to get the callback from TaskOrganizer when an activity (used to be in PiP mode) is removed, reset of the reentry bounds is kept in WM. Bug: 152549281 Test: manually enter/exit PiP Change-Id: I8b4b7f87c4a7601d8bdf32af8105a68450012a87 --- .../android/view/IPinnedStackListener.aidl | 16 ++----- .../system/PinnedStackListenerForwarder.java | 15 ++----- .../systemui/pip/PipAnimationController.java | 10 ++--- .../systemui/pip/PipTaskOrganizer.java | 24 +++++++---- .../systemui/pip/phone/PipManager.java | 42 +++++++++---------- .../android/systemui/pip/tv/PipManager.java | 7 ++-- .../com/android/server/wm/ActivityRecord.java | 15 +------ .../com/android/server/wm/ActivityStack.java | 6 --- .../server/wm/PinnedStackController.java | 19 ++------- 9 files changed, 56 insertions(+), 98 deletions(-) diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl index 596d55aebc6db..071c2593f5226 100644 --- a/core/java/android/view/IPinnedStackListener.aidl +++ b/core/java/android/view/IPinnedStackListener.aidl @@ -60,20 +60,12 @@ oneway interface IPinnedStackListener { void onActionsChanged(in ParceledListSlice actions); /** - * Called by the window manager to notify the listener to save the reentry fraction and size, - * typically when an Activity leaves PiP (picture-in-picture) mode to fullscreen. - * {@param componentName} represents the application component of PiP window - * while {@param bounds} is the current PiP bounds used to calculate the - * reentry snap fraction and size. - */ - void onSaveReentryBounds(in ComponentName componentName, in Rect bounds); - - /** - * Called by the window manager to notify the listener to reset saved reentry fraction and size, - * typically when an Activity enters PiP (picture-in-picture) mode from fullscreen. + * Called by the window manager to notify the listener that Activity (was or is in pinned mode) + * is hidden (either stopped or removed). This is generally used as a signal to reset saved + * reentry fraction and size. * {@param componentName} represents the application component of PiP window. */ - void onResetReentryBounds(in ComponentName componentName); + void onActivityHidden(in ComponentName componentName); /** * Called when the window manager has detected change on DisplayInfo, or diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PinnedStackListenerForwarder.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PinnedStackListenerForwarder.java index 360244c9af52d..34a0268201f4a 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PinnedStackListenerForwarder.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PinnedStackListenerForwarder.java @@ -74,16 +74,9 @@ public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub { } @Override - public void onSaveReentryBounds(ComponentName componentName, Rect bounds) { + public void onActivityHidden(ComponentName componentName) { for (PinnedStackListener listener : mListeners) { - listener.onSaveReentryBounds(componentName, bounds); - } - } - - @Override - public void onResetReentryBounds(ComponentName componentName) { - for (PinnedStackListener listener : mListeners) { - listener.onResetReentryBounds(componentName); + listener.onActivityHidden(componentName); } } @@ -121,9 +114,7 @@ public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub { public void onActionsChanged(ParceledListSlice actions) {} - public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {} - - public void onResetReentryBounds(ComponentName componentName) {} + public void onActivityHidden(ComponentName componentName) {} public void onDisplayInfoChanged(DisplayInfo displayInfo) {} diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index 232c23dc14f0c..153359204d5fd 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -49,10 +49,10 @@ public class PipAnimationController { @Retention(RetentionPolicy.SOURCE) public @interface AnimationType {} - static final int TRANSITION_DIRECTION_NONE = 0; - static final int TRANSITION_DIRECTION_SAME = 1; - static final int TRANSITION_DIRECTION_TO_PIP = 2; - static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3; + public static final int TRANSITION_DIRECTION_NONE = 0; + public static final int TRANSITION_DIRECTION_SAME = 1; + public static final int TRANSITION_DIRECTION_TO_PIP = 2; + public static final int TRANSITION_DIRECTION_TO_FULLSCREEN = 3; @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = { TRANSITION_DIRECTION_NONE, @@ -61,7 +61,7 @@ public class PipAnimationController { TRANSITION_DIRECTION_TO_FULLSCREEN }) @Retention(RetentionPolicy.SOURCE) - @interface TransitionDirection {} + public @interface TransitionDirection {} private final Interpolator mFastOutSlowInInterpolator; private final PipSurfaceTransactionHelper mSurfaceTransactionHelper; diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 6ce5e7cf506cc..1e5cb3b50ce2d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -26,9 +26,8 @@ import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTI import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.ActivityTaskManager; -import android.window.ITaskOrganizerController; import android.app.PictureInPictureParams; +import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Rect; @@ -38,9 +37,9 @@ import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.util.Size; +import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.IWindowContainer; -import android.view.SurfaceControl; import android.window.WindowContainerTransaction; import android.window.WindowOrganizer; @@ -93,7 +92,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mMainHandler.post(() -> { for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) { final PipTransitionCallback callback = mPipTransitionCallbacks.get(i); - callback.onPipTransitionStarted(); + callback.onPipTransitionStarted(mTaskInfo.baseActivity, + animator.getTransitionDirection()); } }); } @@ -104,7 +104,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mMainHandler.post(() -> { for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) { final PipTransitionCallback callback = mPipTransitionCallbacks.get(i); - callback.onPipTransitionFinished(); + callback.onPipTransitionFinished(mTaskInfo.baseActivity, + animator.getTransitionDirection()); } }); finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection()); @@ -115,7 +116,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mMainHandler.post(() -> { for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) { final PipTransitionCallback callback = mPipTransitionCallbacks.get(i); - callback.onPipTransitionCanceled(); + callback.onPipTransitionCanceled(mTaskInfo.baseActivity, + animator.getTransitionDirection()); } }); } @@ -200,6 +202,10 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { return mUpdateHandler; } + public Rect getLastReportedBounds() { + return new Rect(mLastReportedBounds); + } + /** * Registers {@link PipTransitionCallback} to receive transition callbacks. */ @@ -492,16 +498,16 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { /** * Callback when the pip transition is started. */ - void onPipTransitionStarted(); + void onPipTransitionStarted(ComponentName activity, int direction); /** * Callback when the pip transition is finished. */ - void onPipTransitionFinished(); + void onPipTransitionFinished(ComponentName activity, int direction); /** * Callback when the pip transition is cancelled. */ - void onPipTransitionCanceled(); + void onPipTransitionCanceled(ComponentName activity, int direction); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index e89ce2e3a56f4..14fd5923a1f65 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -20,6 +20,8 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.window.WindowOrganizer.TaskOrganizer; +import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN; + import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.IActivityManager; @@ -36,7 +38,6 @@ import android.util.Pair; import android.view.DisplayInfo; import android.view.IPinnedStackController; import android.window.WindowContainerTransaction; -import android.window.WindowOrganizer; import com.android.systemui.Dependency; import com.android.systemui.UiOffloadThread; @@ -171,24 +172,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } @Override - public void onSaveReentryBounds(ComponentName componentName, Rect bounds) { - mHandler.post(() -> { - // On phones, the expansion animation that happens on pip tap before restoring - // to fullscreen makes it so that the bounds received here are the expanded - // bounds. We want to restore to the unexpanded bounds when re-entering pip, - // so we save the bounds before expansion (normal) instead of the current - // bounds. - mReentryBounds.set(mTouchHandler.getNormalBounds()); - // Apply the snap fraction of the current bounds to the normal bounds. - float snapFraction = mPipBoundsHandler.getSnapFraction(bounds); - mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction); - // Save reentry bounds (normal non-expand bounds with current position applied). - mPipBoundsHandler.onSaveReentryBounds(componentName, mReentryBounds); - }); - } - - @Override - public void onResetReentryBounds(ComponentName componentName) { + public void onActivityHidden(ComponentName componentName) { mHandler.post(() -> mPipBoundsHandler.onResetReentryBounds(componentName)); } @@ -326,7 +310,21 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } @Override - public void onPipTransitionStarted() { + public void onPipTransitionStarted(ComponentName activity, int direction) { + if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { + // On phones, the expansion animation that happens on pip tap before restoring + // to fullscreen makes it so that the bounds received here are the expanded + // bounds. We want to restore to the unexpanded bounds when re-entering pip, + // so we save the bounds before expansion (normal) instead of the current + // bounds. + mReentryBounds.set(mTouchHandler.getNormalBounds()); + // Apply the snap fraction of the current bounds to the normal bounds. + final Rect bounds = mPipTaskOrganizer.getLastReportedBounds(); + float snapFraction = mPipBoundsHandler.getSnapFraction(bounds); + mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction); + // Save reentry bounds (normal non-expand bounds with current position applied). + mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds); + } // Disable touches while the animation is running mTouchHandler.setTouchEnabled(false); if (mPinnedStackAnimationRecentsListener != null) { @@ -339,12 +337,12 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } @Override - public void onPipTransitionFinished() { + public void onPipTransitionFinished(ComponentName activity, int direction) { onPipTransitionFinishedOrCanceled(); } @Override - public void onPipTransitionCanceled() { + public void onPipTransitionCanceled(ComponentName activity, int direction) { onPipTransitionFinishedOrCanceled(); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 2dcf1f89c3ec3..ee58db0226394 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -45,7 +45,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.view.DisplayInfo; -import android.window.WindowOrganizer; import com.android.systemui.Dependency; import com.android.systemui.R; @@ -700,15 +699,15 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio }; @Override - public void onPipTransitionStarted() { } + public void onPipTransitionStarted(ComponentName activity, int direction) { } @Override - public void onPipTransitionFinished() { + public void onPipTransitionFinished(ComponentName activity, int direction) { onPipTransitionFinishedOrCanceled(); } @Override - public void onPipTransitionCanceled() { + public void onPipTransitionCanceled(ComponentName activity, int direction) { onPipTransitionFinishedOrCanceled(); } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 6d53786ddf414..310139ebe7a73 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3160,7 +3160,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } // Reset the last saved PiP snap fraction on removal. - mDisplayContent.mPinnedStackControllerLocked.resetReentryBounds(mActivityComponent); + mDisplayContent.mPinnedStackControllerLocked.onActivityHidden(mActivityComponent); mWmService.mEmbeddedWindowController.onActivityRemoved(this); mRemovingFromDisplay = false; } @@ -4426,7 +4426,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.v(WM_DEBUG_ADD_REMOVE, "notifyAppStopped: %s", this); mAppStopped = true; // Reset the last saved PiP snap fraction on app stop. - mDisplayContent.mPinnedStackControllerLocked.resetReentryBounds(mActivityComponent); + mDisplayContent.mPinnedStackControllerLocked.onActivityHidden(mActivityComponent); destroySurfaces(); // Remove any starting window that was added for this app if they are still around. removeStartingWindow(); @@ -6648,17 +6648,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } - void savePinnedStackBounds() { - // Leaving PiP to fullscreen, save the snap fraction based on the pre-animation bounds - // for the next re-entry into PiP (assuming the activity is not hidden or destroyed) - final ActivityStack pinnedStack = mDisplayContent.getRootPinnedTask(); - if (pinnedStack == null) return; - final Rect stackBounds = mTmpRect; - pinnedStack.getBounds(stackBounds); - mDisplayContent.mPinnedStackControllerLocked.saveReentryBounds( - mActivityComponent, stackBounds); - } - /** Returns true if the configuration is compatible with this activity. */ boolean isConfigurationCompatible(Configuration config) { final int orientation = getRequestedOrientation(); diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index fb22481306ddd..42c5580e37d93 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -3392,12 +3392,6 @@ class ActivityStack extends Task { "Can't exit pinned mode if it's not pinned already."); } - // give pinned stack a chance to save current bounds, this should happen before reparent. - final ActivityRecord top = topRunningNonOverlayTaskActivity(); - if (top != null && top.isVisible()) { - top.savePinnedStackBounds(); - } - mWmService.inSurfaceTransaction(() -> { final Task task = getBottomMostTask(); setWindowingMode(WINDOWING_MODE_UNDEFINED); diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java index e14b8ae13bbc6..66dbfd5f2a842 100644 --- a/services/core/java/com/android/server/wm/PinnedStackController.java +++ b/services/core/java/com/android/server/wm/PinnedStackController.java @@ -163,24 +163,13 @@ class PinnedStackController { } /** - * Saves the current snap fraction for re-entry of the current activity into PiP. + * 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. */ - void saveReentryBounds(final ComponentName componentName, final Rect stackBounds) { + void onActivityHidden(ComponentName componentName) { if (mPinnedStackListener == null) return; try { - mPinnedStackListener.onSaveReentryBounds(componentName, stackBounds); - } catch (RemoteException e) { - Slog.e(TAG_WM, "Error delivering save reentry fraction event.", e); - } - } - - /** - * Resets the last saved snap fraction so that the default bounds will be returned. - */ - void resetReentryBounds(ComponentName componentName) { - if (mPinnedStackListener == null) return; - try { - mPinnedStackListener.onResetReentryBounds(componentName); + mPinnedStackListener.onActivityHidden(componentName); } catch (RemoteException e) { Slog.e(TAG_WM, "Error delivering reset reentry fraction event.", e); }