TrustManagerService.java revision 49d53452e744f03593093f6588cea12a405f9ff5
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.server.trust; 18 19import com.android.internal.annotations.GuardedBy; 20import com.android.internal.content.PackageMonitor; 21import com.android.internal.widget.LockPatternUtils; 22import com.android.server.SystemService; 23 24import org.xmlpull.v1.XmlPullParser; 25import org.xmlpull.v1.XmlPullParserException; 26 27import android.Manifest; 28import android.app.ActivityManager; 29import android.app.ActivityManagerNative; 30import android.app.admin.DevicePolicyManager; 31import android.app.trust.ITrustListener; 32import android.app.trust.ITrustManager; 33import android.content.BroadcastReceiver; 34import android.content.ComponentName; 35import android.content.Context; 36import android.content.Intent; 37import android.content.IntentFilter; 38import android.content.pm.ApplicationInfo; 39import android.content.pm.PackageManager; 40import android.content.pm.ResolveInfo; 41import android.content.pm.UserInfo; 42import android.content.res.Resources; 43import android.content.res.TypedArray; 44import android.content.res.XmlResourceParser; 45import android.graphics.drawable.Drawable; 46import android.os.Binder; 47import android.os.DeadObjectException; 48import android.os.Handler; 49import android.os.IBinder; 50import android.os.Message; 51import android.os.RemoteException; 52import android.os.SystemClock; 53import android.os.UserHandle; 54import android.os.UserManager; 55import android.provider.Settings; 56import android.service.trust.TrustAgentService; 57import android.util.ArraySet; 58import android.util.AttributeSet; 59import android.util.Log; 60import android.util.Slog; 61import android.util.SparseBooleanArray; 62import android.util.Xml; 63 64import java.io.FileDescriptor; 65import java.io.IOException; 66import java.io.PrintWriter; 67import java.util.ArrayList; 68import java.util.List; 69 70/** 71 * Manages trust agents and trust listeners. 72 * 73 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s 74 * of each user and notifies them about events that are relevant to them. 75 * It start and stops them based on the value of 76 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}. 77 * 78 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the 79 * trust state changes for any user. 80 * 81 * Trust state and the setting of enabled agents is kept per user and each user has its own 82 * instance of a {@link android.service.trust.TrustAgentService}. 83 */ 84public class TrustManagerService extends SystemService { 85 86 private static final boolean DEBUG = false; 87 private static final String TAG = "TrustManagerService"; 88 89 private static final Intent TRUST_AGENT_INTENT = 90 new Intent(TrustAgentService.SERVICE_INTERFACE); 91 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT; 92 93 private static final int MSG_REGISTER_LISTENER = 1; 94 private static final int MSG_UNREGISTER_LISTENER = 2; 95 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3; 96 private static final int MSG_ENABLED_AGENTS_CHANGED = 4; 97 private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5; 98 99 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>(); 100 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>(); 101 private final Receiver mReceiver = new Receiver(); 102 private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray(); 103 /* package */ final TrustArchive mArchive = new TrustArchive(); 104 private final Context mContext; 105 private final LockPatternUtils mLockPatternUtils; 106 private final UserManager mUserManager; 107 108 @GuardedBy("mUserIsTrusted") 109 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); 110 111 public TrustManagerService(Context context) { 112 super(context); 113 mContext = context; 114 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 115 mLockPatternUtils = new LockPatternUtils(context); 116 } 117 118 @Override 119 public void onStart() { 120 publishBinderService(Context.TRUST_SERVICE, mService); 121 } 122 123 @Override 124 public void onBootPhase(int phase) { 125 if (isSafeMode()) { 126 // No trust agents in safe mode. 127 return; 128 } 129 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 130 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); 131 mReceiver.register(mContext); 132 refreshAgentList(UserHandle.USER_ALL); 133 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { 134 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER); 135 } 136 } 137 138 // Agent management 139 140 private static final class AgentInfo { 141 CharSequence label; 142 Drawable icon; 143 ComponentName component; // service that implements ITrustAgent 144 ComponentName settings; // setting to launch to modify agent. 145 TrustAgentWrapper agent; 146 int userId; 147 148 @Override 149 public boolean equals(Object other) { 150 if (!(other instanceof AgentInfo)) { 151 return false; 152 } 153 AgentInfo o = (AgentInfo) other; 154 return component.equals(o.component) && userId == o.userId; 155 } 156 157 @Override 158 public int hashCode() { 159 return component.hashCode() * 31 + userId; 160 } 161 } 162 163 private void updateTrustAll() { 164 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); 165 for (UserInfo userInfo : userInfos) { 166 updateTrust(userInfo.id, false); 167 } 168 } 169 170 public void updateTrust(int userId, boolean initiatedByUser) { 171 dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId); 172 boolean trusted = aggregateIsTrusted(userId); 173 synchronized (mUserIsTrusted) { 174 mUserIsTrusted.put(userId, trusted); 175 } 176 dispatchOnTrustChanged(trusted, userId, initiatedByUser); 177 } 178 179 void refreshAgentList(int userId) { 180 if (DEBUG) Slog.d(TAG, "refreshAgentList()"); 181 if (isSafeMode()) { 182 // Don't ever bind to trust agents in safe mode. 183 return; 184 } 185 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) { 186 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle," 187 + " must be USER_ALL or a specific user.", new Throwable("here")); 188 userId = UserHandle.USER_ALL; 189 } 190 PackageManager pm = mContext.getPackageManager(); 191 192 List<UserInfo> userInfos; 193 if (userId == UserHandle.USER_ALL) { 194 userInfos = mUserManager.getUsers(true /* excludeDying */); 195 } else { 196 userInfos = new ArrayList<>(); 197 userInfos.add(mUserManager.getUserInfo(userId)); 198 } 199 LockPatternUtils lockPatternUtils = mLockPatternUtils; 200 201 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>(); 202 obsoleteAgents.addAll(mActiveAgents); 203 204 for (UserInfo userInfo : userInfos) { 205 if (!userInfo.supportsSwitchTo()) continue; 206 if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id) 207 == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue; 208 if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue; 209 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager(); 210 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id); 211 final boolean disableTrustAgents = 212 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0; 213 214 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id); 215 if (enabledAgents == null) { 216 continue; 217 } 218 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id); 219 for (ResolveInfo resolveInfo : resolveInfos) { 220 ComponentName name = getComponentName(resolveInfo); 221 222 if (!enabledAgents.contains(name)) continue; 223 if (disableTrustAgents) { 224 List<String> features = 225 dpm.getTrustAgentFeaturesEnabled(null /* admin */, name); 226 // Disable agent if no features are enabled. 227 if (features == null || features.isEmpty()) continue; 228 } 229 230 AgentInfo agentInfo = new AgentInfo(); 231 agentInfo.component = name; 232 agentInfo.userId = userInfo.id; 233 if (!mActiveAgents.contains(agentInfo)) { 234 agentInfo.label = resolveInfo.loadLabel(pm); 235 agentInfo.icon = resolveInfo.loadIcon(pm); 236 agentInfo.settings = getSettingsComponentName(pm, resolveInfo); 237 agentInfo.agent = new TrustAgentWrapper(mContext, this, 238 new Intent().setComponent(name), userInfo.getUserHandle()); 239 mActiveAgents.add(agentInfo); 240 } else { 241 obsoleteAgents.remove(agentInfo); 242 } 243 } 244 } 245 246 boolean trustMayHaveChanged = false; 247 for (int i = 0; i < obsoleteAgents.size(); i++) { 248 AgentInfo info = obsoleteAgents.valueAt(i); 249 if (userId == UserHandle.USER_ALL || userId == info.userId) { 250 if (info.agent.isManagingTrust()) { 251 trustMayHaveChanged = true; 252 } 253 info.agent.unbind(); 254 mActiveAgents.remove(info); 255 } 256 } 257 258 if (trustMayHaveChanged) { 259 updateTrustAll(); 260 } 261 } 262 263 void updateDevicePolicyFeatures() { 264 for (int i = 0; i < mActiveAgents.size(); i++) { 265 AgentInfo info = mActiveAgents.valueAt(i); 266 if (info.agent.isConnected()) { 267 info.agent.updateDevicePolicyFeatures(); 268 } 269 } 270 } 271 272 private void removeAgentsOfPackage(String packageName) { 273 boolean trustMayHaveChanged = false; 274 for (int i = mActiveAgents.size() - 1; i >= 0; i--) { 275 AgentInfo info = mActiveAgents.valueAt(i); 276 if (packageName.equals(info.component.getPackageName())) { 277 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString()); 278 if (info.agent.isManagingTrust()) { 279 trustMayHaveChanged = true; 280 } 281 info.agent.unbind(); 282 mActiveAgents.removeAt(i); 283 } 284 } 285 if (trustMayHaveChanged) { 286 updateTrustAll(); 287 } 288 } 289 290 public void resetAgent(ComponentName name, int userId) { 291 boolean trustMayHaveChanged = false; 292 for (int i = mActiveAgents.size() - 1; i >= 0; i--) { 293 AgentInfo info = mActiveAgents.valueAt(i); 294 if (name.equals(info.component) && userId == info.userId) { 295 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString()); 296 if (info.agent.isManagingTrust()) { 297 trustMayHaveChanged = true; 298 } 299 info.agent.unbind(); 300 mActiveAgents.removeAt(i); 301 } 302 } 303 if (trustMayHaveChanged) { 304 updateTrust(userId, false); 305 } 306 refreshAgentList(userId); 307 } 308 309 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) { 310 if (resolveInfo == null || resolveInfo.serviceInfo == null 311 || resolveInfo.serviceInfo.metaData == null) return null; 312 String cn = null; 313 XmlResourceParser parser = null; 314 Exception caughtException = null; 315 try { 316 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, 317 TrustAgentService.TRUST_AGENT_META_DATA); 318 if (parser == null) { 319 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data"); 320 return null; 321 } 322 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo); 323 AttributeSet attrs = Xml.asAttributeSet(parser); 324 int type; 325 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 326 && type != XmlPullParser.START_TAG) { 327 // Drain preamble. 328 } 329 String nodeName = parser.getName(); 330 if (!"trust-agent".equals(nodeName)) { 331 Slog.w(TAG, "Meta-data does not start with trust-agent tag"); 332 return null; 333 } 334 TypedArray sa = res 335 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent); 336 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity); 337 sa.recycle(); 338 } catch (PackageManager.NameNotFoundException e) { 339 caughtException = e; 340 } catch (IOException e) { 341 caughtException = e; 342 } catch (XmlPullParserException e) { 343 caughtException = e; 344 } finally { 345 if (parser != null) parser.close(); 346 } 347 if (caughtException != null) { 348 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException); 349 return null; 350 } 351 if (cn == null) { 352 return null; 353 } 354 if (cn.indexOf('/') < 0) { 355 cn = resolveInfo.serviceInfo.packageName + "/" + cn; 356 } 357 return ComponentName.unflattenFromString(cn); 358 } 359 360 private ComponentName getComponentName(ResolveInfo resolveInfo) { 361 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null; 362 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name); 363 } 364 365 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) { 366 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(), 367 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) { 368 return; 369 } 370 PackageManager pm = mContext.getPackageManager(); 371 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId); 372 ArraySet<ComponentName> discoveredAgents = new ArraySet<>(); 373 for (ResolveInfo resolveInfo : resolveInfos) { 374 ComponentName componentName = getComponentName(resolveInfo); 375 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags; 376 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 377 Log.i(TAG, "Leaving agent " + componentName + " disabled because package " 378 + "is not a system package."); 379 continue; 380 } 381 discoveredAgents.add(componentName); 382 } 383 384 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId); 385 if (previouslyEnabledAgents != null) { 386 discoveredAgents.addAll(previouslyEnabledAgents); 387 } 388 utils.setEnabledTrustAgents(discoveredAgents, userId); 389 Settings.Secure.putIntForUser(mContext.getContentResolver(), 390 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId); 391 } 392 393 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) { 394 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT, 395 0 /* flags */, userId); 396 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size()); 397 for (ResolveInfo resolveInfo : resolveInfos) { 398 if (resolveInfo.serviceInfo == null) continue; 399 if (resolveInfo.serviceInfo.applicationInfo == null) continue; 400 String packageName = resolveInfo.serviceInfo.packageName; 401 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName) 402 != PackageManager.PERMISSION_GRANTED) { 403 ComponentName name = getComponentName(resolveInfo); 404 Log.w(TAG, "Skipping agent " + name + " because package does not have" 405 + " permission " + PERMISSION_PROVIDE_AGENT + "."); 406 continue; 407 } 408 allowedAgents.add(resolveInfo); 409 } 410 return allowedAgents; 411 } 412 413 // Agent dispatch and aggregation 414 415 private boolean aggregateIsTrusted(int userId) { 416 if (!mUserHasAuthenticatedSinceBoot.get(userId)) { 417 return false; 418 } 419 for (int i = 0; i < mActiveAgents.size(); i++) { 420 AgentInfo info = mActiveAgents.valueAt(i); 421 if (info.userId == userId) { 422 if (info.agent.isTrusted()) { 423 return true; 424 } 425 } 426 } 427 return false; 428 } 429 430 private boolean aggregateIsTrustManaged(int userId) { 431 if (!mUserHasAuthenticatedSinceBoot.get(userId)) { 432 return false; 433 } 434 for (int i = 0; i < mActiveAgents.size(); i++) { 435 AgentInfo info = mActiveAgents.valueAt(i); 436 if (info.userId == userId) { 437 if (info.agent.isManagingTrust()) { 438 return true; 439 } 440 } 441 } 442 return false; 443 } 444 445 private void dispatchUnlockAttempt(boolean successful, int userId) { 446 for (int i = 0; i < mActiveAgents.size(); i++) { 447 AgentInfo info = mActiveAgents.valueAt(i); 448 if (info.userId == userId) { 449 info.agent.onUnlockAttempt(successful); 450 } 451 } 452 453 if (successful) { 454 updateUserHasAuthenticated(userId); 455 } 456 } 457 458 private void updateUserHasAuthenticated(int userId) { 459 if (!mUserHasAuthenticatedSinceBoot.get(userId)) { 460 mUserHasAuthenticatedSinceBoot.put(userId, true); 461 refreshAgentList(userId); 462 } 463 } 464 465 466 private void requireCredentialEntry(int userId) { 467 if (userId == UserHandle.USER_ALL) { 468 mUserHasAuthenticatedSinceBoot.clear(); 469 refreshAgentList(UserHandle.USER_ALL); 470 } else { 471 mUserHasAuthenticatedSinceBoot.put(userId, false); 472 refreshAgentList(userId); 473 } 474 } 475 476 // Listeners 477 478 private void addListener(ITrustListener listener) { 479 for (int i = 0; i < mTrustListeners.size(); i++) { 480 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) { 481 return; 482 } 483 } 484 mTrustListeners.add(listener); 485 updateTrustAll(); 486 } 487 488 private void removeListener(ITrustListener listener) { 489 for (int i = 0; i < mTrustListeners.size(); i++) { 490 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) { 491 mTrustListeners.remove(i); 492 return; 493 } 494 } 495 } 496 497 private void dispatchOnTrustChanged(boolean enabled, int userId, boolean initiatedByUser) { 498 if (!enabled) initiatedByUser = false; 499 for (int i = 0; i < mTrustListeners.size(); i++) { 500 try { 501 mTrustListeners.get(i).onTrustChanged(enabled, userId, initiatedByUser); 502 } catch (DeadObjectException e) { 503 Slog.d(TAG, "Removing dead TrustListener."); 504 mTrustListeners.remove(i); 505 i--; 506 } catch (RemoteException e) { 507 Slog.e(TAG, "Exception while notifying TrustListener.", e); 508 } 509 } 510 } 511 512 private void dispatchOnTrustManagedChanged(boolean managed, int userId) { 513 for (int i = 0; i < mTrustListeners.size(); i++) { 514 try { 515 mTrustListeners.get(i).onTrustManagedChanged(managed, userId); 516 } catch (DeadObjectException e) { 517 Slog.d(TAG, "Removing dead TrustListener."); 518 mTrustListeners.remove(i); 519 i--; 520 } catch (RemoteException e) { 521 Slog.e(TAG, "Exception while notifying TrustListener.", e); 522 } 523 } 524 } 525 526 // Plumbing 527 528 private final IBinder mService = new ITrustManager.Stub() { 529 @Override 530 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException { 531 enforceReportPermission(); 532 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId) 533 .sendToTarget(); 534 } 535 536 @Override 537 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException { 538 enforceReportPermission(); 539 // coalesce refresh messages. 540 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED); 541 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED); 542 } 543 544 @Override 545 public void reportRequireCredentialEntry(int userId) throws RemoteException { 546 enforceReportPermission(); 547 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) { 548 mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget(); 549 } else { 550 throw new IllegalArgumentException( 551 "userId must be an explicit user id or USER_ALL"); 552 } 553 } 554 555 @Override 556 public void registerTrustListener(ITrustListener trustListener) throws RemoteException { 557 enforceListenerPermission(); 558 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget(); 559 } 560 561 @Override 562 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException { 563 enforceListenerPermission(); 564 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget(); 565 } 566 567 @Override 568 public boolean isTrusted(int userId) throws RemoteException { 569 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, 570 false /* allowAll */, true /* requireFull */, "isTrusted", null); 571 userId = resolveProfileParent(userId); 572 synchronized (mUserIsTrusted) { 573 return mUserIsTrusted.get(userId); 574 } 575 } 576 577 private void enforceReportPermission() { 578 mContext.enforceCallingOrSelfPermission( 579 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events"); 580 } 581 582 private void enforceListenerPermission() { 583 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER, 584 "register trust listener"); 585 } 586 587 @Override 588 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) { 589 mContext.enforceCallingPermission(Manifest.permission.DUMP, 590 "dumping TrustManagerService"); 591 if (isSafeMode()) { 592 fout.println("disabled because the system is in safe mode."); 593 return; 594 } 595 final UserInfo currentUser; 596 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); 597 try { 598 currentUser = ActivityManagerNative.getDefault().getCurrentUser(); 599 } catch (RemoteException e) { 600 throw new RuntimeException(e); 601 } 602 mHandler.runWithScissors(new Runnable() { 603 @Override 604 public void run() { 605 fout.println("Trust manager state:"); 606 for (UserInfo user : userInfos) { 607 dumpUser(fout, user, user.id == currentUser.id); 608 } 609 } 610 }, 1500); 611 } 612 613 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) { 614 fout.printf(" User \"%s\" (id=%d, flags=%#x)", 615 user.name, user.id, user.flags); 616 if (isCurrent) { 617 fout.print(" (current)"); 618 } 619 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id))); 620 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id))); 621 fout.println(); 622 fout.println(" Enabled agents:"); 623 boolean duplicateSimpleNames = false; 624 ArraySet<String> simpleNames = new ArraySet<String>(); 625 for (AgentInfo info : mActiveAgents) { 626 if (info.userId != user.id) { continue; } 627 boolean trusted = info.agent.isTrusted(); 628 fout.print(" "); fout.println(info.component.flattenToShortString()); 629 fout.print(" bound=" + dumpBool(info.agent.isBound())); 630 fout.print(", connected=" + dumpBool(info.agent.isConnected())); 631 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust())); 632 fout.print(", trusted=" + dumpBool(trusted)); 633 fout.println(); 634 if (trusted) { 635 fout.println(" message=\"" + info.agent.getMessage() + "\""); 636 } 637 if (!info.agent.isConnected()) { 638 String restartTime = TrustArchive.formatDuration( 639 info.agent.getScheduledRestartUptimeMillis() 640 - SystemClock.uptimeMillis()); 641 fout.println(" restartScheduledAt=" + restartTime); 642 } 643 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) { 644 duplicateSimpleNames = true; 645 } 646 } 647 fout.println(" Events:"); 648 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames); 649 fout.println(); 650 } 651 652 private String dumpBool(boolean b) { 653 return b ? "1" : "0"; 654 } 655 }; 656 657 private int resolveProfileParent(int userId) { 658 long identity = Binder.clearCallingIdentity(); 659 try { 660 UserInfo parent = mUserManager.getProfileParent(userId); 661 if (parent != null) { 662 return parent.getUserHandle().getIdentifier(); 663 } 664 return userId; 665 } finally { 666 Binder.restoreCallingIdentity(identity); 667 } 668 } 669 670 private final Handler mHandler = new Handler() { 671 @Override 672 public void handleMessage(Message msg) { 673 switch (msg.what) { 674 case MSG_REGISTER_LISTENER: 675 addListener((ITrustListener) msg.obj); 676 break; 677 case MSG_UNREGISTER_LISTENER: 678 removeListener((ITrustListener) msg.obj); 679 break; 680 case MSG_DISPATCH_UNLOCK_ATTEMPT: 681 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2); 682 break; 683 case MSG_ENABLED_AGENTS_CHANGED: 684 refreshAgentList(UserHandle.USER_ALL); 685 break; 686 case MSG_REQUIRE_CREDENTIAL_ENTRY: 687 requireCredentialEntry(msg.arg1); 688 break; 689 } 690 } 691 }; 692 693 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 694 @Override 695 public void onSomePackagesChanged() { 696 refreshAgentList(UserHandle.USER_ALL); 697 } 698 699 @Override 700 public boolean onPackageChanged(String packageName, int uid, String[] components) { 701 // We're interested in all changes, even if just some components get enabled / disabled. 702 return true; 703 } 704 705 @Override 706 public void onPackageDisappeared(String packageName, int reason) { 707 removeAgentsOfPackage(packageName); 708 } 709 }; 710 711 private class Receiver extends BroadcastReceiver { 712 713 @Override 714 public void onReceive(Context context, Intent intent) { 715 String action = intent.getAction(); 716 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) { 717 refreshAgentList(getSendingUserId()); 718 updateDevicePolicyFeatures(); 719 } else if (Intent.ACTION_USER_PRESENT.equals(action)) { 720 updateUserHasAuthenticated(getSendingUserId()); 721 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 722 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100); 723 if (userId > 0) { 724 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId); 725 } else { 726 Log.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId); 727 } 728 } 729 } 730 731 public void register(Context context) { 732 IntentFilter filter = new IntentFilter(); 733 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 734 filter.addAction(Intent.ACTION_USER_PRESENT); 735 filter.addAction(Intent.ACTION_USER_ADDED); 736 context.registerReceiverAsUser(this, 737 UserHandle.ALL, 738 filter, 739 null /* permission */, 740 null /* scheduler */); 741 } 742 } 743} 744