Merge "Implement back to launcher animation from shell and WM animation controllers." into tm-dev
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -52,14 +52,17 @@ import com.android.wm.shell.common.annotations.ShellMainThread;
|
||||
*/
|
||||
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 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
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 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
|
||||
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 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
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 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
||||
return;
|
||||
}
|
||||
RemoteAnimationTarget animationTarget = backNavigationInfo.getDepartingAnimationTarget();
|
||||
if (animationTarget != null && mTriggerBack) {
|
||||
if (animationTarget != null) {
|
||||
if (animationTarget.leash != null && animationTarget.leash.isValid()) {
|
||||
mTransaction.remove(animationTarget.leash);
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ public class BackAnimationControllerTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mController = new BackAnimationController(
|
||||
mShellExecutor, mTransaction, mActivityTaskManager, mContext);
|
||||
mController.setEnableAnimations(true);
|
||||
}
|
||||
|
||||
private void createNavigationInfo(RemoteAnimationTarget topAnimationTarget,
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.ComponentName;
|
||||
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 @@ import com.android.internal.protolog.common.ProtoLog;
|
||||
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 @@ class BackNavigationController {
|
||||
* 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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
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 @@ class BackNavigationController {
|
||||
|
||||
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 @@ class BackNavigationController {
|
||||
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) {
|
||||
|
||||
@@ -72,6 +72,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
|
||||
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 @@ class Task extends TaskFragment {
|
||||
|
||||
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 @@ class Task extends TaskFragment {
|
||||
}
|
||||
});
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,10 @@ import static org.mockito.Mockito.when;
|
||||
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 @@ import org.junit.runner.RunWith;
|
||||
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 @@ public class BackNavigationControllerTests extends WindowTestsBase {
|
||||
Task taskA = createTask(mDefaultDisplay);
|
||||
createActivityRecord(taskA);
|
||||
Task task = createTopTaskWithActivity();
|
||||
registerSystemOnBackInvokedCallback();
|
||||
|
||||
BackNavigationInfo backNavigationInfo =
|
||||
mBackNavigationController.startBackNavigation(task, new StubTransaction());
|
||||
assertThat(backNavigationInfo).isNotNull();
|
||||
@@ -75,6 +84,8 @@ public class BackNavigationControllerTests extends WindowTestsBase {
|
||||
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 class BackNavigationControllerTests extends WindowTestsBase {
|
||||
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 @@ public class BackNavigationControllerTests extends WindowTestsBase {
|
||||
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 @@ public class BackNavigationControllerTests extends WindowTestsBase {
|
||||
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() { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user