Loading core/java/android/animation/ValueAnimator.java +11 −6 Original line number Diff line number Diff line Loading @@ -1469,24 +1469,21 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.addOneShotCommitCallback(this); getAnimationHandler().addOneShotCommitCallback(this); } private void removeAnimationCallback() { if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.removeCallback(this); getAnimationHandler().removeCallback(this); } private void addAnimationCallback(long delay) { if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.addAnimationFrameCallback(this, delay); getAnimationHandler().addAnimationFrameCallback(this, delay); } /** Loading Loading @@ -1643,4 +1640,12 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio public void setAllowRunningAsynchronously(boolean mayRunAsync) { // It is up to subclasses to support this, if they can. } /** * @return The {@link AnimationHandler} that will be used to schedule updates for this animator. * @hide */ public AnimationHandler getAnimationHandler() { return AnimationHandler.getInstance(); } } core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.internal.graphics; import android.animation.AnimationHandler.AnimationFrameCallbackProvider; import android.view.Choreographer; /** * Provider of timing pulse that uses SurfaceFlinger Vsync Choreographer for frame callbacks. * * @hide */ public final class SfVsyncFrameCallbackProvider implements AnimationFrameCallbackProvider { private final Choreographer mChoreographer = Choreographer.getSfInstance(); @Override public void postFrameCallback(Choreographer.FrameCallback callback) { mChoreographer.postFrameCallback(callback); } @Override public void postCommitCallback(Runnable runnable) { mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT, runnable, null); } @Override public long getFrameTime() { return mChoreographer.getFrameTime(); } @Override public long getFrameDelay() { return Choreographer.getFrameDelay(); } @Override public void setFrameDelay(long delay) { Choreographer.setFrameDelay(delay); } } No newline at end of file packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java +8 −4 Original line number Diff line number Diff line Loading @@ -21,12 +21,15 @@ import static android.view.WindowManager.INPUT_CONSUMER_PIP; import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.view.BatchedInputEventReceiver; import android.view.Choreographer; import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.IWindowManager; import android.view.MotionEvent; import com.android.systemui.recents.misc.Utilities; import java.io.PrintWriter; /** Loading @@ -52,12 +55,13 @@ public class InputConsumerController { } /** * Input handler used for the PiP input consumer. * Input handler used for the PiP input consumer. Input events are batched and consumed with the * SurfaceFlinger vsync. */ private final class PipInputEventReceiver extends InputEventReceiver { private final class PipInputEventReceiver extends BatchedInputEventReceiver { public PipInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); super(inputChannel, looper, Choreographer.getSfInstance()); } @Override Loading packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +3 −5 Original line number Diff line number Diff line Loading @@ -573,13 +573,11 @@ public class PipMenuActivity extends Activity { } private void cancelDelayedFinish() { View v = getWindow().getDecorView(); v.removeCallbacks(mFinishRunnable); mHandler.removeCallbacks(mFinishRunnable); } private void repostDelayedFinish(long delay) { View v = getWindow().getDecorView(); v.removeCallbacks(mFinishRunnable); v.postDelayed(mFinishRunnable, delay); mHandler.removeCallbacks(mFinishRunnable); mHandler.postDelayed(mFinishRunnable, delay); } } packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +78 −52 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN; import static com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN; import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; Loading @@ -36,14 +37,15 @@ 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 android.view.animation.Interpolator; import com.android.internal.os.BackgroundThread; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.os.SomeArgs; import com.android.internal.policy.PipSnapAlgorithm; import com.android.internal.view.SurfaceFlingerVsyncChoreographer; import com.android.systemui.recents.misc.ForegroundThread; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.FlingAnimationUtils; Loading @@ -52,7 +54,7 @@ import java.io.PrintWriter; /** * A helper to animate and manipulate the PiP. */ public class PipMotionHelper { public class PipMotionHelper implements Handler.Callback { private static final String TAG = "PipMotionHelper"; private static final boolean DEBUG = false; Loading @@ -74,38 +76,34 @@ public class PipMotionHelper { // 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 Context mContext; private IActivityManager mActivityManager; private SurfaceFlingerVsyncChoreographer mVsyncChoreographer; private Handler mHandler; private PipMenuActivityController mMenuController; private PipSnapAlgorithm mSnapAlgorithm; private FlingAnimationUtils mFlingAnimationUtils; private AnimationHandler mAnimationHandler; private final Rect mBounds = new Rect(); private final Rect mStableInsets = new Rect(); private ValueAnimator mBoundsAnimator = null; private ValueAnimator.AnimatorUpdateListener mUpdateBoundsListener = new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mBounds.set((Rect) animation.getAnimatedValue()); } }; public PipMotionHelper(Context context, IActivityManager activityManager, PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils) { mContext = context; mHandler = BackgroundThread.getHandler(); mHandler = new Handler(ForegroundThread.get().getLooper(), this); mActivityManager = activityManager; mMenuController = menuController; mSnapAlgorithm = snapAlgorithm; mFlingAnimationUtils = flingAnimationUtils; mVsyncChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, mContext.getDisplay(), Choreographer.getInstance()); mAnimationHandler = new AnimationHandler(); mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider()); onConfigurationChanged(); } Loading Loading @@ -252,8 +250,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, 0 /* velocityX */, velocityY); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN, mUpdateBoundsListener); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, distanceBetweenRectOffsets(mBounds, toBounds), velocityY); Loading @@ -271,7 +268,7 @@ public class PipMotionHelper { Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN, mUpdateBoundsListener); MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN); if (updateListener != null) { mBoundsAnimator.addUpdateListener(updateListener); } Loading @@ -289,8 +286,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, velocityX, velocityY); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN, mUpdateBoundsListener); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, distanceBetweenRectOffsets(mBounds, toBounds), velocity); Loading @@ -314,7 +310,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdateBoundsListener); FAST_OUT_SLOW_IN); if (updateListener != null) { mBoundsAnimator.addUpdateListener(updateListener); } Loading Loading @@ -379,7 +375,7 @@ public class PipMotionHelper { Rect toBounds = new Rect(pipBounds); toBounds.offsetTo(p.x, p.y); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION, FAST_OUT_LINEAR_IN, mUpdateBoundsListener); FAST_OUT_LINEAR_IN); mBoundsAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading Loading @@ -411,16 +407,20 @@ public class PipMotionHelper { * Creates an animation to move the PiP to give given {@param toBounds}. */ private ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration, Interpolator interpolator, ValueAnimator.AnimatorUpdateListener updateListener) { ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR, fromBounds, toBounds); Interpolator interpolator) { ValueAnimator anim = new ValueAnimator() { @Override public AnimationHandler getAnimationHandler() { return mAnimationHandler; } }; anim.setObjectValues(fromBounds, toBounds); anim.setEvaluator(RECT_EVALUATOR); anim.setDuration(duration); anim.setInterpolator(interpolator); anim.addUpdateListener((ValueAnimator animation) -> { resizePipUnchecked((Rect) animation.getAnimatedValue()); }); if (updateListener != null) { anim.addUpdateListener(updateListener); } return anim; } Loading @@ -433,14 +433,9 @@ public class PipMotionHelper { + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { mVsyncChoreographer.scheduleAtSfVsync(() -> { try { mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not resize pinned stack to bounds: " + toBounds, e); } }); SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args)); } } Loading @@ -453,23 +448,10 @@ public class PipMotionHelper { + " duration=" + duration + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { mHandler.post(() -> { try { StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return; } mActivityManager.resizeStack(PINNED_STACK_ID, toBounds, false /* allowResizeInDockedMode */, true /* preserveWindows */, true /* animate */, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } }); SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; args.argi1 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_ANIMATE, args)); } } Loading Loading @@ -524,6 +506,50 @@ public class PipMotionHelper { return PointF.length(r1.left - r2.left, r1.top - r2.top); } /** * 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; try { mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not resize pinned stack to bounds: " + toBounds, e); } return true; } case MSG_RESIZE_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; int duration = args.argi1; try { StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return true; } mActivityManager.resizeStack(PINNED_STACK_ID, toBounds, false /* allowResizeInDockedMode */, true /* preserveWindows */, true /* animate */, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } return true; } default: return false; } } public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); Loading Loading
core/java/android/animation/ValueAnimator.java +11 −6 Original line number Diff line number Diff line Loading @@ -1469,24 +1469,21 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.addOneShotCommitCallback(this); getAnimationHandler().addOneShotCommitCallback(this); } private void removeAnimationCallback() { if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.removeCallback(this); getAnimationHandler().removeCallback(this); } private void addAnimationCallback(long delay) { if (!mSelfPulse) { return; } AnimationHandler handler = AnimationHandler.getInstance(); handler.addAnimationFrameCallback(this, delay); getAnimationHandler().addAnimationFrameCallback(this, delay); } /** Loading Loading @@ -1643,4 +1640,12 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio public void setAllowRunningAsynchronously(boolean mayRunAsync) { // It is up to subclasses to support this, if they can. } /** * @return The {@link AnimationHandler} that will be used to schedule updates for this animator. * @hide */ public AnimationHandler getAnimationHandler() { return AnimationHandler.getInstance(); } }
core/java/com/android/internal/graphics/SfVsyncFrameCallbackProvider.java 0 → 100644 +55 −0 Original line number Diff line number Diff line /* * 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.internal.graphics; import android.animation.AnimationHandler.AnimationFrameCallbackProvider; import android.view.Choreographer; /** * Provider of timing pulse that uses SurfaceFlinger Vsync Choreographer for frame callbacks. * * @hide */ public final class SfVsyncFrameCallbackProvider implements AnimationFrameCallbackProvider { private final Choreographer mChoreographer = Choreographer.getSfInstance(); @Override public void postFrameCallback(Choreographer.FrameCallback callback) { mChoreographer.postFrameCallback(callback); } @Override public void postCommitCallback(Runnable runnable) { mChoreographer.postCallback(Choreographer.CALLBACK_COMMIT, runnable, null); } @Override public long getFrameTime() { return mChoreographer.getFrameTime(); } @Override public long getFrameDelay() { return Choreographer.getFrameDelay(); } @Override public void setFrameDelay(long delay) { Choreographer.setFrameDelay(delay); } } No newline at end of file
packages/SystemUI/src/com/android/systemui/pip/phone/InputConsumerController.java +8 −4 Original line number Diff line number Diff line Loading @@ -21,12 +21,15 @@ import static android.view.WindowManager.INPUT_CONSUMER_PIP; import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.view.BatchedInputEventReceiver; import android.view.Choreographer; import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.IWindowManager; import android.view.MotionEvent; import com.android.systemui.recents.misc.Utilities; import java.io.PrintWriter; /** Loading @@ -52,12 +55,13 @@ public class InputConsumerController { } /** * Input handler used for the PiP input consumer. * Input handler used for the PiP input consumer. Input events are batched and consumed with the * SurfaceFlinger vsync. */ private final class PipInputEventReceiver extends InputEventReceiver { private final class PipInputEventReceiver extends BatchedInputEventReceiver { public PipInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); super(inputChannel, looper, Choreographer.getSfInstance()); } @Override Loading
packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +3 −5 Original line number Diff line number Diff line Loading @@ -573,13 +573,11 @@ public class PipMenuActivity extends Activity { } private void cancelDelayedFinish() { View v = getWindow().getDecorView(); v.removeCallbacks(mFinishRunnable); mHandler.removeCallbacks(mFinishRunnable); } private void repostDelayedFinish(long delay) { View v = getWindow().getDecorView(); v.removeCallbacks(mFinishRunnable); v.postDelayed(mFinishRunnable, delay); mHandler.removeCallbacks(mFinishRunnable); mHandler.postDelayed(mFinishRunnable, delay); } }
packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +78 −52 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN; import static com.android.systemui.Interpolators.LINEAR_OUT_SLOW_IN; import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorListenerAdapter; Loading @@ -36,14 +37,15 @@ 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 android.view.animation.Interpolator; import com.android.internal.os.BackgroundThread; import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import com.android.internal.os.SomeArgs; import com.android.internal.policy.PipSnapAlgorithm; import com.android.internal.view.SurfaceFlingerVsyncChoreographer; import com.android.systemui.recents.misc.ForegroundThread; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.FlingAnimationUtils; Loading @@ -52,7 +54,7 @@ import java.io.PrintWriter; /** * A helper to animate and manipulate the PiP. */ public class PipMotionHelper { public class PipMotionHelper implements Handler.Callback { private static final String TAG = "PipMotionHelper"; private static final boolean DEBUG = false; Loading @@ -74,38 +76,34 @@ public class PipMotionHelper { // 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 Context mContext; private IActivityManager mActivityManager; private SurfaceFlingerVsyncChoreographer mVsyncChoreographer; private Handler mHandler; private PipMenuActivityController mMenuController; private PipSnapAlgorithm mSnapAlgorithm; private FlingAnimationUtils mFlingAnimationUtils; private AnimationHandler mAnimationHandler; private final Rect mBounds = new Rect(); private final Rect mStableInsets = new Rect(); private ValueAnimator mBoundsAnimator = null; private ValueAnimator.AnimatorUpdateListener mUpdateBoundsListener = new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mBounds.set((Rect) animation.getAnimatedValue()); } }; public PipMotionHelper(Context context, IActivityManager activityManager, PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils) { mContext = context; mHandler = BackgroundThread.getHandler(); mHandler = new Handler(ForegroundThread.get().getLooper(), this); mActivityManager = activityManager; mMenuController = menuController; mSnapAlgorithm = snapAlgorithm; mFlingAnimationUtils = flingAnimationUtils; mVsyncChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, mContext.getDisplay(), Choreographer.getInstance()); mAnimationHandler = new AnimationHandler(); mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider()); onConfigurationChanged(); } Loading Loading @@ -252,8 +250,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, 0 /* velocityX */, velocityY); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN, mUpdateBoundsListener); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, distanceBetweenRectOffsets(mBounds, toBounds), velocityY); Loading @@ -271,7 +268,7 @@ public class PipMotionHelper { Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN, mUpdateBoundsListener); MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN); if (updateListener != null) { mBoundsAnimator.addUpdateListener(updateListener); } Loading @@ -289,8 +286,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds, velocityX, velocityY); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN, mUpdateBoundsListener); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN); mFlingAnimationUtils.apply(mBoundsAnimator, 0, distanceBetweenRectOffsets(mBounds, toBounds), velocity); Loading @@ -314,7 +310,7 @@ public class PipMotionHelper { Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds); if (!mBounds.equals(toBounds)) { mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdateBoundsListener); FAST_OUT_SLOW_IN); if (updateListener != null) { mBoundsAnimator.addUpdateListener(updateListener); } Loading Loading @@ -379,7 +375,7 @@ public class PipMotionHelper { Rect toBounds = new Rect(pipBounds); toBounds.offsetTo(p.x, p.y); mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION, FAST_OUT_LINEAR_IN, mUpdateBoundsListener); FAST_OUT_LINEAR_IN); mBoundsAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading Loading @@ -411,16 +407,20 @@ public class PipMotionHelper { * Creates an animation to move the PiP to give given {@param toBounds}. */ private ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration, Interpolator interpolator, ValueAnimator.AnimatorUpdateListener updateListener) { ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR, fromBounds, toBounds); Interpolator interpolator) { ValueAnimator anim = new ValueAnimator() { @Override public AnimationHandler getAnimationHandler() { return mAnimationHandler; } }; anim.setObjectValues(fromBounds, toBounds); anim.setEvaluator(RECT_EVALUATOR); anim.setDuration(duration); anim.setInterpolator(interpolator); anim.addUpdateListener((ValueAnimator animation) -> { resizePipUnchecked((Rect) animation.getAnimatedValue()); }); if (updateListener != null) { anim.addUpdateListener(updateListener); } return anim; } Loading @@ -433,14 +433,9 @@ public class PipMotionHelper { + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { mVsyncChoreographer.scheduleAtSfVsync(() -> { try { mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not resize pinned stack to bounds: " + toBounds, e); } }); SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args)); } } Loading @@ -453,23 +448,10 @@ public class PipMotionHelper { + " duration=" + duration + " callers=\n" + Debug.getCallers(5, " ")); } if (!toBounds.equals(mBounds)) { mHandler.post(() -> { try { StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return; } mActivityManager.resizeStack(PINNED_STACK_ID, toBounds, false /* allowResizeInDockedMode */, true /* preserveWindows */, true /* animate */, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } }); SomeArgs args = SomeArgs.obtain(); args.arg1 = toBounds; args.argi1 = duration; mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_ANIMATE, args)); } } Loading Loading @@ -524,6 +506,50 @@ public class PipMotionHelper { return PointF.length(r1.left - r2.left, r1.top - r2.top); } /** * 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; try { mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not resize pinned stack to bounds: " + toBounds, e); } return true; } case MSG_RESIZE_ANIMATE: { SomeArgs args = (SomeArgs) msg.obj; Rect toBounds = (Rect) args.arg1; int duration = args.argi1; try { StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); if (stackInfo == null) { // In the case where we've already re-expanded or dismissed the PiP, then // just skip the resize return true; } mActivityManager.resizeStack(PINNED_STACK_ID, toBounds, false /* allowResizeInDockedMode */, true /* preserveWindows */, true /* animate */, duration); mBounds.set(toBounds); } catch (RemoteException e) { Log.e(TAG, "Could not animate resize pinned stack to bounds: " + toBounds, e); } return true; } default: return false; } } public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); Loading