diff options
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));      }  |