diff options
5 files changed, 43 insertions, 18 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index fa28143..8ba2a5a 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -857,6 +857,11 @@ public class Am extends BaseCommand { "Error: Activity not started, voice control not allowed for: " + intent); break; + case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: + out.println( + "Error: Not allowed to start background user activity" + + " that shouldn't be displayed for all users."); + break; default: out.println( "Error: Activity not started, unknown error code " + res); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 134ecdd..576a046 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -86,6 +86,13 @@ public class ActivityManager { public static final String META_HOME_ALTERNATE = "android.app.home.alternate"; /** + * Result for IActivityManager.startActivity: trying to start a background user + * activity that shouldn't be displayed for all users. + * @hide + */ + public static final int START_NOT_CURRENT_USER_ACTIVITY = -8; + + /** * Result for IActivityManager.startActivity: trying to start an activity under voice * control when that activity does not support the VOICE category. * @hide diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index fc96464..b77dec5 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1797,6 +1797,10 @@ public class Instrumentation { case ActivityManager.START_NOT_VOICE_COMPATIBLE: throw new SecurityException( "Starting under voice control not allowed for: " + intent); + case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: + throw new SecurityException( + "Not allowed to start background user activity that shouldn't be" + + " displayed for all users."); default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 5b1543e..b22e390 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -363,19 +363,9 @@ final class ActivityStack { mOverrideConfig = Configuration.EMPTY; } - /** - * Checks whether the userid is a profile of the current user. - */ - private boolean isCurrentProfileLocked(int userId) { - if (userId == mCurrentUser) return true; - for (int i = 0; i < mService.mCurrentProfileIds.length; i++) { - if (mService.mCurrentProfileIds[i] == userId) return true; - } - return false; - } - boolean okToShowLocked(ActivityRecord r) { - return isCurrentProfileLocked(r.userId) || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0; + return mStackSupervisor.isCurrentProfileLocked(r.userId) + || (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0; } final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) { @@ -619,7 +609,8 @@ final class ActivityStack { for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); - final boolean notCurrentUserTask = !isCurrentProfileLocked(task.userId); + final boolean notCurrentUserTask = + !mStackSupervisor.isCurrentProfileLocked(task.userId); final ArrayList<ActivityRecord> activities = task.mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { @@ -655,7 +646,7 @@ final class ActivityStack { // NOTE: If {@link TaskRecord#topRunningActivityLocked} return is not null then it is // okay to show the activity when locked. - if (isCurrentProfileLocked(task.userId) + if (mStackSupervisor.isCurrentProfileLocked(task.userId) || task.topRunningActivityLocked(null) != null) { if (DEBUG_TASKS) Slog.d(TAG_TASKS, "switchUserLocked: stack=" + getStackId() + " moving " + task + " to top"); @@ -2026,11 +2017,11 @@ final class ActivityStack { final boolean notShownWhenLocked = (newActivity != null && (newActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) || (newActivity == null && task.topRunningActivityLocked(null) == null); - if (!isCurrentProfileLocked(task.userId) && notShownWhenLocked) { + if (!mStackSupervisor.isCurrentProfileLocked(task.userId) && notShownWhenLocked) { // Put non-current user tasks below current user tasks. while (--taskNdx >= 0) { final TaskRecord tmpTask = mTaskHistory.get(taskNdx); - if (!isCurrentProfileLocked(tmpTask.userId) + if (!mStackSupervisor.isCurrentProfileLocked(tmpTask.userId) || tmpTask.topRunningActivityLocked(null) == null) { break; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 58bdc28..1585f61 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -24,6 +24,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; +import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS; import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static com.android.server.am.ActivityManagerDebugConfig.*; @@ -1381,8 +1382,9 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; + if (err == ActivityManager.START_SUCCESS) { - final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0; Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false) + "} from uid " + callingUid + " on display " + (container == null ? (mFocusedStack == null ? @@ -1406,7 +1408,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final int launchFlags = intent.getFlags(); - if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { + if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { // Transfer the result target from the source activity to the new // one being started, including any failures. if (requestCode >= 0) { @@ -1450,6 +1452,13 @@ public final class ActivityStackSupervisor implements DisplayListener { err = ActivityManager.START_CLASS_NOT_FOUND; } + if (err == ActivityManager.START_SUCCESS + && !isCurrentProfileLocked(userId) + && (aInfo.flags & FLAG_SHOW_FOR_ALL_USERS) == 0) { + // Trying to launch a background activity that doesn't show for all users. + err = ActivityManager.START_NOT_CURRENT_USER_ACTIVITY; + } + if (err == ActivityManager.START_SUCCESS && sourceRecord != null && sourceRecord.task.voiceSession != null) { // If this activity is being launched as part of a voice session, we need @@ -3231,6 +3240,15 @@ public final class ActivityStackSupervisor implements DisplayListener { mStartingBackgroundUsers.add(uss); } + /** Checks whether the userid is a profile of the current user. */ + boolean isCurrentProfileLocked(int userId) { + if (userId == mCurrentUser) return true; + for (int i = 0; i < mService.mCurrentProfileIds.length; i++) { + if (mService.mCurrentProfileIds[i] == userId) return true; + } + return false; + } + final ArrayList<ActivityRecord> processStoppingActivitiesLocked(boolean remove) { ArrayList<ActivityRecord> stops = null; |