Home | History | Annotate | Download | only in am
      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.am;
     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_UNDEFINED;
     23 import static android.content.Context.DEVICE_POLICY_SERVICE;
     24 import static android.content.Context.STATUS_BAR_SERVICE;
     25 import static android.content.Intent.ACTION_CALL_EMERGENCY;
     26 import static android.os.UserHandle.USER_ALL;
     27 import static android.os.UserHandle.USER_CURRENT;
     28 import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
     29 import static android.view.Display.DEFAULT_DISPLAY;
     30 
     31 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
     32 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
     33 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
     34 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
     35 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
     36 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
     37 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
     38 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
     39 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
     40 
     41 import android.annotation.NonNull;
     42 import android.annotation.Nullable;
     43 import android.app.Activity;
     44 import android.app.ActivityManager;
     45 import android.app.StatusBarManager;
     46 import android.app.admin.DevicePolicyManager;
     47 import android.app.admin.IDevicePolicyManager;
     48 import android.content.ComponentName;
     49 import android.content.Context;
     50 import android.content.Intent;
     51 import android.os.Binder;
     52 import android.os.Debug;
     53 import android.os.Handler;
     54 import android.os.IBinder;
     55 import android.os.RemoteException;
     56 import android.os.ServiceManager;
     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.statusbar.IStatusBarService;
     67 import com.android.internal.widget.LockPatternUtils;
     68 import com.android.server.LocalServices;
     69 import com.android.server.statusbar.StatusBarManagerInternal;
     70 import com.android.server.wm.WindowManagerService;
     71 
     72 import java.io.PrintWriter;
     73 import java.util.ArrayList;
     74 import java.util.Arrays;
     75 
     76 /**
     77  * Helper class that deals with all things related to task locking. This includes the screen pinning
     78  * mode that can be launched via System UI as well as the fully locked mode that can be achieved
     79  * on fully managed devices.
     80  *
     81  * Note: All methods in this class should only be called with the ActivityManagerService lock held.
     82  *
     83  * @see Activity#startLockTask()
     84  * @see Activity#stopLockTask()
     85  */
     86 public class LockTaskController {
     87     private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_AM;
     88     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
     89 
     90     @VisibleForTesting
     91     static final int STATUS_BAR_MASK_LOCKED = StatusBarManager.DISABLE_MASK
     92             & (~StatusBarManager.DISABLE_EXPAND)
     93             & (~StatusBarManager.DISABLE_NOTIFICATION_TICKER)
     94             & (~StatusBarManager.DISABLE_SYSTEM_INFO)
     95             & (~StatusBarManager.DISABLE_BACK);
     96     @VisibleForTesting
     97     static final int STATUS_BAR_MASK_PINNED = StatusBarManager.DISABLE_MASK
     98             & (~StatusBarManager.DISABLE_BACK)
     99             & (~StatusBarManager.DISABLE_HOME)
    100             & (~StatusBarManager.DISABLE_RECENT);
    101 
    102     private static final SparseArray<Pair<Integer, Integer>> STATUS_BAR_FLAG_MAP_LOCKED;
    103     static {
    104         STATUS_BAR_FLAG_MAP_LOCKED = new SparseArray<>();
    105 
    106         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO,
    107                 new Pair<>(StatusBarManager.DISABLE_CLOCK, StatusBarManager.DISABLE2_SYSTEM_ICONS));
    108 
    109         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS,
    110                 new Pair<>(StatusBarManager.DISABLE_NOTIFICATION_ICONS
    111                         | StatusBarManager.DISABLE_NOTIFICATION_ALERTS,
    112                         StatusBarManager.DISABLE2_NOTIFICATION_SHADE));
    113 
    114         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_HOME,
    115                 new Pair<>(StatusBarManager.DISABLE_HOME, StatusBarManager.DISABLE2_NONE));
    116 
    117         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW,
    118                 new Pair<>(StatusBarManager.DISABLE_RECENT, StatusBarManager.DISABLE2_NONE));
    119 
    120         STATUS_BAR_FLAG_MAP_LOCKED.append(DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
    121                 new Pair<>(StatusBarManager.DISABLE_NONE,
    122                         StatusBarManager.DISABLE2_GLOBAL_ACTIONS));
    123     }
    124 
    125     /** Tag used for disabling of keyguard */
    126     private static final String LOCK_TASK_TAG = "Lock-to-App";
    127 
    128     private final IBinder mToken = new Binder();
    129     private final ActivityStackSupervisor mSupervisor;
    130     private final Context mContext;
    131 
    132     // The following system services cannot be final, because they do not exist when this class
    133     // is instantiated during device boot
    134     @VisibleForTesting
    135     IStatusBarService mStatusBarService;
    136     @VisibleForTesting
    137     IDevicePolicyManager mDevicePolicyManager;
    138     @VisibleForTesting
    139     WindowManagerService mWindowManager;
    140     @VisibleForTesting
    141     LockPatternUtils mLockPatternUtils;
    142     @VisibleForTesting
    143     TelecomManager mTelecomManager;
    144 
    145     /**
    146      * The chain of tasks in LockTask mode, in the order of when they first entered LockTask mode.
    147      *
    148      * The first task in the list, which started the current LockTask session, is called the root
    149      * task. It coincides with the Home task in a typical multi-app kiosk deployment. When there are
    150      * more than one locked tasks, the root task can't be finished. Nor can it be moved to the back
    151      * of the stack by {@link ActivityStack#moveTaskToBackLocked(int)};
    152      *
    153      * Calling {@link Activity#stopLockTask()} on the root task will finish all tasks but itself in
    154      * this list, and the device will exit LockTask mode.
    155      *
    156      * The list is empty if LockTask is inactive.
    157      */
    158     private final ArrayList<TaskRecord> mLockTaskModeTasks = new ArrayList<>();
    159 
    160     /**
    161      * Packages that are allowed to be launched into the lock task mode for each user.
    162      */
    163     private final SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
    164 
    165     /**
    166      * Features that are allowed by DPC to show during LockTask mode.
    167      */
    168     private final SparseIntArray mLockTaskFeatures = new SparseIntArray();
    169 
    170     /**
    171      * Store the current lock task mode. Possible values:
    172      * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
    173      * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
    174      */
    175     private int mLockTaskModeState = LOCK_TASK_MODE_NONE;
    176 
    177     /**
    178      * This is ActivityStackSupervisor's Handler.
    179      */
    180     private final Handler mHandler;
    181 
    182     LockTaskController(Context context, ActivityStackSupervisor supervisor,
    183             Handler handler) {
    184         mContext = context;
    185         mSupervisor = supervisor;
    186         mHandler = handler;
    187     }
    188 
    189     /**
    190      * Set the window manager instance used in this class. This is necessary, because the window
    191      * manager does not exist during instantiation of this class.
    192      */
    193     void setWindowManager(WindowManagerService windowManager) {
    194         mWindowManager = windowManager;
    195     }
    196 
    197     /**
    198      * @return the current lock task state. This can be any of
    199      * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
    200      * {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
    201      */
    202     int getLockTaskModeState() {
    203         return mLockTaskModeState;
    204     }
    205 
    206     /**
    207      * @return whether the given task is locked at the moment. Locked tasks cannot be moved to the
    208      * back of the stack.
    209      */
    210     @VisibleForTesting
    211     boolean isTaskLocked(TaskRecord task) {
    212         return mLockTaskModeTasks.contains(task);
    213     }
    214 
    215     /**
    216      * @return {@code true} whether this task first started the current LockTask session.
    217      */
    218     private boolean isRootTask(TaskRecord task) {
    219         return mLockTaskModeTasks.indexOf(task) == 0;
    220     }
    221 
    222     /**
    223      * @return whether the given activity is blocked from finishing, because it is the only activity
    224      * of the last locked task and finishing it would mean that lock task mode is ended illegally.
    225      */
    226     boolean activityBlockedFromFinish(ActivityRecord activity) {
    227         final TaskRecord task = activity.getTask();
    228         if (activity == task.getRootActivity()
    229                 && activity == task.getTopActivity()
    230                 && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV
    231                 && isRootTask(task)) {
    232             Slog.i(TAG, "Not finishing task in lock task mode");
    233             showLockTaskToast();
    234             return true;
    235         }
    236         return false;
    237     }
    238 
    239     /**
    240      * @return whether the given task can be moved to the back of the stack with
    241      * {@link ActivityStack#moveTaskToBackLocked(int)}
    242      * @see #mLockTaskModeTasks
    243      */
    244     boolean canMoveTaskToBack(TaskRecord task) {
    245         if (isRootTask(task)) {
    246             showLockTaskToast();
    247             return false;
    248         }
    249         return true;
    250     }
    251 
    252     /**
    253      * @return whether the requested task is allowed to be locked (either whitelisted, or declares
    254      * lockTaskMode="always" in the manifest).
    255      */
    256     boolean isTaskWhitelisted(TaskRecord task) {
    257         switch(task.mLockTaskAuth) {
    258             case LOCK_TASK_AUTH_WHITELISTED:
    259             case LOCK_TASK_AUTH_LAUNCHABLE:
    260             case LOCK_TASK_AUTH_LAUNCHABLE_PRIV:
    261                 return true;
    262             case LOCK_TASK_AUTH_PINNABLE:
    263             case LOCK_TASK_AUTH_DONT_LOCK:
    264             default:
    265                 return false;
    266         }
    267     }
    268 
    269     /**
    270      * @return whether the requested task is disallowed to be launched.
    271      */
    272     boolean isLockTaskModeViolation(TaskRecord task) {
    273         return isLockTaskModeViolation(task, false);
    274     }
    275 
    276     /**
    277      * @param isNewClearTask whether the task would be cleared as part of the operation.
    278      * @return whether the requested task is disallowed to be launched.
    279      */
    280     boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) {
    281         if (isLockTaskModeViolationInternal(task, isNewClearTask)) {
    282             showLockTaskToast();
    283             return true;
    284         }
    285         return false;
    286     }
    287 
    288     /**
    289      * @return the root task of the lock task.
    290      */
    291     TaskRecord getRootTask() {
    292         if (mLockTaskModeTasks.isEmpty()) {
    293             return null;
    294         }
    295         return mLockTaskModeTasks.get(0);
    296     }
    297 
    298     private boolean isLockTaskModeViolationInternal(TaskRecord task, boolean isNewClearTask) {
    299         // TODO: Double check what's going on here. If the task is already in lock task mode, it's
    300         // likely whitelisted, so will return false below.
    301         if (isTaskLocked(task) && !isNewClearTask) {
    302             // If the task is already at the top and won't be cleared, then allow the operation
    303             return false;
    304         }
    305 
    306         // Allow recents activity if enabled by policy
    307         if (task.isActivityTypeRecents() && isRecentsAllowed(task.userId)) {
    308             return false;
    309         }
    310 
    311         // Allow emergency calling when the device is protected by a locked keyguard
    312         if (isKeyguardAllowed(task.userId) && isEmergencyCallTask(task)) {
    313             return false;
    314         }
    315 
    316         return !(isTaskWhitelisted(task) || mLockTaskModeTasks.isEmpty());
    317     }
    318 
    319     private boolean isRecentsAllowed(int userId) {
    320         return (getLockTaskFeaturesForUser(userId)
    321                 & DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW) != 0;
    322     }
    323 
    324     private boolean isKeyguardAllowed(int userId) {
    325         return (getLockTaskFeaturesForUser(userId)
    326                 & DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD) != 0;
    327     }
    328 
    329     private boolean isEmergencyCallTask(TaskRecord task) {
    330         final Intent intent = task.intent;
    331         if (intent == null) {
    332             return false;
    333         }
    334 
    335         // 1. The emergency keypad activity launched on top of the keyguard
    336         if (EMERGENCY_DIALER_COMPONENT.equals(intent.getComponent())) {
    337             return true;
    338         }
    339 
    340         // 2. The intent sent by the keypad, which is handled by Telephony
    341         if (ACTION_CALL_EMERGENCY.equals(intent.getAction())) {
    342             return true;
    343         }
    344 
    345         // 3. Telephony then starts the default package for making the call
    346         final TelecomManager tm = getTelecomManager();
    347         final String dialerPackage = tm != null ? tm.getSystemDialerPackage() : null;
    348         if (dialerPackage != null && dialerPackage.equals(intent.getComponent().getPackageName())) {
    349             return true;
    350         }
    351 
    352         return false;
    353     }
    354 
    355     /**
    356      * Stop the current lock task mode.
    357      *
    358      * This is called by {@link ActivityManagerService} and performs various checks before actually
    359      * finishing the locked task.
    360      *
    361      * @param task the task that requested the end of lock task mode ({@code null} for quitting app
    362      *             pinning mode)
    363      * @param isSystemCaller indicates whether this request comes from the system via
    364      *                       {@link ActivityManagerService#stopSystemLockTaskMode()}. If
    365      *                       {@code true}, it means the user intends to stop pinned mode through UI;
    366      *                       otherwise, it's called by an app and we need to stop locked or pinned
    367      *                       mode, subject to checks.
    368      * @param callingUid the caller that requested the end of lock task mode.
    369      * @throws IllegalArgumentException if the calling task is invalid (e.g., {@code null} or not in
    370      *                                  foreground)
    371      * @throws SecurityException if the caller is not authorized to stop the lock task mode, i.e. if
    372      *                           they differ from the one that launched lock task mode.
    373      */
    374     void stopLockTaskMode(@Nullable TaskRecord task, boolean isSystemCaller, int callingUid) {
    375         if (mLockTaskModeState == LOCK_TASK_MODE_NONE) {
    376             return;
    377         }
    378 
    379         if (isSystemCaller) {
    380             if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
    381                 clearLockedTasks("stopAppPinning");
    382             } else {
    383                 Slog.e(TAG_LOCKTASK, "Attempted to stop LockTask with isSystemCaller=true");
    384                 showLockTaskToast();
    385             }
    386 
    387         } else {
    388             // Ensure calling activity is not null
    389             if (task == null) {
    390                 throw new IllegalArgumentException("can't stop LockTask for null task");
    391             }
    392 
    393             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
    394             // It is possible lockTaskMode was started by the system process because
    395             // android:lockTaskMode is set to a locking value in the application manifest
    396             // instead of the app calling startLockTaskMode. In this case
    397             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
    398             // {@link TaskRecord.effectiveUid} instead. Also caller with
    399             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
    400             if (callingUid != task.mLockTaskUid
    401                     && (task.mLockTaskUid != 0 || callingUid != task.effectiveUid)) {
    402                 throw new SecurityException("Invalid uid, expected " + task.mLockTaskUid
    403                         + " callingUid=" + callingUid + " effectiveUid=" + task.effectiveUid);
    404             }
    405 
    406             // We don't care if it's pinned or locked mode; this will stop it anyways.
    407             clearLockedTask(task);
    408         }
    409     }
    410 
    411     /**
    412      * Clear all locked tasks and request the end of LockTask mode.
    413      *
    414      * This method is called by {@link UserController} when starting a new foreground user, and,
    415      * unlike {@link #stopLockTaskMode(TaskRecord, boolean, int)}, it doesn't perform the checks.
    416      */
    417     void clearLockedTasks(String reason) {
    418         if (DEBUG_LOCKTASK) Slog.i(TAG_LOCKTASK, "clearLockedTasks: " + reason);
    419         if (!mLockTaskModeTasks.isEmpty()) {
    420             clearLockedTask(mLockTaskModeTasks.get(0));
    421         }
    422     }
    423 
    424     /**
    425      * Clear one locked task from LockTask mode.
    426      *
    427      * If the requested task is the root task (see {@link #mLockTaskModeTasks}), then all locked
    428      * tasks are cleared. Otherwise, only the requested task is cleared. LockTask mode is stopped
    429      * when the last locked task is cleared.
    430      *
    431      * @param task the task to be cleared from LockTask mode.
    432      */
    433     void clearLockedTask(final TaskRecord task) {
    434         if (task == null || mLockTaskModeTasks.isEmpty()) return;
    435 
    436         if (task == mLockTaskModeTasks.get(0)) {
    437             // We're removing the root task while there are other locked tasks. Therefore we should
    438             // clear all locked tasks in reverse order.
    439             for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx > 0; --taskNdx) {
    440                 clearLockedTask(mLockTaskModeTasks.get(taskNdx));
    441             }
    442         }
    443 
    444         removeLockedTask(task);
    445         if (mLockTaskModeTasks.isEmpty()) {
    446             return;
    447         }
    448         task.performClearTaskLocked();
    449         mSupervisor.resumeFocusedStackTopActivityLocked();
    450     }
    451 
    452     /**
    453      * Remove the given task from the locked task list. If this was the last task in the list,
    454      * lock task mode is stopped.
    455      */
    456     private void removeLockedTask(final TaskRecord task) {
    457         if (!mLockTaskModeTasks.remove(task)) {
    458             return;
    459         }
    460         if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: removed " + task);
    461         if (mLockTaskModeTasks.isEmpty()) {
    462             if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
    463                     " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
    464             mHandler.post(() -> performStopLockTask(task.userId));
    465         }
    466     }
    467 
    468     // This method should only be called on the handler thread
    469     private void performStopLockTask(int userId) {
    470         // When lock task ends, we enable the status bars.
    471         try {
    472             setStatusBarState(LOCK_TASK_MODE_NONE, userId);
    473             setKeyguardState(LOCK_TASK_MODE_NONE, userId);
    474             if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
    475                 lockKeyguardIfNeeded();
    476             }
    477             if (getDevicePolicyManager() != null) {
    478                 getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
    479             }
    480             if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
    481                 getStatusBarService().showPinningEnterExitToast(false /* entering */);
    482             }
    483             mWindowManager.onLockTaskStateChanged(LOCK_TASK_MODE_NONE);
    484         } catch (RemoteException ex) {
    485             throw new RuntimeException(ex);
    486         } finally {
    487             mLockTaskModeState = LOCK_TASK_MODE_NONE;
    488         }
    489     }
    490 
    491     /**
    492      * Show the lock task violation toast. Currently we only show toast for screen pinning mode, and
    493      * no-op if the device is in locked mode.
    494      */
    495     void showLockTaskToast() {
    496         if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
    497             try {
    498                 getStatusBarService().showPinningEscapeToast();
    499             } catch (RemoteException e) {
    500                 Slog.e(TAG, "Failed to send pinning escape toast", e);
    501             }
    502         }
    503     }
    504 
    505     // Starting lock task
    506 
    507     /**
    508      * Method to start lock task mode on a given task.
    509      *
    510      * @param task the task that should be locked.
    511      * @param isSystemCaller indicates whether this request was initiated by the system via
    512      *                       {@link ActivityManagerService#startSystemLockTaskMode(int)}. If
    513      *                       {@code true}, this intends to start pinned mode; otherwise, we look
    514      *                       at the calling task's mLockTaskAuth to decide which mode to start.
    515      * @param callingUid the caller that requested the launch of lock task mode.
    516      */
    517     void startLockTaskMode(@NonNull TaskRecord task, boolean isSystemCaller, int callingUid) {
    518         if (!isSystemCaller) {
    519             task.mLockTaskUid = callingUid;
    520             if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
    521                 // startLockTask() called by app, but app is not part of lock task whitelist. Show
    522                 // app pinning request. We will come back here with isSystemCaller true.
    523                 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
    524                 StatusBarManagerInternal statusBarManager = LocalServices.getService(
    525                         StatusBarManagerInternal.class);
    526                 if (statusBarManager != null) {
    527                     statusBarManager.showScreenPinningRequest(task.taskId);
    528                 }
    529                 return;
    530             }
    531         }
    532 
    533         // System can only initiate screen pinning, not full lock task mode
    534         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
    535                 isSystemCaller ? "Locking pinned" : "Locking fully");
    536         setLockTaskMode(task, isSystemCaller ? LOCK_TASK_MODE_PINNED : LOCK_TASK_MODE_LOCKED,
    537                 "startLockTask", true);
    538     }
    539 
    540     /**
    541      * Start lock task mode on the given task.
    542      * @param lockTaskModeState whether fully locked or pinned mode.
    543      * @param andResume whether the task should be brought to foreground as part of the operation.
    544      */
    545     private void setLockTaskMode(@NonNull TaskRecord task, int lockTaskModeState,
    546                                  String reason, boolean andResume) {
    547         // Should have already been checked, but do it again.
    548         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
    549             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
    550                     "setLockTaskMode: Can't lock due to auth");
    551             return;
    552         }
    553         if (isLockTaskModeViolation(task)) {
    554             Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
    555             return;
    556         }
    557 
    558         final Intent taskIntent = task.intent;
    559         if (mLockTaskModeTasks.isEmpty() && taskIntent != null) {
    560             mSupervisor.mRecentTasks.onLockTaskModeStateChanged(lockTaskModeState, task.userId);
    561             // Start lock task on the handler thread
    562             mHandler.post(() -> performStartLockTask(
    563                     taskIntent.getComponent().getPackageName(),
    564                     task.userId,
    565                     lockTaskModeState));
    566         }
    567         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskMode: Locking to " + task +
    568                 " Callers=" + Debug.getCallers(4));
    569 
    570         if (!mLockTaskModeTasks.contains(task)) {
    571             mLockTaskModeTasks.add(task);
    572         }
    573 
    574         if (task.mLockTaskUid == -1) {
    575             task.mLockTaskUid = task.effectiveUid;
    576         }
    577 
    578         if (andResume) {
    579             mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
    580                     lockTaskModeState != LOCK_TASK_MODE_NONE);
    581             mSupervisor.resumeFocusedStackTopActivityLocked();
    582             mWindowManager.executeAppTransition();
    583         } else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
    584             mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
    585                     DEFAULT_DISPLAY, task.getStack(), true /* forceNonResizable */);
    586         }
    587     }
    588 
    589     // This method should only be called on the handler thread
    590     private void performStartLockTask(String packageName, int userId, int lockTaskModeState) {
    591         // When lock task starts, we disable the status bars.
    592         try {
    593             if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
    594                 getStatusBarService().showPinningEnterExitToast(true /* entering */);
    595             }
    596             mWindowManager.onLockTaskStateChanged(lockTaskModeState);
    597             mLockTaskModeState = lockTaskModeState;
    598             setStatusBarState(lockTaskModeState, userId);
    599             setKeyguardState(lockTaskModeState, userId);
    600             if (getDevicePolicyManager() != null) {
    601                 getDevicePolicyManager().notifyLockTaskModeChanged(true, packageName, userId);
    602             }
    603         } catch (RemoteException ex) {
    604             throw new RuntimeException(ex);
    605         }
    606     }
    607 
    608     /**
    609      * Update packages that are allowed to be launched in lock task mode.
    610      * @param userId Which user this whitelist is associated with
    611      * @param packages The whitelist of packages allowed in lock task mode
    612      * @see #mLockTaskPackages
    613      */
    614     void updateLockTaskPackages(int userId, String[] packages) {
    615         mLockTaskPackages.put(userId, packages);
    616 
    617         boolean taskChanged = false;
    618         for (int taskNdx = mLockTaskModeTasks.size() - 1; taskNdx >= 0; --taskNdx) {
    619             final TaskRecord lockedTask = mLockTaskModeTasks.get(taskNdx);
    620             final boolean wasWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
    621                     || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
    622             lockedTask.setLockTaskAuth();
    623             final boolean isWhitelisted = lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
    624                     || lockedTask.mLockTaskAuth == LOCK_TASK_AUTH_WHITELISTED;
    625 
    626             if (mLockTaskModeState != LOCK_TASK_MODE_LOCKED
    627                     || lockedTask.userId != userId
    628                     || !wasWhitelisted || isWhitelisted) {
    629                 continue;
    630             }
    631 
    632             // Terminate locked tasks that have recently lost whitelist authorization.
    633             if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "onLockTaskPackagesUpdated: removing " +
    634                     lockedTask + " mLockTaskAuth()=" + lockedTask.lockTaskAuthToString());
    635             removeLockedTask(lockedTask);
    636             lockedTask.performClearTaskLocked();
    637             taskChanged = true;
    638         }
    639 
    640         for (int displayNdx = mSupervisor.getChildCount() - 1; displayNdx >= 0; --displayNdx) {
    641             mSupervisor.getChildAt(displayNdx).onLockTaskPackagesUpdated();
    642         }
    643 
    644         final ActivityRecord r = mSupervisor.topRunningActivityLocked();
    645         final TaskRecord task = (r != null) ? r.getTask() : null;
    646         if (mLockTaskModeTasks.isEmpty() && task!= null
    647                 && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
    648             // This task must have just been authorized.
    649             if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK,
    650                     "onLockTaskPackagesUpdated: starting new locktask task=" + task);
    651             setLockTaskMode(task, LOCK_TASK_MODE_LOCKED, "package updated", false);
    652             taskChanged = true;
    653         }
    654 
    655         if (taskChanged) {
    656             mSupervisor.resumeFocusedStackTopActivityLocked();
    657         }
    658     }
    659 
    660     boolean isPackageWhitelisted(int userId, String pkg) {
    661         if (pkg == null) {
    662             return false;
    663         }
    664         String[] whitelist;
    665         whitelist = mLockTaskPackages.get(userId);
    666         if (whitelist == null) {
    667             return false;
    668         }
    669         for (String whitelistedPkg : whitelist) {
    670             if (pkg.equals(whitelistedPkg)) {
    671                 return true;
    672             }
    673         }
    674         return false;
    675     }
    676 
    677     /**
    678      * Update the UI features that are enabled for LockTask mode.
    679      * @param userId Which user these feature flags are associated with
    680      * @param flags Bitfield of feature flags
    681      * @see DevicePolicyManager#setLockTaskFeatures(ComponentName, int)
    682      */
    683     void updateLockTaskFeatures(int userId, int flags) {
    684         int oldFlags = getLockTaskFeaturesForUser(userId);
    685         if (flags == oldFlags) {
    686             return;
    687         }
    688 
    689         mLockTaskFeatures.put(userId, flags);
    690         if (!mLockTaskModeTasks.isEmpty() && userId == mLockTaskModeTasks.get(0).userId) {
    691             mHandler.post(() -> {
    692                 if (mLockTaskModeState == LOCK_TASK_MODE_LOCKED) {
    693                     setStatusBarState(mLockTaskModeState, userId);
    694                     setKeyguardState(mLockTaskModeState, userId);
    695                 }
    696             });
    697         }
    698     }
    699 
    700     /**
    701      * Helper method for configuring the status bar disabled state.
    702      * Should only be called on the handler thread to avoid race.
    703      */
    704     private void setStatusBarState(int lockTaskModeState, int userId) {
    705         IStatusBarService statusBar = getStatusBarService();
    706         if (statusBar == null) {
    707             Slog.e(TAG, "Can't find StatusBarService");
    708             return;
    709         }
    710 
    711         // Default state, when lockTaskModeState == LOCK_TASK_MODE_NONE
    712         int flags1 = StatusBarManager.DISABLE_NONE;
    713         int flags2 = StatusBarManager.DISABLE2_NONE;
    714 
    715         if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
    716             flags1 = STATUS_BAR_MASK_PINNED;
    717 
    718         } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) {
    719             int lockTaskFeatures = getLockTaskFeaturesForUser(userId);
    720             Pair<Integer, Integer> statusBarFlags = getStatusBarDisableFlags(lockTaskFeatures);
    721             flags1 = statusBarFlags.first;
    722             flags2 = statusBarFlags.second;
    723         }
    724 
    725         try {
    726             statusBar.disable(flags1, mToken, mContext.getPackageName());
    727             statusBar.disable2(flags2, mToken, mContext.getPackageName());
    728         } catch (RemoteException e) {
    729             Slog.e(TAG, "Failed to set status bar flags", e);
    730         }
    731     }
    732 
    733     /**
    734      * Helper method for configuring the keyguard disabled state.
    735      * Should only be called on the handler thread to avoid race.
    736      */
    737     private void setKeyguardState(int lockTaskModeState, int userId) {
    738         if (lockTaskModeState == LOCK_TASK_MODE_NONE) {
    739             mWindowManager.reenableKeyguard(mToken);
    740 
    741         } else if (lockTaskModeState == LOCK_TASK_MODE_LOCKED) {
    742             if (isKeyguardAllowed(userId)) {
    743                 mWindowManager.reenableKeyguard(mToken);
    744             } else {
    745                 // If keyguard is not secure and it is locked, dismiss the keyguard before
    746                 // disabling it, which avoids the platform to think the keyguard is still on.
    747                 if (mWindowManager.isKeyguardLocked() && !mWindowManager.isKeyguardSecure()) {
    748                     mWindowManager.dismissKeyguard(new IKeyguardDismissCallback.Stub() {
    749                         @Override
    750                         public void onDismissError() throws RemoteException {
    751                             Slog.i(TAG, "setKeyguardState: failed to dismiss keyguard");
    752                         }
    753 
    754                         @Override
    755                         public void onDismissSucceeded() throws RemoteException {
    756                             mHandler.post(
    757                                     () -> mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG));
    758                         }
    759 
    760                         @Override
    761                         public void onDismissCancelled() throws RemoteException {
    762                             Slog.i(TAG, "setKeyguardState: dismiss cancelled");
    763                         }
    764                     }, null);
    765                 } else {
    766                     mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
    767                 }
    768             }
    769 
    770         } else { // lockTaskModeState == LOCK_TASK_MODE_PINNED
    771             mWindowManager.disableKeyguard(mToken, LOCK_TASK_TAG);
    772         }
    773     }
    774 
    775     /**
    776      * Helper method for locking the device immediately. This may be necessary when the device
    777      * leaves the pinned mode.
    778      */
    779     private void lockKeyguardIfNeeded() {
    780         try {
    781             boolean shouldLockKeyguard = Settings.Secure.getIntForUser(
    782                     mContext.getContentResolver(),
    783                     Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
    784                     USER_CURRENT) != 0;
    785             if (shouldLockKeyguard) {
    786                 mWindowManager.lockNow(null);
    787                 mWindowManager.dismissKeyguard(null /* callback */, null /* message */);
    788                 getLockPatternUtils().requireCredentialEntry(USER_ALL);
    789             }
    790         } catch (Settings.SettingNotFoundException e) {
    791             // No setting, don't lock.
    792         }
    793     }
    794 
    795     /**
    796      * Translates from LockTask feature flags to StatusBarManager disable and disable2 flags.
    797      * @param lockTaskFlags Bitfield of flags as per
    798      *                      {@link DevicePolicyManager#setLockTaskFeatures(ComponentName, int)}
    799      * @return A {@link Pair} of {@link StatusBarManager#disable(int)} and
    800      *         {@link StatusBarManager#disable2(int)} flags
    801      */
    802     @VisibleForTesting
    803     Pair<Integer, Integer> getStatusBarDisableFlags(int lockTaskFlags) {
    804         // Everything is disabled by default
    805         int flags1 = StatusBarManager.DISABLE_MASK;
    806         int flags2 = StatusBarManager.DISABLE2_MASK;
    807         for (int i = STATUS_BAR_FLAG_MAP_LOCKED.size() - 1; i >= 0; i--) {
    808             Pair<Integer, Integer> statusBarFlags = STATUS_BAR_FLAG_MAP_LOCKED.valueAt(i);
    809             if ((STATUS_BAR_FLAG_MAP_LOCKED.keyAt(i) & lockTaskFlags) != 0) {
    810                 flags1 &= ~statusBarFlags.first;
    811                 flags2 &= ~statusBarFlags.second;
    812             }
    813         }
    814         // Some flags are not used for LockTask purposes, so we mask them
    815         flags1 &= STATUS_BAR_MASK_LOCKED;
    816         return new Pair<>(flags1, flags2);
    817     }
    818 
    819     /**
    820      * Gets the cached value of LockTask feature flags for a specific user.
    821      */
    822     private int getLockTaskFeaturesForUser(int userId) {
    823         return mLockTaskFeatures.get(userId, DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
    824     }
    825 
    826     // Should only be called on the handler thread
    827     @Nullable
    828     private IStatusBarService getStatusBarService() {
    829         if (mStatusBarService == null) {
    830             mStatusBarService = IStatusBarService.Stub.asInterface(
    831                     ServiceManager.checkService(STATUS_BAR_SERVICE));
    832             if (mStatusBarService == null) {
    833                 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
    834             }
    835         }
    836         return mStatusBarService;
    837     }
    838 
    839     // Should only be called on the handler thread
    840     @Nullable
    841     private IDevicePolicyManager getDevicePolicyManager() {
    842         if (mDevicePolicyManager == null) {
    843             mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
    844                     ServiceManager.checkService(DEVICE_POLICY_SERVICE));
    845             if (mDevicePolicyManager == null) {
    846                 Slog.w(TAG, "warning: no DEVICE_POLICY_SERVICE");
    847             }
    848         }
    849         return mDevicePolicyManager;
    850     }
    851 
    852     @NonNull
    853     private LockPatternUtils getLockPatternUtils() {
    854         if (mLockPatternUtils == null) {
    855             // We don't preserve the LPU object to save memory
    856             return new LockPatternUtils(mContext);
    857         }
    858         return mLockPatternUtils;
    859     }
    860 
    861     @Nullable
    862     private TelecomManager getTelecomManager() {
    863         if (mTelecomManager == null) {
    864             // We don't preserve the TelecomManager object to save memory
    865             return mContext.getSystemService(TelecomManager.class);
    866         }
    867         return mTelecomManager;
    868     }
    869 
    870     public void dump(PrintWriter pw, String prefix) {
    871         pw.println(prefix + "LockTaskController");
    872         prefix = prefix + "  ";
    873         pw.println(prefix + "mLockTaskModeState=" + lockTaskModeToString());
    874         pw.println(prefix + "mLockTaskModeTasks=");
    875         for (int i = 0; i < mLockTaskModeTasks.size(); ++i) {
    876             pw.println(prefix + "  #" + i + " " + mLockTaskModeTasks.get(i));
    877         }
    878         pw.println(prefix + "mLockTaskPackages (userId:packages)=");
    879         for (int i = 0; i < mLockTaskPackages.size(); ++i) {
    880             pw.println(prefix + "  u" + mLockTaskPackages.keyAt(i)
    881                     + ":" + Arrays.toString(mLockTaskPackages.valueAt(i)));
    882         }
    883     }
    884 
    885     private String lockTaskModeToString() {
    886         switch (mLockTaskModeState) {
    887             case LOCK_TASK_MODE_LOCKED:
    888                 return "LOCKED";
    889             case LOCK_TASK_MODE_PINNED:
    890                 return "PINNED";
    891             case LOCK_TASK_MODE_NONE:
    892                 return "NONE";
    893             default: return "unknown=" + mLockTaskModeState;
    894         }
    895     }
    896 }
    897