diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index a28b3e9fc5457..5eda587cf7c8f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -5707,7 +5707,6 @@ public class Activity extends ContextThemeWrapper * 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 @@ public class Activity extends ContextThemeWrapper * @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 @@ public class Activity extends ContextThemeWrapper 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 a836625925137..6fc0c260d89e7 100644 --- a/core/java/android/app/ActivityTaskManager.java +++ b/core/java/android/app/ActivityTaskManager.java @@ -105,14 +105,6 @@ public class ActivityTaskManager { public static final int RESIZE_MODE_USER_FORCED = 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. diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index ef9a2f2733485..87b2417af53f4 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -141,7 +141,7 @@ interface IActivityTaskManager { 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 @@ interface IActivityTaskManager { 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 3cc2b56cd8466..995a9f31b3410 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1999,7 +1999,7 @@ public class Instrumentation { @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 @@ public class Instrumentation { .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 ddea098680eae..3d97d0f59b332 100644 --- a/core/java/android/service/games/GameSessionTrampolineActivity.java +++ b/core/java/android/service/games/GameSessionTrampolineActivity.java @@ -51,7 +51,6 @@ public final class GameSessionTrampolineActivity extends Activity { 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 c2e145eccb97d..96728ed89b705 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.NonNull; 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.AsyncTask; 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 @@ public class ChooserActivity extends ResolverActivity implements 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 6e7690678d217..070d8ff945bae 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -207,7 +207,6 @@ public class IntentForwarderActivity extends Activity { startActivityAsCaller( newIntent, /* options= */ null, - /* permissionToken= */ null, /* ignoreTargetSecurity= */ false, userId); } catch (RuntimeException e) { @@ -231,7 +230,7 @@ public class IntentForwarderActivity extends Activity { return; } sanitizeIntent(innerIntent); - startActivityAsCaller(intentReceived, null, null, false, getUserId()); + startActivityAsCaller(intentReceived, null, false, getUserId()); finish(); } @@ -251,7 +250,7 @@ public class IntentForwarderActivity extends Activity { 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 5ebb148760c67..dc68e16e2eb64 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -1463,7 +1463,7 @@ public class ResolverActivity extends Activity implements 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 1f6b57e5d615d..a663095aa8939 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.content.pm.UserInfo; 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 @@ public class IntentForwarderActivityTest { @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 0ee07b650cf58..5597c9af7362d 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 static com.android.server.wm.ActivityInterceptorCallback.INTENT_RESOLVER_ 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 @@ import com.android.server.wm.ActivityTaskManagerInternal; /** * 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 @@ public final class IntentResolverInterceptor { private Intent modifyChooserIntent(Intent intent) { intent.setComponent(getUnbundledChooserComponentName()); - addStartActivityPermissionTokenToIntent(intent, getUnbundledChooserComponentName()); return intent; } @@ -103,18 +97,6 @@ public final class IntentResolverInterceptor { || 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 ad6f354520511..eacf205c088cd 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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // 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 mStartActivitySources = new HashMap<>(); - - // Permission tokens that have expired, but we remember for error reporting. - final ArrayList mExpiredStartAsCallerTokens = new ArrayList<>(); - private final ArrayList mPendingAssistExtras = new ArrayList<>(); // Keeps track of the active voice interaction service component, notified from @@ -1546,42 +1522,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { .execute(); } - @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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { 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(); }