summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Craig Mautner <cmautner@google.com> 2015-05-13 13:06:11 -0700
committer Craig Mautner <cmautner@google.com> 2015-05-14 12:54:23 -0700
commite0570201f59342ef02412ece2f179ef42441a032 (patch)
treef98d7c5b6790d91515832387f5d98932b74a38a1
parent0125d76fa37d26a29f06371ff349546e21cd3f4d (diff)
Lock top task if whitelisting arrives after start.
If the DevicePolicyManagerService updates the whitelist after a task in the whitelist has started then the task won't have started locked. When the updated whitelist arrives this change automatically locks the topmost task if it is in the whitelist. Also more locktask debugging. Fixes bug 21031298. Change-Id: I2494af6f2819ca91bc01abc5decb3d1adc088226
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerDebugConfig.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java46
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java16
4 files changed, 64 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index d64e39f79e72..925fae0a3431 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -51,6 +51,7 @@ class ActivityManagerDebugConfig {
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
+ static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
static final boolean DEBUG_LRU = DEBUG_ALL || false;
static final boolean DEBUG_MU = DEBUG_ALL || false;
static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
@@ -82,6 +83,7 @@ class ActivityManagerDebugConfig {
static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
static final String POSTFIX_LOCKSCREEN = (APPEND_CATEGORY_NAME) ? "_LOCKSCREEN" : "";
+ static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LOCKTASK" : "";
static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
static final String POSTFIX_MU = "_MU";
static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : "";
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9ffb874d2436..215839515a4e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -265,6 +265,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_LRU = TAG + POSTFIX_LRU;
private static final String TAG_MU = TAG + POSTFIX_MU;
private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
@@ -8762,6 +8763,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException("updateLockTaskPackage called from non-system process");
}
synchronized (this) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
mLockTaskPackages.put(userId, packages);
mStackSupervisor.onLockTaskPackagesUpdatedLocked();
}
@@ -8769,6 +8771,7 @@ public final class ActivityManagerService extends ActivityManagerNative
void startLockTaskModeLocked(TaskRecord task) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
return;
}
@@ -8785,6 +8788,7 @@ public final class ActivityManagerService extends ActivityManagerNative
task.mLockTaskUid = callingUid;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
// startLockTask() called by app and task mode is lockTaskModeDefault.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
StatusBarManagerInternal statusBarManager =
LocalServices.getService(StatusBarManagerInternal.class);
if (statusBarManager != null) {
@@ -8797,6 +8801,8 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new IllegalArgumentException("Invalid task, not in foreground");
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
+ "Locking fully");
mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
ActivityManager.LOCK_TASK_MODE_PINNED :
ActivityManager.LOCK_TASK_MODE_LOCKED,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 54ea6d76782c..f30482852108 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -117,6 +117,7 @@ import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -124,6 +125,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -1183,7 +1185,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
final TaskRecord task = r.task;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
- setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "lockTaskLaunchMode attribute");
+ setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE");
}
final ActivityStack stack = task.stack;
@@ -3327,6 +3329,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
+ private String lockTaskModeToString() {
+ switch (mLockTaskModeState) {
+ case LOCK_TASK_MODE_LOCKED:
+ return "LOCKED";
+ case LOCK_TASK_MODE_PINNED:
+ return "PINNED";
+ case LOCK_TASK_MODE_NONE:
+ return "NONE";
+ default: return "unknown=" + mLockTaskModeState;
+ }
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
@@ -3334,7 +3348,16 @@ public final class ActivityStackSupervisor implements DisplayListener {
pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
- pw.print(prefix); pw.println("mLockTaskModeTasks" + mLockTaskModeTasks);
+ pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
+ final SparseArray<String[]> packages = mService.mLockTaskPackages;
+ if (packages.size() > 0) {
+ pw.println(" mLockTaskPackages (userId:packages)=");
+ for (int i = 0; i < packages.size(); ++i) {
+ pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
+ pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
+ }
+ }
+ pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
@@ -3654,6 +3677,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
void removeLockedTaskLocked(final TaskRecord task) {
if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) {
// Last one.
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
+ " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
final Message lockTaskMsg = Message.obtain();
lockTaskMsg.arg1 = task.userId;
lockTaskMsg.what = LOCK_TASK_END_MSG;
@@ -3679,20 +3704,26 @@ public final class ActivityStackSupervisor implements DisplayListener {
removeLockedTaskLocked(lockedTask);
if (!mLockTaskModeTasks.isEmpty()) {
// There are locked tasks remaining, can only finish this task, not unlock it.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Tasks remaining, can't unlock");
lockedTask.performClearTaskLocked();
resumeTopActivitiesLocked();
return;
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
return;
}
// Should have already been checked, but do it again.
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Can't lock due to auth");
return;
}
if (isLockTaskModeViolation(task)) {
- Slog.e(TAG, "setLockTaskMode: Attempt to start an unauthorized lock task.");
+ Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
return;
}
@@ -3706,6 +3737,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
mHandler.sendMessage(lockTaskMsg);
}
// Add it or move it to the top.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
+ " Callers=" + Debug.getCallers(4));
mLockTaskModeTasks.remove(task);
mLockTaskModeTasks.add(task);
@@ -3759,6 +3792,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
stack.onLockTaskPackagesUpdatedLocked();
}
}
+ final ActivityRecord r = topRunningActivityLocked();
+ final TaskRecord task = r != null ? r.task : null;
+ if (mLockTaskModeTasks.isEmpty() && task != null
+ && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
+ // This task must have just been authorized.
+ setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated");
+ }
if (didSomething) {
resumeTopActivitiesLocked();
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5e9f2b0b321a..f653e9eeaf24 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -63,6 +63,7 @@ import java.util.ArrayList;
final class TaskRecord {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
static final String ATTR_TASKID = "task_id";
@@ -134,12 +135,11 @@ final class TaskRecord {
/** Can't be put in lockTask mode. */
final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
- /** Can enter lockTask with user approval if not already in lockTask. */
+ /** Can enter lockTask with user approval. Can never start over existing lockTask task. */
final static int LOCK_TASK_AUTH_PINNABLE = 1;
/** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
- /** Enters LOCK_TASK_MODE_LOCKED via startLockTask(), enters LOCK_TASK_MODE_PINNED from
- * Overview. Can start over existing lockTask task. */
+ /** Can enter lockTask with user approval. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_WHITELISTED = 3;
int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
@@ -744,21 +744,31 @@ final class TaskRecord {
void setLockTaskAuth() {
switch (mLockTaskMode) {
case LOCK_TASK_LAUNCH_MODE_DEFAULT:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "WHITELISTED" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_NEVER:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_ALWAYS:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;