summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java5
-rw-r--r--core/java/android/app/ActivityManager.java7
-rw-r--r--core/java/android/app/Instrumentation.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java23
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java22
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;