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

Commit 6aa1f22c authored by Shan Huang's avatar Shan Huang Committed by Android (Google) Code Review
Browse files

Merge "Expose IBackAnimation from Shell to Launcher."

parents 9d6ae000 445c5f24
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.wm.shell.back;

import android.view.MotionEvent;

import com.android.wm.shell.common.annotations.ExternalThread;

/**
 * Interface for SysUI to get access to the Back animation related methods.
 * Interface for external process to get access to the Back animation related methods.
 */
@ExternalThread
public interface BackAnimation {

    /**
@@ -32,4 +35,11 @@ public interface BackAnimation {
     * Sets whether the back gesture is past the trigger threshold or not.
     */
    void setTriggerBack(boolean triggerBack);

    /**
     * Returns a binder that can be passed to an external process to update back animations.
     */
    default IBackAnimation createExternalInterface() {
        return null;
    }
}
+78 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.back;

import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;

import android.animation.Animator;
@@ -26,6 +27,7 @@ import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.hardware.HardwareBuffer;
@@ -35,16 +37,18 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.window.BackNavigationInfo;
import android.window.IOnBackInvokedCallback;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ShellMainThread;

/**
 * Controls the window animation run when a user initiates a back gesture.
 */
public class BackAnimationController {
public class BackAnimationController implements RemoteCallable<BackAnimationController> {

    private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
    public static final boolean IS_ENABLED = SystemProperties
@@ -72,18 +76,26 @@ public class BackAnimationController {
    private BackNavigationInfo mBackNavigationInfo;
    private final SurfaceControl.Transaction mTransaction;
    private final IActivityTaskManager mActivityTaskManager;
    private final Context mContext;
    @Nullable
    private IOnBackInvokedCallback mBackToLauncherCallback;

    public BackAnimationController(@ShellMainThread ShellExecutor shellExecutor) {
        this(shellExecutor, new SurfaceControl.Transaction(), ActivityTaskManager.getService());
    public BackAnimationController(
            @ShellMainThread ShellExecutor shellExecutor,
            Context context) {
        this(shellExecutor, new SurfaceControl.Transaction(), ActivityTaskManager.getService(),
                context);
    }

    @VisibleForTesting
    BackAnimationController(@NonNull ShellExecutor shellExecutor,
            @NonNull SurfaceControl.Transaction transaction,
            @NonNull IActivityTaskManager activityTaskManager) {
            @NonNull IActivityTaskManager activityTaskManager,
            Context context) {
        mShellExecutor = shellExecutor;
        mTransaction = transaction;
        mActivityTaskManager = activityTaskManager;
        mContext = context;
    }

    public BackAnimation getBackAnimationImpl() {
@@ -92,7 +104,27 @@ public class BackAnimationController {

    private final BackAnimation mBackAnimation = new BackAnimationImpl();

    @Override
    public Context getContext() {
        return mContext;
    }

    @Override
    public ShellExecutor getRemoteCallExecutor() {
        return mShellExecutor;
    }

    private class BackAnimationImpl implements BackAnimation {
        private IBackAnimationImpl mBackAnimation;

        @Override
        public IBackAnimation createExternalInterface() {
            if (mBackAnimation != null) {
                mBackAnimation.invalidate();
            }
            mBackAnimation = new IBackAnimationImpl(BackAnimationController.this);
            return mBackAnimation;
        }

        @Override
        public void onBackMotion(MotionEvent event) {
@@ -105,6 +137,48 @@ public class BackAnimationController {
        }
    }

    private static class IBackAnimationImpl extends IBackAnimation.Stub {
        private BackAnimationController mController;

        IBackAnimationImpl(BackAnimationController controller) {
            mController = controller;
        }

        @Override
        public void setBackToLauncherCallback(IOnBackInvokedCallback callback) {
            executeRemoteCallWithTaskPermission(mController, "setBackToLauncherCallback",
                    (controller) -> mController.setBackToLauncherCallback(callback));
        }

        @Override
        public void clearBackToLauncherCallback() {
            executeRemoteCallWithTaskPermission(mController, "clearBackToLauncherCallback",
                    (controller) -> mController.clearBackToLauncherCallback());
        }

        @Override
        public void onBackToLauncherAnimationFinished() {
            executeRemoteCallWithTaskPermission(mController, "onBackToLauncherAnimationFinished",
                    (controller) -> mController.onBackToLauncherAnimationFinished());
        }

        void invalidate() {
            mController = null;
        }
    }

    private void setBackToLauncherCallback(IOnBackInvokedCallback callback) {
        mBackToLauncherCallback = callback;
    }

    private void clearBackToLauncherCallback() {
        mBackToLauncherCallback = null;
    }

    private void onBackToLauncherAnimationFinished() {
        finishAnimation();
    }

    /**
     * Called when a new motion event needs to be transferred to this
     * {@link BackAnimationController}
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.wm.shell.back;

import android.window.IOnBackInvokedCallback;

/**
 * Interface for Launcher process to register back invocation callbacks.
 */
interface IBackAnimation {

    /**
     * Sets a {@link IOnBackInvokedCallback} to be invoked when
     * back navigation has type {@link BackNavigationInfo#TYPE_RETURN_TO_HOME}.
     */
    void setBackToLauncherCallback(in IOnBackInvokedCallback callback);

    /**
     * Clears the previously registered {@link IOnBackInvokedCallback}.
     */
    void clearBackToLauncherCallback();

    /**
     * Notifies Shell that the back to launcher animation has fully finished
     * (including the transition animation that runs after the finger is lifted).
     *
     * At this point the top window leash (if one was created) should be ready to be released.
     * //TODO: Remove once we play the transition animation through shell transitions.
     */
    void onBackToLauncherAnimationFinished();
}
+2 −1
Original line number Diff line number Diff line
@@ -696,11 +696,12 @@ public abstract class WMShellBaseModule {
    @WMSingleton
    @Provides
    static Optional<BackAnimationController> provideBackAnimationController(
            Context context,
            @ShellMainThread ShellExecutor shellExecutor
    ) {
        if (BackAnimationController.IS_ENABLED) {
            return Optional.of(
                    new BackAnimationController(shellExecutor));
                    new BackAnimationController(shellExecutor, context));
        }
        return Optional.empty();
    }
+5 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.verify;

import android.app.IActivityTaskManager;
import android.app.WindowConfiguration;
import android.content.Context;
import android.hardware.HardwareBuffer;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -51,6 +52,9 @@ public class BackAnimationControllerTest {

    private final ShellExecutor mShellExecutor = new TestShellExecutor();

    @Mock
    private Context mContext;

    @Mock
    private SurfaceControl.Transaction mTransaction;

@@ -63,7 +67,7 @@ public class BackAnimationControllerTest {
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mController = new BackAnimationController(
                mShellExecutor, mTransaction, mActivityTaskManager);
                mShellExecutor, mTransaction, mActivityTaskManager, mContext);
    }

    private void createNavigationInfo(SurfaceControl topWindowLeash,
Loading