Merge "Remove permission token from startActivityAsCaller" into tm-dev
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a28b3e9..5eda587 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5707,7 +5707,6 @@
      * their launch had come from the original activity.
      * @param intent The Intent to start.
      * @param options ActivityOptions or null.
-     * @param permissionToken Token received from the system that permits this call to be made.
      * @param ignoreTargetSecurity If true, the activity manager will not check whether the
      * caller it is doing the start is, is actually allowed to start the target activity.
      * If you set this to true, you must set an explicit component in the Intent and do any
@@ -5716,18 +5715,18 @@
      * @hide
      */
     public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
-            IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
-        startActivityAsCaller(intent, options, permissionToken, ignoreTargetSecurity, userId, -1);
+            boolean ignoreTargetSecurity, int userId) {
+        startActivityAsCaller(intent, options, ignoreTargetSecurity, userId, -1);
     }
 
     /**
-     * @see #startActivityAsCaller(Intent, Bundle, IBinder, boolean, int)
+     * @see #startActivityAsCaller(Intent, Bundle, boolean, int)
      * @param requestCode The request code used for returning a result or -1 if no result should be
      *                    returned.
      * @hide
      */
     public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
-            IBinder permissionToken, boolean ignoreTargetSecurity, int userId, int requestCode) {
+            boolean ignoreTargetSecurity, int userId, int requestCode) {
         if (mParent != null) {
             throw new RuntimeException("Can't be called from a child");
         }
@@ -5735,8 +5734,7 @@
         Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivityAsCaller(
                         this, mMainThread.getApplicationThread(), mToken, this,
-                        intent, requestCode, options, permissionToken, ignoreTargetSecurity,
-                        userId);
+                        intent, requestCode, options, ignoreTargetSecurity, userId);
         if (ar != null) {
             mMainThread.sendActivityResult(
                     mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index a836625..6fc0c26 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -106,14 +106,6 @@
             RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
 
     /**
-     * Extra included on intents that are delegating the call to
-     * ActivityManager#startActivityAsCaller to another app.  This token is necessary for that call
-     * to succeed.  Type is IBinder.
-     * @hide
-     */
-    public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN";
-
-    /**
      * Extra included on intents that contain an EXTRA_INTENT, with options that the contained
      * intent may want to be started with.  Type is Bundle.
      * TODO: remove once the ChooserActivity moves to systemui
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index ef9a2f2..87b2417 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -141,7 +141,7 @@
     int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
             in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
             int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
-            IBinder permissionToken, boolean ignoreTargetSecurity, int userId);
+            boolean ignoreTargetSecurity, int userId);
 
     boolean isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType,
             int userId);
@@ -182,18 +182,6 @@
     int addAppTask(in IBinder activityToken, in Intent intent,
             in ActivityManager.TaskDescription description, in Bitmap thumbnail);
     Point getAppTaskThumbnailSize();
-    /**
-     * Only callable from the system. This token grants a temporary permission to call
-     * #startActivityAsCaller. The token will time out after START_AS_CALLER_TOKEN_TIMEOUT
-     * if it is not used.
-     *
-     * @param componentName The component name of the delegated component that is allowed to
-     *                      call #startActivityAsCaller with the returned token.
-     *
-     * @return Returns a token that can be given to a "delegate" app that may call
-     *         #startActivityAsCaller
-     */
-    IBinder requestStartActivityPermissionToken(in ComponentName componentName);
 
     oneway void releaseSomeActivities(in IApplicationThread app);
     Bitmap getTaskDescriptionIcon(in String filename, int userId);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 3cc2b56..995a9f3 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1999,7 +1999,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public ActivityResult execStartActivityAsCaller(
             Context who, IBinder contextThread, IBinder token, Activity target,
-            Intent intent, int requestCode, Bundle options, IBinder permissionToken,
+            Intent intent, int requestCode, Bundle options,
             boolean ignoreTargetSecurity, int userId) {
         IApplicationThread whoThread = (IApplicationThread) contextThread;
         if (mActivityMonitors != null) {
@@ -2034,7 +2034,7 @@
                     .startActivityAsCaller(whoThread, who.getOpPackageName(), intent,
                             intent.resolveTypeIfNeeded(who.getContentResolver()),
                             token, target != null ? target.mEmbeddedID : null,
-                            requestCode, 0, null, options, permissionToken,
+                            requestCode, 0, null, options,
                             ignoreTargetSecurity, userId);
             checkStartActivityResult(result, intent);
         } catch (RemoteException e) {
diff --git a/core/java/android/service/games/GameSessionTrampolineActivity.java b/core/java/android/service/games/GameSessionTrampolineActivity.java
index ddea098..3d97d0f 100644
--- a/core/java/android/service/games/GameSessionTrampolineActivity.java
+++ b/core/java/android/service/games/GameSessionTrampolineActivity.java
@@ -51,7 +51,6 @@
             startActivityAsCaller(
                     getIntent().getParcelableExtra(INTENT_KEY),
                     getIntent().getBundleExtra(OPTIONS_KEY),
-                    null,
                     false,
                     getUserId(),
                     REQUEST_CODE);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c2e145e..96728ed 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -28,7 +28,6 @@
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
 import android.app.SharedElementCallback;
 import android.app.prediction.AppPredictionContext;
 import android.app.prediction.AppPredictionManager;
@@ -71,11 +70,9 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Message;
 import android.os.Parcelable;
 import android.os.PatternMatcher;
-import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -761,25 +758,17 @@
             return false;
         }
 
-        try {
-            Intent delegationIntent = new Intent();
-            final ComponentName delegateActivity = ComponentName.unflattenFromString(
-                    Resources.getSystem().getString(R.string.config_chooserActivity));
-            IBinder permissionToken = ActivityTaskManager.getService()
-                    .requestStartActivityPermissionToken(delegateActivity);
-            delegationIntent.setComponent(delegateActivity);
-            delegationIntent.putExtra(Intent.EXTRA_INTENT, getIntent());
-            delegationIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
-            delegationIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+        Intent delegationIntent = new Intent();
+        final ComponentName delegateActivity = ComponentName.unflattenFromString(
+                Resources.getSystem().getString(R.string.config_chooserActivity));
+        delegationIntent.setComponent(delegateActivity);
+        delegationIntent.putExtra(Intent.EXTRA_INTENT, getIntent());
+        delegationIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
 
-            // Don't close until the delegate finishes, or the token will be invalidated.
-            mAwaitingDelegateResponse = true;
-            startActivityForResult(delegationIntent, REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER);
-            return true;
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
-        return false;
+        // Don't close until the delegate finishes, or the token will be invalidated.
+        mAwaitingDelegateResponse = true;
+        startActivityForResult(delegationIntent, REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER);
+        return true;
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 6e76906..070d8ff 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -207,7 +207,6 @@
             startActivityAsCaller(
                     newIntent,
                     /* options= */ null,
-                    /* permissionToken= */ null,
                     /* ignoreTargetSecurity= */ false,
                     userId);
         } catch (RuntimeException e) {
@@ -231,7 +230,7 @@
             return;
         }
         sanitizeIntent(innerIntent);
-        startActivityAsCaller(intentReceived, null, null, false, getUserId());
+        startActivityAsCaller(intentReceived, null, false, getUserId());
         finish();
     }
 
@@ -251,7 +250,7 @@
         sanitizeIntent(intentReceived);
         intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile);
         intentReceived.putExtra(EXTRA_CALLING_USER, UserHandle.of(callingUserId));
-        startActivityAsCaller(intentReceived, null, null, false, userId);
+        startActivityAsCaller(intentReceived, null, false, userId);
         finish();
     }
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 5ebb148..dc68e16 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1463,7 +1463,7 @@
             int userId) {
         // Note: this method will be overridden in the delegate implementation to use the passed-in
         // permission token.
-        startActivityAsCaller(intent, options, null, false, userId);
+        startActivityAsCaller(intent, options, false, userId);
         return true;
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
index 1f6b57e..a663095 100644
--- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -44,7 +44,6 @@
 import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -649,7 +648,7 @@
 
         @Override
         public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
-                IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
+                boolean ignoreTargetSecurity, int userId) {
             mStartActivityIntent = intent;
             mUserIdActivityLaunchedIn = userId;
         }
diff --git a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
index 0ee07b6..5597c9a 100644
--- a/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
+++ b/services/core/java/com/android/server/pm/IntentResolverInterceptor.java
@@ -21,14 +21,11 @@
 import android.Manifest;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.app.ActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.os.RemoteException;
 import android.provider.DeviceConfig;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -39,10 +36,8 @@
 
 /**
  * Service to register an {@code ActivityInterceptorCallback} that modifies any {@code Intent}
- * that's being used to launch a user-space {@code ChooserActivity}, by adding
- * EXTRA_PERMISSION_TOKEN, a Binder representing a single-use-only permission to invoke the
- * #startActivityAsCaller() API (which normally isn't available in user-space); and setting the
- * destination component to the delegated component when appropriate.
+ * that's being used to launch a user-space {@code ChooserActivity} by setting the destination
+ * component to the delegated component when appropriate.
  */
 public final class IntentResolverInterceptor {
     private static final String TAG = "IntentResolverIntercept";
@@ -92,7 +87,6 @@
 
     private Intent modifyChooserIntent(Intent intent) {
         intent.setComponent(getUnbundledChooserComponentName());
-        addStartActivityPermissionTokenToIntent(intent, getUnbundledChooserComponentName());
         return intent;
     }
 
@@ -103,18 +97,6 @@
                 || targetComponent.equals(getUnbundledChooserComponentName());
     }
 
-    private static Intent addStartActivityPermissionTokenToIntent(
-            Intent intent, ComponentName grantee) {
-        try {
-            intent.putExtra(
-                    ActivityTaskManager.EXTRA_PERMISSION_TOKEN,
-                    ActivityTaskManager.getService().requestStartActivityPermissionToken(grantee));
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Failed to add permission token to chooser intent");
-        }
-        return intent;
-    }
-
     private static ComponentName getSystemChooserComponentName() {
         return new ComponentName("android", "com.android.internal.app.ChooserActivity");
     }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ad6f354..eacf205 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -421,30 +421,6 @@
     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
     private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
 
-    // Permission tokens are used to temporarily granted a trusted app the ability to call
-    // #startActivityAsCaller.  A client is expected to dump its token after this time has elapsed,
-    // showing any appropriate error messages to the user.
-    private static final long START_AS_CALLER_TOKEN_TIMEOUT =
-            10 * MINUTE_IN_MILLIS;
-
-    // How long before the service actually expires a token.  This is slightly longer than
-    // START_AS_CALLER_TOKEN_TIMEOUT, to provide a buffer so clients will rarely encounter the
-    // expiration exception.
-    private static final long START_AS_CALLER_TOKEN_TIMEOUT_IMPL =
-            START_AS_CALLER_TOKEN_TIMEOUT + 2 * 1000;
-
-    // How long the service will remember expired tokens, for the purpose of providing error
-    // messaging when a client uses an expired token.
-    private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
-            START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
-
-    // The component name of the delegated activities that are allowed to call
-    // #startActivityAsCaller with the one-time used permission token.
-    final HashMap<IBinder, ComponentName> mStartActivitySources = new HashMap<>();
-
-    // Permission tokens that have expired, but we remember for error reporting.
-    final ArrayList<IBinder> mExpiredStartAsCallerTokens = new ArrayList<>();
-
     private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
 
     // Keeps track of the active voice interaction service component, notified from
@@ -1547,41 +1523,19 @@
     }
 
     @Override
-    public IBinder requestStartActivityPermissionToken(ComponentName componentName) {
-        int callingUid = Binder.getCallingUid();
-        if (UserHandle.getAppId(callingUid) != SYSTEM_UID) {
-            throw new SecurityException("Only the system process can request a permission token, "
-                    + "received request from uid: " + callingUid);
-        }
-        IBinder permissionToken = new Binder();
-        synchronized (mGlobalLock) {
-            mStartActivitySources.put(permissionToken, componentName);
-        }
-
-        Message expireMsg = PooledLambda.obtainMessage(
-                ActivityTaskManagerService::expireStartAsCallerTokenMsg, this, permissionToken);
-        mUiHandler.sendMessageDelayed(expireMsg, START_AS_CALLER_TOKEN_TIMEOUT_IMPL);
-
-        Message forgetMsg = PooledLambda.obtainMessage(
-                ActivityTaskManagerService::forgetStartAsCallerTokenMsg, this, permissionToken);
-        mUiHandler.sendMessageDelayed(forgetMsg, START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT);
-
-        return permissionToken;
-    }
-
-    @Override
     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
+            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions,
             boolean ignoreTargetSecurity, int userId) {
         // This is very dangerous -- it allows you to perform a start activity (including
         // permission grants) as any app that may launch one of your own activities.  So we only
         // allow this in two cases:
-        // 1)  The caller is an activity that is part of the core framework, and then only when it
-        //     is running as the system.
-        // 2)  The caller provides a valid permissionToken.  Permission tokens are one-time use and
-        //     can only be requested from system uid, which may then delegate this call to
-        //     another app.
+        // 1)  The calling process holds the signature permission START_ACTIVITY_AS_CALLER
+        //
+        // 2) The calling process is an activity belonging to the package "android" which is
+        //    running as UID_SYSTEM or as the target UID (the activity which started the activity
+        //    calling this method).
+
         final ActivityRecord sourceRecord;
         final int targetUid;
         final String targetPackage;
@@ -1600,26 +1554,8 @@
                 throw new SecurityException("Called without a process attached to activity");
             }
 
-            final ComponentName componentName;
-            if (permissionToken != null) {
-                // To even attempt to use a permissionToken, an app must also have this signature
-                // permission.
-                mAmInternal.enforceCallingPermission(
-                        android.Manifest.permission.START_ACTIVITY_AS_CALLER,
-                        "startActivityAsCaller");
-                // If called with a permissionToken, the caller must be the same component that
-                // was allowed to use the permissionToken.
-                componentName = mStartActivitySources.remove(permissionToken);
-                if (!sourceRecord.mActivityComponent.equals(componentName)) {
-                    if (mExpiredStartAsCallerTokens.contains(permissionToken)) {
-                        throw new SecurityException("Called with expired permission token: "
-                                + permissionToken);
-                    } else {
-                        throw new SecurityException("Called with invalid permission token: "
-                                + permissionToken);
-                    }
-                }
-            } else {
+            if (checkCallingPermission(Manifest.permission.START_ACTIVITY_AS_CALLER)
+                    != PERMISSION_GRANTED) {
                 // Whether called directly or from a delegate, the source activity must be from the
                 // android package.
                 if (!sourceRecord.info.packageName.equals("android")) {
@@ -4453,15 +4389,6 @@
         Settings.System.putConfigurationForUser(resolver, config, userId);
     }
 
-    private void expireStartAsCallerTokenMsg(IBinder permissionToken) {
-        mStartActivitySources.remove(permissionToken);
-        mExpiredStartAsCallerTokens.add(permissionToken);
-    }
-
-    private void forgetStartAsCallerTokenMsg(IBinder permissionToken) {
-        mExpiredStartAsCallerTokens.remove(permissionToken);
-    }
-
     boolean isActivityStartsLoggingEnabled() {
         return mAmInternal.isActivityStartsLoggingEnabled();
     }