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