Merge "Ensure that we use SF Vsync Choreographer for the PiP transition." into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e1e0db8ca9
@@ -1469,24 +1469,21 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
|
|||||||
if (!mSelfPulse) {
|
if (!mSelfPulse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AnimationHandler handler = AnimationHandler.getInstance();
|
getAnimationHandler().addOneShotCommitCallback(this);
|
||||||
handler.addOneShotCommitCallback(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAnimationCallback() {
|
private void removeAnimationCallback() {
|
||||||
if (!mSelfPulse) {
|
if (!mSelfPulse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AnimationHandler handler = AnimationHandler.getInstance();
|
getAnimationHandler().removeCallback(this);
|
||||||
handler.removeCallback(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAnimationCallback(long delay) {
|
private void addAnimationCallback(long delay) {
|
||||||
if (!mSelfPulse) {
|
if (!mSelfPulse) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AnimationHandler handler = AnimationHandler.getInstance();
|
getAnimationHandler().addAnimationFrameCallback(this, delay);
|
||||||
handler.addAnimationFrameCallback(this, delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1643,4 +1640,12 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio
|
|||||||
public void setAllowRunningAsynchronously(boolean mayRunAsync) {
|
public void setAllowRunningAsynchronously(boolean mayRunAsync) {
|
||||||
// It is up to subclasses to support this, if they can.
|
// 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,12 +21,15 @@ import static android.view.WindowManager.INPUT_CONSUMER_PIP;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.BatchedInputEventReceiver;
|
||||||
|
import android.view.Choreographer;
|
||||||
import android.view.InputChannel;
|
import android.view.InputChannel;
|
||||||
import android.view.InputEvent;
|
import android.view.InputEvent;
|
||||||
import android.view.InputEventReceiver;
|
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.android.systemui.recents.misc.Utilities;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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) {
|
public PipInputEventReceiver(InputChannel inputChannel, Looper looper) {
|
||||||
super(inputChannel, looper);
|
super(inputChannel, looper, Choreographer.getSfInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -573,13 +573,11 @@ public class PipMenuActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void cancelDelayedFinish() {
|
private void cancelDelayedFinish() {
|
||||||
View v = getWindow().getDecorView();
|
mHandler.removeCallbacks(mFinishRunnable);
|
||||||
v.removeCallbacks(mFinishRunnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void repostDelayedFinish(long delay) {
|
private void repostDelayedFinish(long delay) {
|
||||||
View v = getWindow().getDecorView();
|
mHandler.removeCallbacks(mFinishRunnable);
|
||||||
v.removeCallbacks(mFinishRunnable);
|
mHandler.postDelayed(mFinishRunnable, delay);
|
||||||
v.postDelayed(mFinishRunnable, delay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.FAST_OUT_SLOW_IN;
|
||||||
import static com.android.systemui.Interpolators.LINEAR_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;
|
||||||
import android.animation.Animator.AnimatorListener;
|
import android.animation.Animator.AnimatorListener;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@@ -36,14 +37,15 @@ import android.graphics.PointF;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Choreographer;
|
|
||||||
import android.view.animation.Interpolator;
|
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.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.recents.misc.SystemServicesProxy;
|
||||||
import com.android.systemui.statusbar.FlingAnimationUtils;
|
import com.android.systemui.statusbar.FlingAnimationUtils;
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ import java.io.PrintWriter;
|
|||||||
/**
|
/**
|
||||||
* A helper to animate and manipulate the PiP.
|
* 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 String TAG = "PipMotionHelper";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
@@ -74,38 +76,34 @@ public class PipMotionHelper {
|
|||||||
// The fraction of the stack height that the user has to drag offscreen to dismiss the PiP
|
// 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 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 Context mContext;
|
||||||
private IActivityManager mActivityManager;
|
private IActivityManager mActivityManager;
|
||||||
private SurfaceFlingerVsyncChoreographer mVsyncChoreographer;
|
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
|
|
||||||
private PipMenuActivityController mMenuController;
|
private PipMenuActivityController mMenuController;
|
||||||
private PipSnapAlgorithm mSnapAlgorithm;
|
private PipSnapAlgorithm mSnapAlgorithm;
|
||||||
private FlingAnimationUtils mFlingAnimationUtils;
|
private FlingAnimationUtils mFlingAnimationUtils;
|
||||||
|
private AnimationHandler mAnimationHandler;
|
||||||
|
|
||||||
private final Rect mBounds = new Rect();
|
private final Rect mBounds = new Rect();
|
||||||
private final Rect mStableInsets = new Rect();
|
private final Rect mStableInsets = new Rect();
|
||||||
|
|
||||||
private ValueAnimator mBoundsAnimator = null;
|
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,
|
public PipMotionHelper(Context context, IActivityManager activityManager,
|
||||||
PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
|
PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
|
||||||
FlingAnimationUtils flingAnimationUtils) {
|
FlingAnimationUtils flingAnimationUtils) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mHandler = BackgroundThread.getHandler();
|
mHandler = new Handler(ForegroundThread.get().getLooper(), this);
|
||||||
mActivityManager = activityManager;
|
mActivityManager = activityManager;
|
||||||
mMenuController = menuController;
|
mMenuController = menuController;
|
||||||
mSnapAlgorithm = snapAlgorithm;
|
mSnapAlgorithm = snapAlgorithm;
|
||||||
mFlingAnimationUtils = flingAnimationUtils;
|
mFlingAnimationUtils = flingAnimationUtils;
|
||||||
mVsyncChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, mContext.getDisplay(),
|
mAnimationHandler = new AnimationHandler();
|
||||||
Choreographer.getInstance());
|
mAnimationHandler.setProvider(new SfVsyncFrameCallbackProvider());
|
||||||
onConfigurationChanged();
|
onConfigurationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,8 +250,7 @@ public class PipMotionHelper {
|
|||||||
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
|
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
|
||||||
0 /* velocityX */, velocityY);
|
0 /* velocityX */, velocityY);
|
||||||
if (!mBounds.equals(toBounds)) {
|
if (!mBounds.equals(toBounds)) {
|
||||||
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN,
|
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
|
||||||
mUpdateBoundsListener);
|
|
||||||
mFlingAnimationUtils.apply(mBoundsAnimator, 0,
|
mFlingAnimationUtils.apply(mBoundsAnimator, 0,
|
||||||
distanceBetweenRectOffsets(mBounds, toBounds),
|
distanceBetweenRectOffsets(mBounds, toBounds),
|
||||||
velocityY);
|
velocityY);
|
||||||
@@ -271,7 +268,7 @@ public class PipMotionHelper {
|
|||||||
Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds);
|
Rect toBounds = getClosestMinimizedBounds(mBounds, movementBounds);
|
||||||
if (!mBounds.equals(toBounds)) {
|
if (!mBounds.equals(toBounds)) {
|
||||||
mBoundsAnimator = createAnimationToBounds(mBounds, 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) {
|
if (updateListener != null) {
|
||||||
mBoundsAnimator.addUpdateListener(updateListener);
|
mBoundsAnimator.addUpdateListener(updateListener);
|
||||||
}
|
}
|
||||||
@@ -289,8 +286,7 @@ public class PipMotionHelper {
|
|||||||
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
|
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds,
|
||||||
velocityX, velocityY);
|
velocityX, velocityY);
|
||||||
if (!mBounds.equals(toBounds)) {
|
if (!mBounds.equals(toBounds)) {
|
||||||
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN,
|
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, 0, FAST_OUT_SLOW_IN);
|
||||||
mUpdateBoundsListener);
|
|
||||||
mFlingAnimationUtils.apply(mBoundsAnimator, 0,
|
mFlingAnimationUtils.apply(mBoundsAnimator, 0,
|
||||||
distanceBetweenRectOffsets(mBounds, toBounds),
|
distanceBetweenRectOffsets(mBounds, toBounds),
|
||||||
velocity);
|
velocity);
|
||||||
@@ -314,7 +310,7 @@ public class PipMotionHelper {
|
|||||||
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds);
|
Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mBounds);
|
||||||
if (!mBounds.equals(toBounds)) {
|
if (!mBounds.equals(toBounds)) {
|
||||||
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION,
|
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, SNAP_STACK_DURATION,
|
||||||
FAST_OUT_SLOW_IN, mUpdateBoundsListener);
|
FAST_OUT_SLOW_IN);
|
||||||
if (updateListener != null) {
|
if (updateListener != null) {
|
||||||
mBoundsAnimator.addUpdateListener(updateListener);
|
mBoundsAnimator.addUpdateListener(updateListener);
|
||||||
}
|
}
|
||||||
@@ -379,7 +375,7 @@ public class PipMotionHelper {
|
|||||||
Rect toBounds = new Rect(pipBounds);
|
Rect toBounds = new Rect(pipBounds);
|
||||||
toBounds.offsetTo(p.x, p.y);
|
toBounds.offsetTo(p.x, p.y);
|
||||||
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION,
|
mBoundsAnimator = createAnimationToBounds(mBounds, toBounds, DRAG_TO_DISMISS_STACK_DURATION,
|
||||||
FAST_OUT_LINEAR_IN, mUpdateBoundsListener);
|
FAST_OUT_LINEAR_IN);
|
||||||
mBoundsAnimator.addListener(new AnimatorListenerAdapter() {
|
mBoundsAnimator.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
@@ -411,16 +407,20 @@ public class PipMotionHelper {
|
|||||||
* Creates an animation to move the PiP to give given {@param toBounds}.
|
* Creates an animation to move the PiP to give given {@param toBounds}.
|
||||||
*/
|
*/
|
||||||
private ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration,
|
private ValueAnimator createAnimationToBounds(Rect fromBounds, Rect toBounds, int duration,
|
||||||
Interpolator interpolator, ValueAnimator.AnimatorUpdateListener updateListener) {
|
Interpolator interpolator) {
|
||||||
ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR, fromBounds, toBounds);
|
ValueAnimator anim = new ValueAnimator() {
|
||||||
|
@Override
|
||||||
|
public AnimationHandler getAnimationHandler() {
|
||||||
|
return mAnimationHandler;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
anim.setObjectValues(fromBounds, toBounds);
|
||||||
|
anim.setEvaluator(RECT_EVALUATOR);
|
||||||
anim.setDuration(duration);
|
anim.setDuration(duration);
|
||||||
anim.setInterpolator(interpolator);
|
anim.setInterpolator(interpolator);
|
||||||
anim.addUpdateListener((ValueAnimator animation) -> {
|
anim.addUpdateListener((ValueAnimator animation) -> {
|
||||||
resizePipUnchecked((Rect) animation.getAnimatedValue());
|
resizePipUnchecked((Rect) animation.getAnimatedValue());
|
||||||
});
|
});
|
||||||
if (updateListener != null) {
|
|
||||||
anim.addUpdateListener(updateListener);
|
|
||||||
}
|
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,14 +433,9 @@ public class PipMotionHelper {
|
|||||||
+ " callers=\n" + Debug.getCallers(5, " "));
|
+ " callers=\n" + Debug.getCallers(5, " "));
|
||||||
}
|
}
|
||||||
if (!toBounds.equals(mBounds)) {
|
if (!toBounds.equals(mBounds)) {
|
||||||
mVsyncChoreographer.scheduleAtSfVsync(() -> {
|
SomeArgs args = SomeArgs.obtain();
|
||||||
try {
|
args.arg1 = toBounds;
|
||||||
mActivityManager.resizePinnedStack(toBounds, null /* tempPinnedTaskBounds */);
|
mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args));
|
||||||
mBounds.set(toBounds);
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Could not resize pinned stack to bounds: " + toBounds, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,23 +448,10 @@ public class PipMotionHelper {
|
|||||||
+ " duration=" + duration + " callers=\n" + Debug.getCallers(5, " "));
|
+ " duration=" + duration + " callers=\n" + Debug.getCallers(5, " "));
|
||||||
}
|
}
|
||||||
if (!toBounds.equals(mBounds)) {
|
if (!toBounds.equals(mBounds)) {
|
||||||
mHandler.post(() -> {
|
SomeArgs args = SomeArgs.obtain();
|
||||||
try {
|
args.arg1 = toBounds;
|
||||||
StackInfo stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
args.argi1 = duration;
|
||||||
if (stackInfo == null) {
|
mHandler.sendMessage(mHandler.obtainMessage(MSG_RESIZE_ANIMATE, args));
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,6 +506,50 @@ public class PipMotionHelper {
|
|||||||
return PointF.length(r1.left - r2.left, r1.top - r2.top);
|
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) {
|
public void dump(PrintWriter pw, String prefix) {
|
||||||
final String innerPrefix = prefix + " ";
|
final String innerPrefix = prefix + " ";
|
||||||
pw.println(prefix + TAG);
|
pw.println(prefix + TAG);
|
||||||
|
|||||||
@@ -154,6 +154,13 @@ public class SystemServicesProxy {
|
|||||||
Canvas mBgProtectionCanvas;
|
Canvas mBgProtectionCanvas;
|
||||||
|
|
||||||
private final Handler mHandler = new H();
|
private final Handler mHandler = new H();
|
||||||
|
private final Runnable mGcRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
System.gc();
|
||||||
|
System.runFinalization();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
|
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
|
||||||
|
|
||||||
@@ -365,13 +372,7 @@ public class SystemServicesProxy {
|
|||||||
* Requests a gc() from the background thread.
|
* Requests a gc() from the background thread.
|
||||||
*/
|
*/
|
||||||
public void gc() {
|
public void gc() {
|
||||||
BackgroundThread.getHandler().post(new Runnable() {
|
BackgroundThread.getHandler().post(mGcRunnable);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
System.gc();
|
|
||||||
System.runFinalization();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -799,11 +800,8 @@ public class SystemServicesProxy {
|
|||||||
if (RecentsDebugFlags.Static.EnableMockTasks) return;
|
if (RecentsDebugFlags.Static.EnableMockTasks) return;
|
||||||
|
|
||||||
// Remove the task.
|
// Remove the task.
|
||||||
BackgroundThread.getHandler().post(new Runnable() {
|
mUiOffloadThread.submit(() -> {
|
||||||
@Override
|
mAm.removeTask(taskId);
|
||||||
public void run() {
|
|
||||||
mAm.removeTask(taskId);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import android.content.Context;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import com.android.internal.content.PackageMonitor;
|
import com.android.internal.content.PackageMonitor;
|
||||||
import com.android.internal.os.BackgroundThread;
|
|
||||||
import com.android.systemui.recents.events.EventBus;
|
import com.android.systemui.recents.events.EventBus;
|
||||||
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
|
import com.android.systemui.recents.events.activity.PackagesChangedEvent;
|
||||||
|
import com.android.systemui.recents.misc.ForegroundThread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The package monitor listens for changes from PackageManager to update the contents of the
|
* The package monitor listens for changes from PackageManager to update the contents of the
|
||||||
@@ -36,7 +36,7 @@ public class RecentsPackageMonitor extends PackageMonitor {
|
|||||||
// We register for events from all users, but will cross-reference them with
|
// We register for events from all users, but will cross-reference them with
|
||||||
// packages for the current user and any profiles they have. Ensure that events are
|
// packages for the current user and any profiles they have. Ensure that events are
|
||||||
// handled in a background thread.
|
// handled in a background thread.
|
||||||
register(context, BackgroundThread.get().getLooper(), UserHandle.ALL, true);
|
register(context, ForegroundThread.get().getLooper(), UserHandle.ALL, true);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
|
|||||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||||
|
|
||||||
|
import android.animation.AnimationHandler;
|
||||||
|
import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
@@ -30,11 +32,13 @@ import android.os.IBinder;
|
|||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.view.Choreographer;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
import android.view.WindowManagerInternal;
|
import android.view.WindowManagerInternal;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -49,7 +53,7 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
*
|
*
|
||||||
* The object that is resized needs to implement {@link BoundsAnimationTarget} interface.
|
* The object that is resized needs to implement {@link BoundsAnimationTarget} interface.
|
||||||
*
|
*
|
||||||
* NOTE: All calls to methods in this class should be done on the UI thread
|
* NOTE: All calls to methods in this class should be done on the Animation thread
|
||||||
*/
|
*/
|
||||||
public class BoundsAnimationController {
|
public class BoundsAnimationController {
|
||||||
private static final boolean DEBUG_LOCAL = false;
|
private static final boolean DEBUG_LOCAL = false;
|
||||||
@@ -111,20 +115,24 @@ public class BoundsAnimationController {
|
|||||||
private final AppTransitionNotifier mAppTransitionNotifier = new AppTransitionNotifier();
|
private final AppTransitionNotifier mAppTransitionNotifier = new AppTransitionNotifier();
|
||||||
private final Interpolator mFastOutSlowInInterpolator;
|
private final Interpolator mFastOutSlowInInterpolator;
|
||||||
private boolean mFinishAnimationAfterTransition = false;
|
private boolean mFinishAnimationAfterTransition = false;
|
||||||
|
private final AnimationHandler mAnimationHandler;
|
||||||
|
|
||||||
private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
|
private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
|
||||||
|
|
||||||
BoundsAnimationController(Context context, AppTransition transition, Handler handler) {
|
BoundsAnimationController(Context context, AppTransition transition, Handler handler,
|
||||||
|
AnimationHandler animationHandler) {
|
||||||
mHandler = handler;
|
mHandler = handler;
|
||||||
mAppTransition = transition;
|
mAppTransition = transition;
|
||||||
mAppTransition.registerListenerLocked(mAppTransitionNotifier);
|
mAppTransition.registerListenerLocked(mAppTransitionNotifier);
|
||||||
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
|
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
|
||||||
com.android.internal.R.interpolator.fast_out_slow_in);
|
com.android.internal.R.interpolator.fast_out_slow_in);
|
||||||
|
mAnimationHandler = animationHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final class BoundsAnimator extends ValueAnimator
|
final class BoundsAnimator extends ValueAnimator
|
||||||
implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
|
implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
|
||||||
|
|
||||||
private final BoundsAnimationTarget mTarget;
|
private final BoundsAnimationTarget mTarget;
|
||||||
private final Rect mFrom = new Rect();
|
private final Rect mFrom = new Rect();
|
||||||
private final Rect mTo = new Rect();
|
private final Rect mTo = new Rect();
|
||||||
@@ -350,6 +358,14 @@ public class BoundsAnimationController {
|
|||||||
public void onAnimationRepeat(Animator animation) {
|
public void onAnimationRepeat(Animator animation) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AnimationHandler getAnimationHandler() {
|
||||||
|
if (mAnimationHandler != null) {
|
||||||
|
return mAnimationHandler;
|
||||||
|
}
|
||||||
|
return super.getAnimationHandler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
|
public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to,
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
|||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.Manifest.permission;
|
import android.Manifest.permission;
|
||||||
|
import android.animation.AnimationHandler;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
@@ -211,6 +212,7 @@ import android.view.inputmethod.InputMethodManagerInternal;
|
|||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.app.IAssistScreenshotReceiver;
|
import com.android.internal.app.IAssistScreenshotReceiver;
|
||||||
|
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||||
import com.android.internal.os.IResultReceiver;
|
import com.android.internal.os.IResultReceiver;
|
||||||
import com.android.internal.policy.IKeyguardDismissCallback;
|
import com.android.internal.policy.IKeyguardDismissCallback;
|
||||||
import com.android.internal.policy.IShortcutService;
|
import com.android.internal.policy.IShortcutService;
|
||||||
@@ -1046,8 +1048,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
mAppTransition = new AppTransition(context, this);
|
mAppTransition = new AppTransition(context, this);
|
||||||
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
|
mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
|
||||||
|
|
||||||
|
final AnimationHandler animationHandler = new AnimationHandler();
|
||||||
|
animationHandler.setProvider(new SfVsyncFrameCallbackProvider());
|
||||||
mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
|
mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
|
||||||
UiThread.getHandler());
|
AnimationThread.getHandler(), animationHandler);
|
||||||
|
|
||||||
mActivityManager = ActivityManager.getService();
|
mActivityManager = ActivityManager.getService();
|
||||||
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
|
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
|
|||||||
mMockAppTransition = new MockAppTransition(context);
|
mMockAppTransition = new MockAppTransition(context);
|
||||||
mMockAnimator = new MockValueAnimator();
|
mMockAnimator = new MockValueAnimator();
|
||||||
mTarget = new TestBoundsAnimationTarget();
|
mTarget = new TestBoundsAnimationTarget();
|
||||||
mController = new BoundsAnimationController(context, mMockAppTransition, handler);
|
mController = new BoundsAnimationController(context, mMockAppTransition, handler, null);
|
||||||
mDriver = new BoundsAnimationDriver(mController, mTarget);
|
mDriver = new BoundsAnimationDriver(mController, mTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user