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

Commit cce340ef authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Add PiP round corner on/off switch" into rvc-dev am: 8ff649e2...

Merge "Merge "Add PiP round corner on/off switch" into rvc-dev am: 8ff649e2 am: a32cd7c9" into rvc-d1-dev-plus-aosp
parents 01e9dfd5 11333b29
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -477,6 +477,9 @@
    <!-- Allow PIP to resize to a slightly bigger state upon touch/showing the menu -->
    <bool name="config_pipEnableResizeForMenu">true</bool>

    <!-- Allow PIP to enable round corner, see also R.dimen.pip_corner_radius -->
    <bool name="config_pipEnableRoundCorner">false</bool>

    <!-- SystemUI Plugins that can be loaded on user builds. -->
    <string-array name="config_pluginWhitelist" translatable="false">
        <item>com.android.systemui</item>
+28 −29
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.inject.Inject;

/**
 * Controller class of PiP animations (both from and to PiP mode).
 */
@@ -62,12 +64,15 @@ public class PipAnimationController {
    @interface TransitionDirection {}

    private final Interpolator mFastOutSlowInInterpolator;
    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;

    private PipTransitionAnimator mCurrentAnimator;

    PipAnimationController(Context context) {
    @Inject
    PipAnimationController(Context context, PipSurfaceTransactionHelper helper) {
        mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                com.android.internal.R.interpolator.fast_out_slow_in);
        mSurfaceTransactionHelper = helper;
    }

    @SuppressWarnings("unchecked")
@@ -110,6 +115,7 @@ public class PipAnimationController {
    }

    private PipTransitionAnimator setupPipTransitionAnimator(PipTransitionAnimator animator) {
        animator.setSurfaceTransactionHelper(mSurfaceTransactionHelper);
        animator.setInterpolator(mFastOutSlowInInterpolator);
        animator.setFloatValues(FRACTION_START, FRACTION_END);
        return animator;
@@ -151,9 +157,10 @@ public class PipAnimationController {
        private T mEndValue;
        private T mCurrentValue;
        private PipAnimationCallback mPipAnimationCallback;
        private SurfaceControlTransactionFactory mSurfaceControlTransactionFactory;
        private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
                mSurfaceControlTransactionFactory;
        private PipSurfaceTransactionHelper mSurfaceTransactionHelper;
        private @TransitionDirection int mTransitionDirection;
        private int mCornerRadius;

        private PipTransitionAnimator(SurfaceControl leash, @AnimationType int animationType,
                Rect destinationBounds, T startValue, T endValue) {
@@ -242,15 +249,6 @@ public class PipAnimationController {
            mCurrentValue = value;
        }

        int getCornerRadius() {
            return mCornerRadius;
        }

        PipTransitionAnimator<T> setCornerRadius(int cornerRadius) {
            mCornerRadius = cornerRadius;
            return this;
        }

        boolean shouldApplyCornerRadius() {
            return mTransitionDirection != TRANSITION_DIRECTION_TO_FULLSCREEN;
        }
@@ -273,10 +271,19 @@ public class PipAnimationController {
        }

        @VisibleForTesting
        void setSurfaceControlTransactionFactory(SurfaceControlTransactionFactory factory) {
        void setSurfaceControlTransactionFactory(
                PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
            mSurfaceControlTransactionFactory = factory;
        }

        PipSurfaceTransactionHelper getSurfaceTransactionHelper() {
            return mSurfaceTransactionHelper;
        }

        void setSurfaceTransactionHelper(PipSurfaceTransactionHelper helper) {
            mSurfaceTransactionHelper = helper;
        }

        abstract void applySurfaceControlTransaction(SurfaceControl leash,
                SurfaceControl.Transaction tx, float fraction);

@@ -289,14 +296,11 @@ public class PipAnimationController {
                        SurfaceControl.Transaction tx, float fraction) {
                    final float alpha = getStartValue() * (1 - fraction) + getEndValue() * fraction;
                    setCurrentValue(alpha);
                    tx.setAlpha(leash, alpha);
                    getSurfaceTransactionHelper().alpha(tx, leash, alpha);
                    if (Float.compare(fraction, FRACTION_START) == 0) {
                        // Ensure the start condition
                        final Rect bounds = getDestinationBounds();
                        tx.setPosition(leash, bounds.left, bounds.top)
                                .setWindowCrop(leash, bounds.width(), bounds.height());
                        tx.setCornerRadius(leash,
                                shouldApplyCornerRadius() ? getCornerRadius() : 0);
                        getSurfaceTransactionHelper()
                                .crop(tx, leash, getDestinationBounds())
                                .round(tx, leash, shouldApplyCornerRadius());
                    }
                    tx.apply();
                }
@@ -325,21 +329,16 @@ public class PipAnimationController {
                            getCastedFractionValue(start.right, end.right, fraction),
                            getCastedFractionValue(start.bottom, end.bottom, fraction));
                    setCurrentValue(mTmpRect);
                    tx.setPosition(leash, mTmpRect.left, mTmpRect.top)
                            .setWindowCrop(leash, mTmpRect.width(), mTmpRect.height());
                    getSurfaceTransactionHelper().crop(tx, leash, mTmpRect);
                    if (Float.compare(fraction, FRACTION_START) == 0) {
                        // Ensure the start condition
                        tx.setAlpha(leash, 1f);
                        tx.setCornerRadius(leash,
                                shouldApplyCornerRadius() ? getCornerRadius() : 0);
                        getSurfaceTransactionHelper()
                                .alpha(tx, leash, 1f)
                                .round(tx, leash, shouldApplyCornerRadius());
                    }
                    tx.apply();
                }
            };
        }
    }

    interface SurfaceControlTransactionFactory {
        SurfaceControl.Transaction getTransaction();
    }
}
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.systemui.pip;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.SurfaceControl;

import com.android.systemui.R;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
 */
@Singleton
public class PipSurfaceTransactionHelper {

    private final boolean mEnableCornerRadius;
    private final int mCornerRadius;

    @Inject
    public PipSurfaceTransactionHelper(Context context) {
        final Resources res = context.getResources();
        mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner);
        mCornerRadius = res.getDimensionPixelSize(R.dimen.pip_corner_radius);
    }

    /**
     * Operates the alpha on a given transaction and leash
     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
     */
    PipSurfaceTransactionHelper alpha(SurfaceControl.Transaction tx, SurfaceControl leash,
            float alpha) {
        tx.setAlpha(leash, alpha);
        return this;
    }

    /**
     * Operates the crop (and position) on a given transaction and leash
     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
     */
    PipSurfaceTransactionHelper crop(SurfaceControl.Transaction tx, SurfaceControl leash,
            Rect destinationBounds) {
        tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
                .setPosition(leash, destinationBounds.left, destinationBounds.top);
        return this;
    }

    /**
     * Operates the round corner radius on a given transaction and leash
     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
     */
    PipSurfaceTransactionHelper round(SurfaceControl.Transaction tx, SurfaceControl leash,
            boolean applyCornerRadius) {
        if (mEnableCornerRadius) {
            tx.setCornerRadius(leash, applyCornerRadius ? mCornerRadius : 0);
        }
        return this;
    }

    interface SurfaceControlTransactionFactory {
        SurfaceControl.Transaction getTransaction();
    }
}
+20 −29
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.app.PictureInPictureParams;
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
@@ -46,9 +45,7 @@ import com.android.systemui.R;
import com.android.systemui.pip.phone.PipUpdateThread;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

@@ -78,9 +75,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
    private final PipAnimationController mPipAnimationController;
    private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
    private final Rect mLastReportedBounds = new Rect();
    private final int mCornerRadius;
    private final Map<IBinder, Rect> mBoundsToRestore = new HashMap<>();
    private final int mEnterExitAnimationDuration;
    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;

    // These callbacks are called on the update thread
    private final PipAnimationController.PipAnimationCallback mPipAnimationCallback =
@@ -172,16 +168,20 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
    private SurfaceControl mLeash;
    private boolean mInPip;
    private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
    private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
            mSurfaceControlTransactionFactory;

    public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler) {
    public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
            @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper) {
        mMainHandler = new Handler(Looper.getMainLooper());
        mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
        mTaskOrganizerController = ActivityTaskManager.getTaskOrganizerController();
        mPipBoundsHandler = boundsHandler;
        mPipAnimationController = new PipAnimationController(context);
        mCornerRadius = context.getResources().getDimensionPixelSize(R.dimen.pip_corner_radius);
        mEnterExitAnimationDuration = context.getResources()
                .getInteger(R.integer.config_pipResizeAnimationDuration);
        mSurfaceTransactionHelper = surfaceTransactionHelper;
        mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
    }

    public Handler getUpdateHandler() {
@@ -234,7 +234,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            throw new RuntimeException("Unable to get leash", e);
        }
        final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
        mBoundsToRestore.put(mToken.asBinder(), currentBounds);
        if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
            scheduleAnimateResizePip(currentBounds, destinationBounds,
                    TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null);
@@ -242,7 +241,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            mUpdateHandler.post(() -> mPipAnimationController
                    .getAnimator(mLeash, destinationBounds, 0f, 1f)
                    .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                    .setCornerRadius(mCornerRadius)
                    .setPipAnimationCallback(mPipAnimationCallback)
                    .setDuration(mEnterExitAnimationDuration)
                    .start());
@@ -260,8 +258,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            Log.wtf(TAG, "Unrecognized token: " + token);
            return;
        }
        final Rect boundsToRestore = mBoundsToRestore.remove(mToken.asBinder());
        scheduleAnimateResizePip(mLastReportedBounds, boundsToRestore,
        scheduleAnimateResizePip(mLastReportedBounds,
                info.configuration.windowConfiguration.getBounds(),
                TRANSITION_DIRECTION_TO_FULLSCREEN, mEnterExitAnimationDuration, null);
        mInPip = false;
    }
@@ -307,7 +305,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
    private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds,
            @PipAnimationController.TransitionDirection int direction, int durationMs,
            Consumer<Rect> updateBoundsCallback) {
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        if (!mInPip) {
            // Ignore animation when we are no longer in PIP
            return;
@@ -326,7 +323,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
     * {@link WindowContainerTransaction} until {@link #scheduleFinishResizePip} is called.
     */
    public void scheduleResizePip(Rect toBounds, Consumer<Rect> updateBoundsCallback) {
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = updateBoundsCallback;
        args.arg2 = toBounds;
@@ -334,22 +330,20 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
    }

    /**
     * Finish a intermediate resize operation. This is expected to be called after
     * Finish an intermediate resize operation. This is expected to be called after
     * {@link #scheduleResizePip}.
     */
    public void scheduleFinishResizePip(Rect destinationBounds) {
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        SurfaceControl.Transaction tx = new SurfaceControl.Transaction()
                .setPosition(mLeash, destinationBounds.left, destinationBounds.top)
                .setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height())
                .setCornerRadius(mLeash, mInPip ? mCornerRadius : 0);
        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
        mSurfaceTransactionHelper
                .crop(tx, mLeash, destinationBounds)
                .round(tx, mLeash, mInPip);
        scheduleFinishResizePip(tx, destinationBounds, TRANSITION_DIRECTION_NONE, null);
    }

    private void scheduleFinishResizePip(SurfaceControl.Transaction tx,
            Rect destinationBounds, @PipAnimationController.TransitionDirection int direction,
            Consumer<Rect> updateBoundsCallback) {
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = updateBoundsCallback;
        args.arg2 = tx;
@@ -367,7 +361,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            // Ignore offsets when we are no longer in PIP
            return;
        }
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = updateBoundsCallback;
        args.arg2 = originalBounds;
@@ -396,17 +389,16 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
            throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
                    + "directly");
        }
        Objects.requireNonNull(mToken, "Requires valid IWindowContainer");
        // Could happen when dismissPip
        if (mToken == null || mLeash == null) {
            Log.w(TAG, "Abort animation, invalid leash");
            return;
        }
        new SurfaceControl.Transaction()
                .setPosition(mLeash, destinationBounds.left, destinationBounds.top)
                .setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height())
                .setCornerRadius(mLeash, mInPip ? mCornerRadius : 0)
                .apply();
        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
        mSurfaceTransactionHelper
                .crop(tx, mLeash, destinationBounds)
                .round(tx, mLeash, mInPip);
        tx.apply();
    }

    private void finishResize(SurfaceControl.Transaction tx, Rect destinationBounds,
@@ -449,7 +441,6 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
        mUpdateHandler.post(() -> mPipAnimationController
                .getAnimator(mLeash, currentBounds, destinationBounds)
                .setTransitionDirection(direction)
                .setCornerRadius(mCornerRadius)
                .setPipAnimationCallback(mPipAnimationCallback)
                .setDuration(durationMs)
                .start());
+5 −2
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.pip.BasePipManager;
import com.android.systemui.pip.PipBoundsHandler;
import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipSurfaceTransactionHelper;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -210,7 +211,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
            FloatingContentCoordinator floatingContentCoordinator,
            DeviceConfigProxy deviceConfig,
            PipBoundsHandler pipBoundsHandler,
            PipSnapAlgorithm pipSnapAlgorithm) {
            PipSnapAlgorithm pipSnapAlgorithm,
            PipSurfaceTransactionHelper surfaceTransactionHelper) {
        mContext = context;
        mActivityManager = ActivityManager.getService();

@@ -224,7 +226,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio

        final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
        mPipBoundsHandler = pipBoundsHandler;
        mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler);
        mPipTaskOrganizer = new PipTaskOrganizer(context, pipBoundsHandler,
                surfaceTransactionHelper);
        mPipTaskOrganizer.registerPipTransitionCallback(this);
        mInputConsumerController = InputConsumerController.getPipInputConsumer();
        mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
Loading