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

Commit a5477283 authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Animate launching desktop from overview" into main

parents cd460094 a24b63d6
Loading
Loading
Loading
Loading
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.launcher3.desktop

import android.app.IApplicationThread
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import android.view.SurfaceControl
import android.window.IRemoteTransition
import android.window.IRemoteTransitionFinishedCallback
import android.window.RemoteTransition
import android.window.TransitionInfo
import com.android.launcher3.statehandlers.DepthController
import com.android.launcher3.statemanager.StateManager
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.quickstep.SystemUiProxy
import com.android.quickstep.TaskViewUtils
import com.android.quickstep.views.DesktopTaskView
import java.util.function.Consumer

/** Manage recents related operations with desktop tasks */
class DesktopRecentsTransitionController(
    private val stateManager: StateManager<*>,
    private val systemUiProxy: SystemUiProxy,
    private val appThread: IApplicationThread,
    private val depthController: DepthController?
) {

    /** Launch desktop tasks from recents view */
    fun launchDesktopFromRecents(
        desktopTaskView: DesktopTaskView,
        callback: Consumer<Boolean>? = null
    ) {
        val animRunner =
            RemoteDesktopLaunchTransitionRunner(
                desktopTaskView,
                stateManager,
                depthController,
                callback
            )
        val transition = RemoteTransition(animRunner, appThread, "RecentsToDesktop")
        systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition)
    }

    private class RemoteDesktopLaunchTransitionRunner(
        private val desktopTaskView: DesktopTaskView,
        private val stateManager: StateManager<*>,
        private val depthController: DepthController?,
        private val successCallback: Consumer<Boolean>?
    ) : IRemoteTransition.Stub() {

        override fun startAnimation(
            token: IBinder,
            info: TransitionInfo,
            t: SurfaceControl.Transaction,
            finishCallback: IRemoteTransitionFinishedCallback
        ) {
            val errorHandlingFinishCallback = Runnable {
                try {
                    finishCallback.onTransitionFinished(null /* wct */, null /* sct */)
                } catch (e: RemoteException) {
                    Log.e(TAG, "Failed to call finish callback for desktop recents animation", e)
                }
            }

            MAIN_EXECUTOR.execute {
                TaskViewUtils.composeRecentsDesktopLaunchAnimator(
                    desktopTaskView,
                    stateManager,
                    depthController,
                    info,
                    t
                ) {
                    errorHandlingFinishCallback.run()
                    successCallback?.accept(true)
                }
            }
        }

        override fun mergeAnimation(
            transition: IBinder,
            info: TransitionInfo,
            t: SurfaceControl.Transaction,
            mergeTarget: IBinder,
            finishCallback: IRemoteTransitionFinishedCallback
        ) {}
    }

    companion object {
        const val TAG = "DesktopRecentsTransitionController"
    }
}
+13 −2
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
@@ -225,6 +226,9 @@ public class QuickstepLauncher extends Launcher {
     */
    private PendingSplitSelectInfo mPendingSplitSelectInfo = null;

    @Nullable
    private DesktopRecentsTransitionController mDesktopRecentsTransitionController;

    private SafeCloseable mViewCapture;

    private boolean mEnableWidgetDepth;
@@ -235,12 +239,19 @@ public class QuickstepLauncher extends Launcher {

        mActionsView = findViewById(R.id.overview_actions_view);
        RecentsView overviewPanel = getOverviewPanel();
        SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
        mSplitSelectStateController =
                new SplitSelectStateController(this, mHandler, getStateManager(),
                        getDepthController(), getStatsLogManager(),
                        SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this),
                        systemUiProxy, RecentsModel.INSTANCE.get(this),
                        () -> onStateBack());
        overviewPanel.init(mActionsView, mSplitSelectStateController);
        if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
            mDesktopRecentsTransitionController = new DesktopRecentsTransitionController(
                    getStateManager(), systemUiProxy, getIApplicationThread(),
                    getDepthController());
        }
        overviewPanel.init(mActionsView, mSplitSelectStateController,
                mDesktopRecentsTransitionController);
        mSplitWithKeyboardShortcutController = new SplitWithKeyboardShortcutController(this,
                mSplitSelectStateController);
        mSplitToWorkspaceController = new SplitToWorkspaceController(this,
+14 −2
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
@@ -82,6 +83,7 @@ import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -121,6 +123,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
    private final Handler mHandler = new Handler();
    private final Runnable mAnimationStartTimeoutRunnable = this::onAnimationStartTimeout;
    private SplitSelectStateController mSplitSelectStateController;
    @Nullable
    private DesktopRecentsTransitionController mDesktopRecentsTransitionController;

    /**
     * Init drag layer and overview panel views.
@@ -133,13 +137,21 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
        mFallbackRecentsView = findViewById(R.id.overview_panel);
        mActionsView = findViewById(R.id.overview_actions_view);
        getRootView().getSysUiScrim().getSysUIProgress().updateValue(0);
        SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
        mSplitSelectStateController =
                new SplitSelectStateController(this, mHandler, getStateManager(),
                        null /* depthController */, getStatsLogManager(),
                        SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this),
                        systemUiProxy, RecentsModel.INSTANCE.get(this),
                        null /*activityBackCallback*/);
        mDragLayer.recreateControllers();
        mFallbackRecentsView.init(mActionsView, mSplitSelectStateController);
        if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
            mDesktopRecentsTransitionController = new DesktopRecentsTransitionController(
                    getStateManager(), systemUiProxy, getIApplicationThread(),
                    null /* depthController */
            );
        }
        mFallbackRecentsView.init(mActionsView, mSplitSelectStateController,
                mDesktopRecentsTransitionController);

        mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
    }
+2 −2
Original line number Diff line number Diff line
@@ -1268,10 +1268,10 @@ public class SystemUiProxy implements ISystemUiProxy {
    //

    /** Call shell to show all apps active on the desktop */
    public void showDesktopApps(int displayId) {
    public void showDesktopApps(int displayId, @Nullable RemoteTransition transition) {
        if (mDesktopMode != null) {
            try {
                mDesktopMode.showDesktopApps(displayId);
                mDesktopMode.showDesktopApps(displayId, transition);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed call showDesktopApps", e);
            }
+36 −0
Original line number Diff line number Diff line
@@ -613,6 +613,42 @@ public final class TaskViewUtils {
        animator.start();
    }

    /**
     * Start recents to desktop animation
     */
    public static void composeRecentsDesktopLaunchAnimator(
            @NonNull DesktopTaskView launchingTaskView,
            @NonNull StateManager stateManager, @Nullable DepthController depthController,
            @NonNull TransitionInfo transitionInfo,
            SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                t.apply();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                finishCallback.run();
            }
        });

        final RemoteAnimationTarget[] apps = RemoteAnimationTargetCompat.wrapApps(
                transitionInfo, t, null /* leashMap */);
        final RemoteAnimationTarget[] wallpaper = RemoteAnimationTargetCompat.wrapNonApps(
                transitionInfo, true /* wallpapers */, t, null /* leashMap */);
        final RemoteAnimationTarget[] nonApps = RemoteAnimationTargetCompat.wrapNonApps(
                transitionInfo, false /* wallpapers */, t, null /* leashMap */);

        composeRecentsLaunchAnimator(animatorSet, launchingTaskView, apps, wallpaper, nonApps,
                true /* launcherClosing */, stateManager, launchingTaskView.getRecentsView(),
                depthController);

        animatorSet.start();
    }

    public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
            @NonNull RemoteAnimationTarget[] appTargets,
            @NonNull RemoteAnimationTarget[] wallpaperTargets,
Loading