2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 package com.android.server.trust;
19 import com.android.internal.annotations.GuardedBy;
20 import com.android.internal.content.PackageMonitor;
21 import com.android.internal.widget.LockPatternUtils;
22 import com.android.server.SystemService;
24 import org.xmlpull.v1.XmlPullParser;
25 import org.xmlpull.v1.XmlPullParserException;
27 import android.Manifest;
28 import android.app.ActivityManager;
29 import android.app.ActivityManagerNative;
30 import android.app.admin.DevicePolicyManager;
31 import android.app.trust.ITrustListener;
32 import android.app.trust.ITrustManager;
33 import android.content.BroadcastReceiver;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.IntentFilter;
38 import android.content.pm.ApplicationInfo;
39 import android.content.pm.PackageManager;
40 import android.content.pm.ResolveInfo;
41 import android.content.pm.UserInfo;
42 import android.content.res.Resources;
43 import android.content.res.TypedArray;
44 import android.content.res.XmlResourceParser;
45 import android.graphics.drawable.Drawable;
46 import android.os.Binder;
47 import android.os.DeadObjectException;
48 import android.os.Handler;
49 import android.os.IBinder;
50 import android.os.Message;
51 import android.os.PersistableBundle;
52 import android.os.RemoteException;
53 import android.os.SystemClock;
54 import android.os.UserHandle;
55 import android.os.UserManager;
56 import android.os.storage.StorageManager;
57 import android.provider.Settings;
58 import android.service.trust.TrustAgentService;
59 import android.util.ArraySet;
60 import android.util.AttributeSet;
61 import android.util.Log;
62 import android.util.Slog;
63 import android.util.SparseBooleanArray;
64 import android.util.Xml;
65 import android.view.IWindowManager;
66 import android.view.WindowManagerGlobal;
68 import java.io.FileDescriptor;
69 import java.io.IOException;
70 import java.io.PrintWriter;
71 import java.util.ArrayList;
72 import java.util.List;
75 * Manages trust agents and trust listeners.
77 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
78 * of each user and notifies them about events that are relevant to them.
79 * It start and stops them based on the value of
80 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
82 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
83 * trust state changes for any user.
85 * Trust state and the setting of enabled agents is kept per user and each user has its own
86 * instance of a {@link android.service.trust.TrustAgentService}.
88 public class TrustManagerService extends SystemService {
90 private static final boolean DEBUG = false;
91 private static final String TAG = "TrustManagerService";
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;
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_SET_DEVICE_LOCKED = 10;
106 private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 11;
107 private static final int MSG_UNLOCK_USER = 12;
109 private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
111 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
112 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
113 private final Receiver mReceiver = new Receiver();
115 /* package */ final TrustArchive mArchive = new TrustArchive();
116 private final Context mContext;
117 private final LockPatternUtils mLockPatternUtils;
118 private final UserManager mUserManager;
119 private final ActivityManager mActivityManager;
121 @GuardedBy("mUserIsTrusted")
122 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
124 @GuardedBy("mDeviceLockedForUser")
125 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
127 @GuardedBy("mDeviceLockedForUser")
128 private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
130 private final StrongAuthTracker mStrongAuthTracker;
132 private boolean mTrustAgentsCanRun = false;
133 private int mCurrentUser = UserHandle.USER_SYSTEM;
135 public TrustManagerService(Context context) {
138 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
139 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
140 mLockPatternUtils = new LockPatternUtils(context);
141 mStrongAuthTracker = new StrongAuthTracker(context);
145 public void onStart() {
146 publishBinderService(Context.TRUST_SERVICE, mService);
150 public void onBootPhase(int phase) {
152 // No trust agents in safe mode.
155 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
156 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
157 mReceiver.register(mContext);
158 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
159 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
160 mTrustAgentsCanRun = true;
161 refreshAgentList(UserHandle.USER_ALL);
162 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
163 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
169 private static final class AgentInfo {
172 ComponentName component; // service that implements ITrustAgent
173 ComponentName settings; // setting to launch to modify agent.
174 TrustAgentWrapper agent;
178 public boolean equals(Object other) {
179 if (!(other instanceof AgentInfo)) {
182 AgentInfo o = (AgentInfo) other;
183 return component.equals(o.component) && userId == o.userId;
187 public int hashCode() {
188 return component.hashCode() * 31 + userId;
192 private void updateTrustAll() {
193 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
194 for (UserInfo userInfo : userInfos) {
195 updateTrust(userInfo.id, 0);
199 public void updateTrust(int userId, int flags) {
200 boolean managed = aggregateIsTrustManaged(userId);
201 dispatchOnTrustManagedChanged(managed, userId);
202 if (mStrongAuthTracker.isTrustAllowedForUser(userId)
203 && isTrustUsuallyManagedInternal(userId) != managed) {
204 updateTrustUsuallyManaged(userId, managed);
206 boolean trusted = aggregateIsTrusted(userId);
208 synchronized (mUserIsTrusted) {
209 changed = mUserIsTrusted.get(userId) != trusted;
210 mUserIsTrusted.put(userId, trusted);
212 dispatchOnTrustChanged(trusted, userId, flags);
214 refreshDeviceLockedForUser(userId);
218 private void updateTrustUsuallyManaged(int userId, boolean managed) {
219 synchronized (mTrustUsuallyManagedForUser) {
220 mTrustUsuallyManagedForUser.put(userId, managed);
222 // Wait a few minutes before committing to flash, in case the trust agent is transiently not
223 // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
224 mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
225 mHandler.sendMessageDelayed(
226 mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
227 TRUST_USUALLY_MANAGED_FLUSH_DELAY);
230 void refreshAgentList(int userIdOrAll) {
231 if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
232 if (!mTrustAgentsCanRun) {
235 if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
236 Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
237 + " must be USER_ALL or a specific user.", new Throwable("here"));
238 userIdOrAll = UserHandle.USER_ALL;
240 PackageManager pm = mContext.getPackageManager();
242 List<UserInfo> userInfos;
243 if (userIdOrAll == UserHandle.USER_ALL) {
244 userInfos = mUserManager.getUsers(true /* excludeDying */);
246 userInfos = new ArrayList<>();
247 userInfos.add(mUserManager.getUserInfo(userIdOrAll));
249 LockPatternUtils lockPatternUtils = mLockPatternUtils;
251 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
252 obsoleteAgents.addAll(mActiveAgents);
254 for (UserInfo userInfo : userInfos) {
255 if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
256 || userInfo.guestToRemove) continue;
257 if (!userInfo.supportsSwitchToByUser()) continue;
258 if (!StorageManager.isUserKeyUnlocked(userInfo.id)) continue;
259 if (!mActivityManager.isUserRunning(userInfo.id)) continue;
260 if (!lockPatternUtils.isSecure(userInfo.id)) continue;
261 if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) continue;
262 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
263 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
264 final boolean disableTrustAgents =
265 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
267 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
268 if (enabledAgents == null) {
271 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
272 for (ResolveInfo resolveInfo : resolveInfos) {
273 ComponentName name = getComponentName(resolveInfo);
275 if (!enabledAgents.contains(name)) continue;
276 if (disableTrustAgents) {
277 List<PersistableBundle> config =
278 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
279 // Disable agent if no features are enabled.
280 if (config == null || config.isEmpty()) continue;
283 AgentInfo agentInfo = new AgentInfo();
284 agentInfo.component = name;
285 agentInfo.userId = userInfo.id;
286 if (!mActiveAgents.contains(agentInfo)) {
287 agentInfo.label = resolveInfo.loadLabel(pm);
288 agentInfo.icon = resolveInfo.loadIcon(pm);
289 agentInfo.settings = getSettingsComponentName(pm, resolveInfo);
290 agentInfo.agent = new TrustAgentWrapper(mContext, this,
291 new Intent().setComponent(name), userInfo.getUserHandle());
292 mActiveAgents.add(agentInfo);
294 obsoleteAgents.remove(agentInfo);
299 boolean trustMayHaveChanged = false;
300 for (int i = 0; i < obsoleteAgents.size(); i++) {
301 AgentInfo info = obsoleteAgents.valueAt(i);
302 if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
303 if (info.agent.isManagingTrust()) {
304 trustMayHaveChanged = true;
306 info.agent.destroy();
307 mActiveAgents.remove(info);
311 if (trustMayHaveChanged) {
312 if (userIdOrAll == UserHandle.USER_ALL) {
315 updateTrust(userIdOrAll, 0);
320 public void setDeviceLockedForUser(int userId, boolean locked) {
321 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
322 synchronized (mDeviceLockedForUser) {
323 mDeviceLockedForUser.put(userId, locked);
327 ActivityManagerNative.getDefault().notifyLockedProfile(userId);
328 } catch (RemoteException e) {
334 boolean isDeviceLockedInner(int userId) {
335 synchronized (mDeviceLockedForUser) {
336 return mDeviceLockedForUser.get(userId, true);
340 private void refreshDeviceLockedForUser(int userId) {
341 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
342 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
343 + " must be USER_ALL or a specific user.", new Throwable("here"));
344 userId = UserHandle.USER_ALL;
347 List<UserInfo> userInfos;
348 if (userId == UserHandle.USER_ALL) {
349 userInfos = mUserManager.getUsers(true /* excludeDying */);
351 userInfos = new ArrayList<>();
352 userInfos.add(mUserManager.getUserInfo(userId));
355 IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
357 for (int i = 0; i < userInfos.size(); i++) {
358 UserInfo info = userInfos.get(i);
360 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
361 || !info.supportsSwitchToByUser()) {
366 boolean secure = mLockPatternUtils.isSecure(id);
367 boolean trusted = aggregateIsTrusted(id);
368 boolean showingKeyguard = true;
369 if (mCurrentUser == id) {
371 showingKeyguard = wm.isKeyguardLocked();
372 } catch (RemoteException e) {
375 boolean deviceLocked = secure && showingKeyguard && !trusted;
378 synchronized (mDeviceLockedForUser) {
379 changed = isDeviceLockedInner(id) != deviceLocked;
380 mDeviceLockedForUser.put(id, deviceLocked);
383 dispatchDeviceLocked(id, deviceLocked);
388 private void dispatchDeviceLocked(int userId, boolean isLocked) {
389 for (int i = 0; i < mActiveAgents.size(); i++) {
390 AgentInfo agent = mActiveAgents.valueAt(i);
391 if (agent.userId == userId) {
393 agent.agent.onDeviceLocked();
395 agent.agent.onDeviceUnlocked();
401 void updateDevicePolicyFeatures() {
402 boolean changed = false;
403 for (int i = 0; i < mActiveAgents.size(); i++) {
404 AgentInfo info = mActiveAgents.valueAt(i);
405 if (info.agent.isConnected()) {
406 info.agent.updateDevicePolicyFeatures();
411 mArchive.logDevicePolicyChanged();
415 private void removeAgentsOfPackage(String packageName) {
416 boolean trustMayHaveChanged = false;
417 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
418 AgentInfo info = mActiveAgents.valueAt(i);
419 if (packageName.equals(info.component.getPackageName())) {
420 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
421 if (info.agent.isManagingTrust()) {
422 trustMayHaveChanged = true;
424 info.agent.destroy();
425 mActiveAgents.removeAt(i);
428 if (trustMayHaveChanged) {
433 public void resetAgent(ComponentName name, int userId) {
434 boolean trustMayHaveChanged = false;
435 for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
436 AgentInfo info = mActiveAgents.valueAt(i);
437 if (name.equals(info.component) && userId == info.userId) {
438 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
439 if (info.agent.isManagingTrust()) {
440 trustMayHaveChanged = true;
442 info.agent.destroy();
443 mActiveAgents.removeAt(i);
446 if (trustMayHaveChanged) {
447 updateTrust(userId, 0);
449 refreshAgentList(userId);
452 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) {
453 if (resolveInfo == null || resolveInfo.serviceInfo == null
454 || resolveInfo.serviceInfo.metaData == null) return null;
456 XmlResourceParser parser = null;
457 Exception caughtException = null;
459 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
460 TrustAgentService.TRUST_AGENT_META_DATA);
461 if (parser == null) {
462 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
465 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
466 AttributeSet attrs = Xml.asAttributeSet(parser);
468 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
469 && type != XmlPullParser.START_TAG) {
472 String nodeName = parser.getName();
473 if (!"trust-agent".equals(nodeName)) {
474 Slog.w(TAG, "Meta-data does not start with trust-agent tag");
478 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent);
479 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity);
481 } catch (PackageManager.NameNotFoundException e) {
483 } catch (IOException e) {
485 } catch (XmlPullParserException e) {
488 if (parser != null) parser.close();
490 if (caughtException != null) {
491 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
497 if (cn.indexOf('/') < 0) {
498 cn = resolveInfo.serviceInfo.packageName + "/" + cn;
500 return ComponentName.unflattenFromString(cn);
503 private ComponentName getComponentName(ResolveInfo resolveInfo) {
504 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
505 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
508 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
509 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
510 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
513 PackageManager pm = mContext.getPackageManager();
514 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
515 ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
516 for (ResolveInfo resolveInfo : resolveInfos) {
517 ComponentName componentName = getComponentName(resolveInfo);
518 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
519 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
520 Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
521 + "is not a system package.");
524 discoveredAgents.add(componentName);
527 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
528 if (previouslyEnabledAgents != null) {
529 discoveredAgents.addAll(previouslyEnabledAgents);
531 utils.setEnabledTrustAgents(discoveredAgents, userId);
532 Settings.Secure.putIntForUser(mContext.getContentResolver(),
533 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
536 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) {
537 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT,
538 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
540 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size());
541 for (ResolveInfo resolveInfo : resolveInfos) {
542 if (resolveInfo.serviceInfo == null) continue;
543 if (resolveInfo.serviceInfo.applicationInfo == null) continue;
544 String packageName = resolveInfo.serviceInfo.packageName;
545 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
546 != PackageManager.PERMISSION_GRANTED) {
547 ComponentName name = getComponentName(resolveInfo);
548 Log.w(TAG, "Skipping agent " + name + " because package does not have"
549 + " permission " + PERMISSION_PROVIDE_AGENT + ".");
552 allowedAgents.add(resolveInfo);
554 return allowedAgents;
557 // Agent dispatch and aggregation
559 private boolean aggregateIsTrusted(int userId) {
560 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
563 for (int i = 0; i < mActiveAgents.size(); i++) {
564 AgentInfo info = mActiveAgents.valueAt(i);
565 if (info.userId == userId) {
566 if (info.agent.isTrusted()) {
574 private boolean aggregateIsTrustManaged(int userId) {
575 if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
578 for (int i = 0; i < mActiveAgents.size(); i++) {
579 AgentInfo info = mActiveAgents.valueAt(i);
580 if (info.userId == userId) {
581 if (info.agent.isManagingTrust()) {
589 private void dispatchUnlockAttempt(boolean successful, int userId) {
591 mStrongAuthTracker.allowTrustFromUnlock(userId);
594 for (int i = 0; i < mActiveAgents.size(); i++) {
595 AgentInfo info = mActiveAgents.valueAt(i);
596 if (info.userId == userId) {
597 info.agent.onUnlockAttempt(successful);
604 private void addListener(ITrustListener listener) {
605 for (int i = 0; i < mTrustListeners.size(); i++) {
606 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
610 mTrustListeners.add(listener);
614 private void removeListener(ITrustListener listener) {
615 for (int i = 0; i < mTrustListeners.size(); i++) {
616 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
617 mTrustListeners.remove(i);
623 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
625 Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
626 + Integer.toHexString(flags) + ")");
628 if (!enabled) flags = 0;
629 for (int i = 0; i < mTrustListeners.size(); i++) {
631 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
632 } catch (DeadObjectException e) {
633 Slog.d(TAG, "Removing dead TrustListener.");
634 mTrustListeners.remove(i);
636 } catch (RemoteException e) {
637 Slog.e(TAG, "Exception while notifying TrustListener.", e);
642 private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
644 Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
646 for (int i = 0; i < mTrustListeners.size(); i++) {
648 mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
649 } catch (DeadObjectException e) {
650 Slog.d(TAG, "Removing dead TrustListener.");
651 mTrustListeners.remove(i);
653 } catch (RemoteException e) {
654 Slog.e(TAG, "Exception while notifying TrustListener.", e);
662 public void onStartUser(int userId) {
663 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
667 public void onCleanupUser(int userId) {
668 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
672 public void onSwitchUser(int userId) {
673 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
677 public void onUnlockUser(int userId) {
678 mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
683 private final IBinder mService = new ITrustManager.Stub() {
685 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
686 enforceReportPermission();
687 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
692 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
693 enforceReportPermission();
694 // coalesce refresh messages.
695 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
696 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
700 public void reportKeyguardShowingChanged() throws RemoteException {
701 enforceReportPermission();
702 // coalesce refresh messages.
703 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
704 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
708 public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
709 enforceListenerPermission();
710 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
714 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
715 enforceListenerPermission();
716 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
720 public boolean isDeviceLocked(int userId) throws RemoteException {
721 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
722 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
724 long token = Binder.clearCallingIdentity();
726 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
727 userId = resolveProfileParent(userId);
729 return isDeviceLockedInner(userId);
731 Binder.restoreCallingIdentity(token);
736 public boolean isDeviceSecure(int userId) throws RemoteException {
737 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
738 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
740 long token = Binder.clearCallingIdentity();
742 if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
743 userId = resolveProfileParent(userId);
745 return mLockPatternUtils.isSecure(userId);
747 Binder.restoreCallingIdentity(token);
751 private void enforceReportPermission() {
752 mContext.enforceCallingOrSelfPermission(
753 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
756 private void enforceListenerPermission() {
757 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
758 "register trust listener");
762 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
763 mContext.enforceCallingPermission(Manifest.permission.DUMP,
764 "dumping TrustManagerService");
766 fout.println("disabled because the system is in safe mode.");
769 if (!mTrustAgentsCanRun) {
770 fout.println("disabled because the third-party apps can't run yet.");
773 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
774 mHandler.runWithScissors(new Runnable() {
777 fout.println("Trust manager state:");
778 for (UserInfo user : userInfos) {
779 dumpUser(fout, user, user.id == mCurrentUser);
785 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
786 fout.printf(" User \"%s\" (id=%d, flags=%#x)",
787 user.name, user.id, user.flags);
788 if (!user.supportsSwitchToByUser()) {
789 fout.println("(managed profile)");
790 fout.println(" disabled because switching to this user is not possible.");
794 fout.print(" (current)");
796 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
797 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
798 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
799 fout.print(", strongAuthRequired=" + dumpHex(
800 mStrongAuthTracker.getStrongAuthForUser(user.id)));
802 fout.println(" Enabled agents:");
803 boolean duplicateSimpleNames = false;
804 ArraySet<String> simpleNames = new ArraySet<String>();
805 for (AgentInfo info : mActiveAgents) {
806 if (info.userId != user.id) { continue; }
807 boolean trusted = info.agent.isTrusted();
808 fout.print(" "); fout.println(info.component.flattenToShortString());
809 fout.print(" bound=" + dumpBool(info.agent.isBound()));
810 fout.print(", connected=" + dumpBool(info.agent.isConnected()));
811 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
812 fout.print(", trusted=" + dumpBool(trusted));
815 fout.println(" message=\"" + info.agent.getMessage() + "\"");
817 if (!info.agent.isConnected()) {
818 String restartTime = TrustArchive.formatDuration(
819 info.agent.getScheduledRestartUptimeMillis()
820 - SystemClock.uptimeMillis());
821 fout.println(" restartScheduledAt=" + restartTime);
823 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
824 duplicateSimpleNames = true;
827 fout.println(" Events:");
828 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
832 private String dumpBool(boolean b) {
833 return b ? "1" : "0";
836 private String dumpHex(int i) {
837 return "0x" + Integer.toHexString(i);
841 public void setDeviceLockedForUser(int userId, boolean value) {
842 enforceReportPermission();
843 mHandler.obtainMessage(MSG_SET_DEVICE_LOCKED, value ? 1 : 0, userId)
848 public boolean isTrustUsuallyManaged(int userId) {
849 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
850 "query trust state");
851 return isTrustUsuallyManagedInternal(userId);
855 private boolean isTrustUsuallyManagedInternal(int userId) {
856 synchronized (mTrustUsuallyManagedForUser) {
857 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
859 return mTrustUsuallyManagedForUser.valueAt(i);
862 // It's not in memory yet, get the value from persisted storage instead
863 boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
864 synchronized (mTrustUsuallyManagedForUser) {
865 int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
867 // Someone set the trust usually managed in the mean time. Better use that.
868 return mTrustUsuallyManagedForUser.valueAt(i);
870 // .. otherwise it's safe to cache the fetched value now.
871 mTrustUsuallyManagedForUser.put(userId, persistedValue);
872 return persistedValue;
877 private int resolveProfileParent(int userId) {
878 long identity = Binder.clearCallingIdentity();
880 UserInfo parent = mUserManager.getProfileParent(userId);
881 if (parent != null) {
882 return parent.getUserHandle().getIdentifier();
886 Binder.restoreCallingIdentity(identity);
890 private final Handler mHandler = new Handler() {
892 public void handleMessage(Message msg) {
894 case MSG_REGISTER_LISTENER:
895 addListener((ITrustListener) msg.obj);
897 case MSG_UNREGISTER_LISTENER:
898 removeListener((ITrustListener) msg.obj);
900 case MSG_DISPATCH_UNLOCK_ATTEMPT:
901 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
903 case MSG_ENABLED_AGENTS_CHANGED:
904 refreshAgentList(UserHandle.USER_ALL);
905 // This is also called when the security mode of a user changes.
906 refreshDeviceLockedForUser(UserHandle.USER_ALL);
908 case MSG_KEYGUARD_SHOWING_CHANGED:
909 refreshDeviceLockedForUser(mCurrentUser);
912 case MSG_CLEANUP_USER:
913 case MSG_UNLOCK_USER:
914 refreshAgentList(msg.arg1);
916 case MSG_SWITCH_USER:
917 mCurrentUser = msg.arg1;
918 refreshDeviceLockedForUser(UserHandle.USER_ALL);
920 case MSG_SET_DEVICE_LOCKED:
921 setDeviceLockedForUser(msg.arg2, msg.arg1 != 0);
923 case MSG_FLUSH_TRUST_USUALLY_MANAGED:
924 SparseBooleanArray usuallyManaged;
925 synchronized (mTrustUsuallyManagedForUser) {
926 usuallyManaged = mTrustUsuallyManagedForUser.clone();
929 for (int i = 0; i < usuallyManaged.size(); i++) {
930 int userId = usuallyManaged.keyAt(i);
931 boolean value = usuallyManaged.valueAt(i);
932 if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
933 mLockPatternUtils.setTrustUsuallyManaged(value, userId);
941 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
943 public void onSomePackagesChanged() {
944 refreshAgentList(UserHandle.USER_ALL);
948 public boolean onPackageChanged(String packageName, int uid, String[] components) {
949 // We're interested in all changes, even if just some components get enabled / disabled.
954 public void onPackageDisappeared(String packageName, int reason) {
955 removeAgentsOfPackage(packageName);
959 private class Receiver extends BroadcastReceiver {
962 public void onReceive(Context context, Intent intent) {
963 String action = intent.getAction();
964 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
965 refreshAgentList(getSendingUserId());
966 updateDevicePolicyFeatures();
967 } else if (Intent.ACTION_USER_ADDED.equals(action)) {
968 int userId = getUserId(intent);
970 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
972 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
973 int userId = getUserId(intent);
975 synchronized (mUserIsTrusted) {
976 mUserIsTrusted.delete(userId);
978 synchronized (mDeviceLockedForUser) {
979 mDeviceLockedForUser.delete(userId);
981 refreshAgentList(userId);
982 refreshDeviceLockedForUser(userId);
987 private int getUserId(Intent intent) {
988 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
992 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
997 public void register(Context context) {
998 IntentFilter filter = new IntentFilter();
999 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1000 filter.addAction(Intent.ACTION_USER_ADDED);
1001 filter.addAction(Intent.ACTION_USER_REMOVED);
1002 context.registerReceiverAsUser(this,
1005 null /* permission */,
1006 null /* scheduler */);
1010 private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1012 SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
1014 public StrongAuthTracker(Context context) {
1019 public void onStrongAuthRequiredChanged(int userId) {
1020 mStartFromSuccessfulUnlock.delete(userId);
1023 Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
1024 + " trustAllowed=" + isTrustAllowedForUser(userId)
1025 + " agentsCanRun=" + canAgentsRunForUser(userId));
1028 refreshAgentList(userId);
1030 // The list of active trust agents may not have changed, if there was a previous call
1031 // to allowTrustFromUnlock, so we update the trust here too.
1032 updateTrust(userId, 0 /* flags */);
1035 boolean canAgentsRunForUser(int userId) {
1036 return mStartFromSuccessfulUnlock.get(userId)
1037 || super.isTrustAllowedForUser(userId);
1041 * Temporarily suppress strong auth requirements for {@param userId} until strong auth
1042 * changes again. Must only be called when we know about a successful unlock already
1043 * before the underlying StrongAuthTracker.
1045 * Note that this only changes whether trust agents can be started, not the actual trusted
1048 void allowTrustFromUnlock(int userId) {
1049 if (userId < UserHandle.USER_SYSTEM) {
1050 throw new IllegalArgumentException("userId must be a valid user: " + userId);
1052 boolean previous = canAgentsRunForUser(userId);
1053 mStartFromSuccessfulUnlock.put(userId, true);
1056 Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
1057 + " trustAllowed=" + isTrustAllowedForUser(userId)
1058 + " agentsCanRun=" + canAgentsRunForUser(userId));
1061 if (canAgentsRunForUser(userId) != previous) {
1062 refreshAgentList(userId);