SoundTriggerModule.java revision e48188ce35f613f64b513e5d8ce24fada1212d8e
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package android.hardware.soundtrigger;
18
19import android.content.Context;
20import android.content.Intent;
21import android.os.Handler;
22import android.os.Looper;
23import android.os.Message;
24import java.lang.ref.WeakReference;
25import java.util.UUID;
26
27/**
28 * The SoundTriggerModule provides APIs to control sound models and sound detection
29 * on a given sound trigger hardware module.
30 *
31 * @hide
32 */
33public class SoundTriggerModule {
34    private long mNativeContext;
35
36    private int mId;
37    private NativeEventHandlerDelegate mEventHandlerDelegate;
38
39    private static final int EVENT_RECOGNITION = 1;
40    private static final int EVENT_SERVICE_DIED = 2;
41
42    SoundTriggerModule(int moduleId, SoundTrigger.StatusListener listener, Handler handler) {
43        mId = moduleId;
44        mEventHandlerDelegate = new NativeEventHandlerDelegate(listener, handler);
45        native_setup(new WeakReference<SoundTriggerModule>(this));
46    }
47    private native void native_setup(Object module_this);
48
49    @Override
50    protected void finalize() {
51        native_finalize();
52    }
53    private native void native_finalize();
54
55    /**
56     * Detach from this module. The {@link SoundTrigger.StatusListener} callback will not be called
57     * anymore and associated resources will be released.
58     * */
59    public native void detach();
60
61    /**
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
69     *         system permission
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
73     *         service fails
74     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
75     */
76    public native int loadSoundModel(SoundTrigger.SoundModel model, int[] soundModelHandle);
77
78    /**
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
84     *         system permission
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
88     *         service fails
89     */
90    public native int unloadSoundModel(int soundModelHandle);
91
92    /**
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 data Opaque data for use by the implementation for this recognition
98     * @return - {@link SoundTrigger#STATUS_OK} in case of success
99     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
100     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
101     *         system permission
102     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
103     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
104     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
105     *         service fails
106     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
107     */
108    public native int startRecognition(int soundModelHandle, byte[] data);
109
110    /**
111     * Stop listening to all key phrases in a {@link SoundTrigger.SoundModel}
112     * @param soundModelHandle The sound model handle to stop listening to
113     * @return - {@link SoundTrigger#STATUS_OK} in case of success
114     *         - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
115     *         - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
116     *         system permission
117     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
118     *         - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
119     *         - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
120     *         service fails
121     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
122     */
123    public native int stopRecognition(int soundModelHandle);
124
125    private class NativeEventHandlerDelegate {
126        private final Handler mHandler;
127
128        NativeEventHandlerDelegate(final SoundTrigger.StatusListener listener,
129                                   Handler handler) {
130            // find the looper for our new event handler
131            Looper looper;
132            if (handler != null) {
133                looper = handler.getLooper();
134            } else {
135                looper = Looper.myLooper();
136                if (looper == null) {
137                    looper = Looper.getMainLooper();
138                }
139            }
140
141            // construct the event handler with this looper
142            if (looper != null) {
143                // implement the event handler delegate
144                mHandler = new Handler(looper) {
145                    @Override
146                    public void handleMessage(Message msg) {
147                        switch(msg.what) {
148                        case EVENT_RECOGNITION:
149                            if (listener != null) {
150                                listener.onRecognition(
151                                        (SoundTrigger.RecognitionEvent)msg.obj);
152                            }
153                            break;
154                        case EVENT_SERVICE_DIED:
155                            if (listener != null) {
156                                listener.onServiceDied();
157                            }
158                            break;
159                        default:
160                            break;
161                        }
162                    }
163                };
164            } else {
165                mHandler = null;
166            }
167        }
168
169        Handler handler() {
170            return mHandler;
171        }
172    }
173
174    @SuppressWarnings("unused")
175    private static void postEventFromNative(Object module_ref,
176                                            int what, int arg1, int arg2, Object obj) {
177        SoundTriggerModule module = (SoundTriggerModule)((WeakReference)module_ref).get();
178        if (module == null) {
179            return;
180        }
181
182        NativeEventHandlerDelegate delegate = module.mEventHandlerDelegate;
183        if (delegate != null) {
184            Handler handler = delegate.handler();
185            if (handler != null) {
186                Message m = handler.obtainMessage(what, arg1, arg2, obj);
187                handler.sendMessage(m);
188            }
189        }
190    }
191}
192
193