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