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