From 274f05a896330714927f293bc38b5d702605f831 Mon Sep 17 00:00:00 2001 From: Nicholas Ambur Date: Thu, 10 Feb 2022 16:00:32 -0800 Subject: [PATCH] move HotwordDetector ctor work to initialize() new package-private initialize() method is added to AbstractHotwordDetector to perform work which was previously done in the implementing class' ctor. This allows the creator, VoiceInteractionService to control when the initialize work is done after create. This change is apart of a larger topic to allow multiple detectors to be active in parallel. By separating work done in the ctor to another method, we can freely create detectors without impacting the other services it communicates with. This is an internal cleanup, and the client app using the detector will observe no behavior change. Test: atest VoiceInteractionSystemApiTest Bug: 193232191 Change-Id: Ib63cff09e6a0c22fb0f77a0e721637dbb5ae7ed0 --- .../service/voice/AbstractHotwordDetector.java | 7 +++++++ .../service/voice/AlwaysOnHotwordDetector.java | 11 ++++++++--- .../service/voice/SoftwareHotwordDetector.java | 8 ++++++-- .../service/voice/VoiceInteractionService.java | 11 ++++++++--- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java index 01d5638461af8..305995a3d2b77 100644 --- a/core/java/android/service/voice/AbstractHotwordDetector.java +++ b/core/java/android/service/voice/AbstractHotwordDetector.java @@ -64,6 +64,13 @@ abstract class AbstractHotwordDetector implements HotwordDetector { mIsDetectorActive = new AtomicBoolean(true); } + /** + * Method to be called for the detector to ready/register itself with underlying system + * services. + */ + abstract void initialize(@Nullable PersistableBundle options, + @Nullable SharedMemory sharedMemory); + /** * Detect hotword from an externally supplied stream of data. * diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index bec5d1be57fd1..64b66b6a6d42e 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -279,7 +279,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { private KeyphraseMetadata mKeyphraseMetadata; private final KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo; private final IVoiceInteractionManagerService mModelManagementService; - private final IVoiceInteractionSoundTriggerSession mSoundTriggerSession; + private IVoiceInteractionSoundTriggerSession mSoundTriggerSession; private final SoundTriggerListener mInternalCallback; private final Callback mExternalCallback; private final Handler mHandler; @@ -788,8 +788,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback, KeyphraseEnrollmentInfo keyphraseEnrollmentInfo, IVoiceInteractionManagerService modelManagementService, int targetSdkVersion, - boolean supportHotwordDetectionService, @Nullable PersistableBundle options, - @Nullable SharedMemory sharedMemory) { + boolean supportHotwordDetectionService) { super(modelManagementService, callback, supportHotwordDetectionService ? DETECTOR_TYPE_TRUSTED_HOTWORD_DSP : DETECTOR_TYPE_NORMAL); @@ -803,6 +802,12 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector { mModelManagementService = modelManagementService; mTargetSdkVersion = targetSdkVersion; mSupportHotwordDetectionService = supportHotwordDetectionService; + } + + @Override + void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) { + // TODO: transition to use an API that is not updateState to provide + // onHotwordDetectionServiceInitialized status to external callback if (mSupportHotwordDetectionService) { updateStateLocked(options, sharedMemory, mInternalCallback, DETECTOR_TYPE_TRUSTED_HOTWORD_DSP); diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java index 2d662eaf0a4f0..cae9598978e9c 100644 --- a/core/java/android/service/voice/SoftwareHotwordDetector.java +++ b/core/java/android/service/voice/SoftwareHotwordDetector.java @@ -57,8 +57,6 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector { SoftwareHotwordDetector( IVoiceInteractionManagerService managerService, AudioFormat audioFormat, - PersistableBundle options, - SharedMemory sharedMemory, HotwordDetector.Callback callback) { super(managerService, callback, DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE); @@ -66,6 +64,12 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector { mAudioFormat = audioFormat; mCallback = callback; mHandler = new Handler(Looper.getMainLooper()); + } + + @Override + void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) { + // TODO: transition to use an API that is not updateState to provide + // onHotwordDetectionServiceInitialized status to external callback updateStateLocked(options, sharedMemory, new InitializationStateListener(mHandler, mCallback), DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE); diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index bf0cfbe49f31d..88b7a58a57098 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -381,12 +381,15 @@ public class VoiceInteractionService extends Service { synchronized (mLock) { // Allow only one concurrent recognition via the APIs. safelyShutdownAllHotwordDetectors(); - mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback, + + mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, + callback, mKeyphraseEnrollmentInfo, mSystemService, getApplicationContext().getApplicationInfo().targetSdkVersion, - supportHotwordDetectionService, options, sharedMemory); + supportHotwordDetectionService); mHotwordDetector.registerOnDestroyListener((detector) -> onDspHotwordDetectorDestroyed( (AlwaysOnHotwordDetector) detector)); + mHotwordDetector.initialize(options, sharedMemory); } return mHotwordDetector; } @@ -436,12 +439,14 @@ public class VoiceInteractionService extends Service { synchronized (mLock) { // Allow only one concurrent recognition via the APIs. safelyShutdownAllHotwordDetectors(); + mSoftwareHotwordDetector = new SoftwareHotwordDetector( - mSystemService, null, options, sharedMemory, callback); + mSystemService, null, callback); mSoftwareHotwordDetector.registerOnDestroyListener( (detector) -> onMicrophoneHotwordDetectorDestroyed( (SoftwareHotwordDetector) detector)); + mSoftwareHotwordDetector.initialize(options, sharedMemory); } return mSoftwareHotwordDetector; }