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();
}