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