Expose IBackAnimation from Shell to Launcher.

Test: m -j
Bug: b/195946584
Change-Id: I26f48e78c91ef99757da9bc09d4a4f98dc50f863
This commit is contained in:
Shan Huang
2022-01-31 23:58:47 +00:00
parent 4081821956
commit 445c5f24a2
7 changed files with 150 additions and 7 deletions

View File

@@ -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;
}
}

View File

@@ -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}

View File

@@ -0,0 +1,45 @@
/*
* 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();
}

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -59,6 +59,7 @@ public class QuickStepContract {
public static final String KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER = "unlock_animation";
// See IRecentTasks.aidl
public static final String KEY_EXTRA_RECENT_TASKS = "recent_tasks";
public static final String KEY_EXTRA_SHELL_BACK_ANIMATION = "extra_shell_back_animation";
public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;

View File

@@ -26,6 +26,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_BACK_ANIMATION;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
@@ -104,6 +105,7 @@ import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.onehanded.OneHanded;
import com.android.wm.shell.pip.Pip;
@@ -163,6 +165,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
private final Optional<StartingSurface> mStartingSurface;
private final KeyguardUnlockAnimationController mSysuiUnlockAnimationController;
private final Optional<RecentTasks> mRecentTasks;
private final Optional<BackAnimation> mBackAnimation;
private final UiEventLogger mUiEventLogger;
private Region mActiveNavBarRegion;
@@ -508,6 +511,9 @@ public class OverviewProxyService extends CurrentUserTracker implements
mRecentTasks.ifPresent(recentTasks -> params.putBinder(
KEY_EXTRA_RECENT_TASKS,
recentTasks.createExternalInterface().asBinder()));
mBackAnimation.ifPresent((backAnimation) -> params.putBinder(
KEY_EXTRA_SHELL_BACK_ANIMATION,
backAnimation.createExternalInterface().asBinder()));
try {
mOverviewProxy.onInitialize(params);
@@ -566,6 +572,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
Optional<SplitScreen> splitScreenOptional,
Optional<OneHanded> oneHandedOptional,
Optional<RecentTasks> recentTasks,
Optional<BackAnimation> backAnimation,
Optional<StartingSurface> startingSurface,
BroadcastDispatcher broadcastDispatcher,
ShellTransitions shellTransitions,
@@ -593,6 +600,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
mOneHandedOptional = oneHandedOptional;
mShellTransitions = shellTransitions;
mRecentTasks = recentTasks;
mBackAnimation = backAnimation;
mUiEventLogger = uiEventLogger;
// Assumes device always starts with back button until launcher tells it that it does not