OSDN Git Service

f9b170443d8d0eaf84917d338b15e8743271fa72
[android-x86/frameworks-base.git] / services / core / java / com / android / server / trust / TrustManagerService.java
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 }