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 android.service.trust; 18 19 import android.Manifest; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SdkConstant; 24 import android.annotation.SystemApi; 25 import android.app.Service; 26 import android.app.admin.DevicePolicyManager; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.pm.PackageManager; 31 import android.content.pm.ServiceInfo; 32 import android.os.Bundle; 33 import android.os.Handler; 34 import android.os.IBinder; 35 import android.os.Message; 36 import android.os.PersistableBundle; 37 import android.os.RemoteException; 38 import android.os.UserHandle; 39 import android.os.UserManager; 40 import android.util.Log; 41 import android.util.Slog; 42 43 import com.android.internal.infra.AndroidFuture; 44 45 import java.lang.annotation.Retention; 46 import java.lang.annotation.RetentionPolicy; 47 import java.util.List; 48 import java.util.function.Consumer; 49 50 /** 51 * A service that notifies the system about whether it believes the environment of the device 52 * to be trusted. 53 * 54 * <p>Trust agents may only be provided by the platform. It is expected that there is only 55 * one trust agent installed on the platform. In the event there is more than one, 56 * either trust agent can enable trust. 57 * </p> 58 * 59 * <p>To extend this class, you must declare the service in your manifest file with 60 * the {@link android.Manifest.permission#BIND_TRUST_AGENT} permission 61 * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p> 62 * <pre> 63 * <service android:name=".TrustAgent" 64 * android:label="@string/service_name" 65 * android:permission="android.permission.BIND_TRUST_AGENT"> 66 * <intent-filter> 67 * <action android:name="android.service.trust.TrustAgentService" /> 68 * </intent-filter> 69 * <meta-data android:name="android.service.trust.trustagent" 70 * android:value="@xml/trust_agent" /> 71 * </service></pre> 72 * 73 * <p>The associated meta-data file can specify an activity that is accessible through Settings 74 * and should allow configuring the trust agent, as defined in 75 * {@link android.R.styleable#TrustAgent}. For example:</p> 76 * 77 * <pre> 78 * <trust-agent xmlns:android="http://schemas.android.com/apk/res/android" 79 * android:settingsActivity=".TrustAgentSettings" /></pre> 80 * 81 * @hide 82 */ 83 @SystemApi 84 public class TrustAgentService extends Service { 85 86 private final String TAG = TrustAgentService.class.getSimpleName() + 87 "[" + getClass().getSimpleName() + "]"; 88 private static final boolean DEBUG = false; 89 90 /** 91 * The {@link Intent} that must be declared as handled by the service. 92 */ 93 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) 94 public static final String SERVICE_INTERFACE 95 = "android.service.trust.TrustAgentService"; 96 97 /** 98 * The name of the {@code meta-data} tag pointing to additional configuration of the trust 99 * agent. 100 */ 101 public static final String TRUST_AGENT_META_DATA = "android.service.trust.trustagent"; 102 103 104 /** 105 * Flag for {@link #grantTrust(CharSequence, long, int)} indicating that trust is being granted 106 * as the direct result of user action - such as solving a security challenge. The hint is used 107 * by the system to optimize the experience. Behavior may vary by device and release, so 108 * one should only set this parameter if it meets the above criteria rather than relying on 109 * the behavior of any particular device or release. 110 */ 111 public static final int FLAG_GRANT_TRUST_INITIATED_BY_USER = 1 << 0; 112 113 /** 114 * Flag for {@link #grantTrust(CharSequence, long, int)} indicating that the agent would like 115 * to dismiss the keyguard. When using this flag, the {@code TrustAgentService} must ensure 116 * it is only set in response to a direct user action with the expectation of dismissing the 117 * keyguard. 118 */ 119 public static final int FLAG_GRANT_TRUST_DISMISS_KEYGUARD = 1 << 1; 120 121 /** 122 * Flag for {@link #grantTrust(CharSequence, long, int)} indicating the platform should 123 * automatically remove trust after some conditions are met (detailed below) with the option for 124 * the agent to renew the trust again later. 125 * 126 * <p>After this is called, the agent will grant trust until the platform thinks an active 127 * user is no longer using that trust. This can happen for any reason as determined by the 128 * platform. For example, if the user dismisses keyguard, the platform will remove trust; 129 * since this does not automatically lock the device, this results in the device locking the 130 * next time the screen turns off. 131 * 132 * <p>When the platform internally removes the agent's trust in this manner, an agent can 133 * re-grant it (via a call to grantTrust) without the user having to unlock the device through 134 * another method (e.g. PIN). This renewable state only persists for a limited time. 135 */ 136 public static final int FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE = 1 << 2; 137 138 /** 139 * Flag for {@link #grantTrust(CharSequence, long, int)} indicating that the message should 140 * be displayed to the user. 141 * 142 * Without this flag, the message passed to {@code grantTrust} is only used for debugging 143 * purposes. With the flag, it may be displayed to the user as the reason why the device is 144 * unlocked. If this flag isn't set OR the message is set to null, the device will display 145 * its own default message for trust granted. If the TrustAgent intentionally doesn't want to 146 * show any message, then it can set this flag AND set the message to an empty string. 147 */ 148 public static final int FLAG_GRANT_TRUST_DISPLAY_MESSAGE = 1 << 3; 149 150 /** @hide */ 151 @Retention(RetentionPolicy.SOURCE) 152 @IntDef(flag = true, prefix = { "FLAG_GRANT_TRUST_" }, value = { 153 FLAG_GRANT_TRUST_INITIATED_BY_USER, 154 FLAG_GRANT_TRUST_DISMISS_KEYGUARD, 155 FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE, 156 FLAG_GRANT_TRUST_DISPLAY_MESSAGE, 157 }) 158 public @interface GrantTrustFlags {} 159 160 /** 161 * Int enum indicating that escrow token is active. 162 * See {@link #onEscrowTokenStateReceived(long, int)} 163 * 164 */ 165 public static final int TOKEN_STATE_ACTIVE = 1; 166 167 /** 168 * Int enum indicating that escow token is inactive. 169 * See {@link #onEscrowTokenStateReceived(long, int)} 170 * 171 */ 172 public static final int TOKEN_STATE_INACTIVE = 0; 173 174 /** @hide */ 175 @Retention(RetentionPolicy.SOURCE) 176 @IntDef(flag = true, prefix = { "TOKEN_STATE_" }, value = { 177 TOKEN_STATE_ACTIVE, 178 TOKEN_STATE_INACTIVE, 179 }) 180 public @interface TokenState {} 181 182 private static final int MSG_UNLOCK_ATTEMPT = 1; 183 private static final int MSG_CONFIGURE = 2; 184 private static final int MSG_TRUST_TIMEOUT = 3; 185 private static final int MSG_DEVICE_LOCKED = 4; 186 private static final int MSG_DEVICE_UNLOCKED = 5; 187 private static final int MSG_UNLOCK_LOCKOUT = 6; 188 private static final int MSG_ESCROW_TOKEN_ADDED = 7; 189 private static final int MSG_ESCROW_TOKEN_STATE_RECEIVED = 8; 190 private static final int MSG_ESCROW_TOKEN_REMOVED = 9; 191 private static final int MSG_USER_REQUESTED_UNLOCK = 10; 192 private static final int MSG_USER_MAY_REQUEST_UNLOCK = 11; 193 194 private static final String EXTRA_TOKEN = "token"; 195 private static final String EXTRA_TOKEN_HANDLE = "token_handle"; 196 private static final String EXTRA_USER_HANDLE = "user_handle"; 197 private static final String EXTRA_TOKEN_STATE = "token_state"; 198 private static final String EXTRA_TOKEN_REMOVED_RESULT = "token_removed_result"; 199 /** 200 * Class containing raw data for a given configuration request. 201 */ 202 private static final class ConfigurationData { 203 final IBinder token; 204 final List<PersistableBundle> options; ConfigurationData(List<PersistableBundle> opts, IBinder t)205 ConfigurationData(List<PersistableBundle> opts, IBinder t) { 206 options = opts; 207 token = t; 208 } 209 } 210 211 private ITrustAgentServiceCallback mCallback; 212 213 private Runnable mPendingGrantTrustTask; 214 215 private boolean mManagingTrust; 216 217 // Lock used to access mPendingGrantTrustTask and mCallback. 218 private final Object mLock = new Object(); 219 220 private Handler mHandler = new Handler() { 221 public void handleMessage(android.os.Message msg) { 222 switch (msg.what) { 223 case MSG_UNLOCK_ATTEMPT: 224 onUnlockAttempt(msg.arg1 != 0); 225 break; 226 case MSG_USER_REQUESTED_UNLOCK: 227 onUserRequestedUnlock(msg.arg1 != 0); 228 break; 229 case MSG_USER_MAY_REQUEST_UNLOCK: 230 onUserMayRequestUnlock(); 231 break; 232 case MSG_UNLOCK_LOCKOUT: 233 onDeviceUnlockLockout(msg.arg1); 234 break; 235 case MSG_CONFIGURE: { 236 ConfigurationData data = (ConfigurationData) msg.obj; 237 boolean result = onConfigure(data.options); 238 if (data.token != null) { 239 try { 240 synchronized (mLock) { 241 mCallback.onConfigureCompleted(result, data.token); 242 } 243 } catch (RemoteException e) { 244 onError("calling onSetTrustAgentFeaturesEnabledCompleted()"); 245 } 246 } 247 break; 248 } 249 case MSG_TRUST_TIMEOUT: 250 onTrustTimeout(); 251 break; 252 case MSG_DEVICE_LOCKED: 253 onDeviceLocked(); 254 break; 255 case MSG_DEVICE_UNLOCKED: 256 onDeviceUnlocked(); 257 break; 258 case MSG_ESCROW_TOKEN_ADDED: { 259 Bundle data = msg.getData(); 260 byte[] token = data.getByteArray(EXTRA_TOKEN); 261 long handle = data.getLong(EXTRA_TOKEN_HANDLE); 262 UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE, android.os.UserHandle.class); 263 onEscrowTokenAdded(token, handle, user); 264 break; 265 } 266 case MSG_ESCROW_TOKEN_STATE_RECEIVED: { 267 Bundle data = msg.getData(); 268 long handle = data.getLong(EXTRA_TOKEN_HANDLE); 269 int tokenState = data.getInt(EXTRA_TOKEN_STATE, TOKEN_STATE_INACTIVE); 270 onEscrowTokenStateReceived(handle, tokenState); 271 break; 272 } 273 case MSG_ESCROW_TOKEN_REMOVED: { 274 Bundle data = msg.getData(); 275 long handle = data.getLong(EXTRA_TOKEN_HANDLE); 276 boolean success = data.getBoolean(EXTRA_TOKEN_REMOVED_RESULT); 277 onEscrowTokenRemoved(handle, success); 278 break; 279 } 280 } 281 } 282 }; 283 284 @Override onCreate()285 public void onCreate() { 286 super.onCreate(); 287 ComponentName component = new ComponentName(this, getClass()); 288 try { 289 ServiceInfo serviceInfo = getPackageManager().getServiceInfo(component, 0 /* flags */); 290 if (!Manifest.permission.BIND_TRUST_AGENT.equals(serviceInfo.permission)) { 291 throw new IllegalStateException(component.flattenToShortString() 292 + " is not declared with the permission " 293 + "\"" + Manifest.permission.BIND_TRUST_AGENT + "\""); 294 } 295 } catch (PackageManager.NameNotFoundException e) { 296 Log.e(TAG, "Can't get ServiceInfo for " + component.toShortString()); 297 } 298 } 299 300 /** 301 * Called after the user attempts to authenticate in keyguard with their device credentials, 302 * such as pin, pattern or password. 303 * 304 * @param successful true if the user successfully completed the challenge. 305 */ onUnlockAttempt(boolean successful)306 public void onUnlockAttempt(boolean successful) { 307 } 308 309 /** 310 * Called when the user has interacted with the locked device such that they are likely to want 311 * it to be unlocked soon. This approximates the timing when, for example, the platform would 312 * check for face authentication to unlock the device. 313 * 314 * This signal can be used for the agent to make preparations to quickly unlock the device 315 * with {@link #onUserRequestedUnlock}. Agents should not unlock the device based solely on this 316 * signal. There is no guarantee that this method will be called before 317 * {@link #onUserRequestedUnlock(boolean)}. 318 */ onUserMayRequestUnlock()319 public void onUserMayRequestUnlock() { 320 } 321 322 /** 323 * Called when the user has interacted with the locked device such that they likely want it 324 * to be unlocked. 325 * 326 * When this is called, there is a high probability that the user wants to unlock the device and 327 * that a biometric method is either not available or not the optimal method at this time. For 328 * example, this may be called after some kinds of biometric authentication failure. 329 * 330 * A call to this method may be preceded by a call to {@link #onUserMayRequestUnlock} which 331 * the agent can use as a signal to prepare for a subsequent call to this method. 332 * 333 * To attempt to unlock the device, the agent needs to call 334 * {@link #grantTrust(CharSequence, long, int)}. 335 * 336 * @param dismissKeyguard true when the user wants keyguard dismissed 337 * 338 * @see #FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE 339 */ onUserRequestedUnlock(boolean dismissKeyguard)340 public void onUserRequestedUnlock(boolean dismissKeyguard) { 341 } 342 343 /** 344 * Called when the timeout provided by the agent expires. Note that this may be called earlier 345 * than requested by the agent if the trust timeout is adjusted by the system or 346 * {@link DevicePolicyManager}. The agent is expected to re-evaluate the trust state and only 347 * call {@link #grantTrust(CharSequence, long, boolean)} if the trust state should be 348 * continued. 349 */ onTrustTimeout()350 public void onTrustTimeout() { 351 } 352 353 /** 354 * Called when the device enters a state where a PIN, pattern or 355 * password must be entered to unlock it. 356 */ onDeviceLocked()357 public void onDeviceLocked() { 358 } 359 360 /** 361 * Called when the device leaves a state where a PIN, pattern or 362 * password must be entered to unlock it. 363 */ onDeviceUnlocked()364 public void onDeviceUnlocked() { 365 } 366 367 /** 368 * Called when the device enters a temporary unlock lockout. 369 * 370 * <p>This occurs when the user has consecutively failed to unlock the device too many times, 371 * and must wait until a timeout has passed to perform another attempt. The user may then only 372 * use strong authentication mechanisms (PIN, pattern or password) to unlock the device. 373 * Calls to {@link #grantTrust(CharSequence, long, int)} will be ignored until the user has 374 * unlocked the device and {@link #onDeviceUnlocked()} is called. 375 * 376 * @param timeoutMs The amount of time, in milliseconds, that needs to elapse before the user 377 * can attempt to unlock the device again. 378 */ onDeviceUnlockLockout(long timeoutMs)379 public void onDeviceUnlockLockout(long timeoutMs) { 380 } 381 382 /** 383 * Called when an escrow token is added for user userId. 384 * 385 * @param token the added token 386 * @param handle the handle to the corresponding internal synthetic password. A user is unlocked 387 * by presenting both handle and escrow token. 388 * @param user the user to which the escrow token is added. 389 * 390 */ onEscrowTokenAdded(byte[] token, long handle, UserHandle user)391 public void onEscrowTokenAdded(byte[] token, long handle, UserHandle user) { 392 } 393 394 /** 395 * Called when an escrow token state is received upon request. 396 * 397 * @param handle the handle to the internal synthetic password. 398 * @param state the state of the requested escrow token, see {@link TokenState}. 399 * 400 */ onEscrowTokenStateReceived(long handle, @TokenState int tokenState)401 public void onEscrowTokenStateReceived(long handle, @TokenState int tokenState) { 402 } 403 404 /** 405 * Called when an escrow token is removed. 406 * 407 * @param handle the handle to the removed the synthetic password. 408 * @param successful whether the removing operaiton is achieved. 409 * 410 */ onEscrowTokenRemoved(long handle, boolean successful)411 public void onEscrowTokenRemoved(long handle, boolean successful) { 412 } 413 onError(String msg)414 private void onError(String msg) { 415 Slog.v(TAG, "Remote exception while " + msg); 416 } 417 418 /** 419 * Called when device policy admin wants to enable specific options for agent in response to 420 * {@link DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)} and 421 * {@link DevicePolicyManager#setTrustAgentConfiguration(ComponentName, ComponentName, 422 * PersistableBundle)}. 423 * <p>Agents that support configuration options should overload this method and return 'true'. 424 * 425 * @param options The aggregated list of options or an empty list if no restrictions apply. 426 * @return true if it supports configuration options. 427 */ onConfigure(List<PersistableBundle> options)428 public boolean onConfigure(List<PersistableBundle> options) { 429 return false; 430 } 431 432 /** 433 * Attempts to grant trust on the device. 434 * 435 * @param initiatedByUser see {@link #FLAG_GRANT_TRUST_INITIATED_BY_USER} 436 * @deprecated use {@link #grantTrust(CharSequence, long, int, Consumer)} instead. 437 */ 438 @Deprecated grantTrust( final CharSequence message, final long durationMs, final boolean initiatedByUser)439 public final void grantTrust( 440 final CharSequence message, final long durationMs, final boolean initiatedByUser) { 441 grantTrust(message, durationMs, initiatedByUser ? FLAG_GRANT_TRUST_INITIATED_BY_USER : 0); 442 } 443 444 /** 445 * Attempts to grant trust on the device. 446 * @deprecated use {@link #grantTrust(CharSequence, long, int, Consumer)} instead. 447 */ 448 @Deprecated grantTrust( final CharSequence message, final long durationMs, @GrantTrustFlags final int flags)449 public final void grantTrust( 450 final CharSequence message, final long durationMs, @GrantTrustFlags final int flags) { 451 grantTrust(message, durationMs, flags, null); 452 } 453 454 /** 455 * Attempts to grant trust on the device. 456 * 457 * @param message describes why the device is trusted, e.g. "Trusted by location". 458 * @param durationMs amount of time in milliseconds to keep the device in a trusted state. 459 * Trust for this agent will automatically be revoked when the timeout expires unless 460 * extended by a subsequent call to this function. The timeout is measured from the 461 * invocation of this function as dictated by {@link SystemClock#elapsedRealtime())}. 462 * For security reasons, the value should be no larger than necessary. 463 * The value may be adjusted by the system as necessary to comply with a policy controlled 464 * by the system or {@link DevicePolicyManager} restrictions. See {@link #onTrustTimeout()} 465 * for determining when trust expires. 466 * @param flags flags to control call: see constants prefixed by {@code FLAG_GRANT_TRUST_}. 467 * @param resultCallback may be called with the results of the grant 468 * @throws IllegalStateException if the agent is not currently managing trust. 469 * 470 * See {@link GrantTrustResult} for the cases where {@code resultCallback} will be called. 471 */ grantTrust( @onNull final CharSequence message, final long durationMs, @GrantTrustFlags final int flags, @Nullable final Consumer<GrantTrustResult> resultCallback)472 public final void grantTrust( 473 @NonNull final CharSequence message, 474 final long durationMs, 475 @GrantTrustFlags final int flags, 476 @Nullable final Consumer<GrantTrustResult> resultCallback) { 477 synchronized (mLock) { 478 if (!mManagingTrust) { 479 throw new IllegalStateException("Cannot grant trust if agent is not managing trust." 480 + " Call setManagingTrust(true) first."); 481 } 482 483 // Prepare future for the IPC 484 AndroidFuture<GrantTrustResult> future = new AndroidFuture<>(); 485 future.thenAccept(result -> { 486 if (resultCallback != null) { 487 // Instead of taking an explicit executor, we post this to mHandler to be 488 // consistent with the other event methods in this class. 489 mHandler.post(() -> resultCallback.accept(result)); 490 } 491 }); 492 493 if (mCallback != null) { 494 try { 495 mCallback.grantTrust(message.toString(), durationMs, flags, future); 496 } catch (RemoteException e) { 497 onError("calling enableTrust()"); 498 } 499 } else { 500 // Remember trust has been granted so we can effectively grant it once the service 501 // is bound. 502 mPendingGrantTrustTask = new Runnable() { 503 @Override 504 public void run() { 505 grantTrust(message, durationMs, flags, resultCallback); 506 } 507 }; 508 } 509 } 510 } 511 512 /** 513 * Call to revoke trust on the device. 514 */ revokeTrust()515 public final void revokeTrust() { 516 synchronized (mLock) { 517 if (mPendingGrantTrustTask != null) { 518 mPendingGrantTrustTask = null; 519 } 520 if (mCallback != null) { 521 try { 522 mCallback.revokeTrust(); 523 } catch (RemoteException e) { 524 onError("calling revokeTrust()"); 525 } 526 } 527 } 528 } 529 530 /** 531 * Call to notify the system if the agent is ready to manage trust. 532 * 533 * This property is not persistent across recreating the service and defaults to false. 534 * Therefore this method is typically called when initializing the agent in {@link #onCreate}. 535 * 536 * @param managingTrust indicates if the agent would like to manage trust. 537 */ setManagingTrust(boolean managingTrust)538 public final void setManagingTrust(boolean managingTrust) { 539 synchronized (mLock) { 540 if (mManagingTrust != managingTrust) { 541 mManagingTrust = managingTrust; 542 if (mCallback != null) { 543 try { 544 mCallback.setManagingTrust(managingTrust); 545 } catch (RemoteException e) { 546 onError("calling setManagingTrust()"); 547 } 548 } 549 } 550 } 551 } 552 553 /** 554 * Call to add an escrow token to derive a synthetic password. A synthetic password is an 555 * alternaive to the user-set password/pin/pattern in order to unlock encrypted disk. An escrow 556 * token can be taken and internally derive the synthetic password. The new added token will not 557 * be acivated until the user input the correct PIN/Passcode/Password once. 558 * 559 * Result will be return by callback {@link #onEscrowTokenAdded(long, int)} 560 * 561 * @param token an escrow token of high entropy. 562 * @param user the user which the escrow token will be added to. 563 * 564 */ addEscrowToken(byte[] token, UserHandle user)565 public final void addEscrowToken(byte[] token, UserHandle user) { 566 synchronized (mLock) { 567 if (mCallback == null) { 568 Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework"); 569 throw new IllegalStateException("Trust agent is not connected"); 570 } 571 try { 572 mCallback.addEscrowToken(token, user.getIdentifier()); 573 } catch (RemoteException e) { 574 onError("calling addEscrowToken"); 575 } 576 } 577 } 578 579 /** 580 * Call to check the active state of an escrow token. 581 * 582 * Result will be return in callback {@link #onEscrowTokenStateReceived(long, boolean)} 583 * 584 * @param handle the handle of escrow token to the internal synthetic password. 585 * @param user the user which the escrow token is added to. 586 * 587 */ isEscrowTokenActive(long handle, UserHandle user)588 public final void isEscrowTokenActive(long handle, UserHandle user) { 589 synchronized (mLock) { 590 if (mCallback == null) { 591 Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework"); 592 throw new IllegalStateException("Trust agent is not connected"); 593 } 594 try { 595 mCallback.isEscrowTokenActive(handle, user.getIdentifier()); 596 } catch (RemoteException e) { 597 onError("calling isEscrowTokenActive"); 598 } 599 } 600 } 601 602 /** 603 * Call to remove the escrow token. 604 * 605 * Result will be return in callback {@link #onEscrowTokenRemoved(long, boolean)} 606 * 607 * @param handle the handle of escrow tokent to the internal synthetic password. 608 * @param user the user id which the escrow token is added to. 609 * 610 */ removeEscrowToken(long handle, UserHandle user)611 public final void removeEscrowToken(long handle, UserHandle user) { 612 synchronized (mLock) { 613 if (mCallback == null) { 614 Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework"); 615 throw new IllegalStateException("Trust agent is not connected"); 616 } 617 try { 618 mCallback.removeEscrowToken(handle, user.getIdentifier()); 619 } catch (RemoteException e) { 620 onError("callling removeEscrowToken"); 621 } 622 } 623 } 624 625 /** 626 * Call to unlock user's FBE. 627 * 628 * @param handle the handle of escrow tokent to the internal synthetic password. 629 * @param token the escrow token 630 * @param user the user about to be unlocked. 631 * 632 */ unlockUserWithToken(long handle, byte[] token, UserHandle user)633 public final void unlockUserWithToken(long handle, byte[] token, UserHandle user) { 634 UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); 635 if (um.isUserUnlocked(user)) { 636 Slog.i(TAG, "User already unlocked"); 637 return; 638 } 639 640 synchronized (mLock) { 641 if (mCallback == null) { 642 Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework"); 643 throw new IllegalStateException("Trust agent is not connected"); 644 } 645 try { 646 mCallback.unlockUserWithToken(handle, token, user.getIdentifier()); 647 } catch (RemoteException e) { 648 onError("calling unlockUserWithToken"); 649 } 650 } 651 } 652 653 /** 654 * Locks the user. 655 * 656 * This revokes any trust granted by this agent and shows keyguard for the user if it is not 657 * currently shown for them. Other users are not affected. Note that this is in contrast to 658 * {@link #revokeTrust()} which does not show keyguard if it is not already shown. 659 * 660 * If the user has no auth method specified, then keyguard will still be shown but can be 661 * dismissed normally. 662 */ lockUser()663 public final void lockUser() { 664 if (mCallback != null) { 665 try { 666 mCallback.lockUser(); 667 } catch (RemoteException e) { 668 onError("calling lockUser"); 669 } 670 } 671 } 672 673 /** 674 * Request showing a transient error message on the keyguard. 675 * The message will be visible on the lock screen or always on display if possible but can be 676 * overridden by other keyguard events of higher priority - eg. fingerprint auth error. 677 * Other trust agents may override your message if posted simultaneously. 678 * 679 * @param message Message to show. 680 */ showKeyguardErrorMessage(@onNull CharSequence message)681 public final void showKeyguardErrorMessage(@NonNull CharSequence message) { 682 if (message == null) { 683 throw new IllegalArgumentException("message cannot be null"); 684 } 685 synchronized (mLock) { 686 if (mCallback == null) { 687 Slog.w(TAG, "Cannot show message because service is not connected to framework."); 688 throw new IllegalStateException("Trust agent is not connected"); 689 } 690 try { 691 mCallback.showKeyguardErrorMessage(message); 692 } catch (RemoteException e) { 693 onError("calling showKeyguardErrorMessage"); 694 } 695 } 696 } 697 698 @Override onBind(Intent intent)699 public final IBinder onBind(Intent intent) { 700 if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent); 701 return new TrustAgentServiceWrapper(); 702 } 703 704 private final class TrustAgentServiceWrapper extends ITrustAgentService.Stub { 705 @Override /* Binder API */ onUnlockAttempt(boolean successful)706 public void onUnlockAttempt(boolean successful) { 707 mHandler.obtainMessage(MSG_UNLOCK_ATTEMPT, successful ? 1 : 0, 0).sendToTarget(); 708 } 709 710 @Override onUserRequestedUnlock(boolean dismissKeyguard)711 public void onUserRequestedUnlock(boolean dismissKeyguard) { 712 mHandler.obtainMessage(MSG_USER_REQUESTED_UNLOCK, dismissKeyguard ? 1 : 0, 0) 713 .sendToTarget(); 714 } 715 716 @Override onUserMayRequestUnlock()717 public void onUserMayRequestUnlock() { 718 mHandler.obtainMessage(MSG_USER_MAY_REQUEST_UNLOCK).sendToTarget(); 719 } 720 721 @Override onUnlockLockout(int timeoutMs)722 public void onUnlockLockout(int timeoutMs) { 723 mHandler.obtainMessage(MSG_UNLOCK_LOCKOUT, timeoutMs, 0).sendToTarget(); 724 } 725 726 @Override /* Binder API */ onTrustTimeout()727 public void onTrustTimeout() { 728 mHandler.sendEmptyMessage(MSG_TRUST_TIMEOUT); 729 } 730 731 @Override /* Binder API */ onConfigure(List<PersistableBundle> args, IBinder token)732 public void onConfigure(List<PersistableBundle> args, IBinder token) { 733 mHandler.obtainMessage(MSG_CONFIGURE, new ConfigurationData(args, token)) 734 .sendToTarget(); 735 } 736 737 @Override onDeviceLocked()738 public void onDeviceLocked() throws RemoteException { 739 mHandler.obtainMessage(MSG_DEVICE_LOCKED).sendToTarget(); 740 } 741 742 @Override onDeviceUnlocked()743 public void onDeviceUnlocked() throws RemoteException { 744 mHandler.obtainMessage(MSG_DEVICE_UNLOCKED).sendToTarget(); 745 } 746 747 @Override /* Binder API */ setCallback(ITrustAgentServiceCallback callback)748 public void setCallback(ITrustAgentServiceCallback callback) { 749 synchronized (mLock) { 750 mCallback = callback; 751 // The managingTrust property is false implicitly on the server-side, so we only 752 // need to set it here if the agent has decided to manage trust. 753 if (mManagingTrust) { 754 try { 755 mCallback.setManagingTrust(mManagingTrust); 756 } catch (RemoteException e ) { 757 onError("calling setManagingTrust()"); 758 } 759 } 760 if (mPendingGrantTrustTask != null) { 761 mPendingGrantTrustTask.run(); 762 mPendingGrantTrustTask = null; 763 } 764 } 765 } 766 767 @Override onEscrowTokenAdded(byte[] token, long handle, UserHandle user)768 public void onEscrowTokenAdded(byte[] token, long handle, UserHandle user) { 769 Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_ADDED); 770 msg.getData().putByteArray(EXTRA_TOKEN, token); 771 msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle); 772 msg.getData().putParcelable(EXTRA_USER_HANDLE, user); 773 msg.sendToTarget(); 774 } 775 onTokenStateReceived(long handle, int tokenState)776 public void onTokenStateReceived(long handle, int tokenState) { 777 Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_STATE_RECEIVED); 778 msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle); 779 msg.getData().putInt(EXTRA_TOKEN_STATE, tokenState); 780 msg.sendToTarget(); 781 } 782 onEscrowTokenRemoved(long handle, boolean successful)783 public void onEscrowTokenRemoved(long handle, boolean successful) { 784 Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_REMOVED); 785 msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle); 786 msg.getData().putBoolean(EXTRA_TOKEN_REMOVED_RESULT, successful); 787 msg.sendToTarget(); 788 } 789 } 790 } 791