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