diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 8fbb2a90bb382..0dbc9155757ea 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1583,13 +1583,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A hasBeenLaunched = false; mStackSupervisor = supervisor; - // b/35954083: Limit task affinity to uid to avoid various issues associated with sharing - // affinity across uids. - final String uid = Integer.toString(info.applicationInfo.uid); - if (info.taskAffinity != null && !info.taskAffinity.startsWith(uid)) { - info.taskAffinity = uid + ":" + info.taskAffinity; - } + info.taskAffinity = getTaskAffinityWithUid(info.taskAffinity, info.applicationInfo.uid); taskAffinity = info.taskAffinity; + final String uid = Integer.toString(info.applicationInfo.uid); if (info.windowLayout != null && info.windowLayout.windowLayoutAffinity != null && !info.windowLayout.windowLayoutAffinity.startsWith(uid)) { info.windowLayout.windowLayoutAffinity = @@ -1647,6 +1643,22 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + /** + * Generate the task affinity with uid. For b/35954083, Limit task affinity to uid to avoid + * issues associated with sharing affinity across uids. + * + * @param affinity The affinity of the activity. + * @param uid The user-ID that has been assigned to this application. + * @return The task affinity with uid. + */ + static String getTaskAffinityWithUid(String affinity, int uid) { + final String uidStr = Integer.toString(uid); + if (affinity != null && !affinity.startsWith(uidStr)) { + affinity = uidStr + ":" + affinity; + } + return affinity; + } + static int getLockTaskLaunchMode(ActivityInfo aInfo, @Nullable ActivityOptions options) { int lockTaskLaunchMode = aInfo.lockTaskLaunchMode; if (aInfo.applicationInfo.isPrivilegedApp() diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index ed616fe3a33e6..2413386db268f 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -2376,8 +2376,10 @@ class ActivityStack extends Task { boolean shouldUpRecreateTaskLocked(ActivityRecord srec, String destAffinity) { // Basic case: for simple app-centric recents, we need to recreate // the task if the affinity has changed. + + final String affinity = ActivityRecord.getTaskAffinityWithUid(destAffinity, srec.getUid()); if (srec == null || srec.getTask().affinity == null - || !srec.getTask().affinity.equals(destAffinity)) { + || !srec.getTask().affinity.equals(affinity)) { return true; } // Document-centric case: an app may be split in to multiple documents; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java index 5227f3c885baf..822cb5a0c2d42 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java @@ -66,6 +66,7 @@ import android.app.ActivityManager; import android.app.IApplicationThread; import android.content.ComponentName; import android.content.pm.ActivityInfo; +import android.os.Binder; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; @@ -1290,6 +1291,27 @@ public class ActivityStackTests extends ActivityTestsBase { assertEquals(starter.mRequest.callingUid, secondActivity.getUid()); } + @Test + public void testShouldUpRecreateTaskLockedWithCorrectAffinityFormat() { + final String affinity = "affinity"; + final ActivityRecord activity = new ActivityBuilder(mService).setAffinity(affinity) + .setUid(Binder.getCallingUid()).setCreateTask(true).build(); + activity.getTask().affinity = activity.taskAffinity; + + assertFalse(mStack.shouldUpRecreateTaskLocked(activity, affinity)); + } + + @Test + public void testShouldUpRecreateTaskLockedWithWrongAffinityFormat() { + final String affinity = "affinity"; + final ActivityRecord activity = new ActivityBuilder(mService).setAffinity(affinity) + .setUid(Binder.getCallingUid()).setCreateTask(true).build(); + activity.getTask().affinity = activity.taskAffinity; + final String fakeAffinity = activity.getUid() + activity.taskAffinity; + + assertTrue(mStack.shouldUpRecreateTaskLocked(activity, fakeAffinity)); + } + @Test public void testResetTaskWithFinishingActivities() { final ActivityRecord taskTop = diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java index 2991859c5dd4f..466f1a9f7852b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java @@ -109,6 +109,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { private String mTargetActivity; private Task mTask; private String mProcessName = "name"; + private String mAffinity; private int mUid = 12345; private boolean mCreateTask; private ActivityStack mStack; @@ -223,6 +224,11 @@ class ActivityTestsBase extends SystemServiceTestsBase { return this; } + ActivityBuilder setAffinity(String affinity) { + mAffinity = affinity; + return this; + } + ActivityRecord build() { try { mService.deferWindowLayout(); @@ -271,6 +277,7 @@ class ActivityTestsBase extends SystemServiceTestsBase { aInfo.maxAspectRatio = mMaxAspectRatio; aInfo.screenOrientation = mScreenOrientation; aInfo.configChanges |= mConfigChanges; + aInfo.taskAffinity = mAffinity; ActivityOptions options = null; if (mLaunchTaskBehind) {