blob: 230c3af8f6cfaa255a66ddebb01372006ef306d4 [file] [log] [blame]
Ram Periathiruvadi18789a82019-01-08 14:46:51 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.car.trust;
18
19import android.annotation.Nullable;
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070020import android.app.ActivityManager;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080021import android.bluetooth.BluetoothDevice;
22import android.car.trust.ICarTrustAgentBleCallback;
23import android.car.trust.ICarTrustAgentEnrollment;
24import android.car.trust.ICarTrustAgentEnrollmentCallback;
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -070025import android.content.SharedPreferences;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080026import android.os.IBinder;
27import android.os.RemoteException;
28import android.util.Log;
29
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070030import com.android.car.Utils;
31import com.android.internal.annotations.GuardedBy;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080032
33import java.io.PrintWriter;
34import java.util.ArrayList;
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070035import java.util.HashMap;
36import java.util.HashSet;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080037import java.util.List;
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070038import java.util.Map;
39import java.util.Set;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080040
41/**
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070042 * A service that is part of the CarTrustedDeviceService that is responsible for allowing a
43 * phone to enroll as a trusted device. The enrolled phone can then be used for authenticating a
44 * user on the HU. This implements the {@link android.car.trust.CarTrustAgentEnrollmentManager}
45 * APIs that an app like Car Settings can call to conduct an enrollment.
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080046 */
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070047public class CarTrustAgentEnrollmentService extends ICarTrustAgentEnrollment.Stub {
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080048 private static final String TAG = "CarTrustAgentEnroll";
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070049 private static final String FAKE_AUTH_STRING = "000000";
50 private final CarTrustedDeviceService mTrustedDeviceService;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080051 // List of clients listening to Enrollment state change events.
52 private final List<EnrollmentStateClient> mEnrollmentStateClients = new ArrayList<>();
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070053 // List of clients listening to BLE state changes events during enrollment.
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080054 private final List<BleStateChangeClient> mBleStateChangeClients = new ArrayList<>();
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070055 private final CarTrustAgentBleManager mCarTrustAgentBleManager;
56 private CarTrustAgentEnrollmentRequestDelegate mEnrollmentDelegate;
57 private Object mRemoteDeviceLock = new Object();
58 @GuardedBy("mRemoteDeviceLock")
59 private BluetoothDevice mRemoteEnrollmentDevice;
60 @GuardedBy("this")
61 private boolean mEnrollmentHandshakeAccepted;
62 private final Map<Long, Boolean> mTokenActiveState = new HashMap<>();
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080063
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070064 public CarTrustAgentEnrollmentService(CarTrustedDeviceService service,
65 CarTrustAgentBleManager bleService) {
66 mTrustedDeviceService = service;
67 mCarTrustAgentBleManager = bleService;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080068 }
69
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080070 public synchronized void init() {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070071 mCarTrustAgentBleManager.setupEnrollmentBleServer();
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080072 }
73
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080074 public synchronized void release() {
75 for (EnrollmentStateClient client : mEnrollmentStateClients) {
76 client.mListenerBinder.unlinkToDeath(client, 0);
77 }
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070078 for (BleStateChangeClient client : mBleStateChangeClients) {
79 client.mListenerBinder.unlinkToDeath(client, 0);
80 }
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080081 mEnrollmentStateClients.clear();
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070082 setEnrollmentHandshakeAccepted(false);
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080083 }
84
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070085 // Implementing the ICarTrustAgentEnrollment interface
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080086
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070087 /**
88 * Begin BLE advertisement for Enrollment. This should be called from an app that conducts
89 * the enrollment of the trusted device.
90 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -080091 @Override
92 public void startEnrollmentAdvertising() {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -070093 // Stop any current broadcasts
94 mTrustedDeviceService.getCarTrustAgentUnlockService().stopUnlockAdvertising();
95 stopEnrollmentAdvertising();
96 if (Log.isLoggable(TAG, Log.DEBUG)) {
97 Log.d(TAG, "startEnrollmentAdvertising");
98 }
99 mCarTrustAgentBleManager.startEnrollmentAdvertising();
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800100 }
101
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700102 /**
103 * Stop BLE advertisement for Enrollment
104 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800105 @Override
106 public void stopEnrollmentAdvertising() {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700107 mCarTrustAgentBleManager.stopEnrollmentAdvertising();
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800108 }
109
110 @Override
111 public void initiateEnrollmentHandshake(BluetoothDevice device) {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700112 // TODO(b/129029320) - this is not needed since the IHU plays the server
113 // role and the secure handshake is initiated by the client.
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800114 }
115
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700116 /**
117 * Called by the client to notify that the user has accepted a pairing code or any out-of-band
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700118 * confirmation, and send confirmation signals to remote bluetooth device.
119 *
120 * @param device the remote Bluetooth device that will receive the signal.
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700121 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800122 @Override
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700123 public void enrollmentHandshakeAccepted(BluetoothDevice device) {
124 mCarTrustAgentBleManager.sendPairingCodeConfirmation(device);
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700125 setEnrollmentHandshakeAccepted(true);
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800126 }
127
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700128 /**
129 * Terminate the Enrollment process. To be called when an error is encountered during
130 * enrollment. For example - user pressed cancel on pairing code confirmation or user
131 * navigated away from the app before completing enrollment.
132 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800133 @Override
134 public void terminateEnrollmentHandshake() {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700135 setEnrollmentHandshakeAccepted(false);
136 // Disconnect from BLE
137 mCarTrustAgentBleManager.disconnectRemoteDevice(mRemoteEnrollmentDevice);
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800138 }
139
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700140 /**
141 * Returns if there is an active token for the given user and handle.
142 *
143 * @param handle handle corresponding to the escrow token
144 * @param uid user id
145 * @return True if the escrow token is active, false if not
146 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800147 @Override
Ram Periathiruvadia30d5022019-03-14 13:16:03 -0700148 public boolean isEscrowTokenActive(long handle, int uid) {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700149 if (mTokenActiveState.get(handle) != null) {
150 return mTokenActiveState.get(handle);
151 }
Ram Periathiruvadia30d5022019-03-14 13:16:03 -0700152 return false;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800153 }
154
155 @Override
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700156 public void removeEscrowToken(long handle, int uid) {
157 mEnrollmentDelegate.removeEscrowToken(handle, uid);
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800158 }
159
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700160 /**
161 * Get the Handles corresponding to the token for the current user. The client can use this
162 * to list the trusted devices for the user. This means that the client should maintain a map
163 * of the handles:Bluetooth device names.
164 *
165 * @param uid user id
166 * @return array of handles for the user.
167 */
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800168 @Override
Ram Periathiruvadia30d5022019-03-14 13:16:03 -0700169 public long[] getEnrollmentHandlesForUser(int uid) {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700170 Set<String> handlesSet = mTrustedDeviceService.getSharedPrefs().getStringSet(
171 String.valueOf(uid),
172 new HashSet<>());
173 long[] handles = new long[handlesSet.size()];
174 int i = 0;
175 for (String handle : handlesSet) {
176 handles[i++] = Long.valueOf(handle);
177 }
178 return handles;
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800179 }
180
181 /**
182 * Registers a {@link ICarTrustAgentEnrollmentCallback} to be notified for changes to the
183 * enrollment state.
184 *
185 * @param listener {@link ICarTrustAgentEnrollmentCallback}
186 */
187 @Override
188 public synchronized void registerEnrollmentCallback(ICarTrustAgentEnrollmentCallback listener) {
189 if (listener == null) {
190 throw new IllegalArgumentException("Listener is null");
191 }
192 // If a new client is registering, create a new EnrollmentStateClient and add it to the list
193 // of listening clients.
194 EnrollmentStateClient client = findEnrollmentStateClientLocked(listener);
195 if (client == null) {
196 client = new EnrollmentStateClient(listener);
197 try {
198 listener.asBinder().linkToDeath(client, 0);
199 } catch (RemoteException e) {
200 Log.e(TAG, "Cannot link death recipient to binder ", e);
201 return;
202 }
203 mEnrollmentStateClients.add(client);
204 }
205 }
206
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700207 void onEscrowTokenAdded(byte[] token, long handle, int uid) {
208 if (Log.isLoggable(TAG, Log.DEBUG)) {
209 Log.d(TAG, "onEscrowTokenAdded handle:" + handle + " uid:" + uid);
210 }
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700211 mTrustedDeviceService.getSharedPrefs().edit().putInt(String.valueOf(handle), uid).apply();
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700212 Set<String> handles = mTrustedDeviceService.getSharedPrefs().getStringSet(
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700213 String.valueOf(uid), new HashSet<>());
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700214 handles.add(String.valueOf(handle));
215 mTrustedDeviceService.getSharedPrefs().edit().putStringSet(String.valueOf(uid),
216 handles).apply();
217
218 if (mRemoteEnrollmentDevice == null) {
219 Log.e(TAG, "onEscrowTokenAdded() but no remote device connected!");
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700220 removeEscrowToken(handle, uid);
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700221 return;
222 }
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700223 for (EnrollmentStateClient client : mEnrollmentStateClients) {
224 try {
225 client.mListener.onEscrowTokenAdded(handle);
226 } catch (RemoteException e) {
227 Log.e(TAG, "onEscrowTokenAdded dispatch failed", e);
228 }
229 }
230 }
231
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700232 void onEscrowTokenRemoved(long handle, int uid) {
233 if (Log.isLoggable(TAG, Log.DEBUG)) {
234 Log.d(TAG, "onEscrowTokenRemoved handle:" + handle + " uid:" + uid);
235 }
236 for (EnrollmentStateClient client : mEnrollmentStateClients) {
237 try {
238 client.mListener.onEscrowTokenRemoved(handle);
239 } catch (RemoteException e) {
240 Log.e(TAG, "onEscrowTokenAdded dispatch failed", e);
241 }
242 }
243 SharedPreferences.Editor editor = mTrustedDeviceService.getSharedPrefs().edit();
244 editor.remove(String.valueOf(handle));
245 Set<String> handles = mTrustedDeviceService.getSharedPrefs().getStringSet(
246 String.valueOf(uid), new HashSet<>());
247 handles.remove(String.valueOf(handle));
248 editor.putStringSet(String.valueOf(uid), handles);
249 editor.apply();
250 }
251
252 void onEscrowTokenActiveStateChanged(long handle, boolean isTokenActive) {
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700253 if (Log.isLoggable(TAG, Log.DEBUG)) {
254 Log.d(TAG, "onEscrowTokenActiveStateChanged: " + Long.toHexString(handle));
255 }
Ram Periathiruvadi9d94c6b2019-03-20 11:16:44 -0700256 mTokenActiveState.put(handle, isTokenActive);
257 dispatchEscrowTokenActiveStateChanged(handle, isTokenActive);
258 if (isTokenActive) {
259 mCarTrustAgentBleManager.sendEnrollmentHandle(mRemoteEnrollmentDevice, handle);
260 }
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700261 }
262
263 void onEnrollmentAdvertiseStartSuccess() {
264 for (BleStateChangeClient client : mBleStateChangeClients) {
265 try {
266 client.mListener.onEnrollmentAdvertisingStarted();
267 } catch (RemoteException e) {
268 Log.e(TAG, "onAdvertiseSuccess dispatch failed", e);
269 }
270 }
271 }
272
273 void onEnrollmentAdvertiseStartFailure(int errorcode) {
274 for (BleStateChangeClient client : mBleStateChangeClients) {
275 try {
276 client.mListener.onEnrollmentAdvertisingFailed(errorcode);
277 } catch (RemoteException e) {
278 Log.e(TAG, "onAdvertiseSuccess dispatch failed", e);
279 }
280 }
281 }
282
283 void onRemoteDeviceConnected(BluetoothDevice device) {
284 synchronized (mRemoteDeviceLock) {
285 mRemoteEnrollmentDevice = device;
286 }
287 for (BleStateChangeClient client : mBleStateChangeClients) {
288 try {
289 client.mListener.onBleEnrollmentDeviceConnected(device);
290 } catch (RemoteException e) {
291 Log.e(TAG, "onAdvertiseSuccess dispatch failed", e);
292 }
293 }
294 //TODO(b/11788064) Fake Authentication to enable clients to go through the enrollment flow.
295 fakeAuthentication();
296 }
297
298 void onRemoteDeviceDisconnected(BluetoothDevice device) {
299 synchronized (mRemoteDeviceLock) {
300 mRemoteEnrollmentDevice = null;
301 }
302 for (BleStateChangeClient client : mBleStateChangeClients) {
303 try {
304 client.mListener.onBleEnrollmentDeviceDisconnected(device);
305 } catch (RemoteException e) {
306 Log.e(TAG, "onAdvertiseSuccess dispatch failed", e);
307 }
308 }
309 }
310
311 void onEnrollmentDataReceived(byte[] value) {
312 if (mEnrollmentDelegate == null) {
313 if (Log.isLoggable(TAG, Log.DEBUG)) {
314 Log.d(TAG, "Enrollment Delegate not set");
315 }
316 return;
317 }
318 // The phone is not expected to send any data until the user has accepted the
319 // pairing.
320 if (!mEnrollmentHandshakeAccepted) {
321 Log.e(TAG, "User has not accepted the pairing code yet."
322 + Utils.byteArrayToHexString(value));
323 return;
324 }
325 mEnrollmentDelegate.addEscrowToken(value, ActivityManager.getCurrentUser());
326 }
327
328 // TODO(b/11788064) Fake Authentication until we hook up the crypto lib
329 private void fakeAuthentication() {
330 if (mRemoteEnrollmentDevice == null) {
331 Log.e(TAG, "Remote Device disconnected before Enrollment completed");
332 return;
333 }
334 for (EnrollmentStateClient client : mEnrollmentStateClients) {
335 try {
336 client.mListener.onAuthStringAvailable(mRemoteEnrollmentDevice, FAKE_AUTH_STRING);
337 } catch (RemoteException e) {
338 Log.e(TAG, "onAdvertiseSuccess dispatch failed", e);
339 }
340 }
341 }
342
343 private synchronized void setEnrollmentHandshakeAccepted(boolean accepted) {
344 mEnrollmentHandshakeAccepted = accepted;
345 }
346
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800347 /**
348 * Iterates through the list of registered Enrollment State Change clients -
349 * {@link EnrollmentStateClient} and finds if the given client is already registered.
350 *
351 * @param listener Listener to look for.
352 * @return the {@link EnrollmentStateClient} if found, null if not
353 */
354 @Nullable
355 private EnrollmentStateClient findEnrollmentStateClientLocked(
356 ICarTrustAgentEnrollmentCallback listener) {
357 IBinder binder = listener.asBinder();
358 // Find the listener by comparing the binder object they host.
359 for (EnrollmentStateClient client : mEnrollmentStateClients) {
360 if (client.isHoldingBinder(binder)) {
361 return client;
362 }
363 }
364 return null;
365 }
366
367 /**
368 * Unregister the given Enrollment State Change listener
369 *
370 * @param listener client to unregister
371 */
372 @Override
373 public synchronized void unregisterEnrollmentCallback(
374 ICarTrustAgentEnrollmentCallback listener) {
375 if (listener == null) {
376 throw new IllegalArgumentException("Listener is null");
377 }
378
379 EnrollmentStateClient client = findEnrollmentStateClientLocked(listener);
380 if (client == null) {
381 Log.e(TAG, "unregisterEnrollmentCallback(): listener was not previously "
382 + "registered");
383 return;
384 }
385 listener.asBinder().unlinkToDeath(client, 0);
386 mEnrollmentStateClients.remove(client);
387 }
388
389 /**
390 * Registers a {@link ICarTrustAgentBleCallback} to be notified for changes to the BLE state
391 * changes.
392 *
393 * @param listener {@link ICarTrustAgentBleCallback}
394 */
395 @Override
396 public synchronized void registerBleCallback(ICarTrustAgentBleCallback listener) {
397 if (listener == null) {
398 throw new IllegalArgumentException("Listener is null");
399 }
400 // If a new client is registering, create a new EnrollmentStateClient and add it to the list
401 // of listening clients.
402 BleStateChangeClient client = findBleStateClientLocked(listener);
403 if (client == null) {
404 client = new BleStateChangeClient(listener);
405 try {
406 listener.asBinder().linkToDeath(client, 0);
407 } catch (RemoteException e) {
408 Log.e(TAG, "Cannot link death recipient to binder " + e);
409 return;
410 }
411 mBleStateChangeClients.add(client);
412 }
413 }
414
415 /**
416 * Iterates through the list of registered BLE State Change clients -
417 * {@link BleStateChangeClient} and finds if the given client is already registered.
418 *
419 * @param listener Listener to look for.
420 * @return the {@link BleStateChangeClient} if found, null if not
421 */
422 @Nullable
423 private BleStateChangeClient findBleStateClientLocked(
424 ICarTrustAgentBleCallback listener) {
425 IBinder binder = listener.asBinder();
426 // Find the listener by comparing the binder object they host.
427 for (BleStateChangeClient client : mBleStateChangeClients) {
428 if (client.isHoldingBinder(binder)) {
429 return client;
430 }
431 }
432 return null;
433 }
434
435 /**
436 * Unregister the given BLE State Change listener
437 *
438 * @param listener client to unregister
439 */
440 @Override
441 public synchronized void unregisterBleCallback(ICarTrustAgentBleCallback listener) {
442 if (listener == null) {
443 throw new IllegalArgumentException("Listener is null");
444 }
445
446 BleStateChangeClient client = findBleStateClientLocked(listener);
447 if (client == null) {
448 Log.e(TAG, "unregisterBleCallback(): listener was not previously "
449 + "registered");
450 return;
451 }
452 listener.asBinder().unlinkToDeath(client, 0);
453 mBleStateChangeClients.remove(client);
454 }
455
456 /**
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700457 * The interface that an enrollment delegate has to implement to add/remove escrow tokens.
458 */
459 interface CarTrustAgentEnrollmentRequestDelegate {
460 /**
461 * Add the given escrow token that was generated by the peer device that is being enrolled.
462 *
463 * @param token the 64 bit token
464 * @param uid user id
465 */
466 void addEscrowToken(byte[] token, int uid);
467
468 /**
469 * Remove the given escrow token. This should be called when removing a trusted device.
470 *
471 * @param handle the 64 bit token
472 * @param uid user id
473 */
474 void removeEscrowToken(long handle, int uid);
475
476 /**
477 * Query if the token is active. The result is asynchronously delivered through a callback
478 * {@link CarTrustAgentEnrollmentService#onEscrowTokenActiveStateChanged(long, boolean)}
479 *
480 * @param handle the 64 bit token
481 * @param uid user id
482 */
483 void isEscrowTokenActive(long handle, int uid);
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700484 }
485
486 void setEnrollmentRequestDelegate(CarTrustAgentEnrollmentRequestDelegate delegate) {
487 mEnrollmentDelegate = delegate;
488 }
489
490 void dump(PrintWriter writer) {
491 }
492
493 private void dispatchEscrowTokenActiveStateChanged(long handle, boolean active) {
494 for (EnrollmentStateClient client : mEnrollmentStateClients) {
495 try {
496 client.mListener.onEscrowTokenActiveStateChanged(handle, active);
497 } catch (RemoteException e) {
498 Log.e(TAG, "Cannot notify client of a Token Activation change: " + active);
499 }
500 }
501 }
502
503 /**
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800504 * Class that holds onto client related information - listener interface, process that hosts the
505 * binder object etc.
506 * <p>
507 * It also registers for death notifications of the host.
508 */
509 private class EnrollmentStateClient implements IBinder.DeathRecipient {
510 private final IBinder mListenerBinder;
511 private final ICarTrustAgentEnrollmentCallback mListener;
512
513 EnrollmentStateClient(ICarTrustAgentEnrollmentCallback listener) {
514 mListener = listener;
515 mListenerBinder = listener.asBinder();
516 }
517
518 @Override
519 public void binderDied() {
520 if (Log.isLoggable(TAG, Log.DEBUG)) {
521 Log.d(TAG, "Binder died " + mListenerBinder);
522 }
523 mListenerBinder.unlinkToDeath(this, 0);
524 synchronized (CarTrustAgentEnrollmentService.this) {
525 mEnrollmentStateClients.remove(this);
526 }
527 }
528
529 /**
530 * Returns if the given binder object matches to what this client info holds.
531 * Used to check if the listener asking to be registered is already registered.
532 *
533 * @return true if matches, false if not
534 */
535 public boolean isHoldingBinder(IBinder binder) {
536 return mListenerBinder == binder;
537 }
538 }
539
540 private class BleStateChangeClient implements IBinder.DeathRecipient {
541 private final IBinder mListenerBinder;
542 private final ICarTrustAgentBleCallback mListener;
543
544 BleStateChangeClient(ICarTrustAgentBleCallback listener) {
545 mListener = listener;
546 mListenerBinder = listener.asBinder();
547 }
548
549 @Override
550 public void binderDied() {
551 if (Log.isLoggable(TAG, Log.DEBUG)) {
552 Log.d(TAG, "Binder died " + mListenerBinder);
553 }
554 mListenerBinder.unlinkToDeath(this, 0);
555 synchronized (CarTrustAgentEnrollmentService.this) {
556 mBleStateChangeClients.remove(this);
557 }
558 }
559
560 /**
561 * Returns if the given binder object matches to what this client info holds.
562 * Used to check if the listener asking to be registered is already registered.
563 *
564 * @return true if matches, false if not
565 */
566 public boolean isHoldingBinder(IBinder binder) {
567 return mListenerBinder == binder;
568 }
569
Ram Periathiruvadide0ca082019-03-20 11:16:44 -0700570 public void onEnrollmentAdvertisementStarted() {
571 try {
572 mListener.onEnrollmentAdvertisingStarted();
573 } catch (RemoteException e) {
574 Log.e(TAG, "onEnrollmentAdvertisementStarted() failed", e);
575 }
576 }
Ram Periathiruvadi18789a82019-01-08 14:46:51 -0800577 }
578}