diff options
author | Sandeep Siddhartha <sansid@google.com> | 2014-07-31 23:00:10 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-07-24 15:36:21 +0000 |
commit | 90521b282936632e2f2c262ad0f45bfed9e03ea7 (patch) | |
tree | 28f9d60c26d9256f93aed07dffdea85ba9ad8511 | |
parent | 8e554924c527183962fc908c5f916f390f806c74 (diff) | |
parent | 668327d0286591324fa7592ee9b39255076e2165 (diff) | |
download | frameworks_base-90521b282936632e2f2c262ad0f45bfed9e03ea7.zip frameworks_base-90521b282936632e2f2c262ad0f45bfed9e03ea7.tar.gz frameworks_base-90521b282936632e2f2c262ad0f45bfed9e03ea7.tar.bz2 |
Merge "Tighten the checks around a detector being invalidated" into lmp-dev
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | core/java/android/service/voice/AlwaysOnHotwordDetector.java | 66 | ||||
-rw-r--r-- | tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java | 5 |
3 files changed, 60 insertions, 12 deletions
diff --git a/api/current.txt b/api/current.txt index 56b0bf0..74fdd31 100644 --- a/api/current.txt +++ b/api/current.txt @@ -27513,7 +27513,6 @@ package android.service.voice { field public static final int RECOGNITION_MODE_USER_IDENTIFICATION = 2; // 0x2 field public static final int RECOGNITION_MODE_VOICE_TRIGGER = 1; // 0x1 field public static final int STATE_HARDWARE_UNAVAILABLE = -2; // 0xfffffffe - field public static final int STATE_INVALID = -3; // 0xfffffffd field public static final int STATE_KEYPHRASE_ENROLLED = 2; // 0x2 field public static final int STATE_KEYPHRASE_UNENROLLED = 1; // 0x1 field public static final int STATE_KEYPHRASE_UNSUPPORTED = -1; // 0xffffffff diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 3f53ad4..6278e69 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -45,7 +45,8 @@ public class AlwaysOnHotwordDetector { * Indicates that this hotword detector is no longer valid for any recognition * and should not be used anymore. */ - public static final int STATE_INVALID = -3; + private static final int STATE_INVALID = -3; + /** * Indicates that recognition for the given keyphrase is not available on the system * because of the hardware configuration. @@ -156,9 +157,6 @@ public class AlwaysOnHotwordDetector { * If it is {@link #STATE_KEYPHRASE_UNENROLLED} the caller may choose to begin * an enrollment flow for the keyphrase. <br/> * and for {@link #STATE_KEYPHRASE_ENROLLED} a recognition can be started as desired. <p/> - * - * If the return code is {@link #STATE_INVALID}, this detector is stale. - * A new detector should be obtained for use in the future. */ void onAvailabilityChanged(int status); /** @@ -220,6 +218,9 @@ public class AlwaysOnHotwordDetector { * @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 state. + * This may happen if another detector has been instantiated or the + * {@link VoiceInteractionService} hosting this detector has been shut down. */ public int getSupportedRecognitionModes() { synchronized (mLock) { @@ -228,6 +229,11 @@ public class AlwaysOnHotwordDetector { } private int getSupportedRecognitionModesLocked() { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException( + "getSupportedRecognitionModes called on an invalid detector"); + } + // This method only makes sense if we can actually support a recognition. if (mAvailability != STATE_KEYPHRASE_ENROLLED && mAvailability != STATE_KEYPHRASE_UNENROLLED) { @@ -247,9 +253,16 @@ public class AlwaysOnHotwordDetector { * @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 state. + * This may happen if another detector has been instantiated or the + * {@link VoiceInteractionService} hosting this detector has been shut down. */ public void startRecognition(int recognitionFlags) { synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("startRecognition called on an invalid detector"); + } + // Check if we can start/stop a recognition. if (mAvailability != STATE_KEYPHRASE_ENROLLED) { throw new UnsupportedOperationException( @@ -268,9 +281,16 @@ public class AlwaysOnHotwordDetector { * @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 state. + * This may happen if another detector has been instantiated or the + * {@link VoiceInteractionService} hosting this detector has been shut down. */ public void stopRecognition() { synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("stopRecognition called on an invalid detector"); + } + // Check if we can start/stop a recognition. if (mAvailability != STATE_KEYPHRASE_ENROLLED) { throw new UnsupportedOperationException( @@ -293,14 +313,28 @@ public class AlwaysOnHotwordDetector { * @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. */ public Intent getManageIntent(int action) { + synchronized (mLock) { + return getManageIntentLocked(action); + } + } + + private Intent getManageIntentLocked(int action) { + if (mAvailability == STATE_INVALID) { + throw new IllegalStateException("getManageIntent called on an invalid detector"); + } + // This method only makes sense if we can actually support a recognition. if (mAvailability != STATE_KEYPHRASE_ENROLLED && mAvailability != STATE_KEYPHRASE_UNENROLLED) { throw new UnsupportedOperationException( "Managing the given keyphrase is not supported"); } + if (action != MANAGE_ACTION_ENROLL && action != MANAGE_ACTION_RE_ENROLL && action != MANAGE_ACTION_UN_ENROLL) { @@ -387,7 +421,6 @@ public class AlwaysOnHotwordDetector { if (DBG) Slog.d(TAG, "starting recognition..."); int status = startRecognitionLocked(); if (status == STATUS_OK) { - mInternalState |= FLAG_STARTED; mHandler.sendEmptyMessage(MSG_DETECTION_STARTED); } else { if (DBG) Slog.d(TAG, "failed to start recognition: " + status); @@ -404,7 +437,6 @@ public class AlwaysOnHotwordDetector { if (DBG) Slog.d(TAG, "stopping recognition..."); int status = stopRecognitionLocked(); if (status == STATUS_OK) { - mInternalState &= ~FLAG_STARTED; if (!requested) mHandler.sendEmptyMessage(MSG_DETECTION_STOPPED); } else { if (!requested) mHandler.sendEmptyMessage(MSG_DETECTION_ERROR); @@ -483,20 +515,42 @@ public class AlwaysOnHotwordDetector { class MyHandler extends Handler { @Override public void handleMessage(Message msg) { + synchronized (mLock) { + if (mAvailability == STATE_INVALID) { + Slog.w(TAG, "Received message: " + msg.what + " for an invalid detector"); + return; + } + } + switch (msg.what) { case MSG_STATE_CHANGED: mExternalCallback.onAvailabilityChanged(msg.arg1); break; case MSG_HOTWORD_DETECTED: + synchronized (mLock) { + mInternalState &= ~FLAG_REQUESTED; + mInternalState &= ~FLAG_STARTED; + } mExternalCallback.onDetected((byte[]) msg.obj); break; case MSG_DETECTION_STARTED: + synchronized (mLock) { + mInternalState |= FLAG_STARTED; + } mExternalCallback.onDetectionStarted(); break; case MSG_DETECTION_STOPPED: + synchronized (mLock) { + mInternalState &= ~FLAG_REQUESTED; + mInternalState &= ~FLAG_STARTED; + } mExternalCallback.onDetectionStopped(); break; case MSG_DETECTION_ERROR: + synchronized (mLock) { + mInternalState &= ~FLAG_REQUESTED; + mInternalState &= ~FLAG_STARTED; + } mExternalCallback.onError(); break; default: diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java index 49c3d0a..b43ad6f 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java @@ -81,11 +81,6 @@ public class MainInteractionService extends VoiceInteractionService { private void hotwordAvailabilityChangeHelper(int availability) { Log.i(TAG, "Hotword availability = " + availability); switch (availability) { - case AlwaysOnHotwordDetector.STATE_INVALID: - Log.i(TAG, "STATE_INVALID"); - mHotwordDetector = - createAlwaysOnHotwordDetector("Hello There", "en-US", mHotwordCallback); - break; case AlwaysOnHotwordDetector.STATE_HARDWARE_UNAVAILABLE: Log.i(TAG, "STATE_HARDWARE_UNAVAILABLE"); break; |