blob: 3b25b742e3272829d3145e8711e7204f4c861457 [file] [log] [blame]
Benjamin Franza83859f2017-07-03 16:34:14 +01001/*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Benjamin Franza83859f2017-07-03 16:34:14 +010018
19import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
20import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
21import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070022import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Benjamin Franza83859f2017-07-03 16:34:14 +010023import static android.content.Context.DEVICE_POLICY_SERVICE;
24import static android.content.Context.STATUS_BAR_SERVICE;
Charles He858f1322017-11-27 17:11:04 -080025import static android.content.Intent.ACTION_CALL_EMERGENCY;
Yuhan Zhaof3b3d412020-01-24 23:37:13 +000026import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
27import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
Benjamin Franza83859f2017-07-03 16:34:14 +010028import static android.os.UserHandle.USER_ALL;
Amith Yamasani7cbbf2222017-08-30 14:22:37 -070029import static android.os.UserHandle.USER_CURRENT;
Charles He858f1322017-11-27 17:11:04 -080030import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
Benjamin Franza83859f2017-07-03 16:34:14 +010031import static android.view.Display.DEFAULT_DISPLAY;
Charles He520b2832017-09-02 15:27:16 +010032
Wale Ogunwale59507092018-10-29 09:00:30 -070033import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
34import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
35import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
36import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Louis Changcdec0802019-11-11 11:45:07 +080037import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK;
38import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE;
39import static com.android.server.wm.Task.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
40import static com.android.server.wm.Task.LOCK_TASK_AUTH_PINNABLE;
41import static com.android.server.wm.Task.LOCK_TASK_AUTH_WHITELISTED;
Benjamin Franza83859f2017-07-03 16:34:14 +010042
43import android.annotation.NonNull;
44import android.annotation.Nullable;
45import android.app.Activity;
46import android.app.ActivityManager;
Charles Hee078db72017-10-19 18:03:20 +010047import android.app.StatusBarManager;
48import android.app.admin.DevicePolicyManager;
Benjamin Franza83859f2017-07-03 16:34:14 +010049import android.app.admin.IDevicePolicyManager;
Charles Hee078db72017-10-19 18:03:20 +010050import android.content.ComponentName;
Benjamin Franza83859f2017-07-03 16:34:14 +010051import android.content.Context;
Charles He858f1322017-11-27 17:11:04 -080052import android.content.Intent;
Benjamin Franza83859f2017-07-03 16:34:14 +010053import android.os.Binder;
54import android.os.Debug;
55import android.os.Handler;
56import android.os.IBinder;
57import android.os.RemoteException;
58import android.os.ServiceManager;
Adrian Roos1c8e3c02018-11-20 20:07:55 +010059import android.os.UserHandle;
Benjamin Franza83859f2017-07-03 16:34:14 +010060import android.provider.Settings;
Charles He858f1322017-11-27 17:11:04 -080061import android.telecom.TelecomManager;
Charles Hee078db72017-10-19 18:03:20 +010062import android.util.Pair;
Benjamin Franza83859f2017-07-03 16:34:14 +010063import android.util.Slog;
Charles He520b2832017-09-02 15:27:16 +010064import android.util.SparseArray;
Charles He858f1322017-11-27 17:11:04 -080065import android.util.SparseIntArray;
Benjamin Franza83859f2017-07-03 16:34:14 +010066
67import com.android.internal.annotations.VisibleForTesting;
Tony Mak2bf36912018-03-21 15:45:52 +000068import com.android.internal.policy.IKeyguardDismissCallback;
Benjamin Franza83859f2017-07-03 16:34:14 +010069import com.android.internal.statusbar.IStatusBarService;
70import com.android.internal.widget.LockPatternUtils;
71import com.android.server.LocalServices;
Wale Ogunwale59507092018-10-29 09:00:30 -070072import com.android.server.am.ActivityManagerService;
Benjamin Franza83859f2017-07-03 16:34:14 +010073import com.android.server.statusbar.StatusBarManagerInternal;
Benjamin Franza83859f2017-07-03 16:34:14 +010074
75import java.io.PrintWriter;
76import java.util.ArrayList;
Charles He520b2832017-09-02 15:27:16 +010077import java.util.Arrays;
Benjamin Franza83859f2017-07-03 16:34:14 +010078
79/**
80 * Helper class that deals with all things related to task locking. This includes the screen pinning
81 * mode that can be launched via System UI as well as the fully locked mode that can be achieved
82 * on fully managed devices.
83 *
Wale Ogunwale27c48ae2018-10-25 19:01:01 -070084 * Note: All methods in this class should only be called with the ActivityTaskManagerService lock
85 * held.
Benjamin Franza83859f2017-07-03 16:34:14 +010086 *
87 * @see Activity#startLockTask()
88 * @see Activity#stopLockTask()
89 */
90public class LockTaskController {
Wale Ogunwale98875612018-10-12 07:53:02 -070091 private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_ATM;
Benjamin Franza83859f2017-07-03 16:34:14 +010092 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
93
94 @VisibleForTesting
Charles Hee078db72017-10-19 18:03:20 +010095 static final int STATUS_BAR_MASK_LOCKED = StatusBarManager.DISABLE_MASK
96 & (~StatusBarManager.DISABLE_EXPAND)
97 & (~StatusBarManager.DISABLE_NOTIFICATION_TICKER)
98 & (~StatusBarManager.DISABLE_SYSTEM_INFO)
99 & (~StatusBarManager.DISABLE_BACK);
Benjamin Franza83859f2017-07-03 16:34:14 +0100100 @VisibleForTesting
Charles Hee078db72017-10-19 18:03:20 +0100101 static final int STATUS_BAR_MASK_PINNED = StatusBarManager.DISABLE_MASK
102 & (~StatusBarManager.DISABLE_BACK)
103 & (~StatusBarManager.DISABLE_HOME)
104 & (~StatusBarManager.DISABLE_RECENT);
105
106 private static final SparseArray<Pair<Integer, Integer>> STATUS_BAR_FLAG_MAP_LOCKED;
107 static {
108 STATUS_BAR_FLAG_MAP_LOCKED = new SparseArray<>();
109
110 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO,
111 new Pair<>(StatusBarManager.DISABLE_CLOCK, StatusBarManager.DISABLE2_SYSTEM_ICONS));
112
113 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS,
114 new Pair<>(StatusBarManager.DISABLE_NOTIFICATION_ICONS
115 | StatusBarManager.DISABLE_NOTIFICATION_ALERTS,
116 StatusBarManager.DISABLE2_NOTIFICATION_SHADE));
117
118 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME,
119 new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE));
120
Benjamin Franzcaffa772018-02-05 16:36:10 +0000121 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW,
Charles Hee078db72017-10-19 18:03:20 +0100122 new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE));
123
124 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
125 new Pair<>(StatusBarManager.DISABLE_NONE,
126 StatusBarManager.DISABLE2_GLOBAL_ACTIONS));
127 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100128
129 /** Tag used for disabling of keyguard */
130 private static final String LOCK_TASK_TAG = "Lock-to-App";
131
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100132 private final IBinder mToken = new LockTaskToken();
Benjamin Franza83859f2017-07-03 16:34:14 +0100133 private final ActivityStackSupervisor mSupervisor;
134 private final Context mContext;
135
136 // The following system services cannot be final, because they do not exist when this class
137 // is instantiated during device boot
138 @VisibleForTesting
139 IStatusBarService mStatusBarService;
140 @VisibleForTesting
141 IDevicePolicyManager mDevicePolicyManager;
142 @VisibleForTesting
143 WindowManagerService mWindowManager;
144 @VisibleForTesting
145 LockPatternUtils mLockPatternUtils;
Charles He858f1322017-11-27 17:11:04 -0800146 @VisibleForTesting
147 TelecomManager mTelecomManager;
Benjamin Franza83859f2017-07-03 16:34:14 +0100148
149 /**
Charles Heff9b4dff2017-09-22 10:18:37 +0100150 * The chain of tasks in LockTask mode, in the order of when they first entered LockTask mode.
151 *
152 * The first task in the list, which started the current LockTask session, is called the root
153 * task. It coincides with the Home task in a typical multi-app kiosk deployment. When there are
154 * more than one locked tasks, the root task can't be finished. Nor can it be moved to the back
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900155 * of the stack by {@link ActivityStack#moveTaskToBack(Task)};
Charles Heff9b4dff2017-09-22 10:18:37 +0100156 *
157 * Calling {@link Activity#stopLockTask()} on the root task will finish all tasks but itself in
158 * this list, and the device will exit LockTask mode.
159 *
160 * The list is empty if LockTask is inactive.
Benjamin Franza83859f2017-07-03 16:34:14 +0100161 */
Louis Changcdec0802019-11-11 11:45:07 +0800162 private final ArrayList<Task> mLockTaskModeTasks = new ArrayList<>();
Benjamin Franza83859f2017-07-03 16:34:14 +0100163
164 /**
Charles He520b2832017-09-02 15:27:16 +0100165 * Packages that are allowed to be launched into the lock task mode for each user.
166 */
167 private final SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
168
169 /**
Charles Hee078db72017-10-19 18:03:20 +0100170 * Features that are allowed by DPC to show during LockTask mode.
171 */
Charles He858f1322017-11-27 17:11:04 -0800172 private final SparseIntArray mLockTaskFeatures = new SparseIntArray();
Charles Hee078db72017-10-19 18:03:20 +0100173
174 /**
Benjamin Franza83859f2017-07-03 16:34:14 +0100175 * Store the current lock task mode. Possible values:
176 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
177 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
178 */
Charles Heff9b4dff2017-09-22 10:18:37 +0100179 private int mLockTaskModeState = LOCK_TASK_MODE_NONE;
Benjamin Franza83859f2017-07-03 16:34:14 +0100180
181 /**
182 * This is ActivityStackSupervisor's Handler.
183 */
184 private final Handler mHandler;
185
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100186 /**
187 * Stores the user for which we're trying to dismiss the keyguard and then subsequently
188 * disable it.
189 *
190 * Tracking this ensures we don't mistakenly disable the keyguard if we've stopped trying to
191 * between the dismiss request and when it succeeds.
192 *
193 * Must only be accessed from the Handler thread.
194 */
195 private int mPendingDisableFromDismiss = UserHandle.USER_NULL;
196
Benjamin Franza83859f2017-07-03 16:34:14 +0100197 LockTaskController(Context context, ActivityStackSupervisor supervisor,
198 Handler handler) {
199 mContext = context;
200 mSupervisor = supervisor;
201 mHandler = handler;
202 }
203
204 /**
205 * Set the window manager instance used in this class. This is necessary, because the window
206 * manager does not exist during instantiation of this class.
207 */
208 void setWindowManager(WindowManagerService windowManager) {
209 mWindowManager = windowManager;
210 }
211
212 /**
213 * @return the current lock task state. This can be any of
214 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
215 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
216 */
217 int getLockTaskModeState() {
218 return mLockTaskModeState;
219 }
220
221 /**
Charles He520b2832017-09-02 15:27:16 +0100222 * @return whether the given task is locked at the moment. Locked tasks cannot be moved to the
223 * back of the stack.
Benjamin Franza83859f2017-07-03 16:34:14 +0100224 */
Charles Heff9b4dff2017-09-22 10:18:37 +0100225 @VisibleForTesting
Louis Changcdec0802019-11-11 11:45:07 +0800226 boolean isTaskLocked(Task task) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100227 return mLockTaskModeTasks.contains(task);
228 }
229
230 /**
231 * @return {@code true} whether this task first started the current LockTask session.
232 */
Louis Changcdec0802019-11-11 11:45:07 +0800233 private boolean isRootTask(Task task) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100234 return mLockTaskModeTasks.indexOf(task) == 0;
235 }
236
237 /**
238 * @return whether the given activity is blocked from finishing, because it is the only activity
239 * of the last locked task and finishing it would mean that lock task mode is ended illegally.
240 */
241 boolean activityBlockedFromFinish(ActivityRecord activity) {
Louis Changcdec0802019-11-11 11:45:07 +0800242 final Task task = activity.getTask();
Charles Heff9b4dff2017-09-22 10:18:37 +0100243 if (activity == task.getRootActivity()
Wale Ogunwale21e06482019-11-18 05:14:15 -0800244 && activity == task.getTopNonFinishingActivity()
Charles Heff9b4dff2017-09-22 10:18:37 +0100245 && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV
246 && isRootTask(task)) {
247 Slog.i(TAG, "Not finishing task in lock task mode");
Benjamin Franza83859f2017-07-03 16:34:14 +0100248 showLockTaskToast();
249 return true;
250 }
251 return false;
252 }
253
254 /**
Charles Heff9b4dff2017-09-22 10:18:37 +0100255 * @return whether the given task can be moved to the back of the stack with
Wale Ogunwale85fb19a2019-12-05 10:41:05 +0900256 * {@link ActivityStack#moveTaskToBack(Task)}
Charles Heff9b4dff2017-09-22 10:18:37 +0100257 * @see #mLockTaskModeTasks
Benjamin Franza83859f2017-07-03 16:34:14 +0100258 */
Louis Changcdec0802019-11-11 11:45:07 +0800259 boolean canMoveTaskToBack(Task task) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100260 if (isRootTask(task)) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100261 showLockTaskToast();
Charles Heff9b4dff2017-09-22 10:18:37 +0100262 return false;
Benjamin Franza83859f2017-07-03 16:34:14 +0100263 }
Charles Heff9b4dff2017-09-22 10:18:37 +0100264 return true;
Benjamin Franza83859f2017-07-03 16:34:14 +0100265 }
266
267 /**
Charles Hed62f9652017-11-01 10:05:51 +0000268 * @return whether the requested task is allowed to be locked (either whitelisted, or declares
269 * lockTaskMode="always" in the manifest).
270 */
Louis Changcdec0802019-11-11 11:45:07 +0800271 boolean isTaskWhitelisted(Task task) {
Charles Hed62f9652017-11-01 10:05:51 +0000272 switch(task.mLockTaskAuth) {
273 case LOCK_TASK_AUTH_WHITELISTED:
274 case LOCK_TASK_AUTH_LAUNCHABLE:
275 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
276 return true;
277 case LOCK_TASK_AUTH_PINNABLE:
278 case LOCK_TASK_AUTH_DONT_LOCK:
279 default:
280 return false;
281 }
282 }
283
284 /**
285 * @return whether the requested task is disallowed to be launched.
Benjamin Franza83859f2017-07-03 16:34:14 +0100286 */
Louis Changcdec0802019-11-11 11:45:07 +0800287 boolean isLockTaskModeViolation(Task task) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100288 return isLockTaskModeViolation(task, false);
289 }
290
291 /**
292 * @param isNewClearTask whether the task would be cleared as part of the operation.
Charles Hed62f9652017-11-01 10:05:51 +0000293 * @return whether the requested task is disallowed to be launched.
Benjamin Franza83859f2017-07-03 16:34:14 +0100294 */
Louis Changcdec0802019-11-11 11:45:07 +0800295 boolean isLockTaskModeViolation(Task task, boolean isNewClearTask) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100296 if (isLockTaskModeViolationInternal(task, isNewClearTask)) {
297 showLockTaskToast();
298 return true;
299 }
300 return false;
301 }
302
Benjamin Franz7dcbfb02018-01-16 15:16:16 +0000303 /**
304 * @return the root task of the lock task.
305 */
Louis Changcdec0802019-11-11 11:45:07 +0800306 Task getRootTask() {
Benjamin Franz7dcbfb02018-01-16 15:16:16 +0000307 if (mLockTaskModeTasks.isEmpty()) {
308 return null;
309 }
310 return mLockTaskModeTasks.get(0);
311 }
312
Louis Changcdec0802019-11-11 11:45:07 +0800313 private boolean isLockTaskModeViolationInternal(Task task, boolean isNewClearTask) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100314 // TODO: Double check what's going on here. If the task is already in lock task mode, it's
315 // likely whitelisted, so will return false below.
Charles Heff9b4dff2017-09-22 10:18:37 +0100316 if (isTaskLocked(task) && !isNewClearTask) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100317 // If the task is already at the top and won't be cleared, then allow the operation
318 return false;
319 }
Charles Hed62f9652017-11-01 10:05:51 +0000320
321 // Allow recents activity if enabled by policy
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700322 if (task.isActivityTypeRecents() && isRecentsAllowed(task.mUserId)) {
Charles Hed62f9652017-11-01 10:05:51 +0000323 return false;
Benjamin Franza83859f2017-07-03 16:34:14 +0100324 }
Charles Hed62f9652017-11-01 10:05:51 +0000325
Charles He858f1322017-11-27 17:11:04 -0800326 // Allow emergency calling when the device is protected by a locked keyguard
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700327 if (isKeyguardAllowed(task.mUserId) && isEmergencyCallTask(task)) {
Charles He858f1322017-11-27 17:11:04 -0800328 return false;
329 }
330
Charles Hed62f9652017-11-01 10:05:51 +0000331 return !(isTaskWhitelisted(task) || mLockTaskModeTasks.isEmpty());
332 }
333
334 private boolean isRecentsAllowed(int userId) {
335 return (getLockTaskFeaturesForUser(userId)
Benjamin Franzcaffa772018-02-05 16:36:10 +0000336 & DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW) != 0;
Benjamin Franza83859f2017-07-03 16:34:14 +0100337 }
338
Charles He858f1322017-11-27 17:11:04 -0800339 private boolean isKeyguardAllowed(int userId) {
340 return (getLockTaskFeaturesForUser(userId)
341 & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0;
342 }
343
Yuhan Zhaof3b3d412020-01-24 23:37:13 +0000344 private boolean isBlockingInTaskEnabled(int userId) {
345 return (getLockTaskFeaturesForUser(userId)
346 & DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK) != 0;
347 }
348
349 boolean isActivityAllowed(int userId, String packageName, int lockTaskLaunchMode) {
350 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED || !isBlockingInTaskEnabled(userId)) {
351 return true;
352 }
353 switch (lockTaskLaunchMode) {
354 case LOCK_TASK_LAUNCH_MODE_ALWAYS:
355 return true;
356 case LOCK_TASK_LAUNCH_MODE_NEVER:
357 return false;
358 default:
359 }
360 return isPackageWhitelisted(userId, packageName);
361 }
362
Louis Changcdec0802019-11-11 11:45:07 +0800363 private boolean isEmergencyCallTask(Task task) {
Charles He858f1322017-11-27 17:11:04 -0800364 final Intent intent = task.intent;
365 if (intent == null) {
366 return false;
367 }
368
369 // 1. The emergency keypad activity launched on top of the keyguard
370 if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) {
371 return true;
372 }
373
374 // 2. The intent sent by the keypad, which is handled by Telephony
375 if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) {
376 return true;
377 }
378
379 // 3. Telephony then starts the default package for making the call
380 final TelecomManager tm = getTelecomManager();
381 final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null;
382 if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) {
383 return true;
384 }
385
386 return false;
387 }
388
Benjamin Franza83859f2017-07-03 16:34:14 +0100389 /**
390 * Stop the current lock task mode.
391 *
Charles Heff9b4dff2017-09-22 10:18:37 +0100392 * This is called by {@link ActivityManagerService} and performs various checks before actually
393 * finishing the locked task.
394 *
395 * @param task the task that requested the end of lock task mode ({@code null} for quitting app
396 * pinning mode)
397 * @param isSystemCaller indicates whether this request comes from the system via
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700398 * {@link ActivityTaskManagerService#stopSystemLockTaskMode()}. If
Charles Heff9b4dff2017-09-22 10:18:37 +0100399 * {@code true}, it means the user intends to stop pinned mode through UI;
400 * otherwise, it's called by an app and we need to stop locked or pinned
401 * mode, subject to checks.
Benjamin Franza83859f2017-07-03 16:34:14 +0100402 * @param callingUid the caller that requested the end of lock task mode.
Charles Heff9b4dff2017-09-22 10:18:37 +0100403 * @throws IllegalArgumentException if the calling task is invalid (e.g., {@code null} or not in
404 * foreground)
Benjamin Franza83859f2017-07-03 16:34:14 +0100405 * @throws SecurityException if the caller is not authorized to stop the lock task mode, i.e. if
406 * they differ from the one that launched lock task mode.
407 */
Louis Changcdec0802019-11-11 11:45:07 +0800408 void stopLockTaskMode(@Nullable Task task, boolean isSystemCaller, int callingUid) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100409 if (mLockTaskModeState == LOCK_TASK_MODE_NONE) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100410 return;
411 }
412
Charles Heff9b4dff2017-09-22 10:18:37 +0100413 if (isSystemCaller) {
414 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
415 clearLockedTasks("stopAppPinning");
416 } else {
417 Slog.e(TAG_LOCKTASK, "Attempted to stop LockTask with isSystemCaller=true");
418 showLockTaskToast();
419 }
420
421 } else {
422 // Ensure calling activity is not null
423 if (task == null) {
424 throw new IllegalArgumentException("can't stop LockTask for null task");
425 }
426
427 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
428 // It is possible lockTaskMode was started by the system process because
429 // android:lockTaskMode is set to a locking value in the application manifest
430 // instead of the app calling startLockTaskMode. In this case
Louis Changcdec0802019-11-11 11:45:07 +0800431 // {@link Task.mLockTaskUid} will be 0, so we compare the callingUid to the
432 // {@link Task.effectiveUid} instead. Also caller with
Charles Heff9b4dff2017-09-22 10:18:37 +0100433 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
434 if (callingUid != task.mLockTaskUid
435 && (task.mLockTaskUid != 0 || callingUid != task.effectiveUid)) {
436 throw new SecurityException("Invalid uid, expected " + task.mLockTaskUid
437 + " callingUid=" + callingUid + " effectiveUid=" + task.effectiveUid);
438 }
439
440 // We don't care if it's pinned or locked mode; this will stop it anyways.
441 clearLockedTask(task);
442 }
443 }
444
445 /**
446 * Clear all locked tasks and request the end of LockTask mode.
447 *
Wale Ogunwale59507092018-10-29 09:00:30 -0700448 * This method is called by UserController when starting a new foreground user, and,
Louis Changcdec0802019-11-11 11:45:07 +0800449 * unlike {@link #stopLockTaskMode(Task, boolean, int)}, it doesn't perform the checks.
Charles Heff9b4dff2017-09-22 10:18:37 +0100450 */
451 void clearLockedTasks(String reason) {
452 if (DEBUG_LOCKTASK) Slog.i(TAG_LOCKTASK, "clearLockedTasks: " + reason);
453 if (!mLockTaskModeTasks.isEmpty()) {
454 clearLockedTask(mLockTaskModeTasks.get(0));
455 }
456 }
457
458 /**
459 * Clear one locked task from LockTask mode.
460 *
461 * If the requested task is the root task (see {@link #mLockTaskModeTasks}), then all locked
462 * tasks are cleared. Otherwise, only the requested task is cleared. LockTask mode is stopped
463 * when the last locked task is cleared.
464 *
465 * @param task the task to be cleared from LockTask mode.
466 */
Louis Changcdec0802019-11-11 11:45:07 +0800467 void clearLockedTask(final Task task) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100468 if (task == null || mLockTaskModeTasks.isEmpty()) return;
469
470 if (task == mLockTaskModeTasks.get(0)) {
471 // We're removing the root task while there are other locked tasks. Therefore we should
472 // clear all locked tasks in reverse order.
473 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx > 0; --taskNdx) {
474 clearLockedTask(mLockTaskModeTasks.get(taskNdx));
475 }
476 }
477
478 removeLockedTask(task);
479 if (mLockTaskModeTasks.isEmpty()) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100480 return;
481 }
Charles Heff9b4dff2017-09-22 10:18:37 +0100482 task.performClearTaskLocked();
Louis Chang149d5c82019-12-30 09:47:39 +0800483 mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
Benjamin Franza83859f2017-07-03 16:34:14 +0100484 }
485
486 /**
487 * Remove the given task from the locked task list. If this was the last task in the list,
488 * lock task mode is stopped.
489 */
Louis Changcdec0802019-11-11 11:45:07 +0800490 private void removeLockedTask(final Task task) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100491 if (!mLockTaskModeTasks.remove(task)) {
492 return;
493 }
Charles Heff9b4dff2017-09-22 10:18:37 +0100494 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: removed " + task);
Benjamin Franza83859f2017-07-03 16:34:14 +0100495 if (mLockTaskModeTasks.isEmpty()) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100496 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
497 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700498 mHandler.post(() -> performStopLockTask(task.mUserId));
Benjamin Franza83859f2017-07-03 16:34:14 +0100499 }
500 }
501
Benjamin Franza83859f2017-07-03 16:34:14 +0100502 // This method should only be called on the handler thread
503 private void performStopLockTask(int userId) {
504 // When lock task ends, we enable the status bars.
505 try {
Charles Hee078db72017-10-19 18:03:20 +0100506 setStatusBarState(LOCK_TASK_MODE_NONE, userId);
507 setKeyguardState(LOCK_TASK_MODE_NONE, userId);
508 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
509 lockKeyguardIfNeeded();
Benjamin Franza83859f2017-07-03 16:34:14 +0100510 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100511 if (getDevicePolicyManager() != null) {
512 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
513 }
Charles Hebfe82d12017-10-20 11:59:44 +0100514 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
Matthew Ng9c3bce52018-02-01 22:00:31 +0000515 getStatusBarService().showPinningEnterExitToast(false /* entering */);
Charles Hebfe82d12017-10-20 11:59:44 +0100516 }
Benjamin Franz3662b152018-01-16 17:23:44 +0000517 mWindowManager.onLockTaskStateChanged(LOCK_TASK_MODE_NONE);
Benjamin Franza83859f2017-07-03 16:34:14 +0100518 } catch (RemoteException ex) {
519 throw new RuntimeException(ex);
520 } finally {
521 mLockTaskModeState = LOCK_TASK_MODE_NONE;
522 }
523 }
524
525 /**
Charles Hebfe82d12017-10-20 11:59:44 +0100526 * Show the lock task violation toast. Currently we only show toast for screen pinning mode, and
527 * no-op if the device is in locked mode.
Benjamin Franza83859f2017-07-03 16:34:14 +0100528 */
529 void showLockTaskToast() {
Charles Hebfe82d12017-10-20 11:59:44 +0100530 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
Matthew Ng9c3bce52018-02-01 22:00:31 +0000531 try {
532 getStatusBarService().showPinningEscapeToast();
533 } catch (RemoteException e) {
534 Slog.e(TAG, "Failed to send pinning escape toast", e);
535 }
Charles Hebfe82d12017-10-20 11:59:44 +0100536 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100537 }
538
539 // Starting lock task
540
541 /**
542 * Method to start lock task mode on a given task.
543 *
544 * @param task the task that should be locked.
Charles Heff9b4dff2017-09-22 10:18:37 +0100545 * @param isSystemCaller indicates whether this request was initiated by the system via
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700546 * {@link ActivityTaskManagerService#startSystemLockTaskMode(int)}. If
Charles Heff9b4dff2017-09-22 10:18:37 +0100547 * {@code true}, this intends to start pinned mode; otherwise, we look
548 * at the calling task's mLockTaskAuth to decide which mode to start.
Benjamin Franza83859f2017-07-03 16:34:14 +0100549 * @param callingUid the caller that requested the launch of lock task mode.
550 */
Louis Changcdec0802019-11-11 11:45:07 +0800551 void startLockTaskMode(@NonNull Task task, boolean isSystemCaller, int callingUid) {
Charles Heff9b4dff2017-09-22 10:18:37 +0100552 if (!isSystemCaller) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100553 task.mLockTaskUid = callingUid;
554 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
555 // startLockTask() called by app, but app is not part of lock task whitelist. Show
Charles Heff9b4dff2017-09-22 10:18:37 +0100556 // app pinning request. We will come back here with isSystemCaller true.
Benjamin Franza83859f2017-07-03 16:34:14 +0100557 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
558 StatusBarManagerInternal statusBarManager = LocalServices.getService(
559 StatusBarManagerInternal.class);
560 if (statusBarManager != null) {
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700561 statusBarManager.showScreenPinningRequest(task.mTaskId);
Benjamin Franza83859f2017-07-03 16:34:14 +0100562 }
563 return;
564 }
565 }
566
567 // System can only initiate screen pinning, not full lock task mode
Charles Heff9b4dff2017-09-22 10:18:37 +0100568 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
569 isSystemCaller ? "Locking pinned" : "Locking fully");
570 setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED,
Benjamin Franza83859f2017-07-03 16:34:14 +0100571 "startLockTask", true);
572 }
573
574 /**
575 * Start lock task mode on the given task.
576 * @param lockTaskModeState whether fully locked or pinned mode.
577 * @param andResume whether the task should be brought to foreground as part of the operation.
578 */
Louis Changcdec0802019-11-11 11:45:07 +0800579 private void setLockTaskMode(@NonNull Task task, int lockTaskModeState,
Benjamin Franza83859f2017-07-03 16:34:14 +0100580 String reason, boolean andResume) {
581 // Should have already been checked, but do it again.
582 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
583 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
584 "setLockTaskMode: Can't lock due to auth");
585 return;
586 }
587 if (isLockTaskModeViolation(task)) {
588 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
589 return;
590 }
591
Bryce Lee1a990e52018-04-23 10:54:11 -0700592 final Intent taskIntent = task.intent;
593 if (mLockTaskModeTasks.isEmpty() && taskIntent != null) {
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700594 mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.mUserId);
Benjamin Franza83859f2017-07-03 16:34:14 +0100595 // Start lock task on the handler thread
596 mHandler.post(() -> performStartLockTask(
Bryce Lee1a990e52018-04-23 10:54:11 -0700597 taskIntent.getComponent().getPackageName(),
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700598 task.mUserId,
Benjamin Franza83859f2017-07-03 16:34:14 +0100599 lockTaskModeState));
600 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100601 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskMode: Locking to " + task +
602 " Callers=" + Debug.getCallers(4));
Charles Heff9b4dff2017-09-22 10:18:37 +0100603
604 if (!mLockTaskModeTasks.contains(task)) {
605 mLockTaskModeTasks.add(task);
606 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100607
608 if (task.mLockTaskUid == -1) {
609 task.mLockTaskUid = task.effectiveUid;
610 }
611
612 if (andResume) {
Wale Ogunwale66e16852017-10-19 13:35:52 -0700613 mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
Benjamin Franza83859f2017-07-03 16:34:14 +0100614 lockTaskModeState != LOCK_TASK_MODE_NONE);
Louis Chang149d5c82019-12-30 09:47:39 +0800615 mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
lumark588a3e82018-07-20 18:53:54 +0800616 final ActivityStack stack = task.getStack();
617 if (stack != null) {
Wale Ogunwale3a256e62018-12-06 14:41:18 -0800618 stack.getDisplay().mDisplayContent.executeAppTransition();
lumark588a3e82018-07-20 18:53:54 +0800619 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100620 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700621 mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700622 DEFAULT_DISPLAY, task.getStack(), true /* forceNonResizable */);
Benjamin Franza83859f2017-07-03 16:34:14 +0100623 }
624 }
625
626 // This method should only be called on the handler thread
627 private void performStartLockTask(String packageName, int userId, int lockTaskModeState) {
628 // When lock task starts, we disable the status bars.
629 try {
Charles Hebfe82d12017-10-20 11:59:44 +0100630 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
Matthew Ng9c3bce52018-02-01 22:00:31 +0000631 getStatusBarService().showPinningEnterExitToast(true /* entering */);
Charles Hebfe82d12017-10-20 11:59:44 +0100632 }
Benjamin Franz3662b152018-01-16 17:23:44 +0000633 mWindowManager.onLockTaskStateChanged(lockTaskModeState);
Benjamin Franza83859f2017-07-03 16:34:14 +0100634 mLockTaskModeState = lockTaskModeState;
Charles Hee078db72017-10-19 18:03:20 +0100635 setStatusBarState(lockTaskModeState, userId);
636 setKeyguardState(lockTaskModeState, userId);
Benjamin Franza83859f2017-07-03 16:34:14 +0100637 if (getDevicePolicyManager() != null) {
638 getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId);
639 }
640 } catch (RemoteException ex) {
641 throw new RuntimeException(ex);
642 }
643 }
644
645 /**
Charles He520b2832017-09-02 15:27:16 +0100646 * Update packages that are allowed to be launched in lock task mode.
647 * @param userId Which user this whitelist is associated with
648 * @param packages The whitelist of packages allowed in lock task mode
649 * @see #mLockTaskPackages
Benjamin Franza83859f2017-07-03 16:34:14 +0100650 */
Charles He520b2832017-09-02 15:27:16 +0100651 void updateLockTaskPackages(int userId, String[] packages) {
652 mLockTaskPackages.put(userId, packages);
653
654 boolean taskChanged = false;
Benjamin Franza83859f2017-07-03 16:34:14 +0100655 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
Louis Changcdec0802019-11-11 11:45:07 +0800656 final Task lockedTask = mLockTaskModeTasks.get(taskNdx);
Charles He520b2832017-09-02 15:27:16 +0100657 final boolean wasWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
658 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
Benjamin Franza83859f2017-07-03 16:34:14 +0100659 lockedTask.setLockTaskAuth();
Charles He520b2832017-09-02 15:27:16 +0100660 final boolean isWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
661 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
662
663 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700664 || lockedTask.mUserId != userId
Charles He520b2832017-09-02 15:27:16 +0100665 || !wasWhitelisted || isWhitelisted) {
666 continue;
Benjamin Franza83859f2017-07-03 16:34:14 +0100667 }
Charles He520b2832017-09-02 15:27:16 +0100668
669 // Terminate locked tasks that have recently lost whitelist authorization.
670 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
671 lockedTask + " mLockTaskAuth()=" + lockedTask.lockTaskAuthToString());
672 removeLockedTask(lockedTask);
673 lockedTask.performClearTaskLocked();
674 taskChanged = true;
Benjamin Franza83859f2017-07-03 16:34:14 +0100675 }
676
Louis Chang149d5c82019-12-30 09:47:39 +0800677 mSupervisor.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth);
Charles He520b2832017-09-02 15:27:16 +0100678
Louis Chang149d5c82019-12-30 09:47:39 +0800679 final ActivityRecord r = mSupervisor.mRootWindowContainer.topRunningActivity();
Louis Changcdec0802019-11-11 11:45:07 +0800680 final Task task = (r != null) ? r.getTask() : null;
Charles He520b2832017-09-02 15:27:16 +0100681 if (mLockTaskModeTasks.isEmpty() && task!= null
Benjamin Franza83859f2017-07-03 16:34:14 +0100682 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
683 // This task must have just been authorized.
684 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
685 "onLockTaskPackagesUpdated: starting new locktask task=" + task);
Charles He520b2832017-09-02 15:27:16 +0100686 setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false);
687 taskChanged = true;
Benjamin Franza83859f2017-07-03 16:34:14 +0100688 }
Charles He520b2832017-09-02 15:27:16 +0100689
690 if (taskChanged) {
Louis Chang149d5c82019-12-30 09:47:39 +0800691 mSupervisor.mRootWindowContainer.resumeFocusedStacksTopActivities();
Benjamin Franza83859f2017-07-03 16:34:14 +0100692 }
693 }
694
Charles He520b2832017-09-02 15:27:16 +0100695 boolean isPackageWhitelisted(int userId, String pkg) {
696 if (pkg == null) {
697 return false;
698 }
699 String[] whitelist;
700 whitelist = mLockTaskPackages.get(userId);
701 if (whitelist == null) {
702 return false;
703 }
704 for (String whitelistedPkg : whitelist) {
705 if (pkg.equals(whitelistedPkg)) {
706 return true;
707 }
708 }
709 return false;
710 }
711
Benjamin Franza83859f2017-07-03 16:34:14 +0100712 /**
Charles Hee078db72017-10-19 18:03:20 +0100713 * Update the UI features that are enabled for LockTask mode.
714 * @param userId Which user these feature flags are associated with
715 * @param flags Bitfield of feature flags
716 * @see DevicePolicyManager#setLockTaskFeatures(ComponentName, int)
717 */
718 void updateLockTaskFeatures(int userId, int flags) {
719 int oldFlags = getLockTaskFeaturesForUser(userId);
720 if (flags == oldFlags) {
721 return;
722 }
723
724 mLockTaskFeatures.put(userId, flags);
Wale Ogunwale4e79a1c2019-10-05 20:52:40 -0700725 if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).mUserId) {
Charles Hee078db72017-10-19 18:03:20 +0100726 mHandler.post(() -> {
727 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
728 setStatusBarState(mLockTaskModeState, userId);
729 setKeyguardState(mLockTaskModeState, userId);
730 }
731 });
732 }
733 }
734
735 /**
736 * Helper method for configuring the status bar disabled state.
737 * Should only be called on the handler thread to avoid race.
738 */
739 private void setStatusBarState(int lockTaskModeState, int userId) {
740 IStatusBarService statusBar = getStatusBarService();
741 if (statusBar == null) {
742 Slog.e(TAG, "Can't find StatusBarService");
743 return;
744 }
745
746 // Default state, when lockTaskModeState == LOCK_TASK_MODE_NONE
747 int flags1 = StatusBarManager.DISABLE_NONE;
748 int flags2 = StatusBarManager.DISABLE2_NONE;
749
750 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
751 flags1 = STATUS_BAR_MASK_PINNED;
752
753 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) {
754 int lockTaskFeatures = getLockTaskFeaturesForUser(userId);
755 Pair<Integer, Integer> statusBarFlags = getStatusBarDisableFlags(lockTaskFeatures);
756 flags1 = statusBarFlags.first;
757 flags2 = statusBarFlags.second;
758 }
759
760 try {
761 statusBar.disable(flags1, mToken, mContext.getPackageName());
762 statusBar.disable2(flags2, mToken, mContext.getPackageName());
763 } catch (RemoteException e) {
764 Slog.e(TAG, "Failed to set status bar flags", e);
765 }
766 }
767
768 /**
769 * Helper method for configuring the keyguard disabled state.
770 * Should only be called on the handler thread to avoid race.
771 */
772 private void setKeyguardState(int lockTaskModeState, int userId) {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100773 mPendingDisableFromDismiss = UserHandle.USER_NULL;
Charles Hee078db72017-10-19 18:03:20 +0100774 if (lockTaskModeState == LOCK_TASK_MODE_NONE) {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100775 mWindowManager.reenableKeyguard(mToken, userId);
Charles Hee078db72017-10-19 18:03:20 +0100776
777 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) {
Charles He858f1322017-11-27 17:11:04 -0800778 if (isKeyguardAllowed(userId)) {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100779 mWindowManager.reenableKeyguard(mToken, userId);
Charles He858f1322017-11-27 17:11:04 -0800780 } else {
Tony Mak2bf36912018-03-21 15:45:52 +0000781 // If keyguard is not secure and it is locked, dismiss the keyguard before
782 // disabling it, which avoids the platform to think the keyguard is still on.
Brad Stenning2bdc21e2019-03-11 14:33:22 -0700783 if (mWindowManager.isKeyguardLocked() && !mWindowManager.isKeyguardSecure(userId)) {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100784 mPendingDisableFromDismiss = userId;
Tony Mak2bf36912018-03-21 15:45:52 +0000785 mWindowManager.dismissKeyguard(new IKeyguardDismissCallback.Stub() {
786 @Override
787 public void onDismissError() throws RemoteException {
788 Slog.i(TAG, "setKeyguardState: failed to dismiss keyguard");
789 }
790
791 @Override
792 public void onDismissSucceeded() throws RemoteException {
793 mHandler.post(
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100794 () -> {
795 if (mPendingDisableFromDismiss == userId) {
796 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG,
797 userId);
798 mPendingDisableFromDismiss = UserHandle.USER_NULL;
799 }
800 });
Tony Mak2bf36912018-03-21 15:45:52 +0000801 }
802
803 @Override
804 public void onDismissCancelled() throws RemoteException {
805 Slog.i(TAG, "setKeyguardState: dismiss cancelled");
806 }
807 }, null);
808 } else {
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100809 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId);
Tony Mak2bf36912018-03-21 15:45:52 +0000810 }
Charles Hee078db72017-10-19 18:03:20 +0100811 }
812
813 } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100814 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId);
Charles Hee078db72017-10-19 18:03:20 +0100815 }
816 }
817
818 /**
819 * Helper method for locking the device immediately. This may be necessary when the device
820 * leaves the pinned mode.
821 */
822 private void lockKeyguardIfNeeded() {
Jonathan Scott851d4692019-04-29 18:03:58 +0100823 if (shouldLockKeyguard()) {
824 mWindowManager.lockNow(null);
825 mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
826 getLockPatternUtils().requireCredentialEntry(USER_ALL);
827 }
828 }
829
830 private boolean shouldLockKeyguard() {
831 // This functionality should be kept consistent with
832 // com.android.settings.security.ScreenPinningSettings (see b/127605586)
Charles Hee078db72017-10-19 18:03:20 +0100833 try {
Jonathan Scott851d4692019-04-29 18:03:58 +0100834 return Settings.Secure.getIntForUser(
Charles Hee078db72017-10-19 18:03:20 +0100835 mContext.getContentResolver(),
Jonathan Scott851d4692019-04-29 18:03:58 +0100836 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, USER_CURRENT) != 0;
Charles Hee078db72017-10-19 18:03:20 +0100837 } catch (Settings.SettingNotFoundException e) {
Jonathan Scott851d4692019-04-29 18:03:58 +0100838 // Log to SafetyNet for b/127605586
839 android.util.EventLog.writeEvent(0x534e4554, "127605586", -1, "");
Jonathan Scottaa2d6b82019-05-13 12:21:50 +0100840 return getLockPatternUtils().isSecure(USER_CURRENT);
Charles Hee078db72017-10-19 18:03:20 +0100841 }
842 }
843
844 /**
845 * Translates from LockTask feature flags to StatusBarManager disable and disable2 flags.
846 * @param lockTaskFlags Bitfield of flags as per
847 * {@link DevicePolicyManager#setLockTaskFeatures(ComponentName, int)}
848 * @return A {@link Pair} of {@link StatusBarManager#disable(int)} and
849 * {@link StatusBarManager#disable2(int)} flags
850 */
851 @VisibleForTesting
852 Pair<Integer, Integer> getStatusBarDisableFlags(int lockTaskFlags) {
853 // Everything is disabled by default
854 int flags1 = StatusBarManager.DISABLE_MASK;
855 int flags2 = StatusBarManager.DISABLE2_MASK;
856 for (int i = STATUS_BAR_FLAG_MAP_LOCKED.size() - 1; i >= 0; i--) {
857 Pair<Integer, Integer> statusBarFlags = STATUS_BAR_FLAG_MAP_LOCKED.valueAt(i);
858 if ((STATUS_BAR_FLAG_MAP_LOCKED.keyAt(i) & lockTaskFlags) != 0) {
859 flags1 &= ~statusBarFlags.first;
860 flags2 &= ~statusBarFlags.second;
861 }
862 }
863 // Some flags are not used for LockTask purposes, so we mask them
864 flags1 &= STATUS_BAR_MASK_LOCKED;
865 return new Pair<>(flags1, flags2);
866 }
867
868 /**
869 * Gets the cached value of LockTask feature flags for a specific user.
870 */
871 private int getLockTaskFeaturesForUser(int userId) {
872 return mLockTaskFeatures.get(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
873 }
874
Benjamin Franza83859f2017-07-03 16:34:14 +0100875 // Should only be called on the handler thread
876 @Nullable
877 private IStatusBarService getStatusBarService() {
878 if (mStatusBarService == null) {
879 mStatusBarService = IStatusBarService.Stub.asInterface(
880 ServiceManager.checkService(STATUS_BAR_SERVICE));
881 if (mStatusBarService == null) {
882 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
883 }
884 }
885 return mStatusBarService;
886 }
887
888 // Should only be called on the handler thread
889 @Nullable
890 private IDevicePolicyManager getDevicePolicyManager() {
891 if (mDevicePolicyManager == null) {
892 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
893 ServiceManager.checkService(DEVICE_POLICY_SERVICE));
894 if (mDevicePolicyManager == null) {
895 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
896 }
897 }
898 return mDevicePolicyManager;
899 }
900
901 @NonNull
902 private LockPatternUtils getLockPatternUtils() {
903 if (mLockPatternUtils == null) {
904 // We don't preserve the LPU object to save memory
905 return new LockPatternUtils(mContext);
906 }
907 return mLockPatternUtils;
908 }
909
Charles He858f1322017-11-27 17:11:04 -0800910 @Nullable
911 private TelecomManager getTelecomManager() {
912 if (mTelecomManager == null) {
913 // We don't preserve the TelecomManager object to save memory
914 return mContext.getSystemService(TelecomManager.class);
915 }
916 return mTelecomManager;
917 }
918
Benjamin Franza83859f2017-07-03 16:34:14 +0100919 public void dump(PrintWriter pw, String prefix) {
Charles He520b2832017-09-02 15:27:16 +0100920 pw.println(prefix + "LockTaskController");
921 prefix = prefix + " ";
922 pw.println(prefix + "mLockTaskModeState=" + lockTaskModeToString());
923 pw.println(prefix + "mLockTaskModeTasks=");
924 for (int i = 0; i < mLockTaskModeTasks.size(); ++i) {
925 pw.println(prefix + " #" + i + " " + mLockTaskModeTasks.get(i));
926 }
927 pw.println(prefix + "mLockTaskPackages (userId:packages)=");
928 for (int i = 0; i < mLockTaskPackages.size(); ++i) {
929 pw.println(prefix + " u" + mLockTaskPackages.keyAt(i)
930 + ":" + Arrays.toString(mLockTaskPackages.valueAt(i)));
931 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100932 }
933
934 private String lockTaskModeToString() {
935 switch (mLockTaskModeState) {
936 case LOCK_TASK_MODE_LOCKED:
937 return "LOCKED";
938 case LOCK_TASK_MODE_PINNED:
939 return "PINNED";
940 case LOCK_TASK_MODE_NONE:
941 return "NONE";
942 default: return "unknown=" + mLockTaskModeState;
943 }
944 }
Adrian Roos1c8e3c02018-11-20 20:07:55 +0100945
946 /** Marker class for the token used to disable keyguard. */
947 static class LockTaskToken extends Binder {
948 private LockTaskToken() {
949 }
950 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100951}