summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerInternal.java4
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerService.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java96
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java24
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartController.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java110
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java53
-rw-r--r--services/core/java/com/android/server/wm/TaskRecord.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java4
12 files changed, 218 insertions, 111 deletions
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
index 2f50fcb08c02..94a1baa49deb 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
@@ -43,14 +43,14 @@ public interface UriGrantsManagerInternal {
int callingUid, String targetPkg, Uri uri, int modeFlags, int userId);
NeededUriGrants checkGrantUriPermissionFromIntent(int callingUid,
String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId);
+ NeededUriGrants checkGrantUriPermissionFromIntent(int callingUid,
+ Intent intent, String targetPkg, int targetUserId);
/**
* Grant Uri permissions from one app to another. This method only extends
* permission grants if {@code callingUid} has permission to them.
*/
void grantUriPermissionFromIntent(int callingUid,
String targetPkg, Intent intent, int targetUserId);
- void grantUriPermissionFromIntent(int callingUid,
- String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId);
void grantUriPermissionUncheckedFromIntent(
NeededUriGrants needed, UriPermissionOwner owner);
IBinder newUriPermissionOwner(String name);
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 8b332d271a3a..04f7c7ee8574 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -1362,20 +1362,21 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
}
@Override
- public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
- int targetUserId) {
+ public NeededUriGrants checkGrantUriPermissionFromIntent(int callingUid, Intent intent,
+ String targetPkg, int targetUserId) {
synchronized (mLock) {
- UriGrantsManagerService.this.grantUriPermissionFromIntent(
- callingUid, targetPkg, intent, null, targetUserId);
+ final int mode = (intent != null) ? intent.getFlags() : 0;
+ return UriGrantsManagerService.this.checkGrantUriPermissionFromIntent(
+ callingUid, targetPkg, intent, mode, null, targetUserId);
}
}
@Override
public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
- UriPermissionOwner owner, int targetUserId) {
+ int targetUserId) {
synchronized (mLock) {
UriGrantsManagerService.this.grantUriPermissionFromIntent(
- callingUid, targetPkg, intent, owner, targetUserId);
+ callingUid, targetPkg, intent, null, targetUserId);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1344727ab36d..7c4b5711cbe6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -215,6 +215,7 @@ import com.android.server.AttributeCache;
import com.android.server.AttributeCache.Entry;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.PendingIntentRecord;
+import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriPermissionOwner;
import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
import com.android.server.wm.ActivityStack.ActivityState;
@@ -1599,10 +1600,11 @@ final class ActivityRecord extends ConfigurationContainer {
* Deliver a new Intent to an existing activity, so that its onNewIntent()
* method will be called at the proper time.
*/
- final void deliverNewIntentLocked(int callingUid, Intent intent, String referrer) {
+ final void deliverNewIntentLocked(int callingUid, Intent intent, NeededUriGrants intentGrants,
+ String referrer) {
// The activity now gets access to the data associated with this Intent.
- mAtmService.mUgmInternal.grantUriPermissionFromIntent(callingUid, packageName,
- intent, getUriPermissionsLocked(), mUserId);
+ mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
+ getUriPermissionsLocked());
final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
boolean unsent = true;
final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping();
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 3d59e66d13ef..1ad5e7c8f4ae 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -162,6 +162,7 @@ import com.android.server.am.ActivityManagerService.ItemMatcher;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.EventLogTags;
import com.android.server.am.PendingIntentRecord;
+import com.android.server.uri.NeededUriGrants;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -2780,7 +2781,7 @@ class ActivityStack extends ConfigurationContainer {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"no-history finish of " + mLastNoHistoryActivity + " on new resume");
requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
- null, "resume-no-history", false);
+ null, null, "resume-no-history", false);
mLastNoHistoryActivity = null;
}
@@ -3014,7 +3015,7 @@ class ActivityStack extends ConfigurationContainer {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
- requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
+ requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null, null,
"resume-exception", true);
return true;
}
@@ -3422,7 +3423,7 @@ class ActivityStack extends ConfigurationContainer {
if (DEBUG_TASKS) Slog.w(TAG_TASKS,
"resetTaskIntendedTask: calling finishActivity on " + p);
if (finishActivityLocked(
- p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
+ p, Activity.RESULT_CANCELED, null, null, "reset-task", false)) {
end--;
srcPos--;
}
@@ -3501,7 +3502,7 @@ class ActivityStack extends ConfigurationContainer {
continue;
}
finishActivityLocked(
- p, Activity.RESULT_CANCELED, null, "move-affinity", false);
+ p, Activity.RESULT_CANCELED, null, null, "move-affinity", false);
}
} else {
if (taskInsertionPoint < 0) {
@@ -3535,8 +3536,8 @@ class ActivityStack extends ConfigurationContainer {
if (targetNdx > 0) {
ActivityRecord p = taskActivities.get(targetNdx - 1);
if (p.intent.getComponent().equals(target.intent.getComponent())) {
- finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
- false);
+ finishActivityLocked(p, Activity.RESULT_CANCELED, null, null,
+ "replace", false);
}
}
}
@@ -3596,22 +3597,21 @@ class ActivityStack extends ConfigurationContainer {
return taskTop;
}
- void sendActivityResultLocked(int callingUid, ActivityRecord r,
- String resultWho, int requestCode, int resultCode, Intent data) {
-
+ void sendActivityResultLocked(int callingUid, ActivityRecord r, String resultWho,
+ int requestCode, int resultCode, Intent resultData, NeededUriGrants resultGrants) {
if (callingUid > 0) {
- mService.mUgmInternal.grantUriPermissionFromIntent(callingUid, r.packageName,
- data, r.getUriPermissionsLocked(), r.mUserId);
+ mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
+ r.getUriPermissionsLocked());
}
if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
+ " : who=" + resultWho + " req=" + requestCode
- + " res=" + resultCode + " data=" + data);
+ + " res=" + resultCode + " data=" + resultData);
if (mResumedActivity == r && r.attachedToProcess()) {
try {
ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
list.add(new ResultInfo(resultWho, requestCode,
- resultCode, data));
+ resultCode, resultData));
mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken,
ActivityResultItem.obtain(list));
return;
@@ -3620,7 +3620,7 @@ class ActivityStack extends ConfigurationContainer {
}
}
- r.addResultLocked(null, resultWho, requestCode, resultCode, data);
+ r.addResultLocked(null, resultWho, requestCode, resultCode, resultData);
}
/** Returns true if the task is one of the task finishing on-top of the top running task. */
@@ -3727,8 +3727,8 @@ class ActivityStack extends ConfigurationContainer {
if (!r.finishing) {
if (!shouldSleepActivities()) {
if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
- if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
- "stop-no-history", false)) {
+ if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED,
+ null, null, "stop-no-history", false)) {
// If {@link requestFinishActivityLocked} returns {@code true},
// {@link adjustFocusedActivityStack} would have been already called.
r.resumeKeyDispatchingLocked();
@@ -3784,7 +3784,7 @@ class ActivityStack extends ConfigurationContainer {
* some reason it is being left as-is.
*/
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
- Intent resultData, String reason, boolean oomAdj) {
+ Intent resultData, NeededUriGrants resultGrants, String reason, boolean oomAdj) {
ActivityRecord r = isInStackLocked(token);
if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
"Finishing activity token=" + token + " r="
@@ -3794,7 +3794,7 @@ class ActivityStack extends ConfigurationContainer {
return false;
}
- finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
+ finishActivityLocked(r, resultCode, resultData, resultGrants, reason, oomAdj);
return true;
}
@@ -3806,8 +3806,8 @@ class ActivityStack extends ConfigurationContainer {
if (r.resultTo == self && r.requestCode == requestCode) {
if ((r.resultWho == null && resultWho == null) ||
(r.resultWho != null && r.resultWho.equals(resultWho))) {
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
- false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null,
+ "request-sub", false);
}
}
}
@@ -3837,7 +3837,7 @@ class ActivityStack extends ConfigurationContainer {
int activityNdx = task.mActivities.indexOf(r);
getDisplay().mDisplayContent.prepareAppTransition(
TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null, reason, false);
finishedTask = task;
// Also terminate any activities below it that aren't yet
// stopped, to avoid a situation where one will get
@@ -3858,7 +3858,7 @@ class ActivityStack extends ConfigurationContainer {
if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null, reason, false);
}
}
}
@@ -3874,8 +3874,8 @@ class ActivityStack extends ConfigurationContainer {
for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord r = tr.mActivities.get(activityNdx);
if (!r.finishing) {
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
- false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null,
+ "finish-voice", false);
didOne = true;
}
}
@@ -3911,12 +3911,14 @@ class ActivityStack extends ConfigurationContainer {
if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
break;
}
- finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
+ finishActivityLocked(cur, Activity.RESULT_CANCELED, null, null,
+ "request-affinity", true);
}
return true;
}
- private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
+ private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData,
+ NeededUriGrants resultGrants) {
// send the result
ActivityRecord resultTo = r.resultTo;
if (resultTo != null) {
@@ -3929,9 +3931,8 @@ class ActivityStack extends ConfigurationContainer {
}
}
if (r.info.applicationInfo.uid > 0) {
- mService.mUgmInternal.grantUriPermissionFromIntent(r.info.applicationInfo.uid,
- resultTo.packageName, resultData,
- resultTo.getUriPermissionsLocked(), resultTo.mUserId);
+ mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(resultGrants,
+ resultTo.getUriPermissionsLocked());
}
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData);
r.resultTo = null;
@@ -3947,12 +3948,10 @@ class ActivityStack extends ConfigurationContainer {
r.icicle = null;
}
- /**
- * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
- */
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
- String reason, boolean oomAdj) {
- return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
+ NeededUriGrants resultGrants, String reason, boolean oomAdj) {
+ return finishActivityLocked(r, resultCode, resultData, resultGrants, reason, oomAdj,
+ !PAUSE_IMMEDIATELY);
}
/**
@@ -3960,7 +3959,7 @@ class ActivityStack extends ConfigurationContainer {
* list, or false if it is still in the list and will be removed later.
*/
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
- String reason, boolean oomAdj, boolean pauseImmediately) {
+ NeededUriGrants resultGrants, String reason, boolean oomAdj, boolean pauseImmediately) {
if (r.finishing) {
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
@@ -3990,7 +3989,7 @@ class ActivityStack extends ConfigurationContainer {
adjustFocusedActivityStack(r, "finishActivity");
- finishActivityResultsLocked(r, resultCode, resultData);
+ finishActivityResultsLocked(r, resultCode, resultData, resultGrants);
final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
@@ -4223,8 +4222,9 @@ class ActivityStack extends ConfigurationContainer {
return false;
}
- final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
- Intent resultData) {
+ final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent,
+ NeededUriGrants destGrants, int resultCode, Intent resultData,
+ NeededUriGrants resultGrants) {
final TaskRecord task = srec.getTaskRecord();
final ArrayList<ActivityRecord> activities = task.mActivities;
final int start = activities.indexOf(srec);
@@ -4271,7 +4271,8 @@ class ActivityStack extends ConfigurationContainer {
final long origId = Binder.clearCallingIdentity();
for (int i = start; i > finishTo; i--) {
ActivityRecord r = activities.get(i);
- requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
+ requestFinishActivityLocked(r.appToken, resultCode, resultData, resultGrants,
+ "navigate-up", true);
// Only return the supplied result for the first activity finished
resultCode = Activity.RESULT_CANCELED;
resultData = null;
@@ -4285,7 +4286,7 @@ class ActivityStack extends ConfigurationContainer {
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent,
- srec.packageName);
+ destGrants, srec.packageName);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
@@ -4309,7 +4310,7 @@ class ActivityStack extends ConfigurationContainer {
foundParentInTask = false;
}
requestFinishActivityLocked(parent.appToken, resultCode,
- resultData, "navigate-top", true);
+ resultData, resultGrants, "navigate-top", true);
}
}
Binder.restoreCallingIdentity(origId);
@@ -4394,7 +4395,7 @@ class ActivityStack extends ConfigurationContainer {
}
private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
- finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
+ finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null, null);
r.makeFinishingLocked();
if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
"Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
@@ -5126,7 +5127,8 @@ class ActivityStack extends ConfigurationContainer {
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null,
+ "close-sys", true);
}
}
}
@@ -5170,8 +5172,8 @@ class ActivityStack extends ConfigurationContainer {
didSomething = true;
Slog.i(TAG, " Force finishing activity " + r);
lastTask = r.getTaskRecord();
- finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
- true);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, null,
+ "force-stop", true);
}
}
}
@@ -5225,8 +5227,8 @@ class ActivityStack extends ConfigurationContainer {
final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
int activityTop = activities.size() - 1;
if (activityTop >= 0) {
- finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
- "unhandled-back", true);
+ finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED,
+ null, null, "unhandled-back", true);
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index c992a69c2ecb..8d2a92acc91f 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -140,6 +140,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.ActivityManagerService;
import com.android.server.am.EventLogTags;
import com.android.server.am.UserState;
+import com.android.server.uri.NeededUriGrants;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -403,14 +404,17 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
final int startFlags;
final ActivityStack stack;
final WindowProcessController callerApp;
+ final NeededUriGrants neededGrants;
- PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
- int _startFlags, ActivityStack _stack, WindowProcessController app) {
- r = _r;
- sourceRecord = _sourceRecord;
- startFlags = _startFlags;
- stack = _stack;
- callerApp = app;
+ PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord,
+ int startFlags, ActivityStack stack, WindowProcessController callerApp,
+ NeededUriGrants neededGrants) {
+ this.r = r;
+ this.sourceRecord = sourceRecord;
+ this.startFlags = startFlags;
+ this.stack = stack;
+ this.callerApp = callerApp;
+ this.neededGrants = neededGrants;
}
void sendErrorResult(String message) {
@@ -874,8 +878,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
Slog.e(TAG, "Second failure launching "
+ r.intent.getComponent().flattenToShortString() + ", giving up", e);
proc.appDied();
- stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
- "2nd-crash", false);
+ stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED,
+ null, null, "2nd-crash", false);
return false;
}
@@ -1020,7 +1024,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
- Activity.RESULT_CANCELED, null);
+ Activity.RESULT_CANCELED, null, null);
}
final String msg;
if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) {
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 919141c13622..738d143280d9 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -462,7 +462,7 @@ public class ActivityStartController {
"pendingActivityLaunch");
try {
starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags,
- resume, pal.r.pendingOptions, null);
+ resume, pal.r.pendingOptions, null, pal.neededGrants);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1718ac634b10..fb18569ba637 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -127,6 +127,7 @@ import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.EventLogTags;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
+import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
import com.android.server.wm.LaunchParamsController.LaunchParams;
@@ -549,7 +550,8 @@ class ActivityStarter {
*/
int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
+ int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+ NeededUriGrants neededGrants) {
try {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(r.intent);
mLastStartReason = "startResolvedActivity";
@@ -557,7 +559,7 @@ class ActivityStarter {
mLastStartActivityRecord[0] = r;
mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, mLastStartActivityRecord,
- false /* restrictedBgActivity */);
+ false /* restrictedBgActivity */, neededGrants);
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult,
mLastStartActivityRecord[0]);
return mLastStartActivityResult;
@@ -576,6 +578,33 @@ class ActivityStarter {
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
+ // Carefully collect grants without holding lock
+ NeededUriGrants neededGrants = null;
+ if (aInfo != null) {
+ neededGrants = mService.mUgmInternal.checkGrantUriPermissionFromIntent(
+ resolveCallingUid(mRequest.caller), intent, aInfo.applicationInfo.packageName,
+ UserHandle.getUserId(aInfo.applicationInfo.uid));
+ }
+
+ return startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
+ voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
+ callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
+ ignoreTargetSecurity, componentSpecified, outActivity, inTask, reason,
+ allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
+ allowBackgroundActivityStart, neededGrants);
+ }
+
+ private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
+ String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
+ IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
+ IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
+ String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
+ SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
+ ActivityRecord[] outActivity, TaskRecord inTask, String reason,
+ boolean allowPendingRemoteAnimationRegistryLookup,
+ PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart,
+ NeededUriGrants neededGrants) {
+
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
@@ -588,7 +617,7 @@ class ActivityStarter {
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
- allowBackgroundActivityStart);
+ allowBackgroundActivityStart, neededGrants);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
@@ -619,7 +648,8 @@ class ActivityStarter {
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
- PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
+ PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart,
+ NeededUriGrants neededGrants) {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
@@ -754,7 +784,7 @@ class ActivityStarter {
if (err != START_SUCCESS) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(
- -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
+ -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null, null);
}
SafeActivityOptions.abort(options);
return err;
@@ -814,12 +844,16 @@ class ActivityStarter {
callingPid = mInterceptor.mCallingPid;
callingUid = mInterceptor.mCallingUid;
checkedOptions = mInterceptor.mActivityOptions;
+
+ // The interception target shouldn't get any permission grants
+ // intended for the original destination
+ neededGrants = null;
}
if (abort) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
- RESULT_CANCELED, null);
+ RESULT_CANCELED, null, null);
}
// We pretend to the caller that it was really started, but
// they will just get a cancel result.
@@ -875,6 +909,10 @@ class ActivityStarter {
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
+ // The permissions review target shouldn't get any permission
+ // grants intended for the original destination
+ neededGrants = null;
+
if (DEBUG_PERMISSIONS_REVIEW) {
final ActivityStack focusedStack =
mRootActivityContainer.getTopDisplayFocusedStack();
@@ -897,6 +935,10 @@ class ActivityStarter {
callingPid = realCallingPid;
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
+
+ // The ephemeral installer shouldn't get any permission grants
+ // intended for the original destination
+ neededGrants = null;
}
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
@@ -923,7 +965,7 @@ class ActivityStarter {
realCallingPid, realCallingUid, "Activity start")) {
if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
- sourceRecord, startFlags, stack, callerApp));
+ sourceRecord, startFlags, stack, callerApp, neededGrants));
}
ActivityOptions.abort(checkedOptions);
return ActivityManager.START_SWITCHES_CANCELED;
@@ -934,7 +976,8 @@ class ActivityStarter {
mController.doPendingActivityLaunches(false);
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
- true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
+ true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity,
+ neededGrants);
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
return res;
}
@@ -1232,9 +1275,15 @@ class ActivityStarter {
}
}
}
+
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
+ // Carefully collect grants without holding lock
+ NeededUriGrants neededGrants = mService.mUgmInternal.checkGrantUriPermissionFromIntent(
+ resolveCallingUid(mRequest.caller), intent, aInfo.applicationInfo.packageName,
+ UserHandle.getUserId(aInfo.applicationInfo.uid));
+
synchronized (mService.mGlobalLock) {
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
stack.mConfigWillChange = globalConfig != null
@@ -1311,7 +1360,7 @@ class ActivityStarter {
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
- allowBackgroundActivityStart);
+ allowBackgroundActivityStart, neededGrants);
Binder.restoreCallingIdentity(origId);
@@ -1406,14 +1455,16 @@ class ActivityStarter {
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
- ActivityRecord[] outActivity, boolean restrictedBgActivity) {
+ int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+ ActivityRecord[] outActivity, boolean restrictedBgActivity,
+ NeededUriGrants neededGrants) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
+ startFlags, doResume, options, inTask, outActivity, restrictedBgActivity,
+ neededGrants);
} finally {
final ActivityStack currentStack = r.getActivityStack();
startedActivityStack = currentStack != null ? currentStack : mTargetStack;
@@ -1438,7 +1489,8 @@ class ActivityStarter {
final ActivityStack stack = mStartActivity.getActivityStack();
if (stack != null) {
stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
- null /* intentResultData */, "startActivity", true /* oomAdj */);
+ null /* resultData */, null /* resultGrants */,
+ "startActivity", true /* oomAdj */);
}
}
mService.mWindowManager.continueSurfaceLayout();
@@ -1467,7 +1519,7 @@ class ActivityStarter {
if (resultRecord != null) {
ActivityStack resultStack = resultRecord.getActivityStack();
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
- RESULT_CANCELED, null);
+ RESULT_CANCELED, null, null);
}
// We pretend to the caller that it was really started to make it backward compatible, but
// they will just get a cancel result.
@@ -1479,7 +1531,8 @@ class ActivityStarter {
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
- ActivityRecord[] outActivity, boolean restrictedBgActivity) {
+ ActivityRecord[] outActivity, boolean restrictedBgActivity,
+ NeededUriGrants neededGrants) {
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
@@ -1629,7 +1682,7 @@ class ActivityStarter {
if (sourceStack != null) {
sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
- null /* data */);
+ null /* resultData */, null /* resultGrants */);
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
@@ -1696,8 +1749,8 @@ class ActivityStarter {
return result;
}
- mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
- mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
+ mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(neededGrants,
+ mStartActivity.getUriPermissionsLocked());
mService.getPackageManagerInternalLocked().grantEphemeralAccess(
mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
UserHandle.getAppId(mCallingUid));
@@ -1933,7 +1986,7 @@ class ActivityStarter {
Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
- null /* data */);
+ null /* resultData */, null /* resultGrants */);
mStartActivity.resultTo = null;
}
}
@@ -2362,8 +2415,13 @@ class ActivityStarter {
}
ActivityStack.logStartActivity(AM_NEW_INTENT, activity, activity.getTaskRecord());
- activity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
+
+ Intent intent = mStartActivity.intent;
+ NeededUriGrants intentGrants = mService.mUgmInternal.checkGrantUriPermissionFromIntent(
+ mCallingUid, intent, activity.packageName, activity.mUserId);
+ activity.deliverNewIntentLocked(mCallingUid, intent, intentGrants,
mStartActivity.launchedFromPackage);
+
mIntentDelivered = true;
}
@@ -2742,6 +2800,18 @@ class ActivityStarter {
}
}
+ private int resolveCallingUid(IApplicationThread caller) {
+ if (caller != null) {
+ synchronized (mService.mGlobalLock) {
+ final WindowProcessController callerApp = mService.getProcessController(caller);
+ if (callerApp != null) {
+ return callerApp.mInfo.uid;
+ }
+ }
+ }
+ return -1;
+ }
+
private boolean isLaunchModeOneOf(int mode1, int mode2) {
return mode1 == mLaunchMode || mode2 == mLaunchMode;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b97ececa81ee..53cf9e4bfc9d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -265,6 +265,7 @@ import com.android.server.appop.AppOpsService;
import com.android.server.firewall.IntentFirewall;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.PermissionPolicyInternal;
+import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.vr.VrManagerInternal;
@@ -1540,11 +1541,19 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
+ final ActivityRecord r;
synchronized (mGlobalLock) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return true;
}
+ }
+
+ // Carefully collect grants without holding lock
+ final NeededUriGrants resultGrants = mUgmInternal.checkGrantUriPermissionFromIntent(
+ Binder.getCallingUid(), resultData, r.packageName, r.mUserId);
+
+ synchronized (mGlobalLock) {
// Keep track of the root activity of the task before we finish it
final TaskRecord tr = r.getTaskRecord();
ActivityRecord rootR = tr.getRootActivity();
@@ -1606,7 +1615,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
r.mRelaunchReason = RELAUNCH_REASON_NONE;
} else {
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
- resultData, "app-request", true);
+ resultData, resultGrants, "app-request", true);
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
@@ -2132,14 +2141,23 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
Intent resultData) {
-
+ final ActivityRecord r;
synchronized (mGlobalLock) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r != null) {
- return r.getActivityStack().navigateUpToLocked(
- r, destIntent, resultCode, resultData);
+ r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return false;
}
- return false;
+ }
+
+ // Carefully collect grants without holding lock
+ final NeededUriGrants destGrants = mUgmInternal.checkGrantUriPermissionFromIntent(
+ Binder.getCallingUid(), destIntent, r.packageName, r.mUserId);
+ final NeededUriGrants resultGrants = mUgmInternal.checkGrantUriPermissionFromIntent(
+ Binder.getCallingUid(), resultData, r.packageName, r.mUserId);
+
+ synchronized (mGlobalLock) {
+ return r.getActivityStack().navigateUpToLocked(
+ r, destIntent, destGrants, resultCode, resultData, resultGrants);
}
}
@@ -6591,14 +6609,23 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void sendActivityResult(int callingUid, IBinder activityToken, String resultWho,
- int requestCode, int resultCode, Intent data) {
+ int requestCode, int resultCode, Intent resultData) {
+ final ActivityRecord r;
synchronized (mGlobalLock) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
- if (r != null && r.getActivityStack() != null) {
- r.getActivityStack().sendActivityResultLocked(callingUid, r, resultWho,
- requestCode, resultCode, data);
+ r = ActivityRecord.isInStackLocked(activityToken);
+ if (r == null || r.getActivityStack() == null) {
+ return;
}
}
+
+ // Carefully collect grants without holding lock
+ final NeededUriGrants resultGrants = mUgmInternal.checkGrantUriPermissionFromIntent(
+ Binder.getCallingUid(), resultData, r.packageName, r.mUserId);
+
+ synchronized (mGlobalLock) {
+ r.getActivityStack().sendActivityResultLocked(callingUid, r, resultWho,
+ requestCode, resultCode, resultData, resultGrants);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 298b302a17fb..4a0bf02ab517 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -1442,7 +1442,7 @@ class TaskRecord extends ConfigurationContainer {
mActivities.remove(activityNdx);
--activityNdx;
--numActivities;
- } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
+ } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, null,
reason, false, pauseImmediately)) {
--activityNdx;
--numActivities;
@@ -1497,8 +1497,8 @@ class TaskRecord extends ConfigurationContainer {
if (opts != null) {
ret.updateOptionsLocked(opts);
}
- if (mStack != null && mStack.finishActivityLocked(
- r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
+ if (mStack != null && mStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
+ null, null, "clear-task-stack", false)) {
--activityNdx;
--numActivities;
}
@@ -1512,8 +1512,8 @@ class TaskRecord extends ConfigurationContainer {
&& !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
if (!ret.finishing) {
if (mStack != null) {
- mStack.finishActivityLocked(
- ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
+ mStack.finishActivityLocked(ret, Activity.RESULT_CANCELED,
+ null, null, "clear-task-top", false);
}
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2ad25cf123e2..fbd4ec7ff536 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -623,7 +623,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final ActivityRecord r = activities.get(i);
if (!r.finishing && r.isInStackLocked()) {
r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
- null, "finish-heavy", true);
+ null, null, "finish-heavy", true);
}
}
}
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 757267e56fa2..4c0b582e8860 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -940,7 +940,8 @@ public class ActivityStackTests extends ActivityTestsBase {
homeStask.removeTask(homeTask, "testAdjustFocusedStack", REMOVE_TASK_MODE_DESTROYING);
// Finish the only activity.
- mStack.finishActivityLocked(topActivity, 0 /* resultCode */, null /* resultData */,
+ mStack.finishActivityLocked(topActivity, 0 /* resultCode */,
+ null /* resultData */, null /* resultGrants */,
"testAdjustFocusedStack", false /* oomAdj */);
// Although home stack is empty, it should still be the focused stack.
assertEquals(homeStask, mDefaultDisplay.getFocusedStack());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
index a7bbe6e4cf02..2d1200675fd4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartControllerTests.java
@@ -82,12 +82,12 @@ public class ActivityStartControllerTests extends ActivityTestsBase {
wpc.setThread(mock(IApplicationThread.class));
mController.addPendingActivityLaunch(
- new PendingActivityLaunch(activity, source, startFlags, stack, wpc));
+ new PendingActivityLaunch(activity, source, startFlags, stack, wpc, null));
final boolean resume = random.nextBoolean();
mController.doPendingActivityLaunches(resume);
verify(mStarter, times(1)).startResolvedActivity(eq(activity), eq(source), eq(null),
- eq(null), eq(startFlags), eq(resume), eq(null), eq(null));
+ eq(null), eq(startFlags), eq(resume), eq(null), eq(null), eq(null));
}