blob: 940f9051ec1e1a421ea1d29264340bc8bab6bb75 [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
17package com.android.server.am;
18
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;
Benjamin Franza83859f2017-07-03 16:34:14 +010022import static android.app.StatusBarManager.DISABLE_BACK;
23import static android.app.StatusBarManager.DISABLE_HOME;
24import static android.app.StatusBarManager.DISABLE_MASK;
25import static android.app.StatusBarManager.DISABLE_NONE;
26import static android.app.StatusBarManager.DISABLE_RECENT;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070027import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Benjamin Franza83859f2017-07-03 16:34:14 +010028import static android.content.Context.DEVICE_POLICY_SERVICE;
29import static android.content.Context.STATUS_BAR_SERVICE;
30import static android.os.UserHandle.USER_ALL;
Amith Yamasani7cbbf2222017-08-30 14:22:37 -070031import static android.os.UserHandle.USER_CURRENT;
Benjamin Franza83859f2017-07-03 16:34:14 +010032import static android.provider.Settings.Secure.LOCK_TO_APP_EXIT_LOCKED;
33import static android.view.Display.DEFAULT_DISPLAY;
Charles He520b2832017-09-02 15:27:16 +010034
Benjamin Franza83859f2017-07-03 16:34:14 +010035import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
36import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
37import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
38import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
39import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
40import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
41import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
42import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
43import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
44
45import android.annotation.NonNull;
46import android.annotation.Nullable;
47import android.app.Activity;
48import android.app.ActivityManager;
49import android.app.admin.IDevicePolicyManager;
50import android.content.Context;
51import android.os.Binder;
52import android.os.Debug;
53import android.os.Handler;
54import android.os.IBinder;
55import android.os.RemoteException;
56import android.os.ServiceManager;
57import android.provider.Settings;
58import android.util.Slog;
Charles He520b2832017-09-02 15:27:16 +010059import android.util.SparseArray;
Benjamin Franza83859f2017-07-03 16:34:14 +010060
61import com.android.internal.annotations.VisibleForTesting;
62import com.android.internal.statusbar.IStatusBarService;
63import com.android.internal.widget.LockPatternUtils;
64import com.android.server.LocalServices;
65import com.android.server.statusbar.StatusBarManagerInternal;
66import com.android.server.wm.WindowManagerService;
67
68import java.io.PrintWriter;
69import java.util.ArrayList;
Charles He520b2832017-09-02 15:27:16 +010070import java.util.Arrays;
Benjamin Franza83859f2017-07-03 16:34:14 +010071
72/**
73 * Helper class that deals with all things related to task locking. This includes the screen pinning
74 * mode that can be launched via System UI as well as the fully locked mode that can be achieved
75 * on fully managed devices.
76 *
77 * Note: All methods in this class should only be called with the ActivityManagerService lock held.
78 *
79 * @see Activity#startLockTask()
80 * @see Activity#stopLockTask()
81 */
82public class LockTaskController {
83 private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_AM;
84 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
85
86 @VisibleForTesting
87 static final int STATUS_BAR_MASK_LOCKED = DISABLE_MASK
88 & (~DISABLE_BACK);
89 @VisibleForTesting
90 static final int STATUS_BAR_MASK_PINNED = DISABLE_MASK
91 & (~DISABLE_BACK)
92 & (~DISABLE_HOME)
93 & (~DISABLE_RECENT);
94
95 /** Tag used for disabling of keyguard */
96 private static final String LOCK_TASK_TAG = "Lock-to-App";
97
98 private final IBinder mToken = new Binder();
99 private final ActivityStackSupervisor mSupervisor;
100 private final Context mContext;
101
102 // The following system services cannot be final, because they do not exist when this class
103 // is instantiated during device boot
104 @VisibleForTesting
105 IStatusBarService mStatusBarService;
106 @VisibleForTesting
107 IDevicePolicyManager mDevicePolicyManager;
108 @VisibleForTesting
109 WindowManagerService mWindowManager;
110 @VisibleForTesting
111 LockPatternUtils mLockPatternUtils;
112
113 /**
114 * Helper that is responsible for showing the right toast when a disallowed activity operation
115 * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
116 * fully locked mode we only show that unlocking is blocked.
117 */
118 @VisibleForTesting
119 LockTaskNotify mLockTaskNotify;
120
121 /**
122 * The chain of tasks in lockTask mode. The current frontmost task is at the top, and tasks
123 * may be finished until there is only one entry left. If this is empty the system is not
124 * in lockTask mode.
125 */
126 private final ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
127
128 /**
Charles He520b2832017-09-02 15:27:16 +0100129 * Packages that are allowed to be launched into the lock task mode for each user.
130 */
131 private final SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
132
133 /**
Benjamin Franza83859f2017-07-03 16:34:14 +0100134 * Store the current lock task mode. Possible values:
135 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
136 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
137 */
138 private int mLockTaskModeState;
139
140 /**
141 * This is ActivityStackSupervisor's Handler.
142 */
143 private final Handler mHandler;
144
145 LockTaskController(Context context, ActivityStackSupervisor supervisor,
146 Handler handler) {
147 mContext = context;
148 mSupervisor = supervisor;
149 mHandler = handler;
150 }
151
152 /**
153 * Set the window manager instance used in this class. This is necessary, because the window
154 * manager does not exist during instantiation of this class.
155 */
156 void setWindowManager(WindowManagerService windowManager) {
157 mWindowManager = windowManager;
158 }
159
160 /**
161 * @return the current lock task state. This can be any of
162 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
163 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
164 */
165 int getLockTaskModeState() {
166 return mLockTaskModeState;
167 }
168
169 /**
Charles He520b2832017-09-02 15:27:16 +0100170 * @return whether the given task is locked at the moment. Locked tasks cannot be moved to the
171 * back of the stack.
Benjamin Franza83859f2017-07-03 16:34:14 +0100172 */
173 boolean checkLockedTask(TaskRecord task) {
174 if (mLockTaskModeTasks.contains(task)) {
175 showLockTaskToast();
176 return true;
177 }
178 return false;
179 }
180
181 /**
182 * @return whether the given activity is blocked from finishing, because it is the root activity
183 * of the last locked task and finishing it would mean that lock task mode is ended illegally.
184 */
185 boolean activityBlockedFromFinish(ActivityRecord activity) {
186 TaskRecord task = activity.getTask();
187 if (activity == task.getRootActivity()
188 && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV
189 && mLockTaskModeTasks.size() == 1
190 && mLockTaskModeTasks.contains(task)) {
191 Slog.i(TAG, "Not finishing task in lock task mode");
192 showLockTaskToast();
193 return true;
194 }
195 return false;
196 }
197
198 /**
199 * @return whether the requested task is allowed to be launched.
200 */
201 boolean isLockTaskModeViolation(TaskRecord task) {
202 return isLockTaskModeViolation(task, false);
203 }
204
205 /**
206 * @param isNewClearTask whether the task would be cleared as part of the operation.
207 * @return whether the requested task is allowed to be launched.
208 */
209 boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
210 if (isLockTaskModeViolationInternal(task, isNewClearTask)) {
211 showLockTaskToast();
212 return true;
213 }
214 return false;
215 }
216
217 private boolean isLockTaskModeViolationInternal(TaskRecord task, boolean isNewClearTask) {
218 // TODO: Double check what's going on here. If the task is already in lock task mode, it's
219 // likely whitelisted, so will return false below.
220 if (getLockedTask() == task && !isNewClearTask) {
221 // If the task is already at the top and won't be cleared, then allow the operation
222 return false;
223 }
224 final int lockTaskAuth = task.mLockTaskAuth;
225 switch (lockTaskAuth) {
226 case LOCK_TASK_AUTH_DONT_LOCK:
227 return !mLockTaskModeTasks.isEmpty();
228 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
229 case LOCK_TASK_AUTH_LAUNCHABLE:
230 case LOCK_TASK_AUTH_WHITELISTED:
231 return false;
232 case LOCK_TASK_AUTH_PINNABLE:
233 // Pinnable tasks can't be launched on top of locktask tasks.
234 return !mLockTaskModeTasks.isEmpty();
235 default:
236 Slog.w(TAG, "isLockTaskModeViolation: invalid lockTaskAuth value=" + lockTaskAuth);
237 return true;
238 }
239 }
240
241 /**
242 * Stop the current lock task mode.
243 *
244 * @param isSystemInitiated indicates whether this request was initiated by the system via
245 * {@link ActivityManagerService#stopSystemLockTaskMode()}.
246 * @param callingUid the caller that requested the end of lock task mode.
247 * @throws SecurityException if the caller is not authorized to stop the lock task mode, i.e. if
248 * they differ from the one that launched lock task mode.
249 */
250 void stopLockTaskMode(boolean isSystemInitiated, int callingUid) {
251 final TaskRecord lockTask = getLockedTask();
252 if (lockTask == null || mLockTaskModeState == LOCK_TASK_MODE_NONE) {
253 // Our work here is done.
254 return;
255 }
256
257 if (isSystemInitiated && mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
258 // As system can only start app pinning, we also only let it unlock in this mode.
259 showLockTaskToast();
260 return;
261 }
262
263 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
264 // It is possible lockTaskMode was started by the system process because
265 // android:lockTaskMode is set to a locking value in the application manifest
266 // instead of the app calling startLockTaskMode. In this case
267 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
268 // {@link TaskRecord.effectiveUid} instead. Also caller with
269 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
270 if (!isSystemInitiated && callingUid != lockTask.mLockTaskUid
271 && (lockTask.mLockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
272 throw new SecurityException("Invalid uid, expected " + lockTask.mLockTaskUid
273 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
274 }
275
276 clearLockTaskMode("stopLockTask");
277 }
278
279 /**
280 * Remove the given task from the locked task list. If this was the last task in the list,
281 * lock task mode is stopped.
282 */
283 void removeLockedTask(final TaskRecord task) {
284 if (!mLockTaskModeTasks.remove(task)) {
285 return;
286 }
287 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "removeLockedTask: removed " + task);
288 if (mLockTaskModeTasks.isEmpty()) {
289 // Last one.
290 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
291 " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
292 mHandler.post(() -> performStopLockTask(task.userId));
293 }
294 }
295
296 /**
297 * Remove the topmost task from the locked task list. If this is the last task in the list, it
298 * will result in the end of locked task mode.
299 */
300 void clearLockTaskMode(String reason) {
301 // Take out of lock task mode if necessary
302 final TaskRecord lockedTask = getLockedTask();
303 if (lockedTask != null) {
304 removeLockedTask(lockedTask);
305 if (!mLockTaskModeTasks.isEmpty()) {
306 // There are locked tasks remaining, can only finish this task, not unlock it.
307 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
308 "setLockTaskMode: Tasks remaining, can't unlock");
309 lockedTask.performClearTaskLocked();
310 mSupervisor.resumeFocusedStackTopActivityLocked();
311 return;
312 }
313 }
314 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
315 "setLockTaskMode: No tasks to unlock. Callers=" + Debug.getCallers(4));
316 }
317
318 // This method should only be called on the handler thread
319 private void performStopLockTask(int userId) {
320 // When lock task ends, we enable the status bars.
321 try {
322 if (getStatusBarService() != null) {
323 getStatusBarService().disable(DISABLE_NONE, mToken,
324 mContext.getPackageName());
325 }
326 mWindowManager.reenableKeyguard(mToken);
327 if (getDevicePolicyManager() != null) {
328 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
329 }
330 getLockTaskNotify().show(false);
331 try {
Amith Yamasani7cbbf2222017-08-30 14:22:37 -0700332 boolean shouldLockKeyguard = Settings.Secure.getIntForUser(
Benjamin Franza83859f2017-07-03 16:34:14 +0100333 mContext.getContentResolver(),
Amith Yamasani7cbbf2222017-08-30 14:22:37 -0700334 LOCK_TO_APP_EXIT_LOCKED,
335 USER_CURRENT) != 0;
Benjamin Franza83859f2017-07-03 16:34:14 +0100336 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED && shouldLockKeyguard) {
337 mWindowManager.lockNow(null);
338 mWindowManager.dismissKeyguard(null /* callback */);
339 getLockPatternUtils().requireCredentialEntry(USER_ALL);
340 }
341 } catch (Settings.SettingNotFoundException e) {
342 // No setting, don't lock.
343 }
344 } catch (RemoteException ex) {
345 throw new RuntimeException(ex);
346 } finally {
347 mLockTaskModeState = LOCK_TASK_MODE_NONE;
348 }
349 }
350
351 /**
352 * Show the lock task violation toast.
353 */
354 void showLockTaskToast() {
355 mHandler.post(() -> getLockTaskNotify().showToast(mLockTaskModeState));
356 }
357
358 // Starting lock task
359
360 /**
361 * Method to start lock task mode on a given task.
362 *
363 * @param task the task that should be locked.
364 * @param isSystemInitiated indicates whether this request was initiated by the system via
365 * {@link ActivityManagerService#startSystemLockTaskMode(int)}.
366 * @param callingUid the caller that requested the launch of lock task mode.
367 */
368 void startLockTaskMode(@NonNull TaskRecord task, boolean isSystemInitiated,
369 int callingUid) {
370 if (!isSystemInitiated) {
371 task.mLockTaskUid = callingUid;
372 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
373 // startLockTask() called by app, but app is not part of lock task whitelist. Show
374 // app pinning request. We will come back here with isSystemInitiated true.
375 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
376 StatusBarManagerInternal statusBarManager = LocalServices.getService(
377 StatusBarManagerInternal.class);
378 if (statusBarManager != null) {
379 statusBarManager.showScreenPinningRequest(task.taskId);
380 }
381 return;
382 }
383 }
384
385 // System can only initiate screen pinning, not full lock task mode
386 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" : "Locking fully");
387 setLockTaskMode(task, isSystemInitiated ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED,
388 "startLockTask", true);
389 }
390
391 /**
392 * Start lock task mode on the given task.
393 * @param lockTaskModeState whether fully locked or pinned mode.
394 * @param andResume whether the task should be brought to foreground as part of the operation.
395 */
396 private void setLockTaskMode(@NonNull TaskRecord task, int lockTaskModeState,
397 String reason, boolean andResume) {
398 // Should have already been checked, but do it again.
399 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
400 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
401 "setLockTaskMode: Can't lock due to auth");
402 return;
403 }
404 if (isLockTaskModeViolation(task)) {
405 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
406 return;
407 }
408
409 if (mLockTaskModeTasks.isEmpty()) {
410 // Start lock task on the handler thread
411 mHandler.post(() -> performStartLockTask(
412 task.intent.getComponent().getPackageName(),
413 task.userId,
414 lockTaskModeState));
415 }
416
417 // Add it or move it to the top.
418 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskMode: Locking to " + task +
419 " Callers=" + Debug.getCallers(4));
420 mLockTaskModeTasks.remove(task);
421 mLockTaskModeTasks.add(task);
422
423 if (task.mLockTaskUid == -1) {
424 task.mLockTaskUid = task.effectiveUid;
425 }
426
427 if (andResume) {
428 mSupervisor.findTaskToMoveToFrontLocked(task, 0, null, reason,
429 lockTaskModeState != LOCK_TASK_MODE_NONE);
430 mSupervisor.resumeFocusedStackTopActivityLocked();
431 mWindowManager.executeAppTransition();
432 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700433 mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700434 DEFAULT_DISPLAY, task.getStack(), true /* forceNonResizable */);
Benjamin Franza83859f2017-07-03 16:34:14 +0100435 }
436 }
437
438 // This method should only be called on the handler thread
439 private void performStartLockTask(String packageName, int userId, int lockTaskModeState) {
440 // When lock task starts, we disable the status bars.
441 try {
442 getLockTaskNotify().show(true);
443 mLockTaskModeState = lockTaskModeState;
444 if (getStatusBarService() != null) {
445 int flags = 0;
446 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
447 flags = STATUS_BAR_MASK_LOCKED;
448 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
449 flags = STATUS_BAR_MASK_PINNED;
450 }
451 getStatusBarService().disable(flags, mToken, mContext.getPackageName());
452 }
453 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
454 if (getDevicePolicyManager() != null) {
455 getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId);
456 }
457 } catch (RemoteException ex) {
458 throw new RuntimeException(ex);
459 }
460 }
461
462 /**
Charles He520b2832017-09-02 15:27:16 +0100463 * Update packages that are allowed to be launched in lock task mode.
464 * @param userId Which user this whitelist is associated with
465 * @param packages The whitelist of packages allowed in lock task mode
466 * @see #mLockTaskPackages
Benjamin Franza83859f2017-07-03 16:34:14 +0100467 */
Charles He520b2832017-09-02 15:27:16 +0100468 void updateLockTaskPackages(int userId, String[] packages) {
469 mLockTaskPackages.put(userId, packages);
470
471 boolean taskChanged = false;
Benjamin Franza83859f2017-07-03 16:34:14 +0100472 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
473 final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
Charles He520b2832017-09-02 15:27:16 +0100474 final boolean wasWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
475 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
Benjamin Franza83859f2017-07-03 16:34:14 +0100476 lockedTask.setLockTaskAuth();
Charles He520b2832017-09-02 15:27:16 +0100477 final boolean isWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
478 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
479
480 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED
481 || lockedTask.userId != userId
482 || !wasWhitelisted || isWhitelisted) {
483 continue;
Benjamin Franza83859f2017-07-03 16:34:14 +0100484 }
Charles He520b2832017-09-02 15:27:16 +0100485
486 // Terminate locked tasks that have recently lost whitelist authorization.
487 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
488 lockedTask + " mLockTaskAuth()=" + lockedTask.lockTaskAuthToString());
489 removeLockedTask(lockedTask);
490 lockedTask.performClearTaskLocked();
491 taskChanged = true;
Benjamin Franza83859f2017-07-03 16:34:14 +0100492 }
493
494 for (int displayNdx = mSupervisor.getChildCount() - 1; displayNdx >= 0; --displayNdx) {
Wale Ogunwalea0f5b5e2017-10-11 09:37:23 -0700495 mSupervisor.getChildAt(displayNdx).onLockTaskPackagesUpdated();
Benjamin Franza83859f2017-07-03 16:34:14 +0100496 }
Charles He520b2832017-09-02 15:27:16 +0100497
Benjamin Franza83859f2017-07-03 16:34:14 +0100498 final ActivityRecord r = mSupervisor.topRunningActivityLocked();
Charles He520b2832017-09-02 15:27:16 +0100499 final TaskRecord task = (r != null) ? r.getTask() : null;
500 if (mLockTaskModeTasks.isEmpty() && task!= null
Benjamin Franza83859f2017-07-03 16:34:14 +0100501 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
502 // This task must have just been authorized.
503 if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
504 "onLockTaskPackagesUpdated: starting new locktask task=" + task);
Charles He520b2832017-09-02 15:27:16 +0100505 setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false);
506 taskChanged = true;
Benjamin Franza83859f2017-07-03 16:34:14 +0100507 }
Charles He520b2832017-09-02 15:27:16 +0100508
509 if (taskChanged) {
Benjamin Franza83859f2017-07-03 16:34:14 +0100510 mSupervisor.resumeFocusedStackTopActivityLocked();
511 }
512 }
513
Charles He520b2832017-09-02 15:27:16 +0100514 boolean isPackageWhitelisted(int userId, String pkg) {
515 if (pkg == null) {
516 return false;
517 }
518 String[] whitelist;
519 whitelist = mLockTaskPackages.get(userId);
520 if (whitelist == null) {
521 return false;
522 }
523 for (String whitelistedPkg : whitelist) {
524 if (pkg.equals(whitelistedPkg)) {
525 return true;
526 }
527 }
528 return false;
529 }
530
Benjamin Franza83859f2017-07-03 16:34:14 +0100531 /**
532 * @return the topmost locked task
533 */
534 private TaskRecord getLockedTask() {
535 final int top = mLockTaskModeTasks.size() - 1;
536 if (top >= 0) {
537 return mLockTaskModeTasks.get(top);
538 }
539 return null;
540 }
541
542 // Should only be called on the handler thread
543 @Nullable
544 private IStatusBarService getStatusBarService() {
545 if (mStatusBarService == null) {
546 mStatusBarService = IStatusBarService.Stub.asInterface(
547 ServiceManager.checkService(STATUS_BAR_SERVICE));
548 if (mStatusBarService == null) {
549 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
550 }
551 }
552 return mStatusBarService;
553 }
554
555 // Should only be called on the handler thread
556 @Nullable
557 private IDevicePolicyManager getDevicePolicyManager() {
558 if (mDevicePolicyManager == null) {
559 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
560 ServiceManager.checkService(DEVICE_POLICY_SERVICE));
561 if (mDevicePolicyManager == null) {
562 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
563 }
564 }
565 return mDevicePolicyManager;
566 }
567
568 @NonNull
569 private LockPatternUtils getLockPatternUtils() {
570 if (mLockPatternUtils == null) {
571 // We don't preserve the LPU object to save memory
572 return new LockPatternUtils(mContext);
573 }
574 return mLockPatternUtils;
575 }
576
577 // Should only be called on the handler thread
578 @NonNull
579 private LockTaskNotify getLockTaskNotify() {
580 if (mLockTaskNotify == null) {
581 mLockTaskNotify = new LockTaskNotify(mContext);
582 }
583 return mLockTaskNotify;
584 }
585
586 public void dump(PrintWriter pw, String prefix) {
Charles He520b2832017-09-02 15:27:16 +0100587 pw.println(prefix + "LockTaskController");
588 prefix = prefix + " ";
589 pw.println(prefix + "mLockTaskModeState=" + lockTaskModeToString());
590 pw.println(prefix + "mLockTaskModeTasks=");
591 for (int i = 0; i < mLockTaskModeTasks.size(); ++i) {
592 pw.println(prefix + " #" + i + " " + mLockTaskModeTasks.get(i));
593 }
594 pw.println(prefix + "mLockTaskPackages (userId:packages)=");
595 for (int i = 0; i < mLockTaskPackages.size(); ++i) {
596 pw.println(prefix + " u" + mLockTaskPackages.keyAt(i)
597 + ":" + Arrays.toString(mLockTaskPackages.valueAt(i)));
598 }
Benjamin Franza83859f2017-07-03 16:34:14 +0100599 }
600
601 private String lockTaskModeToString() {
602 switch (mLockTaskModeState) {
603 case LOCK_TASK_MODE_LOCKED:
604 return "LOCKED";
605 case LOCK_TASK_MODE_PINNED:
606 return "PINNED";
607 case LOCK_TASK_MODE_NONE:
608 return "NONE";
609 default: return "unknown=" + mLockTaskModeState;
610 }
611 }
612}