summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java15
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java1
5 files changed, 58 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c6cae530e795..f045274e43f7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4759,7 +4759,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@GuardedBy("this")
- private final boolean attachApplicationLocked(IApplicationThread thread,
+ private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// Find the application record that is being attached... either via
@@ -5173,6 +5173,9 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
+ if (thread == null) {
+ throw new SecurityException("Invalid application interface");
+ }
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6bed46226b42..764b92929de0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4241,6 +4241,11 @@ class ActivityStack extends ConfigurationContainer {
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
Intent resultData) {
+ if (!srec.attachedToProcess()) {
+ // Nothing to do if the caller is not attached, because this method should be called
+ // from an alive activity.
+ return false;
+ }
final TaskRecord task = srec.getTaskRecord();
final ArrayList<ActivityRecord> activities = task.mActivities;
final int start = activities.indexOf(srec);
@@ -4294,14 +4299,14 @@ class ActivityStack extends ConfigurationContainer {
}
if (parent != null && foundParentInTask) {
+ final int callingUid = srec.info.applicationInfo.uid;
final int parentLaunchMode = parent.info.launchMode;
final int destIntentFlags = destIntent.getFlags();
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
- parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
- srec.packageName);
+ parent.deliverNewIntentLocked(callingUid, destIntent, srec.packageName);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -4314,10 +4319,10 @@ class ActivityStack extends ConfigurationContainer {
.setActivityInfo(aInfo)
.setResultTo(parent.appToken)
.setCallingPid(-1)
- .setCallingUid(parent.launchedFromUid)
- .setCallingPackage(parent.launchedFromPackage)
+ .setCallingUid(callingUid)
+ .setCallingPackage(srec.packageName)
.setRealCallingPid(-1)
- .setRealCallingUid(parent.launchedFromUid)
+ .setRealCallingUid(callingUid)
.setComponentSpecified(true)
.execute();
foundParentInTask = res == ActivityManager.START_SUCCESS;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 0a88eef86ea8..1ebfa46f1955 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2743,6 +2743,11 @@ class ActivityStarter {
return mRequest.intent;
}
+ @VisibleForTesting
+ int getCallingUid() {
+ return mRequest.callingUid;
+ }
+
ActivityStarter setReason(String reason) {
mRequest.reason = reason;
return this;
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 bde0ef6aa39e..ff27b9bb1c9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -28,7 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
@@ -54,8 +54,11 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
+import android.app.ActivityManager;
+import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -82,8 +85,9 @@ public class ActivityStackTests extends ActivityTestsBase {
@Before
public void setUp() throws Exception {
mDefaultDisplay = mRootActivityContainer.getDefaultDisplay();
- mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
- true /* onTop */));
+ mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
+ true /* onTop */);
+ spyOn(mStack);
mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
}
@@ -1078,6 +1082,37 @@ public class ActivityStackTests extends ActivityTestsBase {
assertTrue(listener.mChanged);
}
+ @Test
+ public void testNavigateUpTo() {
+ final ActivityStartController controller = mock(ActivityStartController.class);
+ final ActivityStarter starter = new ActivityStarter(controller,
+ mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+ doReturn(controller).when(mService).getActivityStartController();
+ spyOn(starter);
+ doReturn(ActivityManager.START_SUCCESS).when(starter).execute();
+
+ final ActivityRecord firstActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(mTask)
+ .setUid(firstActivity.getUid() + 1).build();
+ doReturn(starter).when(controller).obtainStarter(eq(firstActivity.intent), anyString());
+
+ final IApplicationThread thread = secondActivity.app.getThread();
+ secondActivity.app.setThread(null);
+ // This should do nothing from a non-attached caller.
+ assertFalse(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+
+ secondActivity.app.setThread(thread);
+ assertTrue(mStack.navigateUpToLocked(secondActivity /* source record */,
+ firstActivity.intent /* destIntent */, 0 /* resultCode */, null /* resultData */));
+ // The firstActivity uses default launch mode, so the activities between it and itself will
+ // be finished.
+ assertTrue(secondActivity.finishing);
+ assertTrue(firstActivity.finishing);
+ // The calling uid of the new activity should be the current real caller.
+ assertEquals(secondActivity.getUid(), starter.getCallingUid());
+ }
+
private void verifyShouldSleepActivities(boolean focusedStack,
boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
final ActivityDisplay display = mock(ActivityDisplay.class);
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 4986a6d5bd0d..1d366259b590 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -265,6 +265,7 @@ class ActivityTestsBase {
aInfo.applicationInfo.packageName = mComponent.getPackageName();
aInfo.applicationInfo.uid = mUid;
aInfo.packageName = mComponent.getPackageName();
+ aInfo.name = mComponent.getClassName();
if (mTargetActivity != null) {
aInfo.targetActivity = mTargetActivity;
}