Add lock-to-app mode
Added a dialog that shows when app has not been authorized by
DevicePolicyManager.isLockTaskAuthorized. This allows any app
to trigger lock-to-app mode. This same dialog is used when
startLockTaskOnCurrent is triggered by the recents long-press.
Can exit the mode by long-pressing recents again.
Keyguard is disabled when lock-to-app is active.
This CL also prevents apps from finishing when they are the root
task in a lock task TaskRecord.
Change-Id: Ib54d858e570cccf6bfd986958868e15f49bcef75
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9264186..6f2996c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -79,6 +79,8 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.service.voice.IVoiceInteractionSession;
import android.util.EventLog;
import android.util.Slog;
@@ -142,6 +144,8 @@
private final static String VIRTUAL_DISPLAY_BASE_NAME = "ActivityViewVirtualDisplay";
+ private static final String LOCK_TASK_TAG = "Lock-to-App";
+
/** Status Bar Service **/
private IBinder mToken = new Binder();
private IStatusBarService mStatusBarService;
@@ -255,6 +259,10 @@
/** If non-null then the task specified remains in front and no other tasks may be started
* until the task exits or #stopLockTaskMode() is called. */
TaskRecord mLockTaskModeTask;
+ /**
+ * Notifies the user when entering/exiting lock-task.
+ */
+ private LockTaskNotify mLockTaskNotify;
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
@@ -3004,7 +3012,7 @@
return list;
}
- void setLockTaskModeLocked(TaskRecord task) {
+ void setLockTaskModeLocked(TaskRecord task, boolean showHomeRecents) {
if (task == null) {
// Take out of lock task mode if necessary
if (mLockTaskModeTask != null) {
@@ -3028,6 +3036,7 @@
lockTaskMsg.obj = mLockTaskModeTask.intent.getComponent().getPackageName();
lockTaskMsg.arg1 = mLockTaskModeTask.userId;
lockTaskMsg.what = LOCK_TASK_START_MSG;
+ lockTaskMsg.arg2 = showHomeRecents ? 1 : 0;
mHandler.sendMessage(lockTaskMsg);
}
@@ -3130,15 +3139,24 @@
case LOCK_TASK_START_MSG: {
// When lock task starts, we disable the status bars.
try {
- if (getStatusBarService() != null) {
- getStatusBarService().disable
- (StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK,
- mToken, mService.mContext.getPackageName());
+ if (mLockTaskNotify == null) {
+ mLockTaskNotify = new LockTaskNotify(mService.mContext);
}
+ mLockTaskNotify.show(true);
+ if (getStatusBarService() != null) {
+ int flags =
+ StatusBarManager.DISABLE_MASK ^ StatusBarManager.DISABLE_BACK;
+ if (msg.arg2 != 0) {
+ flags ^= StatusBarManager.DISABLE_HOME
+ | StatusBarManager.DISABLE_RECENT;
+ }
+ getStatusBarService().disable(flags, mToken,
+ mService.mContext.getPackageName());
+ }
+ mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(true,
- (String)msg.obj,
- msg.arg1);
+ (String)msg.obj, msg.arg1);
}
} catch (RemoteException ex) {
throw new RuntimeException(ex);
@@ -3147,15 +3165,29 @@
case LOCK_TASK_END_MSG: {
// When lock task ends, we enable the status bars.
try {
- if (getStatusBarService() != null) {
- getStatusBarService().disable
- (StatusBarManager.DISABLE_NONE,
- mToken, mService.mContext.getPackageName());
- }
+ if (getStatusBarService() != null) {
+ getStatusBarService().disable(StatusBarManager.DISABLE_NONE, mToken,
+ mService.mContext.getPackageName());
+ }
+ mWindowManager.reenableKeyguard(mToken);
if (getDevicePolicyManager() != null) {
getDevicePolicyManager().notifyLockTaskModeChanged(false, null,
msg.arg1);
}
+ if (mLockTaskNotify == null) {
+ mLockTaskNotify = new LockTaskNotify(mService.mContext);
+ }
+ mLockTaskNotify.show(false);
+ try {
+ boolean shouldLockKeyguard = Settings.System.getInt(
+ mService.mContext.getContentResolver(),
+ Settings.System.LOCK_TO_APP_EXIT_LOCKED) != 0;
+ if (shouldLockKeyguard) {
+ mWindowManager.lockNow(null);
+ }
+ } catch (SettingNotFoundException e) {
+ // No setting, don't lock.
+ }
} catch (RemoteException ex) {
throw new RuntimeException(ex);
}