From ad594686642d5d62e0aa0501bb5993b22482a417 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Fri, 18 Feb 2022 14:16:58 +0100 Subject: [PATCH] Allowing launch cookies to be passed via pending activity starts When overriding pending activity starts using remote animations, we're now also allowing the passage of a launch cookie to associate the task with the launched app. This allows us to return to the right widgets for certain apps using broadcast trampolines. Fixes: 220290671 Test: add Photos widget, return properly to widget Change-Id: I339ea827836fa53ab5bb1617a72f9e0e5ae0f5ec --- .../android/app/IActivityTaskManager.aidl | 2 +- .../animation/ActivityLaunchAnimator.kt | 2 +- .../server/wm/ActivityStartController.java | 4 ++-- .../server/wm/ActivityTaskManagerService.java | 4 ++-- .../wm/PendingRemoteAnimationRegistry.java | 15 ++++++++++--- .../PendingRemoteAnimationRegistryTest.java | 21 ++++++++++++++----- 6 files changed, 34 insertions(+), 14 deletions(-) diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index 490afc13ee975..ef9a2f2733485 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -299,7 +299,7 @@ interface IActivityTaskManager { * a short predefined amount of time. */ void registerRemoteAnimationForNextActivityStart(in String packageName, - in RemoteAnimationAdapter adapter); + in RemoteAnimationAdapter adapter, in IBinder launchCookie); /** * Registers remote animations for a display. diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index c3f6a5d18b74d..749d3dbd4695e 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -172,7 +172,7 @@ class ActivityLaunchAnimator( if (packageName != null && animationAdapter != null) { try { ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart( - packageName, animationAdapter) + packageName, animationAdapter, null /* launchCookie */) } catch (e: RemoteException) { Log.w(TAG, "Unable to register the remote animation", e) } diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index 2a26050a24db9..c9b8501816690 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -523,8 +523,8 @@ public class ActivityStartController { } void registerRemoteAnimationForNextActivityStart(String packageName, - RemoteAnimationAdapter adapter) { - mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter); + RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) { + mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie); } PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 049747728ade7..2e05e6b499083 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3714,7 +3714,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void registerRemoteAnimationForNextActivityStart(String packageName, - RemoteAnimationAdapter adapter) { + RemoteAnimationAdapter adapter, IBinder launchCookie) { mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, "registerRemoteAnimationForNextActivityStart"); adapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid()); @@ -3722,7 +3722,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final long origId = Binder.clearCallingIdentity(); try { getActivityStartController().registerRemoteAnimationForNextActivityStart( - packageName, adapter); + packageName, adapter, launchCookie); } finally { Binder.restoreCallingIdentity(origId); } diff --git a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java index 3b8631ab3a8e4..073bbbb8edf88 100644 --- a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java +++ b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java @@ -19,6 +19,7 @@ package com.android.server.wm; import android.annotation.Nullable; import android.app.ActivityOptions; import android.os.Handler; +import android.os.IBinder; import android.util.ArrayMap; import android.view.RemoteAnimationAdapter; @@ -43,8 +44,9 @@ class PendingRemoteAnimationRegistry { /** * Adds a remote animation to be run for all activity starts originating from a certain package. */ - void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter) { - mEntries.put(packageName, new Entry(packageName, adapter)); + void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter, + @Nullable IBinder launchCookie) { + mEntries.put(packageName, new Entry(packageName, adapter, launchCookie)); } /** @@ -62,6 +64,10 @@ class PendingRemoteAnimationRegistry { } else { options.setRemoteAnimationAdapter(entry.adapter); } + IBinder launchCookie = entry.launchCookie; + if (launchCookie != null) { + options.setLaunchCookie(launchCookie); + } mEntries.remove(callingPackage); return options; } @@ -69,10 +75,13 @@ class PendingRemoteAnimationRegistry { private class Entry { final String packageName; final RemoteAnimationAdapter adapter; + @Nullable + final IBinder launchCookie; - Entry(String packageName, RemoteAnimationAdapter adapter) { + Entry(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) { this.packageName = packageName; this.adapter = adapter; + this.launchCookie = launchCookie; mHandler.postDelayed(() -> { synchronized (mLock) { final Entry entry = mEntries.get(packageName); diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java index f0071499a2f9c..972567b10da77 100644 --- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import android.app.ActivityOptions; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.view.RemoteAnimationAdapter; @@ -45,6 +46,7 @@ import org.mockito.MockitoAnnotations; public class PendingRemoteAnimationRegistryTest { @Mock RemoteAnimationAdapter mAdapter; + @Mock IBinder mLaunchCookie; private PendingRemoteAnimationRegistry mRegistry; private final OffsettableClock mClock = new OffsettableClock.Stopped(); private TestHandler mHandler; @@ -65,7 +67,7 @@ public class PendingRemoteAnimationRegistryTest { @Test public void testOverrideActivityOptions() { - mRegistry.addPendingAnimation("com.android.test", mAdapter); + mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */); ActivityOptions opts = ActivityOptions.makeBasic(); opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts); assertEquals(mAdapter, opts.getRemoteAnimationAdapter()); @@ -73,15 +75,24 @@ public class PendingRemoteAnimationRegistryTest { @Test public void testOverrideActivityOptions_null() { - mRegistry.addPendingAnimation("com.android.test", mAdapter); + mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */); final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null); assertNotNull(opts); assertEquals(mAdapter, opts.getRemoteAnimationAdapter()); } + @Test + public void testOverrideLaunchCookie() { + mRegistry.addPendingAnimation("com.android.test", mAdapter, mLaunchCookie); + ActivityOptions opts = ActivityOptions.makeBasic(); + opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts); + assertNotNull(opts); + assertEquals(mLaunchCookie, opts.getLaunchCookie()); + } + @Test public void testTimeout() { - mRegistry.addPendingAnimation("com.android.test", mAdapter); + mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */); mClock.fastForward(5000); mHandler.timeAdvance(); assertNull(mRegistry.overrideOptionsIfNeeded("com.android.test", null)); @@ -89,10 +100,10 @@ public class PendingRemoteAnimationRegistryTest { @Test public void testTimeout_overridenEntry() { - mRegistry.addPendingAnimation("com.android.test", mAdapter); + mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */); mClock.fastForward(2500); mHandler.timeAdvance(); - mRegistry.addPendingAnimation("com.android.test", mAdapter); + mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */); mClock.fastForward(1000); mHandler.timeAdvance(); final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);