Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90159a24 authored by Wale Ogunwale's avatar Wale Ogunwale Committed by android-build-merger
Browse files

Merge "Ensure that we use SF Vsync Choreographer for the PiP transition." into oc-dev

am: e1e0db8c

Change-Id: Ie70addce27b9551323d7c9d8f9576aa118b98114
parents d04d501c e1e0db8c
Loading
Loading
Loading
Loading
+11 −6
Original line number Original line Diff line number Diff line
@@ -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();
    }
}
}
+55 −0
Original line number Original line 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
+8 −4
Original line number Original line Diff line number Diff line
@@ -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
+3 −5
Original line number Original line Diff line number Diff line
@@ -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);
    }
    }
}
}
+78 −52
Original line number Original line Diff line number Diff line
@@ -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);
Loading