diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index fec78f0703115..81f1021c6eabe 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1825,6 +1825,12 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" }, + "35398067": { + "message": "goodToGo(): onAnimationStart, transit=%s, apps=%d, wallpapers=%d, nonApps=%d", + "level": "DEBUG", + "group": "WM_DEBUG_REMOTE_ANIMATIONS", + "at": "com\/android\/server\/wm\/RemoteAnimationController.java" + }, "38267433": { "message": "Attempted to reset replacing window on non-existing app token %s", "level": "WARN", diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 99289e0139b0b..394ae7e94b72d 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -1679,11 +1679,15 @@ public class AppTransition implements Dump { || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; } - static boolean isKeyguardTransitOld(@TransitionOldType int transit) { - return isKeyguardGoingAwayTransitOld(transit) || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE + static boolean isKeyguardOccludeTransitOld(@TransitionOldType int transit) { + return transit == TRANSIT_OLD_KEYGUARD_OCCLUDE || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE; } + static boolean isKeyguardTransitOld(@TransitionOldType int transit) { + return isKeyguardGoingAwayTransitOld(transit) || isKeyguardOccludeTransitOld(transit); + } + static boolean isTaskTransitOld(@TransitionOldType int transit) { return isTaskOpenTransitOld(transit) || transit == TRANSIT_OLD_TASK_CLOSE diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 9a43ca8794da1..e7c51a4ac65ad 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -68,7 +68,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACT import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Trace; import android.util.ArrayMap; @@ -428,43 +427,37 @@ public class AppTransitionController { return mainWindow != null ? mainWindow.mAttrs : null; } - RemoteAnimationAdapter getRemoteAnimationOverride(@NonNull WindowContainer container, + RemoteAnimationAdapter getRemoteAnimationOverride(@Nullable WindowContainer container, @TransitionOldType int transit, ArraySet activityTypes) { - final RemoteAnimationDefinition definition = container.getRemoteAnimationDefinition(); - if (definition != null) { - final RemoteAnimationAdapter adapter = definition.getAdapter(transit, activityTypes); - if (adapter != null) { - return adapter; + if (container != null) { + final RemoteAnimationDefinition definition = container.getRemoteAnimationDefinition(); + if (definition != null) { + final RemoteAnimationAdapter adapter = definition.getAdapter(transit, + activityTypes); + if (adapter != null) { + return adapter; + } } } - if (mRemoteAnimationDefinition != null) { - final RemoteAnimationAdapter adapter = mRemoteAnimationDefinition.getAdapter( - transit, activityTypes); - if (adapter != null) { - return adapter; - } - } - return null; + return mRemoteAnimationDefinition != null + ? mRemoteAnimationDefinition.getAdapter(transit, activityTypes) + : null; } /** * Overrides the pending transition with the remote animation defined for the transition in the * set of defined remote animations in the app window token. */ - private void overrideWithRemoteAnimationIfSet(ActivityRecord animLpActivity, + private void overrideWithRemoteAnimationIfSet(@Nullable ActivityRecord animLpActivity, @TransitionOldType int transit, ArraySet activityTypes) { if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) { // The crash transition has higher priority than any involved remote animations. return; } - if (animLpActivity == null) { - return; - } final RemoteAnimationAdapter adapter = getRemoteAnimationOverride(animLpActivity, transit, activityTypes); if (adapter != null) { - animLpActivity.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote( - adapter); + mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(adapter); } } diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index f851e3559def2..67bc7af6dc287 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -121,7 +121,10 @@ class RemoteAnimationController implements DeathRecipient { // Create the app targets final RemoteAnimationTarget[] appTargets = createAppAnimations(); - if (appTargets.length == 0) { + if (appTargets.length == 0 && !AppTransition.isKeyguardOccludeTransitOld(transit)) { + // Keyguard occlude transition can be executed before the occluding activity becomes + // visible. Even in this case, KeyguardService expects to receive binder call, so we + // don't cancel remote animation. ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate, mPendingAnimations=%d", mPendingAnimations.size()); @@ -133,12 +136,16 @@ class RemoteAnimationController implements DeathRecipient { // Create the remote wallpaper animation targets (if any) final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations(); - // TODO(bc-unlock): Create the remote non app animation targets (if any) + // Create the remote non app animation targets (if any) final RemoteAnimationTarget[] nonAppTargets = createNonAppWindowAnimations(transit); mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { try { linkToDeathOfRunner(); + ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): onAnimationStart," + + " transit=%s, apps=%d, wallpapers=%d, nonApps=%d", + AppTransition.appTransitionOldToString(transit), appTargets.length, + wallpaperTargets.length, nonAppTargets.length); mRemoteAnimationAdapter.getRunner().onAnimationStart(transit, appTargets, wallpaperTargets, nonAppTargets, mFinishedCallback); } catch (RemoteException e) { diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 678defe36566a..57cf865268efa 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -23,17 +23,27 @@ import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; import static android.view.WindowManager.TRANSIT_OPEN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doCallRealMethod; +import android.os.Binder; +import android.os.IBinder; +import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.util.ArraySet; +import android.view.IRemoteAnimationFinishedCallback; +import android.view.IRemoteAnimationRunner; +import android.view.RemoteAnimationAdapter; +import android.view.RemoteAnimationDefinition; +import android.view.RemoteAnimationTarget; import android.view.WindowManager; import androidx.test.filters.FlakyTest; @@ -426,4 +436,104 @@ public class AppTransitionControllerTest extends WindowTestsBase { AppTransitionController.getAnimationTargets( opening, closing, false /* visible */)); } -} + + static class TestRemoteAnimationRunner implements IRemoteAnimationRunner { + @Override + public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, + IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + } + + @Override + public void onAnimationCancelled() throws RemoteException { + } + + @Override + public IBinder asBinder() { + return new Binder(); + } + } + + @Test + public void testGetRemoteAnimationOverrideEmpty() { + final ActivityRecord activity = createActivityRecord(mDisplayContent); + assertNull(mAppTransitionController.getRemoteAnimationOverride(activity, + TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + } + + @Test + public void testGetRemoteAnimationOverrideWindowContainer() { + final ActivityRecord activity = createActivityRecord(mDisplayContent); + final RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter); + activity.registerRemoteAnimations(definition); + + assertEquals(adapter, + mAppTransitionController.getRemoteAnimationOverride( + activity, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + assertNull(mAppTransitionController.getRemoteAnimationOverride( + null, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + } + + @Test + public void testGetRemoteAnimationOverrideTransitionController() { + final ActivityRecord activity = createActivityRecord(mDisplayContent); + final RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter); + mAppTransitionController.registerRemoteAnimations(definition); + + assertEquals(adapter, + mAppTransitionController.getRemoteAnimationOverride( + activity, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + assertEquals(adapter, + mAppTransitionController.getRemoteAnimationOverride( + null, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + } + + @Test + public void testGetRemoteAnimationOverrideBoth() { + final ActivityRecord activity = createActivityRecord(mDisplayContent); + final RemoteAnimationDefinition definition1 = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter1 = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition1.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter1); + activity.registerRemoteAnimations(definition1); + + final RemoteAnimationDefinition definition2 = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter2 = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition2.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, adapter2); + mAppTransitionController.registerRemoteAnimations(definition2); + + assertEquals(adapter2, + mAppTransitionController.getRemoteAnimationOverride( + activity, TRANSIT_OLD_KEYGUARD_UNOCCLUDE, new ArraySet())); + assertEquals(adapter2, + mAppTransitionController.getRemoteAnimationOverride( + null, TRANSIT_OLD_KEYGUARD_UNOCCLUDE, new ArraySet())); + } + + @Test + public void testGetRemoteAnimationOverrideWindowContainerHasPriority() { + final ActivityRecord activity = createActivityRecord(mDisplayContent); + final RemoteAnimationDefinition definition1 = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter1 = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition1.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter1); + activity.registerRemoteAnimations(definition1); + + final RemoteAnimationDefinition definition2 = new RemoteAnimationDefinition(); + final RemoteAnimationAdapter adapter2 = new RemoteAnimationAdapter( + new TestRemoteAnimationRunner(), 10, 1); + definition2.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter2); + mAppTransitionController.registerRemoteAnimations(definition2); + + assertEquals(adapter1, + mAppTransitionController.getRemoteAnimationOverride( + activity, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet())); + } +} \ No newline at end of file