aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHongwei Wang <hwwang@google.com>2018-06-05 16:42:06 -0700
committerHongwei Wang <hwwang@google.com>2018-06-21 14:36:19 -0700
commit25fa6f2e47fc034cc6bef7be6d0fae6889194f1d (patch)
tree537e7b22f40dc18377baa765765d6221b53ca338
parent12eecfd9600c0f48b3652733f60c29e70ad6650b (diff)
downloadCar-25fa6f2e47fc034cc6bef7be6d0fae6889194f1d.tar.gz
Associate user id with unlock token handle
Note: this assumes user-0 is always unlocked otherwise one would not be able to access shared preference for user-0 when cold booted to lock screen. To test this CL, turn on the following system property android.car.systemuser.headless=true This build flag will make Android boot into a headless user-0 model and user-0 will always be unlocked. Bluetooth stack gets restarted every time switching user. This CL also ensures the BLE trust agent service is started after bluetooth finishes rebooting. Current limitations: - Unlock token works only if user sets password - Unlock token is not activated till user finishes lock-unlock once Bug: 78602296 Bug: 77854782 Test: unlock user by trust device on Mojave Change-Id: Ifc2bf97593adbb77d518d6b11c06ea5234a4ebbd
-rw-r--r--TrustAgent/res/values/strings.xml2
-rw-r--r--TrustAgent/src/com/android/car/trust/CarBleTrustAgent.java191
-rw-r--r--TrustAgent/src/com/android/car/trust/CarEnrolmentActivity.java68
-rw-r--r--TrustAgent/src/com/android/car/trust/CarTrustAgentBleService.java22
-rw-r--r--car-lib/src/android/car/trust/ICarTrustAgentBleService.aidl3
5 files changed, 180 insertions, 106 deletions
diff --git a/TrustAgent/res/values/strings.xml b/TrustAgent/res/values/strings.xml
index d077262102..192b7e4b99 100644
--- a/TrustAgent/res/values/strings.xml
+++ b/TrustAgent/res/values/strings.xml
@@ -36,4 +36,6 @@
<string name="start_advertising">Start Advertising</string>
<string name="revoke_trust">Revoke Trust</string>
+ <string translatable="false" name="token_handle_shared_preferences">com.android.car.trust.TOKEN_HANDLE</string>
+
</resources>
diff --git a/TrustAgent/src/com/android/car/trust/CarBleTrustAgent.java b/TrustAgent/src/com/android/car/trust/CarBleTrustAgent.java
index 227ea8919e..1dfbd504a1 100644
--- a/TrustAgent/src/com/android/car/trust/CarBleTrustAgent.java
+++ b/TrustAgent/src/com/android/car/trust/CarBleTrustAgent.java
@@ -16,27 +16,25 @@
package com.android.car.trust;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothGattServer;
-import android.bluetooth.BluetoothGattServerCallback;
-import android.bluetooth.BluetoothManager;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.UserSwitchObserver;
+import android.bluetooth.BluetoothAdapter;
import android.car.trust.ICarTrustAgentBleService;
import android.car.trust.ICarTrustAgentTokenRequestDelegate;
import android.car.trust.ICarTrustAgentUnlockCallback;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
-import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.os.UserManager;
import android.service.trust.TrustAgentService;
import android.util.Log;
-import java.util.concurrent.TimeUnit;
-
/**
* A BluetoothLE (BLE) based {@link TrustAgentService} that uses the escrow token unlock APIs. </p>
*
@@ -49,39 +47,44 @@ public class CarBleTrustAgent extends TrustAgentService {
private static final String TAG = CarBleTrustAgent.class.getSimpleName();
- private static final long TRUST_DURATION_MS = TimeUnit.MINUTES.toMicros(5);
- private static final long BLE_RETRY_MS = TimeUnit.SECONDS.toMillis(1);
-
- private Handler mHandler;
- private BluetoothManager mBluetoothManager;
- private ICarTrustAgentBleService mCarTrustAgentBleService;
- private boolean mCarTrustAgentBleServiceBound;
-
+ /**
+ * {@link CarTrustAgentBleService} will callback this function when it receives both
+ * handle and token.
+ */
private final ICarTrustAgentUnlockCallback mUnlockCallback =
new ICarTrustAgentUnlockCallback.Stub() {
@Override
- public void onUnlockDataReceived(byte[] token, long handle) {
- UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
- // TODO(b/77854782): get the actual user to unlock by token
- UserHandle userHandle = getForegroundUserHandle();
-
- Log.d(TAG, "About to unlock user. Handle: " + handle
- + " Time: " + System.currentTimeMillis());
- unlockUserWithToken(handle, token, userHandle);
-
- Log.d(TAG, "Attempted to unlock user, is user unlocked: "
- + um.isUserUnlocked(userHandle)
- + " Time: " + System.currentTimeMillis());
- setManagingTrust(true);
+ public void onUnlockDataReceived(byte[] token, long handle) throws RemoteException {
+ UserHandle userHandle = getUserHandleByTokenHandle(handle);
+ if (userHandle == null) {
+ Log.e(TAG, "Unable to find user by token handle " + handle);
+ return;
+ }
- if (um.isUserUnlocked(userHandle)) {
- Log.d(TAG, getString(R.string.trust_granted_explanation));
- grantTrust("Granting trust from escrow token",
- TRUST_DURATION_MS, FLAG_GRANT_TRUST_DISMISS_KEYGUARD);
+ int uid = userHandle.getIdentifier();
+ if (ActivityManager.getCurrentUser() != uid) {
+ Log.d(TAG, "Switch to user: " + uid);
+ // Try to unlock when user switch completes
+ ActivityManager.getService().registerUserSwitchObserver(
+ getUserSwitchObserver(uid, token, handle), TAG);
+ ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
+ am.switchUser(uid);
+ } else {
+ unlockUserInternally(uid, token, handle);
}
}
};
+ /**
+ * Delegates the escrow token API calls from {@link CarTrustAgentBleService} to
+ * {@link TrustAgentService}. Due to the asynchronous nature, the results will be posted to
+ * {@link CarTrustAgentBleService} by the following calls
+ * <ul>
+ * <li>{@link #onEscrowTokenAdded(byte[], long, UserHandle)}</li>
+ * <li>{@link #onEscrowTokenRemoved(long, boolean)}</li>
+ * <li>{@link #onEscrowTokenStateReceived(long, int)}</li>
+ * </ul>
+ */
private final ICarTrustAgentTokenRequestDelegate mTokenRequestDelegate =
new ICarTrustAgentTokenRequestDelegate.Stub() {
@Override
@@ -105,6 +108,9 @@ public class CarBleTrustAgent extends TrustAgentService {
}
};
+ /**
+ * Service connection to {@link CarTrustAgentBleService}
+ */
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
@@ -114,7 +120,6 @@ public class CarBleTrustAgent extends TrustAgentService {
try {
mCarTrustAgentBleService.registerUnlockCallback(mUnlockCallback);
mCarTrustAgentBleService.setTokenRequestDelegate(mTokenRequestDelegate);
- maybeStartBleUnlockService();
} catch (RemoteException e) {
Log.e(TAG, "Error registerUnlockCallback", e);
}
@@ -122,10 +127,12 @@ public class CarBleTrustAgent extends TrustAgentService {
@Override
public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "CarTrustAgentBleService disconnected");
if (mCarTrustAgentBleService != null) {
try {
mCarTrustAgentBleService.unregisterUnlockCallback(mUnlockCallback);
mCarTrustAgentBleService.setTokenRequestDelegate(null);
+ mCarTrustAgentBleService.stopUnlockAdvertising();
} catch (RemoteException e) {
Log.e(TAG, "Error unregisterUnlockCallback", e);
}
@@ -135,45 +142,57 @@ public class CarBleTrustAgent extends TrustAgentService {
}
};
+ /**
+ * Receives the bluetooth state change broadcasts. Bluetooth is restarted when switching user,
+ * we need to ensure calling {@link ICarTrustAgentBleService#startUnlockAdvertising} after
+ * bluetooth is started.
+ */
+ private final BroadcastReceiver mBluetoothBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case BluetoothAdapter.ACTION_STATE_CHANGED:
+ onBluetoothStateChanged(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1));
+ break;
+ }
+ }
+ };
+
+ private ICarTrustAgentBleService mCarTrustAgentBleService;
+ private boolean mCarTrustAgentBleServiceBound;
+
+ /**
+ * TODO: Currently it relies on {@link #onDeviceLocked()} and {@link #onDeviceUnlocked()}
+ * callback, and these callbacks won't happen if the user has unlocked once.
+ */
+ private boolean mIsOnLockScreen;
+
@Override
public void onCreate() {
super.onCreate();
-
- Log.d(TAG, "Bluetooth trust agent starting up");
- mHandler = new Handler();
- mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
-
- // If the user is already unlocked, don't bother starting the BLE service.
- UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
- if (!um.isUserUnlocked(getForegroundUserHandle())) {
- Log.d(TAG, "User locked, will now bind CarTrustAgentBleService");
- Intent intent = new Intent(this, CarTrustAgentBleService.class);
- bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
- } else {
- setManagingTrust(true);
- }
+ setManagingTrust(true);
+ bindService(new Intent(this, CarTrustAgentBleService.class),
+ mServiceConnection, Context.BIND_AUTO_CREATE);
+ IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+ registerReceiver(mBluetoothBroadcastReceiver, intentFilter);
}
@Override
public void onDestroy() {
Log.d(TAG, "Car Trust agent shutting down");
- mHandler.removeCallbacks(null);
-
- // Unbind the service to avoid leaks from BLE stack.
if (mCarTrustAgentBleServiceBound) {
unbindService(mServiceConnection);
}
+ unregisterReceiver(mBluetoothBroadcastReceiver);
super.onDestroy();
}
@Override
public void onDeviceLocked() {
super.onDeviceLocked();
+ mIsOnLockScreen = true;
if (mCarTrustAgentBleServiceBound) {
try {
- // Only one BLE advertising is allowed, ensure enrolment advertising is stopped
- // before start unlock advertising.
- mCarTrustAgentBleService.stopEnrolmentAdvertising();
mCarTrustAgentBleService.startUnlockAdvertising();
} catch (RemoteException e) {
Log.e(TAG, "Error startUnlockAdvertising", e);
@@ -184,36 +203,47 @@ public class CarBleTrustAgent extends TrustAgentService {
@Override
public void onDeviceUnlocked() {
super.onDeviceUnlocked();
+ mIsOnLockScreen = false;
if (mCarTrustAgentBleServiceBound) {
try {
- // Only one BLE advertising is allowed, ensure unlock advertising is stopped.
mCarTrustAgentBleService.stopUnlockAdvertising();
} catch (RemoteException e) {
Log.e(TAG, "Error stopUnlockAdvertising", e);
}
}
+ // Revoke trust right after to enable keyguard when switching user
+ revokeTrust();
}
- private void maybeStartBleUnlockService() {
- Log.d(TAG, "Trying to open a Ble GATT server");
- BluetoothGattServer gattServer = mBluetoothManager.openGattServer(
- this, new BluetoothGattServerCallback() {
+ private UserSwitchObserver getUserSwitchObserver(int uid,
+ byte[] token, long handle) {
+ return new UserSwitchObserver() {
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ if (uid != newUserId) return;
+ unlockUserInternally(uid, token, handle);
+ ActivityManager.getService().unregisterUserSwitchObserver(this);
+ }
+
@Override
- public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
- super.onConnectionStateChange(device, status, newState);
+ public void onLockedBootComplete(int newUserId) {
+ // ignored.
}
- });
+ };
+ }
+
+ private void unlockUserInternally(int uid, byte[] token, long handle) {
+ Log.d(TAG, "About to unlock user: " + uid);
+ unlockUserWithToken(handle, token, UserHandle.of(uid));
+ grantTrust("Granting trust from escrow token",
+ 0, FLAG_GRANT_TRUST_DISMISS_KEYGUARD);
+ }
- // The BLE stack is started up before the trust agent service, however Gatt capabilities
- // might not be ready just yet. Keep trying until a GattServer can open up before proceeding
- // to start the rest of the BLE services.
- if (gattServer == null) {
- Log.e(TAG, "Gatt not available, will try again...in " + BLE_RETRY_MS + "ms");
- mHandler.postDelayed(this::maybeStartBleUnlockService, BLE_RETRY_MS);
- } else {
- mHandler.removeCallbacks(null);
- gattServer.close();
- Log.d(TAG, "GATT available, starting up UnlockService");
+ private void onBluetoothStateChanged(int state) {
+ Log.d(TAG, "onBluetoothStateChanged: " + state);
+ if ((state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_BLE_ON)
+ && mCarTrustAgentBleServiceBound
+ && mIsOnLockScreen) {
try {
mCarTrustAgentBleService.startUnlockAdvertising();
} catch (RemoteException e) {
@@ -259,12 +289,15 @@ public class CarBleTrustAgent extends TrustAgentService {
}
}
- /**
- * TODO(b/77854782): return the {@link UserHandle} of foreground user.
- * CarBleTrustAgent itself runs as user-0
- */
- private UserHandle getForegroundUserHandle() {
- Log.d(TAG, "getForegroundUserHandle for " + UserHandle.myUserId());
- return UserHandle.of(UserHandle.myUserId());
+ private @Nullable UserHandle getUserHandleByTokenHandle(long tokenHandle) {
+ if (mCarTrustAgentBleServiceBound) {
+ try {
+ int userId = mCarTrustAgentBleService.getUserIdByEscrowTokenHandle(tokenHandle);
+ return userId < 0 ? null : UserHandle.of(userId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error getUserHandleByTokenHandle");
+ }
+ }
+ return null;
}
}
diff --git a/TrustAgent/src/com/android/car/trust/CarEnrolmentActivity.java b/TrustAgent/src/com/android/car/trust/CarEnrolmentActivity.java
index d7160e3435..4b587d1419 100644
--- a/TrustAgent/src/com/android/car/trust/CarEnrolmentActivity.java
+++ b/TrustAgent/src/com/android/car/trust/CarEnrolmentActivity.java
@@ -46,13 +46,16 @@ public class CarEnrolmentActivity extends Activity {
private static final String SP_HANDLE_KEY = "sp-test";
private static final int FINE_LOCATION_REQUEST_CODE = 42;
+ /**
+ * Receives escrow token callbacks, registered on {@link CarTrustAgentBleService}
+ */
private final ICarTrustAgentTokenResponseCallback mCarTrustAgentTokenResponseCallback =
new ICarTrustAgentTokenResponseCallback.Stub() {
@Override
public void onEscrowTokenAdded(byte[] token, long handle, int uid) {
runOnUiThread(() -> {
mPrefs.edit().putLong(SP_HANDLE_KEY, handle).apply();
- Log.d(TAG, "stored new handle");
+ Log.d(TAG, "stored new handle for user: " + uid);
});
if (mBluetoothDevice == null) {
@@ -81,6 +84,9 @@ public class CarEnrolmentActivity extends Activity {
}
};
+ /**
+ * Receives BLE state change callbacks, registered on {@link CarTrustAgentBleService}
+ */
private final ICarTrustAgentBleCallback mBleConnectionCallback =
new ICarTrustAgentBleCallback.Stub() {
@Override
@@ -108,6 +114,12 @@ public class CarEnrolmentActivity extends Activity {
}
};
+ /**
+ * {@link CarTrustAgentBleService} will callback this when receives enrolment data.
+ *
+ * Here is the place we can prompt to the user on HU whether or not to add this
+ * {@link #mBluetoothDevice} as a trust device.
+ */
private final ICarTrustAgentEnrolmentCallback mEnrolmentCallback =
new ICarTrustAgentEnrolmentCallback.Stub() {
@Override
@@ -121,6 +133,9 @@ public class CarEnrolmentActivity extends Activity {
}
};
+ /**
+ * Service connection to {@link CarTrustAgentBleService}
+ */
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
@@ -135,6 +150,7 @@ public class CarEnrolmentActivity extends Activity {
} catch (RemoteException e) {
Log.e(TAG, "Error startEnrolmentAdvertising", e);
}
+ checkTokenHandle();
}
@Override
@@ -169,8 +185,10 @@ public class CarEnrolmentActivity extends Activity {
mPrefs = PreferenceManager.getDefaultSharedPreferences(this /* context */);
findViewById(R.id.start_button).setOnClickListener((view) -> {
- Intent bindIntent = new Intent(this, CarTrustAgentBleService.class);
- bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ if (!mCarTrustAgentBleServiceBound) {
+ Intent bindIntent = new Intent(this, CarTrustAgentBleService.class);
+ bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ }
});
findViewById(R.id.revoke_trust_button).setOnClickListener((view) -> {
@@ -193,33 +211,17 @@ public class CarEnrolmentActivity extends Activity {
requestPermissions(
new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION },
FINE_LOCATION_REQUEST_CODE);
- } else {
- long tokenHandle = getTokenHandle();
- if (tokenHandle != -1) {
- Log.d(TAG, "onResume, checking handle active: " + tokenHandle);
- if (mCarTrustAgentBleServiceBound) {
- try {
- // Due to the asynchronous nature of isEscrowTokenActive in
- // TrustAgentService, query result will be delivered via
- // {@link #mCarTrustAgentTokenResponseCallback}
- mCarTrustAgentBleService.isEscrowTokenActive(tokenHandle,
- UserHandle.myUserId());
- } catch (RemoteException e) {
- Log.e(TAG, "Error isEscrowTokenActive", e);
- }
- }
- } else {
- appendOutputText("No handles found");
- }
}
}
@Override
- protected void onDestroy() {
+ protected void onStop() {
+ super.onStop();
+
if (mCarTrustAgentBleServiceBound) {
unbindService(mServiceConnection);
+ mCarTrustAgentBleServiceBound = false;
}
- super.onDestroy();
}
private void appendOutputText(final String text) {
@@ -234,7 +236,23 @@ public class CarEnrolmentActivity extends Activity {
mCarTrustAgentBleService.addEscrowToken(token, UserHandle.myUserId());
}
- private long getTokenHandle() {
- return mPrefs.getLong(SP_HANDLE_KEY, -1);
+ private void checkTokenHandle() {
+ long tokenHandle = mPrefs.getLong(SP_HANDLE_KEY, -1);
+ if (tokenHandle != -1) {
+ Log.d(TAG, "Checking handle active: " + tokenHandle);
+ if (mCarTrustAgentBleServiceBound) {
+ try {
+ // Due to the asynchronous nature of isEscrowTokenActive in
+ // TrustAgentService, query result will be delivered via
+ // {@link #mCarTrustAgentTokenResponseCallback}
+ mCarTrustAgentBleService.isEscrowTokenActive(tokenHandle,
+ UserHandle.myUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error isEscrowTokenActive", e);
+ }
+ }
+ } else {
+ appendOutputText("No handles found");
+ }
}
}
diff --git a/TrustAgent/src/com/android/car/trust/CarTrustAgentBleService.java b/TrustAgent/src/com/android/car/trust/CarTrustAgentBleService.java
index f8ba90f36a..2cc2080089 100644
--- a/TrustAgent/src/com/android/car/trust/CarTrustAgentBleService.java
+++ b/TrustAgent/src/com/android/car/trust/CarTrustAgentBleService.java
@@ -25,6 +25,7 @@ import android.car.trust.ICarTrustAgentTokenRequestDelegate;
import android.car.trust.ICarTrustAgentTokenResponseCallback;
import android.car.trust.ICarTrustAgentUnlockCallback;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteCallbackList;
@@ -62,6 +63,8 @@ public class CarTrustAgentBleService extends SimpleBleServer {
private byte[] mCurrentUnlockToken;
private Long mCurrentUnlockHandle;
+ private SharedPreferences mTokenHandleSharedPreferences;
+
@Override
public void onCreate() {
super.onCreate();
@@ -72,6 +75,10 @@ public class CarTrustAgentBleService extends SimpleBleServer {
setupEnrolmentBleServer();
setupUnlockBleServer();
+
+ mTokenHandleSharedPreferences = getSharedPreferences(
+ getString(R.string.token_handle_shared_preferences),
+ MODE_PRIVATE);
}
@Override
@@ -260,8 +267,8 @@ public class CarTrustAgentBleService extends SimpleBleServer {
@Override
public void startEnrolmentAdvertising() {
- Log.d(TAG, "startEnrolmentAdvertising");
stopUnlockAdvertising();
+ Log.d(TAG, "startEnrolmentAdvertising");
startAdvertising(mEnrolmentUuid, mEnrolmentGattServer);
}
@@ -290,8 +297,8 @@ public class CarTrustAgentBleService extends SimpleBleServer {
@Override
public void startUnlockAdvertising() {
- Log.d(TAG, "startUnlockAdvertising");
stopEnrolmentAdvertising();
+ Log.d(TAG, "startUnlockAdvertising");
startAdvertising(mUnlockUuid, mUnlockGattServer);
}
@@ -353,6 +360,9 @@ public class CarTrustAgentBleService extends SimpleBleServer {
public void onEscrowTokenAdded(byte[] token, long handle, int uid)
throws RemoteException {
Log.d(TAG, "onEscrowTokenAdded handle:" + handle + " uid:" + uid);
+ mTokenHandleSharedPreferences.edit()
+ .putInt(String.valueOf(handle), uid)
+ .apply();
if (mTokenResponseCallback != null) {
mTokenResponseCallback.onEscrowTokenAdded(token, handle, uid);
}
@@ -361,6 +371,9 @@ public class CarTrustAgentBleService extends SimpleBleServer {
@Override
public void onEscrowTokenRemoved(long handle, boolean successful) throws RemoteException {
Log.d(TAG, "onEscrowTokenRemoved handle:" + handle);
+ mTokenHandleSharedPreferences.edit()
+ .remove(String.valueOf(handle))
+ .apply();
if (mTokenResponseCallback != null) {
mTokenResponseCallback.onEscrowTokenRemoved(handle, successful);
}
@@ -373,5 +386,10 @@ public class CarTrustAgentBleService extends SimpleBleServer {
mTokenResponseCallback.onEscrowTokenActiveStateChanged(handle, active);
}
}
+
+ @Override
+ public int getUserIdByEscrowTokenHandle(long tokenHandle) {
+ return mTokenHandleSharedPreferences.getInt(String.valueOf(tokenHandle), -1);
+ }
}
}
diff --git a/car-lib/src/android/car/trust/ICarTrustAgentBleService.aidl b/car-lib/src/android/car/trust/ICarTrustAgentBleService.aidl
index 8b50fd379a..4dec6a0a43 100644
--- a/car-lib/src/android/car/trust/ICarTrustAgentBleService.aidl
+++ b/car-lib/src/android/car/trust/ICarTrustAgentBleService.aidl
@@ -58,4 +58,7 @@ interface ICarTrustAgentBleService {
void onEscrowTokenAdded(in byte[] token, long handle, int uid);
void onEscrowTokenRemoved(long handle, boolean successful);
void onEscrowTokenActiveStateChanged(long handle, boolean active);
+
+ /** Management */
+ int getUserIdByEscrowTokenHandle(long tokenHandle);
}