Merge "Implement back to launcher animation from shell and WM animation controllers." into tm-dev
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index df2b2a3..e898f57 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1309,6 +1309,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "-711194343": {
+ "message": "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"-706481945": {
"message": "TaskFragment parent info changed name=%s parentTaskId=%d",
"level": "VERBOSE",
@@ -2587,6 +2593,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "599897753": {
+ "message": "Previous Activity is %s. Back type is %s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"600140673": {
"message": "checkBootAnimationComplete: Waiting for anim complete",
"level": "INFO",
@@ -2671,12 +2683,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "664667685": {
- "message": "Activity %s: enableOnBackInvokedCallback=false. Returning null BackNavigationInfo.",
- "level": "DEBUG",
- "group": "WM_DEBUG_BACK_PREVIEW",
- "at": "com\/android\/server\/wm\/BackNavigationController.java"
- },
"665256544": {
"message": "All windows drawn!",
"level": "DEBUG",
@@ -2887,6 +2893,12 @@
"group": "WM_DEBUG_STATES",
"at": "com\/android\/server\/wm\/TaskFragment.java"
},
+ "948208142": {
+ "message": "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"950074526": {
"message": "setLockTaskMode: Can't lock due to auth",
"level": "WARN",
@@ -3103,6 +3115,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "1172542963": {
+ "message": "onBackNavigationDone backType=%s, task=%s, prevTaskTopActivity=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"1178653181": {
"message": "Old wallpaper still the target.",
"level": "VERBOSE",
@@ -3415,11 +3433,11 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "1554795024": {
- "message": "Previous Activity is %s",
+ "1544805551": {
+ "message": "Skipping app transition animation. task=%s",
"level": "DEBUG",
"group": "WM_DEBUG_BACK_PREVIEW",
- "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ "at": "com\/android\/server\/wm\/Task.java"
},
"1557732761": {
"message": "For Intent %s bringing to top: %s",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index e50ad38..08cb252 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -52,14 +52,17 @@
*/
public class BackAnimationController implements RemoteCallable<BackAnimationController> {
- private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
- public static final boolean IS_ENABLED = SystemProperties
- .getInt(BACK_PREDICTABILITY_PROP, 1) > 0;
private static final String BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP =
"persist.debug.back_predictability_progress_threshold";
+ // By default, enable new back dispatching without any animations.
+ private static final int BACK_PREDICTABILITY_PROP =
+ SystemProperties.getInt("persist.debug.back_predictability", 1);
+ public static final boolean IS_ENABLED = BACK_PREDICTABILITY_PROP > 0;
private static final int PROGRESS_THRESHOLD = SystemProperties
.getInt(BACK_PREDICTABILITY_PROGRESS_THRESHOLD_PROP, -1);
private static final String TAG = "BackAnimationController";
+ @VisibleForTesting
+ boolean mEnableAnimations = (BACK_PREDICTABILITY_PROP & (1 << 1)) != 0;
/**
* Location of the initial touch event of the back gesture.
@@ -255,7 +258,7 @@
backNavigationInfo.getTaskWindowConfiguration());
}
mTransaction.apply();
- } else if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME) {
+ } else if (shouldDispatchToLauncher(backType)) {
targetCallback = mBackToLauncherCallback;
} else if (backType == BackNavigationInfo.TYPE_CALLBACK) {
targetCallback = mBackNavigationInfo.getOnBackInvokedCallback();
@@ -309,7 +312,7 @@
BackEvent backEvent = new BackEvent(0, 0, progress, swipeEdge, animationTarget);
IOnBackInvokedCallback targetCallback = null;
- if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME) {
+ if (shouldDispatchToLauncher(backType)) {
targetCallback = mBackToLauncherCallback;
} else if (backType == BackNavigationInfo.TYPE_CROSS_TASK
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) {
@@ -330,8 +333,7 @@
return;
}
int backType = mBackNavigationInfo.getType();
- boolean shouldDispatchToLauncher = backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
- && mBackToLauncherCallback != null;
+ boolean shouldDispatchToLauncher = shouldDispatchToLauncher(backType);
IOnBackInvokedCallback targetCallback = shouldDispatchToLauncher
? mBackToLauncherCallback
: mBackNavigationInfo.getOnBackInvokedCallback();
@@ -356,6 +358,17 @@
}
}
+ private boolean shouldDispatchToLauncher(int backType) {
+ return backType == BackNavigationInfo.TYPE_RETURN_TO_HOME
+ && mBackToLauncherCallback != null
+ && mEnableAnimations;
+ }
+
+ @VisibleForTesting
+ void setEnableAnimations(boolean shouldEnable) {
+ mEnableAnimations = shouldEnable;
+ }
+
private static void dispatchOnBackStarted(IOnBackInvokedCallback callback) {
if (callback == null) {
return;
@@ -468,7 +481,7 @@
return;
}
RemoteAnimationTarget animationTarget = backNavigationInfo.getDepartingAnimationTarget();
- if (animationTarget != null && mTriggerBack) {
+ if (animationTarget != null) {
if (animationTarget.leash != null && animationTarget.leash.isValid()) {
mTransaction.remove(animationTarget.leash);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 9054685..3e7ee25 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -78,6 +78,7 @@
MockitoAnnotations.initMocks(this);
mController = new BackAnimationController(
mShellExecutor, mTransaction, mActivityTaskManager, mContext);
+ mController.setEnableAnimations(true);
}
private void createNavigationInfo(RemoteAnimationTarget topAnimationTarget,
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 487aff6..dbc0141 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -25,6 +25,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
+import android.os.Bundle;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -44,7 +45,11 @@
class BackNavigationController {
private static final String TAG = "BackNavigationController";
- private static final String BACK_PREDICTABILITY_PROP = "persist.debug.back_predictability";
+ // By default, enable new back dispatching without any animations.
+ private static final int BACK_PREDICTABILITY_PROP =
+ SystemProperties.getInt("persist.debug.back_predictability", 1);
+ private static final int ANIMATIONS_MASK = 1 << 1;
+ private static final int SCREENSHOT_MASK = 1 << 2;
@Nullable
private TaskSnapshotController mTaskSnapshotController;
@@ -53,11 +58,15 @@
* Returns true if the back predictability feature is enabled
*/
static boolean isEnabled() {
- return SystemProperties.getInt(BACK_PREDICTABILITY_PROP, 1) > 0;
+ return BACK_PREDICTABILITY_PROP > 0;
}
static boolean isScreenshotEnabled() {
- return false;
+ return (BACK_PREDICTABILITY_PROP & SCREENSHOT_MASK) != 0;
+ }
+
+ private static boolean isAnimationEnabled() {
+ return (BACK_PREDICTABILITY_PROP & ANIMATIONS_MASK) != 0;
}
/**
@@ -93,14 +102,17 @@
ActivityRecord prev;
WindowContainer<?> removedWindowContainer;
ActivityRecord activityRecord;
+ ActivityRecord prevTaskTopActivity = null;
SurfaceControl animationLeashParent;
WindowConfiguration taskWindowConfiguration;
HardwareBuffer screenshotBuffer = null;
+ SurfaceControl screenshotSurface;
int prevTaskId;
int prevUserId;
RemoteAnimationTarget topAppTarget;
SurfaceControl animLeash;
- IOnBackInvokedCallback callback = null;
+ IOnBackInvokedCallback applicationCallback = null;
+ IOnBackInvokedCallback systemCallback = null;
synchronized (task.mWmService.mGlobalLock) {
@@ -116,15 +128,14 @@
removedWindowContainer = activityRecord;
taskWindowConfiguration = window.getWindowConfiguration();
}
- IOnBackInvokedCallback applicationCallback = null;
- IOnBackInvokedCallback systemCallback = null;
if (window != null) {
applicationCallback = window.getApplicationOnBackInvokedCallback();
- callback = applicationCallback;
- if (callback == null) {
- systemCallback = window.getSystemOnBackInvokedCallback();
- callback = systemCallback;
- }
+ systemCallback = window.getSystemOnBackInvokedCallback();
+ }
+ if (applicationCallback == null && systemCallback == null) {
+ // Return null when either there's no window, or apps have just initialized and
+ // have not finished registering callbacks.
+ return null;
}
ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation task=%s, "
@@ -133,24 +144,24 @@
task, activityRecord, applicationCallback, systemCallback);
// TODO Temp workaround for Sysui until b/221071505 is fixed
- if (activityRecord == null && callback != null) {
+ if (activityRecord == null && applicationCallback != null) {
return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
null /* topWindowLeash */, null /* screenshotSurface */,
null /* screenshotBuffer */, null /* taskWindowConfiguration */,
null /* onBackNavigationDone */,
- callback /* onBackInvokedCallback */);
+ applicationCallback /* onBackInvokedCallback */);
}
// For IME and Home, either a callback is registered, or we do nothing. In both cases,
// we don't need to pass the leashes below.
if (activityRecord == null || task.getDisplayContent().getImeContainer().isVisible()
|| activityRecord.isActivityTypeHome()) {
- if (callback != null) {
+ if (applicationCallback != null) {
return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
null /* topWindowLeash */, null /* screenshotSurface */,
null /* screenshotBuffer */, null /* taskWindowConfiguration */,
null /* onBackNavigationDone */,
- callback /* onBackInvokedCallback */);
+ applicationCallback /* onBackInvokedCallback */);
} else {
return null;
}
@@ -159,12 +170,12 @@
prev = task.getActivity(
(r) -> !r.finishing && r.getTask() == task && !r.isTopRunningActivity());
- if (callback != null) {
+ if (applicationCallback != null) {
return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
null /* topWindowLeash */, null /* screenshotSurface */,
null /* screenshotBuffer */, null /* taskWindowConfiguration */,
null /* onBackNavigationDone */,
- callback /* onBackInvokedCallback */);
+ applicationCallback /* onBackInvokedCallback */);
} else if (prev != null) {
backType = BackNavigationInfo.TYPE_CROSS_ACTIVITY;
} else if (task.returnsToHomeRootTask()) {
@@ -188,8 +199,8 @@
prevTaskId = prevTask != null ? prevTask.mTaskId : 0;
prevUserId = prevTask != null ? prevTask.mUserId : 0;
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Previous Activity is %s",
- prev != null ? prev.mActivityComponent : null);
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Previous Activity is %s. "
+ + "Back type is %s", prev != null ? prev.mActivityComponent : null, backType);
//TODO(207481538) Remove once the infrastructure to support per-activity screenshot is
// implemented. For now we simply have the mBackScreenshots hash map that dumbly
@@ -204,6 +215,7 @@
return null;
}
// Prepare a leash to animate the current top window
+ // TODO(b/220934562): Use surface animator to better manage animation conflicts.
animLeash = removedWindowContainer.makeAnimationLeash()
.setName("BackPreview Leash for " + removedWindowContainer)
.setHidden(false)
@@ -231,12 +243,30 @@
activityRecord.windowType);
}
- SurfaceControl.Builder builder = new SurfaceControl.Builder()
+ screenshotSurface = new SurfaceControl.Builder()
.setName("BackPreview Screenshot for " + prev)
.setParent(animationLeashParent)
.setHidden(false)
- .setBLASTLayer();
- SurfaceControl screenshotSurface = builder.build();
+ .setBLASTLayer()
+ .build();
+ if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && isAnimationEnabled()) {
+ task.mBackGestureStarted = true;
+ // Make launcher show from behind by marking its top activity as visible and
+ // launch-behind to bump its visibility for the duration of the back gesture.
+ prevTaskTopActivity = prevTask.getTopNonFinishingActivity();
+ if (prevTaskTopActivity != null) {
+ if (!prevTaskTopActivity.mVisibleRequested) {
+ prevTaskTopActivity.setVisibility(true);
+ }
+ prevTaskTopActivity.mLaunchTaskBehind = true;
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+ "Setting Activity.mLauncherTaskBehind to true. Activity=%s",
+ prevTaskTopActivity);
+ prevTaskTopActivity.mRootWindowContainer.ensureActivitiesVisible(
+ null /* starting */, 0 /* configChanges */,
+ false /* preserveWindows */);
+ }
+ }
// Find a screenshot of the previous activity
@@ -253,17 +283,20 @@
WindowContainer<?> finalRemovedWindowContainer = removedWindowContainer;
try {
- activityRecord.token.linkToDeath(
- () -> resetSurfaces(finalRemovedWindowContainer), 0);
+ activityRecord.token.linkToDeath(() -> resetSurfaces(finalRemovedWindowContainer), 0);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to link to death", e);
resetSurfaces(removedWindowContainer);
return null;
}
- RemoteCallback onBackNavigationDone = new RemoteCallback(
- result -> resetSurfaces(finalRemovedWindowContainer
- ));
+ int finalBackType = backType;
+ final IOnBackInvokedCallback callback =
+ applicationCallback != null ? applicationCallback : systemCallback;
+ ActivityRecord finalPrevTaskTopActivity = prevTaskTopActivity;
+ RemoteCallback onBackNavigationDone = new RemoteCallback(result -> onBackNavigationDone(
+ result, finalRemovedWindowContainer, finalBackType, task,
+ finalPrevTaskTopActivity));
return new BackNavigationInfo(backType,
topAppTarget,
screenshotSurface,
@@ -273,6 +306,39 @@
callback);
}
+ private void onBackNavigationDone(
+ Bundle result, WindowContainer windowContainer, int backType,
+ Task task, ActivityRecord prevTaskTopActivity) {
+ SurfaceControl surfaceControl = windowContainer.getSurfaceControl();
+ boolean triggerBack = result != null
+ ? result.getBoolean(BackNavigationInfo.KEY_TRIGGER_BACK)
+ : false;
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "onBackNavigationDone backType=%s, "
+ + "task=%s, prevTaskTopActivity=%s", backType, task, prevTaskTopActivity);
+
+ if (backType == BackNavigationInfo.TYPE_RETURN_TO_HOME && isAnimationEnabled()) {
+ if (triggerBack) {
+ if (surfaceControl != null && surfaceControl.isValid()) {
+ // When going back to home, hide the task surface before it is re-parented to
+ // avoid flicker.
+ SurfaceControl.Transaction t = windowContainer.getSyncTransaction();
+ t.hide(surfaceControl);
+ t.apply();
+ }
+ }
+ if (prevTaskTopActivity != null && !triggerBack) {
+ // Restore the launch-behind state.
+ task.mTaskSupervisor.scheduleLaunchTaskBehindComplete(prevTaskTopActivity.token);
+ prevTaskTopActivity.mLaunchTaskBehind = false;
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+ "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+ prevTaskTopActivity);
+ }
+ } else {
+ task.mBackGestureStarted = false;
+ }
+ resetSurfaces(windowContainer);
+ }
private HardwareBuffer getActivitySnapshot(@NonNull Task task,
ComponentName activityComponent) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index cd7ebe3..dd4dd5f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -72,6 +72,7 @@
import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP;
import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BACK_PREVIEW;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES;
@@ -609,6 +610,12 @@
boolean mLastSurfaceShowing = true;
+ /**
+ * Tracks if a back gesture is in progress.
+ * Skips any system transition animations if this is set to {@code true}.
+ */
+ boolean mBackGestureStarted = false;
+
private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
@@ -3322,6 +3329,14 @@
}
});
}
+ } else if (mBackGestureStarted) {
+ // Cancel playing transitions if a back navigation animation is in progress.
+ // This bit is set by {@link BackNavigationController} when a back gesture is started.
+ // It is used as a one-off transition overwrite that is cleared when the back gesture
+ // is committed and triggers a transition, or when the gesture is cancelled.
+ mBackGestureStarted = false;
+ mDisplayContent.mSkipAppTransitionAnimation = true;
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Skipping app transition animation. task=%s", this);
} else {
super.applyAnimationUnchecked(lp, enter, transit, isVoiceInteraction, sources);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index c21a5b6..92550a3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -30,7 +30,10 @@
import android.annotation.NonNull;
import android.hardware.HardwareBuffer;
import android.platform.test.annotations.Presubmit;
+import android.window.BackEvent;
import android.window.BackNavigationInfo;
+import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import android.window.TaskSnapshot;
import org.junit.Before;
@@ -42,15 +45,19 @@
public class BackNavigationControllerTests extends WindowTestsBase {
private BackNavigationController mBackNavigationController;
+ private IOnBackInvokedCallback mOnBackInvokedCallback;
@Before
public void setUp() throws Exception {
mBackNavigationController = new BackNavigationController();
+ mOnBackInvokedCallback = createBackCallback();
}
@Test
public void backTypeHomeWhenBackToLauncher() {
Task task = createTopTaskWithActivity();
+ registerSystemOnBackInvokedCallback();
+
BackNavigationInfo backNavigationInfo =
mBackNavigationController.startBackNavigation(task, new StubTransaction());
assertThat(backNavigationInfo).isNotNull();
@@ -63,6 +70,8 @@
Task taskA = createTask(mDefaultDisplay);
createActivityRecord(taskA);
Task task = createTopTaskWithActivity();
+ registerSystemOnBackInvokedCallback();
+
BackNavigationInfo backNavigationInfo =
mBackNavigationController.startBackNavigation(task, new StubTransaction());
assertThat(backNavigationInfo).isNotNull();
@@ -75,6 +84,8 @@
Task task = createTopTaskWithActivity();
mAtm.setFocusedTask(task.mTaskId,
createAppWindow(task, FIRST_APPLICATION_WINDOW, "window").mActivityRecord);
+ registerSystemOnBackInvokedCallback();
+
BackNavigationInfo backNavigationInfo =
mBackNavigationController.startBackNavigation(task, new StubTransaction());
assertThat(backNavigationInfo).isNotNull();
@@ -89,6 +100,7 @@
public void backNavInfoFullyPopulated() {
Task task = createTopTaskWithActivity();
createAppWindow(task, FIRST_APPLICATION_WINDOW, "window");
+ registerSystemOnBackInvokedCallback();
// We need a mock screenshot so
TaskSnapshotController taskSnapshotController = createMockTaskSnapshotController();
@@ -104,6 +116,30 @@
assertThat(backNavigationInfo.getTaskWindowConfiguration()).isNotNull();
}
+ @Test
+ public void preparesForBackToHome() {
+ Task task = createTopTaskWithActivity();
+ ActivityRecord activity = task.getTopActivity(false, false);
+ registerSystemOnBackInvokedCallback();
+
+ BackNavigationInfo backNavigationInfo =
+ mBackNavigationController.startBackNavigation(task, new StubTransaction());
+ assertThat(typeToString(backNavigationInfo.getType()))
+ .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));
+ }
+
+ @Test
+ public void backTypeCallback() {
+ Task task = createTopTaskWithActivity();
+ ActivityRecord activity = task.getTopActivity(false, false);
+ registerApplicationOnBackInvokedCallback();
+
+ BackNavigationInfo backNavigationInfo =
+ mBackNavigationController.startBackNavigation(task, new StubTransaction());
+ assertThat(typeToString(backNavigationInfo.getType()))
+ .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));
+ }
+
@NonNull
private TaskSnapshotController createMockTaskSnapshotController() {
TaskSnapshotController taskSnapshotController = mock(TaskSnapshotController.class);
@@ -126,4 +162,30 @@
mAtm.setFocusedTask(task.mTaskId, record);
return task;
}
+
+ private void registerSystemOnBackInvokedCallback() {
+ mWm.getFocusedWindowLocked().setOnBackInvokedCallback(
+ mOnBackInvokedCallback, OnBackInvokedDispatcher.PRIORITY_SYSTEM);
+ }
+
+ private void registerApplicationOnBackInvokedCallback() {
+ mWm.getFocusedWindowLocked().setOnBackInvokedCallback(
+ mOnBackInvokedCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT);
+ }
+
+ private IOnBackInvokedCallback createBackCallback() {
+ return new IOnBackInvokedCallback.Stub() {
+ @Override
+ public void onBackStarted() { }
+
+ @Override
+ public void onBackProgressed(BackEvent backEvent) { }
+
+ @Override
+ public void onBackCancelled() { }
+
+ @Override
+ public void onBackInvoked() { }
+ };
+ }
}