Loading core/java/android/app/IActivityTaskManager.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -298,13 +298,6 @@ interface IActivityTaskManager { void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration, in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations); /** * Dismisses PiP * @param animate True if the dismissal should be animated. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. */ void dismissPip(boolean animate, int animationDuration); void suppressResizeConfigChanges(boolean suppress); void moveTasksToFullscreenStack(int fromStackId, boolean onTop); boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds); Loading packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +51 −11 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.pip; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE; Loading @@ -26,8 +29,6 @@ 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.Context; import android.content.pm.ActivityInfo; Loading @@ -38,9 +39,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; Loading Loading @@ -216,6 +217,29 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mOneShotAnimationType = animationType; } /** * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction} * - setActivityWindowingMode to fullscreen at beginning of the transaction. without changing * the windowing mode of the Task itself. This makes sure the activity render it's fullscreen * configuration while the Task is still in PiP. * - setWindowingMode to fullscreen at the end of transition * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void dismissPip(int animationDurationMs) { try { final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN); WindowOrganizer.applyTransaction(wct); } catch (RemoteException e) { Log.e(TAG, "Failed to apply container transaction", e); } final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder()); scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs, null /* updateBoundsCallback */); mInPip = false; } @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(info, "Requires RunningTaskInfo"); Loading @@ -235,7 +259,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mBoundsToRestore.put(mToken.asBinder(), currentBounds); if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) { scheduleAnimateResizePip(currentBounds, destinationBounds, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null); TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { mUpdateHandler.post(() -> mPipAnimationController .getAnimator(mLeash, destinationBounds, 0f, 1f) Loading @@ -249,6 +274,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } } /** * Note that dismissing PiP is now originated from SystemUI, see {@link #dismissPip(int)}. * Meanwhile this callback is invoked whenever the task is removed. For instance: * - as a result of removeStacksInWindowingModes from WM * - activity itself is died */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { IWindowContainer token = info.token; Loading @@ -259,7 +290,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } final Rect boundsToRestore = mBoundsToRestore.remove(token.asBinder()); scheduleAnimateResizePip(mLastReportedBounds, boundsToRestore, TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null); TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null /* updateBoundsCallback */); mInPip = false; } Loading @@ -274,7 +306,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { getAspectRatioOrDefault(newParams), null /* bounds */, getMinimalSize(info.topActivityInfo)); Objects.requireNonNull(destinationBounds, "Missing destination bounds"); scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null); scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null /* updateBoundsCallback */); } /** Loading Loading @@ -434,12 +467,19 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } mLastReportedBounds.set(destinationBounds); try { // If we are animating to fullscreen, then we need to reset the override bounds on the // task to ensure that the task "matches" the parent's bounds Rect taskBounds = direction == TRANSITION_DIRECTION_TO_FULLSCREEN ? null : destinationBounds; final WindowContainerTransaction wct = new WindowContainerTransaction(); final Rect taskBounds; if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { // If we are animating to fullscreen, then we need to reset the override bounds // on the task to ensure that the task "matches" the parent's bounds, this applies // also to the final windowing mode, which should be reset to undefined rather than // fullscreen. taskBounds = null; wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED) .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); } else { taskBounds = destinationBounds; } if (direction == TRANSITION_DIRECTION_TO_PIP) { wct.scheduleFinishEnterPip(mToken, taskBounds); } else { Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +1 −5 Original line number Diff line number Diff line Loading @@ -219,11 +219,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cancelAnimations(); mMenuController.hideMenuWithoutResize(); mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION); } catch (RemoteException e) { Log.e(TAG, "Error expanding PiP activity", e); } mPipTaskOrganizer.dismissPip(skipAnimation ? 0 : EXPAND_STACK_TO_FULLSCREEN_DURATION); }); } Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +0 −29 Original line number Diff line number Diff line Loading @@ -3986,35 +3986,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } /** * Dismisses Pip * @param animate True if the dismissal should be animated. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. */ @Override public void dismissPip(boolean animate, int animationDuration) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { final ActivityStack stack = mRootWindowContainer.getDefaultDisplay().getRootPinnedTask(); if (stack == null) { Slog.w(TAG, "dismissPip: pinned stack not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { throw new IllegalArgumentException("Stack: " + stack + " doesn't support animated resize."); } stack.dismissPip(); } } finally { Binder.restoreCallingIdentity(ident); } } @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); Loading services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +0 −1 Original line number Diff line number Diff line Loading @@ -1113,7 +1113,6 @@ public class RecentTasksTest extends ActivityTestsBase { () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true)); assertSecurityException(expectCallable, () -> mService.setTaskWindowingModeSplitScreenPrimary(0, true)); assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0)); assertSecurityException(expectCallable, () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); assertSecurityException(expectCallable, () -> mService.getAllStackInfos()); Loading Loading
core/java/android/app/IActivityTaskManager.aidl +0 −7 Original line number Diff line number Diff line Loading @@ -298,13 +298,6 @@ interface IActivityTaskManager { void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration, in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations); /** * Dismisses PiP * @param animate True if the dismissal should be animated. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. */ void dismissPip(boolean animate, int animationDuration); void suppressResizeConfigChanges(boolean suppress); void moveTasksToFullscreenStack(int fromStackId, boolean onTop); boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds); Loading
packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +51 −11 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.pip; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA; import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_BOUNDS; import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_NONE; Loading @@ -26,8 +29,6 @@ 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.Context; import android.content.pm.ActivityInfo; Loading @@ -38,9 +39,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; Loading Loading @@ -216,6 +217,29 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mOneShotAnimationType = animationType; } /** * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction} * - setActivityWindowingMode to fullscreen at beginning of the transaction. without changing * the windowing mode of the Task itself. This makes sure the activity render it's fullscreen * configuration while the Task is still in PiP. * - setWindowingMode to fullscreen at the end of transition * @param animationDurationMs duration in millisecond for the exiting PiP transition */ public void dismissPip(int animationDurationMs) { try { final WindowContainerTransaction wct = new WindowContainerTransaction(); wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN); WindowOrganizer.applyTransaction(wct); } catch (RemoteException e) { Log.e(TAG, "Failed to apply container transaction", e); } final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder()); scheduleAnimateResizePip(mLastReportedBounds, destinationBounds, TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs, null /* updateBoundsCallback */); mInPip = false; } @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(info, "Requires RunningTaskInfo"); Loading @@ -235,7 +259,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { mBoundsToRestore.put(mToken.asBinder(), currentBounds); if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) { scheduleAnimateResizePip(currentBounds, destinationBounds, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null); TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { mUpdateHandler.post(() -> mPipAnimationController .getAnimator(mLeash, destinationBounds, 0f, 1f) Loading @@ -249,6 +274,12 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } } /** * Note that dismissing PiP is now originated from SystemUI, see {@link #dismissPip(int)}. * Meanwhile this callback is invoked whenever the task is removed. For instance: * - as a result of removeStacksInWindowingModes from WM * - activity itself is died */ @Override public void onTaskVanished(ActivityManager.RunningTaskInfo info) { IWindowContainer token = info.token; Loading @@ -259,7 +290,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } final Rect boundsToRestore = mBoundsToRestore.remove(token.asBinder()); scheduleAnimateResizePip(mLastReportedBounds, boundsToRestore, TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null); TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null /* updateBoundsCallback */); mInPip = false; } Loading @@ -274,7 +306,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { getAspectRatioOrDefault(newParams), null /* bounds */, getMinimalSize(info.topActivityInfo)); Objects.requireNonNull(destinationBounds, "Missing destination bounds"); scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null); scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration, null /* updateBoundsCallback */); } /** Loading Loading @@ -434,12 +467,19 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub { } mLastReportedBounds.set(destinationBounds); try { // If we are animating to fullscreen, then we need to reset the override bounds on the // task to ensure that the task "matches" the parent's bounds Rect taskBounds = direction == TRANSITION_DIRECTION_TO_FULLSCREEN ? null : destinationBounds; final WindowContainerTransaction wct = new WindowContainerTransaction(); final Rect taskBounds; if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) { // If we are animating to fullscreen, then we need to reset the override bounds // on the task to ensure that the task "matches" the parent's bounds, this applies // also to the final windowing mode, which should be reset to undefined rather than // fullscreen. taskBounds = null; wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED) .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); } else { taskBounds = destinationBounds; } if (direction == TRANSITION_DIRECTION_TO_PIP) { wct.scheduleFinishEnterPip(mToken, taskBounds); } else { Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +1 −5 Original line number Diff line number Diff line Loading @@ -219,11 +219,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, cancelAnimations(); mMenuController.hideMenuWithoutResize(); mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION); } catch (RemoteException e) { Log.e(TAG, "Error expanding PiP activity", e); } mPipTaskOrganizer.dismissPip(skipAnimation ? 0 : EXPAND_STACK_TO_FULLSCREEN_DURATION); }); } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +0 −29 Original line number Diff line number Diff line Loading @@ -3986,35 +3986,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } /** * Dismisses Pip * @param animate True if the dismissal should be animated. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. */ @Override public void dismissPip(boolean animate, int animationDuration) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { final ActivityStack stack = mRootWindowContainer.getDefaultDisplay().getRootPinnedTask(); if (stack == null) { Slog.w(TAG, "dismissPip: pinned stack not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { throw new IllegalArgumentException("Stack: " + stack + " doesn't support animated resize."); } stack.dismissPip(); } } finally { Binder.restoreCallingIdentity(ident); } } @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); Loading
services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +0 −1 Original line number Diff line number Diff line Loading @@ -1113,7 +1113,6 @@ public class RecentTasksTest extends ActivityTestsBase { () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true)); assertSecurityException(expectCallable, () -> mService.setTaskWindowingModeSplitScreenPrimary(0, true)); assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0)); assertSecurityException(expectCallable, () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); assertSecurityException(expectCallable, () -> mService.getAllStackInfos()); Loading