From 2c11dc99632354836281cbe3000b911e72a30d14 Mon Sep 17 00:00:00 2001 From: Tony Mak Date: Mon, 18 Apr 2016 11:43:28 +0100 Subject: [PATCH] User action should only stop lock task mode if it is in pinned mode There are two lock task modes: pinned and locked. Pinned mode is the one that one that need users action to accept the pinned request. For locked mode, it is triggered by DPM. We should not allow user to stop locked mode by user action. Please notice that it does not happen before because the action to dismiss lock task mode is pressing both back and recents button and recents button is hidden in locked mode. But it becomes a problem after the user action is changed to long pressing back button. So changes are as follows: 1. Only stop lock task mode if it is pinned mode in stopLockTaskModeOnCurrent 2. Remove the permission checking in stopLockTaskModeOnCurrent. I can't see the reason we are having this because there is no permission checking to in stopLockTaskMode when it is in pinned mode. So you can always stop pinned lock task mode anyway by calling stopLockTaskMode directly. Bug: 28184751 Change-Id: I610cc1dfade7737e0b08fc9a13dad29e62e09a32 --- .../server/am/ActivityManagerService.java | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 40430b4b3f3e8..72d7521e94bf8 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9968,19 +9968,25 @@ public final class ActivityManagerService extends ActivityManagerNative final int callingUid = Binder.getCallingUid(); final int lockTaskUid = lockTask.mLockTaskUid; - // Ensure the same caller for startLockTaskMode and stopLockTaskMode. - // It is possible lockTaskMode was started by the system process because - // android:lockTaskMode is set to a locking value in the application manifest instead of - // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will - // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead. - if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED && - callingUid != lockTaskUid - && (lockTaskUid != 0 - || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) { - throw new SecurityException("Invalid uid, expected " + lockTaskUid - + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid); + final int lockTaskModeState = mStackSupervisor.getLockTaskModeState(); + if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) { + // Done. + return; + } else { + // Ensure the same caller for startLockTaskMode and stopLockTaskMode. + // It is possible lockTaskMode was started by the system process because + // android:lockTaskMode is set to a locking value in the application manifest + // instead of the app calling startLockTaskMode. In this case + // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the + // {@link TaskRecord.effectiveUid} instead. Also caller with + // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task. + if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED + && callingUid != lockTaskUid + && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) { + throw new SecurityException("Invalid uid, expected " + lockTaskUid + + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid); + } } - long ident = Binder.clearCallingIdentity(); try { Log.d(TAG, "stopLockTaskMode"); @@ -9994,15 +10000,16 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * This API should be called by SystemUI only when user perform certain action to dismiss + * lock task mode. We should only dismiss pinned lock task mode in this case. + */ @Override public void stopSystemLockTaskMode() throws RemoteException { - enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode"); - // This makes inner call to look as if it was initiated by system. - long ident = Binder.clearCallingIdentity(); - try { + if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) { stopLockTaskMode(); - } finally { - Binder.restoreCallingIdentity(ident); + } else { + mStackSupervisor.showLockTaskToast(); } }