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