Merge "Allow requesting start-activity-permission-token for an activity"
This commit is contained in:
@@ -178,17 +178,16 @@ interface IActivityTaskManager {
|
||||
Point getAppTaskThumbnailSize();
|
||||
/**
|
||||
* Only callable from the system. This token grants a temporary permission to call
|
||||
* #startActivityAsCallerWithToken. The token will time out after
|
||||
* START_AS_CALLER_TOKEN_TIMEOUT if it is not used.
|
||||
* #startActivityAsCaller. The token will time out after START_AS_CALLER_TOKEN_TIMEOUT
|
||||
* if it is not used.
|
||||
*
|
||||
* @param delegatorToken The Binder token referencing the system Activity that wants to delegate
|
||||
* the #startActivityAsCaller to another app. The "caller" will be the caller of this
|
||||
* activity's token, not the delegate's caller (which is probably the delegator itself).
|
||||
* @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 IBinder delegatorToken);
|
||||
IBinder requestStartActivityPermissionToken(in ComponentName componentName);
|
||||
|
||||
oneway void releaseSomeActivities(in IApplicationThread app);
|
||||
Bitmap getTaskDescriptionIcon(in String filename, int userId);
|
||||
|
||||
@@ -759,11 +759,11 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
}
|
||||
|
||||
try {
|
||||
IBinder permissionToken = ActivityTaskManager.getService()
|
||||
.requestStartActivityPermissionToken(getActivityToken());
|
||||
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);
|
||||
|
||||
@@ -1437,11 +1437,11 @@ public class ResolverActivity extends Activity implements
|
||||
try {
|
||||
// TODO: Once this is a small springboard activity, it can move off the UI process
|
||||
// and we can move the request method to ActivityManagerInternal.
|
||||
IBinder permissionToken = ActivityTaskManager.getService()
|
||||
.requestStartActivityPermissionToken(getActivityToken());
|
||||
final Intent chooserIntent = new Intent();
|
||||
final ComponentName delegateActivity = ComponentName.unflattenFromString(
|
||||
Resources.getSystem().getString(R.string.config_chooserActivity));
|
||||
IBinder permissionToken = ActivityTaskManager.getService()
|
||||
.requestStartActivityPermissionToken(delegateActivity);
|
||||
chooserIntent.setClassName(delegateActivity.getPackageName(),
|
||||
delegateActivity.getClassName());
|
||||
chooserIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
|
||||
|
||||
@@ -437,9 +437,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
|
||||
START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
|
||||
|
||||
// Activity tokens of system activities that are delegating their call to
|
||||
// #startActivityByCaller, keyed by the permissionToken granted to the delegate.
|
||||
final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>();
|
||||
// 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<>();
|
||||
@@ -1513,7 +1513,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder requestStartActivityPermissionToken(IBinder delegatorToken) {
|
||||
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, "
|
||||
@@ -1521,7 +1521,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
}
|
||||
IBinder permissionToken = new Binder();
|
||||
synchronized (mGlobalLock) {
|
||||
mStartActivitySources.put(permissionToken, delegatorToken);
|
||||
mStartActivitySources.put(permissionToken, componentName);
|
||||
}
|
||||
|
||||
Message expireMsg = PooledLambda.obtainMessage(
|
||||
@@ -1546,7 +1546,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
// 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 by a system activity, which may then delegate this call to
|
||||
// can only be requested from system uid, which may then delegate this call to
|
||||
// another app.
|
||||
final ActivityRecord sourceRecord;
|
||||
final int targetUid;
|
||||
@@ -1557,18 +1557,26 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
if (resultTo == null) {
|
||||
throw new SecurityException("Must be called from an activity");
|
||||
}
|
||||
final IBinder sourceToken;
|
||||
|
||||
sourceRecord = ActivityRecord.isInAnyTask(resultTo);
|
||||
if (sourceRecord == null) {
|
||||
throw new SecurityException("Called with bad activity token: " + resultTo);
|
||||
}
|
||||
if (sourceRecord.app == null) {
|
||||
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, we want the sourceRecord from the delegator
|
||||
// activity that requested this token.
|
||||
sourceToken = mStartActivitySources.remove(permissionToken);
|
||||
if (sourceToken == null) {
|
||||
// Invalid permissionToken, check if it recently expired.
|
||||
// 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);
|
||||
@@ -1578,33 +1586,21 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// This method was called directly by the source.
|
||||
sourceToken = resultTo;
|
||||
}
|
||||
|
||||
sourceRecord = ActivityRecord.isInAnyTask(sourceToken);
|
||||
if (sourceRecord == null) {
|
||||
throw new SecurityException("Called with bad activity token: " + sourceToken);
|
||||
}
|
||||
if (sourceRecord.app == null) {
|
||||
throw new SecurityException("Called without a process attached to activity");
|
||||
}
|
||||
|
||||
// Whether called directly or from a delegate, the source activity must be from the
|
||||
// android package.
|
||||
if (!sourceRecord.info.packageName.equals("android")) {
|
||||
throw new SecurityException("Must be called from an activity that is "
|
||||
+ "declared in the android package");
|
||||
}
|
||||
|
||||
if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
|
||||
// This is still okay, as long as this activity is running under the
|
||||
// uid of the original calling activity.
|
||||
if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
|
||||
throw new SecurityException(
|
||||
"Calling activity in uid " + sourceRecord.app.mUid
|
||||
+ " must be system uid or original calling uid "
|
||||
+ sourceRecord.launchedFromUid);
|
||||
// Whether called directly or from a delegate, the source activity must be from the
|
||||
// android package.
|
||||
if (!sourceRecord.info.packageName.equals("android")) {
|
||||
throw new SecurityException("Must be called from an activity that is "
|
||||
+ "declared in the android package");
|
||||
}
|
||||
if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
|
||||
// This is still okay, as long as this activity is running under the
|
||||
// uid of the original calling activity.
|
||||
if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) {
|
||||
throw new SecurityException(
|
||||
"Calling activity in uid " + sourceRecord.app.mUid
|
||||
+ " must be system uid or original calling uid "
|
||||
+ sourceRecord.launchedFromUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ignoreTargetSecurity) {
|
||||
|
||||
Reference in New Issue
Block a user