blob: 377d30bcde480c6e411cb35f24feb3ce9dcca721 [file] [log] [blame]
Eric Laurentb7a11d82014-04-18 17:40:41 -07001/*
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
17#define LOG_TAG "SoundTriggerHwService"
18//#define LOG_NDEBUG 0
19
20#include <stdio.h>
21#include <string.h>
22#include <sys/types.h>
23#include <pthread.h>
24
Mikhail Naganov959e2d02019-03-28 11:08:19 -070025#include <audio_utils/clock.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000026#include <system/sound_trigger.h>
27#include <cutils/atomic.h>
28#include <cutils/properties.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070029#include <hardware/hardware.h>
30#include <media/AudioSystem.h>
Andy Hungab7ef302018-05-15 19:35:29 -070031#include <mediautils/ServiceUtilities.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000032#include <utils/Errors.h>
33#include <utils/Log.h>
Eric Laurentb7a11d82014-04-18 17:40:41 -070034#include <binder/IServiceManager.h>
35#include <binder/MemoryBase.h>
36#include <binder/MemoryHeapBase.h>
Eric Laurent7a544b42016-08-05 19:01:13 -070037#include <system/sound_trigger.h>
Eric Laurent8ba53d82014-08-01 23:15:05 +000038#include "SoundTriggerHwService.h"
Eric Laurentb7a11d82014-04-18 17:40:41 -070039
Eric Laurentb7a11d82014-04-18 17:40:41 -070040#define HW_MODULE_PREFIX "primary"
Eric Laurent7a544b42016-08-05 19:01:13 -070041namespace android {
Eric Laurentb7a11d82014-04-18 17:40:41 -070042
43SoundTriggerHwService::SoundTriggerHwService()
44 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070045 mNextUniqueId(1),
46 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
47 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070048{
49}
50
51void SoundTriggerHwService::onFirstRef()
52{
Eric Laurentb7a11d82014-04-18 17:40:41 -070053 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070054
Eric Laurent7a544b42016-08-05 19:01:13 -070055 sp<SoundTriggerHalInterface> halInterface =
56 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070057
Eric Laurent7a544b42016-08-05 19:01:13 -070058 if (halInterface == 0) {
59 ALOGW("could not connect to HAL");
60 return;
61 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070062 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070063 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070064 if (rc != 0) {
65 ALOGE("could not read implementation properties");
66 return;
67 }
68 descriptor.handle =
69 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
70 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
71 descriptor.handle);
72
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070073 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -070074 mModules.add(descriptor.handle, module);
75 mCallbackThread = new CallbackThread(this);
76}
77
78SoundTriggerHwService::~SoundTriggerHwService()
79{
80 if (mCallbackThread != 0) {
81 mCallbackThread->exit();
82 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070083}
84
jiabin68e0df72019-03-18 17:55:35 -070085status_t SoundTriggerHwService::listModules(const String16& opPackageName,
86 struct sound_trigger_module_descriptor *modules,
Eric Laurentb7a11d82014-04-18 17:40:41 -070087 uint32_t *numModules)
88{
89 ALOGV("listModules");
jiabin68e0df72019-03-18 17:55:35 -070090 if (!captureHotwordAllowed(opPackageName,
91 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -070092 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +000093 return PERMISSION_DENIED;
94 }
95
Eric Laurentb7a11d82014-04-18 17:40:41 -070096 AutoMutex lock(mServiceLock);
97 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
98 return BAD_VALUE;
99 }
100 size_t maxModules = *numModules;
101 *numModules = mModules.size();
102 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
103 modules[i] = mModules.valueAt(i)->descriptor();
104 }
105 return NO_ERROR;
106}
107
jiabin68e0df72019-03-18 17:55:35 -0700108status_t SoundTriggerHwService::attach(const String16& opPackageName,
109 const sound_trigger_module_handle_t handle,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700110 const sp<ISoundTriggerClient>& client,
111 sp<ISoundTrigger>& moduleInterface)
112{
113 ALOGV("attach module %d", handle);
jiabin68e0df72019-03-18 17:55:35 -0700114 if (!captureHotwordAllowed(opPackageName,
115 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700116 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000117 return PERMISSION_DENIED;
118 }
119
Eric Laurentb7a11d82014-04-18 17:40:41 -0700120 AutoMutex lock(mServiceLock);
121 moduleInterface.clear();
122 if (client == 0) {
123 return BAD_VALUE;
124 }
125 ssize_t index = mModules.indexOfKey(handle);
126 if (index < 0) {
127 return BAD_VALUE;
128 }
129 sp<Module> module = mModules.valueAt(index);
130
jiabin68e0df72019-03-18 17:55:35 -0700131 sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700132 if (moduleClient == 0) {
133 return NO_INIT;
134 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700135
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700136 moduleClient->setCaptureState_l(mCaptureState);
137 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700138
Eric Laurentb7a11d82014-04-18 17:40:41 -0700139 return NO_ERROR;
140}
141
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700142status_t SoundTriggerHwService::setCaptureState(bool active)
143{
144 ALOGV("setCaptureState %d", active);
145 AutoMutex lock(mServiceLock);
146 mCaptureState = active;
147 for (size_t i = 0; i < mModules.size(); i++) {
148 mModules.valueAt(i)->setCaptureState_l(active);
149 }
150 return NO_ERROR;
151}
152
153
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700154static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700155
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700156static bool dumpTryLock(Mutex& mutex)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700157{
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700158 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
159 return err == NO_ERROR;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700160}
161
162status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
163 String8 result;
164 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
165 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
166 write(fd, result.string(), result.size());
167 } else {
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700168 bool locked = dumpTryLock(mServiceLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700169 // failed to lock - SoundTriggerHwService is probably deadlocked
170 if (!locked) {
171 result.append("SoundTriggerHwService may be deadlocked\n");
172 write(fd, result.string(), result.size());
173 }
174
175 if (locked) mServiceLock.unlock();
176 }
177 return NO_ERROR;
178}
179
180status_t SoundTriggerHwService::onTransact(
181 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
182 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
183}
184
185
186// static
187void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
188 void *cookie)
189{
190 Module *module = (Module *)cookie;
191 if (module == NULL) {
192 return;
193 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700194 sp<SoundTriggerHwService> service = module->service().promote();
195 if (service == 0) {
196 return;
197 }
198
199 service->sendRecognitionEvent(event, module);
200}
201
Chris Thornton79c56612017-10-25 14:47:44 -0700202sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700203 struct sound_trigger_recognition_event *event)
204{
Chris Thornton79c56612017-10-25 14:47:44 -0700205 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700206 sp<IMemory> eventMemory;
207
208 //sanitize event
209 switch (event->type) {
210 case SOUND_MODEL_TYPE_KEYPHRASE:
211 ALOGW_IF(event->data_size != 0 && event->data_offset !=
212 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700213 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700214 event->data_offset);
215 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
216 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800217 case SOUND_MODEL_TYPE_GENERIC:
218 ALOGW_IF(event->data_size != 0 && event->data_offset !=
219 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700220 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800221 event->data_offset);
222 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
223 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700224 case SOUND_MODEL_TYPE_UNKNOWN:
225 ALOGW_IF(event->data_size != 0 && event->data_offset !=
226 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700227 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700228 event->data_offset);
229 event->data_offset = sizeof(struct sound_trigger_recognition_event);
230 break;
231 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700232 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700233 }
234
235 size_t size = event->data_offset + event->data_size;
236 eventMemory = mMemoryDealer->allocate(size);
237 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
238 eventMemory.clear();
239 return eventMemory;
240 }
241 memcpy(eventMemory->pointer(), event, size);
242
243 return eventMemory;
244}
245
246void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
247 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700248{
249 if (module == NULL) {
250 return;
251 }
252 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
253 if (eventMemory == 0) {
254 return;
255 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700256
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700257 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
258 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700259 callbackEvent->setModule(module);
260 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700261}
262
263// static
264void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
265 void *cookie)
266{
267 Module *module = (Module *)cookie;
268 if (module == NULL) {
269 return;
270 }
271 sp<SoundTriggerHwService> service = module->service().promote();
272 if (service == 0) {
273 return;
274 }
275
276 service->sendSoundModelEvent(event, module);
277}
278
Chris Thornton79c56612017-10-25 14:47:44 -0700279sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700280{
Chris Thornton79c56612017-10-25 14:47:44 -0700281 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700282 sp<IMemory> eventMemory;
283
284 size_t size = event->data_offset + event->data_size;
285 eventMemory = mMemoryDealer->allocate(size);
286 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
287 eventMemory.clear();
288 return eventMemory;
289 }
290 memcpy(eventMemory->pointer(), event, size);
291
292 return eventMemory;
293}
294
295void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
296 Module *module)
297{
Chris Thornton79c56612017-10-25 14:47:44 -0700298 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700299 if (eventMemory == 0) {
300 return;
301 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700302 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
303 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700304 callbackEvent->setModule(module);
305 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700306}
307
308
Chris Thornton07405ee2017-11-14 20:45:27 -0800309sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700310{
Chris Thornton79c56612017-10-25 14:47:44 -0700311 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700312 sp<IMemory> eventMemory;
313
314 size_t size = sizeof(sound_trigger_service_state_t);
315 eventMemory = mMemoryDealer->allocate(size);
316 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
317 eventMemory.clear();
318 return eventMemory;
319 }
320 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
321 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700322}
323
Chris Thornton07405ee2017-11-14 20:45:27 -0800324void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700325 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700326{
Chris Thornton07405ee2017-11-14 20:45:27 -0800327 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700328 if (eventMemory == 0) {
329 return;
330 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700331 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
332 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800333 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700334 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700335}
336
Chris Thornton07405ee2017-11-14 20:45:27 -0800337void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
338 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700339{
Chris Thornton07405ee2017-11-14 20:45:27 -0800340 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700341 if (eventMemory == 0) {
342 return;
343 }
344 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
345 eventMemory);
346 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700347 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700348}
349
Chris Thornton79c56612017-10-25 14:47:44 -0700350void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700351{
352 mCallbackThread->sendCallbackEvent(event);
353}
354
355void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
356{
357 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700358 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700359 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700360 {
361 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700362 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700363 module = event->mModule.promote();
364 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700365 moduleClient = event->mModuleClient.promote();
366 if (moduleClient == 0) {
367 return;
368 }
Chris Thornton79c56612017-10-25 14:47:44 -0700369 } else {
370 // Sanity check on this being a Module we know about.
371 bool foundModule = false;
372 for (size_t i = 0; i < mModules.size(); i++) {
373 if (mModules.valueAt(i).get() == module.get()) {
374 foundModule = true;
375 break;
376 }
377 }
378 if (!foundModule) {
379 ALOGE("onCallbackEvent for unknown module");
380 return;
381 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700382 }
383 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700384 if (module != 0) {
385 ALOGV("onCallbackEvent for module");
386 module->onCallbackEvent(event);
387 } else if (moduleClient != 0) {
388 ALOGV("onCallbackEvent for moduleClient");
389 moduleClient->onCallbackEvent(event);
390 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700391 {
392 AutoMutex lock(mServiceLock);
393 // clear now to execute with mServiceLock locked
394 event->mMemory.clear();
395 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700396}
397
398#undef LOG_TAG
399#define LOG_TAG "SoundTriggerHwService::CallbackThread"
400
401SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
402 : mService(service)
403{
404}
405
406SoundTriggerHwService::CallbackThread::~CallbackThread()
407{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700408 while (!mEventQueue.isEmpty()) {
409 mEventQueue[0]->mMemory.clear();
410 mEventQueue.removeAt(0);
411 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700412}
413
414void SoundTriggerHwService::CallbackThread::onFirstRef()
415{
416 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
417}
418
419bool SoundTriggerHwService::CallbackThread::threadLoop()
420{
421 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700422 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700423 sp<SoundTriggerHwService> service;
424 {
425 Mutex::Autolock _l(mCallbackLock);
426 while (mEventQueue.isEmpty() && !exitPending()) {
427 ALOGV("CallbackThread::threadLoop() sleep");
428 mCallbackCond.wait(mCallbackLock);
429 ALOGV("CallbackThread::threadLoop() wake up");
430 }
431 if (exitPending()) {
432 break;
433 }
434 event = mEventQueue[0];
435 mEventQueue.removeAt(0);
436 service = mService.promote();
437 }
438 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700439 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700440 }
441 }
442 return false;
443}
444
445void SoundTriggerHwService::CallbackThread::exit()
446{
447 Mutex::Autolock _l(mCallbackLock);
448 requestExit();
449 mCallbackCond.broadcast();
450}
451
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700452void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
453 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700454{
455 AutoMutex lock(mCallbackLock);
456 mEventQueue.add(event);
457 mCallbackCond.signal();
458}
459
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700460SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
461 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700462{
463}
464
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700465SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700466{
467}
468
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700469
Eric Laurentb7a11d82014-04-18 17:40:41 -0700470#undef LOG_TAG
471#define LOG_TAG "SoundTriggerHwService::Module"
472
473SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700474 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700475 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700476 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700477 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700478{
479}
480
481SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700482 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700483}
484
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700485sp<SoundTriggerHwService::ModuleClient>
jiabin68e0df72019-03-18 17:55:35 -0700486SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
487 const String16& opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700488{
489 AutoMutex lock(mLock);
490 sp<ModuleClient> moduleClient;
491
492 for (size_t i = 0; i < mModuleClients.size(); i++) {
493 if (mModuleClients[i]->client() == client) {
494 // Client already present, reuse client
495 return moduleClient;
496 }
497 }
jiabin68e0df72019-03-18 17:55:35 -0700498 moduleClient = new ModuleClient(this, client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700499
500 ALOGV("addClient() client %p", moduleClient.get());
501 mModuleClients.add(moduleClient);
502
503 return moduleClient;
504}
505
506void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
507{
508 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700509 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700510
Eric Laurent338e8ba2017-10-05 10:58:38 -0700511 {
512 AutoMutex lock(mLock);
513 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700514
Eric Laurent338e8ba2017-10-05 10:58:38 -0700515 for (size_t i = 0; i < mModuleClients.size(); i++) {
516 if (mModuleClients[i] == moduleClient) {
517 index = i;
518 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700519 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700520 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700521 if (index == -1) {
522 return;
523 }
524
525 ALOGV("remove client %p", moduleClient.get());
526 mModuleClients.removeAt(index);
527
528 // Iterate in reverse order as models are removed from list inside the loop.
529 for (size_t i = mModels.size(); i > 0; i--) {
530 sp<Model> model = mModels.valueAt(i - 1);
531 if (moduleClient == model->mModuleClient) {
532 mModels.removeItemsAt(i - 1);
533 ALOGV("detach() unloading model %d", model->mHandle);
534 if (mHalInterface != 0) {
535 if (model->mState == Model::STATE_ACTIVE) {
536 mHalInterface->stopRecognition(model->mHandle);
537 }
538 mHalInterface->unloadSoundModel(model->mHandle);
539 }
540 releasedSessions.add(model->mCaptureSession);
541 }
542 }
543 }
544
545 for (size_t i = 0; i < releasedSessions.size(); i++) {
546 // do not call AudioSystem methods with mLock held
547 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700548 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700549}
550
551status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700552 sp<ModuleClient> moduleClient,
553 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700554{
555 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700556 if (mHalInterface == 0) {
557 return NO_INIT;
558 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700559
Eric Laurentb7a11d82014-04-18 17:40:41 -0700560 struct sound_trigger_sound_model *sound_model =
561 (struct sound_trigger_sound_model *)modelMemory->pointer();
562
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700563 size_t structSize;
564 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
565 structSize = sizeof(struct sound_trigger_phrase_sound_model);
566 } else {
567 structSize = sizeof(struct sound_trigger_sound_model);
568 }
569
570 if (sound_model->data_offset < structSize ||
571 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
572 modelMemory->size() < sound_model->data_offset ||
573 sound_model->data_size > (modelMemory->size() - sound_model->data_offset)) {
574 android_errorWriteLog(0x534e4554, "30148546");
575 ALOGE("loadSoundModel() data_size is too big");
576 return BAD_VALUE;
577 }
578
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700579 audio_session_t session;
580 audio_io_handle_t ioHandle;
581 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700582 // do not call AudioSystem methods with mLock held
583 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700584 if (status != NO_ERROR) {
585 return status;
586 }
587
Eric Laurent338e8ba2017-10-05 10:58:38 -0700588 {
589 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700590
Eric Laurent338e8ba2017-10-05 10:58:38 -0700591 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
592 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
593 mDescriptor.properties.max_sound_models);
594 status = INVALID_OPERATION;
595 goto exit;
596 }
597
598 status = mHalInterface->loadSoundModel(sound_model,
599 SoundTriggerHwService::soundModelCallback,
600 this, handle);
601 if (status != NO_ERROR) {
602 goto exit;
603 }
604
605 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
606 moduleClient);
607 mModels.replaceValueFor(*handle, model);
608 }
609exit:
610 if (status != NO_ERROR) {
611 // do not call AudioSystem methods with mLock held
612 AudioSystem::releaseSoundTriggerSession(session);
613 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700614 return status;
615}
616
617status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
618{
619 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700620 status_t status;
621 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800622
Eric Laurent338e8ba2017-10-05 10:58:38 -0700623 {
624 AutoMutex lock(mLock);
625 if (mHalInterface == 0) {
626 return NO_INIT;
627 }
628 ssize_t index = mModels.indexOfKey(handle);
629 if (index < 0) {
630 return BAD_VALUE;
631 }
632 sp<Model> model = mModels.valueAt(index);
633 mModels.removeItem(handle);
634 if (model->mState == Model::STATE_ACTIVE) {
635 mHalInterface->stopRecognition(model->mHandle);
636 model->mState = Model::STATE_IDLE;
637 }
638 status = mHalInterface->unloadSoundModel(handle);
639 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700640 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700641 // do not call AudioSystem methods with mLock held
642 AudioSystem::releaseSoundTriggerSession(session);
643 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700644}
645
646status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700647 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700648{
649 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700650 if (mHalInterface == 0) {
651 return NO_INIT;
652 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700653
654 struct sound_trigger_recognition_config *config =
655 (struct sound_trigger_recognition_config *)dataMemory->pointer();
656
657 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
658 config->data_size > (UINT_MAX - config->data_offset) ||
659 dataMemory->size() < config->data_offset ||
660 config->data_size > (dataMemory->size() - config->data_offset)) {
661 ALOGE("startRecognition() data_size is too big");
662 return BAD_VALUE;
663 }
664
Eric Laurentb7a11d82014-04-18 17:40:41 -0700665 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700666 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
667 return INVALID_OPERATION;
668 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700669 sp<Model> model = getModel(handle);
670 if (model == 0) {
671 return BAD_VALUE;
672 }
673
674 if (model->mState == Model::STATE_ACTIVE) {
675 return INVALID_OPERATION;
676 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700677
Eric Laurentb7a11d82014-04-18 17:40:41 -0700678
679 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700680 config->capture_handle = model->mCaptureIOHandle;
681 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700682 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700683 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700684 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700685
686 if (status == NO_ERROR) {
687 model->mState = Model::STATE_ACTIVE;
688 model->mConfig = *config;
689 }
690
691 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700692}
693
694status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
695{
696 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700697 if (mHalInterface == 0) {
698 return NO_INIT;
699 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700700 AutoMutex lock(mLock);
701 sp<Model> model = getModel(handle);
702 if (model == 0) {
703 return BAD_VALUE;
704 }
705
706 if (model->mState != Model::STATE_ACTIVE) {
707 return INVALID_OPERATION;
708 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700709 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700710 model->mState = Model::STATE_IDLE;
711 return NO_ERROR;
712}
713
mike dooley6e189b12018-11-07 15:44:37 +0100714status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000715{
716 ALOGV("getModelState() model handle %d", handle);
717 if (mHalInterface == 0) {
718 return NO_INIT;
719 }
720 AutoMutex lock(mLock);
721 sp<Model> model = getModel(handle);
722 if (model == 0) {
723 return BAD_VALUE;
724 }
725
726 if (model->mState != Model::STATE_ACTIVE) {
727 return INVALID_OPERATION;
728 }
729
mike dooley6e189b12018-11-07 15:44:37 +0100730 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000731}
732
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700733void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700734{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700735 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700736
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700737 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700738
739 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
740 return;
741 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700742 if (mModuleClients.isEmpty()) {
743 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700744 return;
745 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700746
Chris Thornton02b74212017-11-06 14:45:30 -0800747 Vector< sp<ModuleClient> > clients;
748
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700749 switch (event->mType) {
750 case CallbackEvent::TYPE_RECOGNITION: {
751 struct sound_trigger_recognition_event *recognitionEvent =
752 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700753 {
754 AutoMutex lock(mLock);
755 sp<Model> model = getModel(recognitionEvent->model);
756 if (model == 0) {
757 ALOGW("%s model == 0", __func__);
758 return;
759 }
760 if (model->mState != Model::STATE_ACTIVE) {
761 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
762 return;
763 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700764
Eric Laurent886561f2014-08-28 19:45:37 -0700765 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100766 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800767 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700768 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700769 } break;
770 case CallbackEvent::TYPE_SOUNDMODEL: {
771 struct sound_trigger_model_event *soundmodelEvent =
772 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700773 {
774 AutoMutex lock(mLock);
775 sp<Model> model = getModel(soundmodelEvent->model);
776 if (model == 0) {
777 ALOGW("%s model == 0", __func__);
778 return;
779 }
Chris Thornton02b74212017-11-06 14:45:30 -0800780 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700781 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700782 } break;
783 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700784 {
785 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700786 for (size_t i = 0; i < mModuleClients.size(); i++) {
787 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800788 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700789 }
790 }
Eric Laurent886561f2014-08-28 19:45:37 -0700791 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700792 } break;
793 default:
794 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
795 }
Chris Thornton02b74212017-11-06 14:45:30 -0800796
797 for (size_t i = 0; i < clients.size(); i++) {
798 clients[i]->onCallbackEvent(event);
799 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700800}
801
802sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
803 sound_model_handle_t handle)
804{
805 sp<Model> model;
806 ssize_t index = mModels.indexOfKey(handle);
807 if (index >= 0) {
808 model = mModels.valueAt(index);
809 }
810 return model;
811}
812
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700813// Called with mServiceLock held
814void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700815{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700816 ALOGV("Module::setCaptureState_l %d", active);
817 sp<SoundTriggerHwService> service;
818 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700819
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700820 Vector< sp<IMemory> > events;
821 {
822 AutoMutex lock(mLock);
823 state = (active && !mDescriptor.properties.concurrent_capture) ?
824 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700825
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700826 if (state == mServiceState) {
827 return;
828 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700829
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700830 mServiceState = state;
831
832 service = mService.promote();
833 if (service == 0) {
834 return;
835 }
836
837 if (state == SOUND_TRIGGER_STATE_ENABLED) {
838 goto exit;
839 }
840
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700841 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700842 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700843
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700844 for (size_t i = 0; i < mModels.size(); i++) {
845 sp<Model> model = mModels.valueAt(i);
846 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700847 if (mHalInterface != 0 && !supports_stop_all) {
848 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700849 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700850 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800851 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
852 struct sound_trigger_phrase_recognition_event event;
853 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
854 event.num_phrases = model->mConfig.num_phrases;
855 for (size_t i = 0; i < event.num_phrases; i++) {
856 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700857 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800858 event.common.status = RECOGNITION_STATUS_ABORT;
859 event.common.type = model->mType;
860 event.common.model = model->mHandle;
861 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700862 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800863 if (eventMemory != 0) {
864 events.add(eventMemory);
865 }
866 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
867 struct sound_trigger_generic_recognition_event event;
868 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
869 event.common.status = RECOGNITION_STATUS_ABORT;
870 event.common.type = model->mType;
871 event.common.model = model->mHandle;
872 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700873 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800874 if (eventMemory != 0) {
875 events.add(eventMemory);
876 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800877 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
878 struct sound_trigger_phrase_recognition_event event;
879 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
880 event.common.status = RECOGNITION_STATUS_ABORT;
881 event.common.type = model->mType;
882 event.common.model = model->mHandle;
883 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700884 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800885 if (eventMemory != 0) {
886 events.add(eventMemory);
887 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800888 } else {
889 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700890 }
891 }
892 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700893 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700894
895 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700896 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
897 events[i]);
898 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700899 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700900 }
901
902exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800903 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700904}
905
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700906
907SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
908 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700909 sound_trigger_sound_model_type_t type,
910 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700911 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700912 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
913 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700914{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700915}
916
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700917#undef LOG_TAG
918#define LOG_TAG "SoundTriggerHwService::ModuleClient"
919
920SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
jiabin68e0df72019-03-18 17:55:35 -0700921 const sp<ISoundTriggerClient>& client,
922 const String16& opPackageName)
923 : mModule(module), mClient(client), mOpPackageName(opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700924{
925}
926
927void SoundTriggerHwService::ModuleClient::onFirstRef()
928{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800929 sp<IBinder> binder = IInterface::asBinder(mClient);
930 if (binder != 0) {
931 binder->linkToDeath(this);
932 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700933}
934
935SoundTriggerHwService::ModuleClient::~ModuleClient()
936{
937}
938
939status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
940 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700941 String8 result;
942 return NO_ERROR;
943}
944
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700945void SoundTriggerHwService::ModuleClient::detach() {
946 ALOGV("detach()");
jiabin68e0df72019-03-18 17:55:35 -0700947 if (!captureHotwordAllowed(mOpPackageName,
948 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700949 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700950 return;
951 }
952
953 {
954 AutoMutex lock(mLock);
955 if (mClient != 0) {
956 IInterface::asBinder(mClient)->unlinkToDeath(this);
957 mClient.clear();
958 }
959 }
960
961 sp<Module> module = mModule.promote();
962 if (module == 0) {
963 return;
964 }
965 module->detach(this);
966}
967
968status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
969 sound_model_handle_t *handle)
970{
971 ALOGV("loadSoundModel() handle");
jiabin68e0df72019-03-18 17:55:35 -0700972 if (!captureHotwordAllowed(mOpPackageName,
973 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700974 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700975 return PERMISSION_DENIED;
976 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700977 if (checkIMemory(modelMemory) != NO_ERROR) {
978 return BAD_VALUE;
979 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700980
981 sp<Module> module = mModule.promote();
982 if (module == 0) {
983 return NO_INIT;
984 }
985 return module->loadSoundModel(modelMemory, this, handle);
986}
987
988status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
989{
990 ALOGV("unloadSoundModel() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -0700991 if (!captureHotwordAllowed(mOpPackageName,
992 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700993 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700994 return PERMISSION_DENIED;
995 }
996
997 sp<Module> module = mModule.promote();
998 if (module == 0) {
999 return NO_INIT;
1000 }
1001 return module->unloadSoundModel(handle);
1002}
1003
1004status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1005 const sp<IMemory>& dataMemory)
1006{
1007 ALOGV("startRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001008 if (!captureHotwordAllowed(mOpPackageName,
1009 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001010 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001011 return PERMISSION_DENIED;
1012 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001013 if (checkIMemory(dataMemory) != NO_ERROR) {
1014 return BAD_VALUE;
1015 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001016
1017 sp<Module> module = mModule.promote();
1018 if (module == 0) {
1019 return NO_INIT;
1020 }
1021 return module->startRecognition(handle, dataMemory);
1022}
1023
1024status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1025{
1026 ALOGV("stopRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001027 if (!captureHotwordAllowed(mOpPackageName,
1028 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001029 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001030 return PERMISSION_DENIED;
1031 }
1032
1033 sp<Module> module = mModule.promote();
1034 if (module == 0) {
1035 return NO_INIT;
1036 }
1037 return module->stopRecognition(handle);
1038}
1039
mike dooley6e189b12018-11-07 15:44:37 +01001040status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001041{
1042 ALOGV("getModelState() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001043 if (!captureHotwordAllowed(mOpPackageName,
1044 IPCThreadState::self()->getCallingPid(),
Michael Dooley67e3d412018-10-16 19:51:16 +00001045 IPCThreadState::self()->getCallingUid())) {
1046 return PERMISSION_DENIED;
1047 }
1048
1049 sp<Module> module = mModule.promote();
1050 if (module == 0) {
1051 return NO_INIT;
1052 }
mike dooley6e189b12018-11-07 15:44:37 +01001053 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001054}
1055
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001056void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1057{
1058 ALOGV("ModuleClient::setCaptureState_l %d", active);
1059 sp<SoundTriggerHwService> service;
1060 sound_trigger_service_state_t state;
1061
1062 sp<Module> module = mModule.promote();
1063 if (module == 0) {
1064 return;
1065 }
1066 {
1067 AutoMutex lock(mLock);
1068 state = (active && !module->isConcurrentCaptureAllowed()) ?
1069 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1070
1071 service = module->service().promote();
1072 if (service == 0) {
1073 return;
1074 }
1075 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001076 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001077}
1078
1079void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1080{
1081 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1082
1083 sp<IMemory> eventMemory = event->mMemory;
1084
1085 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1086 return;
1087 }
1088
Chris Thornton02b74212017-11-06 14:45:30 -08001089 sp<ISoundTriggerClient> client;
1090 {
1091 AutoMutex lock(mLock);
1092 client = mClient;
1093 }
1094
1095 if (client != 0) {
1096 switch (event->mType) {
1097 case CallbackEvent::TYPE_RECOGNITION: {
1098 client->onRecognitionEvent(eventMemory);
1099 } break;
1100 case CallbackEvent::TYPE_SOUNDMODEL: {
1101 client->onSoundModelEvent(eventMemory);
1102 } break;
1103 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001104 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001105 } break;
1106 default:
1107 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001108 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001109 }
1110}
1111
1112void SoundTriggerHwService::ModuleClient::binderDied(
1113 const wp<IBinder> &who __unused) {
1114 ALOGW("client binder died for client %p", this);
1115 detach();
1116}
1117
Eric Laurentb7a11d82014-04-18 17:40:41 -07001118}; // namespace android