1 /*
2  * Copyright (C) 2008 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 
17 #ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
18 #define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
19 
20 #include <utils/Vector.h>
21 //#include <binder/AppOpsManager.h>
22 #include <binder/MemoryDealer.h>
23 #include <binder/BinderService.h>
24 #include <binder/IAppOpsCallback.h>
25 #include <soundtrigger/ISoundTriggerHwService.h>
26 #include <soundtrigger/ISoundTrigger.h>
27 #include <soundtrigger/ISoundTriggerClient.h>
28 #include <system/sound_trigger.h>
29 #include "SoundTriggerHalInterface.h"
30 
31 namespace android {
32 
33 class MemoryHeapBase;
34 
35 class SoundTriggerHwService :
36     public BinderService<SoundTriggerHwService>,
37     public BnSoundTriggerHwService
38 {
39     friend class BinderService<SoundTriggerHwService>;
40 public:
41     class Module;
42     class ModuleClient;
43 
getServiceName()44     static char const* getServiceName() { return "media.sound_trigger_hw"; }
45 
46                         SoundTriggerHwService();
47     virtual             ~SoundTriggerHwService();
48 
49     // ISoundTriggerHwService
50     virtual status_t listModules(struct sound_trigger_module_descriptor *modules,
51                                  uint32_t *numModules);
52 
53     virtual status_t attach(const sound_trigger_module_handle_t handle,
54                             const sp<ISoundTriggerClient>& client,
55                             sp<ISoundTrigger>& module);
56 
57     virtual status_t setCaptureState(bool active);
58 
59     virtual status_t    onTransact(uint32_t code, const Parcel& data,
60                                    Parcel* reply, uint32_t flags);
61 
62     virtual status_t    dump(int fd, const Vector<String16>& args);
63 
64     class Model : public RefBase {
65      public:
66 
67         enum {
68             STATE_IDLE,
69             STATE_ACTIVE
70         };
71 
72         Model(sound_model_handle_t handle, audio_session_t session, audio_io_handle_t ioHandle,
73               audio_devices_t device, sound_trigger_sound_model_type_t type,
74               sp<ModuleClient>& moduleClient);
~Model()75         ~Model() {}
76 
77         sound_model_handle_t    mHandle;
78         int                     mState;
79         audio_session_t         mCaptureSession;
80         audio_io_handle_t       mCaptureIOHandle;
81         audio_devices_t         mCaptureDevice;
82         sound_trigger_sound_model_type_t mType;
83         struct sound_trigger_recognition_config mConfig;
84         sp<ModuleClient>        mModuleClient;
85     };
86 
87     class CallbackEvent : public RefBase {
88     public:
89         typedef enum {
90             TYPE_RECOGNITION,
91             TYPE_SOUNDMODEL,
92             TYPE_SERVICE_STATE,
93         } event_type;
94         CallbackEvent(event_type type, sp<IMemory> memory);
95 
96         virtual             ~CallbackEvent();
97 
setModule(wp<Module> module)98         void setModule(wp<Module> module) { mModule = module; }
setModuleClient(wp<ModuleClient> moduleClient)99         void setModuleClient(wp<ModuleClient> moduleClient) { mModuleClient = moduleClient; }
100 
101         event_type mType;
102         sp<IMemory> mMemory;
103         wp<Module> mModule;
104         wp<ModuleClient> mModuleClient;
105     };
106 
107     class Module : public RefBase {
108     public:
109 
110        Module(const sp<SoundTriggerHwService>& service,
111               const sp<SoundTriggerHalInterface>& halInterface,
112               sound_trigger_module_descriptor descriptor);
113 
114        virtual ~Module();
115 
116        virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
117                                        sp<ModuleClient> moduleClient,
118                                        sound_model_handle_t *handle);
119 
120        virtual status_t unloadSoundModel(sound_model_handle_t handle);
121 
122        virtual status_t startRecognition(sound_model_handle_t handle,
123                                          const sp<IMemory>& dataMemory);
124        virtual status_t stopRecognition(sound_model_handle_t handle);
125 
halInterface()126        sp<SoundTriggerHalInterface> halInterface() const { return mHalInterface; }
descriptor()127        struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
service()128        wp<SoundTriggerHwService> service() const { return mService; }
isConcurrentCaptureAllowed()129        bool isConcurrentCaptureAllowed() const { return mDescriptor.properties.concurrent_capture; }
130 
131        sp<Model> getModel(sound_model_handle_t handle);
132 
133        void setCaptureState_l(bool active);
134 
135        sp<ModuleClient> addClient(const sp<ISoundTriggerClient>& client);
136 
137        void detach(const sp<ModuleClient>& moduleClient);
138 
139        void onCallbackEvent(const sp<CallbackEvent>& event);
140 
141     private:
142 
143         Mutex                                  mLock;
144         wp<SoundTriggerHwService>              mService;
145         sp<SoundTriggerHalInterface>           mHalInterface;
146         struct sound_trigger_module_descriptor mDescriptor;
147         Vector< sp<ModuleClient> >             mModuleClients;
148         DefaultKeyedVector< sound_model_handle_t, sp<Model> >     mModels;
149         sound_trigger_service_state_t          mServiceState;
150     }; // class Module
151 
152     class ModuleClient : public virtual RefBase,
153                          public BnSoundTrigger,
154                          public IBinder::DeathRecipient {
155     public:
156 
157        ModuleClient(const sp<Module>& module,
158               const sp<ISoundTriggerClient>& client);
159 
160        virtual ~ModuleClient();
161 
162        virtual void detach();
163 
164        virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
165                                        sound_model_handle_t *handle);
166 
167        virtual status_t unloadSoundModel(sound_model_handle_t handle);
168 
169        virtual status_t startRecognition(sound_model_handle_t handle,
170                                          const sp<IMemory>& dataMemory);
171        virtual status_t stopRecognition(sound_model_handle_t handle);
172 
173        virtual status_t dump(int fd, const Vector<String16>& args);
174 
175        virtual void onFirstRef();
176 
177        // IBinder::DeathRecipient implementation
178        virtual void        binderDied(const wp<IBinder> &who);
179 
180        void onCallbackEvent(const sp<CallbackEvent>& event);
181 
182        void setCaptureState_l(bool active);
183 
client()184        sp<ISoundTriggerClient> client() const { return mClient; }
185 
186     private:
187 
188         mutable Mutex               mLock;
189         wp<Module>                  mModule;
190         sp<ISoundTriggerClient>     mClient;
191     }; // class ModuleClient
192 
193     class CallbackThread : public Thread {
194     public:
195 
196         explicit CallbackThread(const wp<SoundTriggerHwService>& service);
197 
198         virtual             ~CallbackThread();
199 
200         // Thread virtuals
201         virtual bool        threadLoop();
202 
203         // RefBase
204         virtual void        onFirstRef();
205 
206                 void        exit();
207                 void        sendCallbackEvent(const sp<CallbackEvent>& event);
208 
209     private:
210         wp<SoundTriggerHwService>   mService;
211         Condition                   mCallbackCond;
212         Mutex                       mCallbackLock;
213         Vector< sp<CallbackEvent> > mEventQueue;
214     };
215 
216     static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
217            sp<IMemory> prepareRecognitionEvent(struct sound_trigger_recognition_event *event);
218            void sendRecognitionEvent(struct sound_trigger_recognition_event *event, Module *module);
219 
220     static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
221            sp<IMemory> prepareSoundModelEvent(struct sound_trigger_model_event *event);
222            void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);
223 
224            sp<IMemory> prepareServiceStateEvent(sound_trigger_service_state_t state);
225            void sendServiceStateEvent(sound_trigger_service_state_t state, Module *module);
226            void sendServiceStateEvent(sound_trigger_service_state_t state,
227                                       ModuleClient *moduleClient);
228 
229            void sendCallbackEvent(const sp<CallbackEvent>& event);
230            void onCallbackEvent(const sp<CallbackEvent>& event);
231 
232 private:
233 
234     virtual void onFirstRef();
235 
236     Mutex               mServiceLock;
237     volatile int32_t    mNextUniqueId;
238     DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> >     mModules;
239     sp<CallbackThread>  mCallbackThread;
240     sp<MemoryDealer>    mMemoryDealer;
241     Mutex               mMemoryDealerLock;
242     bool                mCaptureState;
243 };
244 
245 } // namespace android
246 
247 #endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
248