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
17 package com.android.server.trust;
18
19 import android.Manifest;
20 import android.annotation.UserIdInt;
21 import android.app.ActivityManager;
22 import android.app.admin.DevicePolicyManager;
23 import android.app.trust.ITrustListener;
24 import android.app.trust.ITrustManager;
25 import android.content.BroadcastReceiver;
26 import android.content.ComponentName;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.content.pm.ApplicationInfo;
31 import android.content.pm.PackageManager;
32 import android.content.pm.ResolveInfo;
33 import android.content.pm.UserInfo;
34 import android.content.res.Resources;
35 import android.content.res.TypedArray;
36 import android.content.res.XmlResourceParser;
37 import android.graphics.drawable.Drawable;
38 import android.os.Binder;
39 import android.os.Build;
40 import android.os.DeadObjectException;
41 import android.os.Handler;
42 import android.os.IBinder;
43 import android.os.Message;
44 import android.os.PersistableBundle;
45 import android.os.RemoteException;
46 import android.os.SystemClock;
47 import android.os.UserHandle;
48 import android.os.UserManager;
49 import android.os.storage.StorageManager;
50 import android.provider.Settings;
51 import android.service.trust.TrustAgentService;
52 import android.text.TextUtils;
53 import android.util.ArraySet;
54 import android.util.AttributeSet;
55 import android.util.Log;
56 import android.util.Slog;
57 import android.util.SparseBooleanArray;
58 import android.util.Xml;
59 import android.view.IWindowManager;
60 import android.view.WindowManagerGlobal;
61 import com.android.internal.annotations.GuardedBy;
62 import com.android.internal.content.PackageMonitor;
63 import com.android.internal.policy.IKeyguardDismissCallback;
64 import com.android.internal.util.DumpUtils;
65 import com.android.internal.widget.LockPatternUtils;
66 import com.android.server.SystemService;
67 import java.io.FileDescriptor;
68 import java.io.IOException;
69 import java.io.PrintWriter;
70 import java.util.ArrayList;
71 import java.util.List;
72 import org.xmlpull.v1.XmlPullParser;
73 import 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 */
89 public 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 }