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