Loading core/java/android/app/admin/DevicePolicyManager.java +3 −0 Original line number Diff line number Diff line Loading @@ -3975,6 +3975,9 @@ public class DevicePolicyManager { * <p>Any packages that shares uid with an allowed package will also be allowed * to activate lock task. * * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task * package list results in locked tasks belonging to those packages to be finished. * * This function can only be called by the device owner. * @param packages The list of packages allowed to enter lock task mode * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Loading core/res/res/values/attrs_manifest.xml +12 −9 Original line number Diff line number Diff line Loading @@ -1058,18 +1058,20 @@ lockTask mode is disabled. <p>While in lockTask mode with multiple permitted tasks running, each launched task is permitted to finish, transitioning to the previous locked task, until there is only one task remaining. At that point the last task running is not permitted to finish. --> task remaining. At that point the last task running is not permitted to finish, unless it uses the value always. --> <attr name="lockTaskMode"> <!-- This is the default value. Tasks will not launch into lockTask mode but can be placed there by calling {@link android.app.Activity#startLockTask}. If a task with this mode has been whitelisted using {@link android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling startLockTask will enter lockTask mode immediately, otherwise the user will be presented with a dialog to approve entering lockTask mode. android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling {@link android.app.Activity#startLockTask} will enter lockTask mode immediately, otherwise the user will be presented with a dialog to approve entering pinned mode. <p>If the system is already in lockTask mode when a new task rooted at this activity is launched that task will or will not start depending on whether the package of this activity has been whitelisted. <p>Tasks rooted at this activity can only exit lockTask mode using stopLockTask(). --> <p>Tasks rooted at this activity can only exit lockTask mode using {@link android.app.Activity#stopLockTask}. --> <enum name="normal" value="0"/> <!-- Tasks will not launch into lockTask mode and cannot be placed there using {@link android.app.Activity#startLockTask} or be pinned from the Overview screen. Loading @@ -1082,16 +1084,17 @@ <!-- Tasks rooted at this activity will always launch into lockTask mode. If the system is already in lockTask mode when this task is launched then the new task will be launched on top of the current task. Tasks launched in this mode are capable of exiting lockTask mode using finish(), whereas tasks entering lockTask mode using startLockTask() must use stopLockTask() to exit. lockTask mode using {@link android.app.Activity#finish()}. <p>Note: This mode is only available to system and privileged applications. Non-privileged apps with this value will be treated as normal. --> <enum name="always" value="2"/> <!-- If the DevicePolicyManager (DPM) authorizes this package ({@link android.app.admin.DevicePolicyManager#setLockTaskPackages}) then this mode is identical to always. If the DPM does not authorize this package then this mode is identical to normal. --> identical to always, except that the activity needs to call {@link android.app.Activity#stopLockTask} before being able to finish if it is the last locked task. If the DPM does not authorize this package then this mode is identical to normal. --> <enum name="if_whitelisted" value="3"/> </attr> <!-- When set installer will extract native libraries. If set to false Loading services/core/java/com/android/server/am/ActivityManagerService.java +7 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; Loading Loading @@ -4197,9 +4198,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (rootR == null) { Slog.w(TAG, "Finishing task with all activities already finished"); } // Do not allow task to finish if last task in lockTask mode. Launchable apps can // finish themselves. if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r && // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can // finish. if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && mStackSupervisor.isLastLockedTask(tr)) { Slog.i(TAG, "Not finishing task in lock task mode"); mStackSupervisor.showLockTaskToast(); Loading Loading @@ -4361,9 +4362,10 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } // Do not allow the last non-launchable task to finish in Lock Task mode. // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps // can finish. final TaskRecord task = r.task; if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { mStackSupervisor.showLockTaskToast(); return false; Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; import static com.android.server.am.ActivityStack.ActivityState.*; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; Loading Loading @@ -1179,7 +1180,8 @@ public final class ActivityStackSupervisor implements DisplayListener { mService.updateOomAdjLocked(); final TaskRecord task = r.task; if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) { setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false); } Loading Loading @@ -3785,6 +3787,7 @@ public final class ActivityStackSupervisor implements DisplayListener { switch (lockTaskAuth) { case LOCK_TASK_AUTH_DONT_LOCK: return !mLockTaskModeTasks.isEmpty(); case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: case LOCK_TASK_AUTH_LAUNCHABLE: case LOCK_TASK_AUTH_WHITELISTED: return false; Loading @@ -3801,12 +3804,14 @@ public final class ActivityStackSupervisor implements DisplayListener { boolean didSomething = false; for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); if (lockedTask.mLockTaskMode != LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED) { continue; } final boolean wasLaunchable = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE; final boolean wasWhitelisted = (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); lockedTask.setLockTaskAuth(); if (wasLaunchable && lockedTask.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE) { final boolean isWhitelisted = (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); if (wasWhitelisted && !isWhitelisted) { // Lost whitelisting authorization. End it now. if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); Loading services/core/java/com/android/server/am/TaskRecord.java +14 −6 Original line number Diff line number Diff line Loading @@ -134,12 +134,15 @@ 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. Can never start over existing lockTask task. */ /** Can enter app pinning 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; /** Can enter lockTask with user approval. Can start over existing lockTask task. */ /** Can enter lockTask without user approval. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_WHITELISTED = 3; /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing * lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4; int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE; int mLockTaskUid = -1; // The uid of the application that called startLockTask(). Loading Loading @@ -747,11 +750,18 @@ final class TaskRecord { case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE"; case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE"; case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED"; case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV"; default: return "unknown=" + mLockTaskAuth; } } void setLockTaskAuth() { if (!mPrivileged && (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS || mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) { // Non-priv apps are not allowed to use always or never, fall back to default mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; } switch (mLockTaskMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: mLockTaskAuth = isLockTaskWhitelistedLocked() ? Loading @@ -759,13 +769,11 @@ final class TaskRecord { break; case LOCK_TASK_LAUNCH_MODE_NEVER: mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE; mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; break; case LOCK_TASK_LAUNCH_MODE_ALWAYS: mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE; mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; break; case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +3 −0 Original line number Diff line number Diff line Loading @@ -3975,6 +3975,9 @@ public class DevicePolicyManager { * <p>Any packages that shares uid with an allowed package will also be allowed * to activate lock task. * * From {@link android.os.Build.VERSION_CODES#MNC} removing packages from the lock task * package list results in locked tasks belonging to those packages to be finished. * * This function can only be called by the device owner. * @param packages The list of packages allowed to enter lock task mode * @param admin Which {@link DeviceAdminReceiver} this request is associated with. Loading
core/res/res/values/attrs_manifest.xml +12 −9 Original line number Diff line number Diff line Loading @@ -1058,18 +1058,20 @@ lockTask mode is disabled. <p>While in lockTask mode with multiple permitted tasks running, each launched task is permitted to finish, transitioning to the previous locked task, until there is only one task remaining. At that point the last task running is not permitted to finish. --> task remaining. At that point the last task running is not permitted to finish, unless it uses the value always. --> <attr name="lockTaskMode"> <!-- This is the default value. Tasks will not launch into lockTask mode but can be placed there by calling {@link android.app.Activity#startLockTask}. If a task with this mode has been whitelisted using {@link android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling startLockTask will enter lockTask mode immediately, otherwise the user will be presented with a dialog to approve entering lockTask mode. android.app.admin.DevicePolicyManager#setLockTaskPackages} then calling {@link android.app.Activity#startLockTask} will enter lockTask mode immediately, otherwise the user will be presented with a dialog to approve entering pinned mode. <p>If the system is already in lockTask mode when a new task rooted at this activity is launched that task will or will not start depending on whether the package of this activity has been whitelisted. <p>Tasks rooted at this activity can only exit lockTask mode using stopLockTask(). --> <p>Tasks rooted at this activity can only exit lockTask mode using {@link android.app.Activity#stopLockTask}. --> <enum name="normal" value="0"/> <!-- Tasks will not launch into lockTask mode and cannot be placed there using {@link android.app.Activity#startLockTask} or be pinned from the Overview screen. Loading @@ -1082,16 +1084,17 @@ <!-- Tasks rooted at this activity will always launch into lockTask mode. If the system is already in lockTask mode when this task is launched then the new task will be launched on top of the current task. Tasks launched in this mode are capable of exiting lockTask mode using finish(), whereas tasks entering lockTask mode using startLockTask() must use stopLockTask() to exit. lockTask mode using {@link android.app.Activity#finish()}. <p>Note: This mode is only available to system and privileged applications. Non-privileged apps with this value will be treated as normal. --> <enum name="always" value="2"/> <!-- If the DevicePolicyManager (DPM) authorizes this package ({@link android.app.admin.DevicePolicyManager#setLockTaskPackages}) then this mode is identical to always. If the DPM does not authorize this package then this mode is identical to normal. --> identical to always, except that the activity needs to call {@link android.app.Activity#stopLockTask} before being able to finish if it is the last locked task. If the DPM does not authorize this package then this mode is identical to normal. --> <enum name="if_whitelisted" value="3"/> </attr> <!-- When set installer will extract native libraries. If set to false Loading
services/core/java/com/android/server/am/ActivityManagerService.java +7 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; Loading Loading @@ -4197,9 +4198,9 @@ public final class ActivityManagerService extends ActivityManagerNative if (rootR == null) { Slog.w(TAG, "Finishing task with all activities already finished"); } // Do not allow task to finish if last task in lockTask mode. Launchable apps can // finish themselves. if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && rootR == r && // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can // finish. if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && mStackSupervisor.isLastLockedTask(tr)) { Slog.i(TAG, "Not finishing task in lock task mode"); mStackSupervisor.showLockTaskToast(); Loading Loading @@ -4361,9 +4362,10 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } // Do not allow the last non-launchable task to finish in Lock Task mode. // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps // can finish. final TaskRecord task = r.task; if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE && if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { mStackSupervisor.showLockTaskToast(); return false; Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +11 −6 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE; import static com.android.server.am.ActivityStack.ActivityState.*; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED; Loading Loading @@ -1179,7 +1180,8 @@ public final class ActivityStackSupervisor implements DisplayListener { mService.updateOomAdjLocked(); final TaskRecord task = r.task; if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE || task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) { setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false); } Loading Loading @@ -3785,6 +3787,7 @@ public final class ActivityStackSupervisor implements DisplayListener { switch (lockTaskAuth) { case LOCK_TASK_AUTH_DONT_LOCK: return !mLockTaskModeTasks.isEmpty(); case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: case LOCK_TASK_AUTH_LAUNCHABLE: case LOCK_TASK_AUTH_WHITELISTED: return false; Loading @@ -3801,12 +3804,14 @@ public final class ActivityStackSupervisor implements DisplayListener { boolean didSomething = false; for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx); if (lockedTask.mLockTaskMode != LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED) { continue; } final boolean wasLaunchable = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE; final boolean wasWhitelisted = (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); lockedTask.setLockTaskAuth(); if (wasLaunchable && lockedTask.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE) { final boolean isWhitelisted = (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) || (lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED); if (wasWhitelisted && !isWhitelisted) { // Lost whitelisting authorization. End it now. if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " + lockedTask + " mLockTaskAuth=" + lockedTask.lockTaskAuthToString()); Loading
services/core/java/com/android/server/am/TaskRecord.java +14 −6 Original line number Diff line number Diff line Loading @@ -134,12 +134,15 @@ 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. Can never start over existing lockTask task. */ /** Can enter app pinning 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; /** Can enter lockTask with user approval. Can start over existing lockTask task. */ /** Can enter lockTask without user approval. Can start over existing lockTask task. */ final static int LOCK_TASK_AUTH_WHITELISTED = 3; /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing * lockTask task. */ final static int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4; int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE; int mLockTaskUid = -1; // The uid of the application that called startLockTask(). Loading Loading @@ -747,11 +750,18 @@ final class TaskRecord { case LOCK_TASK_AUTH_PINNABLE: return "LOCK_TASK_AUTH_PINNABLE"; case LOCK_TASK_AUTH_LAUNCHABLE: return "LOCK_TASK_AUTH_LAUNCHABLE"; case LOCK_TASK_AUTH_WHITELISTED: return "LOCK_TASK_AUTH_WHITELISTED"; case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: return "LOCK_TASK_AUTH_LAUNCHABLE_PRIV"; default: return "unknown=" + mLockTaskAuth; } } void setLockTaskAuth() { if (!mPrivileged && (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS || mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) { // Non-priv apps are not allowed to use always or never, fall back to default mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; } switch (mLockTaskMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: mLockTaskAuth = isLockTaskWhitelistedLocked() ? Loading @@ -759,13 +769,11 @@ final class TaskRecord { break; case LOCK_TASK_LAUNCH_MODE_NEVER: mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE; mLockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; break; case LOCK_TASK_LAUNCH_MODE_ALWAYS: mLockTaskAuth = mPrivileged ? LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE; mLockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; break; case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED: Loading