TrustManagerService.java revision 237b061182d36fd3bf2238092ccf3d529ec8877b
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.admin.DevicePolicyManager; 30import android.app.trust.ITrustListener; 31import android.app.trust.ITrustManager; 32import android.content.BroadcastReceiver; 33import android.content.ComponentName; 34import android.content.Context; 35import android.content.Intent; 36import android.content.IntentFilter; 37import android.content.pm.ApplicationInfo; 38import android.content.pm.PackageManager; 39import android.content.pm.ResolveInfo; 40import android.content.pm.UserInfo; 41import android.content.res.Resources; 42import android.content.res.TypedArray; 43import android.content.res.XmlResourceParser; 44import android.graphics.drawable.Drawable; 45import android.os.Binder; 46import android.os.DeadObjectException; 47import android.os.Handler; 48import android.os.IBinder; 49import android.os.Message; 50import android.os.PersistableBundle; 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; 63import android.view.IWindowManager; 64import android.view.WindowManagerGlobal; 65 66import java.io.FileDescriptor; 67import java.io.IOException; 68import java.io.PrintWriter; 69import java.util.ArrayList; 70import java.util.List; 71 72/** 73 * Manages trust agents and trust listeners. 74 * 75 * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s 76 * of each user and notifies them about events that are relevant to them. 77 * It start and stops them based on the value of 78 * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}. 79 * 80 * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the 81 * trust state changes for any user. 82 * 83 * Trust state and the setting of enabled agents is kept per user and each user has its own 84 * instance of a {@link android.service.trust.TrustAgentService}. 85 */ 86public class TrustManagerService extends SystemService { 87 88 private static final boolean DEBUG = false; 89 private static final String TAG = "TrustManagerService"; 90 91 private static final Intent TRUST_AGENT_INTENT = 92 new Intent(TrustAgentService.SERVICE_INTERFACE); 93 private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT; 94 95 private static final int MSG_REGISTER_LISTENER = 1; 96 private static final int MSG_UNREGISTER_LISTENER = 2; 97 private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3; 98 private static final int MSG_ENABLED_AGENTS_CHANGED = 4; 99 private static final int MSG_REQUIRE_CREDENTIAL_ENTRY = 5; 100 private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6; 101 private static final int MSG_START_USER = 7; 102 private static final int MSG_CLEANUP_USER = 8; 103 private static final int MSG_SWITCH_USER = 9; 104 105 private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<AgentInfo>(); 106 private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<ITrustListener>(); 107 private final Receiver mReceiver = new Receiver(); 108 private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray(); 109 /* package */ final TrustArchive mArchive = new TrustArchive(); 110 private final Context mContext; 111 private final LockPatternUtils mLockPatternUtils; 112 private final UserManager mUserManager; 113 private final ActivityManager mActivityManager; 114 115 @GuardedBy("mUserIsTrusted") 116 private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); 117 118 @GuardedBy("mDeviceLockedForUser") 119 private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray(); 120 121 private boolean mTrustAgentsCanRun = false; 122 private int mCurrentUser = UserHandle.USER_OWNER; 123 124 public TrustManagerService(Context context) { 125 super(context); 126 mContext = context; 127 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 128 mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); 129 mLockPatternUtils = new LockPatternUtils(context); 130 } 131 132 @Override 133 public void onStart() { 134 publishBinderService(Context.TRUST_SERVICE, mService); 135 } 136 137 @Override 138 public void onBootPhase(int phase) { 139 if (isSafeMode()) { 140 // No trust agents in safe mode. 141 return; 142 } 143 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 144 mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); 145 mReceiver.register(mContext); 146 } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { 147 mTrustAgentsCanRun = true; 148 refreshAgentList(UserHandle.USER_ALL); 149 } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { 150 maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER); 151 } 152 } 153 154 // Agent management 155 156 private static final class AgentInfo { 157 CharSequence label; 158 Drawable icon; 159 ComponentName component; // service that implements ITrustAgent 160 ComponentName settings; // setting to launch to modify agent. 161 TrustAgentWrapper agent; 162 int userId; 163 164 @Override 165 public boolean equals(Object other) { 166 if (!(other instanceof AgentInfo)) { 167 return false; 168 } 169 AgentInfo o = (AgentInfo) other; 170 return component.equals(o.component) && userId == o.userId; 171 } 172 173 @Override 174 public int hashCode() { 175 return component.hashCode() * 31 + userId; 176 } 177 } 178 179 private void updateTrustAll() { 180 List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); 181 for (UserInfo userInfo : userInfos) { 182 updateTrust(userInfo.id, 0); 183 } 184 } 185 186 public void updateTrust(int userId, int flags) { 187 dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId); 188 boolean trusted = aggregateIsTrusted(userId); 189 boolean changed; 190 synchronized (mUserIsTrusted) { 191 changed = mUserIsTrusted.get(userId) != trusted; 192 mUserIsTrusted.put(userId, trusted); 193 } 194 dispatchOnTrustChanged(trusted, userId, flags); 195 if (changed) { 196 refreshDeviceLockedForUser(userId); 197 } 198 } 199 200 void refreshAgentList(int userId) { 201 if (DEBUG) Slog.d(TAG, "refreshAgentList()"); 202 if (!mTrustAgentsCanRun) { 203 return; 204 } 205 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) { 206 Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle," 207 + " must be USER_ALL or a specific user.", new Throwable("here")); 208 userId = UserHandle.USER_ALL; 209 } 210 PackageManager pm = mContext.getPackageManager(); 211 212 List<UserInfo> userInfos; 213 if (userId == UserHandle.USER_ALL) { 214 userInfos = mUserManager.getUsers(true /* excludeDying */); 215 } else { 216 userInfos = new ArrayList<>(); 217 userInfos.add(mUserManager.getUserInfo(userId)); 218 } 219 LockPatternUtils lockPatternUtils = mLockPatternUtils; 220 221 ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>(); 222 obsoleteAgents.addAll(mActiveAgents); 223 224 for (UserInfo userInfo : userInfos) { 225 if (userInfo == null || userInfo.partial || !userInfo.isEnabled() 226 || userInfo.guestToRemove) continue; 227 if (!userInfo.supportsSwitchTo()) continue; 228 if (!mActivityManager.isUserRunning(userInfo.id)) continue; 229 if (!lockPatternUtils.isSecure(userInfo.id)) continue; 230 if (!getUserHasAuthenticated(userInfo.id)) continue; 231 DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager(); 232 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id); 233 final boolean disableTrustAgents = 234 (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0; 235 236 List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id); 237 if (enabledAgents == null) { 238 continue; 239 } 240 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id); 241 for (ResolveInfo resolveInfo : resolveInfos) { 242 ComponentName name = getComponentName(resolveInfo); 243 244 if (!enabledAgents.contains(name)) continue; 245 if (disableTrustAgents) { 246 List<PersistableBundle> config = 247 dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id); 248 // Disable agent if no features are enabled. 249 if (config == null || config.isEmpty()) continue; 250 } 251 252 AgentInfo agentInfo = new AgentInfo(); 253 agentInfo.component = name; 254 agentInfo.userId = userInfo.id; 255 if (!mActiveAgents.contains(agentInfo)) { 256 agentInfo.label = resolveInfo.loadLabel(pm); 257 agentInfo.icon = resolveInfo.loadIcon(pm); 258 agentInfo.settings = getSettingsComponentName(pm, resolveInfo); 259 agentInfo.agent = new TrustAgentWrapper(mContext, this, 260 new Intent().setComponent(name), userInfo.getUserHandle()); 261 mActiveAgents.add(agentInfo); 262 } else { 263 obsoleteAgents.remove(agentInfo); 264 } 265 } 266 } 267 268 boolean trustMayHaveChanged = false; 269 for (int i = 0; i < obsoleteAgents.size(); i++) { 270 AgentInfo info = obsoleteAgents.valueAt(i); 271 if (userId == UserHandle.USER_ALL || userId == info.userId) { 272 if (info.agent.isManagingTrust()) { 273 trustMayHaveChanged = true; 274 } 275 info.agent.destroy(); 276 mActiveAgents.remove(info); 277 } 278 } 279 280 if (trustMayHaveChanged) { 281 if (userId == UserHandle.USER_ALL) { 282 updateTrustAll(); 283 } else { 284 updateTrust(userId, 0); 285 } 286 } 287 } 288 289 boolean isDeviceLockedInner(int userId) { 290 synchronized (mDeviceLockedForUser) { 291 return mDeviceLockedForUser.get(userId, true); 292 } 293 } 294 295 private void refreshDeviceLockedForUser(int userId) { 296 if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) { 297 Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle," 298 + " must be USER_ALL or a specific user.", new Throwable("here")); 299 userId = UserHandle.USER_ALL; 300 } 301 302 List<UserInfo> userInfos; 303 if (userId == UserHandle.USER_ALL) { 304 userInfos = mUserManager.getUsers(true /* excludeDying */); 305 } else { 306 userInfos = new ArrayList<>(); 307 userInfos.add(mUserManager.getUserInfo(userId)); 308 } 309 310 IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 311 312 for (int i = 0; i < userInfos.size(); i++) { 313 UserInfo info = userInfos.get(i); 314 315 if (info == null || info.partial || !info.isEnabled() || info.guestToRemove 316 || !info.supportsSwitchTo()) { 317 continue; 318 } 319 320 int id = info.id; 321 boolean secure = mLockPatternUtils.isSecure(id); 322 boolean trusted = aggregateIsTrusted(id); 323 boolean showingKeyguard = true; 324 if (mCurrentUser == id) { 325 try { 326 showingKeyguard = wm.isKeyguardLocked(); 327 } catch (RemoteException e) { 328 } 329 } 330 boolean deviceLocked = secure && showingKeyguard && !trusted; 331 332 boolean changed; 333 synchronized (mDeviceLockedForUser) { 334 changed = isDeviceLockedInner(id) != deviceLocked; 335 mDeviceLockedForUser.put(id, deviceLocked); 336 } 337 if (changed) { 338 dispatchDeviceLocked(id, deviceLocked); 339 } 340 } 341 } 342 343 private void dispatchDeviceLocked(int userId, boolean isLocked) { 344 for (int i = 0; i < mActiveAgents.size(); i++) { 345 AgentInfo agent = mActiveAgents.valueAt(i); 346 if (agent.userId == userId) { 347 if (isLocked) { 348 agent.agent.onDeviceLocked(); 349 } else{ 350 agent.agent.onDeviceUnlocked(); 351 } 352 } 353 } 354 } 355 356 void updateDevicePolicyFeatures() { 357 for (int i = 0; i < mActiveAgents.size(); i++) { 358 AgentInfo info = mActiveAgents.valueAt(i); 359 if (info.agent.isConnected()) { 360 info.agent.updateDevicePolicyFeatures(); 361 } 362 } 363 } 364 365 private void removeAgentsOfPackage(String packageName) { 366 boolean trustMayHaveChanged = false; 367 for (int i = mActiveAgents.size() - 1; i >= 0; i--) { 368 AgentInfo info = mActiveAgents.valueAt(i); 369 if (packageName.equals(info.component.getPackageName())) { 370 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString()); 371 if (info.agent.isManagingTrust()) { 372 trustMayHaveChanged = true; 373 } 374 info.agent.destroy(); 375 mActiveAgents.removeAt(i); 376 } 377 } 378 if (trustMayHaveChanged) { 379 updateTrustAll(); 380 } 381 } 382 383 public void resetAgent(ComponentName name, int userId) { 384 boolean trustMayHaveChanged = false; 385 for (int i = mActiveAgents.size() - 1; i >= 0; i--) { 386 AgentInfo info = mActiveAgents.valueAt(i); 387 if (name.equals(info.component) && userId == info.userId) { 388 Log.i(TAG, "Resetting agent " + info.component.flattenToShortString()); 389 if (info.agent.isManagingTrust()) { 390 trustMayHaveChanged = true; 391 } 392 info.agent.destroy(); 393 mActiveAgents.removeAt(i); 394 } 395 } 396 if (trustMayHaveChanged) { 397 updateTrust(userId, 0); 398 } 399 refreshAgentList(userId); 400 } 401 402 private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) { 403 if (resolveInfo == null || resolveInfo.serviceInfo == null 404 || resolveInfo.serviceInfo.metaData == null) return null; 405 String cn = null; 406 XmlResourceParser parser = null; 407 Exception caughtException = null; 408 try { 409 parser = resolveInfo.serviceInfo.loadXmlMetaData(pm, 410 TrustAgentService.TRUST_AGENT_META_DATA); 411 if (parser == null) { 412 Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data"); 413 return null; 414 } 415 Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo); 416 AttributeSet attrs = Xml.asAttributeSet(parser); 417 int type; 418 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 419 && type != XmlPullParser.START_TAG) { 420 // Drain preamble. 421 } 422 String nodeName = parser.getName(); 423 if (!"trust-agent".equals(nodeName)) { 424 Slog.w(TAG, "Meta-data does not start with trust-agent tag"); 425 return null; 426 } 427 TypedArray sa = res 428 .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent); 429 cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity); 430 sa.recycle(); 431 } catch (PackageManager.NameNotFoundException e) { 432 caughtException = e; 433 } catch (IOException e) { 434 caughtException = e; 435 } catch (XmlPullParserException e) { 436 caughtException = e; 437 } finally { 438 if (parser != null) parser.close(); 439 } 440 if (caughtException != null) { 441 Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException); 442 return null; 443 } 444 if (cn == null) { 445 return null; 446 } 447 if (cn.indexOf('/') < 0) { 448 cn = resolveInfo.serviceInfo.packageName + "/" + cn; 449 } 450 return ComponentName.unflattenFromString(cn); 451 } 452 453 private ComponentName getComponentName(ResolveInfo resolveInfo) { 454 if (resolveInfo == null || resolveInfo.serviceInfo == null) return null; 455 return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name); 456 } 457 458 private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) { 459 if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(), 460 Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) { 461 return; 462 } 463 PackageManager pm = mContext.getPackageManager(); 464 List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId); 465 ArraySet<ComponentName> discoveredAgents = new ArraySet<>(); 466 for (ResolveInfo resolveInfo : resolveInfos) { 467 ComponentName componentName = getComponentName(resolveInfo); 468 int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags; 469 if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 470 Log.i(TAG, "Leaving agent " + componentName + " disabled because package " 471 + "is not a system package."); 472 continue; 473 } 474 discoveredAgents.add(componentName); 475 } 476 477 List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId); 478 if (previouslyEnabledAgents != null) { 479 discoveredAgents.addAll(previouslyEnabledAgents); 480 } 481 utils.setEnabledTrustAgents(discoveredAgents, userId); 482 Settings.Secure.putIntForUser(mContext.getContentResolver(), 483 Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId); 484 } 485 486 private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) { 487 List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT, 488 0 /* flags */, userId); 489 ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size()); 490 for (ResolveInfo resolveInfo : resolveInfos) { 491 if (resolveInfo.serviceInfo == null) continue; 492 if (resolveInfo.serviceInfo.applicationInfo == null) continue; 493 String packageName = resolveInfo.serviceInfo.packageName; 494 if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName) 495 != PackageManager.PERMISSION_GRANTED) { 496 ComponentName name = getComponentName(resolveInfo); 497 Log.w(TAG, "Skipping agent " + name + " because package does not have" 498 + " permission " + PERMISSION_PROVIDE_AGENT + "."); 499 continue; 500 } 501 allowedAgents.add(resolveInfo); 502 } 503 return allowedAgents; 504 } 505 506 // Agent dispatch and aggregation 507 508 private boolean aggregateIsTrusted(int userId) { 509 if (!getUserHasAuthenticated(userId)) { 510 return false; 511 } 512 for (int i = 0; i < mActiveAgents.size(); i++) { 513 AgentInfo info = mActiveAgents.valueAt(i); 514 if (info.userId == userId) { 515 if (info.agent.isTrusted()) { 516 return true; 517 } 518 } 519 } 520 return false; 521 } 522 523 private boolean aggregateIsTrustManaged(int userId) { 524 if (!getUserHasAuthenticated(userId)) { 525 return false; 526 } 527 for (int i = 0; i < mActiveAgents.size(); i++) { 528 AgentInfo info = mActiveAgents.valueAt(i); 529 if (info.userId == userId) { 530 if (info.agent.isManagingTrust()) { 531 return true; 532 } 533 } 534 } 535 return false; 536 } 537 538 private void dispatchUnlockAttempt(boolean successful, int userId) { 539 for (int i = 0; i < mActiveAgents.size(); i++) { 540 AgentInfo info = mActiveAgents.valueAt(i); 541 if (info.userId == userId) { 542 info.agent.onUnlockAttempt(successful); 543 } 544 } 545 546 if (successful) { 547 updateUserHasAuthenticated(userId); 548 } 549 } 550 551 private void updateUserHasAuthenticated(int userId) { 552 boolean changed = setUserHasAuthenticated(userId); 553 if (changed) { 554 refreshAgentList(userId); 555 } 556 } 557 558 private boolean getUserHasAuthenticated(int userId) { 559 synchronized (mUserHasAuthenticatedSinceBoot) { 560 return mUserHasAuthenticatedSinceBoot.get(userId); 561 } 562 } 563 564 /** 565 * @return whether the value has changed 566 */ 567 private boolean setUserHasAuthenticated(int userId) { 568 synchronized (mUserHasAuthenticatedSinceBoot) { 569 if (!mUserHasAuthenticatedSinceBoot.get(userId)) { 570 mUserHasAuthenticatedSinceBoot.put(userId, true); 571 return true; 572 } 573 return false; 574 } 575 } 576 577 private void clearUserHasAuthenticated(int userId) { 578 synchronized (mUserHasAuthenticatedSinceBoot) { 579 if (userId == UserHandle.USER_ALL) { 580 mUserHasAuthenticatedSinceBoot.clear(); 581 } else { 582 mUserHasAuthenticatedSinceBoot.put(userId, false); 583 } 584 } 585 } 586 587 private void requireCredentialEntry(int userId) { 588 clearUserHasAuthenticated(userId); 589 refreshAgentList(userId); 590 } 591 592 // Listeners 593 594 private void addListener(ITrustListener listener) { 595 for (int i = 0; i < mTrustListeners.size(); i++) { 596 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) { 597 return; 598 } 599 } 600 mTrustListeners.add(listener); 601 updateTrustAll(); 602 } 603 604 private void removeListener(ITrustListener listener) { 605 for (int i = 0; i < mTrustListeners.size(); i++) { 606 if (mTrustListeners.get(i).asBinder() == listener.asBinder()) { 607 mTrustListeners.remove(i); 608 return; 609 } 610 } 611 } 612 613 private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) { 614 if (!enabled) flags = 0; 615 for (int i = 0; i < mTrustListeners.size(); i++) { 616 try { 617 mTrustListeners.get(i).onTrustChanged(enabled, userId, flags); 618 } catch (DeadObjectException e) { 619 Slog.d(TAG, "Removing dead TrustListener."); 620 mTrustListeners.remove(i); 621 i--; 622 } catch (RemoteException e) { 623 Slog.e(TAG, "Exception while notifying TrustListener.", e); 624 } 625 } 626 } 627 628 private void dispatchOnTrustManagedChanged(boolean managed, int userId) { 629 for (int i = 0; i < mTrustListeners.size(); i++) { 630 try { 631 mTrustListeners.get(i).onTrustManagedChanged(managed, userId); 632 } catch (DeadObjectException e) { 633 Slog.d(TAG, "Removing dead TrustListener."); 634 mTrustListeners.remove(i); 635 i--; 636 } catch (RemoteException e) { 637 Slog.e(TAG, "Exception while notifying TrustListener.", e); 638 } 639 } 640 } 641 642 // User lifecycle 643 644 @Override 645 public void onStartUser(int userId) { 646 mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget(); 647 } 648 649 @Override 650 public void onCleanupUser(int userId) { 651 mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget(); 652 } 653 654 @Override 655 public void onSwitchUser(int userId) { 656 mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget(); 657 } 658 659 // Plumbing 660 661 private final IBinder mService = new ITrustManager.Stub() { 662 @Override 663 public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException { 664 enforceReportPermission(); 665 mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId) 666 .sendToTarget(); 667 } 668 669 @Override 670 public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException { 671 enforceReportPermission(); 672 // coalesce refresh messages. 673 mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED); 674 mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED); 675 } 676 677 @Override 678 public void reportRequireCredentialEntry(int userId) throws RemoteException { 679 enforceReportPermission(); 680 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_OWNER) { 681 mHandler.obtainMessage(MSG_REQUIRE_CREDENTIAL_ENTRY, userId, 0).sendToTarget(); 682 } else { 683 throw new IllegalArgumentException( 684 "userId must be an explicit user id or USER_ALL"); 685 } 686 } 687 688 @Override 689 public void reportKeyguardShowingChanged() throws RemoteException { 690 enforceReportPermission(); 691 // coalesce refresh messages. 692 mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED); 693 mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED); 694 } 695 696 @Override 697 public void registerTrustListener(ITrustListener trustListener) throws RemoteException { 698 enforceListenerPermission(); 699 mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget(); 700 } 701 702 @Override 703 public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException { 704 enforceListenerPermission(); 705 mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget(); 706 } 707 708 @Override 709 public boolean isDeviceLocked(int userId) throws RemoteException { 710 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, 711 false /* allowAll */, true /* requireFull */, "isDeviceLocked", null); 712 userId = resolveProfileParent(userId); 713 714 return isDeviceLockedInner(userId); 715 } 716 717 @Override 718 public boolean isDeviceSecure(int userId) throws RemoteException { 719 userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, 720 false /* allowAll */, true /* requireFull */, "isDeviceSecure", null); 721 userId = resolveProfileParent(userId); 722 723 long token = Binder.clearCallingIdentity(); 724 try { 725 return new LockPatternUtils(mContext).isSecure(userId); 726 } finally { 727 Binder.restoreCallingIdentity(token); 728 } 729 } 730 731 @Override 732 public boolean hasUserAuthenticatedSinceBoot(int userId) throws RemoteException { 733 mContext.enforceCallingOrSelfPermission( 734 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, null); 735 long token = Binder.clearCallingIdentity(); 736 try { 737 return getUserHasAuthenticated(userId); 738 } finally { 739 Binder.restoreCallingIdentity(token); 740 } 741 } 742 743 private void enforceReportPermission() { 744 mContext.enforceCallingOrSelfPermission( 745 Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events"); 746 } 747 748 private void enforceListenerPermission() { 749 mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER, 750 "register trust listener"); 751 } 752 753 @Override 754 protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) { 755 mContext.enforceCallingPermission(Manifest.permission.DUMP, 756 "dumping TrustManagerService"); 757 if (isSafeMode()) { 758 fout.println("disabled because the system is in safe mode."); 759 return; 760 } 761 if (!mTrustAgentsCanRun) { 762 fout.println("disabled because the third-party apps can't run yet."); 763 return; 764 } 765 final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */); 766 mHandler.runWithScissors(new Runnable() { 767 @Override 768 public void run() { 769 fout.println("Trust manager state:"); 770 for (UserInfo user : userInfos) { 771 dumpUser(fout, user, user.id == mCurrentUser); 772 } 773 } 774 }, 1500); 775 } 776 777 private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) { 778 fout.printf(" User \"%s\" (id=%d, flags=%#x)", 779 user.name, user.id, user.flags); 780 if (!user.supportsSwitchTo()) { 781 fout.println("(managed profile)"); 782 fout.println(" disabled because switching to this user is not possible."); 783 return; 784 } 785 if (isCurrent) { 786 fout.print(" (current)"); 787 } 788 fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id))); 789 fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id))); 790 fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id))); 791 fout.println(); 792 fout.println(" Enabled agents:"); 793 boolean duplicateSimpleNames = false; 794 ArraySet<String> simpleNames = new ArraySet<String>(); 795 for (AgentInfo info : mActiveAgents) { 796 if (info.userId != user.id) { continue; } 797 boolean trusted = info.agent.isTrusted(); 798 fout.print(" "); fout.println(info.component.flattenToShortString()); 799 fout.print(" bound=" + dumpBool(info.agent.isBound())); 800 fout.print(", connected=" + dumpBool(info.agent.isConnected())); 801 fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust())); 802 fout.print(", trusted=" + dumpBool(trusted)); 803 fout.println(); 804 if (trusted) { 805 fout.println(" message=\"" + info.agent.getMessage() + "\""); 806 } 807 if (!info.agent.isConnected()) { 808 String restartTime = TrustArchive.formatDuration( 809 info.agent.getScheduledRestartUptimeMillis() 810 - SystemClock.uptimeMillis()); 811 fout.println(" restartScheduledAt=" + restartTime); 812 } 813 if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) { 814 duplicateSimpleNames = true; 815 } 816 } 817 fout.println(" Events:"); 818 mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames); 819 fout.println(); 820 } 821 822 private String dumpBool(boolean b) { 823 return b ? "1" : "0"; 824 } 825 }; 826 827 private int resolveProfileParent(int userId) { 828 long identity = Binder.clearCallingIdentity(); 829 try { 830 UserInfo parent = mUserManager.getProfileParent(userId); 831 if (parent != null) { 832 return parent.getUserHandle().getIdentifier(); 833 } 834 return userId; 835 } finally { 836 Binder.restoreCallingIdentity(identity); 837 } 838 } 839 840 private final Handler mHandler = new Handler() { 841 @Override 842 public void handleMessage(Message msg) { 843 switch (msg.what) { 844 case MSG_REGISTER_LISTENER: 845 addListener((ITrustListener) msg.obj); 846 break; 847 case MSG_UNREGISTER_LISTENER: 848 removeListener((ITrustListener) msg.obj); 849 break; 850 case MSG_DISPATCH_UNLOCK_ATTEMPT: 851 dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2); 852 break; 853 case MSG_ENABLED_AGENTS_CHANGED: 854 refreshAgentList(UserHandle.USER_ALL); 855 // This is also called when the security mode of a user changes. 856 refreshDeviceLockedForUser(UserHandle.USER_ALL); 857 break; 858 case MSG_REQUIRE_CREDENTIAL_ENTRY: 859 requireCredentialEntry(msg.arg1); 860 break; 861 case MSG_KEYGUARD_SHOWING_CHANGED: 862 refreshDeviceLockedForUser(mCurrentUser); 863 break; 864 case MSG_START_USER: 865 case MSG_CLEANUP_USER: 866 refreshAgentList(msg.arg1); 867 break; 868 case MSG_SWITCH_USER: 869 mCurrentUser = msg.arg1; 870 refreshDeviceLockedForUser(UserHandle.USER_ALL); 871 break; 872 } 873 } 874 }; 875 876 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 877 @Override 878 public void onSomePackagesChanged() { 879 refreshAgentList(UserHandle.USER_ALL); 880 } 881 882 @Override 883 public boolean onPackageChanged(String packageName, int uid, String[] components) { 884 // We're interested in all changes, even if just some components get enabled / disabled. 885 return true; 886 } 887 888 @Override 889 public void onPackageDisappeared(String packageName, int reason) { 890 removeAgentsOfPackage(packageName); 891 } 892 }; 893 894 private class Receiver extends BroadcastReceiver { 895 896 @Override 897 public void onReceive(Context context, Intent intent) { 898 String action = intent.getAction(); 899 if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) { 900 refreshAgentList(getSendingUserId()); 901 updateDevicePolicyFeatures(); 902 } else if (Intent.ACTION_USER_PRESENT.equals(action)) { 903 updateUserHasAuthenticated(getSendingUserId()); 904 } else if (Intent.ACTION_USER_ADDED.equals(action)) { 905 int userId = getUserId(intent); 906 if (userId > 0) { 907 maybeEnableFactoryTrustAgents(mLockPatternUtils, userId); 908 } 909 } else if (Intent.ACTION_USER_REMOVED.equals(action)) { 910 int userId = getUserId(intent); 911 if (userId > 0) { 912 mUserHasAuthenticatedSinceBoot.delete(userId); 913 synchronized (mUserIsTrusted) { 914 mUserIsTrusted.delete(userId); 915 } 916 synchronized (mDeviceLockedForUser) { 917 mDeviceLockedForUser.delete(userId); 918 } 919 refreshAgentList(userId); 920 refreshDeviceLockedForUser(userId); 921 } 922 } 923 } 924 925 private int getUserId(Intent intent) { 926 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100); 927 if (userId > 0) { 928 return userId; 929 } else { 930 Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId); 931 return -100; 932 } 933 } 934 935 public void register(Context context) { 936 IntentFilter filter = new IntentFilter(); 937 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 938 filter.addAction(Intent.ACTION_USER_PRESENT); 939 filter.addAction(Intent.ACTION_USER_ADDED); 940 filter.addAction(Intent.ACTION_USER_REMOVED); 941 context.registerReceiverAsUser(this, 942 UserHandle.ALL, 943 filter, 944 null /* permission */, 945 null /* scheduler */); 946 } 947 } 948} 949