* an activity and associated task and stack.
*/
class ActivityStarter {
+ public static final int PID_NULL = 0;
+
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
TaskRecord inTask, String reason) {
+ return startActivityMayWait(caller, callingUid, PID_NULL, UserHandle.USER_NULL,
+ callingPackage, intent, resolvedType, voiceSession, voiceInteractor, resultTo,
+ resultWho, requestCode, startFlags, profilerInfo, outResult, globalConfig, bOptions,
+ ignoreTargetSecurity, userId, inTask, reason);
+ }
+
+ final int startActivityMayWait(IApplicationThread caller, int callingUid,
+ int requestRealCallingPid, int requestRealCallingUid,
+ String callingPackage, Intent intent, String resolvedType,
+ IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
+ IBinder resultTo, String resultWho, int requestCode, int startFlags,
+ ProfilerInfo profilerInfo, WaitResult outResult,
+ Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
+ TaskRecord inTask, String reason) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
ActivityOptions options = ActivityOptions.fromBundle(bOptions);
synchronized (mService) {
- final int realCallingPid = Binder.getCallingPid();
- final int realCallingUid = Binder.getCallingUid();
+
+ final int realCallingPid = requestRealCallingPid != PID_NULL
+ ? requestRealCallingPid
+ : Binder.getCallingPid();
+ final int realCallingUid = requestRealCallingUid != UserHandle.USER_NULL
+ ? requestRealCallingUid
+ : Binder.getCallingUid();
+
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
Intent[] intents, String[] resolvedTypes, IBinder resultTo,
Bundle bOptions, int userId, String reason) {
+ return startActivities(caller, callingUid, PID_NULL, UserHandle.USER_NULL, callingPackage,
+ intents, resolvedTypes, resultTo, bOptions, userId, reason);
+ }
+
+ final int startActivities(IApplicationThread caller, int callingUid,
+ int incomingRealCallingPid, int incomingRealCallingUid, String callingPackage,
+ Intent[] intents, String[] resolvedTypes, IBinder resultTo,
+ Bundle bOptions, int userId, String reason) {
if (intents == null) {
throw new NullPointerException("intents is null");
}
throw new IllegalArgumentException("intents are length different than resolvedTypes");
}
- final int realCallingPid = Binder.getCallingPid();
- final int realCallingUid = Binder.getCallingUid();
+ final int realCallingPid = incomingRealCallingPid != PID_NULL
+ ? incomingRealCallingPid
+ : Binder.getCallingPid();
+
+ final int realCallingUid = incomingRealCallingUid != UserHandle.USER_NULL
+ ? incomingRealCallingUid
+ : Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
} else {
callingPid = callingUid = -1;
}
+ boolean forceNewTask = false;
+ final int filterCallingUid = callingUid >= 0 ? callingUid : realCallingUid;
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mService) {
// Don't modify the client's object!
intent = new Intent(intent);
+ if (forceNewTask) {
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
return res;
}
- resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
+ final ActivityRecord started = outActivity[0];
+ if (started != null && started.getUid() == filterCallingUid) {
+ // Only the started activity which has the same uid as the source caller can
+ // be the caller of next activity.
+ resultTo = started.appToken;
+ forceNewTask = false;
+ } else {
+ // Different apps not adjacent to the caller are forced to be new task.
+ resultTo = null;
+ forceNewTask = true;
+ }
}
}
} finally {