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.ProtoLogGroup.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.common.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 final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); 267 if (taskFragment.asTask() != null 268 || !taskFragment.isDelayLastActivityRemoval() 269 || adjacentTaskFragment == null) { 270 // Don't block activity from finishing if the TaskFragment don't have any adjacent 271 // TaskFragment, or it won't finish together with its adjacent TaskFragment. 272 return false; 273 } 274 275 final boolean hasOtherActivityInTaskFragment = 276 taskFragment.getActivity(a -> !a.finishing && a != activity) != null; 277 if (hasOtherActivityInTaskFragment) { 278 // Don't block activity from finishing if there's other Activity in the same 279 // TaskFragment. 280 return false; 281 } 282 283 final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing 284 && a != activity && a.getTaskFragment() != adjacentTaskFragment) != null; 285 if (hasOtherActivityInTask) { 286 // Do not block activity from finishing if there are another running activities 287 // after the current and adjacent TaskFragments are removed. Note that we don't 288 // check activities in adjacent TaskFragment because it will be finished together 289 // with TaskFragment regardless of numbers of activities. 290 return false; 291 } 292 } 293 294 Slog.i(TAG, "Not finishing task in lock task mode"); 295 showLockTaskToast(); 296 return true; 297 } 298 299 /** 300 * @return whether the given task can be moved to the back of the stack with 301 * {@link Task#moveTaskToBack(Task)} 302 * @see #mLockTaskModeTasks 303 */ canMoveTaskToBack(Task task)304 boolean canMoveTaskToBack(Task task) { 305 if (isRootTask(task)) { 306 showLockTaskToast(); 307 return false; 308 } 309 return true; 310 } 311 312 /** 313 * @return whether the requested task auth is allowed to be locked. 314 */ isTaskAuthAllowlisted(int lockTaskAuth)315 static boolean isTaskAuthAllowlisted(int lockTaskAuth) { 316 switch(lockTaskAuth) { 317 case LOCK_TASK_AUTH_ALLOWLISTED: 318 case LOCK_TASK_AUTH_LAUNCHABLE: 319 case LOCK_TASK_AUTH_LAUNCHABLE_PRIV: 320 return true; 321 case LOCK_TASK_AUTH_PINNABLE: 322 case LOCK_TASK_AUTH_DONT_LOCK: 323 default: 324 return false; 325 } 326 } 327 328 /** 329 * @return whether the requested task is disallowed to be launched. 330 */ isLockTaskModeViolation(Task task)331 boolean isLockTaskModeViolation(Task task) { 332 return isLockTaskModeViolation(task, false); 333 } 334 335 /** 336 * @param isNewClearTask whether the task would be cleared as part of the operation. 337 * @return whether the requested task is disallowed to be launched. 338 */ isLockTaskModeViolation(Task task, boolean isNewClearTask)339 boolean isLockTaskModeViolation(Task task, boolean isNewClearTask) { 340 // TODO: Double check what's going on here. If the task is already in lock task mode, it's 341 // likely allowlisted, so will return false below. 342 if (isTaskLocked(task) && !isNewClearTask) { 343 // If the task is already at the top and won't be cleared, then allow the operation 344 } else if (isLockTaskModeViolationInternal(task, task.mUserId, task.intent, 345 task.mLockTaskAuth)) { 346 showLockTaskToast(); 347 return true; 348 } 349 return false; 350 } 351 352 /** 353 * @param activity an activity that is going to be started in a new task as the root activity. 354 * @return whether the given activity is allowed to be launched. 355 */ isNewTaskLockTaskModeViolation(ActivityRecord activity)356 boolean isNewTaskLockTaskModeViolation(ActivityRecord activity) { 357 // Use the belong task (if any) to perform the lock task checks 358 if (activity.getTask() != null) { 359 return isLockTaskModeViolation(activity.getTask()); 360 } 361 362 int auth = getLockTaskAuth(activity, null /* task */); 363 if (isLockTaskModeViolationInternal(activity, activity.mUserId, activity.intent, auth)) { 364 showLockTaskToast(); 365 return true; 366 } 367 return false; 368 } 369 370 /** 371 * @return the root task of the lock task. 372 */ getRootTask()373 Task getRootTask() { 374 if (mLockTaskModeTasks.isEmpty()) { 375 return null; 376 } 377 return mLockTaskModeTasks.get(0); 378 } 379 isLockTaskModeViolationInternal(WindowContainer wc, int userId, Intent intent, int taskAuth)380 private boolean isLockTaskModeViolationInternal(WindowContainer wc, int userId, 381 Intent intent, int taskAuth) { 382 // Allow recents activity if enabled by policy 383 if (wc.isActivityTypeRecents() && isRecentsAllowed(userId)) { 384 return false; 385 } 386 387 // Allow emergency calling when the device is protected by a locked keyguard 388 if (isKeyguardAllowed(userId) && isEmergencyCallIntent(intent)) { 389 return false; 390 } 391 392 // Allow the dream to start during lock task mode 393 if (wc.isActivityTypeDream()) { 394 return false; 395 } 396 397 if (isWirelessEmergencyAlert(intent)) { 398 return false; 399 } 400 401 return !(isTaskAuthAllowlisted(taskAuth) || mLockTaskModeTasks.isEmpty()); 402 } 403 isRecentsAllowed(int userId)404 private boolean isRecentsAllowed(int userId) { 405 return (getLockTaskFeaturesForUser(userId) 406 & DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW) != 0; 407 } 408 isKeyguardAllowed(int userId)409 private boolean isKeyguardAllowed(int userId) { 410 return (getLockTaskFeaturesForUser(userId) 411 & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0; 412 } 413 isBlockingInTaskEnabled(int userId)414 private boolean isBlockingInTaskEnabled(int userId) { 415 return (getLockTaskFeaturesForUser(userId) 416 & DevicePolicyManager.LOCK_TASK_FEATURE_BLOCK_ACTIVITY_START_IN_TASK) != 0; 417 } 418 isActivityAllowed(int userId, String packageName, int lockTaskLaunchMode)419 boolean isActivityAllowed(int userId, String packageName, int lockTaskLaunchMode) { 420 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED || !isBlockingInTaskEnabled(userId)) { 421 return true; 422 } 423 switch (lockTaskLaunchMode) { 424 case LOCK_TASK_LAUNCH_MODE_ALWAYS: 425 return true; 426 case LOCK_TASK_LAUNCH_MODE_NEVER: 427 return false; 428 default: 429 } 430 return isPackageAllowlisted(userId, packageName); 431 } 432 isWirelessEmergencyAlert(Intent intent)433 private boolean isWirelessEmergencyAlert(Intent intent) { 434 if (intent == null) { 435 return false; 436 } 437 438 final ComponentName cellBroadcastAlertDialogComponentName = 439 CellBroadcastUtils.getDefaultCellBroadcastAlertDialogComponent(mContext); 440 441 if (cellBroadcastAlertDialogComponentName == null) { 442 return false; 443 } 444 445 if (cellBroadcastAlertDialogComponentName.equals(intent.getComponent())) { 446 return true; 447 } 448 449 return false; 450 } 451 isEmergencyCallIntent(Intent intent)452 private boolean isEmergencyCallIntent(Intent intent) { 453 if (intent == null) { 454 return false; 455 } 456 457 // 1. The emergency keypad activity launched on top of the keyguard 458 if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) { 459 return true; 460 } 461 462 // 2. The intent sent by the keypad, which is handled by Telephony 463 if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) { 464 return true; 465 } 466 467 // 3. Telephony then starts the default package for making the call 468 final TelecomManager tm = getTelecomManager(); 469 final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null; 470 if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) { 471 return true; 472 } 473 474 return false; 475 } 476 477 /** 478 * Stop the current lock task mode. 479 * 480 * This is called by {@link ActivityManagerService} and performs various checks before actually 481 * finishing the locked task. 482 * 483 * @param task the task that requested the end of lock task mode ({@code null} for quitting app 484 * pinning mode) 485 * @param stopAppPinning indicates whether to stop app pinning mode or to stop a task from 486 * being locked. 487 * @param callingUid the caller that requested the end of lock task mode. 488 * @throws IllegalArgumentException if the calling task is invalid (e.g., {@code null} or not in 489 * foreground) 490 * @throws SecurityException if the caller is not authorized to stop the lock task mode, i.e. if 491 * they differ from the one that launched lock task mode. 492 */ stopLockTaskMode(@ullable Task task, boolean stopAppPinning, int callingUid)493 void stopLockTaskMode(@Nullable Task task, boolean stopAppPinning, int callingUid) { 494 if (mLockTaskModeState == LOCK_TASK_MODE_NONE) { 495 return; 496 } 497 498 if (stopAppPinning) { 499 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 500 clearLockedTasks("stopAppPinning"); 501 } else { 502 Slog.e(TAG_LOCKTASK, "Attempted to stop app pinning while fully locked"); 503 showLockTaskToast(); 504 } 505 506 } else { 507 // Ensure calling activity is not null 508 if (task == null) { 509 throw new IllegalArgumentException("can't stop LockTask for null task"); 510 } 511 512 // Ensure the same caller for startLockTaskMode and stopLockTaskMode. 513 // It is possible lockTaskMode was started by the system process because 514 // android:lockTaskMode is set to a locking value in the application manifest 515 // instead of the app calling startLockTaskMode. In this case 516 // {@link Task.mLockTaskUid} will be 0, so we compare the callingUid to the 517 // {@link Task.effectiveUid} instead. Also caller with 518 // {@link MANAGE_ACTIVITY_TASKS} can stop any lock task. 519 if (callingUid != task.mLockTaskUid 520 && (task.mLockTaskUid != 0 || callingUid != task.effectiveUid)) { 521 throw new SecurityException("Invalid uid, expected " + task.mLockTaskUid 522 + " callingUid=" + callingUid + " effectiveUid=" + task.effectiveUid); 523 } 524 525 // We don't care if it's pinned or locked mode; this will stop it anyways. 526 clearLockedTask(task); 527 } 528 } 529 530 /** 531 * Clear all locked tasks and request the end of LockTask mode. 532 * 533 * This method is called by UserController when starting a new foreground user, and, 534 * unlike {@link #stopLockTaskMode(Task, boolean, int)}, it doesn't perform the checks. 535 */ clearLockedTasks(String reason)536 void clearLockedTasks(String reason) { 537 ProtoLog.i(WM_DEBUG_LOCKTASK, "clearLockedTasks: %s", reason); 538 if (!mLockTaskModeTasks.isEmpty()) { 539 clearLockedTask(mLockTaskModeTasks.get(0)); 540 } 541 } 542 543 /** 544 * Clear one locked task from LockTask mode. 545 * 546 * If the requested task is the root task (see {@link #mLockTaskModeTasks}), then all locked 547 * tasks are cleared. Otherwise, only the requested task is cleared. LockTask mode is stopped 548 * when the last locked task is cleared. 549 * 550 * @param task the task to be cleared from LockTask mode. 551 */ clearLockedTask(final Task task)552 void clearLockedTask(final Task task) { 553 if (task == null || mLockTaskModeTasks.isEmpty()) return; 554 555 if (task == mLockTaskModeTasks.get(0)) { 556 // We're removing the root task while there are other locked tasks. Therefore we should 557 // clear all locked tasks in reverse order. 558 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx > 0; --taskNdx) { 559 clearLockedTask(mLockTaskModeTasks.get(taskNdx)); 560 } 561 } 562 563 removeLockedTask(task); 564 if (mLockTaskModeTasks.isEmpty()) { 565 return; 566 } 567 task.performClearTaskForReuse(false /* excludingTaskOverlay*/); 568 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 569 } 570 571 /** 572 * Remove the given task from the locked task list. If this was the last task in the list, 573 * lock task mode is stopped. 574 */ removeLockedTask(final Task task)575 private void removeLockedTask(final Task task) { 576 if (!mLockTaskModeTasks.remove(task)) { 577 return; 578 } 579 ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: removed %s", task); 580 if (mLockTaskModeTasks.isEmpty()) { 581 ProtoLog.d(WM_DEBUG_LOCKTASK, "removeLockedTask: task=%s last task, " 582 + "reverting locktask mode. Callers=%s", task, Debug.getCallers(3)); 583 mHandler.post(() -> performStopLockTask(task.mUserId)); 584 } 585 } 586 587 // This method should only be called on the handler thread performStopLockTask(int userId)588 private void performStopLockTask(int userId) { 589 // Update the internal mLockTaskModeState early to avoid the scenario that SysUI queries 590 // mLockTaskModeState (from setStatusBarState) and gets staled state. 591 // TODO: revisit this approach. 592 // The race condition raised above can be addressed by moving this function out of handler 593 // thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState. 594 final int oldLockTaskModeState = mLockTaskModeState; 595 mLockTaskModeState = LOCK_TASK_MODE_NONE; 596 mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); 597 // When lock task ends, we enable the status bars. 598 try { 599 setStatusBarState(mLockTaskModeState, userId); 600 setKeyguardState(mLockTaskModeState, userId); 601 if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) { 602 lockKeyguardIfNeeded(userId); 603 } 604 if (getDevicePolicyManager() != null) { 605 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId); 606 } 607 if (oldLockTaskModeState == LOCK_TASK_MODE_PINNED) { 608 final IStatusBarService statusBarService = getStatusBarService(); 609 if (statusBarService != null) { 610 statusBarService.showPinningEnterExitToast(false /* entering */); 611 } 612 } 613 mWindowManager.onLockTaskStateChanged(mLockTaskModeState); 614 } catch (RemoteException ex) { 615 throw new RuntimeException(ex); 616 } 617 } 618 619 /** 620 * Show the lock task violation toast. Currently we only show toast for screen pinning mode, and 621 * no-op if the device is in locked mode. 622 */ showLockTaskToast()623 void showLockTaskToast() { 624 if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 625 try { 626 final IStatusBarService statusBarService = getStatusBarService(); 627 if (statusBarService != null) { 628 statusBarService.showPinningEscapeToast(); 629 } 630 } catch (RemoteException e) { 631 Slog.e(TAG, "Failed to send pinning escape toast", e); 632 } 633 } 634 } 635 636 // Starting lock task 637 638 /** 639 * Method to start lock task mode on a given task. 640 * 641 * @param task the task that should be locked. 642 * @param isSystemCaller indicates whether this request was initiated by the system via 643 * {@link ActivityTaskManagerService#startSystemLockTaskMode(int)}. If 644 * {@code true}, this intends to start pinned mode; otherwise, we look 645 * at the calling task's mLockTaskAuth to decide which mode to start. 646 * @param callingUid the caller that requested the launch of lock task mode. 647 */ startLockTaskMode(@onNull Task task, boolean isSystemCaller, int callingUid)648 void startLockTaskMode(@NonNull Task task, boolean isSystemCaller, int callingUid) { 649 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 650 ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskMode: Can't lock due to auth"); 651 return; 652 } 653 if (!isSystemCaller) { 654 task.mLockTaskUid = callingUid; 655 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { 656 // startLockTask() called by app, but app is not part of lock task allowlist. Show 657 // app pinning request. We will come back here with isSystemCaller true. 658 ProtoLog.w(WM_DEBUG_LOCKTASK, "Mode default, asking user"); 659 StatusBarManagerInternal statusBarManager = LocalServices.getService( 660 StatusBarManagerInternal.class); 661 if (statusBarManager != null) { 662 statusBarManager.showScreenPinningRequest(task.mTaskId); 663 } 664 return; 665 } else if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) { 666 // startLockTask() called by app, and app is part of lock task allowlist. 667 // Deactivate the currently pinned task before doing so. 668 Slog.i(TAG, "Stop app pinning before entering full lock task mode"); 669 stopLockTaskMode(/* task= */ null, /* stopAppPinning= */ true, callingUid); 670 } 671 } 672 673 // When a task is locked, dismiss the root pinned task if it exists 674 mSupervisor.mRootWindowContainer.removeRootTasksInWindowingModes(WINDOWING_MODE_PINNED); 675 676 // System can only initiate screen pinning, not full lock task mode 677 ProtoLog.w(WM_DEBUG_LOCKTASK, "%s", isSystemCaller ? "Locking pinned" : "Locking fully"); 678 setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED, 679 "startLockTask", true); 680 } 681 682 /** 683 * Start lock task mode on the given task. 684 * @param lockTaskModeState whether fully locked or pinned mode. 685 * @param andResume whether the task should be brought to foreground as part of the operation. 686 */ setLockTaskMode(@onNull Task task, int lockTaskModeState, String reason, boolean andResume)687 private void setLockTaskMode(@NonNull Task task, int lockTaskModeState, 688 String reason, boolean andResume) { 689 // Should have already been checked, but do it again. 690 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 691 ProtoLog.w(WM_DEBUG_LOCKTASK, 692 "setLockTaskMode: Can't lock due to auth"); 693 return; 694 } 695 if (isLockTaskModeViolation(task)) { 696 Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task."); 697 return; 698 } 699 700 final Intent taskIntent = task.intent; 701 if (mLockTaskModeTasks.isEmpty() && taskIntent != null) { 702 mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.mUserId); 703 // Start lock task on the handler thread 704 mHandler.post(() -> performStartLockTask( 705 taskIntent.getComponent().getPackageName(), 706 task.mUserId, 707 lockTaskModeState)); 708 } 709 ProtoLog.w(WM_DEBUG_LOCKTASK, "setLockTaskMode: Locking to %s Callers=%s", 710 task, Debug.getCallers(4)); 711 712 if (!mLockTaskModeTasks.contains(task)) { 713 mLockTaskModeTasks.add(task); 714 } 715 716 if (task.mLockTaskUid == -1) { 717 task.mLockTaskUid = task.effectiveUid; 718 } 719 720 if (andResume) { 721 mSupervisor.findTaskToMoveToFront(task, 0, null, reason, 722 lockTaskModeState != LOCK_TASK_MODE_NONE); 723 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 724 final Task rootTask = task.getRootTask(); 725 if (rootTask != null) { 726 rootTask.mDisplayContent.executeAppTransition(); 727 } 728 } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) { 729 mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED, 730 mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(), 731 task.getRootTask(), true /* forceNonResizable */); 732 } 733 } 734 735 // This method should only be called on the handler thread performStartLockTask(String packageName, int userId, int lockTaskModeState)736 private void performStartLockTask(String packageName, int userId, int lockTaskModeState) { 737 // When lock task starts, we disable the status bars. 738 try { 739 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { 740 final IStatusBarService statusBarService = getStatusBarService(); 741 if (statusBarService != null) { 742 statusBarService.showPinningEnterExitToast(true /* entering */); 743 } 744 } 745 mWindowManager.onLockTaskStateChanged(lockTaskModeState); 746 mLockTaskModeState = lockTaskModeState; 747 mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); 748 setStatusBarState(lockTaskModeState, userId); 749 setKeyguardState(lockTaskModeState, userId); 750 if (getDevicePolicyManager() != null) { 751 getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId); 752 } 753 } catch (RemoteException ex) { 754 throw new RuntimeException(ex); 755 } 756 } 757 758 /** 759 * Update packages that are allowed to be launched in lock task mode. 760 * @param userId Which user this allowlist is associated with 761 * @param packages The allowlist of packages allowed in lock task mode 762 * @see #mLockTaskPackages 763 */ updateLockTaskPackages(int userId, String[] packages)764 void updateLockTaskPackages(int userId, String[] packages) { 765 mLockTaskPackages.put(userId, packages); 766 767 boolean taskChanged = false; 768 for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) { 769 final Task lockedTask = mLockTaskModeTasks.get(taskNdx); 770 final boolean wasAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 771 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; 772 lockedTask.setLockTaskAuth(); 773 final boolean isAllowlisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE 774 || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_ALLOWLISTED; 775 776 if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED 777 || lockedTask.mUserId != userId 778 || !wasAllowlisted || isAllowlisted) { 779 continue; 780 } 781 782 // Terminate locked tasks that have recently lost allowlist authorization. 783 ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: removing %s" 784 + " mLockTaskAuth()=%s", lockedTask, lockedTask.lockTaskAuthToString()); 785 removeLockedTask(lockedTask); 786 lockedTask.performClearTaskForReuse(false /* excludingTaskOverlay*/); 787 taskChanged = true; 788 } 789 790 mSupervisor.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth); 791 792 final ActivityRecord r = mSupervisor.mRootWindowContainer.topRunningActivity(); 793 final Task task = (r != null) ? r.getTask() : null; 794 if (mLockTaskModeTasks.isEmpty() && task!= null 795 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) { 796 // This task must have just been authorized. 797 ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: starting new " 798 + "locktask task=%s", task); 799 setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false); 800 taskChanged = true; 801 } 802 803 if (taskChanged) { 804 mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities(); 805 } 806 } 807 getLockTaskAuth(@ullable ActivityRecord rootActivity, @Nullable Task task)808 int getLockTaskAuth(@Nullable ActivityRecord rootActivity, @Nullable Task task) { 809 if (rootActivity == null && task == null) { 810 return LOCK_TASK_AUTH_DONT_LOCK; 811 } 812 if (rootActivity == null) { 813 return LOCK_TASK_AUTH_PINNABLE; 814 } 815 816 final String pkg = (task == null || task.realActivity == null) ? rootActivity.packageName 817 : task.realActivity.getPackageName(); 818 final int userId = task != null ? task.mUserId : rootActivity.mUserId; 819 int lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; 820 switch (rootActivity.lockTaskLaunchMode) { 821 case LOCK_TASK_LAUNCH_MODE_DEFAULT: 822 lockTaskAuth = isPackageAllowlisted(userId, pkg) 823 ? LOCK_TASK_AUTH_ALLOWLISTED : LOCK_TASK_AUTH_PINNABLE; 824 break; 825 826 case LOCK_TASK_LAUNCH_MODE_NEVER: 827 lockTaskAuth = LOCK_TASK_AUTH_DONT_LOCK; 828 break; 829 830 case LOCK_TASK_LAUNCH_MODE_ALWAYS: 831 lockTaskAuth = LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 832 break; 833 834 case LOCK_TASK_LAUNCH_MODE_IF_ALLOWLISTED: 835 lockTaskAuth = isPackageAllowlisted(userId, pkg) 836 ? LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE; 837 break; 838 } 839 return lockTaskAuth; 840 } 841 isPackageAllowlisted(int userId, String pkg)842 boolean isPackageAllowlisted(int userId, String pkg) { 843 if (pkg == null) { 844 return false; 845 } 846 String[] allowlist; 847 allowlist = mLockTaskPackages.get(userId); 848 if (allowlist == null) { 849 return false; 850 } 851 for (String allowlistedPkg : allowlist) { 852 if (pkg.equals(allowlistedPkg)) { 853 return true; 854 } 855 } 856 return false; 857 } 858 859 /** 860 * Update the UI features that are enabled for LockTask mode. 861 * @param userId Which user these feature flags are associated with 862 * @param flags Bitfield of feature flags 863 * @see DevicePolicyManager#setLockTaskFeatures(ComponentName, int) 864 */ updateLockTaskFeatures(int userId, int flags)865 void updateLockTaskFeatures(int userId, int flags) { 866 int oldFlags = getLockTaskFeaturesForUser(userId); 867 if (flags == oldFlags) { 868 return; 869 } 870 871 mLockTaskFeatures.put(userId, flags); 872 if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).mUserId) { 873 mHandler.post(() -> { 874 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) { 875 setStatusBarState(mLockTaskModeState, userId); 876 setKeyguardState(mLockTaskModeState, userId); 877 } 878 }); 879 } 880 } 881 882 /** 883 * Helper method for configuring the status bar disabled state. 884 * Should only be called on the handler thread to avoid race. 885 */ setStatusBarState(int lockTaskModeState, int userId)886 private void setStatusBarState(int lockTaskModeState, int userId) { 887 IStatusBarService statusBar = getStatusBarService(); 888 if (statusBar == null) { 889 Slog.e(TAG, "Can't find StatusBarService"); 890 return; 891 } 892 893 // Default state, when lockTaskModeState == LOCK_TASK_MODE_NONE 894 int flags1 = StatusBarManager.DISABLE_NONE; 895 int flags2 = StatusBarManager.DISABLE2_NONE; 896 897 if (lockTaskModeState == LOCK_TASK_MODE_PINNED) { 898 flags1 = STATUS_BAR_MASK_PINNED; 899 900 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { 901 int lockTaskFeatures = getLockTaskFeaturesForUser(userId); 902 Pair<Integer, Integer> statusBarFlags = getStatusBarDisableFlags(lockTaskFeatures); 903 flags1 = statusBarFlags.first; 904 flags2 = statusBarFlags.second; 905 } 906 907 try { 908 statusBar.disable(flags1, mToken, mContext.getPackageName()); 909 statusBar.disable2(flags2, mToken, mContext.getPackageName()); 910 } catch (RemoteException e) { 911 Slog.e(TAG, "Failed to set status bar flags", e); 912 } 913 } 914 915 /** 916 * Helper method for configuring the keyguard disabled state. 917 * Should only be called on the handler thread to avoid race. 918 */ setKeyguardState(int lockTaskModeState, int userId)919 private void setKeyguardState(int lockTaskModeState, int userId) { 920 mPendingDisableFromDismiss = UserHandle.USER_NULL; 921 if (lockTaskModeState == LOCK_TASK_MODE_NONE) { 922 mWindowManager.reenableKeyguard(mToken, userId); 923 924 } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) { 925 if (isKeyguardAllowed(userId)) { 926 mWindowManager.reenableKeyguard(mToken, userId); 927 } else { 928 // If keyguard is not secure and it is locked, dismiss the keyguard before 929 // disabling it, which avoids the platform to think the keyguard is still on. 930 if (mWindowManager.isKeyguardLocked() && !mWindowManager.isKeyguardSecure(userId)) { 931 mPendingDisableFromDismiss = userId; 932 mWindowManager.dismissKeyguard(new IKeyguardDismissCallback.Stub() { 933 @Override 934 public void onDismissError() throws RemoteException { 935 Slog.i(TAG, "setKeyguardState: failed to dismiss keyguard"); 936 } 937 938 @Override 939 public void onDismissSucceeded() throws RemoteException { 940 mHandler.post( 941 () -> { 942 if (mPendingDisableFromDismiss == userId) { 943 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, 944 userId); 945 mPendingDisableFromDismiss = UserHandle.USER_NULL; 946 } 947 }); 948 } 949 950 @Override 951 public void onDismissCancelled() throws RemoteException { 952 Slog.i(TAG, "setKeyguardState: dismiss cancelled"); 953 } 954 }, null); 955 } else { 956 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId); 957 } 958 } 959 960 } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED 961 mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG, userId); 962 } 963 } 964 965 /** 966 * Helper method for locking the device immediately. This may be necessary when the device 967 * leaves the pinned mode. 968 */ lockKeyguardIfNeeded(int userId)969 private void lockKeyguardIfNeeded(int userId) { 970 if (shouldLockKeyguard(userId)) { 971 mWindowManager.lockNow(null); 972 mWindowManager.dismissKeyguard(null /* callback */, null /* message */); 973 getLockPatternUtils().requireCredentialEntry(USER_ALL); 974 } 975 } 976 shouldLockKeyguard(int userId)977 private boolean shouldLockKeyguard(int userId) { 978 // This functionality should be kept consistent with 979 // com.android.settings.security.ScreenPinningSettings (see b/127605586) 980 try { 981 return Settings.Secure.getIntForUser( 982 mContext.getContentResolver(), 983 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, USER_CURRENT) != 0; 984 } catch (Settings.SettingNotFoundException e) { 985 // Log to SafetyNet for b/127605586 986 android.util.EventLog.writeEvent(0x534e4554, "127605586", -1, ""); 987 return getLockPatternUtils().isSecure(userId); 988 } 989 } 990 991 /** 992 * Translates from LockTask feature flags to StatusBarManager disable and disable2 flags. 993 * @param lockTaskFlags Bitfield of flags as per 994 * {@link DevicePolicyManager#setLockTaskFeatures(ComponentName, int)} 995 * @return A {@link Pair} of {@link StatusBarManager#disable(int)} and 996 * {@link StatusBarManager#disable2(int)} flags 997 */ 998 @VisibleForTesting getStatusBarDisableFlags(int lockTaskFlags)999 Pair<Integer, Integer> getStatusBarDisableFlags(int lockTaskFlags) { 1000 // Everything is disabled by default 1001 int flags1 = StatusBarManager.DISABLE_MASK; 1002 int flags2 = StatusBarManager.DISABLE2_MASK; 1003 for (int i = STATUS_BAR_FLAG_MAP_LOCKED.size() - 1; i >= 0; i--) { 1004 Pair<Integer, Integer> statusBarFlags = STATUS_BAR_FLAG_MAP_LOCKED.valueAt(i); 1005 if ((STATUS_BAR_FLAG_MAP_LOCKED.keyAt(i) & lockTaskFlags) != 0) { 1006 flags1 &= ~statusBarFlags.first; 1007 flags2 &= ~statusBarFlags.second; 1008 } 1009 } 1010 // Some flags are not used for LockTask purposes, so we mask them 1011 flags1 &= STATUS_BAR_MASK_LOCKED; 1012 return new Pair<>(flags1, flags2); 1013 } 1014 1015 /** 1016 * @param packageName The package to check 1017 * @return Whether the package is the base of any locked task 1018 */ isBaseOfLockedTask(String packageName)1019 boolean isBaseOfLockedTask(String packageName) { 1020 for (int i = 0; i < mLockTaskModeTasks.size(); i++) { 1021 if (packageName.equals(mLockTaskModeTasks.get(i).getBasePackageName())) { 1022 return true; 1023 } 1024 } 1025 return false; 1026 } 1027 1028 /** 1029 * Gets the cached value of LockTask feature flags for a specific user. 1030 */ getLockTaskFeaturesForUser(int userId)1031 private int getLockTaskFeaturesForUser(int userId) { 1032 return mLockTaskFeatures.get(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE); 1033 } 1034 1035 // Should only be called on the handler thread 1036 @Nullable getStatusBarService()1037 private IStatusBarService getStatusBarService() { 1038 if (mStatusBarService == null) { 1039 mStatusBarService = IStatusBarService.Stub.asInterface( 1040 ServiceManager.checkService(STATUS_BAR_SERVICE)); 1041 if (mStatusBarService == null) { 1042 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE"); 1043 } 1044 } 1045 return mStatusBarService; 1046 } 1047 1048 // Should only be called on the handler thread 1049 @Nullable getDevicePolicyManager()1050 private IDevicePolicyManager getDevicePolicyManager() { 1051 if (mDevicePolicyManager == null) { 1052 mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface( 1053 ServiceManager.checkService(DEVICE_POLICY_SERVICE)); 1054 if (mDevicePolicyManager == null) { 1055 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE"); 1056 } 1057 } 1058 return mDevicePolicyManager; 1059 } 1060 1061 @NonNull getLockPatternUtils()1062 private LockPatternUtils getLockPatternUtils() { 1063 if (mLockPatternUtils == null) { 1064 // We don't preserve the LPU object to save memory 1065 return new LockPatternUtils(mContext); 1066 } 1067 return mLockPatternUtils; 1068 } 1069 1070 @Nullable getTelecomManager()1071 private TelecomManager getTelecomManager() { 1072 if (mTelecomManager == null) { 1073 // We don't preserve the TelecomManager object to save memory 1074 return mContext.getSystemService(TelecomManager.class); 1075 } 1076 return mTelecomManager; 1077 } 1078 dump(PrintWriter pw, String prefix)1079 public void dump(PrintWriter pw, String prefix) { 1080 pw.println(prefix + "LockTaskController:"); 1081 prefix = prefix + " "; 1082 pw.println(prefix + "mLockTaskModeState=" + lockTaskModeToString()); 1083 pw.println(prefix + "mLockTaskModeTasks="); 1084 for (int i = 0; i < mLockTaskModeTasks.size(); ++i) { 1085 pw.println(prefix + " #" + i + " " + mLockTaskModeTasks.get(i)); 1086 } 1087 pw.println(prefix + "mLockTaskPackages (userId:packages)="); 1088 for (int i = 0; i < mLockTaskPackages.size(); ++i) { 1089 pw.println(prefix + " u" + mLockTaskPackages.keyAt(i) 1090 + ":" + Arrays.toString(mLockTaskPackages.valueAt(i))); 1091 } 1092 pw.println(); 1093 } 1094 lockTaskModeToString()1095 private String lockTaskModeToString() { 1096 switch (mLockTaskModeState) { 1097 case LOCK_TASK_MODE_LOCKED: 1098 return "LOCKED"; 1099 case LOCK_TASK_MODE_PINNED: 1100 return "PINNED"; 1101 case LOCK_TASK_MODE_NONE: 1102 return "NONE"; 1103 default: return "unknown=" + mLockTaskModeState; 1104 } 1105 } 1106 1107 /** Marker class for the token used to disable keyguard. */ 1108 static class LockTaskToken extends Binder { LockTaskToken()1109 private LockTaskToken() { 1110 } 1111 } 1112 } 1113