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.
*/
void registerRemoteAnimationForNextActivityStart(in String packageName,
in RemoteAnimationAdapter adapter);
in RemoteAnimationAdapter adapter, in IBinder launchCookie);
/**
* Registers remote animations for a display.

View File

@@ -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)
}

View File

@@ -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() {

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);