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 com.android.internal.content.PackageMonitor;
     20 import com.android.internal.widget.LockPatternUtils;
     21 import com.android.server.SystemService;
     22 
     23 import org.xmlpull.v1.XmlPullParser;
     24 import org.xmlpull.v1.XmlPullParserException;
     25 
     26 import android.Manifest;
     27 import android.app.ActivityManagerNative;
     28 import android.app.admin.DevicePolicyManager;
     29 import android.app.trust.ITrustListener;
     30 import android.app.trust.ITrustManager;
     31 import android.content.BroadcastReceiver;
     32 import android.content.ComponentName;
     33 import android.content.Context;
     34 import android.content.Intent;
     35 import android.content.IntentFilter;
     36 import android.content.pm.ApplicationInfo;
     37 import android.content.pm.PackageManager;
     38 import android.content.pm.ResolveInfo;
     39 import android.content.pm.UserInfo;
     40 import android.content.res.Resources;
     41 import android.content.res.TypedArray;
     42 import android.content.res.XmlResourceParser;
     43 import android.graphics.drawable.Drawable;
     44 import android.os.DeadObjectException;
     45 import android.os.Handler;
     46 import android.os.IBinder;
     47 import android.os.Message;
     48 import android.os.RemoteException;
     49 import android.os.SystemClock;
     50 import android.os.UserHandle;
     51 import android.os.UserManager;
     52 import android.provider.Settings;
     53 import android.service.trust.TrustAgentService;
     54 import android.util.ArraySet;
     55 import android.util.AttributeSet;
     56 import android.util.Log;
     57 import android.util.Slog;
     58 import android.util.SparseBooleanArray;
     59 import android.util.Xml;
     60 
     61 import java.io.FileDescriptor;
     62 import java.io.IOException;
     63 import java.io.PrintWriter;
     64 import java.util.ArrayList;
     65 import java.util.List;
     66 
     67 /**
     68  * Manages trust agents and trust listeners.
     69  *
     70  * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
     71  * of each user and notifies them about events that are relevant to them.
     72  * It start and stops them based on the value of
     73  * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
     74  *
     75  * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
     76  * trust state changes for any user.
     77  *
     78  * Trust state and the setting of enabled agents is kept per user and each user has its own
     79  * instance of a {@link android.service.trust.TrustAgentService}.
     80  */
     81 public class TrustManagerService extends SystemService {
     82 
     83     private static final boolean DEBUG = false;
     84     private static final String TAG = "TrustManagerService";
     85 
     86     private static final Intent TRUST_AGENT_INTENT =
     87             new Intent(TrustAgentService.SERVICE_INTERFACE);
     88     private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
     89 
     90     private static final int MSG_REGISTER_LISTENER = 1;
     91     private static final int MSG_UNREGISTER_LISTENER = 2;
     92     private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
     93     private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
     94     private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5;
     95 
     96     private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>();
     97     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>();
     98     private final Receiver mReceiver = new Receiver();
     99     private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray();
    100     /* package */ final TrustArchive mArchive = new TrustArchive();
    101     private final Context mContext;
    102     private final LockPatternUtils mLockPatternUtils;
    103 
    104     private UserManager mUserManager;
    105 
    106     public TrustManagerService(Context context) {
    107         super(context);
    108         mContext = context;
    109         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    110         mLockPatternUtils = new LockPatternUtils(context);
    111     }
    112 
    113     @Override
    114     public void onStart() {
    115         publishBinderService(Context.TRUST_SERVICE, mService);
    116     }
    117 
    118     @Override
    119     public void onBootPhase(int phase) {
    120         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) {
    121             mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
    122             mReceiver.register(mContext);
    123             refreshAgentList(UserHandle.USER_ALL);
    124         } else if (phase == SystemService.PHASE_BOOT_COMPLETED && !isSafeMode()) {
    125             maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER);
    126         }
    127     }
    128 
    129     // Agent management
    130 
    131     private static final class AgentInfo {
    132         CharSequence label;
    133         Drawable icon;
    134         ComponentName component; // service that implements ITrustAgent
    135         ComponentName settings; // setting to launch to modify agent.
    136         TrustAgentWrapper agent;
    137         int userId;
    138 
    139         @Override
    140         public boolean equals(Object other) {
    141             if (!(other instanceof AgentInfo)) {
    142                 return false;
    143             }
    144             AgentInfo o = (AgentInfo) other;
    145             return component.equals(o.component) && userId == o.userId;
    146         }
    147 
    148         @Override
    149         public int hashCode() {
    150             return component.hashCode() * 31 + userId;
    151         }
    152     }
    153 
    154     private void updateTrustAll() {
    155         List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
    156         for (UserInfo userInfo : userInfos) {
    157             updateTrust(userInfo.id, false);
    158         }
    159     }
    160 
    161     public void updateTrust(int userId, boolean initiatedByUser) {
    162         dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId);
    163         dispatchOnTrustChanged(aggregateIsTrusted(userId), userId, initiatedByUser);
    164     }
    165 
    166     void refreshAgentList(int userId) {
    167         if (DEBUG) Slog.d(TAG, "refreshAgentList()");
    168         if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) {
    169             Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle,"
    170                     + " must be USER_ALL or a specific user.", new Throwable("here"));
    171             userId = UserHandle.USER_ALL;
    172         }
    173         PackageManager pm = mContext.getPackageManager();
    174 
    175         List<UserInfo> userInfos;
    176         if (userId == UserHandle.USER_ALL) {
    177             userInfos = mUserManager.getUsers(true /* excludeDying */);
    178         } else {
    179             userInfos = new ArrayList<>();
    180             userInfos.add(mUserManager.getUserInfo(userId));
    181         }
    182         LockPatternUtils lockPatternUtils = mLockPatternUtils;
    183 
    184         ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
    185         obsoleteAgents.addAll(mActiveAgents);
    186 
    187         for (UserInfo userInfo : userInfos) {
    188             if (!userInfo.supportsSwitchTo()) continue;
    189             if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id)
    190                     == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue;
    191             if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue;
    192             DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
    193             int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
    194             final boolean disableTrustAgents =
    195                     (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
    196 
    197             List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
    198             if (enabledAgents == null) {
    199                 continue;
    200             }
    201             List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
    202             for (ResolveInfo resolveInfo : resolveInfos) {
    203                 ComponentName name = getComponentName(resolveInfo);
    204 
    205                 if (!enabledAgents.contains(name)) continue;
    206                 if (disableTrustAgents) {
    207                     List<String> features =
    208                             dpm.getTrustAgentFeaturesEnabled(null /* admin */, name);
    209                     // Disable agent if no features are enabled.
    210                     if (features == null || features.isEmpty()) continue;
    211                 }
    212 
    213                 AgentInfo agentInfo = new AgentInfo();
    214                 agentInfo.component = name;
    215                 agentInfo.userId = userInfo.id;
    216                 if (!mActiveAgents.contains(agentInfo)) {
    217                     agentInfo.label = resolveInfo.loadLabel(pm);
    218                     agentInfo.icon = resolveInfo.loadIcon(pm);
    219                     agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
    220                     agentInfo.agent = new TrustAgentWrapper(mContext, this,
    221                             new Intent().setComponent(name), userInfo.getUserHandle());
    222                     mActiveAgents.add(agentInfo);
    223                 } else {
    224                     obsoleteAgents.remove(agentInfo);
    225                 }
    226             }
    227         }
    228 
    229         boolean trustMayHaveChanged = false;
    230         for (int i = 0; i < obsoleteAgents.size(); i++) {
    231             AgentInfo info = obsoleteAgents.valueAt(i);
    232             if (userId == UserHandle.USER_ALL || userId == info.userId) {
    233                 if (info.agent.isManagingTrust()) {
    234                     trustMayHaveChanged = true;
    235                 }
    236                 info.agent.unbind();
    237                 mActiveAgents.remove(info);
    238             }
    239         }
    240 
    241         if (trustMayHaveChanged) {
    242             updateTrustAll();
    243         }
    244     }
    245 
    246     void updateDevicePolicyFeatures() {
    247         for (int i = 0; i < mActiveAgents.size(); i++) {
    248             AgentInfo info = mActiveAgents.valueAt(i);
    249             if (info.agent.isConnected()) {
    250                 info.agent.updateDevicePolicyFeatures();
    251             }
    252         }
    253     }
    254 
    255     private void removeAgentsOfPackage(String packageName) {
    256         boolean trustMayHaveChanged = false;
    257         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    258             AgentInfo info = mActiveAgents.valueAt(i);
    259             if (packageName.equals(info.component.getPackageName())) {
    260                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    261                 if (info.agent.isManagingTrust()) {
    262                     trustMayHaveChanged = true;
    263                 }
    264                 info.agent.unbind();
    265                 mActiveAgents.removeAt(i);
    266             }
    267         }
    268         if (trustMayHaveChanged) {
    269             updateTrustAll();
    270         }
    271     }
    272 
    273     public void resetAgent(ComponentName name, int userId) {
    274         boolean trustMayHaveChanged = false;
    275         for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
    276             AgentInfo info = mActiveAgents.valueAt(i);
    277             if (name.equals(info.component) && userId == info.userId) {
    278                 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
    279                 if (info.agent.isManagingTrust()) {
    280                     trustMayHaveChanged = true;
    281                 }
    282                 info.agent.unbind();
    283                 mActiveAgents.removeAt(i);
    284             }
    285         }
    286         if (trustMayHaveChanged) {
    287             updateTrust(userId, false);
    288         }
    289         refreshAgentList(userId);
    290     }
    291 
    292     private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
    293         if (resolveInfo == null || resolveInfo.serviceInfo == null
    294                 || resolveInfo.serviceInfo.metaData == null) return null;
    295         String cn = null;
    296         XmlResourceParser parser = null;
    297         Exception caughtException = null;
    298         try {
    299             parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
    300                     TrustAgentService.TRUST_AGENT_META_DATA);
    301             if (parser == null) {
    302                 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
    303                 return null;
    304             }
    305             Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
    306             AttributeSet attrs = Xml.asAttributeSet(parser);
    307             int type;
    308             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
    309                     && type != XmlPullParser.START_TAG) {
    310                 // Drain preamble.
    311             }
    312             String nodeName = parser.getName();
    313             if (!"trust-agent".equals(nodeName)) {
    314                 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
    315                 return null;
    316             }
    317             TypedArray sa = res
    318                     .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
    319             cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
    320             sa.recycle();
    321         } catch (PackageManager.NameNotFoundException e) {
    322             caughtException = e;
    323         } catch (IOException e) {
    324             caughtException = e;
    325         } catch (XmlPullParserException e) {
    326             caughtException = e;
    327         } finally {
    328             if (parser != null) parser.close();
    329         }
    330         if (caughtException != null) {
    331             Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
    332             return null;
    333         }
    334         if (cn == null) {
    335             return null;
    336         }
    337         if (cn.indexOf('/') < 0) {
    338             cn = resolveInfo.serviceInfo.packageName + "/" + cn;
    339         }
    340         return ComponentName.unflattenFromString(cn);
    341     }
    342 
    343     private ComponentName getComponentName(ResolveInfo resolveInfo) {
    344         if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
    345         return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
    346     }
    347 
    348     private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
    349         if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
    350                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
    351             return;
    352         }
    353         PackageManager pm = mContext.getPackageManager();
    354         List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
    355         ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
    356         for (ResolveInfo resolveInfo : resolveInfos) {
    357             ComponentName componentName = getComponentName(resolveInfo);
    358             int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
    359             if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
    360                 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
    361                         + "is not a system package.");
    362                 continue;
    363             }
    364             discoveredAgents.add(componentName);
    365         }
    366 
    367         List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
    368         if (previouslyEnabledAgents != null) {
    369             discoveredAgents.addAll(previouslyEnabledAgents);
    370         }
    371         utils.setEnabledTrustAgents(discoveredAgents, userId);
    372         Settings.Secure.putIntForUser(mContext.getContentResolver(),
    373                 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
    374     }
    375 
    376     private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
    377         List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
    378                 0 /* flags */, userId);
    379         ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
    380         for (ResolveInfo resolveInfo : resolveInfos) {
    381             if (resolveInfo.serviceInfo == null) continue;
    382             if (resolveInfo.serviceInfo.applicationInfo == null) continue;
    383             String packageName = resolveInfo.serviceInfo.packageName;
    384             if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
    385                     != PackageManager.PERMISSION_GRANTED) {
    386                 ComponentName name = getComponentName(resolveInfo);
    387                 Log.w(TAG, "Skipping agent " + name + " because package does not have"
    388                         + " permission " + PERMISSION_PROVIDE_AGENT + ".");
    389                 continue;
    390             }
    391             allowedAgents.add(resolveInfo);
    392         }
    393         return allowedAgents;
    394     }
    395 
    396     // Agent dispatch and aggregation
    397 
    398     private boolean aggregateIsTrusted(int userId) {
    399         if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
    400             return false;
    401         }
    402         for (int i = 0; i < mActiveAgents.size(); i++) {
    403             AgentInfo info = mActiveAgents.valueAt(i);
    404             if (info.userId == userId) {
    405                 if (info.agent.isTrusted()) {
    406                     return true;
    407                 }
    408             }
    409         }
    410         return false;
    411     }
    412 
    413     private boolean aggregateIsTrustManaged(int userId) {
    414         if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
    415             return false;
    416         }
    417         for (int i = 0; i < mActiveAgents.size(); i++) {
    418             AgentInfo info = mActiveAgents.valueAt(i);
    419             if (info.userId == userId) {
    420                 if (info.agent.isManagingTrust()) {
    421                     return true;
    422                 }
    423             }
    424         }
    425         return false;
    426     }
    427 
    428     private void dispatchUnlockAttempt(boolean successful, int userId) {
    429         for (int i = 0; i < mActiveAgents.size(); i++) {
    430             AgentInfo info = mActiveAgents.valueAt(i);
    431             if (info.userId == userId) {
    432                 info.agent.onUnlockAttempt(successful);
    433             }
    434         }
    435 
    436         if (successful) {
    437             updateUserHasAuthenticated(userId);
    438         }
    439     }
    440 
    441     private void updateUserHasAuthenticated(int userId) {
    442         if (!mUserHasAuthenticatedSinceBoot.get(userId)) {
    443             mUserHasAuthenticatedSinceBoot.put(userId, true);
    444             refreshAgentList(userId);
    445         }
    446     }
    447 
    448 
    449     private void requireCredentialEntry(int userId) {
    450         if (userId == UserHandle.USER_ALL) {
    451             mUserHasAuthenticatedSinceBoot.clear();
    452             refreshAgentList(UserHandle.USER_ALL);
    453         } else {
    454             mUserHasAuthenticatedSinceBoot.put(userId, false);
    455             refreshAgentList(userId);
    456         }
    457     }
    458 
    459     // Listeners
    460 
    461     private void addListener(ITrustListener listener) {
    462         for (int i = 0; i < mTrustListeners.size(); i++) {
    463             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    464                 return;
    465             }
    466         }
    467         mTrustListeners.add(listener);
    468         updateTrustAll();
    469     }
    470 
    471     private void removeListener(ITrustListener listener) {
    472         for (int i = 0; i < mTrustListeners.size(); i++) {
    473             if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
    474                 mTrustListeners.remove(i);
    475                 return;
    476             }
    477         }
    478     }
    479 
    480     private void dispatchOnTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
    481         if (!enabled) initiatedByUser = false;
    482         for (int i = 0; i < mTrustListeners.size(); i++) {
    483             try {
    484                 mTrustListeners.get(i).onTrustChanged(enabled, userId, initiatedByUser);
    485             } catch (DeadObjectException e) {
    486                 Slog.d(TAG, "Removing dead TrustListener.");
    487                 mTrustListeners.remove(i);
    488                 i--;
    489             } catch (RemoteException e) {
    490                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    491             }
    492         }
    493     }
    494 
    495     private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
    496         for (int i = 0; i < mTrustListeners.size(); i++) {
    497             try {
    498                 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
    499             } catch (DeadObjectException e) {
    500                 Slog.d(TAG, "Removing dead TrustListener.");
    501                 mTrustListeners.remove(i);
    502                 i--;
    503             } catch (RemoteException e) {
    504                 Slog.e(TAG, "Exception while notifying TrustListener.", e);
    505             }
    506         }
    507     }
    508 
    509     // Plumbing
    510 
    511     private final IBinder mService = new ITrustManager.Stub() {
    512         @Override
    513         public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
    514             enforceReportPermission();
    515             mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
    516                     .sendToTarget();
    517         }
    518 
    519         @Override
    520         public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
    521             enforceReportPermission();
    522             // coalesce refresh messages.
    523             mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
    524             mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
    525         }
    526 
    527         @Override
    528         public void reportRequireCredentialEntry(int userId) throws RemoteException {
    529             enforceReportPermission();
    530             if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) {
    531                 mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget();
    532             } else {
    533                 throw new IllegalArgumentException(
    534                         "userId must be an explicit user id or USER_ALL");
    535             }
    536         }
    537 
    538         @Override
    539         public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
    540             enforceListenerPermission();
    541             mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
    542         }
    543 
    544         @Override
    545         public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
    546             enforceListenerPermission();
    547             mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
    548         }
    549 
    550         private void enforceReportPermission() {
    551             mContext.enforceCallingOrSelfPermission(
    552                     Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
    553         }
    554 
    555         private void enforceListenerPermission() {
    556             mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
    557                     "register trust listener");
    558         }
    559 
    560         @Override
    561         protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
    562             mContext.enforceCallingPermission(Manifest.permission.DUMP,
    563                     "dumping TrustManagerService");
    564             final UserInfo currentUser;
    565             final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
    566             try {
    567                 currentUser = ActivityManagerNative.getDefault().getCurrentUser();
    568             } catch (RemoteException e) {
    569                 throw new RuntimeException(e);
    570             }
    571             mHandler.runWithScissors(new Runnable() {
    572                 @Override
    573                 public void run() {
    574                     fout.println("Trust manager state:");
    575                     for (UserInfo user : userInfos) {
    576                         dumpUser(fout, user, user.id == currentUser.id);
    577                     }
    578                 }
    579             }, 1500);
    580         }
    581 
    582         private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
    583             fout.printf(" User \"%s\" (id=%d, flags=%#x)",
    584                     user.name, user.id, user.flags);
    585             if (isCurrent) {
    586                 fout.print(" (current)");
    587             }
    588             fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
    589             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
    590             fout.println();
    591             fout.println("   Enabled agents:");
    592             boolean duplicateSimpleNames = false;
    593             ArraySet<String> simpleNames = new ArraySet<String>();
    594             for (AgentInfo info : mActiveAgents) {
    595                 if (info.userId != user.id) { continue; }
    596                 boolean trusted = info.agent.isTrusted();
    597                 fout.print("    "); fout.println(info.component.flattenToShortString());
    598                 fout.print("     bound=" + dumpBool(info.agent.isBound()));
    599                 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
    600                 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
    601                 fout.print(", trusted=" + dumpBool(trusted));
    602                 fout.println();
    603                 if (trusted) {
    604                     fout.println("      message=\"" + info.agent.getMessage() + "\"");
    605                 }
    606                 if (!info.agent.isConnected()) {
    607                     String restartTime = TrustArchive.formatDuration(
    608                             info.agent.getScheduledRestartUptimeMillis()
    609                                     - SystemClock.uptimeMillis());
    610                     fout.println("      restartScheduledAt=" + restartTime);
    611                 }
    612                 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
    613                     duplicateSimpleNames = true;
    614                 }
    615             }
    616             fout.println("   Events:");
    617             mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
    618             fout.println();
    619         }
    620 
    621         private String dumpBool(boolean b) {
    622             return b ? "1" : "0";
    623         }
    624     };
    625 
    626     private final Handler mHandler = new Handler() {
    627         @Override
    628         public void handleMessage(Message msg) {
    629             switch (msg.what) {
    630                 case MSG_REGISTER_LISTENER:
    631                     addListener((ITrustListener) msg.obj);
    632                     break;
    633                 case MSG_UNREGISTER_LISTENER:
    634                     removeListener((ITrustListener) msg.obj);
    635                     break;
    636                 case MSG_DISPATCH_UNLOCK_ATTEMPT:
    637                     dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
    638                     break;
    639                 case MSG_ENABLED_AGENTS_CHANGED:
    640                     refreshAgentList(UserHandle.USER_ALL);
    641                     break;
    642                 case MSG_REQUIRE_CREDENTIAL_ENTRY:
    643                     requireCredentialEntry(msg.arg1);
    644                     break;
    645             }
    646         }
    647     };
    648 
    649     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
    650         @Override
    651         public void onSomePackagesChanged() {
    652             refreshAgentList(UserHandle.USER_ALL);
    653         }
    654 
    655         @Override
    656         public boolean onPackageChanged(String packageName, int uid, String[] components) {
    657             // We're interested in all changes, even if just some components get enabled / disabled.
    658             return true;
    659         }
    660 
    661         @Override
    662         public void onPackageDisappeared(String packageName, int reason) {
    663             removeAgentsOfPackage(packageName);
    664         }
    665     };
    666 
    667     private class Receiver extends BroadcastReceiver {
    668 
    669         @Override
    670         public void onReceive(Context context, Intent intent) {
    671             String action = intent.getAction();
    672             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
    673                 refreshAgentList(getSendingUserId());
    674                 updateDevicePolicyFeatures();
    675             } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
    676                 updateUserHasAuthenticated(getSendingUserId());
    677             } else if (Intent.ACTION_USER_ADDED.equals(action)) {
    678                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
    679                 if (userId > 0) {
    680                     maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
    681                 } else {
    682                     Log.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
    683                 }
    684             }
    685         }
    686 
    687         public void register(Context context) {
    688             IntentFilter filter = new IntentFilter();
    689             filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
    690             filter.addAction(Intent.ACTION_USER_PRESENT);
    691             filter.addAction(Intent.ACTION_USER_ADDED);
    692             context.registerReceiverAsUser(this,
    693                     UserHandle.ALL,
    694                     filter,
    695                     null /* permission */,
    696                     null /* scheduler */);
    697         }
    698     }
    699 }
    700