2 * Copyright (C) 2014 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package android
.hardware
.soundtrigger
;
19 import android
.os
.Handler
;
20 import android
.os
.Looper
;
21 import android
.os
.Message
;
22 import java
.lang
.ref
.WeakReference
;
25 * The SoundTriggerModule provides APIs to control sound models and sound detection
26 * on a given sound trigger hardware module.
30 public class SoundTriggerModule
{
31 private long mNativeContext
;
34 private NativeEventHandlerDelegate mEventHandlerDelegate
;
36 // to be kept in sync with core/jni/android_hardware_SoundTrigger.cpp
37 private static final int EVENT_RECOGNITION
= 1;
38 private static final int EVENT_SERVICE_DIED
= 2;
39 private static final int EVENT_SOUNDMODEL
= 3;
40 private static final int EVENT_SERVICE_STATE_CHANGE
= 4;
42 SoundTriggerModule(int moduleId
, SoundTrigger
.StatusListener listener
, Handler handler
) {
44 mEventHandlerDelegate
= new NativeEventHandlerDelegate(listener
, handler
);
45 native_setup(new WeakReference
<SoundTriggerModule
>(this));
47 private native void native_setup(Object module_this
);
50 protected void finalize() {
53 private native void native_finalize();
56 * Detach from this module. The {@link SoundTrigger.StatusListener} callback will not be called
57 * anymore and associated resources will be released.
59 public native void detach();
62 * Load a {@link SoundTrigger.SoundModel} to the hardware. A sound model must be loaded in
63 * order to start listening to a key phrase in this model.
64 * @param model The sound model to load.
65 * @param soundModelHandle an array of int where the sound model handle will be returned.
66 * @return - {@link SoundTrigger#STATUS_OK} in case of success
67 * - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
68 * - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
70 * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
71 * - {@link SoundTrigger#STATUS_BAD_VALUE} if parameters are invalid
72 * - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
74 * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
76 public native int loadSoundModel(SoundTrigger
.SoundModel model
, int[] soundModelHandle
);
79 * Unload a {@link SoundTrigger.SoundModel} and abort any pendiong recognition
80 * @param soundModelHandle The sound model handle
81 * @return - {@link SoundTrigger#STATUS_OK} in case of success
82 * - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
83 * - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
85 * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
86 * - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
87 * - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
90 public native int unloadSoundModel(int soundModelHandle
);
93 * Start listening to all key phrases in a {@link SoundTrigger.SoundModel}.
94 * Recognition must be restarted after each callback (success or failure) received on
95 * the {@link SoundTrigger.StatusListener}.
96 * @param soundModelHandle The sound model handle to start listening to
97 * @param config contains configuration information for this recognition request:
98 * recognition mode, keyphrases, users, minimum confidence levels...
99 * @return - {@link SoundTrigger#STATUS_OK} in case of success
100 * - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
101 * - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
103 * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
104 * - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
105 * - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
107 * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
109 public native int startRecognition(int soundModelHandle
, SoundTrigger
.RecognitionConfig config
);
112 * Stop listening to all key phrases in a {@link SoundTrigger.SoundModel}
113 * @param soundModelHandle The sound model handle to stop listening to
114 * @return - {@link SoundTrigger#STATUS_OK} in case of success
115 * - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
116 * - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
118 * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
119 * - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
120 * - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
122 * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
124 public native int stopRecognition(int soundModelHandle
);
126 private class NativeEventHandlerDelegate
{
127 private final Handler mHandler
;
129 NativeEventHandlerDelegate(final SoundTrigger
.StatusListener listener
,
131 // find the looper for our new event handler
133 if (handler
!= null) {
134 looper
= handler
.getLooper();
136 looper
= Looper
.getMainLooper();
139 // construct the event handler with this looper
140 if (looper
!= null) {
141 // implement the event handler delegate
142 mHandler
= new Handler(looper
) {
144 public void handleMessage(Message msg
) {
146 case EVENT_RECOGNITION
:
147 if (listener
!= null) {
148 listener
.onRecognition(
149 (SoundTrigger
.RecognitionEvent
)msg
.obj
);
152 case EVENT_SOUNDMODEL
:
153 if (listener
!= null) {
154 listener
.onSoundModelUpdate(
155 (SoundTrigger
.SoundModelEvent
)msg
.obj
);
158 case EVENT_SERVICE_STATE_CHANGE
:
159 if (listener
!= null) {
160 listener
.onServiceStateChange(msg
.arg1
);
163 case EVENT_SERVICE_DIED
:
164 if (listener
!= null) {
165 listener
.onServiceDied();
183 @SuppressWarnings("unused")
184 private static void postEventFromNative(Object module_ref
,
185 int what
, int arg1
, int arg2
, Object obj
) {
186 SoundTriggerModule module
= (SoundTriggerModule
)((WeakReference
)module_ref
).get();
187 if (module
== null) {
191 NativeEventHandlerDelegate delegate
= module
.mEventHandlerDelegate
;
192 if (delegate
!= null) {
193 Handler handler
= delegate
.handler();
194 if (handler
!= null) {
195 Message m
= handler
.obtainMessage(what
, arg1
, arg2
, obj
);
196 handler
.sendMessage(m
);