Merge "Revert "update HotwordDetector exception throws"" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
05bd77c0b4
@@ -12993,20 +12993,20 @@ package android.service.trust {
|
||||
package android.service.voice {
|
||||
|
||||
public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
|
||||
method @Nullable public android.content.Intent createEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @Nullable public android.content.Intent createReEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @Nullable public android.content.Intent createUnEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @Nullable public android.content.Intent createEnrollIntent();
|
||||
method @Nullable public android.content.Intent createReEnrollIntent();
|
||||
method @Nullable public android.content.Intent createUnEnrollIntent();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int);
|
||||
method public int getSupportedAudioCapabilities();
|
||||
method public int getSupportedRecognitionModes() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int, @NonNull byte[]) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public int getSupportedRecognitionModes();
|
||||
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int, @NonNull byte[]);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
|
||||
method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition();
|
||||
method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
|
||||
field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
|
||||
field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
|
||||
field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
|
||||
@@ -13185,10 +13185,10 @@ package android.service.voice {
|
||||
|
||||
public interface HotwordDetector {
|
||||
method public default void destroy();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
|
||||
method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
|
||||
method public boolean stopRecognition();
|
||||
method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
|
||||
}
|
||||
|
||||
public static interface HotwordDetector.Callback {
|
||||
@@ -13202,9 +13202,6 @@ package android.service.voice {
|
||||
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
|
||||
}
|
||||
|
||||
public static class HotwordDetector.IllegalDetectorStateException extends android.util.AndroidException {
|
||||
}
|
||||
|
||||
public final class HotwordRejectedResult implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method public int getConfidenceLevel();
|
||||
@@ -13272,9 +13269,9 @@ package android.service.voice {
|
||||
|
||||
public class VisualQueryDetector {
|
||||
method public void destroy();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean startRecognition();
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean stopRecognition();
|
||||
method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
|
||||
}
|
||||
|
||||
public static interface VisualQueryDetector.Callback {
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityThread;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.permission.Identity;
|
||||
import android.os.Binder;
|
||||
@@ -100,7 +99,7 @@ abstract class AbstractDetector implements HotwordDetector {
|
||||
public boolean startRecognition(
|
||||
@NonNull ParcelFileDescriptor audioStream,
|
||||
@NonNull AudioFormat audioFormat,
|
||||
@Nullable PersistableBundle options) throws IllegalDetectorStateException {
|
||||
@Nullable PersistableBundle options) {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "#recognizeHotword");
|
||||
}
|
||||
@@ -132,18 +131,13 @@ abstract class AbstractDetector implements HotwordDetector {
|
||||
* @param sharedMemory The unrestricted data blob to provide to the
|
||||
* {@link VisualQueryDetectionService} and {@link HotwordDetectionService}. Use this to
|
||||
* provide the hotword models data or other such data to the trusted process.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
|
||||
* Android Tiramisu or above and attempts to start a recognition when the detector is
|
||||
* not able based on the state. Because the caller receives updates via an asynchronous
|
||||
* callback and the state of the detector can change without caller's knowledge, a
|
||||
* checked exception is thrown.
|
||||
* @throws IllegalStateException if this {@link HotwordDetector} wasn't specified to use a
|
||||
* {@link HotwordDetectionService} or {@link VisualQueryDetectionService} when it was
|
||||
* created.
|
||||
*/
|
||||
@Override
|
||||
public void updateState(@Nullable PersistableBundle options,
|
||||
@Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
|
||||
@Nullable SharedMemory sharedMemory) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "updateState()");
|
||||
}
|
||||
@@ -199,13 +193,9 @@ abstract class AbstractDetector implements HotwordDetector {
|
||||
}
|
||||
}
|
||||
|
||||
protected void throwIfDetectorIsNoLongerActive() throws IllegalDetectorStateException {
|
||||
protected void throwIfDetectorIsNoLongerActive() {
|
||||
if (!mIsDetectorActive.get()) {
|
||||
Slog.e(TAG, "attempting to use a destroyed detector which is no longer active");
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"attempting to use a destroyed detector which is no longer active");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"attempting to use a destroyed detector which is no longer active");
|
||||
}
|
||||
|
||||
@@ -827,28 +827,19 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and this AlwaysOnHotwordDetector wasn't specified to use a
|
||||
* {@link HotwordDetectionService} when it was created. In addition, the exception can
|
||||
* be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
|
||||
* this AlwaysOnHotwordDetector wasn't specified to use a
|
||||
* {@link HotwordDetectionService} when it was created. In addition, the exception can
|
||||
* be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
|
||||
* @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
|
||||
* {@link HotwordDetectionService} when it was created. In addition, if this
|
||||
* AlwaysOnHotwordDetector is in an invalid or error state.
|
||||
*/
|
||||
@Override
|
||||
public final void updateState(@Nullable PersistableBundle options,
|
||||
@Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
|
||||
@Nullable SharedMemory sharedMemory) {
|
||||
synchronized (mLock) {
|
||||
if (!mSupportSandboxedDetectionService) {
|
||||
throw new IllegalStateException(
|
||||
"updateState called, but it doesn't support hotword detection service");
|
||||
}
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"updateState called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"updateState called on an invalid detector or error state");
|
||||
}
|
||||
@@ -869,17 +860,16 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
@TestApi
|
||||
public void overrideAvailability(int availability) {
|
||||
synchronized (mLock) {
|
||||
mAvailability = availability;
|
||||
mIsAvailabilityOverriddenByTestApi = true;
|
||||
// ENROLLED state requires there to be metadata about the sound model so a fake one
|
||||
// is created.
|
||||
if (mKeyphraseMetadata == null && availability == STATE_KEYPHRASE_ENROLLED) {
|
||||
if (mKeyphraseMetadata == null && mAvailability == STATE_KEYPHRASE_ENROLLED) {
|
||||
Set<Locale> fakeSupportedLocales = new HashSet<>();
|
||||
fakeSupportedLocales.add(mLocale);
|
||||
mKeyphraseMetadata = new KeyphraseMetadata(1, mText, fakeSupportedLocales,
|
||||
AlwaysOnHotwordDetector.RECOGNITION_MODE_VOICE_TRIGGER);
|
||||
}
|
||||
|
||||
mAvailability = availability;
|
||||
mIsAvailabilityOverriddenByTestApi = true;
|
||||
notifyStateChangedLocked();
|
||||
}
|
||||
}
|
||||
@@ -935,23 +925,14 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* @see #RECOGNITION_MODE_USER_IDENTIFICATION
|
||||
* @see #RECOGNITION_MODE_VOICE_TRIGGER
|
||||
*
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above. Because the caller receives availability updates via an asynchronous
|
||||
* callback, it may be due to the availability changing while this call is performed.
|
||||
* - Throws if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 Android if the recognition isn't supported. Callers should only call this method
|
||||
* after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
|
||||
* avoid this exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
|
||||
* 33 if the detector is in an invalid or error state. This may happen if another
|
||||
* detector has been instantiated or the {@link VoiceInteractionService} hosting this
|
||||
* detector has been shut down.
|
||||
* @throws UnsupportedOperationException if the keyphrase itself isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
public @RecognitionModes
|
||||
int getSupportedRecognitionModes() throws IllegalDetectorStateException {
|
||||
public @RecognitionModes int getSupportedRecognitionModes() {
|
||||
if (DBG) Slog.d(TAG, "getSupportedRecognitionModes()");
|
||||
synchronized (mLock) {
|
||||
return getSupportedRecognitionModesLocked();
|
||||
@@ -959,22 +940,14 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private int getSupportedRecognitionModesLocked() throws IllegalDetectorStateException {
|
||||
private int getSupportedRecognitionModesLocked() {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException("getSupportedRecognitionModes called on an"
|
||||
+ " invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"getSupportedRecognitionModes called on an invalid detector or error state");
|
||||
}
|
||||
|
||||
// This method only makes sense if we can actually support a recognition.
|
||||
if (mAvailability != STATE_KEYPHRASE_ENROLLED || mKeyphraseMetadata == null) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException("Getting supported recognition modes for"
|
||||
+ " the keyphrase is not supported");
|
||||
}
|
||||
throw new UnsupportedOperationException(
|
||||
"Getting supported recognition modes for the keyphrase is not supported");
|
||||
}
|
||||
@@ -1029,30 +1002,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* startRecognition request. This data is intended to provide additional parameters
|
||||
* when starting the opaque sound model.
|
||||
* @return Indicates whether the call succeeded or not.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and attempts to start a recognition when the detector is not able based on
|
||||
* the availability state. This can be thrown even if the state has been checked before
|
||||
* calling this method because the caller receives availability updates via an
|
||||
* asynchronous callback, it may be due to the availability changing while this call is
|
||||
* performed.
|
||||
* - Throws if the recognition isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* - Also throws if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 Android if the recognition isn't supported. Callers should only call this method
|
||||
* after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
|
||||
* avoid this exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
|
||||
* 33 if the detector is in an invalid or error state. This may happen if another
|
||||
* detector has been instantiated or the {@link VoiceInteractionService} hosting this
|
||||
* detector has been shut down.
|
||||
* @throws UnsupportedOperationException if the recognition isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
public boolean startRecognition(@RecognitionFlags int recognitionFlags, @NonNull byte[] data)
|
||||
throws IllegalDetectorStateException {
|
||||
public boolean startRecognition(@RecognitionFlags int recognitionFlags, @NonNull byte[] data) {
|
||||
synchronized (mLock) {
|
||||
return startRecognitionLocked(recognitionFlags, data)
|
||||
== STATUS_OK;
|
||||
@@ -1069,30 +1027,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
*
|
||||
* @param recognitionFlags The flags to control the recognition properties.
|
||||
* @return Indicates whether the call succeeded or not.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and attempts to start a recognition when the detector is not able based on
|
||||
* the availability state. This can be thrown even if the state has been checked before
|
||||
* calling this method because the caller receives availability updates via an
|
||||
* asynchronous callback, it may be due to the availability changing while this call is
|
||||
* performed.
|
||||
* - Throws if the recognition isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* - Also throws if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 if the recognition isn't supported. Callers should only call this method after a
|
||||
* supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
|
||||
* exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid or error state. This may happen if another detector has
|
||||
* been instantiated or the {@link VoiceInteractionService} hosting this detector has
|
||||
* been shut down.
|
||||
* @throws UnsupportedOperationException if the recognition isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
public boolean startRecognition(@RecognitionFlags int recognitionFlags)
|
||||
throws IllegalDetectorStateException {
|
||||
public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
|
||||
if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
|
||||
synchronized (mLock) {
|
||||
return startRecognitionLocked(recognitionFlags, null /* data */) == STATUS_OK;
|
||||
@@ -1106,8 +1049,7 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
@Override
|
||||
public boolean startRecognition()
|
||||
throws IllegalDetectorStateException {
|
||||
public boolean startRecognition() {
|
||||
return startRecognition(0);
|
||||
}
|
||||
|
||||
@@ -1117,44 +1059,28 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* Settings.Secure.VOICE_INTERACTION_SERVICE.
|
||||
*
|
||||
* @return Indicates whether the call succeeded or not.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
|
||||
* API level 33 or above and attempts to stop a recognition when the detector is
|
||||
* not able based on the state. This can be thrown even if the state has been checked
|
||||
* before calling this method because the caller receives availability updates via an
|
||||
* asynchronous callback, it may be due to the availability changing while this call is
|
||||
* performed.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 if the recognition isn't supported. Callers should only call this method after a
|
||||
* supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
|
||||
* exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid or error state. This may happen if another detector has
|
||||
* been instantiated or the {@link VoiceInteractionService} hosting this detector has
|
||||
* been shut down.
|
||||
* @throws UnsupportedOperationException if the recognition isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
// TODO: Remove this RequiresPermission since it isn't actually enforced. Also fix the javadoc
|
||||
// about permissions enforcement (when it throws vs when it just returns false) for other
|
||||
// methods in this class.
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
@Override
|
||||
public boolean stopRecognition() throws IllegalDetectorStateException {
|
||||
public boolean stopRecognition() {
|
||||
if (DBG) Slog.d(TAG, "stopRecognition()");
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"stopRecognition called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"stopRecognition called on an invalid detector or error state");
|
||||
}
|
||||
|
||||
// Check if we can start/stop a recognition.
|
||||
if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"Recognition for the given keyphrase is not supported");
|
||||
}
|
||||
throw new UnsupportedOperationException(
|
||||
"Recognition for the given keyphrase is not supported");
|
||||
}
|
||||
@@ -1179,28 +1105,18 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter
|
||||
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or
|
||||
* if API is not supported by HAL
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* if the detector is in an invalid or error state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid or error state. This may happen if another detector has
|
||||
* been instantiated or the {@link VoiceInteractionService} hosting this detector has
|
||||
* been shut down.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
public int setParameter(@ModelParams int modelParam, int value)
|
||||
throws IllegalDetectorStateException {
|
||||
public int setParameter(@ModelParams int modelParam, int value) {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "setParameter(" + modelParam + ", " + value + ")");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"setParameter called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"setParameter called on an invalid detector or error state");
|
||||
}
|
||||
@@ -1221,27 +1137,18 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
*
|
||||
* @param modelParam {@link ModelParams}
|
||||
* @return value of parameter
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* if the detector is in an invalid or error state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
|
||||
* the detector is in an invalid or error state. This may happen if another detector has
|
||||
* been instantiated or the {@link VoiceInteractionService} hosting this detector has
|
||||
* been shut down.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
public int getParameter(@ModelParams int modelParam) throws IllegalDetectorStateException {
|
||||
public int getParameter(@ModelParams int modelParam) {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "getParameter(" + modelParam + ")");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"getParameter called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"getParameter called on an invalid detector or error state");
|
||||
}
|
||||
@@ -1259,29 +1166,19 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
*
|
||||
* @param modelParam {@link ModelParams}
|
||||
* @return supported range of parameter, null if not supported
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* if the detector is in an invalid or error state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
|
||||
* the detector is in an invalid or error state. This may happen if another detector has
|
||||
* been instantiated or the {@link VoiceInteractionService} hosting this detector has
|
||||
* been shut down.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
@Nullable
|
||||
public ModelParamRange queryParameter(@ModelParams int modelParam)
|
||||
throws IllegalDetectorStateException {
|
||||
public ModelParamRange queryParameter(@ModelParams int modelParam) {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "queryParameter(" + modelParam + ")");
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"queryParameter called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"queryParameter called on an invalid detector or error state");
|
||||
}
|
||||
@@ -1298,25 +1195,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* otherwise {@link #createReEnrollIntent()} should be preferred.
|
||||
*
|
||||
* @return An {@link Intent} to start enrollment for the given keyphrase.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above.
|
||||
* - Thrown if managing they keyphrase isn't supported. Callers should only call this
|
||||
* method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* - Thrown if the detector is in an invalid state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 if managing they keyphrase isn't supported. Callers should only call this method
|
||||
* after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
|
||||
* avoid this exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid state. This may happen if another detector has been
|
||||
* instantiated or the {@link VoiceInteractionService} hosting this detector has been
|
||||
* shut down.
|
||||
* @throws UnsupportedOperationException if managing they keyphrase isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@Nullable
|
||||
public Intent createEnrollIntent() throws IllegalDetectorStateException {
|
||||
public Intent createEnrollIntent() {
|
||||
if (DBG) Slog.d(TAG, "createEnrollIntent");
|
||||
synchronized (mLock) {
|
||||
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_ENROLL);
|
||||
@@ -1330,25 +1217,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
|
||||
*
|
||||
* @return An {@link Intent} to start un-enrollment for the given keyphrase.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above.
|
||||
* - Thrown if managing they keyphrase isn't supported. Callers should only call this
|
||||
* method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* - Thrown if the detector is in an invalid state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 if managing they keyphrase isn't supported. Callers should only call this method
|
||||
* after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
|
||||
* avoid this exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid state. This may happen if another detector has been
|
||||
* instantiated or the {@link VoiceInteractionService} hosting this detector has been
|
||||
* shut down.
|
||||
* @throws UnsupportedOperationException if managing they keyphrase isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@Nullable
|
||||
public Intent createUnEnrollIntent() throws IllegalDetectorStateException {
|
||||
public Intent createUnEnrollIntent() {
|
||||
if (DBG) Slog.d(TAG, "createUnEnrollIntent");
|
||||
synchronized (mLock) {
|
||||
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_UN_ENROLL);
|
||||
@@ -1362,25 +1239,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
* i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
|
||||
*
|
||||
* @return An {@link Intent} to start re-enrollment for the given keyphrase.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above.
|
||||
* - Thrown if managing they keyphrase isn't supported. Callers should only call this
|
||||
* method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* - Thrown if the detector is in an invalid state. This may happen if another detector
|
||||
* has been instantiated or the {@link VoiceInteractionService} hosting this detector
|
||||
* has been shut down.
|
||||
* @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
|
||||
* 33 if managing they keyphrase isn't supported. Callers should only call this method
|
||||
* after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
|
||||
* avoid this exception.
|
||||
* @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
|
||||
* detector is in an invalid state. This may happen if another detector has been
|
||||
* instantiated or the {@link VoiceInteractionService} hosting this detector has been
|
||||
* shut down.
|
||||
* @throws UnsupportedOperationException if managing they keyphrase isn't supported.
|
||||
* Callers should only call this method after a supported state callback on
|
||||
* {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
|
||||
* @throws IllegalStateException if the detector is in an invalid or error state.
|
||||
* This may happen if another detector has been instantiated or the
|
||||
* {@link VoiceInteractionService} hosting this detector has been shut down.
|
||||
*/
|
||||
@Nullable
|
||||
public Intent createReEnrollIntent() throws IllegalDetectorStateException {
|
||||
public Intent createReEnrollIntent() {
|
||||
if (DBG) Slog.d(TAG, "createReEnrollIntent");
|
||||
synchronized (mLock) {
|
||||
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_RE_ENROLL);
|
||||
@@ -1388,24 +1255,15 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action)
|
||||
throws IllegalDetectorStateException {
|
||||
private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action) {
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"getManageIntent called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"getManageIntent called on an invalid detector or error state");
|
||||
"getManageIntent called on an invalid detector or error state");
|
||||
}
|
||||
|
||||
// This method only makes sense if we can actually support a recognition.
|
||||
if (mAvailability != STATE_KEYPHRASE_ENROLLED
|
||||
&& mAvailability != STATE_KEYPHRASE_UNENROLLED) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"Managing the given keyphrase is not supported");
|
||||
}
|
||||
throw new UnsupportedOperationException(
|
||||
"Managing the given keyphrase is not supported");
|
||||
}
|
||||
@@ -1489,27 +1347,19 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private int startRecognitionLocked(int recognitionFlags,
|
||||
@Nullable byte[] data) throws IllegalDetectorStateException {
|
||||
@Nullable byte[] data) {
|
||||
if (DBG) {
|
||||
Slog.d(TAG, "startRecognition("
|
||||
+ recognitionFlags
|
||||
+ ", " + Arrays.toString(data) + ")");
|
||||
}
|
||||
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"startRecognition called on an invalid detector or error state");
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"startRecognition called on an invalid detector or error state");
|
||||
}
|
||||
|
||||
// Check if we can start/stop a recognition.
|
||||
if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
|
||||
if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
|
||||
throw new IllegalDetectorStateException(
|
||||
"Recognition for the given keyphrase is not supported");
|
||||
}
|
||||
throw new UnsupportedOperationException(
|
||||
"Recognition for the given keyphrase is not supported");
|
||||
}
|
||||
|
||||
@@ -23,14 +23,10 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.media.AudioFormat;
|
||||
import android.os.Build;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.SharedMemory;
|
||||
import android.util.AndroidException;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@@ -43,23 +39,6 @@ import java.io.PrintWriter;
|
||||
@SystemApi
|
||||
public interface HotwordDetector {
|
||||
|
||||
/**
|
||||
* Prior to API level 33, API calls of {@link android.service.voice.HotwordDetector} could
|
||||
* return both {@link java.lang.IllegalStateException} or
|
||||
* {@link java.lang.UnsupportedOperationException} depending on the detector's underlying state.
|
||||
* This lead to confusing behavior as the underlying state of the detector can be modified
|
||||
* without the knowledge of the caller via system service layer updates.
|
||||
*
|
||||
* This change ID, when enabled, changes the API calls to only throw checked exception
|
||||
* {@link android.service.voice.HotwordDetector.IllegalDetectorStateException} when checking
|
||||
* against state information modified by both the caller and the system services.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
|
||||
long HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION = 226355112L;
|
||||
|
||||
/**
|
||||
* Indicates that it is a non-trusted hotword detector.
|
||||
*
|
||||
@@ -109,26 +88,16 @@ public interface HotwordDetector {
|
||||
* Calling this again while recognition is active does nothing.
|
||||
*
|
||||
* @return {@code true} if the request to start recognition succeeded
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and attempts to start a recognition when the detector is not able based on
|
||||
* the state. This can be thrown even if the state has been checked before calling this
|
||||
* method because the caller receives updates via an asynchronous callback, and the
|
||||
* state of the detector can change concurrently to the caller calling this method.
|
||||
*/
|
||||
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
|
||||
boolean startRecognition() throws IllegalDetectorStateException;
|
||||
boolean startRecognition();
|
||||
|
||||
/**
|
||||
* Stops sandboxed detection recognition.
|
||||
*
|
||||
* @return {@code true} if the request to stop recognition succeeded
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and attempts to stop a recognition when the detector is not able based on
|
||||
* the state. This can be thrown even if the state has been checked before calling this
|
||||
* method because the caller receives updates via an asynchronous callback, and the
|
||||
* state of the detector can change concurrently to the caller calling this method.
|
||||
*/
|
||||
boolean stopRecognition() throws IllegalDetectorStateException;
|
||||
boolean stopRecognition();
|
||||
|
||||
/**
|
||||
* Starts hotword recognition on audio coming from an external connected microphone.
|
||||
@@ -142,16 +111,11 @@ public interface HotwordDetector {
|
||||
* PersistableBundle does not allow any remotable objects or other contents that can be
|
||||
* used to communicate with other processes.
|
||||
* @return {@code true} if the request to start recognition succeeded
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and attempts to start a recognition when the detector is not able based on
|
||||
* the state. This can be thrown even if the state has been checked before calling this
|
||||
* method because the caller receives updates via an asynchronous callback, and the
|
||||
* state of the detector can change concurrently to the caller calling this method.
|
||||
*/
|
||||
boolean startRecognition(
|
||||
@NonNull ParcelFileDescriptor audioStream,
|
||||
@NonNull AudioFormat audioFormat,
|
||||
@Nullable PersistableBundle options) throws IllegalDetectorStateException;
|
||||
@Nullable PersistableBundle options);
|
||||
|
||||
/**
|
||||
* Set configuration and pass read-only data to sandboxed detection service.
|
||||
@@ -161,17 +125,10 @@ public interface HotwordDetector {
|
||||
* communicate with other processes.
|
||||
* @param sharedMemory The unrestricted data blob to provide to sandboxed detection services.
|
||||
* Use this to provide model data or other such data to the trusted process.
|
||||
* @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
|
||||
* or above and the detector is not able to perform the operation based on the
|
||||
* underlying state. This can be thrown even if the state has been checked before
|
||||
* calling this method because the caller receives updates via an asynchronous callback,
|
||||
* and the state of the detector can change concurrently to the caller calling this
|
||||
* method.
|
||||
* @throws IllegalStateException if this HotwordDetector wasn't specified to use a
|
||||
* sandboxed detection service when it was created.
|
||||
*/
|
||||
void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory)
|
||||
throws IllegalDetectorStateException;
|
||||
void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory);
|
||||
|
||||
/**
|
||||
* Invalidates this detector so that any future calls to this result
|
||||
@@ -298,14 +255,4 @@ public interface HotwordDetector {
|
||||
*/
|
||||
void onHotwordDetectionServiceRestarted();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HotwordDetector} specific exception thrown when the underlying state of the detector
|
||||
* is invalid for the given action.
|
||||
*/
|
||||
class IllegalDetectorStateException extends AndroidException {
|
||||
IllegalDetectorStateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class SoftwareHotwordDetector extends AbstractDetector {
|
||||
|
||||
@RequiresPermission(RECORD_AUDIO)
|
||||
@Override
|
||||
public boolean startRecognition() throws IllegalDetectorStateException {
|
||||
public boolean startRecognition() {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "#startRecognition");
|
||||
}
|
||||
@@ -109,7 +109,7 @@ class SoftwareHotwordDetector extends AbstractDetector {
|
||||
/** TODO: stopRecognition */
|
||||
@RequiresPermission(RECORD_AUDIO)
|
||||
@Override
|
||||
public boolean stopRecognition() throws IllegalDetectorStateException {
|
||||
public boolean stopRecognition() {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "#stopRecognition");
|
||||
}
|
||||
|
||||
@@ -84,8 +84,7 @@ public class VisualQueryDetector {
|
||||
* @see HotwordDetector#updateState(PersistableBundle, SharedMemory)
|
||||
*/
|
||||
public void updateState(@Nullable PersistableBundle options,
|
||||
@Nullable SharedMemory sharedMemory) throws
|
||||
HotwordDetector.IllegalDetectorStateException {
|
||||
@Nullable SharedMemory sharedMemory) {
|
||||
mInitializationDelegate.updateState(options, sharedMemory);
|
||||
}
|
||||
|
||||
@@ -104,7 +103,7 @@ public class VisualQueryDetector {
|
||||
* @see HotwordDetector#startRecognition()
|
||||
*/
|
||||
@RequiresPermission(allOf = {CAMERA, RECORD_AUDIO})
|
||||
public boolean startRecognition() throws HotwordDetector.IllegalDetectorStateException {
|
||||
public boolean startRecognition() {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "#startRecognition");
|
||||
}
|
||||
@@ -128,7 +127,7 @@ public class VisualQueryDetector {
|
||||
* @see HotwordDetector#stopRecognition()
|
||||
*/
|
||||
@RequiresPermission(allOf = {CAMERA, RECORD_AUDIO})
|
||||
public boolean stopRecognition() throws HotwordDetector.IllegalDetectorStateException {
|
||||
public boolean stopRecognition() {
|
||||
if (DEBUG) {
|
||||
Slog.i(TAG, "#stopRecognition");
|
||||
}
|
||||
@@ -236,13 +235,13 @@ public class VisualQueryDetector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopRecognition() throws IllegalDetectorStateException {
|
||||
public boolean stopRecognition() {
|
||||
throwIfDetectorIsNoLongerActive();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startRecognition() throws IllegalDetectorStateException {
|
||||
public boolean startRecognition() {
|
||||
throwIfDetectorIsNoLongerActive();
|
||||
return true;
|
||||
}
|
||||
@@ -251,7 +250,7 @@ public class VisualQueryDetector {
|
||||
public final boolean startRecognition(
|
||||
@NonNull ParcelFileDescriptor audioStream,
|
||||
@NonNull AudioFormat audioFormat,
|
||||
@Nullable PersistableBundle options) throws IllegalDetectorStateException {
|
||||
@Nullable PersistableBundle options) {
|
||||
//No-op, not supported by VisualQueryDetector as it should be trusted.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.content.Intent;
|
||||
import android.service.voice.AlwaysOnHotwordDetector;
|
||||
import android.service.voice.AlwaysOnHotwordDetector.Callback;
|
||||
import android.service.voice.AlwaysOnHotwordDetector.EventPayload;
|
||||
import android.service.voice.HotwordDetector;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -84,24 +83,16 @@ public class MainInteractionService extends VoiceInteractionService {
|
||||
break;
|
||||
case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNENROLLED:
|
||||
Log.i(TAG, "STATE_KEYPHRASE_UNENROLLED");
|
||||
try {
|
||||
Intent enroll = mHotwordDetector.createEnrollIntent();
|
||||
Log.i(TAG, "Need to enroll with " + enroll);
|
||||
} catch (HotwordDetector.IllegalDetectorStateException e) {
|
||||
Log.e(TAG, "createEnrollIntent failed", e);
|
||||
}
|
||||
Intent enroll = mHotwordDetector.createEnrollIntent();
|
||||
Log.i(TAG, "Need to enroll with " + enroll);
|
||||
break;
|
||||
case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
|
||||
Log.i(TAG, "STATE_KEYPHRASE_ENROLLED - starting recognition");
|
||||
try {
|
||||
if (mHotwordDetector.startRecognition(
|
||||
AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
|
||||
Log.i(TAG, "startRecognition succeeded");
|
||||
} else {
|
||||
Log.i(TAG, "startRecognition failed");
|
||||
}
|
||||
} catch (HotwordDetector.IllegalDetectorStateException e) {
|
||||
Log.e(TAG, "startRecognition failed", e);
|
||||
if (mHotwordDetector.startRecognition(
|
||||
AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
|
||||
Log.i(TAG, "startRecognition succeeded");
|
||||
} else {
|
||||
Log.i(TAG, "startRecognition failed");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user