1 /* 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 17 package com.android.server.wm; 18 19 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; 20 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; 21 import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED; 22 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; 23 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 24 import static android.content.Context.DEVICE_POLICY_SERVICE; 25 import static android.content.Context.STATUS_BAR_SERVICE; 26 import static android.content.Intent.ACTION_CALL_EMERGENCY; 27 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS; 28 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT; 29 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED; 30 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER; 31 import static android.os.UserHandle.USER_ALL; 32 import static android.os.UserHandle.USER_CURRENT; 33 import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT; 34 35 import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_LOCKTASK; 36 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK; 37 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; 38 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; 39 40 import android.annotation.NonNull; 41 import android.annotation.Nullable; 42 import android.app.Activity; 43 import android.app.ActivityManager; 44 import android.app.StatusBarManager; 45 import android.app.admin.DevicePolicyManager; 46 import android.app.admin.IDevicePolicyManager; 47 import android.content.ComponentName; 48 import android.content.Context; 49 import android.content.Intent; 50 import android.os.Binder; 51 import android.os.Debug; 52 import android.os.Handler; 53 import android.os.IBinder; 54 import android.os.RemoteException; 55 import android.os.ServiceManager; 56 import android.os.UserHandle; 57 import android.provider.Settings; 58 import android.telecom.TelecomManager; 59 import android.util.Pair; 60 import android.util.Slog; 61 import android.util.SparseArray; 62 import android.util.SparseIntArray; 63 64 import com.android.internal.annotations.VisibleForTesting; 65 import com.android.internal.policy.IKeyguardDismissCallback; 66 import com.android.internal.protolog.ProtoLog; 67 import com.android.internal.statusbar.IStatusBarService; 68 import com.android.internal.telephony.CellBroadcastUtils; 69 import com.android.internal.widget.LockPatternUtils; 70 import com.android.server.LocalServices; 71 import com.android.server.am.ActivityManagerService; 72 import com.android.server.statusbar.StatusBarManagerInternal; 73 74 import java.io.PrintWriter; 75 import java.util.ArrayList; 76 import java.util.Arrays; 77 78 /** 79 * Helper class that deals with all things related to task locking. This includes the screen pinning 80 * mode that can be launched via System UI as well as the fully locked mode that can be achieved 81 * on fully managed devices. 82 * 83 * Note: All methods in this class should only be called with the ActivityTaskManagerService lock 84 * held. 85 * 86 * @see Activity#startLockTask() 87 * @see Activity#stopLockTask() 88 */ 89 public class LockTaskController { 90 private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_ATM; 91 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 92 93 @VisibleForTesting 94 static final int STATUS_BAR_MASK_LOCKED = StatusBarManager.DISABLE_MASK 95 & (~StatusBarManager.DISABLE_EXPAND) 96 & (~StatusBarManager.DISABLE_NOTIFICATION_TICKER) 97 & (~StatusBarManager.DISABLE_SYSTEM_INFO) 98 & (~StatusBarManager.DISABLE_BACK); 99 @VisibleForTesting 100 static final int STATUS_BAR_MASK_PINNED = StatusBarManager.DISABLE_MASK 101 & (~StatusBarManager.DISABLE_BACK) 102 & (~StatusBarManager.DISABLE_HOME) 103 & (~StatusBarManager.DISABLE_RECENT); 104 105 private static final SparseArray<Pair<Integer, Integer>> STATUS_BAR_FLAG_MAP_LOCKED; 106 static { 107 STATUS_BAR_FLAG_MAP_LOCKED = new SparseArray<>(); 108 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO, new Pair<>(StatusBarManager.DISABLE_CLOCK, StatusBarManager.DISABLE2_SYSTEM_ICONS))109 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO, 110 new Pair<>(StatusBarManager.DISABLE_CLOCK, StatusBarManager.DISABLE2_SYSTEM_ICONS)); 111 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS, new Pair<>(StatusBarManager.DISABLE_NOTIFICATION_ICONS | StatusBarManager.DISABLE_NOTIFICATION_ALERTS, StatusBarManager.DISABLE2_NOTIFICATION_SHADE))112 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS, 113 new Pair<>(StatusBarManager.DISABLE_NOTIFICATION_ICONS 114 | StatusBarManager.DISABLE_NOTIFICATION_ALERTS, 115 StatusBarManager.DISABLE2_NOTIFICATION_SHADE)); 116 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME, new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE))117 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME, 118 new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE)); 119 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW, new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE))120 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW, 121 new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE)); 122 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS, new Pair<>(StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_GLOBAL_ACTIONS))123 STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS, 124 new Pair<>(StatusBarManager.DISABLE_NONE, 125 StatusBarManager.DISABLE2_GLOBAL_ACTIONS)); 126 } 127 128 /** Tag used for disabling of keyguard */ 129 private static final String LOCK_TASK_TAG = "Lock-to-App"; 130 131 /** Can't be put in lockTask mode. */ 132 static final int LOCK_TASK_AUTH_DONT_LOCK = 0; 133 /** Can enter app pinning with user approval. Can never start over existing lockTask task. */ 134 static final int LOCK_TASK_AUTH_PINNABLE = 1; 135 /** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */ 136 static final int LOCK_TASK_AUTH_LAUNCHABLE = 2; 137 /** Can enter lockTask without user approval. Can start over existing lockTask task. */ 138 static final int LOCK_TASK_AUTH_ALLOWLISTED = 3; 139 /** Priv-app that starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing 140 * lockTask task. */ 141 static final int LOCK_TASK_AUTH_LAUNCHABLE_PRIV = 4; 142 143 private final IBinder mToken = new LockTaskToken(); 144 private final ActivityTaskSupervisor mSupervisor; 145 private final Context mContext; 146 private final TaskChangeNotificationController mTaskChangeNotificationController; 147 148 // The following system services cannot be final, because they do not exist when this class 149 // is instantiated during device boot 150 @VisibleForTesting 151 IStatusBarService mStatusBarService; 152 @VisibleForTesting 153 IDevicePolicyManager mDevicePolicyManager; 154 @VisibleForTesting 155 WindowManagerService mWindowManager; 156 @VisibleForTesting 157 LockPatternUtils mLockPatternUtils; 158 @VisibleForTesting 159 TelecomManager mTelecomManager; 160 161 /** 162 * The chain of tasks in LockTask mode, in the order of when they first entered LockTask mode. 163 * 164 * The first task in the list, which started the current LockTask session, is called the root 165 * task. It coincides with the Home task in a typical multi-app kiosk deployment. When there are 166 * more than one locked tasks, the root task can't be finished. Nor can it be moved to the back 167 * of the stack by {@link Task#moveTaskToBack(Task)}; 168 * 169 * Calling {@link Activity#stopLockTask()} on the root task will finish all tasks but itself in 170 * this list, and the device will exit LockTask mode. 171 * 172 * The list is empty if LockTask is inactive. 173 */ 174 private final ArrayList<Task> mLockTaskModeTasks = new ArrayList<>(); 175 176 /** 177 * Packages that are allowed to be launched into the lock task mode for each user. 178 */ 179 private final SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); 180 181 /** 182 * Features that are allowed by DPC to show during LockTask mode. 183 */ 184 private final SparseIntArray mLockTaskFeatures = new SparseIntArray(); 185 186 /** 187 * Store the current lock task mode. Possible values: 188 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 189 * {@link ActivityManager#LOCK_TASK_MODE_PINNED} 190 */ 191 private volatile int mLockTaskModeState = LOCK_TASK_MODE_NONE; 192 193 /** 194 * This is ActivityTaskSupervisor's Handler. 195 */ 196 private final Handler mHandler; 197 198 /** 199 * Stores the user for which we're trying to dismiss the keyguard and then subsequently 200 * disable it. 201 * 202 * Tracking this ensures we don't mistakenly disable the keyguard if we've stopped trying to 203 * between the dismiss request and when it succeeds. 204 * 205 * Must only be accessed from the Handler thread. 206 */ 207 private int mPendingDisableFromDismiss = UserHandle.USER_NULL; 208 LockTaskController(Context context, ActivityTaskSupervisor supervisor, Handler handler, TaskChangeNotificationController taskChangeNotificationController)209 LockTaskController(Context context, ActivityTaskSupervisor supervisor, 210 Handler handler, TaskChangeNotificationController taskChangeNotificationController) { 211 mContext = context; 212 mSupervisor = supervisor; 213 mHandler = handler; 214 mTaskChangeNotificationController = taskChangeNotificationController; 215 } 216 217 /** 218 * Set the window manager instance used in this class. This is necessary, because the window 219 * manager does not exist during instantiation of this class. 220 */ setWindowManager(WindowManagerService windowManager)221 void setWindowManager(WindowManagerService windowManager) { 222 mWindowManager = windowManager; 223 } 224 225 /** 226 * @return the current lock task state. This can be any of 227 * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, 228 * {@link ActivityManager#LOCK_TASK_MODE_PINNED}. 229 */ getLockTaskModeState()230 int getLockTaskModeState() { 231 return mLockTaskModeState; 232 } 233 234 /** 235 * @return whether the given task is locked at the moment. Locked tasks cannot be moved to the 236 * back of the stack. 237 */ 238 @VisibleForTesting isTaskLocked(Task task)239 boolean isTaskLocked(Task task) { 240 return mLockTaskModeTasks.contains(task); 241 } 242 243 /** 244 * @return {@code true} whether this task first started the current LockTask session. 245 */ isRootTask(Task task)246 private boolean isRootTask(Task task) { 247 return mLockTaskModeTasks.indexOf(task) == 0; 248 } 249 250 /** 251 * @return whether the given activity is blocked from finishing, because it is the only activity 252 * of the last locked task and finishing it would mean that lock task mode is ended illegally. 253 */ activityBlockedFromFinish(ActivityRecord activity)254 boolean activityBlockedFromFinish(ActivityRecord activity) { 255 final Task task = activity.getTask(); 256 if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || !isRootTask(task)) { 257 return false; 258 } 259 260 final ActivityRecord taskTop = task.getTopNonFinishingActivity(); 261 final ActivityRecord taskRoot = task.getRootActivity(); 262 // If task has more than one Activity, verify if there's only adjacent TaskFragments that 263 // should be finish together in the Task. 264 if (activity != taskRoot || activity != taskTop) { 265 final TaskFragment taskFragment = activity.getTaskFragment(); 266 if (taskFragment.asTask() != null 267 || !taskFragment.isDelayLastActivityRemoval() 268 || !taskFragment.hasAdjacentTaskFragment()) { 269 // Don't block activity from finishing if the TaskFragment don't have any adjacent 270 // TaskFragment, or it won't finish together with its adjacent TaskFragment. 271 return false; 272 } 273 274 final boolean hasOtherActivityInTaskFragment = 275 taskFragment.getActivity(a -> !a.finishing && a != activity) != null; 276 if (hasOtherActivityInTaskFragment) { 277 // Don't block activity from finishing if there's other Activity in the same 278 // TaskFragment. 279 return false; 280 } 281 282 final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing 283 && a != activity && !taskFragment.isAdjacentTo(a.getTaskFragment())) != null; 284 if (hasOtherActivityInTask) { 285 // Do not block activity from finishing if there are another running activities 286 // after the current and adjacent TaskFragments are removed. Note that we don't 287 // check activities in adjacent TaskFragment because it will be finished together 288 // with TaskFragment regardless of numbers of activities. 289 return false; 290 } 291 } 292 293 Slog.i(TAG, "Not finishing task in lock task mode"); 294 showLockTaskToast(); 295 return true; 296 } 297 298 /** 299 * @return whether the given task can be moved to the back of the stack with 300 * {@link Task#moveTaskToBack(Task)} 301 * @see #mLockTaskModeTasks 302 */ canMoveTaskToBack(Task task)303 boolean canMoveTaskToBack(Task task) { 304 if (isRootTask(task)) { 305 showLockTaskToast(); 306 return false; 307 } 308 return true; 309 } 310 311 /** 312 * @return whether the requested task auth is allowed to be locked. 313 */ isTaskAuthAllowlisted(int lockTaskAuth)314 static boolean isTaskAuthAllowlisted(int lockTaskAuth) { 315 switch(lockTaskAuth) { 316 case LOCK_TASK_AUTH_ALLOWLISTED: 317 case LOCK_TASK_AUTH_LAUNCHABLE: 318 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 319 return true; 320 case LOCK_TASK_AUTH_PINNABLE: 321 case LOCK_TASK_AUTH_DONT_LOCK: 322 default: 323 return false; 324 } 325 } 326 327 /** 328 * @return whether the requested task is disallowed to be launched. 329 */ isLockTaskModeViolation(Task task)330 boolean isLockTaskModeViolation(Task task) { 331 return isLockTaskModeViolation(task, false); 332 } 333 334 /** 335 * @param isNewClearTask whether the task would be cleared as part of the operation. 336 * @return whether the requested task is disallowed to be launched. 337 */ isLockTaskModeViolation(Task task, boolean isNewClearTask)338 boolean isLockTaskModeViolation(Task task, boolean isNewClearTask) { 339 // TODO: Double check what's going on here. If the task is already in lock task mode, it's 340 // likely allowlisted, so will return false below. 341 if (isTaskLocked(task) && !isNewClearTask) { 342 // If the task is already at the top and won't be cleared, then allow the operation 343 } else if (isLockTaskModeViolationInternal(task, task.mUserId, task.intent, 344 task.mLockTaskAuth)) { 345 showLockTaskToast(); 346 return true; 347 } 348 return false; 349 } 350 351 /** 352 * @param activity an activity that is going to be started in a new task as the root activity. 353 * @return whether the given activity is allowed to be launched. 354 */ isNewTaskLockTaskModeViolation(ActivityRecord activity)355 boolean isNewTaskLockTaskModeViolation(ActivityRecord activity) { 356 // Use the belong task (if any) to perform the lock task checks 357 if (activity.getTask() != null) { 358 return isLockTaskModeViolation(activity.getTask()); 359 } 360 361 int auth = getLockTaskAuth(activity, null /* task */); 362 if (isLockTaskModeViolationInternal(activity, activity.mUserId, activity.intent, auth)) { 363 showLockTaskToast(); 364 return true; 365 } 366 return false; 367 } 368 369 /** 370 * @return the root task of the lock task. 371 */ getRootTask()372 Task getRootTask() { 373 if (mLockTaskModeTasks.isEmpty()) { 374 return null; 375 } 376 return mLockTaskModeTasks.get(0); 377 } 378 isLockTaskModeViolationInternal(WindowContainer wc, int userId, Intent intent, int taskAuth)379 private boolean isLockTaskModeViolationInternal(WindowContainer wc, int userId, 380 Intent intent, int taskAuth) { 381 // Allow recents activity if enabled by policy 382 if (wc.isActivityTypeRecents() && isRecentsAllowed(userId)) { 383 return false; 384 } 385 386 // Allow emergency calling when the device is protected by a locked keyguard 387 if (isKeyguardAllowed(userId) && isEmergencyCallIntent(intent)) { 388 return false; 389 } 390 391 // Allow the dream to start during lock task mode 392 if (wc.isActivityTypeDream()) { 393 return false; 394 } 395 396 if (isWirelessEmergencyAlert(intent)) { 397 return false; 398 } 399 400 return !(isTaskAuthAllowlisted(taskAuth) || mLockTaskModeTasks.isEmpty()); 401 } 402 isRecentsAllowed(int userId)403 private boolean isRecentsAllowed(int userId) { 404 return (getLockTaskFeaturesForUser(userId) 405 & DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW) != 0; 406 } 407 isKeyguardAllowed(int userId)408 private boolean isKeyguardAllowed(int userId) { 409 return (getLockTaskFeaturesForUser(userId) 410 & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0; 411 } 412 isBlockingInTaskEnabled(int userId)413 private boolean isBlockingInTaskEnabled(int userId) { 414 return (getLockTaskFeaturesForUser(userId) 415 & DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK) != 0; 416 } 417 isActivityAllowed(int userId, String packageName, int lockTaskLaunchMode)418 boolean isActivityAllowed(int userId, String packageName, int lockTaskLaunchMode) { 419 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED || !isBlockingInTaskEnabled(userId)) { 420 return true; 421 } 422 switch (lockTaskLaunchMode) { 423 case LOCK_TASK_LAUNCH_MODE_ALWAYS: 424 return true; 425 case LOCK_TASK_LAUNCH_MODE_NEVER: 426 return false; 427 default: 428 } 429 return isPackageAllowlisted(userId, packageName); 430 } 431 isWirelessEmergencyAlert(Intent intent)432 private boolean isWirelessEmergencyAlert(Intent intent) { 433 if (intent == null) { 434 return false; 435 } 436 437 final ComponentName cellBroadcastAlertDialogComponentName = 438 CellBroadcastUtils.getDefaultCellBroadcastAlertDialogComponent(mContext); 439 440 if (cellBroadcastAlertDialogComponentName == null) { 441 return false; 442 } 443 444 if (cellBroadcastAlertDialogComponentName.equals(intent.getComponent())) { 445 return true; 446 } 447 448 return false; 449 } 450 isEmergencyCallIntent(Intent intent)451 private boolean isEmergencyCallIntent(Intent intent) { 452 if (intent == null) { 453 return false; 454 } 455 456 // 1. The emergency keypad activity launched on top of the keyguard 457 if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) { 458 return true; 459 } 460 461 // 2. The intent sent by the keypad, which is handled by Telephony 462 if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) { 463 return true; 464 } 465 466 // 3. Telephony then starts the default package for making the call 467 final TelecomManager tm = getTelecomManager(); 468 final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null; 469 if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) { 470 return true; 471 } 472 473 return false; 474 } 475 476 /** 477 * Stop the current lock task mode. 478 * 479 * This is called by {@link ActivityManagerService} and performs various checks before actually 480 * finishing the locked task. 481 * 482 * @param task the task that requested the end of lock task mode ({@code null} for quitting app 483 * pinning mode) 484 * @param stopAppPinning indicates whether to stop app pinning mode or to stop a task from 485 * being locked. 486 * @param callingUid the caller that requested the end of lock task mode. 487 * @throws IllegalArgumentException if the calling task is invalid (e.g., {@code null} or not in 488 * foreground) 489 * @throws SecurityException if the caller is not authorized to stop the lock task mode, i.e. if 490 * they differ from the one that launched lock task mode. 491 */ stopLockTaskMode(@ullable Task task, boolean stopAppPinning, int callingUid)492 void stopLockTaskMode(@Nullable Task task, boolean stopAppPinning, int callingUid) { 493 if (mLockTaskModeState == LOCK_TASK_MODE_NONE) { 494 return; 495 } 496 497 if (stopAppPinning) { 498 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 499 clearLockedTasks("stopAppPinning"); 500 } else { 501 Slog.e(TAG_LOCKTASK, "Attempted to stop app pinning while fully locked"); 502 showLockTaskToast(); 503 } 504 505 } else { 506 // Ensure calling activity is not null 507 if (task == null) { 508 throw new IllegalArgumentException("can't stop LockTask for null task"); 509 } 510 511 // Ensure the same caller for startLockTaskMode and stopLockTaskMode. 512 // It is possible lockTaskMode was started by the system process because 513 // android:lockTaskMode is set to a locking value in the application manifest 514 // instead of the app calling startLockTaskMode. In this case 515 // {@link Task.mLockTaskUid} will be 0, so we compare the callingUid to the 516 // {@link Task.effectiveUid} instead. Also caller with 517 // {@link MANAGE_ACTIVITY_TASKS} can stop any lock task. 518 if (callingUid != task.mLockTaskUid 519 && (task.mLockTaskUid != 0 || callingUid != task.effectiveUid)) { 520 throw new SecurityException("Invalid uid, expected " + task.mLockTaskUid 521 + " callingUid=" + callingUid + " effectiveUid=" + task.effectiveUid); 522 } 523 524 // We don't care if it's pinned or locked mode; this will stop it anyways. 525 clearLockedTask(task); 526 } 527 } 528 529 /** 530 * Clear all locked tasks and request the end of LockTask mode. 531 * 532 * This method is called by UserController when starting a new foreground user, and, 533 * unlike {@link #stopLockTaskMode(Task, boolean, int)}, it doesn't perform the checks. 534 */ clearLockedTasks(String reason)535 void clearLockedTasks(String reason) { 536 ProtoLog.i(WM_DEBUG_LOCKTASK, "clearLockedTasks: %s", reason); 537 if (!mLockTaskModeTasks.isEmpty()) { 538 clearLockedTask(mLockTaskModeTasks.get(0)); 539 } 540 } 541 542 /** 543 * Clear one locked task from LockTask mode. 544 * 545 * If the requested task is the root task (see {@link #mLockTaskModeTasks}), then all locked 546 * tasks are cleared. Otherwise, only the requested task is cleared. LockTask mode is stopped 547 * when the last locked task is cleared. 548 * 549 * @param task the task to be cleared from LockTask mode. 550 */ clearLockedTask(final Task task)551 void clearLockedTask(final Task task) { 552 if (task == null || mLockTaskModeTasks.isEmpty()) return; 553 554 if (task == mLockTaskModeTasks.get(0)) { 555 // We're removing the root task while there are other locked tasks. Therefore we should 556 // clear all locked tasks in reverse order. 557 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx > 0; --taskNdx) { 558 clearLockedTask(mLockTaskModeTasks.get(taskNdx)); 559 } 560 } 561 562 removeLockedTask(task); 563 if (mLockTaskModeTasks.isEmpty()) { 564 return; 565 } 566 task.performClearTaskForReuse(false /* excludingTaskOverlay*/); 567 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 568 } 569 570 /** 571 * Remove the given task from the locked task list. If this was the last task in the list, 572 * lock task mode is stopped. 573 */ removeLockedTask(final Task task)574 private void removeLockedTask(final Task task) { 575 if (!mLockTaskModeTasks.remove(task)) { 576 return; 577 } 578 ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: removed %s", task); 579 if (mLockTaskModeTasks.isEmpty()) { 580 ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: task=%s last task, " 581 + "reverting locktask mode. Callers=%s", task, Debug.getCallers(3)); 582 mHandler.post(() -> performStopLockTask(task.mUserId)); 583 } 584 } 585 586 // This method should only be called on the handler thread performStopLockTask(int userId)587 private void performStopLockTask(int userId) { 588 // Update the internal mLockTaskModeState early to avoid the scenario that SysUI queries 589 // mLockTaskModeState (from setStatusBarState) and gets staled state. 590 // TODO: revisit this approach. 591 // The race condition raised above can be addressed by moving this function out of handler 592 // thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState. 593 final int oldLockTaskModeState = mLockTaskModeState; 594 mLockTaskModeState = LOCK_TASK_MODE_NONE; 595 mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); 596 // When lock task ends, we enable the status bars. 597 try { 598 setStatusBarState(mLockTaskModeState, userId); 599 setKeyguardState(mLockTaskModeState, userId); 600 if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) { 601 lockKeyguardIfNeeded(userId); 602 } 603 if (getDevicePolicyManager() != null) { 604 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId); 605 } 606 if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) { 607 final IStatusBarService statusBarService = getStatusBarService(); 608 if (statusBarService != null) { 609 statusBarService.showPinningEnterExitToast(false /* entering */); 610 } 611 } 612 } catch (RemoteException ex) { 613 throw new RuntimeException(ex); 614 } 615 } 616 617 /** 618 * Show the lock task violation toast. Currently we only show toast for screen pinning mode, and 619 * no-op if the device is in locked mode. 620 */ showLockTaskToast()621 void showLockTaskToast() { 622 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 623 try { 624 final IStatusBarService statusBarService = getStatusBarService(); 625 if (statusBarService != null) { 626 statusBarService.showPinningEscapeToast(); 627 } 628 } catch (RemoteException e) { 629 Slog.e(TAG, "Failed to send pinning escape toast", e); 630 } 631 } 632 } 633 634 // Starting lock task 635 636 /** 637 * Method to start lock task mode on a given task. 638 * 639 * @param task the task that should be locked. 640 * @param isSystemCaller indicates whether this request was initiated by the system via 641 * {@link ActivityTaskManagerService#startSystemLockTaskMode(int)}. If 642 * {@code true}, this intends to start pinned mode; otherwise, we look 643 * at the calling task's mLockTaskAuth to decide which mode to start. 644 * @param callingUid the caller that requested the launch of lock task mode. 645 */ startLockTaskMode(@onNull Task task, boolean isSystemCaller, int callingUid)646 void startLockTaskMode(@NonNull Task task, boolean isSystemCaller, int callingUid) { 647 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 648 ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskMode: Can't lock due to auth"); 649 return; 650 } 651 if (!isSystemCaller) { 652 task.mLockTaskUid = callingUid; 653 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { 654 if (mLockTaskModeTasks.contains(task)) { 655 ProtoLog.w(WM_DEBUG_LOCKTASK, "Already locked."); 656 return; 657 } 658 // startLockTask() called by app, but app is not part of lock task allowlist. Show 659 // app pinning request. We will come back here with isSystemCaller true. 660 ProtoLog.w(WM_DEBUG_LOCKTASK, "Mode default, asking user"); 661 StatusBarManagerInternal statusBarManager = LocalServices.getService( 662 StatusBarManagerInternal.class); 663 if (statusBarManager != null) { 664 statusBarManager.showScreenPinningRequest(task.mTaskId, task.mUserId); 665 } 666 return; 667 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 668 // startLockTask() called by app, and app is part of lock task allowlist. 669 // Deactivate the currently pinned task before doing so. 670 Slog.i(TAG, "Stop app pinning before entering full lock task mode"); 671 stopLockTaskMode(/* task= */ null, /* stopAppPinning= */ true, callingUid); 672 } 673 } 674 675 // When a task is locked, dismiss the root pinned task if it exists 676 mSupervisor.mRootWindowContainer.removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); 677 678 // System can only initiate screen pinning, not full lock task mode 679 ProtoLog.w(WM_DEBUG_LOCKTASK, "%s", isSystemCaller ? "Locking pinned" : "Locking fully"); 680 setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED, 681 "startLockTask", true); 682 } 683 684 /** 685 * Start lock task mode on the given task. 686 * @param lockTaskModeState whether fully locked or pinned mode. 687 * @param andResume whether the task should be brought to foreground as part of the operation. 688 */ setLockTaskMode(@onNull Task task, int lockTaskModeState, String reason, boolean andResume)689 private void setLockTaskMode(@NonNull Task task, int lockTaskModeState, 690 String reason, boolean andResume) { 691 // Should have already been checked, but do it again. 692 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 693 ProtoLog.w(WM_DEBUG_LOCKTASK, 694 "setLockTaskMode: Can't lock due to auth"); 695 return; 696 } 697 if (isLockTaskModeViolation(task)) { 698 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 699 return; 700 } 701 702 final Intent taskIntent = task.intent; 703 if (mLockTaskModeTasks.isEmpty() && taskIntent != null) { 704 mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.mUserId); 705 // Start lock task on the handler thread 706 mHandler.post(() -> performStartLockTask( 707 taskIntent.getComponent().getPackageName(), 708 task.mUserId, 709 lockTaskModeState)); 710 } 711 ProtoLog.w(WM_DEBUG_LOCKTASK, "setLockTaskMode: Locking to %s Callers=%s", 712 task, Debug.getCallers(4)); 713 714 if (!mLockTaskModeTasks.contains(task)) { 715 mLockTaskModeTasks.add(task); 716 } 717 718 if (task.mLockTaskUid == -1) { 719 task.mLockTaskUid = task.effectiveUid; 720 } 721 722 if (andResume) { 723 mSupervisor.findTaskToMoveToFront(task, 0, null, reason, 724 lockTaskModeState != LOCK_TASK_MODE_NONE); 725 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 726 final Task rootTask = task.getRootTask(); 727 if (rootTask != null) { 728 rootTask.mDisplayContent.executeAppTransition(); 729 } 730 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 731 mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, 732 mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(), 733 task.getRootTask(), true /* forceNonResizable */); 734 } 735 } 736 737 // This method should only be called on the handler thread performStartLockTask(String packageName, int userId, int lockTaskModeState)738 private void performStartLockTask(String packageName, int userId, int lockTaskModeState) { 739 // When lock task starts, we disable the status bars. 740 try { 741 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { 742 final IStatusBarService statusBarService = getStatusBarService(); 743 if (statusBarService != null) { 744 statusBarService.showPinningEnterExitToast(true /* entering */); 745 } 746 } 747 mLockTaskModeState = lockTaskModeState; 748 mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); 749 setStatusBarState(lockTaskModeState, userId); 750 setKeyguardState(lockTaskModeState, userId); 751 if (getDevicePolicyManager() != null) { 752 getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId); 753 } 754 } catch (RemoteException ex) { 755 throw new RuntimeException(ex); 756 } 757 } 758 759 /** 760 * Update packages that are allowed to be launched in lock task mode. 761 * @param userId Which user this allowlist is associated with 762 * @param packages The allowlist of packages allowed in lock task mode 763 * @see #mLockTaskPackages 764 */ updateLockTaskPackages(int userId, String[] packages)765 void updateLockTaskPackages(int userId, String[] packages) { 766 mLockTaskPackages.put(userId, packages); 767 768 boolean taskChanged = false; 769 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 770 final Task lockedTask = mLockTaskModeTasks.get(taskNdx); 771 final boolean wasAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 772 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; 773 lockedTask.setLockTaskAuth(); 774 final boolean isAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 775 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; 776 777 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED 778 || lockedTask.mUserId != userId 779 || !wasAllowlisted || isAllowlisted) { 780 continue; 781 } 782 783 // Terminate locked tasks that have recently lost allowlist authorization. 784 ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: removing %s" 785 + " mLockTaskAuth()=%s", lockedTask, lockedTask.lockTaskAuthToString()); 786 removeLockedTask(lockedTask); 787 lockedTask.performClearTaskForReuse(false /* excludingTaskOverlay*/); 788 taskChanged = true; 789 } 790 791 mSupervisor.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth); 792 793 final ActivityRecord r = mSupervisor.mRootWindowContainer.topRunningActivity(); 794 final Task task = (r != null) ? r.getTask() : null; 795 if (mLockTaskModeTasks.isEmpty() && task!= null 796 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 797 // This task must have just been authorized. 798 ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: starting new " 799 + "locktask task=%s", task); 800 setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false); 801 taskChanged = true; 802 } 803 804 if (taskChanged) { 805 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 806 } 807 } 808 getLockTaskAuth(@ullable ActivityRecord rootActivity, @Nullable Task task)809 int getLockTaskAuth(@Nullable ActivityRecord rootActivity, @Nullable Task task) { 810 if (rootActivity == null && task == null) { 811 return LOCK_TASK_AUTH_DONT_LOCK; 812 } 813 if (rootActivity == null) { 814 return LOCK_TASK_AUTH_PINNABLE; 815 } 816 817 final String pkg = (task == null || task.realActivity == null) ? rootActivity.packageName 818 : task.realActivity.getPackageName(); 819 final int userId = task != null ? task.mUserId : rootActivity.mUserId; 820 int lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; 821 switch (rootActivity.lockTaskLaunchMode) { 822 case LOCK_TASK_LAUNCH_MODE_DEFAULT: 823 lockTaskAuth = isPackageAllowlisted(userId, pkg) 824 ? LOCK_TASK_AUTH_ALLOWLISTED : LOCK_TASK_AUTH_PINNABLE; 825 break; 826 827 case LOCK_TASK_LAUNCH_MODE_NEVER: 828 lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; 829 break; 830 831 case LOCK_TASK_LAUNCH_MODE_ALWAYS: 832 lockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 833 break; 834 835 case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED: 836 lockTaskAuth = isPackageAllowlisted(userId, pkg) 837 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE; 838 break; 839 } 840 return lockTaskAuth; 841 } 842 isPackageAllowlisted(int userId, String pkg)843 boolean isPackageAllowlisted(int userId, String pkg) { 844 if (pkg == null) { 845 return false; 846 } 847 String[] allowlist; 848 allowlist = mLockTaskPackages.get(userId); 849 if (allowlist == null) { 850 return false; 851 } 852 for (String allowlistedPkg : allowlist) { 853 if (pkg.equals(allowlistedPkg)) { 854 return true; 855 } 856 } 857 return false; 858 } 859 860 /** 861 * Update the UI features that are enabled for LockTask mode. 862 * @param userId Which user these feature flags are associated with 863 * @param flags Bitfield of feature flags 864 * @see DevicePolicyManager#setLockTaskFeatures(ComponentName, int) 865 */ updateLockTaskFeatures(int userId, int flags)866 void updateLockTaskFeatures(int userId, int flags) { 867 int oldFlags = getLockTaskFeaturesForUser(userId); 868 if (flags == oldFlags) { 869 return; 870 } 871 872 mLockTaskFeatures.put(userId, flags); 873 if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).mUserId) { 874 mHandler.post(() -> { 875 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 876 setStatusBarState(mLockTaskModeState, userId); 877 setKeyguardState(mLockTaskModeState, userId); 878 } 879 }); 880 } 881 } 882 883 /** 884 * Helper method for configuring the status bar disabled state. 885 * Should only be called on the handler thread to avoid race. 886 */ setStatusBarState(int lockTaskModeState, int userId)887 private void setStatusBarState(int lockTaskModeState, int userId) { 888 IStatusBarService statusBar = getStatusBarService(); 889 if (statusBar == null) { 890 Slog.e(TAG, "Can't find StatusBarService"); 891 return; 892 } 893 894 // Default state, when lockTaskModeState == LOCK_TASK_MODE_NONE 895 int flags1 = StatusBarManager.DISABLE_NONE; 896 int flags2 = StatusBarManager.DISABLE2_NONE; 897 898 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { 899 flags1 = STATUS_BAR_MASK_PINNED; 900 901 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { 902 int lockTaskFeatures = getLockTaskFeaturesForUser(userId); 903 Pair<Integer, Integer> statusBarFlags = getStatusBarDisableFlags(lockTaskFeatures); 904 flags1 = statusBarFlags.first; 905 flags2 = statusBarFlags.second; 906 } 907 908 try { 909 statusBar.disable(flags1, mToken, mContext.getPackageName()); 910 statusBar.disable2(flags2, mToken, mContext.getPackageName()); 911 } catch (RemoteException e) { 912 Slog.e(TAG, "Failed to set status bar flags", e); 913 } 914 } 915 916 /** 917 * Helper method for configuring the keyguard disabled state. 918 * Should only be called on the handler thread to avoid race. 919 */ setKeyguardState(int lockTaskModeState, int userId)920 private void setKeyguardState(int lockTaskModeState, int userId) { 921 mPendingDisableFromDismiss = UserHandle.USER_NULL; 922 if (lockTaskModeState == LOCK_TASK_MODE_NONE) { 923 mWindowManager.reenableKeyguard(mToken, userId); 924 925 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { 926 if (isKeyguardAllowed(userId)) { 927 mWindowManager.reenableKeyguard(mToken, userId); 928 } else { 929 // If keyguard is not secure and it is locked, dismiss the keyguard before 930 // disabling it, which avoids the platform to think the keyguard is still on. 931 if (mWindowManager.isKeyguardLocked() && !mWindowManager.isKeyguardSecure(userId)) { 932 mPendingDisableFromDismiss = userId; 933 mWindowManager.dismissKeyguard(new IKeyguardDismissCallback.Stub() { 934 @Override 935 public void onDismissError() throws RemoteException { 936 Slog.i(TAG, "setKeyguardState: failed to dismiss keyguard"); 937 } 938 939 @Override 940 public void onDismissSucceeded() throws RemoteException { 941 mHandler.post( 942 () -> { 943 if (mPendingDisableFromDismiss == userId) { 944 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, 945 userId); 946 mPendingDisableFromDismiss = UserHandle.USER_NULL; 947 } 948 }); 949 } 950 951 @Override 952 public void onDismissCancelled() throws RemoteException { 953 Slog.i(TAG, "setKeyguardState: dismiss cancelled"); 954 } 955 }, null); 956 } else { 957 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId); 958 } 959 } 960 961 } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED 962 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId); 963 } 964 } 965 966 /** 967 * Helper method for locking the device immediately. This may be necessary when the device 968 * leaves the pinned mode. 969 */ lockKeyguardIfNeeded(int userId)970 private void lockKeyguardIfNeeded(int userId) { 971 if (shouldLockKeyguard(userId)) { 972 mWindowManager.lockNow(null); 973 mWindowManager.dismissKeyguard(null /* callback */, null /* message */); 974 getLockPatternUtils().requireCredentialEntry(USER_ALL); 975 } 976 } 977 shouldLockKeyguard(int userId)978 private boolean shouldLockKeyguard(int userId) { 979 // This functionality should be kept consistent with 980 // com.android.settings.security.ScreenPinningSettings (see b/127605586) 981 try { 982 return Settings.Secure.getIntForUser( 983 mContext.getContentResolver(), 984 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, USER_CURRENT) != 0; 985 } catch (Settings.SettingNotFoundException e) { 986 // Log to SafetyNet for b/127605586 987 android.util.EventLog.writeEvent(0x534e4554, "127605586", -1, ""); 988 return getLockPatternUtils().isSecure(userId); 989 } 990 } 991 992 /** 993 * Translates from LockTask feature flags to StatusBarManager disable and disable2 flags. 994 * @param lockTaskFlags Bitfield of flags as per 995 * {@link DevicePolicyManager#setLockTaskFeatures(ComponentName, int)} 996 * @return A {@link Pair} of {@link StatusBarManager#disable(int)} and 997 * {@link StatusBarManager#disable2(int)} flags 998 */ 999 @VisibleForTesting getStatusBarDisableFlags(int lockTaskFlags)1000 Pair<Integer, Integer> getStatusBarDisableFlags(int lockTaskFlags) { 1001 // Everything is disabled by default 1002 int flags1 = StatusBarManager.DISABLE_MASK; 1003 int flags2 = StatusBarManager.DISABLE2_MASK; 1004 for (int i = STATUS_BAR_FLAG_MAP_LOCKED.size() - 1; i >= 0; i--) { 1005 Pair<Integer, Integer> statusBarFlags = STATUS_BAR_FLAG_MAP_LOCKED.valueAt(i); 1006 if ((STATUS_BAR_FLAG_MAP_LOCKED.keyAt(i) & lockTaskFlags) != 0) { 1007 flags1 &= ~statusBarFlags.first; 1008 flags2 &= ~statusBarFlags.second; 1009 } 1010 } 1011 // Some flags are not used for LockTask purposes, so we mask them 1012 flags1 &= STATUS_BAR_MASK_LOCKED; 1013 return new Pair<>(flags1, flags2); 1014 } 1015 1016 /** 1017 * @param packageName The package to check 1018 * @return Whether the package is the base of any locked task 1019 */ isBaseOfLockedTask(String packageName)1020 boolean isBaseOfLockedTask(String packageName) { 1021 for (int i = 0; i < mLockTaskModeTasks.size(); i++) { 1022 if (packageName.equals(mLockTaskModeTasks.get(i).getBasePackageName())) { 1023 return true; 1024 } 1025 } 1026 return false; 1027 } 1028 1029 /** 1030 * Gets the cached value of LockTask feature flags for a specific user. 1031 */ getLockTaskFeaturesForUser(int userId)1032 private int getLockTaskFeaturesForUser(int userId) { 1033 return mLockTaskFeatures.get(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); 1034 } 1035 1036 // Should only be called on the handler thread 1037 @Nullable getStatusBarService()1038 private IStatusBarService getStatusBarService() { 1039 if (mStatusBarService == null) { 1040 mStatusBarService = IStatusBarService.Stub.asInterface( 1041 ServiceManager.checkService(STATUS_BAR_SERVICE)); 1042 if (mStatusBarService == null) { 1043 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 1044 } 1045 } 1046 return mStatusBarService; 1047 } 1048 1049 // Should only be called on the handler thread 1050 @Nullable getDevicePolicyManager()1051 private IDevicePolicyManager getDevicePolicyManager() { 1052 if (mDevicePolicyManager == null) { 1053 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 1054 ServiceManager.checkService(DEVICE_POLICY_SERVICE)); 1055 if (mDevicePolicyManager == null) { 1056 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 1057 } 1058 } 1059 return mDevicePolicyManager; 1060 } 1061 1062 @NonNull getLockPatternUtils()1063 private LockPatternUtils getLockPatternUtils() { 1064 if (mLockPatternUtils == null) { 1065 // We don't preserve the LPU object to save memory 1066 return new LockPatternUtils(mContext); 1067 } 1068 return mLockPatternUtils; 1069 } 1070 1071 @Nullable getTelecomManager()1072 private TelecomManager getTelecomManager() { 1073 if (mTelecomManager == null) { 1074 // We don't preserve the TelecomManager object to save memory 1075 return mContext.getSystemService(TelecomManager.class); 1076 } 1077 return mTelecomManager; 1078 } 1079 dump(PrintWriter pw, String prefix)1080 public void dump(PrintWriter pw, String prefix) { 1081 pw.println(prefix + "LockTaskController:"); 1082 prefix = prefix + " "; 1083 pw.println(prefix + "mLockTaskModeState=" + lockTaskModeToString()); 1084 pw.println(prefix + "mLockTaskModeTasks="); 1085 for (int i = 0; i < mLockTaskModeTasks.size(); ++i) { 1086 pw.println(prefix + " #" + i + " " + mLockTaskModeTasks.get(i)); 1087 } 1088 pw.println(prefix + "mLockTaskPackages (userId:packages)="); 1089 for (int i = 0; i < mLockTaskPackages.size(); ++i) { 1090 pw.println(prefix + " u" + mLockTaskPackages.keyAt(i) 1091 + ":" + Arrays.toString(mLockTaskPackages.valueAt(i))); 1092 } 1093 pw.println(); 1094 } 1095 lockTaskModeToString()1096 private String lockTaskModeToString() { 1097 switch (mLockTaskModeState) { 1098 case LOCK_TASK_MODE_LOCKED: 1099 return "LOCKED"; 1100 case LOCK_TASK_MODE_PINNED: 1101 return "PINNED"; 1102 case LOCK_TASK_MODE_NONE: 1103 return "NONE"; 1104 default: return "unknown=" + mLockTaskModeState; 1105 } 1106 } 1107 1108 /** Marker class for the token used to disable keyguard. */ 1109 static class LockTaskToken extends Binder { LockTaskToken()1110 private LockTaskToken() { 1111 } 1112 } 1113 } 1114