From f47f173b06e2972bb376da8ff11db3a83c21d10b Mon Sep 17 00:00:00 2001 From: Arunesh Mishra Date: Thu, 18 Feb 2016 16:16:12 -0800 Subject: [PATCH] Fix AlwaysOnHotwordDetector recognition event bug. Parcelables don't work well with inheritance. So changed the IRecognitionStatusCallback to have onKeyphraseDetected() and onGenericSoundTriggerDetected() for those respective events. Made corresponding changes to AlwaysOnHotwordDetector and SoundTriggerDetector. Bug: 27250528 Change-Id: Ic08a431e7cc4248c688b05c865348170246de576 --- .../IRecognitionStatusCallback.aidl | 16 ++++++-- .../hardware/soundtrigger/SoundTrigger.aidl | 2 +- .../hardware/soundtrigger/SoundTrigger.java | 40 +++++++++++++++++-- .../voice/AlwaysOnHotwordDetector.java | 10 ++--- .../soundtrigger/SoundTriggerDetector.java | 9 ++++- .../soundtrigger/SoundTriggerHelper.java | 14 +++---- .../TestSoundTriggerActivity.java | 8 +++- 7 files changed, 77 insertions(+), 22 deletions(-) diff --git a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl index 597efa566d2c2..dcc3369668100 100644 --- a/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl +++ b/core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl @@ -26,10 +26,20 @@ oneway interface IRecognitionStatusCallback { * Called when the keyphrase is spoken. * * @param recognitionEvent Object containing data relating to the - * recognition event such as trigger audio data, if it was requested - * and is available. + * keyphrase recognition event such as keyphrase + * extras. */ - void onDetected(in SoundTrigger.RecognitionEvent recognitionEvent); + void onKeyphraseDetected(in SoundTrigger.KeyphraseRecognitionEvent recognitionEvent); + + /** + * Called when a generic sound trigger event is witnessed. + * + * @param recognitionEvent Object containing data relating to the + * recognition event such as trigger audio data (if + * requested). + */ + + void onGenericSoundTriggerDetected(in SoundTrigger.GenericRecognitionEvent recognitionEvent); /** * Called when the detection fails due to an error. diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl index fec64ea338ea7..325a9addc8ff3 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.aidl +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.aidl @@ -20,7 +20,7 @@ parcelable SoundTrigger.ConfidenceLevel; parcelable SoundTrigger.Keyphrase; parcelable SoundTrigger.RecognitionEvent; parcelable SoundTrigger.KeyphraseRecognitionEvent; -parcelable SoundTrigger.GenericSoundRecognitionEvent; +parcelable SoundTrigger.GenericRecognitionEvent; parcelable SoundTrigger.KeyphraseRecognitionExtra; parcelable SoundTrigger.KeyphraseSoundModel; parcelable SoundTrigger.GenericSoundModel; diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index 882908a9f46e7..cc2b7643d3e67 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -595,7 +595,7 @@ public class SoundTrigger { } }; - private static RecognitionEvent fromParcel(Parcel in) { + protected static RecognitionEvent fromParcel(Parcel in) { int status = in.readInt(); int soundModelHandle = in.readInt(); boolean captureAvailable = in.readByte() == 1; @@ -980,7 +980,7 @@ public class SoundTrigger { public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public KeyphraseRecognitionEvent createFromParcel(Parcel in) { - return KeyphraseRecognitionEvent.fromParcel(in); + return KeyphraseRecognitionEvent.fromParcelForKeyphrase(in); } public KeyphraseRecognitionEvent[] newArray(int size) { @@ -988,7 +988,7 @@ public class SoundTrigger { } }; - private static KeyphraseRecognitionEvent fromParcel(Parcel in) { + private static KeyphraseRecognitionEvent fromParcelForKeyphrase(Parcel in) { int status = in.readInt(); int soundModelHandle = in.readInt(); boolean captureAvailable = in.readByte() == 1; @@ -1094,6 +1094,40 @@ public class SoundTrigger { captureDelayMs, capturePreambleMs, triggerInData, captureFormat, data); } + + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public GenericRecognitionEvent createFromParcel(Parcel in) { + return GenericRecognitionEvent.fromParcelForGeneric(in); + } + + public GenericRecognitionEvent[] newArray(int size) { + return new GenericRecognitionEvent[size]; + } + }; + + private static GenericRecognitionEvent fromParcelForGeneric(Parcel in) { + RecognitionEvent event = RecognitionEvent.fromParcel(in); + return new GenericRecognitionEvent(event.status, event.soundModelHandle, + event.captureAvailable, event.captureSession, event.captureDelayMs, + event.capturePreambleMs, event.triggerInData, event.captureFormat, event.data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) return false; + RecognitionEvent other = (RecognitionEvent) obj; + return super.equals(obj); + } + + @Override + public String toString() { + return "GenericRecognitionEvent ::" + super.toString(); + } } /** diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 76a401d745598..9464a8754fa82 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -617,11 +617,7 @@ public class AlwaysOnHotwordDetector { } @Override - public void onDetected(RecognitionEvent event) { - if (! (event instanceof KeyphraseRecognitionEvent)) { - Slog.e(TAG, "onDetected() called for a soundtrigger event."); - return; - } + public void onKeyphraseDetected(KeyphraseRecognitionEvent event) { if (DBG) { Slog.d(TAG, "onDetected(" + event + ")"); } else { @@ -632,6 +628,10 @@ public class AlwaysOnHotwordDetector { event.captureFormat, event.captureSession, event.data)) .sendToTarget(); } + @Override + public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) { + Slog.w(TAG, "Generic sound trigger event detected at AOHD: " + event); + } @Override public void onError(int status) { diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java index 8f022db5b02e9..df0961bd17d43 100644 --- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java +++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java @@ -289,8 +289,8 @@ public final class SoundTriggerDetector { * @hide */ @Override - public void onDetected(SoundTrigger.RecognitionEvent event) { - Slog.d(TAG, "onDetected()" + event); + public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) { + Slog.d(TAG, "onGenericSoundTriggerDetected()" + event); Message.obtain(mHandler, MSG_SOUND_TRIGGER_DETECTED, new EventPayload(event.triggerInData, event.captureAvailable, @@ -298,6 +298,11 @@ public final class SoundTriggerDetector { .sendToTarget(); } + @Override + public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) { + Slog.e(TAG, "Ignoring onKeyphraseDetected() called for " + event); + } + /** * @hide */ diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java index 7ee7423538a07..e05f00d646f05 100644 --- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java +++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java @@ -573,7 +573,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } private boolean isKeyphraseRecognitionEvent(RecognitionEvent event) { - return mCurrentKeyphraseModelHandle == event.soundModelHandle; + return event instanceof KeyphraseRecognitionEvent; } private void onGenericRecognitionSuccessLocked(GenericRecognitionEvent event) { @@ -595,9 +595,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } try { - callback.onDetected((GenericRecognitionEvent) event); + callback.onGenericSoundTriggerDetected((GenericRecognitionEvent) event); } catch (RemoteException e) { - Slog.w(TAG, "RemoteException in onDetected", e); + Slog.w(TAG, "RemoteException in onGenericSoundTriggerDetected", e); } model.setStopped(); @@ -715,10 +715,10 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { try { if (mKeyphraseListener != null) { - mKeyphraseListener.onDetected((KeyphraseRecognitionEvent) event); + mKeyphraseListener.onKeyphraseDetected((KeyphraseRecognitionEvent) event); } } catch (RemoteException e) { - Slog.w(TAG, "RemoteException in onDetected", e); + Slog.w(TAG, "RemoteException in onKeyphraseDetected", e); } mKeyphraseStarted = false; @@ -767,7 +767,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { int status = mModule.startRecognition(mCurrentKeyphraseModelHandle, mRecognitionConfig); if (status != SoundTrigger.STATUS_OK) { - Slog.w(TAG, "startRecognition failed with " + status); + Slog.w(TAG, "startKeyphraseRecognition failed with " + status); // Notify of error if needed. if (notify) { try { @@ -967,7 +967,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { int status = mModule.startRecognition(handle, config); if (status != SoundTrigger.STATUS_OK) { - Slog.w(TAG, "startRecognition failed with " + status); + Slog.w(TAG, "startGenericRecognition failed with " + status); // Notify of error if needed. if (notify) { try { diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java index 95e2dcffe9c4e..4770c056814c8 100644 --- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java +++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java @@ -204,7 +204,10 @@ public class TestSoundTriggerActivity extends Activity { UUID modelUuid = getSelectedUuid(); SoundTriggerDetector detector = getDetector(); if (detector == null) { - Log.i(TAG, "Created an instance of the SoundTriggerDetector."); + Log.i(TAG, "Created an instance of the SoundTriggerDetector for model #" + + mSelectedModelId); + postMessage("Created an instance of the SoundTriggerDetector for model #" + + mSelectedModelId); detector = mSoundTriggerUtil.createSoundTriggerDetector(modelUuid, new DetectorCallback()); setDetector(detector); @@ -213,6 +216,7 @@ public class TestSoundTriggerActivity extends Activity { if (!detector.startRecognition( SoundTriggerDetector.RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS)) { Log.e(TAG, "Fast failure attempting to start recognition."); + postMessage("Fast failure attempting to start recognition:" + mSelectedModelId); } } @@ -220,11 +224,13 @@ public class TestSoundTriggerActivity extends Activity { SoundTriggerDetector detector = getDetector(); if (detector == null) { Log.e(TAG, "Stop called on null detector."); + postMessage("Error: Stop called on null detector."); return; } postMessage("Triggering stop recognition for model: " + mSelectedModelId); if (!detector.stopRecognition()) { Log.e(TAG, "Fast failure attempting to stop recognition."); + postMessage("Fast failure attempting to stop recognition: " + mSelectedModelId); } }