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