From 45c00b5877e908f44853783b42deb437cfd30d94 Mon Sep 17 00:00:00 2001 From: Sandeep Siddhartha Date: Thu, 16 Oct 2014 16:17:11 -0700 Subject: [PATCH] Don't unload the sound model on stopRecognition This helps us in majority of the scenarios where the sound model doesn't change across start/stop calls. Bug: 17954633 Change-Id: Ibff817bb69bc69d2bb3a2603460fed596688b892 --- .../hardware/soundtrigger/SoundTrigger.java | 59 ++++++++++++++++++++++ .../voiceinteraction/SoundTriggerHelper.java | 47 +++++++---------- 2 files changed, 77 insertions(+), 29 deletions(-) diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java index 746ead29bf2e..c85e97b5c27b 100644 --- a/core/java/android/hardware/soundtrigger/SoundTrigger.java +++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java @@ -211,6 +211,43 @@ public class SoundTrigger { this.type = type; this.data = data; } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(data); + result = prime * result + type; + result = prime * result + ((uuid == null) ? 0 : uuid.hashCode()); + result = prime * result + ((vendorUuid == null) ? 0 : vendorUuid.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof SoundModel)) + return false; + SoundModel other = (SoundModel) obj; + if (!Arrays.equals(data, other.data)) + return false; + if (type != other.type) + return false; + if (uuid == null) { + if (other.uuid != null) + return false; + } else if (!uuid.equals(other.uuid)) + return false; + if (vendorUuid == null) { + if (other.vendorUuid != null) + return false; + } else if (!vendorUuid.equals(other.vendorUuid)) + return false; + return true; + } } /***************************************************************************** @@ -395,6 +432,28 @@ public class SoundTrigger { + ", uuid=" + uuid + ", vendorUuid=" + vendorUuid + ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]"; } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + Arrays.hashCode(keyphrases); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (!(obj instanceof KeyphraseSoundModel)) + return false; + KeyphraseSoundModel other = (KeyphraseSoundModel) obj; + if (!Arrays.equals(keyphrases, other.keyphrases)) + return false; + return true; + } } /** diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java index 8ce7f74cef57..3ca0c84543d3 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java @@ -40,7 +40,6 @@ import android.util.Slog; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.UUID; /** * Helper for {@link SoundTrigger} APIs. @@ -78,7 +77,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { private IRecognitionStatusCallback mActiveListener; private int mKeyphraseId = INVALID_VALUE; private int mCurrentSoundModelHandle = INVALID_VALUE; - private UUID mCurrentSoundModelUuid = null; + private KeyphraseSoundModel mCurrentSoundModel = null; // FIXME: Ideally this should not be stored if allowMultipleTriggers happens at a lower layer. private RecognitionConfig mRecognitionConfig = null; private boolean mRequested = false; @@ -134,7 +133,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { + (mActiveListener == null ? "null" : mActiveListener.asBinder())); Slog.d(TAG, "current SoundModel handle=" + mCurrentSoundModelHandle); Slog.d(TAG, "current SoundModel UUID=" - + (mCurrentSoundModelUuid == null ? null : mCurrentSoundModelUuid)); + + (mCurrentSoundModel == null ? null : mCurrentSoundModel.uuid)); } if (!mStarted) { @@ -166,20 +165,16 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } // Unload the previous model if the current one isn't invalid - // and, it's not the same as the new one, or we are already started - // if we are already started, we can get multiple calls to start - // if the underlying sound model changes, in which case we should unload and reload. - // The model reuse helps only in cases when we trigger and stop internally - // without a start recognition call. + // and, it's not the same as the new one. + // This helps use cache and reuse the model and just start/stop it when necessary. if (mCurrentSoundModelHandle != INVALID_VALUE - && (!soundModel.uuid.equals(mCurrentSoundModelUuid) || mStarted)) { + && !soundModel.equals(mCurrentSoundModel)) { Slog.w(TAG, "Unloading previous sound model"); int status = mModule.unloadSoundModel(mCurrentSoundModelHandle); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "unloadSoundModel call failed with " + status); } - mCurrentSoundModelHandle = INVALID_VALUE; - mCurrentSoundModelUuid = null; + internalClearSoundModelLocked(); mStarted = false; } @@ -198,7 +193,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { // Load the sound model if the current one is null. int soundModelHandle = mCurrentSoundModelHandle; if (mCurrentSoundModelHandle == INVALID_VALUE - || mCurrentSoundModelUuid == null) { + || mCurrentSoundModel == null) { int[] handle = new int[] { INVALID_VALUE }; int status = mModule.loadSoundModel(soundModel, handle); if (status != SoundTrigger.STATUS_OK) { @@ -218,7 +213,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { mRequested = true; mKeyphraseId = keyphraseId; mCurrentSoundModelHandle = soundModelHandle; - mCurrentSoundModelUuid = soundModel.uuid; + mCurrentSoundModel = soundModel; mRecognitionConfig = recognitionConfig; // Register the new listener. This replaces the old one. // There can only be a maximum of one active listener at any given time. @@ -275,14 +270,9 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { return status; } - status = mModule.unloadSoundModel(mCurrentSoundModelHandle); - if (status != SoundTrigger.STATUS_OK) { - Slog.w(TAG, "unloadSoundModel call failed with " + status); - } - - // Clear the internal state once the recognition has been stopped. - // Unload sound model call may fail in scenarios, and we'd still want - // to reload the sound model. + // We leave the sound model loaded but not started, this helps us when we start + // back. + // Also clear the internal state once the recognition has been stopped. internalClearStateLocked(); return status; } @@ -303,11 +293,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { mRequested = false; int status = updateRecognitionLocked(false /* don't notify for synchronous calls */); - status = mModule.unloadSoundModel(mCurrentSoundModelHandle); - if (status != SoundTrigger.STATUS_OK) { - Slog.w(TAG, "unloadSoundModel call failed with " + status); - } - internalClearStateLocked(); } } @@ -456,6 +441,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } catch (RemoteException e) { Slog.w(TAG, "RemoteException in onError", e); } finally { + internalClearSoundModelLocked(); internalClearStateLocked(); if (mModule != null) { mModule.detach(); @@ -535,8 +521,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { mRequested = false; mKeyphraseId = INVALID_VALUE; - mCurrentSoundModelHandle = INVALID_VALUE; - mCurrentSoundModelUuid = null; mRecognitionConfig = null; mActiveListener = null; @@ -550,6 +534,11 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } + private void internalClearSoundModelLocked() { + mCurrentSoundModelHandle = INVALID_VALUE; + mCurrentSoundModel = null; + } + class MyCallStateListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String arg1) { @@ -581,7 +570,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { pw.print(" keyphrase ID="); pw.println(mKeyphraseId); pw.print(" sound model handle="); pw.println(mCurrentSoundModelHandle); pw.print(" sound model UUID="); - pw.println(mCurrentSoundModelUuid == null ? "null" : mCurrentSoundModelUuid); + pw.println(mCurrentSoundModel == null ? "null" : mCurrentSoundModel.uuid); pw.print(" current listener="); pw.println(mActiveListener == null ? "null" : mActiveListener.asBinder()); -- 2.11.0