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

Commit b615394f authored by Issei Suzuki's avatar Issei Suzuki
Browse files

Let keyguard (un)occlude animation run even when no activity exists.

Keyguard (un)occlude transition can be executed even before the
occluding app becomes ready. Normally we skip to run remote animation
for such cases since nothing to animate, however, KeyguardService uses
IRemoteAnimationRunner#onAnimationStart as a signal to update its
internal state, so WindowManager has to trigger the binder call.

Bug: 175687166
Bug: 182975035
Test: atest AppTransitionControllerTest
Change-Id: I190f2cf750f849b8aafdb43642cb03e5382f50d5
parent 02841faa
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -1825,6 +1825,12 @@
      "group": "WM_DEBUG_IME",
      "group": "WM_DEBUG_IME",
      "at": "com\/android\/server\/wm\/InsetsSourceProvider.java"
      "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": {
    "38267433": {
      "message": "Attempted to reset replacing window on non-existing app token %s",
      "message": "Attempted to reset replacing window on non-existing app token %s",
      "level": "WARN",
      "level": "WARN",
+6 −2
Original line number Original line Diff line number Diff line
@@ -1679,11 +1679,15 @@ public class AppTransition implements Dump {
                || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
                || transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
    }
    }


    static boolean isKeyguardTransitOld(@TransitionOldType int transit) {
    static boolean isKeyguardOccludeTransitOld(@TransitionOldType int transit) {
        return isKeyguardGoingAwayTransitOld(transit) || transit == TRANSIT_OLD_KEYGUARD_OCCLUDE
        return transit == TRANSIT_OLD_KEYGUARD_OCCLUDE
                || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
                || transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
    }
    }


    static boolean isKeyguardTransitOld(@TransitionOldType int transit) {
        return isKeyguardGoingAwayTransitOld(transit) || isKeyguardOccludeTransitOld(transit);
    }

    static boolean isTaskTransitOld(@TransitionOldType int transit) {
    static boolean isTaskTransitOld(@TransitionOldType int transit) {
        return isTaskOpenTransitOld(transit)
        return isTaskOpenTransitOld(transit)
                || transit == TRANSIT_OLD_TASK_CLOSE
                || transit == TRANSIT_OLD_TASK_CLOSE
+14 −21
Original line number Original line Diff line number Diff line
@@ -69,7 +69,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_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;


import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.os.Trace;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -429,43 +428,37 @@ public class AppTransitionController {
        return mainWindow != null ? mainWindow.mAttrs : null;
        return mainWindow != null ? mainWindow.mAttrs : null;
    }
    }


    RemoteAnimationAdapter getRemoteAnimationOverride(@NonNull WindowContainer container,
    RemoteAnimationAdapter getRemoteAnimationOverride(@Nullable WindowContainer container,
            @TransitionOldType int transit, ArraySet<Integer> activityTypes) {
            @TransitionOldType int transit, ArraySet<Integer> activityTypes) {
        if (container != null) {
            final RemoteAnimationDefinition definition = container.getRemoteAnimationDefinition();
            final RemoteAnimationDefinition definition = container.getRemoteAnimationDefinition();
            if (definition != null) {
            if (definition != null) {
            final RemoteAnimationAdapter adapter = definition.getAdapter(transit, activityTypes);
                final RemoteAnimationAdapter adapter = definition.getAdapter(transit,
                        activityTypes);
                if (adapter != null) {
                if (adapter != null) {
                    return adapter;
                    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
     * Overrides the pending transition with the remote animation defined for the transition in the
     * set of defined remote animations in the app window token.
     * 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<Integer> activityTypes) {
            @TransitionOldType int transit, ArraySet<Integer> activityTypes) {
        if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) {
        if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) {
            // The crash transition has higher priority than any involved remote animations.
            // The crash transition has higher priority than any involved remote animations.
            return;
            return;
        }
        }
        if (animLpActivity == null) {
            return;
        }
        final RemoteAnimationAdapter adapter =
        final RemoteAnimationAdapter adapter =
                getRemoteAnimationOverride(animLpActivity, transit, activityTypes);
                getRemoteAnimationOverride(animLpActivity, transit, activityTypes);
        if (adapter != null) {
        if (adapter != null) {
            animLpActivity.getDisplayContent().mAppTransition.overridePendingAppTransitionRemote(
            mDisplayContent.mAppTransition.overridePendingAppTransitionRemote(adapter);
                    adapter);
        }
        }
    }
    }


+9 −2
Original line number Original line Diff line number Diff line
@@ -121,7 +121,10 @@ class RemoteAnimationController implements DeathRecipient {


        // Create the app targets
        // Create the app targets
        final RemoteAnimationTarget[] appTargets = createAppAnimations();
        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,
            ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
                    "goodToGo(): No apps to animate, mPendingAnimations=%d",
                    "goodToGo(): No apps to animate, mPendingAnimations=%d",
                    mPendingAnimations.size());
                    mPendingAnimations.size());
@@ -133,12 +136,16 @@ class RemoteAnimationController implements DeathRecipient {
        // Create the remote wallpaper animation targets (if any)
        // Create the remote wallpaper animation targets (if any)
        final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations();
        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);
        final RemoteAnimationTarget[] nonAppTargets = createNonAppWindowAnimations(transit);


        mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
        mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
            try {
            try {
                linkToDeathOfRunner();
                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,
                mRemoteAnimationAdapter.getRunner().onAnimationStart(transit, appTargets,
                        wallpaperTargets, nonAppTargets, mFinishedCallback);
                        wallpaperTargets, nonAppTargets, mFinishedCallback);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
+111 −1
Original line number Original line Diff line number Diff line
@@ -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_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
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_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_OPEN;


import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doCallRealMethod;
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.platform.test.annotations.Presubmit;
import android.util.ArraySet;
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 android.view.WindowManager;


import androidx.test.filters.FlakyTest;
import androidx.test.filters.FlakyTest;
@@ -426,4 +436,104 @@ public class AppTransitionControllerTest extends WindowTestsBase {
                AppTransitionController.getAnimationTargets(
                AppTransitionController.getAnimationTargets(
                        opening, closing, false /* visible */));
                        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<Integer>()));
    }

    @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<Integer>()));
        assertNull(mAppTransitionController.getRemoteAnimationOverride(
                        null, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet<Integer>()));
    }

    @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<Integer>()));
        assertEquals(adapter,
                mAppTransitionController.getRemoteAnimationOverride(
                        null, TRANSIT_OLD_ACTIVITY_OPEN, new ArraySet<Integer>()));
    }

    @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<Integer>()));
        assertEquals(adapter2,
                mAppTransitionController.getRemoteAnimationOverride(
                        null, TRANSIT_OLD_KEYGUARD_UNOCCLUDE, new ArraySet<Integer>()));
    }

    @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<Integer>()));
    }
}
}
 No newline at end of file