Add escrow token APIs to TrustAgentService
Security review: b/31273740
Design doc: go/auto_login
Test: manual
Change-Id: Ib11d4146135a58f1dc451ae8e081977a8f8e6ace
diff --git a/api/system-current.txt b/api/system-current.txt
index fc78b4b..feea86e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -39845,20 +39845,29 @@
public class TrustAgentService extends android.app.Service {
ctor public TrustAgentService();
+ method public final void addEscrowToken(byte[], android.os.UserHandle);
method public final deprecated void grantTrust(java.lang.CharSequence, long, boolean);
method public final void grantTrust(java.lang.CharSequence, long, int);
+ method public final void isEscrowTokenActive(long, android.os.UserHandle);
method public final android.os.IBinder onBind(android.content.Intent);
method public boolean onConfigure(java.util.List<android.os.PersistableBundle>);
method public void onDeviceLocked();
method public void onDeviceUnlockLockout(long);
method public void onDeviceUnlocked();
+ method public void onEscrowTokenAdded(byte[], long, android.os.UserHandle);
+ method public void onEscrowTokenRemoved(long, boolean);
+ method public void onEscrowTokenStateReceived(long, int);
method public void onTrustTimeout();
method public void onUnlockAttempt(boolean);
+ method public final void removeEscrowToken(long, android.os.UserHandle);
method public final void revokeTrust();
method public final void setManagingTrust(boolean);
+ method public final void unlockUserWithToken(long, byte[], android.os.UserHandle);
field public static final int FLAG_GRANT_TRUST_DISMISS_KEYGUARD = 2; // 0x2
field public static final int FLAG_GRANT_TRUST_INITIATED_BY_USER = 1; // 0x1
field public static final java.lang.String SERVICE_INTERFACE = "android.service.trust.TrustAgentService";
+ field public static final int TOKEN_STATE_ACTIVE = 1; // 0x1
+ field public static final int TOKEN_STATE_INACTIVE = 0; // 0x0
field public static final java.lang.String TRUST_AGENT_META_DATA = "android.service.trust.trustagent";
}
diff --git a/core/java/android/service/trust/ITrustAgentService.aidl b/core/java/android/service/trust/ITrustAgentService.aidl
index 22b4d09..21661db 100644
--- a/core/java/android/service/trust/ITrustAgentService.aidl
+++ b/core/java/android/service/trust/ITrustAgentService.aidl
@@ -16,6 +16,7 @@
package android.service.trust;
import android.os.PersistableBundle;
+import android.os.UserHandle;
import android.service.trust.ITrustAgentServiceCallback;
/**
@@ -30,4 +31,7 @@
oneway void onDeviceUnlocked();
oneway void onConfigure(in List<PersistableBundle> options, IBinder token);
oneway void setCallback(ITrustAgentServiceCallback callback);
+ oneway void onEscrowTokenAdded(in byte[] token, long handle, in UserHandle user);
+ oneway void onTokenStateReceived(long handle, int tokenState);
+ oneway void onEscrowTokenRemoved(long handle, boolean successful);
}
diff --git a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
index ec66cc8..14df7cb 100644
--- a/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
+++ b/core/java/android/service/trust/ITrustAgentServiceCallback.aidl
@@ -28,4 +28,8 @@
void revokeTrust();
void setManagingTrust(boolean managingTrust);
void onConfigureCompleted(boolean result, IBinder token);
+ void addEscrowToken(in byte[] token, int userId);
+ void isEscrowTokenActive(long handle, int userId);
+ void removeEscrowToken(long handle, int userId);
+ void unlockUserWithToken(long handle, in byte[] token, int userId);
}
diff --git a/core/java/android/service/trust/TrustAgentService.java b/core/java/android/service/trust/TrustAgentService.java
index 0d5177d..2b37a23 100644
--- a/core/java/android/service/trust/TrustAgentService.java
+++ b/core/java/android/service/trust/TrustAgentService.java
@@ -23,16 +23,20 @@
import android.app.Service;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import android.util.Slog;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
@@ -118,13 +122,44 @@
public @interface GrantTrustFlags {}
+ /**
+ * Int enum indicating that escrow token is active.
+ * See {@link #onEscrowTokenStateReceived(long, int)}
+ *
+ */
+ public static final int TOKEN_STATE_ACTIVE = 1;
+
+ /**
+ * Int enum indicating that escow token is inactive.
+ * See {@link #onEscrowTokenStateReceived(long, int)}
+ *
+ */
+ public static final int TOKEN_STATE_INACTIVE = 0;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {
+ TOKEN_STATE_ACTIVE,
+ TOKEN_STATE_INACTIVE,
+ })
+ public @interface TokenState {}
+
private static final int MSG_UNLOCK_ATTEMPT = 1;
private static final int MSG_CONFIGURE = 2;
private static final int MSG_TRUST_TIMEOUT = 3;
private static final int MSG_DEVICE_LOCKED = 4;
private static final int MSG_DEVICE_UNLOCKED = 5;
private static final int MSG_UNLOCK_LOCKOUT = 6;
+ private static final int MSG_ESCROW_TOKEN_ADDED = 7;
+ private static final int MSG_ESCROW_TOKEN_STATE_RECEIVED = 8;
+ private static final int MSG_ESCROW_TOKEN_REMOVED = 9;
+ private static final String EXTRA_TOKEN = "token";
+ private static final String EXTRA_TOKEN_HANDLE = "token_handle";
+ private static final String EXTRA_USER_HANDLE = "user_handle";
+ private static final String EXTRA_TOKEN_STATE = "token_state";
+ private static final String EXTRA_TOKEN_REMOVED_RESULT = "token_removed_result";
/**
* Class containing raw data for a given configuration request.
*/
@@ -155,7 +190,7 @@
case MSG_UNLOCK_LOCKOUT:
onDeviceUnlockLockout(msg.arg1);
break;
- case MSG_CONFIGURE:
+ case MSG_CONFIGURE: {
ConfigurationData data = (ConfigurationData) msg.obj;
boolean result = onConfigure(data.options);
if (data.token != null) {
@@ -168,6 +203,7 @@
}
}
break;
+ }
case MSG_TRUST_TIMEOUT:
onTrustTimeout();
break;
@@ -177,6 +213,28 @@
case MSG_DEVICE_UNLOCKED:
onDeviceUnlocked();
break;
+ case MSG_ESCROW_TOKEN_ADDED: {
+ Bundle data = msg.getData();
+ byte[] token = data.getByteArray(EXTRA_TOKEN);
+ long handle = data.getLong(EXTRA_TOKEN_HANDLE);
+ UserHandle user = (UserHandle) data.getParcelable(EXTRA_USER_HANDLE);
+ onEscrowTokenAdded(token, handle, user);
+ break;
+ }
+ case MSG_ESCROW_TOKEN_STATE_RECEIVED: {
+ Bundle data = msg.getData();
+ long handle = data.getLong(EXTRA_TOKEN_HANDLE);
+ int tokenState = data.getInt(EXTRA_TOKEN_STATE, TOKEN_STATE_INACTIVE);
+ onEscrowTokenStateReceived(handle, tokenState);
+ break;
+ }
+ case MSG_ESCROW_TOKEN_REMOVED: {
+ Bundle data = msg.getData();
+ long handle = data.getLong(EXTRA_TOKEN_HANDLE);
+ boolean success = data.getBoolean(EXTRA_TOKEN_REMOVED_RESULT);
+ onEscrowTokenRemoved(handle, success);
+ break;
+ }
}
}
};
@@ -245,6 +303,38 @@
public void onDeviceUnlockLockout(long timeoutMs) {
}
+ /**
+ * Called when an escrow token is added for user userId.
+ *
+ * @param token the added token
+ * @param handle the handle to the corresponding internal synthetic password. A user is unlocked
+ * by presenting both handle and escrow token.
+ * @param user the user to which the escrow token is added.
+ *
+ */
+ public void onEscrowTokenAdded(byte[] token, long handle, UserHandle user) {
+ }
+
+ /**
+ * Called when an escrow token state is received upon request.
+ *
+ * @param handle the handle to the internal synthetic password.
+ * @param state the state of the requested escrow token, see {@link TokenState}.
+ *
+ */
+ public void onEscrowTokenStateReceived(long handle, @TokenState int tokenState) {
+ }
+
+ /**
+ * Called when an escrow token is removed.
+ *
+ * @param handle the handle to the removed the synthetic password.
+ * @param successful whether the removing operaiton is achieved.
+ *
+ */
+ public void onEscrowTokenRemoved(long handle, boolean successful) {
+ }
+
private void onError(String msg) {
Slog.v(TAG, "Remote exception while " + msg);
}
@@ -257,7 +347,7 @@
* <p>Agents that support configuration options should overload this method and return 'true'.
*
* @param options The aggregated list of options or an empty list if no restrictions apply.
- * @return true if the {@link TrustAgentService} supports configuration options.
+ * @return true if the {@link } supports configuration options.
*/
public boolean onConfigure(List<PersistableBundle> options) {
return false;
@@ -373,6 +463,106 @@
}
}
+ /**
+ * Call to add an escrow token to derive a synthetic password. A synthetic password is an
+ * alternaive to the user-set password/pin/pattern in order to unlock encrypted disk. An escrow
+ * token can be taken and internally derive the synthetic password. The new added token will not
+ * be acivated until the user input the correct PIN/Passcode/Password once.
+ *
+ * Result will be return by callback {@link #onEscrowTokenAdded(long, int)}
+ *
+ * @param token an escrow token of high entropy.
+ * @param user the user which the escrow token will be added to.
+ *
+ */
+ public final void addEscrowToken(byte[] token, UserHandle user) {
+ synchronized (mLock) {
+ if (mCallback == null) {
+ Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework");
+ throw new IllegalStateException("Trust agent is not connected");
+ }
+ try {
+ mCallback.addEscrowToken(token, user.getIdentifier());
+ } catch (RemoteException e) {
+ onError("calling addEscrowToken");
+ }
+ }
+ }
+
+ /**
+ * Call to check the active state of an escrow token.
+ *
+ * Result will be return in callback {@link #onEscrowTokenStateReceived(long, boolean)}
+ *
+ * @param handle the handle of escrow token to the internal synthetic password.
+ * @param user the user which the escrow token is added to.
+ *
+ */
+ public final void isEscrowTokenActive(long handle, UserHandle user) {
+ synchronized (mLock) {
+ if (mCallback == null) {
+ Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework");
+ throw new IllegalStateException("Trust agent is not connected");
+ }
+ try {
+ mCallback.isEscrowTokenActive(handle, user.getIdentifier());
+ } catch (RemoteException e) {
+ onError("calling isEscrowTokenActive");
+ }
+ }
+ }
+
+ /**
+ * Call to remove the escrow token.
+ *
+ * Result will be return in callback {@link #onEscrowTokenRemoved(long, boolean)}
+ *
+ * @param handle the handle of escrow tokent to the internal synthetic password.
+ * @param user the user id which the escrow token is added to.
+ *
+ */
+ public final void removeEscrowToken(long handle, UserHandle user) {
+ synchronized (mLock) {
+ if (mCallback == null) {
+ Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework");
+ throw new IllegalStateException("Trust agent is not connected");
+ }
+ try {
+ mCallback.removeEscrowToken(handle, user.getIdentifier());
+ } catch (RemoteException e) {
+ onError("callling removeEscrowToken");
+ }
+ }
+ }
+
+ /**
+ * Call to unlock user's FBE.
+ *
+ * @param handle the handle of escrow tokent to the internal synthetic password.
+ * @param token the escrow token
+ * @param user the user about to be unlocked.
+ *
+ */
+ public final void unlockUserWithToken(long handle, byte[] token, UserHandle user) {
+ UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+ if (um.isUserUnlocked()) {
+ Slog.i(TAG, "User already unlocked");
+ return;
+ }
+
+ synchronized (mLock) {
+ if (mCallback == null) {
+ Slog.w(TAG, "Cannot add escrow token if the agent is not connecting to framework");
+ throw new IllegalStateException("Trust agent is not connected");
+ }
+ try {
+ mCallback.unlockUserWithToken(handle, token, user.getIdentifier());
+ } catch (RemoteException e) {
+ onError("calling unlockUserWithToken");
+ }
+ }
+ }
+
@Override
public final IBinder onBind(Intent intent) {
if (DEBUG) Slog.v(TAG, "onBind() intent = " + intent);
@@ -430,6 +620,28 @@
}
}
}
- }
+ @Override
+ public void onEscrowTokenAdded(byte[] token, long handle, UserHandle user) {
+ Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_ADDED);
+ msg.getData().putByteArray(EXTRA_TOKEN, token);
+ msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle);
+ msg.getData().putParcelable(EXTRA_USER_HANDLE, user);
+ msg.sendToTarget();
+ }
+
+ public void onTokenStateReceived(long handle, int tokenState) {
+ Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_STATE_RECEIVED);
+ msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle);
+ msg.getData().putInt(EXTRA_TOKEN_STATE, tokenState);
+ msg.sendToTarget();
+ }
+
+ public void onEscrowTokenRemoved(long handle, boolean successful) {
+ Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_REMOVED);
+ msg.getData().putLong(EXTRA_TOKEN_HANDLE, handle);
+ msg.getData().putBoolean(EXTRA_TOKEN_REMOVED_RESULT, successful);
+ msg.sendToTarget();
+ }
+ }
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fcb0e08..9c2d8c0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2751,4 +2751,13 @@
without explicit consent of the user. If no accessibility service with the specified name
exists on the device, the accessibility shortcut will be disabled by default. -->
<string name="config_defaultAccessibilityService" translatable="false"></string>
+
+ <!-- Flag indicates that whether escrow token API is enabled for TrustAgent -->
+ <!-- Warning: This API can be dangerous when not implemented properly. In particular,
+ escrow token must NOT be retrievable from device storage. In other words, either
+ escrow token is not stored on device or its ciphertext is stored on device while
+ the decryption key is not. Before enabling this feature, please ensure you've read
+ and followed the pertinent sections of the escrow tokens section of the CDD <link>-->
+ <!-- TODO(b/35230407) complete the link field -->
+ <bool name="config_allowEscrowTokenForTrustAgent">false</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0d63a1e..0ad9ea0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2848,6 +2848,9 @@
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
<java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
+ <!-- android.service.trust -->
+ <java-symbol type="bool" name="config_allowEscrowTokenForTrustAgent"/>
+
<!-- Time picker -->
<java-symbol type="id" name="toggle_mode"/>
<java-symbol type="id" name="input_mode"/>
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 6c1648c..996a3d2 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -16,6 +16,7 @@
package com.android.server.trust;
+import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
@@ -27,6 +28,7 @@
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -35,11 +37,11 @@
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.util.Log;
-import android.util.Slog;
import android.service.trust.ITrustAgentService;
import android.service.trust.ITrustAgentServiceCallback;
-
+import android.service.trust.TrustAgentService;
+import android.util.Log;
+import android.util.Slog;
import java.util.Collections;
import java.util.List;
@@ -47,6 +49,7 @@
* A wrapper around a TrustAgentService interface. Coordinates communication between
* TrustManager and the actual TrustAgent.
*/
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class TrustAgentWrapper {
private static final String EXTRA_COMPONENT_NAME = "componentName";
private static final String TRUST_EXPIRED_ACTION = "android.server.trust.TRUST_EXPIRED_ACTION";
@@ -60,6 +63,10 @@
private static final int MSG_RESTART_TIMEOUT = 4;
private static final int MSG_SET_TRUST_AGENT_FEATURES_COMPLETED = 5;
private static final int MSG_MANAGING_TRUST = 6;
+ private static final int MSG_ADD_ESCROW_TOKEN = 7;
+ private static final int MSG_REMOVE_ESCROW_TOKEN = 8;
+ private static final int MSG_ESCROW_TOKEN_STATE = 9;
+ private static final int MSG_UNLOCK_USER = 10;
/**
* Time in uptime millis that we wait for the service connection, both when starting
@@ -71,6 +78,9 @@
* Long extra for {@link #MSG_GRANT_TRUST}
*/
private static final String DATA_DURATION = "duration";
+ private static final String DATA_ESCROW_TOKEN = "escrow_token";
+ private static final String DATA_HANDLE = "handle";
+ private static final String DATA_USER_ID = "user_id";
private final TrustManagerService mTrustManagerService;
private final int mUserId;
@@ -190,6 +200,49 @@
mTrustManagerService.mArchive.logManagingTrust(mUserId, mName, mManagingTrust);
mTrustManagerService.updateTrust(mUserId, 0);
break;
+ case MSG_ADD_ESCROW_TOKEN: {
+ byte[] eToken = msg.getData().getByteArray(DATA_ESCROW_TOKEN);
+ int userId = msg.getData().getInt(DATA_USER_ID);
+ long handle = mTrustManagerService.addEscrowToken(eToken, userId);
+ try {
+ mTrustAgentService.onEscrowTokenAdded(
+ eToken, handle, UserHandle.of(userId));
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ break;
+ }
+ case MSG_ESCROW_TOKEN_STATE: {
+ long handle = msg.getData().getLong(DATA_HANDLE);
+ int userId = msg.getData().getInt(DATA_USER_ID);
+ boolean active = mTrustManagerService.isEscrowTokenActive(handle, userId);
+ try {
+ mTrustAgentService.onTokenStateReceived(handle,
+ active ? TrustAgentService.TOKEN_STATE_ACTIVE
+ : TrustAgentService.TOKEN_STATE_INACTIVE);
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ break;
+ }
+ case MSG_REMOVE_ESCROW_TOKEN: {
+ long handle = msg.getData().getLong(DATA_HANDLE);
+ int userId = msg.getData().getInt(DATA_USER_ID);
+ boolean success = mTrustManagerService.removeEscrowToken(handle, userId);
+ try {
+ mTrustAgentService.onEscrowTokenRemoved(handle, success);
+ } catch (RemoteException e) {
+ onError(e);
+ }
+ break;
+ }
+ case MSG_UNLOCK_USER: {
+ long handle = msg.getData().getLong(DATA_HANDLE);
+ int userId = msg.getData().getInt(DATA_USER_ID);
+ byte[] eToken = msg.getData().getByteArray(DATA_ESCROW_TOKEN);
+ mTrustManagerService.unlockUserWithToken(handle, eToken, userId);
+ break;
+ }
}
}
};
@@ -225,6 +278,67 @@
mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
result ? 1 : 0, 0, token).sendToTarget();
}
+
+ @Override
+ public void addEscrowToken(byte[] token, int userId) {
+ if (mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
+ Slog.e(TAG, "Escrow token API is not allowed.");
+ return;
+ }
+
+ if (DEBUG) Slog.d(TAG, "adding escrow token for user " + userId);
+ Message msg = mHandler.obtainMessage(MSG_ADD_ESCROW_TOKEN);
+ msg.getData().putByteArray(DATA_ESCROW_TOKEN, token);
+ msg.getData().putInt(DATA_USER_ID, userId);
+ msg.sendToTarget();
+ }
+
+ @Override
+ public void isEscrowTokenActive(long handle, int userId) {
+ if (mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
+ Slog.e(TAG, "Escrow token API is not allowed.");
+ return;
+ }
+
+ if (DEBUG) Slog.d(TAG, "checking the state of escrow token on user " + userId);
+ Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_STATE);
+ msg.getData().putLong(DATA_HANDLE, handle);
+ msg.getData().putInt(DATA_USER_ID, userId);
+ msg.sendToTarget();
+ }
+
+ @Override
+ public void removeEscrowToken(long handle, int userId) {
+ if (mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
+ Slog.e(TAG, "Escrow token API is not allowed.");
+ return;
+ }
+
+ if (DEBUG) Slog.d(TAG, "removing escrow token on user " + userId);
+ Message msg = mHandler.obtainMessage(MSG_REMOVE_ESCROW_TOKEN);
+ msg.getData().putLong(DATA_HANDLE, handle);
+ msg.getData().putInt(DATA_USER_ID, userId);
+ msg.sendToTarget();
+ }
+
+ @Override
+ public void unlockUserWithToken(long handle, byte[] token, int userId) {
+ if (mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
+ Slog.e(TAG, "Escrow token API is not allowed.");
+ return;
+ }
+
+ if (DEBUG) Slog.d(TAG, "unlocking user " + userId);
+ Message msg = mHandler.obtainMessage(MSG_UNLOCK_USER);
+ msg.getData().putInt(DATA_USER_ID, userId);
+ msg.getData().putLong(DATA_HANDLE, handle);
+ msg.getData().putByteArray(DATA_ESCROW_TOKEN, token);
+ msg.sendToTarget();
+ }
};
private final ServiceConnection mConnection = new ServiceConnection() {
@@ -294,7 +408,7 @@
}
private void onError(Exception e) {
- Slog.w(TAG , "Remote Exception", e);
+ Slog.w(TAG , "Exception ", e);
}
private void onTrustTimeout() {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 71b725e..4570b0d 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -16,14 +16,6 @@
package com.android.server.trust;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.server.SystemService;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.Manifest;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
@@ -65,12 +57,17 @@
import android.util.Xml;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
-
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
/**
* Manages trust agents and trust listeners.
@@ -229,6 +226,22 @@
TRUST_USUALLY_MANAGED_FLUSH_DELAY);
}
+ public long addEscrowToken(byte[] token, int userId) {
+ return mLockPatternUtils.addEscrowToken(token, userId);
+ }
+
+ public boolean removeEscrowToken(long handle, int userId) {
+ return mLockPatternUtils.removeEscrowToken(handle, userId);
+ }
+
+ public boolean isEscrowTokenActive(long handle, int userId) {
+ return mLockPatternUtils.isEscrowTokenActive(handle, userId);
+ }
+
+ public void unlockUserWithToken(long handle, byte[] token, int userId) {
+ mLockPatternUtils.unlockUserWithToken(handle, token, userId);
+ }
+
void refreshAgentList(int userIdOrAll) {
if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
if (!mTrustAgentsCanRun) {
@@ -329,7 +342,7 @@
if (!StorageManager.isUserKeyUnlocked(userInfo.id)
&& !directUnlock) {
if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + "'s trust agent " + name + ": FDE still locked and "
+ + "'s trust agent " + name + ": FBE still locked and "
+ " the agent cannot unlock user profile.");
continue;
}