1 /* 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 17 package com.android.server.soundtrigger_middleware; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.hardware.soundtrigger.V2_0.ISoundTriggerHw; 22 import android.media.soundtrigger.ModelParameterRange; 23 import android.media.soundtrigger.PhraseSoundModel; 24 import android.media.soundtrigger.Properties; 25 import android.media.soundtrigger.RecognitionConfig; 26 import android.media.soundtrigger.SoundModel; 27 import android.media.soundtrigger.Status; 28 import android.media.soundtrigger_middleware.PhraseRecognitionEventSys; 29 import android.media.soundtrigger_middleware.RecognitionEventSys; 30 import android.os.IBinder; 31 import android.os.IHwBinder; 32 import android.os.RemoteException; 33 import android.os.SystemClock; 34 import android.system.OsConstants; 35 import android.util.Slog; 36 37 import java.io.IOException; 38 import java.util.HashMap; 39 import java.util.Map; 40 import java.util.Objects; 41 import java.util.concurrent.ConcurrentHashMap; 42 import java.util.concurrent.ConcurrentMap; 43 import java.util.concurrent.atomic.AtomicInteger; 44 import java.util.concurrent.atomic.AtomicReference; 45 46 /** 47 * An implementation of {@link ISoundTriggerHal}, on top of any 48 * android.hardware.soundtrigger.V2_x.ISoundTriggerHw implementation. This class hides away some of 49 * the details involved with retaining backward compatibility and adapts to the more pleasant syntax 50 * exposed by {@link ISoundTriggerHal}, compared to the bare driver interface. 51 * <p> 52 * Exception handling: 53 * <ul> 54 * <li>All {@link RemoteException}s get rethrown as {@link RuntimeException}. 55 * <li>All HAL malfunctions get thrown as {@link HalException}. 56 * <li>All unsupported operations get thrown as {@link RecoverableException} with a 57 * {@link android.media.soundtrigger.Status#OPERATION_NOT_SUPPORTED} 58 * code. 59 * </ul> 60 */ 61 final class SoundTriggerHw2Compat implements ISoundTriggerHal { 62 private static final String TAG = "SoundTriggerHw2Compat"; 63 64 private final @NonNull Runnable mRebootRunnable; 65 private final @NonNull IHwBinder mBinder; 66 private @NonNull android.hardware.soundtrigger.V2_0.ISoundTriggerHw mUnderlying_2_0; 67 private @Nullable android.hardware.soundtrigger.V2_1.ISoundTriggerHw mUnderlying_2_1; 68 private @Nullable android.hardware.soundtrigger.V2_2.ISoundTriggerHw mUnderlying_2_2; 69 private @Nullable android.hardware.soundtrigger.V2_3.ISoundTriggerHw mUnderlying_2_3; 70 71 // HAL <=2.1 requires us to pass a callback argument to startRecognition. We will store the one 72 // passed on load and then pass it on start. We don't bother storing the callback on newer 73 // versions. 74 private final @NonNull ConcurrentMap<Integer, ModelCallback> mModelCallbacks = 75 new ConcurrentHashMap<>(); 76 77 // A map from IBinder.DeathRecipient to IHwBinder.DeathRecipient for doing the mapping upon 78 // unlinking. 79 private final @NonNull Map<IBinder.DeathRecipient, IHwBinder.DeathRecipient> 80 mDeathRecipientMap = new HashMap<>(); 81 82 // The properties are read at construction time and cached, since we need to use some of them 83 // to enforce constraints. 84 private final @NonNull Properties mProperties; 85 create( @onNull ISoundTriggerHw underlying, @NonNull Runnable rebootRunnable, ICaptureStateNotifier notifier)86 static ISoundTriggerHal create( 87 @NonNull ISoundTriggerHw underlying, 88 @NonNull Runnable rebootRunnable, 89 ICaptureStateNotifier notifier) { 90 return create(underlying.asBinder(), rebootRunnable, notifier); 91 } 92 create(@onNull IHwBinder binder, @NonNull Runnable rebootRunnable, ICaptureStateNotifier notifier)93 static ISoundTriggerHal create(@NonNull IHwBinder binder, 94 @NonNull Runnable rebootRunnable, 95 ICaptureStateNotifier notifier) { 96 SoundTriggerHw2Compat compat = new SoundTriggerHw2Compat(binder, rebootRunnable); 97 ISoundTriggerHal result = compat; 98 // Add max model limiter for versions. 99 result = new SoundTriggerHalMaxModelLimiter(result, compat.mProperties.maxSoundModels); 100 // Add concurrent capture handler for HALs which do not support concurrent capture. 101 if (!compat.mProperties.concurrentCapture) { 102 result = new SoundTriggerHalConcurrentCaptureHandler(result, notifier); 103 } 104 return result; 105 } 106 SoundTriggerHw2Compat(@onNull IHwBinder binder, @NonNull Runnable rebootRunnable)107 private SoundTriggerHw2Compat(@NonNull IHwBinder binder, @NonNull Runnable rebootRunnable) { 108 mRebootRunnable = Objects.requireNonNull(rebootRunnable); 109 mBinder = Objects.requireNonNull(binder); 110 initUnderlying(binder); 111 mProperties = Objects.requireNonNull(getPropertiesInternal()); 112 } 113 initUnderlying(IHwBinder binder)114 private void initUnderlying(IHwBinder binder) { 115 // We want to share the proxy instances rather than create a separate proxy for every 116 // version, so we go down the versions in descending order to find the latest one supported, 117 // and then simply up-cast it to obtain all the versions that are earlier. 118 119 // Attempt 2.3 120 android.hardware.soundtrigger.V2_3.ISoundTriggerHw as2_3 = 121 android.hardware.soundtrigger.V2_3.ISoundTriggerHw.asInterface(binder); 122 if (as2_3 != null) { 123 mUnderlying_2_0 = mUnderlying_2_1 = mUnderlying_2_2 = mUnderlying_2_3 = as2_3; 124 return; 125 } 126 127 // Attempt 2.2 128 android.hardware.soundtrigger.V2_2.ISoundTriggerHw as2_2 = 129 android.hardware.soundtrigger.V2_2.ISoundTriggerHw.asInterface(binder); 130 if (as2_2 != null) { 131 mUnderlying_2_0 = mUnderlying_2_1 = mUnderlying_2_2 = as2_2; 132 mUnderlying_2_3 = null; 133 return; 134 } 135 136 // Attempt 2.1 137 android.hardware.soundtrigger.V2_1.ISoundTriggerHw as2_1 = 138 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.asInterface(binder); 139 if (as2_1 != null) { 140 mUnderlying_2_0 = mUnderlying_2_1 = as2_1; 141 mUnderlying_2_2 = mUnderlying_2_3 = null; 142 return; 143 } 144 145 // Attempt 2.0 146 android.hardware.soundtrigger.V2_0.ISoundTriggerHw as2_0 = 147 android.hardware.soundtrigger.V2_0.ISoundTriggerHw.asInterface(binder); 148 if (as2_0 != null) { 149 mUnderlying_2_0 = as2_0; 150 mUnderlying_2_1 = mUnderlying_2_2 = mUnderlying_2_3 = null; 151 return; 152 } 153 154 throw new RuntimeException("Binder doesn't support ISoundTriggerHw@2.0"); 155 } 156 handleHalStatus(int status, String methodName)157 private static void handleHalStatus(int status, String methodName) { 158 if (status != 0) { 159 throw new HalException(status, methodName); 160 } 161 } 162 handleHalStatusAllowBusy(int status, String methodName)163 private static void handleHalStatusAllowBusy(int status, String methodName) { 164 if (status == -OsConstants.EBUSY) { 165 throw new RecoverableException(Status.RESOURCE_CONTENTION); 166 } 167 handleHalStatus(status, methodName); 168 } 169 170 @Override reboot()171 public void reboot() { 172 mRebootRunnable.run(); 173 } 174 175 @Override detach()176 public void detach() { 177 // No-op. 178 } 179 180 @Override getProperties()181 public Properties getProperties() { 182 return mProperties; 183 } 184 getPropertiesInternal()185 private Properties getPropertiesInternal() { 186 try { 187 AtomicInteger retval = new AtomicInteger(-1); 188 AtomicReference<android.hardware.soundtrigger.V2_3.Properties> properties = 189 new AtomicReference<>(); 190 try { 191 as2_3().getProperties_2_3( 192 (r, p) -> { 193 retval.set(r); 194 properties.set(p); 195 }); 196 } catch (NotSupported e) { 197 // Fall-back to the 2.0 version: 198 return getProperties_2_0(); 199 } 200 handleHalStatus(retval.get(), "getProperties_2_3"); 201 return ConversionUtil.hidl2aidlProperties(properties.get()); 202 } catch (RemoteException e) { 203 throw e.rethrowAsRuntimeException(); 204 } 205 } 206 207 @Override registerCallback(GlobalCallback callback)208 public void registerCallback(GlobalCallback callback) { 209 // In versions 2.x the events represented by this callback don't exist, we can 210 // safely ignore this. 211 } 212 213 @Override loadSoundModel(SoundModel soundModel, ModelCallback callback)214 public int loadSoundModel(SoundModel soundModel, ModelCallback callback) { 215 android.hardware.soundtrigger.V2_3.ISoundTriggerHw.SoundModel hidlModel = 216 ConversionUtil.aidl2hidlSoundModel(soundModel); 217 try { 218 AtomicInteger retval = new AtomicInteger(-1); 219 AtomicInteger handle = new AtomicInteger(0); 220 try { 221 as2_1().loadSoundModel_2_1(hidlModel, new ModelCallbackWrapper(callback), 222 0, 223 (r, h) -> { 224 retval.set(r); 225 handle.set(h); 226 }); 227 handleHalStatus(retval.get(), "loadSoundModel_2_1"); 228 mModelCallbacks.put(handle.get(), callback); 229 } catch (NotSupported ee) { 230 // Fall-back to the 2.0 version: 231 return loadSoundModel_2_0(hidlModel, callback); 232 } 233 return handle.get(); 234 } catch (RemoteException e) { 235 throw e.rethrowAsRuntimeException(); 236 } finally { 237 // TODO(b/219825762): We should be able to use the entire object in a try-with-resources 238 // clause, instead of having to explicitly close internal fields. 239 if (hidlModel.data != null) { 240 try { 241 hidlModel.data.close(); 242 } catch (IOException e) { 243 Slog.e(TAG, "Failed to close file", e); 244 } 245 } 246 } 247 } 248 249 @Override loadPhraseSoundModel(PhraseSoundModel soundModel, ModelCallback callback)250 public int loadPhraseSoundModel(PhraseSoundModel soundModel, ModelCallback callback) { 251 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel hidlModel = 252 ConversionUtil.aidl2hidlPhraseSoundModel(soundModel); 253 try { 254 AtomicInteger retval = new AtomicInteger(-1); 255 AtomicInteger handle = new AtomicInteger(0); 256 try { 257 as2_1().loadPhraseSoundModel_2_1(hidlModel, new ModelCallbackWrapper(callback), 258 0, 259 (r, h) -> { 260 retval.set(r); 261 handle.set(h); 262 }); 263 handleHalStatus(retval.get(), "loadPhraseSoundModel_2_1"); 264 mModelCallbacks.put(handle.get(), callback); 265 } catch (NotSupported ee) { 266 // Fall-back to the 2.0 version: 267 return loadPhraseSoundModel_2_0(hidlModel, callback); 268 } 269 return handle.get(); 270 } catch (RemoteException e) { 271 throw e.rethrowAsRuntimeException(); 272 } finally { 273 // TODO(b/219825762): We should be able to use the entire object in a try-with-resources 274 // clause, instead of having to explicitly close internal fields. 275 if (hidlModel.common.data != null) { 276 try { 277 hidlModel.common.data.close(); 278 } catch (IOException e) { 279 Slog.e(TAG, "Failed to close file", e); 280 } 281 } 282 } 283 } 284 285 @Override unloadSoundModel(int modelHandle)286 public void unloadSoundModel(int modelHandle) { 287 try { 288 // Safe if key doesn't exist. 289 mModelCallbacks.remove(modelHandle); 290 int retval = as2_0().unloadSoundModel(modelHandle); 291 handleHalStatus(retval, "unloadSoundModel"); 292 } catch (RemoteException e) { 293 throw e.rethrowAsRuntimeException(); 294 } 295 } 296 297 @Override stopRecognition(int modelHandle)298 public void stopRecognition(int modelHandle) { 299 try { 300 int retval = as2_0().stopRecognition(modelHandle); 301 handleHalStatus(retval, "stopRecognition"); 302 } catch (RemoteException e) { 303 throw e.rethrowAsRuntimeException(); 304 } 305 306 } 307 308 @Override startRecognition(int modelHandle, int deviceHandle, int ioHandle, RecognitionConfig config)309 public void startRecognition(int modelHandle, int deviceHandle, int ioHandle, 310 RecognitionConfig config) { 311 android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig = 312 ConversionUtil.aidl2hidlRecognitionConfig(config, deviceHandle, ioHandle); 313 try { 314 try { 315 int retval = as2_3().startRecognition_2_3(modelHandle, hidlConfig); 316 handleHalStatus(retval, "startRecognition_2_3"); 317 } catch (NotSupported ee) { 318 // Fall-back to the 2.0 version: 319 startRecognition_2_1(modelHandle, hidlConfig); 320 } 321 } catch (RemoteException e) { 322 throw e.rethrowAsRuntimeException(); 323 } 324 } 325 326 @Override forceRecognitionEvent(int modelHandle)327 public void forceRecognitionEvent(int modelHandle) { 328 try { 329 int retval = as2_2().getModelState(modelHandle); 330 handleHalStatus(retval, "getModelState"); 331 } catch (RemoteException e) { 332 throw e.rethrowAsRuntimeException(); 333 } catch (NotSupported e) { 334 throw e.throwAsRecoverableException(); 335 } 336 } 337 338 @Override getModelParameter(int modelHandle, int param)339 public int getModelParameter(int modelHandle, int param) { 340 AtomicInteger status = new AtomicInteger(-1); 341 AtomicInteger value = new AtomicInteger(0); 342 try { 343 as2_3().getParameter(modelHandle, param, 344 (s, v) -> { 345 status.set(s); 346 value.set(v); 347 }); 348 } catch (RemoteException e) { 349 throw e.rethrowAsRuntimeException(); 350 } catch (NotSupported e) { 351 throw e.throwAsRecoverableException(); 352 } 353 handleHalStatus(status.get(), "getParameter"); 354 return value.get(); 355 } 356 357 @Override setModelParameter(int modelHandle, int param, int value)358 public void setModelParameter(int modelHandle, int param, int value) { 359 try { 360 int retval = as2_3().setParameter(modelHandle, param, value); 361 handleHalStatus(retval, "setParameter"); 362 } catch (RemoteException e) { 363 throw e.rethrowAsRuntimeException(); 364 } catch (NotSupported e) { 365 throw e.throwAsRecoverableException(); 366 } 367 } 368 369 @Override queryParameter(int modelHandle, int param)370 public ModelParameterRange queryParameter(int modelHandle, int param) { 371 AtomicInteger status = new AtomicInteger(-1); 372 AtomicReference<android.hardware.soundtrigger.V2_3.OptionalModelParameterRange> 373 optionalRange = 374 new AtomicReference<>(); 375 try { 376 as2_3().queryParameter(modelHandle, param, 377 (s, r) -> { 378 status.set(s); 379 optionalRange.set(r); 380 }); 381 } catch (NotSupported e) { 382 // For older drivers, we consider no model parameter to be supported. 383 return null; 384 } catch (RemoteException e) { 385 throw e.rethrowAsRuntimeException(); 386 } 387 handleHalStatus(status.get(), "queryParameter"); 388 return (optionalRange.get().getDiscriminator() 389 == android.hardware.soundtrigger.V2_3.OptionalModelParameterRange.hidl_discriminator.range) 390 ? 391 ConversionUtil.hidl2aidlModelParameterRange(optionalRange.get().range()) : null; 392 } 393 394 @Override linkToDeath(IBinder.DeathRecipient recipient)395 public void linkToDeath(IBinder.DeathRecipient recipient) { 396 IHwBinder.DeathRecipient wrapper = cookie -> recipient.binderDied(); 397 mDeathRecipientMap.put(recipient, wrapper); 398 mBinder.linkToDeath(wrapper, 0); 399 } 400 401 @Override unlinkToDeath(IBinder.DeathRecipient recipient)402 public void unlinkToDeath(IBinder.DeathRecipient recipient) { 403 mBinder.unlinkToDeath(mDeathRecipientMap.remove(recipient)); 404 } 405 406 @Override interfaceDescriptor()407 public String interfaceDescriptor() { 408 try { 409 return as2_0().interfaceDescriptor(); 410 } catch (RemoteException e) { 411 throw e.rethrowAsRuntimeException(); 412 } 413 } 414 415 @Override flushCallbacks()416 public void flushCallbacks() { 417 // This is a no-op. Only implemented for decorators. 418 } 419 420 @Override clientAttached(IBinder binder)421 public void clientAttached(IBinder binder) { 422 // This is a no-op. Only implemented for decorators. 423 } 424 425 @Override clientDetached(IBinder binder)426 public void clientDetached(IBinder binder) { 427 // This is a no-op. Only implemented for decorators. 428 } 429 getProperties_2_0()430 private Properties getProperties_2_0() 431 throws RemoteException { 432 AtomicInteger retval = new AtomicInteger(-1); 433 AtomicReference<android.hardware.soundtrigger.V2_0.ISoundTriggerHw.Properties> 434 properties = 435 new AtomicReference<>(); 436 as2_0().getProperties( 437 (r, p) -> { 438 retval.set(r); 439 properties.set(p); 440 }); 441 handleHalStatus(retval.get(), "getProperties"); 442 return ConversionUtil.hidl2aidlProperties( 443 Hw2CompatUtil.convertProperties_2_0_to_2_3(properties.get())); 444 } 445 loadSoundModel_2_0( android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel soundModel, ModelCallback callback)446 private int loadSoundModel_2_0( 447 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel soundModel, 448 ModelCallback callback) 449 throws RemoteException { 450 // Convert the soundModel to V2.0. 451 android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel model_2_0 = 452 Hw2CompatUtil.convertSoundModel_2_1_to_2_0(soundModel); 453 454 AtomicInteger retval = new AtomicInteger(-1); 455 AtomicInteger handle = new AtomicInteger(0); 456 as2_0().loadSoundModel(model_2_0, new ModelCallbackWrapper(callback), 0, (r, h) -> { 457 retval.set(r); 458 handle.set(h); 459 }); 460 handleHalStatus(retval.get(), "loadSoundModel"); 461 mModelCallbacks.put(handle.get(), callback); 462 return handle.get(); 463 } 464 loadPhraseSoundModel_2_0( android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel soundModel, ModelCallback callback)465 private int loadPhraseSoundModel_2_0( 466 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel soundModel, 467 ModelCallback callback) 468 throws RemoteException { 469 // Convert the soundModel to V2.0. 470 android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel model_2_0 = 471 Hw2CompatUtil.convertPhraseSoundModel_2_1_to_2_0(soundModel); 472 473 AtomicInteger retval = new AtomicInteger(-1); 474 AtomicInteger handle = new AtomicInteger(0); 475 as2_0().loadPhraseSoundModel(model_2_0, new ModelCallbackWrapper(callback), 0, 476 (r, h) -> { 477 retval.set(r); 478 handle.set(h); 479 }); 480 handleHalStatus(retval.get(), "loadSoundModel"); 481 mModelCallbacks.put(handle.get(), callback); 482 return handle.get(); 483 } 484 startRecognition_2_1(int modelHandle, android.hardware.soundtrigger.V2_3.RecognitionConfig config)485 private void startRecognition_2_1(int modelHandle, 486 android.hardware.soundtrigger.V2_3.RecognitionConfig config) { 487 try { 488 try { 489 android.hardware.soundtrigger.V2_1.ISoundTriggerHw.RecognitionConfig config_2_1 = 490 Hw2CompatUtil.convertRecognitionConfig_2_3_to_2_1(config); 491 int retval = as2_1().startRecognition_2_1(modelHandle, config_2_1, 492 new ModelCallbackWrapper(mModelCallbacks.get(modelHandle)), 0); 493 handleHalStatus(retval, "startRecognition_2_1"); 494 } catch (NotSupported e) { 495 // Fall-back to the 2.0 version: 496 startRecognition_2_0(modelHandle, config); 497 } 498 } catch (RemoteException e) { 499 throw e.rethrowAsRuntimeException(); 500 } 501 } 502 startRecognition_2_0(int modelHandle, android.hardware.soundtrigger.V2_3.RecognitionConfig config)503 private void startRecognition_2_0(int modelHandle, 504 android.hardware.soundtrigger.V2_3.RecognitionConfig config) 505 throws RemoteException { 506 android.hardware.soundtrigger.V2_0.ISoundTriggerHw.RecognitionConfig config_2_0 = 507 Hw2CompatUtil.convertRecognitionConfig_2_3_to_2_0(config); 508 int retval = as2_0().startRecognition(modelHandle, config_2_0, 509 new ModelCallbackWrapper(mModelCallbacks.get(modelHandle)), 0); 510 handleHalStatus(retval, "startRecognition"); 511 } 512 513 private @NonNull as2_0()514 android.hardware.soundtrigger.V2_0.ISoundTriggerHw as2_0() { 515 return mUnderlying_2_0; 516 } 517 518 private @NonNull as2_1()519 android.hardware.soundtrigger.V2_1.ISoundTriggerHw as2_1() throws NotSupported { 520 if (mUnderlying_2_1 == null) { 521 throw new NotSupported("Underlying driver version < 2.1"); 522 } 523 return mUnderlying_2_1; 524 } 525 526 private @NonNull as2_2()527 android.hardware.soundtrigger.V2_2.ISoundTriggerHw as2_2() throws NotSupported { 528 if (mUnderlying_2_2 == null) { 529 throw new NotSupported("Underlying driver version < 2.2"); 530 } 531 return mUnderlying_2_2; 532 } 533 534 private @NonNull as2_3()535 android.hardware.soundtrigger.V2_3.ISoundTriggerHw as2_3() throws NotSupported { 536 if (mUnderlying_2_3 == null) { 537 throw new NotSupported("Underlying driver version < 2.3"); 538 } 539 return mUnderlying_2_3; 540 } 541 542 /** 543 * A checked exception representing the requested interface version not being supported. 544 * At the public interface layer, use {@link #throwAsRecoverableException()} to propagate it to 545 * the caller if the request cannot be fulfilled. 546 */ 547 private static class NotSupported extends Exception { NotSupported(String message)548 NotSupported(String message) { 549 super(message); 550 } 551 552 /** 553 * Throw this as a recoverable exception. 554 * 555 * @return Never actually returns anything. Always throws. Used so that caller can write 556 * throw e.throwAsRecoverableException(). 557 */ throwAsRecoverableException()558 RecoverableException throwAsRecoverableException() { 559 throw new RecoverableException(Status.OPERATION_NOT_SUPPORTED, getMessage()); 560 } 561 } 562 563 private static class ModelCallbackWrapper extends 564 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.Stub { 565 private final @NonNull ModelCallback mDelegate; 566 ModelCallbackWrapper( @onNull ModelCallback delegate)567 private ModelCallbackWrapper( 568 @NonNull ModelCallback delegate) { 569 mDelegate = Objects.requireNonNull(delegate); 570 } 571 572 @Override recognitionCallback_2_1( android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event, int cookie)573 public void recognitionCallback_2_1( 574 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event, 575 int cookie) { 576 RecognitionEventSys eventSys = new RecognitionEventSys(); 577 eventSys.recognitionEvent = ConversionUtil.hidl2aidlRecognitionEvent(event); 578 eventSys.halEventReceivedMillis = SystemClock.elapsedRealtime(); 579 mDelegate.recognitionCallback(event.header.model, eventSys); 580 } 581 582 @Override phraseRecognitionCallback_2_1( android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent event, int cookie)583 public void phraseRecognitionCallback_2_1( 584 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent event, 585 int cookie) { 586 PhraseRecognitionEventSys eventSys = new PhraseRecognitionEventSys(); 587 eventSys.phraseRecognitionEvent = ConversionUtil.hidl2aidlPhraseRecognitionEvent(event); 588 eventSys.halEventReceivedMillis = SystemClock.elapsedRealtime(); 589 mDelegate.phraseRecognitionCallback(event.common.header.model, eventSys); 590 } 591 592 @Override soundModelCallback_2_1( android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.ModelEvent event, int cookie)593 public void soundModelCallback_2_1( 594 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.ModelEvent event, 595 int cookie) { 596 // Nobody cares. 597 } 598 599 @Override recognitionCallback( android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent event, int cookie)600 public void recognitionCallback( 601 android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent event, 602 int cookie) { 603 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.RecognitionEvent event_2_1 = 604 Hw2CompatUtil.convertRecognitionEvent_2_0_to_2_1(event); 605 recognitionCallback_2_1(event_2_1, cookie); 606 } 607 608 @Override phraseRecognitionCallback( android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent event, int cookie)609 public void phraseRecognitionCallback( 610 android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent event, 611 int cookie) { 612 android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.PhraseRecognitionEvent 613 event_2_1 = Hw2CompatUtil.convertPhraseRecognitionEvent_2_0_to_2_1(event); 614 phraseRecognitionCallback_2_1(event_2_1, cookie); 615 } 616 617 @Override soundModelCallback( android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.ModelEvent event, int cookie)618 public void soundModelCallback( 619 android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.ModelEvent event, 620 int cookie) { 621 // Nobody cares. 622 } 623 } 624 } 625