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
This commit is contained in:
Selim Cinek
2022-02-18 14:16:58 +01:00
parent d62c6e6c7d
commit ad59468664
6 changed files with 34 additions and 14 deletions

View File

@@ -299,7 +299,7 @@ interface IActivityTaskManager {
* a short predefined amount of time. * a short predefined amount of time.
*/ */
void registerRemoteAnimationForNextActivityStart(in String packageName, void registerRemoteAnimationForNextActivityStart(in String packageName,
in RemoteAnimationAdapter adapter); in RemoteAnimationAdapter adapter, in IBinder launchCookie);
/** /**
* Registers remote animations for a display. * Registers remote animations for a display.

View File

@@ -172,7 +172,7 @@ class ActivityLaunchAnimator(
if (packageName != null && animationAdapter != null) { if (packageName != null && animationAdapter != null) {
try { try {
ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart( ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(
packageName, animationAdapter) packageName, animationAdapter, null /* launchCookie */)
} catch (e: RemoteException) { } catch (e: RemoteException) {
Log.w(TAG, "Unable to register the remote animation", e) Log.w(TAG, "Unable to register the remote animation", e)
} }

View File

@@ -523,8 +523,8 @@ public class ActivityStartController {
} }
void registerRemoteAnimationForNextActivityStart(String packageName, void registerRemoteAnimationForNextActivityStart(String packageName,
RemoteAnimationAdapter adapter) { RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter); mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
} }
PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() { PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() {

View File

@@ -3714,7 +3714,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override @Override
public void registerRemoteAnimationForNextActivityStart(String packageName, public void registerRemoteAnimationForNextActivityStart(String packageName,
RemoteAnimationAdapter adapter) { RemoteAnimationAdapter adapter, IBinder launchCookie) {
mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
"registerRemoteAnimationForNextActivityStart"); "registerRemoteAnimationForNextActivityStart");
adapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid()); adapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
@@ -3722,7 +3722,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
getActivityStartController().registerRemoteAnimationForNextActivityStart( getActivityStartController().registerRemoteAnimationForNextActivityStart(
packageName, adapter); packageName, adapter, launchCookie);
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);
} }

View File

@@ -19,6 +19,7 @@ package com.android.server.wm;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.view.RemoteAnimationAdapter; 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. * Adds a remote animation to be run for all activity starts originating from a certain package.
*/ */
void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter) { void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter,
mEntries.put(packageName, new Entry(packageName, adapter)); @Nullable IBinder launchCookie) {
mEntries.put(packageName, new Entry(packageName, adapter, launchCookie));
} }
/** /**
@@ -62,6 +64,10 @@ class PendingRemoteAnimationRegistry {
} else { } else {
options.setRemoteAnimationAdapter(entry.adapter); options.setRemoteAnimationAdapter(entry.adapter);
} }
IBinder launchCookie = entry.launchCookie;
if (launchCookie != null) {
options.setLaunchCookie(launchCookie);
}
mEntries.remove(callingPackage); mEntries.remove(callingPackage);
return options; return options;
} }
@@ -69,10 +75,13 @@ class PendingRemoteAnimationRegistry {
private class Entry { private class Entry {
final String packageName; final String packageName;
final RemoteAnimationAdapter adapter; final RemoteAnimationAdapter adapter;
@Nullable
final IBinder launchCookie;
Entry(String packageName, RemoteAnimationAdapter adapter) { Entry(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
this.packageName = packageName; this.packageName = packageName;
this.adapter = adapter; this.adapter = adapter;
this.launchCookie = launchCookie;
mHandler.postDelayed(() -> { mHandler.postDelayed(() -> {
synchronized (mLock) { synchronized (mLock) {
final Entry entry = mEntries.get(packageName); final Entry entry = mEntries.get(packageName);

View File

@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationAdapter;
@@ -45,6 +46,7 @@ import org.mockito.MockitoAnnotations;
public class PendingRemoteAnimationRegistryTest { public class PendingRemoteAnimationRegistryTest {
@Mock RemoteAnimationAdapter mAdapter; @Mock RemoteAnimationAdapter mAdapter;
@Mock IBinder mLaunchCookie;
private PendingRemoteAnimationRegistry mRegistry; private PendingRemoteAnimationRegistry mRegistry;
private final OffsettableClock mClock = new OffsettableClock.Stopped(); private final OffsettableClock mClock = new OffsettableClock.Stopped();
private TestHandler mHandler; private TestHandler mHandler;
@@ -65,7 +67,7 @@ public class PendingRemoteAnimationRegistryTest {
@Test @Test
public void testOverrideActivityOptions() { public void testOverrideActivityOptions() {
mRegistry.addPendingAnimation("com.android.test", mAdapter); mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
ActivityOptions opts = ActivityOptions.makeBasic(); ActivityOptions opts = ActivityOptions.makeBasic();
opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts); opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts);
assertEquals(mAdapter, opts.getRemoteAnimationAdapter()); assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
@@ -73,15 +75,24 @@ public class PendingRemoteAnimationRegistryTest {
@Test @Test
public void testOverrideActivityOptions_null() { 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); final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);
assertNotNull(opts); assertNotNull(opts);
assertEquals(mAdapter, opts.getRemoteAnimationAdapter()); 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 @Test
public void testTimeout() { public void testTimeout() {
mRegistry.addPendingAnimation("com.android.test", mAdapter); mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
mClock.fastForward(5000); mClock.fastForward(5000);
mHandler.timeAdvance(); mHandler.timeAdvance();
assertNull(mRegistry.overrideOptionsIfNeeded("com.android.test", null)); assertNull(mRegistry.overrideOptionsIfNeeded("com.android.test", null));
@@ -89,10 +100,10 @@ public class PendingRemoteAnimationRegistryTest {
@Test @Test
public void testTimeout_overridenEntry() { public void testTimeout_overridenEntry() {
mRegistry.addPendingAnimation("com.android.test", mAdapter); mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
mClock.fastForward(2500); mClock.fastForward(2500);
mHandler.timeAdvance(); mHandler.timeAdvance();
mRegistry.addPendingAnimation("com.android.test", mAdapter); mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
mClock.fastForward(1000); mClock.fastForward(1000);
mHandler.timeAdvance(); mHandler.timeAdvance();
final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null); final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);