Loading core/java/android/app/IActivityTaskManager.aidl +14 −2 Original line number Diff line number Diff line Loading @@ -247,8 +247,20 @@ interface IActivityTaskManager { boolean preserveWindows, boolean animate, int animationDuration); boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, in Rect initialBounds, boolean showRecents); /** * Use the offset to adjust the stack boundary with animation. * * @param stackId Id of the stack to adjust. * @param compareBounds Offset is only applied if the current pinned stack bounds is equal to * the compareBounds. * @param xOffset The horizontal offset. * @param yOffset The vertical offset. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. * @throws RemoteException */ void offsetPinnedStackBounds(int stackId, in Rect compareBounds, int xOffset, int yOffset, int animationDuration); /** * Removes stacks in the input windowing modes from the system if they are of activity type * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +39 −2 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call private static final int MSG_RESIZE_IMMEDIATE = 1; private static final int MSG_RESIZE_ANIMATE = 2; private static final int MSG_OFFSET_ANIMATE = 3; private Context mContext; private IActivityManager mActivityManager; Loading Loading @@ -360,9 +361,20 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** * Animates the PiP to offset it from the IME or shelf. */ void animateToOffset(Rect toBounds) { void animateToOffset(Rect originalBounds, int offset) { cancelAnimations(); resizeAndAnimatePipUnchecked(toBounds, SHIFT_DURATION); adjustAndAnimatePipOffset(originalBounds, offset, SHIFT_DURATION); } private void adjustAndAnimatePipOffset(Rect originalBounds, int offset, int duration) { if (offset == 0) { return; } SomeArgs args = SomeArgs.obtain(); args.arg1 = originalBounds; args.argi1 = offset; args.argi2 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_OFFSET_ANIMATE, args)); } /** Loading Loading @@ -549,6 +561,31 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call return true; } case MSG_OFFSET_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect originalBounds = (Rect) args.arg1; final int offset = args.argi1; final int duration = args.argi2; try { StackInfo stackInfo = mActivityTaskManager.getStackInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return true; } mActivityTaskManager.offsetPinnedStackBounds(stackInfo.stackId, originalBounds, 0/* xOffset */, offset, duration); Rect toBounds = new Rect(originalBounds); toBounds.offset(0, offset); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate offset pinned stack with offset: " + offset, e); } return true; } default: return false; } Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +3 −4 Original line number Diff line number Diff line Loading @@ -346,12 +346,11 @@ public class PipTouchHandler { } private void animateToOffset(Rect animatingBounds, Rect toAdjustedBounds) { final Rect bounds = new Rect(animatingBounds); bounds.offset(0, toAdjustedBounds.bottom - bounds.top); int offset = toAdjustedBounds.bottom - animatingBounds.top; // In landscape mode, PIP window can go offset while launching IME. We want to align the // the top of the PIP window with the top of the movement bounds in that case. bounds.offset(0, Math.max(0, mMovementBounds.top - bounds.top)); mMotionHelper.animateToOffset(bounds); offset += Math.max(0, mMovementBounds.top - animatingBounds.top); mMotionHelper.animateToOffset(animatingBounds, offset); } private void onRegistrationChanged(boolean isRegistered) { Loading services/core/java/com/android/server/wm/ActivityStack.java +13 −0 Original line number Diff line number Diff line Loading @@ -5631,6 +5631,19 @@ class ActivityStack extends ConfigurationContainer { } } /** * Get current bounds of this stack, return empty when it is unavailable. * @see TaskStack#getAnimationOrCurrentBounds(Rect) */ void getAnimationOrCurrentBounds(Rect outBounds) { final TaskStack stack = getTaskStack(); if (stack == null) { outBounds.setEmpty(); return; } stack.getAnimationOrCurrentBounds(outBounds); } private boolean skipResizeAnimation(boolean toFullscreen) { if (!toFullscreen) { return false; Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +34 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,40 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } @Override public void offsetPinnedStackBounds(int stackId, Rect compareBounds, int xOffset, int yOffset, int animationDuration) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "offsetPinnedStackBounds()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { if (xOffset == 0 && yOffset == 0) { return; } final ActivityStack stack = mRootActivityContainer.getStack(stackId); if (stack == null) { Slog.w(TAG, "offsetPinnedStackBounds: stackId " + stackId + " not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { throw new IllegalArgumentException("Stack: " + stackId + " doesn't support animated resize."); } final Rect destBounds = new Rect(); stack.getAnimationOrCurrentBounds(destBounds); if (!destBounds.isEmpty() || !destBounds.equals(compareBounds)) { Slog.w(TAG, "The current stack bounds does not matched! It may be obsolete."); return; } destBounds.offset(xOffset, yOffset); stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, animationDuration, false /* fromFullscreen */); } } finally { Binder.restoreCallingIdentity(ident); } } /** * Moves the specified task to the primary-split-screen stack. * Loading Loading
core/java/android/app/IActivityTaskManager.aidl +14 −2 Original line number Diff line number Diff line Loading @@ -247,8 +247,20 @@ interface IActivityTaskManager { boolean preserveWindows, boolean animate, int animationDuration); boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, in Rect initialBounds, boolean showRecents); /** * Use the offset to adjust the stack boundary with animation. * * @param stackId Id of the stack to adjust. * @param compareBounds Offset is only applied if the current pinned stack bounds is equal to * the compareBounds. * @param xOffset The horizontal offset. * @param yOffset The vertical offset. * @param animationDuration The duration of the resize animation in milliseconds or -1 if the * default animation duration should be used. * @throws RemoteException */ void offsetPinnedStackBounds(int stackId, in Rect compareBounds, int xOffset, int yOffset, int animationDuration); /** * Removes stacks in the input windowing modes from the system if they are of activity type * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +39 −2 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call private static final int MSG_RESIZE_IMMEDIATE = 1; private static final int MSG_RESIZE_ANIMATE = 2; private static final int MSG_OFFSET_ANIMATE = 3; private Context mContext; private IActivityManager mActivityManager; Loading Loading @@ -360,9 +361,20 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** * Animates the PiP to offset it from the IME or shelf. */ void animateToOffset(Rect toBounds) { void animateToOffset(Rect originalBounds, int offset) { cancelAnimations(); resizeAndAnimatePipUnchecked(toBounds, SHIFT_DURATION); adjustAndAnimatePipOffset(originalBounds, offset, SHIFT_DURATION); } private void adjustAndAnimatePipOffset(Rect originalBounds, int offset, int duration) { if (offset == 0) { return; } SomeArgs args = SomeArgs.obtain(); args.arg1 = originalBounds; args.argi1 = offset; args.argi2 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_OFFSET_ANIMATE, args)); } /** Loading Loading @@ -549,6 +561,31 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call return true; } case MSG_OFFSET_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect originalBounds = (Rect) args.arg1; final int offset = args.argi1; final int duration = args.argi2; try { StackInfo stackInfo = mActivityTaskManager.getStackInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return true; } mActivityTaskManager.offsetPinnedStackBounds(stackInfo.stackId, originalBounds, 0/* xOffset */, offset, duration); Rect toBounds = new Rect(originalBounds); toBounds.offset(0, offset); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate offset pinned stack with offset: " + offset, e); } return true; } default: return false; } Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +3 −4 Original line number Diff line number Diff line Loading @@ -346,12 +346,11 @@ public class PipTouchHandler { } private void animateToOffset(Rect animatingBounds, Rect toAdjustedBounds) { final Rect bounds = new Rect(animatingBounds); bounds.offset(0, toAdjustedBounds.bottom - bounds.top); int offset = toAdjustedBounds.bottom - animatingBounds.top; // In landscape mode, PIP window can go offset while launching IME. We want to align the // the top of the PIP window with the top of the movement bounds in that case. bounds.offset(0, Math.max(0, mMovementBounds.top - bounds.top)); mMotionHelper.animateToOffset(bounds); offset += Math.max(0, mMovementBounds.top - animatingBounds.top); mMotionHelper.animateToOffset(animatingBounds, offset); } private void onRegistrationChanged(boolean isRegistered) { Loading
services/core/java/com/android/server/wm/ActivityStack.java +13 −0 Original line number Diff line number Diff line Loading @@ -5631,6 +5631,19 @@ class ActivityStack extends ConfigurationContainer { } } /** * Get current bounds of this stack, return empty when it is unavailable. * @see TaskStack#getAnimationOrCurrentBounds(Rect) */ void getAnimationOrCurrentBounds(Rect outBounds) { final TaskStack stack = getTaskStack(); if (stack == null) { outBounds.setEmpty(); return; } stack.getAnimationOrCurrentBounds(outBounds); } private boolean skipResizeAnimation(boolean toFullscreen) { if (!toFullscreen) { return false; Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +34 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,40 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } @Override public void offsetPinnedStackBounds(int stackId, Rect compareBounds, int xOffset, int yOffset, int animationDuration) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "offsetPinnedStackBounds()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { if (xOffset == 0 && yOffset == 0) { return; } final ActivityStack stack = mRootActivityContainer.getStack(stackId); if (stack == null) { Slog.w(TAG, "offsetPinnedStackBounds: stackId " + stackId + " not found."); return; } if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { throw new IllegalArgumentException("Stack: " + stackId + " doesn't support animated resize."); } final Rect destBounds = new Rect(); stack.getAnimationOrCurrentBounds(destBounds); if (!destBounds.isEmpty() || !destBounds.equals(compareBounds)) { Slog.w(TAG, "The current stack bounds does not matched! It may be obsolete."); return; } destBounds.offset(xOffset, yOffset); stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, animationDuration, false /* fromFullscreen */); } } finally { Binder.restoreCallingIdentity(ident); } } /** * Moves the specified task to the primary-split-screen stack. * Loading