Home | History | Annotate | Download | only in trust
      1 /*
      2  * Copyright (C) 2014 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.trust;
     18 
     19 import android.Manifest;
     20 import android.annotation.UserIdInt;
     21 import android.app.ActivityManager;
     22 import android.app.admin.DevicePolicyManager;
     23 import android.app.trust.ITrustListener;
     24 import android.app.trust.ITrustManager;
     25 import android.content.BroadcastReceiver;
     26 import android.content.ComponentName;
     27 import android.content.Context;
     28 import android.content.Intent;
     29 import android.content.IntentFilter;
     30 import android.content.pm.ApplicationInfo;
     31 import android.content.pm.PackageManager;
     32 import android.content.pm.ResolveInfo;
     33 import android.content.pm.UserInfo;
     34 import android.content.res.Resources;
     35 import android.content.res.TypedArray;
     36 import android.content.res.XmlResourceParser;
     37 import android.graphics.drawable.Drawable;
     38 import android.os.Binder;
     39 import android.os.Build;
     40 import android.os.DeadObjectException;
     41 import android.os.Handler;
     42 import android.os.IBinder;
     43 import android.os.Message;
     44 import android.os.PersistableBundle;
     45 import android.os.RemoteException;
     46 import android.os.SystemClock;
     47 import android.os.UserHandle;
     48 import android.os.UserManager;
     49 import android.os.storage.StorageManager;
     50 import android.provider.Settings;
     51 import android.service.trust.TrustAgentService;
     52 import android.util.ArraySet;
     53 import android.util.AttributeSet;
     54 import android.util.Log;
     55 import android.util.Slog;
     56 import android.util.SparseBooleanArray;
     57 import android.util.Xml;
     58 import android.view.IWindowManager;
     59 import android.view.WindowManagerGlobal;
     60 import com.android.internal.annotations.GuardedBy;
     61 import com.android.internal.content.PackageMonitor;
     62 import com.android.internal.util.DumpUtils;
     63 import com.android.internal.widget.LockPatternUtils;
     64 import com.android.server.SystemService;
     65 import java.io.FileDescriptor;
     66 import java.io.IOException;
     67 import java.io.PrintWriter;
     68 import java.util.ArrayList;
     69 import java.util.List;
     70 import org.xmlpull.v1.XmlPullParser;
     71 import org.xmlpull.v1.XmlPullParserException;
     72 
     73 /**
     74  * Manages trust agents and trust listeners.
     75  *
     76  * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
     77  * of each user and notifies them about events that are relevant to them.
     78  * It start and stops them based on the value of
     79  * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
     80  *
     81  * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
     82  * trust state changes for any user.
     83  *
     84  * Trust state and the setting of enabled agents is kept per user and each user has its own
     85  * instance of a {@link android.service.trust.TrustAgentService}.
     86  */
     87 public class TrustManagerService extends SystemService {
     88     private static final String TAG = "TrustManagerService";
     89     static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
     90 
     91     private static final Intent TRUST_AGENT_INTENT =
     92             new Intent(TrustAgentService.SERVICE_INTERFACE);
     93     private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
     94 
     95     private static final int MSG_REGISTER_LISTENER = 1;
     96     private static final int MSG_UNREGISTER_LISTENER = 2;
     97     private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
     98     private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
     99     private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
    100     private static final int MSG_START_USER = 7;
    101     private static final int MSG_CLEANUP_USER = 8;
    102     private static final int MSG_SWITCH_USER = 9;
    103     private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
    104     private static final int MSG_UNLOCK_USER = 11;
    105     private static final int MSG_STOP_USER = 12;
    106     private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
    107 
    108     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
    109 
    110     private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
    111     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
    112     private final Receiver mReceiver = new Receiver();
    113 
    114     /* package */ final TrustArchive mArchive = new TrustArchive();
    115     private final Context mContext;
    116     private final LockPatternUtils mLockPatternUtils;
    117     private final UserManager mUserManager;
    118     private final ActivityManager mActivityManager;
    119 
    120     @GuardedBy("mUserIsTrusted")
    121     private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
    122 
    123     @GuardedBy("mDeviceLockedForUser")
    124     private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
    125 
    126     @GuardedBy("mDeviceLockedForUser")
    127     private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
    128 
    129     private final StrongAuthTracker mStrongAuthTracker;
    130 
    131     private boolean mTrustAgentsCanRun = false;
    132     private int mCurrentUser = UserHandle.USER_SYSTEM;
    133 
    134     public TrustManagerService(Context context) {
    135         super(context);
    136         mContext = context;
    137         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    138         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    139         mLockPatternUtils = new LockPatternUtils(context);
    140         mStrongAuthTracker = new StrongAuthTracker(context);
    141     }
    142 
    143     @Override
    144     public void onStart() {
    145         publishBinderService(Context.TRUST_SERVICE, mService);
    146     }
    147 
    148     @Override
    149     public void onBootPhase(int phase) {
    150         if (isSafeMode()) {
    151             // No trust agents in safe mode.
    152             return;
    153         }
    154         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
    155             mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
    156             mReceiver.register(mContext);
    157             mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
    158         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
    159             mTrustAgentsCanRun = true;
    160             refreshAgentList(UserHandle.USER_ALL);
    161             refreshDeviceLockedForUser(UserHandle.USER_ALL);
    162         } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
    163             maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
    164         }
    165     }
    166 
    167     // Agent management
    168 
    169     private static final class AgentInfo {
    170         CharSequence label;
    171         Drawable icon;
    172         ComponentName component; // service that implements ITrustAgent
    173         SettingsAttrs settings; // setting to launch to modify agent.
    174         TrustAgentWrapper agent;
    175         int userId;
    176 
    177         @Override
    178         public boolean equals(Object other) {
    179             if (!(other instanceof AgentInfo)) {
    180                 return false;
    181             }
    182             AgentInfo o = (AgentInfo) other;
    183             return component.equals(o.component) && userId == o.userId;
    184         }
    185 
    186         @Override
    187         public int hashCode() {
    188             return component.hashCode() * 31 + userId;
    189         }
    190     }
    191 
    192     private void updateTrustAll() {
    193         List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
    194         for (UserInfo userInfo : userInfos) {
    195             updateTrust(userInfo.id, 0);
    196         }
    197     }
    198 
    199     public void updateTrust(int userId, int flags) {
    200         boolean managed = aggregateIsTrustManaged(userId);
    201         dispatchOnTrustManagedChanged(managed, userId);
    202         if (mStrongAuthTracker.isTrustAllowedForUser(userId)
    203                 && isTrustUsuallyManagedInternal(userId) != managed) {
    204             updateTrustUsuallyManaged(userId, managed);
    205         }
    206         boolean trusted = aggregateIsTrusted(userId);
    207         boolean changed;
    208         synchronized (mUserIsTrusted) {
    209             changed = mUserIsTrusted.get(userId) != trusted;
    210             mUserIsTrusted.put(userId, trusted);
    211         }
    212         dispatchOnTrustChanged(trusted, userId, flags);
    213         if (changed) {
    214             refreshDeviceLockedForUser(userId);
    215         }
    216     }
    217 
    218     private void updateTrustUsuallyManaged(int userId, boolean managed) {
    219         synchronized (mTrustUsuallyManagedForUser) {
    220             mTrustUsuallyManagedForUser.put(userId, managed);
    221         }
    222         // Wait a few minutes before committing to flash, in case the trust agent is transiently not
    223         // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
    224         mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
    225         mHandler.sendMessageDelayed(
    226                 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
    227                 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
    228     }
    229 
    230     public long addEscrowToken(byte[] token, int userId) {
    231         return mLockPatternUtils.addEscrowToken(token, userId);
    232     }
    233 
    234     public boolean removeEscrowToken(long handle, int userId) {
    235         return mLockPatternUtils.removeEscrowToken(handle, userId);
    236     }
    237 
    238     public boolean isEscrowTokenActive(long handle, int userId) {
    239         return mLockPatternUtils.isEscrowTokenActive(handle, userId);
    240     }
    241 
    242     public void unlockUserWithToken(long handle, byte[] token, int userId) {
    243         mLockPatternUtils.unlockUserWithToken(handle, token, userId);
    244     }
    245 
    246     void refreshAgentList(int userIdOrAll) {
    247         if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
    248         if (!mTrustAgentsCanRun) {
    249             return;
    250         }
    251         if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
    252             Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
    253                     + " must be USER_ALL or a specific user.", new Throwable("here"));
    254             userIdOrAll = UserHandle.USER_ALL;
    255         }
    256         PackageManager pm = mContext.getPackageManager();
    257 
    258         List<UserInfo> userInfos;
    259         if (userIdOrAll == UserHandle.USER_ALL) {
    260             userInfos = mUserManager.getUsers(true /* excludeDying */);
    261         } else {
    262             userInfos = new ArrayList<>();
    263             userInfos.add(mUserManager.getUserInfo(userIdOrAll));
    264         }
    265         LockPatternUtils lockPatternUtils = mLockPatternUtils;
    266 
    267         ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
    268         obsoleteAgents.addAll(mActiveAgents);
    269 
    270         for (UserInfo userInfo : userInfos) {
    271             if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
    272                     || userInfo.guestToRemove) continue;
    273             if (!userInfo.supportsSwitchToByUser()) {
    274                 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    275                         + ": switchToByUser=false");
    276                 continue;
    277             }
    278             if (!mActivityManager.isUserRunning(userInfo.id)) {
    279                 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    280                         + ": user not started");
    281                 continue;
    282             }
    283             if (!lockPatternUtils.isSecure(userInfo.id)) {
    284                 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    285                         + ": no secure credential");
    286                 continue;
    287             }
    288 
    289             DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
    290             int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
    291             final boolean disableTrustAgents =
    292                     (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
    293 
    294             List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
    295             if (enabledAgents == null) {
    296                 if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    297                         + ": no agents enabled by user");
    298                 continue;
    299             }
    300             List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
    301             for (ResolveInfo resolveInfo : resolveInfos) {
    302                 ComponentName name = getComponentName(resolveInfo);
    303 
    304                 if (!enabledAgents.contains(name)) {
    305                     if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
    306                             + name.flattenToShortString() + " u"+ userInfo.id
    307                             + ": not enabled by user");
    308                     continue;
    309                 }
    310                 if (disableTrustAgents) {
    311                     List<PersistableBundle> config =
    312                             dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
    313                     // Disable agent if no features are enabled.
    314                     if (config == null || config.isEmpty()) {
    315                         if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
    316                                 + name.flattenToShortString() + " u"+ userInfo.id
    317                                 + ": not allowed by DPM");
    318                         continue;
    319                     }
    320                 }
    321                 AgentInfo agentInfo = new AgentInfo();
    322                 agentInfo.component = name;
    323                 agentInfo.userId = userInfo.id;
    324                 if (!mActiveAgents.contains(agentInfo)) {
    325                     agentInfo.label = resolveInfo.loadLabel(pm);
    326                     agentInfo.icon = resolveInfo.loadIcon(pm);
    327                     agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
    328                 } else {
    329                     int index = mActiveAgents.indexOf(agentInfo);
    330                     agentInfo = mActiveAgents.valueAt(index);
    331                 }
    332 
    333                 boolean directUnlock = resolveInfo.serviceInfo.directBootAware
    334                     && agentInfo.settings.canUnlockProfile;
    335 
    336                 if (directUnlock) {
    337                     if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
    338                             + "of user " + userInfo.id + "can unlock user profile.");
    339                 }
    340 
    341                 if (!StorageManager.isUserKeyUnlocked(userInfo.id)
    342                         && !directUnlock) {
    343                     if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    344                             + "'s trust agent " + name + ": FBE still locked and "
    345                             + " the agent cannot unlock user profile.");
    346                     continue;
    347                 }
    348 
    349                 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
    350                     int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
    351                     if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
    352                         if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
    353                             || !directUnlock) {
    354                             if (DEBUG)
    355                                 Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
    356                                     + ": prevented by StrongAuthTracker = 0x"
    357                                     + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
    358                                     userInfo.id)));
    359                             continue;
    360                         }
    361                     }
    362                 }
    363 
    364                 if (agentInfo.agent == null) {
    365                     agentInfo.agent = new TrustAgentWrapper(mContext, this,
    366                             new Intent().setComponent(name), userInfo.getUserHandle());
    367                 }
    368 
    369                 if (!mActiveAgents.contains(agentInfo)) {
    370                     mActiveAgents.add(agentInfo);
    371                 } else {
    372                     obsoleteAgents.remove(agentInfo);
    373                 }
    374             }
    375         }
    376 
    377         boolean trustMayHaveChanged = false;
    378         for (int i = 0; i < obsoleteAgents.size(); i++) {
    379             AgentInfo info = obsoleteAgents.valueAt(i);
    380             if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
    381                 if (info.agent.isManagingTrust()) {
    382                     trustMayHaveChanged = true;
    383                 }
    384                 info.agent.destroy();
    385                 mActiveAgents.remove(info);
    386             }
    387         }
    388 
    389         if (trustMayHaveChanged) {
    390             if (userIdOrAll == UserHandle.USER_ALL) {
    391                 updateTrustAll();
    392             } else {
    393                 updateTrust(userIdOrAll, 0);
    394             }
    395         }
    396     }
    397 
    398     boolean isDeviceLockedInner(int userId) {
    399         synchronized (mDeviceLockedForUser) {
    400             return mDeviceLockedForUser.get(userId, true);
    401         }
    402     }
    403 
    404     private void refreshDeviceLockedForUser(int userId) {
    405         if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
    406             Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
    407                     + " must be USER_ALL or a specific user.", new Throwable("here"));
    408             userId = UserHandle.USER_ALL;
    409         }
    410 
    411         List<UserInfo> userInfos;
    412         if (userId == UserHandle.USER_ALL) {
    413             userInfos = mUserManager.getUsers(true /* excludeDying */);
    414         } else {
    415             userInfos = new ArrayList<>();
    416             userInfos.add(mUserManager.getUserInfo(userId));
    417         }
    418 
    419         IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
    420 
    421         for (int i = 0; i < userInfos.size(); i++) {
    422             UserInfo info = userInfos.get(i);
    423 
    424             if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
    425                     || !info.supportsSwitchToByUser()) {
    426                 continue;
    427             }
    428 
    429             int id = info.id;
    430             boolean secure = mLockPatternUtils.isSecure(id);
    431             boolean trusted = aggregateIsTrusted(id);
    432             boolean showingKeyguard = true;
    433             if (mCurrentUser == id) {
    434                 try {
    435                     showingKeyguard = wm.isKeyguardLocked();
    436                 } catch (RemoteException e) {
    437                 }
    438             }
    439             boolean deviceLocked = secure && showingKeyguard && !trusted;
    440             setDeviceLockedForUser(id, deviceLocked);
    441         }
    442     }
    443 
    444     private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
    445         final boolean changed;
    446         synchronized (mDeviceLockedForUser) {
    447             changed = isDeviceLockedInner(userId) != locked;
    448             mDeviceLockedForUser.put(userId, locked);
    449         }
    450         if (changed) {
    451             dispatchDeviceLocked(userId, locked);
    452         }
    453     }
    454 
    455     private void dispatchDeviceLocked(int userId, boolean isLocked) {
    456         for (int i = 0; i < mActiveAgents.size(); i++) {
    457             AgentInfo agent = mActiveAgents.valueAt(i);
    458             if (agent.userId == userId) {
    459                 if (isLocked) {
    460                     agent.agent.onDeviceLocked();
    461                 } else{
    462                     agent.agent.onDeviceUnlocked();
    463                 }
    464             }
    465         }
    466     }
    467 
    468     void updateDevicePolicyFeatures() {
    469         boolean changed = false;
    470         for (int i = 0; i < mActiveAgents.size(); i++) {
    471             AgentInfo info = mActiveAgents.valueAt(i);
    472             if (info.agent.isConnected()) {
    473                 info.agent.updateDevicePolicyFeatures();
    474                 changed = true;
    475             }
    476         }
    477         if (changed) {
    478             mArchive.logDevicePolicyChanged();
    479         }
    480     }
    481 
    482     private void removeAgentsOfPackage(String packageName) {
    483         boolean trustMayHaveChanged = false;
    484         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    485             AgentInfo info = mActiveAgents.valueAt(i);
    486             if (packageName.equals(info.component.getPackageName())) {
    487                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    488                 if (info.agent.isManagingTrust()) {
    489                     trustMayHaveChanged = true;
    490                 }
    491                 info.agent.destroy();
    492                 mActiveAgents.removeAt(i);
    493             }
    494         }
    495         if (trustMayHaveChanged) {
    496             updateTrustAll();
    497         }
    498     }
    499 
    500     public void resetAgent(ComponentName name, int userId) {
    501         boolean trustMayHaveChanged = false;
    502         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    503             AgentInfo info = mActiveAgents.valueAt(i);
    504             if (name.equals(info.component) && userId == info.userId) {
    505                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    506                 if (info.agent.isManagingTrust()) {
    507                     trustMayHaveChanged = true;
    508                 }
    509                 info.agent.destroy();
    510                 mActiveAgents.removeAt(i);
    511             }
    512         }
    513         if (trustMayHaveChanged) {
    514             updateTrust(userId, 0);
    515         }
    516         refreshAgentList(userId);
    517     }
    518 
    519     private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
    520         if (resolveInfo == null || resolveInfo.serviceInfo == null
    521                 || resolveInfo.serviceInfo.metaData == null) return null;
    522         String cn = null;
    523         boolean canUnlockProfile = false;
    524 
    525         XmlResourceParser parser = null;
    526         Exception caughtException = null;
    527         try {
    528             parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
    529                     TrustAgentService.TRUST_AGENT_META_DATA);
    530             if (parser == null) {
    531                 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
    532                 return null;
    533             }
    534             Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
    535             AttributeSet attrs = Xml.asAttributeSet(parser);
    536             int type;
    537             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
    538                     && type != XmlPullParser.START_TAG) {
    539                 // Drain preamble.
    540             }
    541             String nodeName = parser.getName();
    542             if (!"trust-agent".equals(nodeName)) {
    543                 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
    544                 return null;
    545             }
    546             TypedArray sa = res
    547                     .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
    548             cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
    549             canUnlockProfile = sa.getBoolean(
    550                     com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
    551             sa.recycle();
    552         } catch (PackageManager.NameNotFoundException e) {
    553             caughtException = e;
    554         } catch (IOException e) {
    555             caughtException = e;
    556         } catch (XmlPullParserException e) {
    557             caughtException = e;
    558         } finally {
    559             if (parser != null) parser.close();
    560         }
    561         if (caughtException != null) {
    562             Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
    563             return null;
    564         }
    565         if (cn == null) {
    566             return null;
    567         }
    568         if (cn.indexOf('/') < 0) {
    569             cn = resolveInfo.serviceInfo.packageName + "/" + cn;
    570         }
    571         return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
    572     }
    573 
    574     private ComponentName getComponentName(ResolveInfo resolveInfo) {
    575         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
    576         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
    577     }
    578 
    579     private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
    580         if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
    581                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
    582             return;
    583         }
    584         PackageManager pm = mContext.getPackageManager();
    585         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
    586         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
    587         for (ResolveInfo resolveInfo : resolveInfos) {
    588             ComponentName componentName = getComponentName(resolveInfo);
    589             int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
    590             if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    591                 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
    592                         + "is not a system package.");
    593                 continue;
    594             }
    595             discoveredAgents.add(componentName);
    596         }
    597 
    598         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
    599         if (previouslyEnabledAgents != null) {
    600             discoveredAgents.addAll(previouslyEnabledAgents);
    601         }
    602         utils.setEnabledTrustAgents(discoveredAgents, userId);
    603         Settings.Secure.putIntForUser(mContext.getContentResolver(),
    604                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
    605     }
    606 
    607     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
    608         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
    609                 PackageManager.GET_META_DATA |
    610                 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
    611                 userId);
    612         ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
    613         for (ResolveInfo resolveInfo : resolveInfos) {
    614             if (resolveInfo.serviceInfo == null) continue;
    615             if (resolveInfo.serviceInfo.applicationInfo == null) continue;
    616             String packageName = resolveInfo.serviceInfo.packageName;
    617             if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
    618                     != PackageManager.PERMISSION_GRANTED) {
    619                 ComponentName name = getComponentName(resolveInfo);
    620                 Log.w(TAG, "Skipping agent " + name + " because package does not have"
    621                         + " permission " + PERMISSION_PROVIDE_AGENT + ".");
    622                 continue;
    623             }
    624             allowedAgents.add(resolveInfo);
    625         }
    626         return allowedAgents;
    627     }
    628 
    629     // Agent dispatch and aggregation
    630 
    631     private boolean aggregateIsTrusted(int userId) {
    632         if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
    633             return false;
    634         }
    635         for (int i = 0; i < mActiveAgents.size(); i++) {
    636             AgentInfo info = mActiveAgents.valueAt(i);
    637             if (info.userId == userId) {
    638                 if (info.agent.isTrusted()) {
    639                     return true;
    640                 }
    641             }
    642         }
    643         return false;
    644     }
    645 
    646     private boolean aggregateIsTrustManaged(int userId) {
    647         if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
    648             return false;
    649         }
    650         for (int i = 0; i < mActiveAgents.size(); i++) {
    651             AgentInfo info = mActiveAgents.valueAt(i);
    652             if (info.userId == userId) {
    653                 if (info.agent.isManagingTrust()) {
    654                     return true;
    655                 }
    656             }
    657         }
    658         return false;
    659     }
    660 
    661     private void dispatchUnlockAttempt(boolean successful, int userId) {
    662         if (successful) {
    663             mStrongAuthTracker.allowTrustFromUnlock(userId);
    664         }
    665 
    666         for (int i = 0; i < mActiveAgents.size(); i++) {
    667             AgentInfo info = mActiveAgents.valueAt(i);
    668             if (info.userId == userId) {
    669                 info.agent.onUnlockAttempt(successful);
    670             }
    671         }
    672     }
    673 
    674     private void dispatchUnlockLockout(int timeoutMs, int userId) {
    675         for (int i = 0; i < mActiveAgents.size(); i++) {
    676             AgentInfo info = mActiveAgents.valueAt(i);
    677             if (info.userId == userId) {
    678                 info.agent.onUnlockLockout(timeoutMs);
    679             }
    680         }
    681     }
    682 
    683     // Listeners
    684 
    685     private void addListener(ITrustListener listener) {
    686         for (int i = 0; i < mTrustListeners.size(); i++) {
    687             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    688                 return;
    689             }
    690         }
    691         mTrustListeners.add(listener);
    692         updateTrustAll();
    693     }
    694 
    695     private void removeListener(ITrustListener listener) {
    696         for (int i = 0; i < mTrustListeners.size(); i++) {
    697             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    698                 mTrustListeners.remove(i);
    699                 return;
    700             }
    701         }
    702     }
    703 
    704     private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
    705         if (DEBUG) {
    706             Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
    707                     + Integer.toHexString(flags) + ")");
    708         }
    709         if (!enabled) flags = 0;
    710         for (int i = 0; i < mTrustListeners.size(); i++) {
    711             try {
    712                 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
    713             } catch (DeadObjectException e) {
    714                 Slog.d(TAG, "Removing dead TrustListener.");
    715                 mTrustListeners.remove(i);
    716                 i--;
    717             } catch (RemoteException e) {
    718                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    719             }
    720         }
    721     }
    722 
    723     private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
    724         if (DEBUG) {
    725             Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
    726         }
    727         for (int i = 0; i < mTrustListeners.size(); i++) {
    728             try {
    729                 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
    730             } catch (DeadObjectException e) {
    731                 Slog.d(TAG, "Removing dead TrustListener.");
    732                 mTrustListeners.remove(i);
    733                 i--;
    734             } catch (RemoteException e) {
    735                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    736             }
    737         }
    738     }
    739 
    740     // User lifecycle
    741 
    742     @Override
    743     public void onStartUser(int userId) {
    744         mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
    745     }
    746 
    747     @Override
    748     public void onCleanupUser(int userId) {
    749         mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
    750     }
    751 
    752     @Override
    753     public void onSwitchUser(int userId) {
    754         mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
    755     }
    756 
    757     @Override
    758     public void onUnlockUser(int userId) {
    759         mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
    760     }
    761 
    762     @Override
    763     public void onStopUser(@UserIdInt int userId) {
    764         mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
    765     }
    766 
    767     // Plumbing
    768 
    769     private final IBinder mService = new ITrustManager.Stub() {
    770         @Override
    771         public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
    772             enforceReportPermission();
    773             mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
    774                     .sendToTarget();
    775         }
    776 
    777         @Override
    778         public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
    779             enforceReportPermission();
    780             mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
    781                     .sendToTarget();
    782         }
    783 
    784         @Override
    785         public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
    786             enforceReportPermission();
    787             // coalesce refresh messages.
    788             mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
    789             mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
    790         }
    791 
    792         @Override
    793         public void reportKeyguardShowingChanged() throws RemoteException {
    794             enforceReportPermission();
    795             // coalesce refresh messages.
    796             mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
    797             mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
    798 
    799             // Make sure handler processes the message before returning, such that isDeviceLocked
    800             // after this call will retrieve the correct value.
    801             mHandler.runWithScissors(() -> {}, 0);
    802         }
    803 
    804         @Override
    805         public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
    806             enforceListenerPermission();
    807             mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
    808         }
    809 
    810         @Override
    811         public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
    812             enforceListenerPermission();
    813             mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
    814         }
    815 
    816         @Override
    817         public boolean isDeviceLocked(int userId) throws RemoteException {
    818             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
    819                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
    820 
    821             long token = Binder.clearCallingIdentity();
    822             try {
    823                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
    824                     userId = resolveProfileParent(userId);
    825                 }
    826                 return isDeviceLockedInner(userId);
    827             } finally {
    828                 Binder.restoreCallingIdentity(token);
    829             }
    830         }
    831 
    832         @Override
    833         public boolean isDeviceSecure(int userId) throws RemoteException {
    834             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
    835                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
    836 
    837             long token = Binder.clearCallingIdentity();
    838             try {
    839                 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
    840                     userId = resolveProfileParent(userId);
    841                 }
    842                 return mLockPatternUtils.isSecure(userId);
    843             } finally {
    844                 Binder.restoreCallingIdentity(token);
    845             }
    846         }
    847 
    848         private void enforceReportPermission() {
    849             mContext.enforceCallingOrSelfPermission(
    850                     Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
    851         }
    852 
    853         private void enforceListenerPermission() {
    854             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
    855                     "register trust listener");
    856         }
    857 
    858         @Override
    859         protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
    860             if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
    861             if (isSafeMode()) {
    862                 fout.println("disabled because the system is in safe mode.");
    863                 return;
    864             }
    865             if (!mTrustAgentsCanRun) {
    866                 fout.println("disabled because the third-party apps can't run yet.");
    867                 return;
    868             }
    869             final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
    870             mHandler.runWithScissors(new Runnable() {
    871                 @Override
    872                 public void run() {
    873                     fout.println("Trust manager state:");
    874                     for (UserInfo user : userInfos) {
    875                         dumpUser(fout, user, user.id == mCurrentUser);
    876                     }
    877                 }
    878             }, 1500);
    879         }
    880 
    881         private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
    882             fout.printf(" User \"%s\" (id=%d, flags=%#x)",
    883                     user.name, user.id, user.flags);
    884             if (!user.supportsSwitchToByUser()) {
    885                 fout.println("(managed profile)");
    886                 fout.println("   disabled because switching to this user is not possible.");
    887                 return;
    888             }
    889             if (isCurrent) {
    890                 fout.print(" (current)");
    891             }
    892             fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
    893             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
    894             fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
    895             fout.print(", strongAuthRequired=" + dumpHex(
    896                     mStrongAuthTracker.getStrongAuthForUser(user.id)));
    897             fout.println();
    898             fout.println("   Enabled agents:");
    899             boolean duplicateSimpleNames = false;
    900             ArraySet<String> simpleNames = new ArraySet<String>();
    901             for (AgentInfo info : mActiveAgents) {
    902                 if (info.userId != user.id) { continue; }
    903                 boolean trusted = info.agent.isTrusted();
    904                 fout.print("    "); fout.println(info.component.flattenToShortString());
    905                 fout.print("     bound=" + dumpBool(info.agent.isBound()));
    906                 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
    907                 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
    908                 fout.print(", trusted=" + dumpBool(trusted));
    909                 fout.println();
    910                 if (trusted) {
    911                     fout.println("      message=\"" + info.agent.getMessage() + "\"");
    912                 }
    913                 if (!info.agent.isConnected()) {
    914                     String restartTime = TrustArchive.formatDuration(
    915                             info.agent.getScheduledRestartUptimeMillis()
    916                                     - SystemClock.uptimeMillis());
    917                     fout.println("      restartScheduledAt=" + restartTime);
    918                 }
    919                 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
    920                     duplicateSimpleNames = true;
    921                 }
    922             }
    923             fout.println("   Events:");
    924             mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
    925             fout.println();
    926         }
    927 
    928         private String dumpBool(boolean b) {
    929             return b ? "1" : "0";
    930         }
    931 
    932         private String dumpHex(int i) {
    933             return "0x" + Integer.toHexString(i);
    934         }
    935 
    936         @Override
    937         public void setDeviceLockedForUser(int userId, boolean locked) {
    938             enforceReportPermission();
    939             final long identity = Binder.clearCallingIdentity();
    940             try {
    941                 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
    942                     synchronized (mDeviceLockedForUser) {
    943                         mDeviceLockedForUser.put(userId, locked);
    944                     }
    945                     if (locked) {
    946                         try {
    947                             ActivityManager.getService().notifyLockedProfile(userId);
    948                         } catch (RemoteException e) {
    949                         }
    950                     }
    951                     final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
    952                     lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    953                     lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
    954                     mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
    955                             Manifest.permission.TRUST_LISTENER, /* options */ null);
    956                 }
    957             } finally {
    958                 Binder.restoreCallingIdentity(identity);
    959             }
    960         }
    961 
    962         @Override
    963         public boolean isTrustUsuallyManaged(int userId) {
    964             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
    965                     "query trust state");
    966             return isTrustUsuallyManagedInternal(userId);
    967         }
    968     };
    969 
    970     private boolean isTrustUsuallyManagedInternal(int userId) {
    971         synchronized (mTrustUsuallyManagedForUser) {
    972             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
    973             if (i >= 0) {
    974                 return mTrustUsuallyManagedForUser.valueAt(i);
    975             }
    976         }
    977         // It's not in memory yet, get the value from persisted storage instead
    978         boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
    979         synchronized (mTrustUsuallyManagedForUser) {
    980             int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
    981             if (i >= 0) {
    982                 // Someone set the trust usually managed in the mean time. Better use that.
    983                 return mTrustUsuallyManagedForUser.valueAt(i);
    984             } else {
    985                 // .. otherwise it's safe to cache the fetched value now.
    986                 mTrustUsuallyManagedForUser.put(userId, persistedValue);
    987                 return persistedValue;
    988             }
    989         }
    990     }
    991 
    992     private int resolveProfileParent(int userId) {
    993         long identity = Binder.clearCallingIdentity();
    994         try {
    995             UserInfo parent = mUserManager.getProfileParent(userId);
    996             if (parent != null) {
    997                 return parent.getUserHandle().getIdentifier();
    998             }
    999             return userId;
   1000         } finally {
   1001             Binder.restoreCallingIdentity(identity);
   1002         }
   1003     }
   1004 
   1005     private final Handler mHandler = new Handler() {
   1006         @Override
   1007         public void handleMessage(Message msg) {
   1008             switch (msg.what) {
   1009                 case MSG_REGISTER_LISTENER:
   1010                     addListener((ITrustListener) msg.obj);
   1011                     break;
   1012                 case MSG_UNREGISTER_LISTENER:
   1013                     removeListener((ITrustListener) msg.obj);
   1014                     break;
   1015                 case MSG_DISPATCH_UNLOCK_ATTEMPT:
   1016                     dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
   1017                     break;
   1018                 case MSG_DISPATCH_UNLOCK_LOCKOUT:
   1019                     dispatchUnlockLockout(msg.arg1, msg.arg2);
   1020                     break;
   1021                 case MSG_ENABLED_AGENTS_CHANGED:
   1022                     refreshAgentList(UserHandle.USER_ALL);
   1023                     // This is also called when the security mode of a user changes.
   1024                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
   1025                     break;
   1026                 case MSG_KEYGUARD_SHOWING_CHANGED:
   1027                     refreshDeviceLockedForUser(mCurrentUser);
   1028                     break;
   1029                 case MSG_START_USER:
   1030                 case MSG_CLEANUP_USER:
   1031                 case MSG_UNLOCK_USER:
   1032                     refreshAgentList(msg.arg1);
   1033                     break;
   1034                 case MSG_SWITCH_USER:
   1035                     mCurrentUser = msg.arg1;
   1036                     refreshDeviceLockedForUser(UserHandle.USER_ALL);
   1037                     break;
   1038                 case MSG_STOP_USER:
   1039                     setDeviceLockedForUser(msg.arg1, true);
   1040                     break;
   1041                 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
   1042                     SparseBooleanArray usuallyManaged;
   1043                     synchronized (mTrustUsuallyManagedForUser) {
   1044                         usuallyManaged = mTrustUsuallyManagedForUser.clone();
   1045                     }
   1046 
   1047                     for (int i = 0; i < usuallyManaged.size(); i++) {
   1048                         int userId = usuallyManaged.keyAt(i);
   1049                         boolean value = usuallyManaged.valueAt(i);
   1050                         if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
   1051                             mLockPatternUtils.setTrustUsuallyManaged(value, userId);
   1052                         }
   1053                     }
   1054                     break;
   1055             }
   1056         }
   1057     };
   1058 
   1059     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
   1060         @Override
   1061         public void onSomePackagesChanged() {
   1062             refreshAgentList(UserHandle.USER_ALL);
   1063         }
   1064 
   1065         @Override
   1066         public boolean onPackageChanged(String packageName, int uid, String[] components) {
   1067             // We're interested in all changes, even if just some components get enabled / disabled.
   1068             return true;
   1069         }
   1070 
   1071         @Override
   1072         public void onPackageDisappeared(String packageName, int reason) {
   1073             removeAgentsOfPackage(packageName);
   1074         }
   1075     };
   1076 
   1077     private static class SettingsAttrs {
   1078         public ComponentName componentName;
   1079         public boolean canUnlockProfile;
   1080 
   1081         public SettingsAttrs(
   1082                 ComponentName componentName,
   1083                 boolean canUnlockProfile) {
   1084             this.componentName = componentName;
   1085             this.canUnlockProfile = canUnlockProfile;
   1086         }
   1087     };
   1088 
   1089     private class Receiver extends BroadcastReceiver {
   1090 
   1091         @Override
   1092         public void onReceive(Context context, Intent intent) {
   1093             String action = intent.getAction();
   1094             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
   1095                 refreshAgentList(getSendingUserId());
   1096                 updateDevicePolicyFeatures();
   1097             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
   1098                 int userId = getUserId(intent);
   1099                 if (userId > 0) {
   1100                     maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
   1101                 }
   1102             } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
   1103                 int userId = getUserId(intent);
   1104                 if (userId > 0) {
   1105                     synchronized (mUserIsTrusted) {
   1106                         mUserIsTrusted.delete(userId);
   1107                     }
   1108                     synchronized (mDeviceLockedForUser) {
   1109                         mDeviceLockedForUser.delete(userId);
   1110                     }
   1111                     synchronized (mTrustUsuallyManagedForUser) {
   1112                         mTrustUsuallyManagedForUser.delete(userId);
   1113                     }
   1114                     refreshAgentList(userId);
   1115                     refreshDeviceLockedForUser(userId);
   1116                 }
   1117             }
   1118         }
   1119 
   1120         private int getUserId(Intent intent) {
   1121             int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
   1122             if (userId > 0) {
   1123                 return userId;
   1124             } else {
   1125                 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
   1126                 return -100;
   1127             }
   1128         }
   1129 
   1130         public void register(Context context) {
   1131             IntentFilter filter = new IntentFilter();
   1132             filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
   1133             filter.addAction(Intent.ACTION_USER_ADDED);
   1134             filter.addAction(Intent.ACTION_USER_REMOVED);
   1135             context.registerReceiverAsUser(this,
   1136                     UserHandle.ALL,
   1137                     filter,
   1138                     null /* permission */,
   1139                     null /* scheduler */);
   1140         }
   1141     }
   1142 
   1143     private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
   1144 
   1145         SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
   1146 
   1147         public StrongAuthTracker(Context context) {
   1148             super(context);
   1149         }
   1150 
   1151         @Override
   1152         public void onStrongAuthRequiredChanged(int userId) {
   1153             mStartFromSuccessfulUnlock.delete(userId);
   1154 
   1155             if (DEBUG) {
   1156                 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
   1157                         + " trustAllowed=" + isTrustAllowedForUser(userId)
   1158                         + " agentsCanRun=" + canAgentsRunForUser(userId));
   1159             }
   1160 
   1161             refreshAgentList(userId);
   1162 
   1163             // The list of active trust agents may not have changed, if there was a previous call
   1164             // to allowTrustFromUnlock, so we update the trust here too.
   1165             updateTrust(userId, 0 /* flags */);
   1166         }
   1167 
   1168         boolean canAgentsRunForUser(int userId) {
   1169             return mStartFromSuccessfulUnlock.get(userId)
   1170                     || super.isTrustAllowedForUser(userId);
   1171         }
   1172 
   1173         /**
   1174          * Temporarily suppress strong auth requirements for {@param userId} until strong auth
   1175          * changes again. Must only be called when we know about a successful unlock already
   1176          * before the underlying StrongAuthTracker.
   1177          *
   1178          * Note that this only changes whether trust agents can be started, not the actual trusted
   1179          * value.
   1180          */
   1181         void allowTrustFromUnlock(int userId) {
   1182             if (userId < UserHandle.USER_SYSTEM) {
   1183                 throw new IllegalArgumentException("userId must be a valid user: " + userId);
   1184             }
   1185             boolean previous = canAgentsRunForUser(userId);
   1186             mStartFromSuccessfulUnlock.put(userId, true);
   1187 
   1188             if (DEBUG) {
   1189                 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
   1190                         + " trustAllowed=" + isTrustAllowedForUser(userId)
   1191                         + " agentsCanRun=" + canAgentsRunForUser(userId));
   1192             }
   1193 
   1194             if (canAgentsRunForUser(userId) != previous) {
   1195                 refreshAgentList(userId);
   1196             }
   1197         }
   1198     }
   1199 }
   1200