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 android.Manifest;
20import android.annotation.UserIdInt;
21import android.app.ActivityManager;
22import android.app.admin.DevicePolicyManager;
23import android.app.trust.ITrustListener;
24import android.app.trust.ITrustManager;
25import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.Context;
28import android.content.Intent;
29import android.content.IntentFilter;
30import android.content.pm.ApplicationInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.ResolveInfo;
33import android.content.pm.UserInfo;
34import android.content.res.Resources;
35import android.content.res.TypedArray;
36import android.content.res.XmlResourceParser;
37import android.graphics.drawable.Drawable;
38import android.os.Binder;
39import android.os.Build;
40import android.os.DeadObjectException;
41import android.os.Handler;
42import android.os.IBinder;
43import android.os.Message;
44import android.os.PersistableBundle;
45import android.os.RemoteException;
46import android.os.SystemClock;
47import android.os.UserHandle;
48import android.os.UserManager;
49import android.os.storage.StorageManager;
50import android.provider.Settings;
51import android.service.trust.TrustAgentService;
52import android.text.TextUtils;
53import android.util.ArraySet;
54import android.util.AttributeSet;
55import android.util.Log;
56import android.util.Slog;
57import android.util.SparseBooleanArray;
58import android.util.Xml;
59import android.view.IWindowManager;
60import android.view.WindowManagerGlobal;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.policy.IKeyguardDismissCallback;
64import com.android.internal.util.DumpUtils;
65import com.android.internal.widget.LockPatternUtils;
66import com.android.server.SystemService;
67import java.io.FileDescriptor;
68import java.io.IOException;
69import java.io.PrintWriter;
70import java.util.ArrayList;
71import java.util.List;
72import org.xmlpull.v1.XmlPullParser;
73import org.xmlpull.v1.XmlPullParserException;
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    private static final String TAG = "TrustManagerService";
91    static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
92
93    private static final Intent TRUST_AGENT_INTENT =
94            new Intent(TrustAgentService.SERVICE_INTERFACE);
95    private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
96
97    private static final int MSG_REGISTER_LISTENER = 1;
98    private static final int MSG_UNREGISTER_LISTENER = 2;
99    private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
100    private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
101    private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
102    private static final int MSG_START_USER = 7;
103    private static final int MSG_CLEANUP_USER = 8;
104    private static final int MSG_SWITCH_USER = 9;
105    private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
106    private static final int MSG_UNLOCK_USER = 11;
107    private static final int MSG_STOP_USER = 12;
108    private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
109    private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
110
111    private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
112
113    private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
114    private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
115    private final Receiver mReceiver = new Receiver();
116
117    /* package */ final TrustArchive mArchive = new TrustArchive();
118    private final Context mContext;
119    private final LockPatternUtils mLockPatternUtils;
120    private final UserManager mUserManager;
121    private final ActivityManager mActivityManager;
122
123    @GuardedBy("mUserIsTrusted")
124    private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
125
126    @GuardedBy("mDeviceLockedForUser")
127    private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
128
129    @GuardedBy("mTrustUsuallyManagedForUser")
130    private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
131
132    // set to true only if user can skip bouncer
133    @GuardedBy("mUsersUnlockedByFingerprint")
134    private final SparseBooleanArray mUsersUnlockedByFingerprint = new SparseBooleanArray();
135
136    private final StrongAuthTracker mStrongAuthTracker;
137
138    private boolean mTrustAgentsCanRun = false;
139    private int mCurrentUser = UserHandle.USER_SYSTEM;
140
141    public TrustManagerService(Context context) {
142        super(context);
143        mContext = context;
144        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
145        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
146        mLockPatternUtils = new LockPatternUtils(context);
147        mStrongAuthTracker = new StrongAuthTracker(context);
148    }
149
150    @Override
151    public void onStart() {
152        publishBinderService(Context.TRUST_SERVICE, mService);
153    }
154
155    @Override
156    public void onBootPhase(int phase) {
157        if (isSafeMode()) {
158            // No trust agents in safe mode.
159            return;
160        }
161        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
162            mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
163            mReceiver.register(mContext);
164            mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
165        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
166            mTrustAgentsCanRun = true;
167            refreshAgentList(UserHandle.USER_ALL);
168            refreshDeviceLockedForUser(UserHandle.USER_ALL);
169        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
170            maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
171        }
172    }
173
174    // Agent management
175
176    private static final class AgentInfo {
177        CharSequence label;
178        Drawable icon;
179        ComponentName component; // service that implements ITrustAgent
180        SettingsAttrs settings; // setting to launch to modify agent.
181        TrustAgentWrapper agent;
182        int userId;
183
184        @Override
185        public boolean equals(Object other) {
186            if (!(other instanceof AgentInfo)) {
187                return false;
188            }
189            AgentInfo o = (AgentInfo) other;
190            return component.equals(o.component) && userId == o.userId;
191        }
192
193        @Override
194        public int hashCode() {
195            return component.hashCode() * 31 + userId;
196        }
197    }
198
199    private void updateTrustAll() {
200        List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
201        for (UserInfo userInfo : userInfos) {
202            updateTrust(userInfo.id, 0);
203        }
204    }
205
206    public void updateTrust(int userId, int flags) {
207        boolean managed = aggregateIsTrustManaged(userId);
208        dispatchOnTrustManagedChanged(managed, userId);
209        if (mStrongAuthTracker.isTrustAllowedForUser(userId)
210                && isTrustUsuallyManagedInternal(userId) != managed) {
211            updateTrustUsuallyManaged(userId, managed);
212        }
213        boolean trusted = aggregateIsTrusted(userId);
214        boolean changed;
215        synchronized (mUserIsTrusted) {
216            changed = mUserIsTrusted.get(userId) != trusted;
217            mUserIsTrusted.put(userId, trusted);
218        }
219        dispatchOnTrustChanged(trusted, userId, flags);
220        if (changed) {
221            refreshDeviceLockedForUser(userId);
222        }
223    }
224
225    private void updateTrustUsuallyManaged(int userId, boolean managed) {
226        synchronized (mTrustUsuallyManagedForUser) {
227            mTrustUsuallyManagedForUser.put(userId, managed);
228        }
229        // Wait a few minutes before committing to flash, in case the trust agent is transiently not
230        // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
231        mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
232        mHandler.sendMessageDelayed(
233                mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
234                TRUST_USUALLY_MANAGED_FLUSH_DELAY);
235    }
236
237    public long addEscrowToken(byte[] token, int userId) {
238        return mLockPatternUtils.addEscrowToken(token, userId);
239    }
240
241    public boolean removeEscrowToken(long handle, int userId) {
242        return mLockPatternUtils.removeEscrowToken(handle, userId);
243    }
244
245    public boolean isEscrowTokenActive(long handle, int userId) {
246        return mLockPatternUtils.isEscrowTokenActive(handle, userId);
247    }
248
249    public void unlockUserWithToken(long handle, byte[] token, int userId) {
250        mLockPatternUtils.unlockUserWithToken(handle, token, userId);
251    }
252
253    void showKeyguardErrorMessage(CharSequence message) {
254        dispatchOnTrustError(message);
255    }
256
257    void refreshAgentList(int userIdOrAll) {
258        if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
259        if (!mTrustAgentsCanRun) {
260            return;
261        }
262        if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
263            Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
264                    + " must be USER_ALL or a specific user.", new Throwable("here"));
265            userIdOrAll = UserHandle.USER_ALL;
266        }
267        PackageManager pm = mContext.getPackageManager();
268
269        List<UserInfo> userInfos;
270        if (userIdOrAll == UserHandle.USER_ALL) {
271            userInfos = mUserManager.getUsers(true /* excludeDying */);
272        } else {
273            userInfos = new ArrayList<>();
274            userInfos.add(mUserManager.getUserInfo(userIdOrAll));
275        }
276        LockPatternUtils lockPatternUtils = mLockPatternUtils;
277
278        ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
279        obsoleteAgents.addAll(mActiveAgents);
280
281        for (UserInfo userInfo : userInfos) {
282            if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
283                    || userInfo.guestToRemove) continue;
284            if (!userInfo.supportsSwitchToByUser()) {
285                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
286                        + ": switchToByUser=false");
287                continue;
288            }
289            if (!mActivityManager.isUserRunning(userInfo.id)) {
290                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
291                        + ": user not started");
292                continue;
293            }
294            if (!lockPatternUtils.isSecure(userInfo.id)) {
295                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
296                        + ": no secure credential");
297                continue;
298            }
299
300            DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
301            int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
302            final boolean disableTrustAgents =
303                    (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
304
305            List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
306            if (enabledAgents == null) {
307                if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
308                        + ": no agents enabled by user");
309                continue;
310            }
311            List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
312            for (ResolveInfo resolveInfo : resolveInfos) {
313                ComponentName name = getComponentName(resolveInfo);
314
315                if (!enabledAgents.contains(name)) {
316                    if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
317                            + name.flattenToShortString() + " u"+ userInfo.id
318                            + ": not enabled by user");
319                    continue;
320                }
321                if (disableTrustAgents) {
322                    List<PersistableBundle> config =
323                            dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
324                    // Disable agent if no features are enabled.
325                    if (config == null || config.isEmpty()) {
326                        if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
327                                + name.flattenToShortString() + " u"+ userInfo.id
328                                + ": not allowed by DPM");
329                        continue;
330                    }
331                }
332                AgentInfo agentInfo = new AgentInfo();
333                agentInfo.component = name;
334                agentInfo.userId = userInfo.id;
335                if (!mActiveAgents.contains(agentInfo)) {
336                    agentInfo.label = resolveInfo.loadLabel(pm);
337                    agentInfo.icon = resolveInfo.loadIcon(pm);
338                    agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
339                } else {
340                    int index = mActiveAgents.indexOf(agentInfo);
341                    agentInfo = mActiveAgents.valueAt(index);
342                }
343
344                boolean directUnlock = resolveInfo.serviceInfo.directBootAware
345                    && agentInfo.settings.canUnlockProfile;
346
347                if (directUnlock) {
348                    if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
349                            + "of user " + userInfo.id + "can unlock user profile.");
350                }
351
352                if (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
353                        && !directUnlock) {
354                    if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
355                            + "'s trust agent " + name + ": FBE still locked and "
356                            + " the agent cannot unlock user profile.");
357                    continue;
358                }
359
360                if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) {
361                    int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id);
362                    if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) {
363                        if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
364                            || !directUnlock) {
365                            if (DEBUG)
366                                Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
367                                    + ": prevented by StrongAuthTracker = 0x"
368                                    + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser(
369                                    userInfo.id)));
370                            continue;
371                        }
372                    }
373                }
374
375                if (agentInfo.agent == null) {
376                    agentInfo.agent = new TrustAgentWrapper(mContext, this,
377                            new Intent().setComponent(name), userInfo.getUserHandle());
378                }
379
380                if (!mActiveAgents.contains(agentInfo)) {
381                    mActiveAgents.add(agentInfo);
382                } else {
383                    obsoleteAgents.remove(agentInfo);
384                }
385            }
386        }
387
388        boolean trustMayHaveChanged = false;
389        for (int i = 0; i < obsoleteAgents.size(); i++) {
390            AgentInfo info = obsoleteAgents.valueAt(i);
391            if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
392                if (info.agent.isManagingTrust()) {
393                    trustMayHaveChanged = true;
394                }
395                info.agent.destroy();
396                mActiveAgents.remove(info);
397            }
398        }
399
400        if (trustMayHaveChanged) {
401            if (userIdOrAll == UserHandle.USER_ALL) {
402                updateTrustAll();
403            } else {
404                updateTrust(userIdOrAll, 0);
405            }
406        }
407    }
408
409    boolean isDeviceLockedInner(int userId) {
410        synchronized (mDeviceLockedForUser) {
411            return mDeviceLockedForUser.get(userId, true);
412        }
413    }
414
415    private void refreshDeviceLockedForUser(int userId) {
416        if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
417            Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
418                    + " must be USER_ALL or a specific user.", new Throwable("here"));
419            userId = UserHandle.USER_ALL;
420        }
421        List<UserInfo> userInfos;
422        if (userId == UserHandle.USER_ALL) {
423            userInfos = mUserManager.getUsers(true /* excludeDying */);
424        } else {
425            userInfos = new ArrayList<>();
426            userInfos.add(mUserManager.getUserInfo(userId));
427        }
428
429        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
430
431        for (int i = 0; i < userInfos.size(); i++) {
432            UserInfo info = userInfos.get(i);
433
434            if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
435                    || !info.supportsSwitchToByUser()) {
436                continue;
437            }
438
439            int id = info.id;
440            boolean secure = mLockPatternUtils.isSecure(id);
441            boolean trusted = aggregateIsTrusted(id);
442            boolean showingKeyguard = true;
443            boolean fingerprintAuthenticated = false;
444
445            if (mCurrentUser == id) {
446                synchronized(mUsersUnlockedByFingerprint) {
447                    fingerprintAuthenticated = mUsersUnlockedByFingerprint.get(id, false);
448                }
449                try {
450                    showingKeyguard = wm.isKeyguardLocked();
451                } catch (RemoteException e) {
452                }
453            }
454            boolean deviceLocked = secure && showingKeyguard && !trusted &&
455                    !fingerprintAuthenticated;
456            setDeviceLockedForUser(id, deviceLocked);
457        }
458    }
459
460    private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
461        final boolean changed;
462        synchronized (mDeviceLockedForUser) {
463            changed = isDeviceLockedInner(userId) != locked;
464            mDeviceLockedForUser.put(userId, locked);
465        }
466        if (changed) {
467            dispatchDeviceLocked(userId, locked);
468        }
469    }
470
471    private void dispatchDeviceLocked(int userId, boolean isLocked) {
472        for (int i = 0; i < mActiveAgents.size(); i++) {
473            AgentInfo agent = mActiveAgents.valueAt(i);
474            if (agent.userId == userId) {
475                if (isLocked) {
476                    agent.agent.onDeviceLocked();
477                } else{
478                    agent.agent.onDeviceUnlocked();
479                }
480            }
481        }
482    }
483
484    void updateDevicePolicyFeatures() {
485        boolean changed = false;
486        for (int i = 0; i < mActiveAgents.size(); i++) {
487            AgentInfo info = mActiveAgents.valueAt(i);
488            if (info.agent.isConnected()) {
489                info.agent.updateDevicePolicyFeatures();
490                changed = true;
491            }
492        }
493        if (changed) {
494            mArchive.logDevicePolicyChanged();
495        }
496    }
497
498    private void removeAgentsOfPackage(String packageName) {
499        boolean trustMayHaveChanged = false;
500        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
501            AgentInfo info = mActiveAgents.valueAt(i);
502            if (packageName.equals(info.component.getPackageName())) {
503                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
504                if (info.agent.isManagingTrust()) {
505                    trustMayHaveChanged = true;
506                }
507                info.agent.destroy();
508                mActiveAgents.removeAt(i);
509            }
510        }
511        if (trustMayHaveChanged) {
512            updateTrustAll();
513        }
514    }
515
516    public void resetAgent(ComponentName name, int userId) {
517        boolean trustMayHaveChanged = false;
518        for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
519            AgentInfo info = mActiveAgents.valueAt(i);
520            if (name.equals(info.component) && userId == info.userId) {
521                Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
522                if (info.agent.isManagingTrust()) {
523                    trustMayHaveChanged = true;
524                }
525                info.agent.destroy();
526                mActiveAgents.removeAt(i);
527            }
528        }
529        if (trustMayHaveChanged) {
530            updateTrust(userId, 0);
531        }
532        refreshAgentList(userId);
533    }
534
535    private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) {
536        if (resolveInfo == null || resolveInfo.serviceInfo == null
537                || resolveInfo.serviceInfo.metaData == null) return null;
538        String cn = null;
539        boolean canUnlockProfile = false;
540
541        XmlResourceParser parser = null;
542        Exception caughtException = null;
543        try {
544            parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
545                    TrustAgentService.TRUST_AGENT_META_DATA);
546            if (parser == null) {
547                Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
548                return null;
549            }
550            Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
551            AttributeSet attrs = Xml.asAttributeSet(parser);
552            int type;
553            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
554                    && type != XmlPullParser.START_TAG) {
555                // Drain preamble.
556            }
557            String nodeName = parser.getName();
558            if (!"trust-agent".equals(nodeName)) {
559                Slog.w(TAG, "Meta-data does not start with trust-agent tag");
560                return null;
561            }
562            TypedArray sa = res
563                    .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
564            cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
565            canUnlockProfile = sa.getBoolean(
566                    com.android.internal.R.styleable.TrustAgent_unlockProfile, false);
567            sa.recycle();
568        } catch (PackageManager.NameNotFoundException e) {
569            caughtException = e;
570        } catch (IOException e) {
571            caughtException = e;
572        } catch (XmlPullParserException e) {
573            caughtException = e;
574        } finally {
575            if (parser != null) parser.close();
576        }
577        if (caughtException != null) {
578            Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
579            return null;
580        }
581        if (cn == null) {
582            return null;
583        }
584        if (cn.indexOf('/') < 0) {
585            cn = resolveInfo.serviceInfo.packageName + "/" + cn;
586        }
587        return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
588    }
589
590    private ComponentName getComponentName(ResolveInfo resolveInfo) {
591        if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
592        return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
593    }
594
595    private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
596        if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
597                Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
598            return;
599        }
600        PackageManager pm = mContext.getPackageManager();
601        List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
602        ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
603        boolean shouldUseDefaultAgent = defaultAgent != null;
604        ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
605
606        if (shouldUseDefaultAgent) {
607            discoveredAgents.add(defaultAgent);
608            Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
609        } else { // A default agent is not set; perform regular trust agent discovery
610            for (ResolveInfo resolveInfo : resolveInfos) {
611                ComponentName componentName = getComponentName(resolveInfo);
612                int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
613                if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
614                    Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
615                            + "is not a system package.");
616                    continue;
617                }
618                discoveredAgents.add(componentName);
619            }
620        }
621
622        List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
623        if (previouslyEnabledAgents != null) {
624            discoveredAgents.addAll(previouslyEnabledAgents);
625        }
626        utils.setEnabledTrustAgents(discoveredAgents, userId);
627        Settings.Secure.putIntForUser(mContext.getContentResolver(),
628                Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
629    }
630
631    /**
632     * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
633     * is no trust agent set.
634     */
635    private static ComponentName getDefaultFactoryTrustAgent(Context context) {
636        String defaultTrustAgent = context.getResources()
637            .getString(com.android.internal.R.string.config_defaultTrustAgent);
638        if (TextUtils.isEmpty(defaultTrustAgent)) {
639            return null;
640        }
641        return ComponentName.unflattenFromString(defaultTrustAgent);
642    }
643
644    private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
645        List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
646                PackageManager.GET_META_DATA |
647                PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
648                userId);
649        ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
650        for (ResolveInfo resolveInfo : resolveInfos) {
651            if (resolveInfo.serviceInfo == null) continue;
652            if (resolveInfo.serviceInfo.applicationInfo == null) continue;
653            String packageName = resolveInfo.serviceInfo.packageName;
654            if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
655                    != PackageManager.PERMISSION_GRANTED) {
656                ComponentName name = getComponentName(resolveInfo);
657                Log.w(TAG, "Skipping agent " + name + " because package does not have"
658                        + " permission " + PERMISSION_PROVIDE_AGENT + ".");
659                continue;
660            }
661            allowedAgents.add(resolveInfo);
662        }
663        return allowedAgents;
664    }
665
666    // Agent dispatch and aggregation
667
668    private boolean aggregateIsTrusted(int userId) {
669        if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
670            return false;
671        }
672        for (int i = 0; i < mActiveAgents.size(); i++) {
673            AgentInfo info = mActiveAgents.valueAt(i);
674            if (info.userId == userId) {
675                if (info.agent.isTrusted()) {
676                    return true;
677                }
678            }
679        }
680        return false;
681    }
682
683    private boolean aggregateIsTrustManaged(int userId) {
684        if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
685            return false;
686        }
687        for (int i = 0; i < mActiveAgents.size(); i++) {
688            AgentInfo info = mActiveAgents.valueAt(i);
689            if (info.userId == userId) {
690                if (info.agent.isManagingTrust()) {
691                    return true;
692                }
693            }
694        }
695        return false;
696    }
697
698    private void dispatchUnlockAttempt(boolean successful, int userId) {
699        if (successful) {
700            mStrongAuthTracker.allowTrustFromUnlock(userId);
701        }
702
703        for (int i = 0; i < mActiveAgents.size(); i++) {
704            AgentInfo info = mActiveAgents.valueAt(i);
705            if (info.userId == userId) {
706                info.agent.onUnlockAttempt(successful);
707            }
708        }
709    }
710
711    private void dispatchUnlockLockout(int timeoutMs, int userId) {
712        for (int i = 0; i < mActiveAgents.size(); i++) {
713            AgentInfo info = mActiveAgents.valueAt(i);
714            if (info.userId == userId) {
715                info.agent.onUnlockLockout(timeoutMs);
716            }
717        }
718    }
719
720    // Listeners
721
722    private void addListener(ITrustListener listener) {
723        for (int i = 0; i < mTrustListeners.size(); i++) {
724            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
725                return;
726            }
727        }
728        mTrustListeners.add(listener);
729        updateTrustAll();
730    }
731
732    private void removeListener(ITrustListener listener) {
733        for (int i = 0; i < mTrustListeners.size(); i++) {
734            if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
735                mTrustListeners.remove(i);
736                return;
737            }
738        }
739    }
740
741    private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
742        if (DEBUG) {
743            Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
744                    + Integer.toHexString(flags) + ")");
745        }
746        if (!enabled) flags = 0;
747        for (int i = 0; i < mTrustListeners.size(); i++) {
748            try {
749                mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
750            } catch (DeadObjectException e) {
751                Slog.d(TAG, "Removing dead TrustListener.");
752                mTrustListeners.remove(i);
753                i--;
754            } catch (RemoteException e) {
755                Slog.e(TAG, "Exception while notifying TrustListener.", e);
756            }
757        }
758    }
759
760    private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
761        if (DEBUG) {
762            Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
763        }
764        for (int i = 0; i < mTrustListeners.size(); i++) {
765            try {
766                mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
767            } catch (DeadObjectException e) {
768                Slog.d(TAG, "Removing dead TrustListener.");
769                mTrustListeners.remove(i);
770                i--;
771            } catch (RemoteException e) {
772                Slog.e(TAG, "Exception while notifying TrustListener.", e);
773            }
774        }
775    }
776
777    private void dispatchOnTrustError(CharSequence message) {
778        if (DEBUG) {
779            Log.i(TAG, "onTrustError(" + message + ")");
780        }
781        for (int i = 0; i < mTrustListeners.size(); i++) {
782            try {
783                mTrustListeners.get(i).onTrustError(message);
784            } catch (DeadObjectException e) {
785                Slog.d(TAG, "Removing dead TrustListener.");
786                mTrustListeners.remove(i);
787                i--;
788            } catch (RemoteException e) {
789                Slog.e(TAG, "Exception while notifying TrustListener.", e);
790            }
791        }
792    }
793
794    // User lifecycle
795
796    @Override
797    public void onStartUser(int userId) {
798        mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
799    }
800
801    @Override
802    public void onCleanupUser(int userId) {
803        mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
804    }
805
806    @Override
807    public void onSwitchUser(int userId) {
808        mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
809    }
810
811    @Override
812    public void onUnlockUser(int userId) {
813        mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
814    }
815
816    @Override
817    public void onStopUser(@UserIdInt int userId) {
818        mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
819    }
820
821    // Plumbing
822
823    private final IBinder mService = new ITrustManager.Stub() {
824        @Override
825        public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
826            enforceReportPermission();
827            mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
828                    .sendToTarget();
829        }
830
831        @Override
832        public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
833            enforceReportPermission();
834            mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
835                    .sendToTarget();
836        }
837
838        @Override
839        public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
840            enforceReportPermission();
841            // coalesce refresh messages.
842            mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
843            mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
844        }
845
846        @Override
847        public void reportKeyguardShowingChanged() throws RemoteException {
848            enforceReportPermission();
849            // coalesce refresh messages.
850            mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
851            mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
852
853            // Make sure handler processes the message before returning, such that isDeviceLocked
854            // after this call will retrieve the correct value.
855            mHandler.runWithScissors(() -> {}, 0);
856        }
857
858        @Override
859        public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
860            enforceListenerPermission();
861            mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
862        }
863
864        @Override
865        public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
866            enforceListenerPermission();
867            mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
868        }
869
870        @Override
871        public boolean isDeviceLocked(int userId) throws RemoteException {
872            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
873                    false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
874
875            long token = Binder.clearCallingIdentity();
876            try {
877                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
878                    userId = resolveProfileParent(userId);
879                }
880                return isDeviceLockedInner(userId);
881            } finally {
882                Binder.restoreCallingIdentity(token);
883            }
884        }
885
886        @Override
887        public boolean isDeviceSecure(int userId) throws RemoteException {
888            userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
889                    false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
890
891            long token = Binder.clearCallingIdentity();
892            try {
893                if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
894                    userId = resolveProfileParent(userId);
895                }
896                return mLockPatternUtils.isSecure(userId);
897            } finally {
898                Binder.restoreCallingIdentity(token);
899            }
900        }
901
902        private void enforceReportPermission() {
903            mContext.enforceCallingOrSelfPermission(
904                    Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
905        }
906
907        private void enforceListenerPermission() {
908            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
909                    "register trust listener");
910        }
911
912        @Override
913        protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
914            if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
915            if (isSafeMode()) {
916                fout.println("disabled because the system is in safe mode.");
917                return;
918            }
919            if (!mTrustAgentsCanRun) {
920                fout.println("disabled because the third-party apps can't run yet.");
921                return;
922            }
923            final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
924            mHandler.runWithScissors(new Runnable() {
925                @Override
926                public void run() {
927                    fout.println("Trust manager state:");
928                    for (UserInfo user : userInfos) {
929                        dumpUser(fout, user, user.id == mCurrentUser);
930                    }
931                }
932            }, 1500);
933        }
934
935        private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
936            fout.printf(" User \"%s\" (id=%d, flags=%#x)",
937                    user.name, user.id, user.flags);
938            if (!user.supportsSwitchToByUser()) {
939                fout.println("(managed profile)");
940                fout.println("   disabled because switching to this user is not possible.");
941                return;
942            }
943            if (isCurrent) {
944                fout.print(" (current)");
945            }
946            fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
947            fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
948            fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
949            fout.print(", strongAuthRequired=" + dumpHex(
950                    mStrongAuthTracker.getStrongAuthForUser(user.id)));
951            fout.println();
952            fout.println("   Enabled agents:");
953            boolean duplicateSimpleNames = false;
954            ArraySet<String> simpleNames = new ArraySet<String>();
955            for (AgentInfo info : mActiveAgents) {
956                if (info.userId != user.id) { continue; }
957                boolean trusted = info.agent.isTrusted();
958                fout.print("    "); fout.println(info.component.flattenToShortString());
959                fout.print("     bound=" + dumpBool(info.agent.isBound()));
960                fout.print(", connected=" + dumpBool(info.agent.isConnected()));
961                fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
962                fout.print(", trusted=" + dumpBool(trusted));
963                fout.println();
964                if (trusted) {
965                    fout.println("      message=\"" + info.agent.getMessage() + "\"");
966                }
967                if (!info.agent.isConnected()) {
968                    String restartTime = TrustArchive.formatDuration(
969                            info.agent.getScheduledRestartUptimeMillis()
970                                    - SystemClock.uptimeMillis());
971                    fout.println("      restartScheduledAt=" + restartTime);
972                }
973                if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
974                    duplicateSimpleNames = true;
975                }
976            }
977            fout.println("   Events:");
978            mArchive.dump(fout, 50, user.id, "    " /* linePrefix */, duplicateSimpleNames);
979            fout.println();
980        }
981
982        private String dumpBool(boolean b) {
983            return b ? "1" : "0";
984        }
985
986        private String dumpHex(int i) {
987            return "0x" + Integer.toHexString(i);
988        }
989
990        @Override
991        public void setDeviceLockedForUser(int userId, boolean locked) {
992            enforceReportPermission();
993            final long identity = Binder.clearCallingIdentity();
994            try {
995                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
996                    synchronized (mDeviceLockedForUser) {
997                        mDeviceLockedForUser.put(userId, locked);
998                    }
999                    if (locked) {
1000                        try {
1001                            ActivityManager.getService().notifyLockedProfile(userId);
1002                        } catch (RemoteException e) {
1003                        }
1004                    }
1005                    final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
1006                    lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1007                    lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
1008                    mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
1009                            Manifest.permission.TRUST_LISTENER, /* options */ null);
1010                }
1011            } finally {
1012                Binder.restoreCallingIdentity(identity);
1013            }
1014        }
1015
1016        @Override
1017        public boolean isTrustUsuallyManaged(int userId) {
1018            mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
1019                    "query trust state");
1020            return isTrustUsuallyManagedInternal(userId);
1021        }
1022
1023        @Override
1024        public void unlockedByFingerprintForUser(int userId) {
1025            enforceReportPermission();
1026            synchronized(mUsersUnlockedByFingerprint) {
1027                mUsersUnlockedByFingerprint.put(userId, true);
1028            }
1029            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
1030                    0 /* arg2 */).sendToTarget();
1031        }
1032
1033        @Override
1034        public void clearAllFingerprints() {
1035            enforceReportPermission();
1036            synchronized(mUsersUnlockedByFingerprint) {
1037                mUsersUnlockedByFingerprint.clear();
1038            }
1039            mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
1040                    0 /* arg2 */).sendToTarget();
1041        }
1042    };
1043
1044    private boolean isTrustUsuallyManagedInternal(int userId) {
1045        synchronized (mTrustUsuallyManagedForUser) {
1046            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1047            if (i >= 0) {
1048                return mTrustUsuallyManagedForUser.valueAt(i);
1049            }
1050        }
1051        // It's not in memory yet, get the value from persisted storage instead
1052        boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
1053        synchronized (mTrustUsuallyManagedForUser) {
1054            int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
1055            if (i >= 0) {
1056                // Someone set the trust usually managed in the mean time. Better use that.
1057                return mTrustUsuallyManagedForUser.valueAt(i);
1058            } else {
1059                // .. otherwise it's safe to cache the fetched value now.
1060                mTrustUsuallyManagedForUser.put(userId, persistedValue);
1061                return persistedValue;
1062            }
1063        }
1064    }
1065
1066    private int resolveProfileParent(int userId) {
1067        long identity = Binder.clearCallingIdentity();
1068        try {
1069            UserInfo parent = mUserManager.getProfileParent(userId);
1070            if (parent != null) {
1071                return parent.getUserHandle().getIdentifier();
1072            }
1073            return userId;
1074        } finally {
1075            Binder.restoreCallingIdentity(identity);
1076        }
1077    }
1078
1079    private final Handler mHandler = new Handler() {
1080        @Override
1081        public void handleMessage(Message msg) {
1082            switch (msg.what) {
1083                case MSG_REGISTER_LISTENER:
1084                    addListener((ITrustListener) msg.obj);
1085                    break;
1086                case MSG_UNREGISTER_LISTENER:
1087                    removeListener((ITrustListener) msg.obj);
1088                    break;
1089                case MSG_DISPATCH_UNLOCK_ATTEMPT:
1090                    dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
1091                    break;
1092                case MSG_DISPATCH_UNLOCK_LOCKOUT:
1093                    dispatchUnlockLockout(msg.arg1, msg.arg2);
1094                    break;
1095                case MSG_ENABLED_AGENTS_CHANGED:
1096                    refreshAgentList(UserHandle.USER_ALL);
1097                    // This is also called when the security mode of a user changes.
1098                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
1099                    break;
1100                case MSG_KEYGUARD_SHOWING_CHANGED:
1101                    refreshDeviceLockedForUser(mCurrentUser);
1102                    break;
1103                case MSG_START_USER:
1104                case MSG_CLEANUP_USER:
1105                case MSG_UNLOCK_USER:
1106                    refreshAgentList(msg.arg1);
1107                    break;
1108                case MSG_SWITCH_USER:
1109                    mCurrentUser = msg.arg1;
1110                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
1111                    break;
1112                case MSG_STOP_USER:
1113                    setDeviceLockedForUser(msg.arg1, true);
1114                    break;
1115                case MSG_FLUSH_TRUST_USUALLY_MANAGED:
1116                    SparseBooleanArray usuallyManaged;
1117                    synchronized (mTrustUsuallyManagedForUser) {
1118                        usuallyManaged = mTrustUsuallyManagedForUser.clone();
1119                    }
1120
1121                    for (int i = 0; i < usuallyManaged.size(); i++) {
1122                        int userId = usuallyManaged.keyAt(i);
1123                        boolean value = usuallyManaged.valueAt(i);
1124                        if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
1125                            mLockPatternUtils.setTrustUsuallyManaged(value, userId);
1126                        }
1127                    }
1128                    break;
1129                case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
1130                    refreshDeviceLockedForUser(msg.arg1);
1131                    break;
1132            }
1133        }
1134    };
1135
1136    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1137        @Override
1138        public void onSomePackagesChanged() {
1139            refreshAgentList(UserHandle.USER_ALL);
1140        }
1141
1142        @Override
1143        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1144            // We're interested in all changes, even if just some components get enabled / disabled.
1145            return true;
1146        }
1147
1148        @Override
1149        public void onPackageDisappeared(String packageName, int reason) {
1150            removeAgentsOfPackage(packageName);
1151        }
1152    };
1153
1154    private static class SettingsAttrs {
1155        public ComponentName componentName;
1156        public boolean canUnlockProfile;
1157
1158        public SettingsAttrs(
1159                ComponentName componentName,
1160                boolean canUnlockProfile) {
1161            this.componentName = componentName;
1162            this.canUnlockProfile = canUnlockProfile;
1163        }
1164    };
1165
1166    private class Receiver extends BroadcastReceiver {
1167
1168        @Override
1169        public void onReceive(Context context, Intent intent) {
1170            String action = intent.getAction();
1171            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
1172                refreshAgentList(getSendingUserId());
1173                updateDevicePolicyFeatures();
1174            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
1175                int userId = getUserId(intent);
1176                if (userId > 0) {
1177                    maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
1178                }
1179            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
1180                int userId = getUserId(intent);
1181                if (userId > 0) {
1182                    synchronized (mUserIsTrusted) {
1183                        mUserIsTrusted.delete(userId);
1184                    }
1185                    synchronized (mDeviceLockedForUser) {
1186                        mDeviceLockedForUser.delete(userId);
1187                    }
1188                    synchronized (mTrustUsuallyManagedForUser) {
1189                        mTrustUsuallyManagedForUser.delete(userId);
1190                    }
1191                    synchronized (mUsersUnlockedByFingerprint) {
1192                        mUsersUnlockedByFingerprint.delete(userId);
1193                    }
1194                    refreshAgentList(userId);
1195                    refreshDeviceLockedForUser(userId);
1196                }
1197            }
1198        }
1199
1200        private int getUserId(Intent intent) {
1201            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
1202            if (userId > 0) {
1203                return userId;
1204            } else {
1205                Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
1206                return -100;
1207            }
1208        }
1209
1210        public void register(Context context) {
1211            IntentFilter filter = new IntentFilter();
1212            filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1213            filter.addAction(Intent.ACTION_USER_ADDED);
1214            filter.addAction(Intent.ACTION_USER_REMOVED);
1215            context.registerReceiverAsUser(this,
1216                    UserHandle.ALL,
1217                    filter,
1218                    null /* permission */,
1219                    null /* scheduler */);
1220        }
1221    }
1222
1223    private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1224
1225        SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1226
1227        public StrongAuthTracker(Context context) {
1228            super(context);
1229        }
1230
1231        @Override
1232        public void onStrongAuthRequiredChanged(int userId) {
1233            mStartFromSuccessfulUnlock.delete(userId);
1234
1235            if (DEBUG) {
1236                Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1237                        + " trustAllowed=" + isTrustAllowedForUser(userId)
1238                        + " agentsCanRun=" + canAgentsRunForUser(userId));
1239            }
1240
1241            refreshAgentList(userId);
1242
1243            // The list of active trust agents may not have changed, if there was a previous call
1244            // to allowTrustFromUnlock, so we update the trust here too.
1245            updateTrust(userId, 0 /* flags */);
1246        }
1247
1248        boolean canAgentsRunForUser(int userId) {
1249            return mStartFromSuccessfulUnlock.get(userId)
1250                    || super.isTrustAllowedForUser(userId);
1251        }
1252
1253        /**
1254         * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1255         * changes again. Must only be called when we know about a successful unlock already
1256         * before the underlying StrongAuthTracker.
1257         *
1258         * Note that this only changes whether trust agents can be started, not the actual trusted
1259         * value.
1260         */
1261        void allowTrustFromUnlock(int userId) {
1262            if (userId < UserHandle.USER_SYSTEM) {
1263                throw new IllegalArgumentException("userId must be a valid user: " + userId);
1264            }
1265            boolean previous = canAgentsRunForUser(userId);
1266            mStartFromSuccessfulUnlock.put(userId, true);
1267
1268            if (DEBUG) {
1269                Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1270                        + " trustAllowed=" + isTrustAllowedForUser(userId)
1271                        + " agentsCanRun=" + canAgentsRunForUser(userId));
1272            }
1273
1274            if (canAgentsRunForUser(userId) != previous) {
1275                refreshAgentList(userId);
1276            }
1277        }
1278    }
1279}
1280