Loading services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java +95 −8 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } modelData.setHandle(handle[0]); modelData.setLoaded(); Slog.d(TAG, "Generic sound model loaded with handle:" + handle[0]); } modelData.setCallback(callback); modelData.setRecognitionConfig(recognitionConfig); Loading Loading @@ -227,7 +228,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { synchronized (mLock) { if (DBG) { Slog.d(TAG, "startRecognition for keyphraseId=" + keyphraseId Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId + " soundModel=" + soundModel + ", listener=" + listener.asBinder() + ", recognitionConfig=" + recognitionConfig); Slog.d(TAG, "moduleProperties=" + mModuleProperties); Loading @@ -243,13 +244,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } if (mModuleProperties == null) { Slog.w(TAG, "Attempting startRecognition without the capability"); Slog.w(TAG, "Attempting startKeyphraseRecognition without the capability"); return STATUS_ERROR; } if (mModule == null) { mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null); if (mModule == null) { Slog.w(TAG, "startRecognition cannot attach to sound trigger module"); Slog.w(TAG, "startKeyphraseRecognition cannot attach to sound trigger module"); return STATUS_ERROR; } } Loading Loading @@ -348,26 +349,29 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } if (currentCallback == null || !modelData.isModelStarted()) { // startRecognition hasn't been called or it failed. Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition"); // startGenericRecognition hasn't been called or it failed. Slog.w(TAG, "Attempting stopGenericRecognition without a successful" + " startGenericRecognition"); return STATUS_ERROR; } if (currentCallback.asBinder() != listener.asBinder()) { // We don't allow a different listener to stop the recognition than the one // that started it. Slog.w(TAG, "Attempting stopRecognition for another recognition"); Slog.w(TAG, "Attempting stopGenericRecognition for another recognition"); return STATUS_ERROR; } int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "stopGenericRecognition failed: " + status); return status; } // 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. modelData.clearState(); modelData.setLoaded(); modelData.clearCallback(); if (!computeRecognitionRunning()) { internalClearGlobalStateLocked(); Loading Loading @@ -471,6 +475,66 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { return mModuleProperties; } int unloadKeyphraseSoundModel(int keyphraseId) { if (mModule == null || mCurrentKeyphraseModelHandle == INVALID_VALUE) { return STATUS_ERROR; } if (mKeyphraseId != keyphraseId) { Slog.w(TAG, "Given sound model is not the one loaded."); return STATUS_ERROR; } synchronized (mLock) { // Stop recognition if it's the current one. mRequested = false; int status = updateRecognitionLocked(false /* don't notify */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "Stop recognition failed for keyphrase ID:" + status); } status = mModule.unloadSoundModel(mCurrentKeyphraseModelHandle); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "unloadKeyphraseSoundModel call failed with " + status); } internalClearKeyphraseSoundModelLocked(); return status; } } int unloadGenericSoundModel(UUID modelId) { if (modelId == null || mModule == null) { return STATUS_ERROR; } ModelData modelData = mGenericModelDataMap.get(modelId); if (modelData == null) { Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" + modelId); return STATUS_ERROR; } synchronized (mLock) { if (!modelData.isModelLoaded()) { // Nothing to do here. Slog.i(TAG, "Unload: Given generic model is not loaded:" + modelId); return STATUS_OK; } if (modelData.isModelStarted()) { int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "stopGenericRecognition failed: " + status); } } int status = mModule.unloadSoundModel(modelData.getHandle()); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "unloadGenericSoundModel() call failed with " + status); Slog.w(TAG, "unloadGenericSoundModel() force-marking model as unloaded."); } mGenericModelDataMap.remove(modelId); if (DBG) dumpGenericModelState(); return status; } } //---- SoundTrigger.StatusListener methods @Override public void onRecognition(RecognitionEvent event) { Loading Loading @@ -913,6 +977,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } else { Slog.i(TAG, "startRecognition successful."); modelData.setStarted(); // Notify of resume if needed. if (notify) { Loading @@ -923,6 +988,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } if (DBG) dumpGenericModelState(); return status; } Loading Loading @@ -951,9 +1017,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } if (DBG) dumpGenericModelState(); return status; } private void dumpGenericModelState() { for (UUID modelId : mGenericModelDataMap.keySet()) { ModelData modelData = mGenericModelDataMap.get(modelId); Slog.i(TAG, "Model :" + modelData.toString()); } } // Computes whether we have any recognition running at all (voice or generic). Sets // the mRecognitionRunning variable with the result. private boolean computeRecognitionRunning() { Loading Loading @@ -1069,5 +1143,18 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { synchronized RecognitionConfig getRecognitionConfig() { return mRecognitionConfig; } String stateToString() { switch(mModelState) { case MODEL_NOTLOADED: return "NOT_LOADED"; case MODEL_LOADED: return "LOADED"; case MODEL_STARTED: return "STARTED"; } return "Unknown state"; } public String toString() { return "Handle: " + mModelHandle + "ModelState: " + stateToString(); } } } services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -75,5 +75,7 @@ public abstract class SoundTriggerInternal { public abstract ModuleProperties getModuleProperties(); public abstract int unloadKeyphraseModel(int keyphaseId); public abstract void dump(FileDescriptor fd, PrintWriter pw, String[] args); } services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +9 −1 Original line number Diff line number Diff line Loading @@ -122,10 +122,10 @@ public class SoundTriggerService extends SystemService { public int startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback, RecognitionConfig config) { enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER); if (!isInitialized()) return STATUS_ERROR; if (DEBUG) { Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid); } if (!isInitialized()) return STATUS_ERROR; GenericSoundModel model = getSoundModel(parcelUuid); if (model == null) { Loading Loading @@ -173,6 +173,8 @@ public class SoundTriggerService extends SystemService { if (DEBUG) { Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId); } // Unload the model if it is loaded. mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid()); mDbHelper.deleteGenericSoundModel(soundModelId.getUuid()); } } Loading Loading @@ -215,6 +217,12 @@ public class SoundTriggerService extends SystemService { return mSoundTriggerHelper.getModuleProperties(); } @Override public int unloadKeyphraseModel(int keyphraseId) { if (!isInitialized()) return STATUS_ERROR; return mSoundTriggerHelper.unloadKeyphraseSoundModel(keyphraseId); } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!isInitialized()) return; Loading services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,10 @@ public class VoiceInteractionManagerService extends SystemService { final long caller = Binder.clearCallingIdentity(); boolean deleted = false; try { int unloadStatus = mSoundTriggerInternal.unloadKeyphraseModel(keyphraseId); if (unloadStatus != SoundTriggerInternal.STATUS_OK) { Slog.w(TAG, "Unable to unload keyphrase sound model:" + unloadStatus); } deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); return deleted ? SoundTriggerInternal.STATUS_OK : SoundTriggerInternal.STATUS_ERROR; } finally { Loading tests/SoundTriggerTestApp/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -2,10 +2,12 @@ package="com.android.test.soundtrigger"> <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" /> <uses-permission android:name="android.permission.WAKE_LOCk" /> <application> <activity android:name="TestSoundTriggerActivity" android:label="SoundTrigger Test Application" android:screenOrientation="portrait" android:theme="@android:style/Theme.Material"> <!-- <intent-filter> Loading Loading
services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java +95 −8 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } modelData.setHandle(handle[0]); modelData.setLoaded(); Slog.d(TAG, "Generic sound model loaded with handle:" + handle[0]); } modelData.setCallback(callback); modelData.setRecognitionConfig(recognitionConfig); Loading Loading @@ -227,7 +228,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { synchronized (mLock) { if (DBG) { Slog.d(TAG, "startRecognition for keyphraseId=" + keyphraseId Slog.d(TAG, "startKeyphraseRecognition for keyphraseId=" + keyphraseId + " soundModel=" + soundModel + ", listener=" + listener.asBinder() + ", recognitionConfig=" + recognitionConfig); Slog.d(TAG, "moduleProperties=" + mModuleProperties); Loading @@ -243,13 +244,13 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } if (mModuleProperties == null) { Slog.w(TAG, "Attempting startRecognition without the capability"); Slog.w(TAG, "Attempting startKeyphraseRecognition without the capability"); return STATUS_ERROR; } if (mModule == null) { mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null); if (mModule == null) { Slog.w(TAG, "startRecognition cannot attach to sound trigger module"); Slog.w(TAG, "startKeyphraseRecognition cannot attach to sound trigger module"); return STATUS_ERROR; } } Loading Loading @@ -348,26 +349,29 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } if (currentCallback == null || !modelData.isModelStarted()) { // startRecognition hasn't been called or it failed. Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition"); // startGenericRecognition hasn't been called or it failed. Slog.w(TAG, "Attempting stopGenericRecognition without a successful" + " startGenericRecognition"); return STATUS_ERROR; } if (currentCallback.asBinder() != listener.asBinder()) { // We don't allow a different listener to stop the recognition than the one // that started it. Slog.w(TAG, "Attempting stopRecognition for another recognition"); Slog.w(TAG, "Attempting stopGenericRecognition for another recognition"); return STATUS_ERROR; } int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "stopGenericRecognition failed: " + status); return status; } // 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. modelData.clearState(); modelData.setLoaded(); modelData.clearCallback(); if (!computeRecognitionRunning()) { internalClearGlobalStateLocked(); Loading Loading @@ -471,6 +475,66 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { return mModuleProperties; } int unloadKeyphraseSoundModel(int keyphraseId) { if (mModule == null || mCurrentKeyphraseModelHandle == INVALID_VALUE) { return STATUS_ERROR; } if (mKeyphraseId != keyphraseId) { Slog.w(TAG, "Given sound model is not the one loaded."); return STATUS_ERROR; } synchronized (mLock) { // Stop recognition if it's the current one. mRequested = false; int status = updateRecognitionLocked(false /* don't notify */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "Stop recognition failed for keyphrase ID:" + status); } status = mModule.unloadSoundModel(mCurrentKeyphraseModelHandle); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "unloadKeyphraseSoundModel call failed with " + status); } internalClearKeyphraseSoundModelLocked(); return status; } } int unloadGenericSoundModel(UUID modelId) { if (modelId == null || mModule == null) { return STATUS_ERROR; } ModelData modelData = mGenericModelDataMap.get(modelId); if (modelData == null) { Slog.w(TAG, "Unload error: Attempting unload invalid generic model with id:" + modelId); return STATUS_ERROR; } synchronized (mLock) { if (!modelData.isModelLoaded()) { // Nothing to do here. Slog.i(TAG, "Unload: Given generic model is not loaded:" + modelId); return STATUS_OK; } if (modelData.isModelStarted()) { int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "stopGenericRecognition failed: " + status); } } int status = mModule.unloadSoundModel(modelData.getHandle()); if (status != SoundTrigger.STATUS_OK) { Slog.w(TAG, "unloadGenericSoundModel() call failed with " + status); Slog.w(TAG, "unloadGenericSoundModel() force-marking model as unloaded."); } mGenericModelDataMap.remove(modelId); if (DBG) dumpGenericModelState(); return status; } } //---- SoundTrigger.StatusListener methods @Override public void onRecognition(RecognitionEvent event) { Loading Loading @@ -913,6 +977,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } else { Slog.i(TAG, "startRecognition successful."); modelData.setStarted(); // Notify of resume if needed. if (notify) { Loading @@ -923,6 +988,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } if (DBG) dumpGenericModelState(); return status; } Loading Loading @@ -951,9 +1017,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } } } if (DBG) dumpGenericModelState(); return status; } private void dumpGenericModelState() { for (UUID modelId : mGenericModelDataMap.keySet()) { ModelData modelData = mGenericModelDataMap.get(modelId); Slog.i(TAG, "Model :" + modelData.toString()); } } // Computes whether we have any recognition running at all (voice or generic). Sets // the mRecognitionRunning variable with the result. private boolean computeRecognitionRunning() { Loading Loading @@ -1069,5 +1143,18 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { synchronized RecognitionConfig getRecognitionConfig() { return mRecognitionConfig; } String stateToString() { switch(mModelState) { case MODEL_NOTLOADED: return "NOT_LOADED"; case MODEL_LOADED: return "LOADED"; case MODEL_STARTED: return "STARTED"; } return "Unknown state"; } public String toString() { return "Handle: " + mModelHandle + "ModelState: " + stateToString(); } } }
services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerInternal.java +2 −0 Original line number Diff line number Diff line Loading @@ -75,5 +75,7 @@ public abstract class SoundTriggerInternal { public abstract ModuleProperties getModuleProperties(); public abstract int unloadKeyphraseModel(int keyphaseId); public abstract void dump(FileDescriptor fd, PrintWriter pw, String[] args); }
services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java +9 −1 Original line number Diff line number Diff line Loading @@ -122,10 +122,10 @@ public class SoundTriggerService extends SystemService { public int startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback, RecognitionConfig config) { enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER); if (!isInitialized()) return STATUS_ERROR; if (DEBUG) { Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid); } if (!isInitialized()) return STATUS_ERROR; GenericSoundModel model = getSoundModel(parcelUuid); if (model == null) { Loading Loading @@ -173,6 +173,8 @@ public class SoundTriggerService extends SystemService { if (DEBUG) { Slog.i(TAG, "deleteSoundModel(): id = " + soundModelId); } // Unload the model if it is loaded. mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid()); mDbHelper.deleteGenericSoundModel(soundModelId.getUuid()); } } Loading Loading @@ -215,6 +217,12 @@ public class SoundTriggerService extends SystemService { return mSoundTriggerHelper.getModuleProperties(); } @Override public int unloadKeyphraseModel(int keyphraseId) { if (!isInitialized()) return STATUS_ERROR; return mSoundTriggerHelper.unloadKeyphraseSoundModel(keyphraseId); } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!isInitialized()) return; Loading
services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +4 −0 Original line number Diff line number Diff line Loading @@ -760,6 +760,10 @@ public class VoiceInteractionManagerService extends SystemService { final long caller = Binder.clearCallingIdentity(); boolean deleted = false; try { int unloadStatus = mSoundTriggerInternal.unloadKeyphraseModel(keyphraseId); if (unloadStatus != SoundTriggerInternal.STATUS_OK) { Slog.w(TAG, "Unable to unload keyphrase sound model:" + unloadStatus); } deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); return deleted ? SoundTriggerInternal.STATUS_OK : SoundTriggerInternal.STATUS_ERROR; } finally { Loading
tests/SoundTriggerTestApp/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -2,10 +2,12 @@ package="com.android.test.soundtrigger"> <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" /> <uses-permission android:name="android.permission.WAKE_LOCk" /> <application> <activity android:name="TestSoundTriggerActivity" android:label="SoundTrigger Test Application" android:screenOrientation="portrait" android:theme="@android:style/Theme.Material"> <!-- <intent-filter> Loading