Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class InputConsumerController { private final class InputEventReceiver extends BatchedInputEventReceiver { public InputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper, Choreographer.getSfInstance()); super(inputChannel, looper, Choreographer.getInstance()); } @Override Loading packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +29 −38 Original line number Diff line number Diff line Loading @@ -19,11 +19,8 @@ package com.android.systemui.pip; import android.animation.Animator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.MainThread; import android.content.Context; import android.graphics.Rect; import android.os.RemoteException; import android.view.IWindowContainer; import android.view.SurfaceControl; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; Loading Loading @@ -61,31 +58,30 @@ public class PipAnimationController { com.android.internal.R.interpolator.fast_out_slow_in); } @MainThread PipTransitionAnimator getAnimator(IWindowContainer wc, boolean scheduleFinishPip, PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, Rect destinationBounds, float alphaStart, float alphaEnd) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofAlpha(wc, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA && mCurrentAnimator.isRunning()) { mCurrentAnimator.updateEndValue(alphaEnd); } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofAlpha(wc, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); } return mCurrentAnimator; } @MainThread PipTransitionAnimator getAnimator(IWindowContainer wc, boolean scheduleFinishPip, PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, Rect startBounds, Rect endBounds) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofBounds(wc, scheduleFinishPip, startBounds, endBounds)); PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, startBounds, endBounds)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS && mCurrentAnimator.isRunning()) { mCurrentAnimator.setDestinationBounds(endBounds); Loading @@ -94,7 +90,8 @@ public class PipAnimationController { } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofBounds(wc, scheduleFinishPip, startBounds, endBounds)); PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, startBounds, endBounds)); } return mCurrentAnimator; } Loading @@ -116,18 +113,18 @@ public class PipAnimationController { /** * Called when PiP animation is started. */ public void onPipAnimationStart(IWindowContainer wc, PipTransitionAnimator animator) {} public void onPipAnimationStart(PipTransitionAnimator animator) {} /** * Called when PiP animation is ended. */ public void onPipAnimationEnd(IWindowContainer wc, SurfaceControl.Transaction tx, public void onPipAnimationEnd(SurfaceControl.Transaction tx, PipTransitionAnimator animator) {} /** * Called when PiP animation is cancelled. */ public void onPipAnimationCancel(IWindowContainer wc, PipTransitionAnimator animator) {} public void onPipAnimationCancel(PipTransitionAnimator animator) {} } /** Loading @@ -137,7 +134,6 @@ public class PipAnimationController { public abstract static class PipTransitionAnimator<T> extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { private final IWindowContainer mWindowContainer; private final boolean mScheduleFinishPip; private final SurfaceControl mLeash; private final @AnimationType int mAnimationType; Loading @@ -149,13 +145,11 @@ public class PipAnimationController { private PipAnimationCallback mPipAnimationCallback; private SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private PipTransitionAnimator(IWindowContainer wc, boolean scheduleFinishPip, private PipTransitionAnimator(SurfaceControl leash, boolean scheduleFinishPip, @AnimationType int animationType, Rect destinationBounds, T startValue, T endValue) { mWindowContainer = wc; mScheduleFinishPip = scheduleFinishPip; try { mLeash = wc.getLeash(); mLeash = leash; mAnimationType = animationType; mDestinationBounds.set(destinationBounds); mStartValue = startValue; Loading @@ -163,9 +157,6 @@ public class PipAnimationController { addListener(this); addUpdateListener(this); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; } catch (RemoteException e) { throw new RuntimeException(e); } } @Override Loading @@ -173,7 +164,7 @@ public class PipAnimationController { mCurrentValue = mStartValue; applySurfaceControlTransaction(mLeash, newSurfaceControlTransaction(), FRACTION_START); if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationStart(mWindowContainer, this); mPipAnimationCallback.onPipAnimationStart(this); } } Loading @@ -189,14 +180,14 @@ public class PipAnimationController { final SurfaceControl.Transaction tx = newSurfaceControlTransaction(); applySurfaceControlTransaction(mLeash, tx, FRACTION_END); if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationEnd(mWindowContainer, tx, this); mPipAnimationCallback.onPipAnimationEnd(tx, this); } } @Override public void onAnimationCancel(Animator animation) { if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationCancel(mWindowContainer, this); mPipAnimationCallback.onPipAnimationCancel(this); } } Loading Loading @@ -260,9 +251,9 @@ public class PipAnimationController { abstract void applySurfaceControlTransaction(SurfaceControl leash, SurfaceControl.Transaction tx, float fraction); static PipTransitionAnimator<Float> ofAlpha(IWindowContainer wc, boolean scheduleFinishPip, static PipTransitionAnimator<Float> ofAlpha(SurfaceControl leash, boolean scheduleFinishPip, Rect destinationBounds, float startValue, float endValue) { return new PipTransitionAnimator<Float>(wc, scheduleFinishPip, ANIM_TYPE_ALPHA, return new PipTransitionAnimator<Float>(leash, scheduleFinishPip, ANIM_TYPE_ALPHA, destinationBounds, startValue, endValue) { @Override void applySurfaceControlTransaction(SurfaceControl leash, Loading @@ -281,10 +272,10 @@ public class PipAnimationController { }; } static PipTransitionAnimator<Rect> ofBounds(IWindowContainer wc, boolean scheduleFinishPip, static PipTransitionAnimator<Rect> ofBounds(SurfaceControl leash, boolean scheduleFinishPip, Rect startValue, Rect endValue) { // construct new Rect instances in case they are recycled return new PipTransitionAnimator<Rect>(wc, scheduleFinishPip, ANIM_TYPE_BOUNDS, return new PipTransitionAnimator<Rect>(leash, scheduleFinishPip, ANIM_TYPE_BOUNDS, endValue, new Rect(startValue), new Rect(endValue)) { private final Rect mTmpRect = new Rect(); Loading packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +216 −97 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +19 −109 Original line number Diff line number Diff line Loading @@ -28,16 +28,11 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.Debug; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.util.Log; import android.view.Choreographer; import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.os.SomeArgs; import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.shared.system.WindowManagerWrapper; Loading @@ -47,11 +42,12 @@ import com.android.systemui.util.animation.FloatProperties; import com.android.systemui.util.animation.PhysicsAnimator; import java.io.PrintWriter; import java.util.function.Consumer; /** * A helper to animate and manipulate the PiP. */ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Callback, public class PipMotionHelper implements PipAppOpsListener.Callback, FloatingContentCoordinator.FloatingContent { private static final String TAG = "PipMotionHelper"; Loading @@ -68,14 +64,9 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call // The fraction of the stack height that the user has to drag offscreen to dismiss the PiP private static final float DISMISS_OFFSCREEN_FRACTION = 0.3f; 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 final Context mContext; private final IActivityTaskManager mActivityTaskManager; private final PipTaskOrganizer mPipTaskOrganizer; private final Handler mHandler; private PipMenuActivityController mMenuController; private PipSnapAlgorithm mSnapAlgorithm; Loading @@ -92,9 +83,6 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** The region that all of PIP must stay within. */ private Rect mFloatingAllowedArea = new Rect(); private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider = new SfVsyncFrameCallbackProvider(); /** * Bounds that are animated using the physics animator. */ Loading @@ -112,16 +100,11 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call private PhysicsAnimator<Rect> mAnimatedBoundsPhysicsAnimator = PhysicsAnimator.getInstance( mAnimatedBounds); /** Callback that re-sizes PIP to the animated bounds. */ private final Choreographer.FrameCallback mResizePipVsyncCallback = l -> resizePipUnchecked(mAnimatedBounds); /** * Update listener that posts a vsync frame callback to resize PIP to {@link #mAnimatedBounds}. * Update listener that resizes the PIP to {@link #mAnimatedBounds}. */ private final PhysicsAnimator.UpdateListener<Rect> mResizePipVsyncUpdateListener = (target, values) -> mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback); private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener = (target, values) -> resizePipUnchecked(mAnimatedBounds); /** FlingConfig instances provided to PhysicsAnimator for fling gestures. */ private PhysicsAnimator.FlingConfig mFlingConfigX; Loading @@ -137,12 +120,13 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY); private final Consumer<Rect> mUpdateBoundsCallback = (toBounds) -> mBounds.set(toBounds); public PipMotionHelper(Context context, IActivityTaskManager activityTaskManager, PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils, FloatingContentCoordinator floatingContentCoordinator) { mContext = context; mHandler = new Handler(ForegroundThread.get().getLooper(), this); mActivityTaskManager = activityTaskManager; mPipTaskOrganizer = pipTaskOrganizer; mMenuController = menuController; Loading Loading @@ -234,7 +218,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call } cancelAnimations(); mMenuController.hideMenuWithoutResize(); mHandler.post(() -> { mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION); } catch (RemoteException e) { Loading @@ -253,7 +237,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call } cancelAnimations(); mMenuController.hideMenuWithoutResize(); mHandler.post(() -> { mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.removeStacksInWindowingModes( new int[]{ WINDOWING_MODE_PINNED }); Loading Loading @@ -406,17 +390,13 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call * Animates the PiP to offset it from the IME or shelf. */ void animateToOffset(Rect originalBounds, int offset) { cancelAnimations(); adjustAndAnimatePipOffset(originalBounds, offset, SHIFT_DURATION); if (DEBUG) { Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset + " callers=\n" + Debug.getCallers(5, " ")); } private void adjustAndAnimatePipOffset(Rect originalBounds, int offset, int duration) { SomeArgs args = SomeArgs.obtain(); args.arg1 = originalBounds; // offset would be zero if triggered from screen rotation. args.argi1 = offset; args.argi2 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_OFFSET_ANIMATE, args)); cancelAnimations(); mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION, mUpdateBoundsCallback); } /** Loading @@ -437,8 +417,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** * Starts the physics animator which will update the animated PIP bounds using physics * animations, as well as the TimeAnimator which will apply those bounds to PIP at intervals * synchronized with the SurfaceFlinger vsync frame provider. * animations, as well as the TimeAnimator which will apply those bounds to PIP. * * This will also add end actions to the bounds animator that cancel the TimeAnimator and update * the 'real' bounds to equal the final animated bounds. Loading @@ -448,7 +427,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call mAnimatedBoundsPhysicsAnimator .withEndActions(() -> mPipTaskOrganizer.onMotionMovementEnd(mAnimatedBounds)) .addUpdateListener(mResizePipVsyncUpdateListener) .addUpdateListener(mResizePipUpdateListener) .start(); } Loading @@ -471,9 +450,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args)); mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback); } } Loading @@ -486,10 +463,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call + " duration=" + duration + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; args.argi1 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_ANIMATE, args)); mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration, mUpdateBoundsCallback); setAnimatingToBounds(toBounds); } } Loading Loading @@ -538,70 +512,6 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call return dismissArea.contains(endpoint.x, endpoint.y); } /** * Handles messages to be processed on the background thread. */ public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_RESIZE_IMMEDIATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; mPipTaskOrganizer.resizePip(toBounds); mBounds.set(toBounds); return true; } case MSG_RESIZE_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; int duration = args.argi1; 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; } mPipTaskOrganizer.animateResizePip(toBounds, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } 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; } mPipTaskOrganizer.offsetPinnedStack(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; } } public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); Loading packages/SystemUI/src/com/android/systemui/pip/phone/ForegroundThread.java→packages/SystemUI/src/com/android/systemui/pip/phone/PipUpdateThread.java +15 −10 Original line number Diff line number Diff line Loading @@ -21,33 +21,38 @@ import android.os.HandlerThread; /** * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton * foreground thread for each process. * foreground thread for each process for updating PIP. */ public final class ForegroundThread extends HandlerThread { private static ForegroundThread sInstance; public final class PipUpdateThread extends HandlerThread { private static PipUpdateThread sInstance; private static Handler sHandler; private ForegroundThread() { super("recents.fg"); private PipUpdateThread() { super("pip"); } private static void ensureThreadLocked() { if (sInstance == null) { sInstance = new ForegroundThread(); sInstance = new PipUpdateThread(); sInstance.start(); sHandler = new Handler(sInstance.getLooper()); } } public static ForegroundThread get() { synchronized (ForegroundThread.class) { /** * @return the static update thread instance */ public static PipUpdateThread get() { synchronized (PipUpdateThread.class) { ensureThreadLocked(); return sInstance; } } /** * @return the static update thread handler instance */ public static Handler getHandler() { synchronized (ForegroundThread.class) { synchronized (PipUpdateThread.class) { ensureThreadLocked(); return sHandler; } Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ public class InputConsumerController { private final class InputEventReceiver extends BatchedInputEventReceiver { public InputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper, Choreographer.getSfInstance()); super(inputChannel, looper, Choreographer.getInstance()); } @Override Loading
packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +29 −38 Original line number Diff line number Diff line Loading @@ -19,11 +19,8 @@ package com.android.systemui.pip; import android.animation.Animator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.MainThread; import android.content.Context; import android.graphics.Rect; import android.os.RemoteException; import android.view.IWindowContainer; import android.view.SurfaceControl; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; Loading Loading @@ -61,31 +58,30 @@ public class PipAnimationController { com.android.internal.R.interpolator.fast_out_slow_in); } @MainThread PipTransitionAnimator getAnimator(IWindowContainer wc, boolean scheduleFinishPip, PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, Rect destinationBounds, float alphaStart, float alphaEnd) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofAlpha(wc, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA && mCurrentAnimator.isRunning()) { mCurrentAnimator.updateEndValue(alphaEnd); } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofAlpha(wc, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); PipTransitionAnimator.ofAlpha(leash, scheduleFinishPip, destinationBounds, alphaStart, alphaEnd)); } return mCurrentAnimator; } @MainThread PipTransitionAnimator getAnimator(IWindowContainer wc, boolean scheduleFinishPip, PipTransitionAnimator getAnimator(SurfaceControl leash, boolean scheduleFinishPip, Rect startBounds, Rect endBounds) { if (mCurrentAnimator == null) { mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofBounds(wc, scheduleFinishPip, startBounds, endBounds)); PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, startBounds, endBounds)); } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS && mCurrentAnimator.isRunning()) { mCurrentAnimator.setDestinationBounds(endBounds); Loading @@ -94,7 +90,8 @@ public class PipAnimationController { } else { mCurrentAnimator.cancel(); mCurrentAnimator = setupPipTransitionAnimator( PipTransitionAnimator.ofBounds(wc, scheduleFinishPip, startBounds, endBounds)); PipTransitionAnimator.ofBounds(leash, scheduleFinishPip, startBounds, endBounds)); } return mCurrentAnimator; } Loading @@ -116,18 +113,18 @@ public class PipAnimationController { /** * Called when PiP animation is started. */ public void onPipAnimationStart(IWindowContainer wc, PipTransitionAnimator animator) {} public void onPipAnimationStart(PipTransitionAnimator animator) {} /** * Called when PiP animation is ended. */ public void onPipAnimationEnd(IWindowContainer wc, SurfaceControl.Transaction tx, public void onPipAnimationEnd(SurfaceControl.Transaction tx, PipTransitionAnimator animator) {} /** * Called when PiP animation is cancelled. */ public void onPipAnimationCancel(IWindowContainer wc, PipTransitionAnimator animator) {} public void onPipAnimationCancel(PipTransitionAnimator animator) {} } /** Loading @@ -137,7 +134,6 @@ public class PipAnimationController { public abstract static class PipTransitionAnimator<T> extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { private final IWindowContainer mWindowContainer; private final boolean mScheduleFinishPip; private final SurfaceControl mLeash; private final @AnimationType int mAnimationType; Loading @@ -149,13 +145,11 @@ public class PipAnimationController { private PipAnimationCallback mPipAnimationCallback; private SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private PipTransitionAnimator(IWindowContainer wc, boolean scheduleFinishPip, private PipTransitionAnimator(SurfaceControl leash, boolean scheduleFinishPip, @AnimationType int animationType, Rect destinationBounds, T startValue, T endValue) { mWindowContainer = wc; mScheduleFinishPip = scheduleFinishPip; try { mLeash = wc.getLeash(); mLeash = leash; mAnimationType = animationType; mDestinationBounds.set(destinationBounds); mStartValue = startValue; Loading @@ -163,9 +157,6 @@ public class PipAnimationController { addListener(this); addUpdateListener(this); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; } catch (RemoteException e) { throw new RuntimeException(e); } } @Override Loading @@ -173,7 +164,7 @@ public class PipAnimationController { mCurrentValue = mStartValue; applySurfaceControlTransaction(mLeash, newSurfaceControlTransaction(), FRACTION_START); if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationStart(mWindowContainer, this); mPipAnimationCallback.onPipAnimationStart(this); } } Loading @@ -189,14 +180,14 @@ public class PipAnimationController { final SurfaceControl.Transaction tx = newSurfaceControlTransaction(); applySurfaceControlTransaction(mLeash, tx, FRACTION_END); if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationEnd(mWindowContainer, tx, this); mPipAnimationCallback.onPipAnimationEnd(tx, this); } } @Override public void onAnimationCancel(Animator animation) { if (mPipAnimationCallback != null) { mPipAnimationCallback.onPipAnimationCancel(mWindowContainer, this); mPipAnimationCallback.onPipAnimationCancel(this); } } Loading Loading @@ -260,9 +251,9 @@ public class PipAnimationController { abstract void applySurfaceControlTransaction(SurfaceControl leash, SurfaceControl.Transaction tx, float fraction); static PipTransitionAnimator<Float> ofAlpha(IWindowContainer wc, boolean scheduleFinishPip, static PipTransitionAnimator<Float> ofAlpha(SurfaceControl leash, boolean scheduleFinishPip, Rect destinationBounds, float startValue, float endValue) { return new PipTransitionAnimator<Float>(wc, scheduleFinishPip, ANIM_TYPE_ALPHA, return new PipTransitionAnimator<Float>(leash, scheduleFinishPip, ANIM_TYPE_ALPHA, destinationBounds, startValue, endValue) { @Override void applySurfaceControlTransaction(SurfaceControl leash, Loading @@ -281,10 +272,10 @@ public class PipAnimationController { }; } static PipTransitionAnimator<Rect> ofBounds(IWindowContainer wc, boolean scheduleFinishPip, static PipTransitionAnimator<Rect> ofBounds(SurfaceControl leash, boolean scheduleFinishPip, Rect startValue, Rect endValue) { // construct new Rect instances in case they are recycled return new PipTransitionAnimator<Rect>(wc, scheduleFinishPip, ANIM_TYPE_BOUNDS, return new PipTransitionAnimator<Rect>(leash, scheduleFinishPip, ANIM_TYPE_BOUNDS, endValue, new Rect(startValue), new Rect(endValue)) { private final Rect mTmpRect = new Rect(); Loading
packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +216 −97 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +19 −109 Original line number Diff line number Diff line Loading @@ -28,16 +28,11 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.os.Debug; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.util.Log; import android.view.Choreographer; import androidx.dynamicanimation.animation.SpringForce; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.os.SomeArgs; import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.shared.system.WindowManagerWrapper; Loading @@ -47,11 +42,12 @@ import com.android.systemui.util.animation.FloatProperties; import com.android.systemui.util.animation.PhysicsAnimator; import java.io.PrintWriter; import java.util.function.Consumer; /** * A helper to animate and manipulate the PiP. */ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Callback, public class PipMotionHelper implements PipAppOpsListener.Callback, FloatingContentCoordinator.FloatingContent { private static final String TAG = "PipMotionHelper"; Loading @@ -68,14 +64,9 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call // The fraction of the stack height that the user has to drag offscreen to dismiss the PiP private static final float DISMISS_OFFSCREEN_FRACTION = 0.3f; 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 final Context mContext; private final IActivityTaskManager mActivityTaskManager; private final PipTaskOrganizer mPipTaskOrganizer; private final Handler mHandler; private PipMenuActivityController mMenuController; private PipSnapAlgorithm mSnapAlgorithm; Loading @@ -92,9 +83,6 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** The region that all of PIP must stay within. */ private Rect mFloatingAllowedArea = new Rect(); private final SfVsyncFrameCallbackProvider mSfVsyncFrameProvider = new SfVsyncFrameCallbackProvider(); /** * Bounds that are animated using the physics animator. */ Loading @@ -112,16 +100,11 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call private PhysicsAnimator<Rect> mAnimatedBoundsPhysicsAnimator = PhysicsAnimator.getInstance( mAnimatedBounds); /** Callback that re-sizes PIP to the animated bounds. */ private final Choreographer.FrameCallback mResizePipVsyncCallback = l -> resizePipUnchecked(mAnimatedBounds); /** * Update listener that posts a vsync frame callback to resize PIP to {@link #mAnimatedBounds}. * Update listener that resizes the PIP to {@link #mAnimatedBounds}. */ private final PhysicsAnimator.UpdateListener<Rect> mResizePipVsyncUpdateListener = (target, values) -> mSfVsyncFrameProvider.postFrameCallback(mResizePipVsyncCallback); private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener = (target, values) -> resizePipUnchecked(mAnimatedBounds); /** FlingConfig instances provided to PhysicsAnimator for fling gestures. */ private PhysicsAnimator.FlingConfig mFlingConfigX; Loading @@ -137,12 +120,13 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY); private final Consumer<Rect> mUpdateBoundsCallback = (toBounds) -> mBounds.set(toBounds); public PipMotionHelper(Context context, IActivityTaskManager activityTaskManager, PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils, FloatingContentCoordinator floatingContentCoordinator) { mContext = context; mHandler = new Handler(ForegroundThread.get().getLooper(), this); mActivityTaskManager = activityTaskManager; mPipTaskOrganizer = pipTaskOrganizer; mMenuController = menuController; Loading Loading @@ -234,7 +218,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call } cancelAnimations(); mMenuController.hideMenuWithoutResize(); mHandler.post(() -> { mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION); } catch (RemoteException e) { Loading @@ -253,7 +237,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call } cancelAnimations(); mMenuController.hideMenuWithoutResize(); mHandler.post(() -> { mPipTaskOrganizer.getUpdateHandler().post(() -> { try { mActivityTaskManager.removeStacksInWindowingModes( new int[]{ WINDOWING_MODE_PINNED }); Loading Loading @@ -406,17 +390,13 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call * Animates the PiP to offset it from the IME or shelf. */ void animateToOffset(Rect originalBounds, int offset) { cancelAnimations(); adjustAndAnimatePipOffset(originalBounds, offset, SHIFT_DURATION); if (DEBUG) { Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset + " callers=\n" + Debug.getCallers(5, " ")); } private void adjustAndAnimatePipOffset(Rect originalBounds, int offset, int duration) { SomeArgs args = SomeArgs.obtain(); args.arg1 = originalBounds; // offset would be zero if triggered from screen rotation. args.argi1 = offset; args.argi2 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_OFFSET_ANIMATE, args)); cancelAnimations(); mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION, mUpdateBoundsCallback); } /** Loading @@ -437,8 +417,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call /** * Starts the physics animator which will update the animated PIP bounds using physics * animations, as well as the TimeAnimator which will apply those bounds to PIP at intervals * synchronized with the SurfaceFlinger vsync frame provider. * animations, as well as the TimeAnimator which will apply those bounds to PIP. * * This will also add end actions to the bounds animator that cancel the TimeAnimator and update * the 'real' bounds to equal the final animated bounds. Loading @@ -448,7 +427,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call mAnimatedBoundsPhysicsAnimator .withEndActions(() -> mPipTaskOrganizer.onMotionMovementEnd(mAnimatedBounds)) .addUpdateListener(mResizePipVsyncUpdateListener) .addUpdateListener(mResizePipUpdateListener) .start(); } Loading @@ -471,9 +450,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args)); mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback); } } Loading @@ -486,10 +463,7 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call + " duration=" + duration + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; args.argi1 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_ANIMATE, args)); mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration, mUpdateBoundsCallback); setAnimatingToBounds(toBounds); } } Loading Loading @@ -538,70 +512,6 @@ public class PipMotionHelper implements Handler.Callback, PipAppOpsListener.Call return dismissArea.contains(endpoint.x, endpoint.y); } /** * Handles messages to be processed on the background thread. */ public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_RESIZE_IMMEDIATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; mPipTaskOrganizer.resizePip(toBounds); mBounds.set(toBounds); return true; } case MSG_RESIZE_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; int duration = args.argi1; 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; } mPipTaskOrganizer.animateResizePip(toBounds, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } 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; } mPipTaskOrganizer.offsetPinnedStack(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; } } public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); Loading
packages/SystemUI/src/com/android/systemui/pip/phone/ForegroundThread.java→packages/SystemUI/src/com/android/systemui/pip/phone/PipUpdateThread.java +15 −10 Original line number Diff line number Diff line Loading @@ -21,33 +21,38 @@ import android.os.HandlerThread; /** * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton * foreground thread for each process. * foreground thread for each process for updating PIP. */ public final class ForegroundThread extends HandlerThread { private static ForegroundThread sInstance; public final class PipUpdateThread extends HandlerThread { private static PipUpdateThread sInstance; private static Handler sHandler; private ForegroundThread() { super("recents.fg"); private PipUpdateThread() { super("pip"); } private static void ensureThreadLocked() { if (sInstance == null) { sInstance = new ForegroundThread(); sInstance = new PipUpdateThread(); sInstance.start(); sHandler = new Handler(sInstance.getLooper()); } } public static ForegroundThread get() { synchronized (ForegroundThread.class) { /** * @return the static update thread instance */ public static PipUpdateThread get() { synchronized (PipUpdateThread.class) { ensureThreadLocked(); return sInstance; } } /** * @return the static update thread handler instance */ public static Handler getHandler() { synchronized (ForegroundThread.class) { synchronized (PipUpdateThread.class) { ensureThreadLocked(); return sHandler; } Loading