summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandeep Siddhartha <sansid@google.com>2014-07-31 23:00:10 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-24 15:36:21 +0000
commit90521b282936632e2f2c262ad0f45bfed9e03ea7 (patch)
tree28f9d60c26d9256f93aed07dffdea85ba9ad8511
parent8e554924c527183962fc908c5f916f390f806c74 (diff)
parent668327d0286591324fa7592ee9b39255076e2165 (diff)
downloadframeworks_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.txt1
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java66
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java5
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;