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