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