OSDN Git Service

RESTRICT AUTOMERGE Create separated tasks for different apps from startActivities
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityStarter.java
index 7575f71..aec552d 100644 (file)
@@ -136,6 +136,8 @@ import java.util.Date;
  * 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;
@@ -677,6 +679,20 @@ class ActivityStarter {
             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");
@@ -730,8 +746,14 @@ class ActivityStarter {
 
         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;
@@ -883,6 +905,14 @@ class ActivityStarter {
     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");
         }
@@ -893,8 +923,13 @@ class ActivityStarter {
             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) {
@@ -905,6 +940,8 @@ class ActivityStarter {
         } else {
             callingPid = callingUid = -1;
         }
+        boolean forceNewTask = false;
+        final int filterCallingUid = callingUid >= 0 ? callingUid : realCallingUid;
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mService) {
@@ -924,6 +961,9 @@ class ActivityStarter {
 
                     // 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,
@@ -949,7 +989,17 @@ class ActivityStarter {
                         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 {