summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl30
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java16
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java15
-rw-r--r--core/java/android/service/voice/SoundTriggerFailure.java21
-rw-r--r--core/java/android/service/voice/VisualQueryDetector.java11
-rw-r--r--core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl17
-rw-r--r--media/java/android/media/soundtrigger/SoundTriggerDetector.java43
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java62
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java28
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java28
10 files changed, 177 insertions, 94 deletions
diff --git a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
index dcc336966810..466373030c78 100644
--- a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
+++ b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl
@@ -42,12 +42,6 @@ oneway interface IRecognitionStatusCallback {
void onGenericSoundTriggerDetected(in SoundTrigger.GenericRecognitionEvent recognitionEvent);
/**
- * Called when the detection fails due to an error.
- *
- * @param status The error code that was seen.
- */
- void onError(int status);
- /**
* Called when the recognition is paused temporarily for some reason.
*/
void onRecognitionPaused();
@@ -55,4 +49,28 @@ oneway interface IRecognitionStatusCallback {
* Called when the recognition is resumed after it was temporarily paused.
*/
void onRecognitionResumed();
+
+ // Error callbacks to follow
+ /**
+ * Called when this recognition has been preempted by another.
+ */
+ void onPreempted();
+
+ /**
+ * Called when the underlying ST module service has died.
+ */
+ void onModuleDied();
+
+ /**
+ * Called when the service failed to gracefully resume recognition following a pause.
+ * @param status - The received error code.
+ */
+ void onResumeFailed(int status);
+
+ /**
+ * Called when the service failed to pause recognition when required.
+ * TODO(b/276507281) Remove. This should never happen, so we should abort instead.
+ * @param status - The received error code.
+ */
+ void onPauseFailed(int status);
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index 8688a18880b7..24c96eae03cb 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -1573,16 +1573,6 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
}
@Override
- public void onError(int status) {
- Slog.i(TAG, "onError: " + status);
- // TODO(b/271534248): This is a workaround before the sound trigger uses the new error
- // method.
- Message.obtain(mHandler, MSG_DETECTION_SOUND_TRIGGER_FAILURE,
- new SoundTriggerFailure(SoundTriggerFailure.ERROR_CODE_UNKNOWN,
- "Sound trigger error")).sendToTarget();
- }
-
- @Override
public void onHotwordDetectionServiceFailure(
HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
Slog.v(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
@@ -1605,6 +1595,12 @@ public class AlwaysOnHotwordDetector extends AbstractDetector {
}
@Override
+ public void onSoundTriggerFailure(SoundTriggerFailure soundTriggerFailure) {
+ Message.obtain(mHandler, MSG_DETECTION_SOUND_TRIGGER_FAILURE,
+ Objects.requireNonNull(soundTriggerFailure)).sendToTarget();
+ }
+
+ @Override
public void onUnknownFailure(String errorMessage) throws RemoteException {
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE,
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index eac7aee43859..7ab4fafcf312 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -234,14 +234,6 @@ class SoftwareHotwordDetector extends AbstractDetector {
}
@Override
- public void onError(int status) throws RemoteException {
- if (DEBUG) {
- Slog.i(TAG, "Ignored #onError (" + status + ") event");
- }
- // TODO: Check if we still need to implement this method with DetectorFailure mechanism.
- }
-
- @Override
public void onHotwordDetectionServiceFailure(
HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
throws RemoteException {
@@ -265,6 +257,13 @@ class SoftwareHotwordDetector extends AbstractDetector {
}
@Override
+ public void onSoundTriggerFailure(SoundTriggerFailure onSoundTriggerFailure)
+ throws RemoteException {
+ // It should never be called here.
+ Slog.wtf(TAG, "Unexpected STFailure in software detector: " + onSoundTriggerFailure);
+ }
+
+ @Override
public void onUnknownFailure(String errorMessage) throws RemoteException {
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
diff --git a/core/java/android/service/voice/SoundTriggerFailure.java b/core/java/android/service/voice/SoundTriggerFailure.java
index 5560800a373f..2ce5e5da4724 100644
--- a/core/java/android/service/voice/SoundTriggerFailure.java
+++ b/core/java/android/service/voice/SoundTriggerFailure.java
@@ -73,18 +73,28 @@ public final class SoundTriggerFailure implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface SoundTriggerErrorCode {}
- private int mErrorCode = ERROR_CODE_UNKNOWN;
- private String mErrorMessage = "Unknown";
+ private final int mErrorCode;
+ private final String mErrorMessage;
/**
* @hide
*/
@TestApi
- public SoundTriggerFailure(int errorCode, @NonNull String errorMessage) {
+ public SoundTriggerFailure(@SoundTriggerErrorCode int errorCode,
+ @NonNull String errorMessage) {
if (TextUtils.isEmpty(errorMessage)) {
throw new IllegalArgumentException("errorMessage is empty or null.");
}
- mErrorCode = errorCode;
+ switch (errorCode) {
+ case ERROR_CODE_UNKNOWN:
+ case ERROR_CODE_MODULE_DIED:
+ case ERROR_CODE_RECOGNITION_RESUME_FAILED:
+ case ERROR_CODE_UNEXPECTED_PREEMPTION:
+ mErrorCode = errorCode;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid ErrorCode: " + errorCode);
+ }
mErrorMessage = errorMessage;
}
@@ -110,13 +120,14 @@ public final class SoundTriggerFailure implements Parcelable {
@FailureSuggestedAction.FailureSuggestedActionDef
public int getSuggestedAction() {
switch (mErrorCode) {
+ case ERROR_CODE_UNKNOWN:
case ERROR_CODE_MODULE_DIED:
case ERROR_CODE_UNEXPECTED_PREEMPTION:
return FailureSuggestedAction.RECREATE_DETECTOR;
case ERROR_CODE_RECOGNITION_RESUME_FAILED:
return FailureSuggestedAction.RESTART_RECOGNITION;
default:
- return FailureSuggestedAction.NONE;
+ throw new AssertionError("Unexpected error code");
}
}
diff --git a/core/java/android/service/voice/VisualQueryDetector.java b/core/java/android/service/voice/VisualQueryDetector.java
index b4f5ff1046ae..93b7964705ba 100644
--- a/core/java/android/service/voice/VisualQueryDetector.java
+++ b/core/java/android/service/voice/VisualQueryDetector.java
@@ -391,12 +391,6 @@ public class VisualQueryDetector {
}
@Override
- public void onError(int status) throws RemoteException {
- Slog.v(TAG, "Initialization Error: (" + status + ")");
- // Do nothing
- }
-
- @Override
public void onHotwordDetectionServiceFailure(
HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
throws RemoteException {
@@ -420,6 +414,11 @@ public class VisualQueryDetector {
}
@Override
+ public void onSoundTriggerFailure(SoundTriggerFailure soundTriggerFailure) {
+ Slog.wtf(TAG, "Unexpected STFailure in VisualQueryDetector" + soundTriggerFailure);
+ }
+
+ @Override
public void onUnknownFailure(String errorMessage) throws RemoteException {
Slog.v(TAG, "onUnknownFailure: " + errorMessage);
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
diff --git a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
index ad0d1a401991..380118846dc7 100644
--- a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
+++ b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
@@ -20,6 +20,7 @@ import android.hardware.soundtrigger.SoundTrigger;
import android.service.voice.HotwordDetectedResult;
import android.service.voice.HotwordDetectionServiceFailure;
import android.service.voice.HotwordRejectedResult;
+import android.service.voice.SoundTriggerFailure;
import android.service.voice.VisualQueryDetectionServiceFailure;
/**
@@ -57,13 +58,6 @@ oneway interface IHotwordRecognitionStatusCallback {
void onRejected(in HotwordRejectedResult result);
/**
- * Called when the detection fails due to an error.
- *
- * @param status The error code that was seen.
- */
- void onError(int status);
-
- /**
* Called when the detection fails due to an error occurs in the
* {@link HotwordDetectionService}.
*
@@ -84,6 +78,15 @@ oneway interface IHotwordRecognitionStatusCallback {
in VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
/**
+ * Called when the detection fails due to an error occurs in the
+ * {@link com.android.server.soundtrigger.SoundTriggerService}.
+ *
+ * @param soundTriggerFailure It provides the error code, error message and
+ * suggested action.
+ */
+ void onSoundTriggerFailure(in SoundTriggerFailure soundTriggerFailure);
+
+ /**
* Called when the detection fails due to an unknown error occurs.
*
* @param errorMessage It provides the error message.
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
index 1a3e54d54ee7..afa0a3271906 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -391,8 +391,26 @@ public final class SoundTriggerDetector {
* @hide
*/
@Override
- public void onError(int status) {
- Slog.d(TAG, "onError()" + status);
+ public void onRecognitionPaused() {
+ Slog.d(TAG, "onRecognitionPaused()");
+ mHandler.sendEmptyMessage(MSG_DETECTION_PAUSE);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onRecognitionResumed() {
+ Slog.d(TAG, "onRecognitionResumed()");
+ mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onPreempted() {
+ Slog.d(TAG, "onPreempted()");
mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
}
@@ -400,18 +418,27 @@ public final class SoundTriggerDetector {
* @hide
*/
@Override
- public void onRecognitionPaused() {
- Slog.d(TAG, "onRecognitionPaused()");
- mHandler.sendEmptyMessage(MSG_DETECTION_PAUSE);
+ public void onModuleDied() {
+ Slog.d(TAG, "onModuleDied()");
+ mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
}
/**
* @hide
*/
@Override
- public void onRecognitionResumed() {
- Slog.d(TAG, "onRecognitionResumed()");
- mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
+ public void onResumeFailed(int status) {
+ Slog.d(TAG, "onResumeFailed()" + status);
+ mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void onPauseFailed(int status) {
+ Slog.d(TAG, "onPauseFailed()" + status);
+ mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 5efd158133ed..07dc1c66bc4d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -315,12 +315,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig,
int keyphraseId, boolean runInBatterySaverMode) {
synchronized (mLock) {
+ // TODO Remove previous callback handling
IRecognitionStatusCallback oldCallback = modelData.getCallback();
if (oldCallback != null && oldCallback.asBinder() != callback.asBinder()) {
Slog.w(TAG, "Canceling previous recognition for model id: "
+ modelData.getModelId());
try {
- oldCallback.onError(STATUS_ERROR);
+ oldCallback.onPreempted();
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onDetectionStopped", e);
}
@@ -759,15 +760,12 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
onRecognitionAbortLocked(event);
break;
case SoundTrigger.RECOGNITION_STATUS_FAILURE:
- // Fire failures to all listeners since it's not tied to a keyphrase.
- onRecognitionFailureLocked();
- break;
case SoundTrigger.RECOGNITION_STATUS_SUCCESS:
case SoundTrigger.RECOGNITION_STATUS_GET_STATE_RESPONSE:
if (isKeyphraseRecognitionEvent(event)) {
- onKeyphraseRecognitionSuccessLocked((KeyphraseRecognitionEvent) event);
+ onKeyphraseRecognitionLocked((KeyphraseRecognitionEvent) event);
} else {
- onGenericRecognitionSuccessLocked((GenericRecognitionEvent) event);
+ onGenericRecognitionLocked((GenericRecognitionEvent) event);
}
break;
}
@@ -778,7 +776,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return event instanceof KeyphraseRecognitionEvent;
}
- private void onGenericRecognitionSuccessLocked(GenericRecognitionEvent event) {
+ private void onGenericRecognitionLocked(GenericRecognitionEvent event) {
MetricsLogger.count(mContext, "sth_generic_recognition_event", 1);
if (event.status != SoundTrigger.RECOGNITION_STATUS_SUCCESS
&& event.status != SoundTrigger.RECOGNITION_STATUS_GET_STATE_RESPONSE) {
@@ -901,17 +899,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
}
- private void onRecognitionFailureLocked() {
- Slog.w(TAG, "Recognition failure");
- MetricsLogger.count(mContext, "sth_recognition_failure_event", 1);
- try {
- sendErrorCallbacksToAllLocked(STATUS_ERROR);
- } finally {
- internalClearModelStateLocked();
- internalClearGlobalStateLocked();
- }
- }
-
private int getKeyphraseIdFromEvent(KeyphraseRecognitionEvent event) {
if (event == null) {
Slog.w(TAG, "Null RecognitionEvent received.");
@@ -927,7 +914,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
return keyphraseExtras[0].id;
}
- private void onKeyphraseRecognitionSuccessLocked(KeyphraseRecognitionEvent event) {
+ private void onKeyphraseRecognitionLocked(KeyphraseRecognitionEvent event) {
Slog.i(TAG, "Recognition success");
MetricsLogger.count(mContext, "sth_keyphrase_recognition_event", 1);
int keyphraseId = getKeyphraseIdFromEvent(event);
@@ -1001,7 +988,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
private void onServiceDiedLocked() {
try {
MetricsLogger.count(mContext, "sth_service_died", 1);
- sendErrorCallbacksToAllLocked(SoundTrigger.STATUS_DEAD_OBJECT);
+ for (ModelData modelData : mModelDataMap.values()) {
+ IRecognitionStatusCallback callback = modelData.getCallback();
+ if (callback != null) {
+ try {
+ callback.onModuleDied();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException send moduleDied for model handle " +
+ modelData.getHandle(), e);
+ }
+ }
+ }
} finally {
internalClearModelStateLocked();
internalClearGlobalStateLocked();
@@ -1111,21 +1108,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
}
- // Sends an error callback to all models with a valid registered callback.
- private void sendErrorCallbacksToAllLocked(int errorCode) {
- for (ModelData modelData : mModelDataMap.values()) {
- IRecognitionStatusCallback callback = modelData.getCallback();
- if (callback != null) {
- try {
- callback.onError(errorCode);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException sendErrorCallbacksToAllLocked for model handle " +
- modelData.getHandle(), e);
- }
- }
- }
- }
-
/**
* Stops and unloads all models. This is intended as a clean-up call with the expectation that
* this instance is not used after.
@@ -1342,11 +1324,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// Notify of error if needed.
if (notifyClientOnError) {
try {
- callback.onError(status);
+ callback.onResumeFailed(status);
} catch (DeadObjectException e) {
forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onError", e);
+ Slog.w(TAG, "RemoteException in onResumeFailed", e);
}
}
} else {
@@ -1382,15 +1364,15 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
status = mModule.stopRecognition(modelData.getHandle());
if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "stopRecognition call failed with " + status);
+ Slog.e(TAG, "stopRecognition call failed with " + status);
MetricsLogger.count(mContext, "sth_stop_recognition_error", 1);
if (notify) {
try {
- callback.onError(status);
+ callback.onPauseFailed(status);
} catch (DeadObjectException e) {
forceStopAndUnloadModelLocked(modelData, e);
} catch (RemoteException e) {
- Slog.w(TAG, "RemoteException in onError", e);
+ Slog.w(TAG, "RemoteException in onPauseFailed", e);
}
}
} else {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index a54e3560e5a3..00974ac8f1f7 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -25,6 +25,7 @@ import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_BAD_VALUE;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_DEAD_OBJECT;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK;
import static android.provider.Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY;
@@ -1387,8 +1388,7 @@ public class SoundTriggerService extends SystemService {
}));
}
- @Override
- public void onError(int status) {
+ private void onError(int status) {
if (DEBUG) Slog.v(TAG, mPuuid + ": onError: " + status);
sEventLogger.enqueue(new EventLogger.StringEvent(mPuuid
@@ -1411,6 +1411,30 @@ public class SoundTriggerService extends SystemService {
}
@Override
+ public void onPreempted() {
+ if (DEBUG) Slog.v(TAG, mPuuid + ": onPreempted");
+ onError(STATUS_ERROR);
+ }
+
+ @Override
+ public void onModuleDied() {
+ if (DEBUG) Slog.v(TAG, mPuuid + ": onModuleDied");
+ onError(STATUS_DEAD_OBJECT);
+ }
+
+ @Override
+ public void onResumeFailed(int status) {
+ if (DEBUG) Slog.v(TAG, mPuuid + ": onResumeFailed: " + status);
+ onError(status);
+ }
+
+ @Override
+ public void onPauseFailed(int status) {
+ if (DEBUG) Slog.v(TAG, mPuuid + ": onPauseFailed: " + status);
+ onError(status);
+ }
+
+ @Override
public void onRecognitionPaused() {
Slog.i(TAG, mPuuid + "->" + mServiceName + ": IGNORED onRecognitionPaused");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index f3cb9baedd4b..a1adee732701 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -56,6 +56,7 @@ import android.service.voice.HotwordDetector;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.service.voice.ISandboxedDetectionService;
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
+import android.service.voice.SoundTriggerFailure;
import android.service.voice.VisualQueryDetectionService;
import android.service.voice.VisualQueryDetectionServiceFailure;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
@@ -576,8 +577,31 @@ final class HotwordDetectionConnection {
}
@Override
- public void onError(int status) throws RemoteException {
- mExternalCallback.onError(status);
+ public void onPreempted() throws RemoteException {
+ mExternalCallback.onSoundTriggerFailure(new SoundTriggerFailure(
+ SoundTriggerFailure.ERROR_CODE_UNEXPECTED_PREEMPTION,
+ "Unexpected startRecognition on already started ST session"));
+ }
+
+ @Override
+ public void onModuleDied() throws RemoteException {
+ mExternalCallback.onSoundTriggerFailure(new SoundTriggerFailure(
+ SoundTriggerFailure.ERROR_CODE_MODULE_DIED,
+ "STHAL died"));
+ }
+
+ @Override
+ public void onResumeFailed(int status) throws RemoteException {
+ mExternalCallback.onSoundTriggerFailure(new SoundTriggerFailure(
+ SoundTriggerFailure.ERROR_CODE_RECOGNITION_RESUME_FAILED,
+ "STService recognition resume failed with: " + status));
+ }
+
+ @Override
+ public void onPauseFailed(int status) throws RemoteException {
+ mExternalCallback.onSoundTriggerFailure(new SoundTriggerFailure(
+ SoundTriggerFailure.ERROR_CODE_RECOGNITION_RESUME_FAILED,
+ "STService recognition pause failed with: " + status));
}
@Override