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