blob: 51afdcd82e0b0bae612ee63d1865c231c9601341 [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
Ytai Ben-Tsvic25b0422019-09-18 15:24:09 -070043namespace {
44
45// Given an IMemory, returns a copy of its content along with its size.
46// Returns nullptr on failure or if input is nullptr.
47std::pair<std::unique_ptr<uint8_t[]>,
48 size_t> CopyToArray(const sp<IMemory>& mem) {
49 if (mem == nullptr) {
50 return std::make_pair(nullptr, 0);
51 }
52
53 const size_t size = mem->size();
54 if (size == 0) {
55 return std::make_pair(nullptr, 0);
56 }
57
58 std::unique_ptr<uint8_t[]> ar = std::make_unique<uint8_t[]>(size);
59 if (ar == nullptr) {
60 return std::make_pair(nullptr, 0);
61 }
62
63 memcpy(ar.get(), mem->pointer(), size);
64 return std::make_pair(std::move(ar), size);
65}
66
67}
68
Eric Laurentb7a11d82014-04-18 17:40:41 -070069SoundTriggerHwService::SoundTriggerHwService()
70 : BnSoundTriggerHwService(),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070071 mNextUniqueId(1),
72 mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
73 mCaptureState(false)
Eric Laurentb7a11d82014-04-18 17:40:41 -070074{
75}
76
77void SoundTriggerHwService::onFirstRef()
78{
Eric Laurentb7a11d82014-04-18 17:40:41 -070079 int rc;
Eric Laurentb7a11d82014-04-18 17:40:41 -070080
Eric Laurent7a544b42016-08-05 19:01:13 -070081 sp<SoundTriggerHalInterface> halInterface =
82 SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
Eric Laurentb7a11d82014-04-18 17:40:41 -070083
Eric Laurent7a544b42016-08-05 19:01:13 -070084 if (halInterface == 0) {
85 ALOGW("could not connect to HAL");
86 return;
87 }
Eric Laurentb7a11d82014-04-18 17:40:41 -070088 sound_trigger_module_descriptor descriptor;
Eric Laurent7a544b42016-08-05 19:01:13 -070089 rc = halInterface->getProperties(&descriptor.properties);
Eric Laurentb7a11d82014-04-18 17:40:41 -070090 if (rc != 0) {
91 ALOGE("could not read implementation properties");
92 return;
93 }
94 descriptor.handle =
95 (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
96 ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
97 descriptor.handle);
98
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -070099 sp<Module> module = new Module(this, halInterface, descriptor);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700100 mModules.add(descriptor.handle, module);
101 mCallbackThread = new CallbackThread(this);
102}
103
104SoundTriggerHwService::~SoundTriggerHwService()
105{
106 if (mCallbackThread != 0) {
107 mCallbackThread->exit();
108 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700109}
110
jiabin68e0df72019-03-18 17:55:35 -0700111status_t SoundTriggerHwService::listModules(const String16& opPackageName,
112 struct sound_trigger_module_descriptor *modules,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700113 uint32_t *numModules)
114{
115 ALOGV("listModules");
jiabin68e0df72019-03-18 17:55:35 -0700116 if (!captureHotwordAllowed(opPackageName,
117 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700118 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000119 return PERMISSION_DENIED;
120 }
121
Eric Laurentb7a11d82014-04-18 17:40:41 -0700122 AutoMutex lock(mServiceLock);
123 if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
124 return BAD_VALUE;
125 }
126 size_t maxModules = *numModules;
127 *numModules = mModules.size();
128 for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
129 modules[i] = mModules.valueAt(i)->descriptor();
130 }
131 return NO_ERROR;
132}
133
jiabin68e0df72019-03-18 17:55:35 -0700134status_t SoundTriggerHwService::attach(const String16& opPackageName,
135 const sound_trigger_module_handle_t handle,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700136 const sp<ISoundTriggerClient>& client,
137 sp<ISoundTrigger>& moduleInterface)
138{
139 ALOGV("attach module %d", handle);
jiabin68e0df72019-03-18 17:55:35 -0700140 if (!captureHotwordAllowed(opPackageName,
141 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700142 IPCThreadState::self()->getCallingUid())) {
Eric Laurent8ba53d82014-08-01 23:15:05 +0000143 return PERMISSION_DENIED;
144 }
145
Eric Laurentb7a11d82014-04-18 17:40:41 -0700146 AutoMutex lock(mServiceLock);
147 moduleInterface.clear();
148 if (client == 0) {
149 return BAD_VALUE;
150 }
151 ssize_t index = mModules.indexOfKey(handle);
152 if (index < 0) {
153 return BAD_VALUE;
154 }
155 sp<Module> module = mModules.valueAt(index);
156
jiabin68e0df72019-03-18 17:55:35 -0700157 sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700158 if (moduleClient == 0) {
159 return NO_INIT;
160 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700161
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700162 moduleClient->setCaptureState_l(mCaptureState);
163 moduleInterface = moduleClient;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700164
Eric Laurentb7a11d82014-04-18 17:40:41 -0700165 return NO_ERROR;
166}
167
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700168status_t SoundTriggerHwService::setCaptureState(bool active)
169{
170 ALOGV("setCaptureState %d", active);
171 AutoMutex lock(mServiceLock);
172 mCaptureState = active;
173 for (size_t i = 0; i < mModules.size(); i++) {
174 mModules.valueAt(i)->setCaptureState_l(active);
175 }
176 return NO_ERROR;
177}
178
179
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700180static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700181
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700182static bool dumpTryLock(Mutex& mutex)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700183{
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700184 status_t err = mutex.timedLock(kDumpLockTimeoutNs);
185 return err == NO_ERROR;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700186}
187
188status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
189 String8 result;
190 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
191 result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
192 write(fd, result.string(), result.size());
193 } else {
Mikhail Naganov959e2d02019-03-28 11:08:19 -0700194 bool locked = dumpTryLock(mServiceLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700195 // failed to lock - SoundTriggerHwService is probably deadlocked
196 if (!locked) {
197 result.append("SoundTriggerHwService may be deadlocked\n");
198 write(fd, result.string(), result.size());
199 }
200
201 if (locked) mServiceLock.unlock();
202 }
203 return NO_ERROR;
204}
205
206status_t SoundTriggerHwService::onTransact(
207 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
208 return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
209}
210
211
212// static
213void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
214 void *cookie)
215{
216 Module *module = (Module *)cookie;
217 if (module == NULL) {
218 return;
219 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700220 sp<SoundTriggerHwService> service = module->service().promote();
221 if (service == 0) {
222 return;
223 }
224
225 service->sendRecognitionEvent(event, module);
226}
227
Chris Thornton79c56612017-10-25 14:47:44 -0700228sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700229 struct sound_trigger_recognition_event *event)
230{
Chris Thornton79c56612017-10-25 14:47:44 -0700231 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700232 sp<IMemory> eventMemory;
233
234 //sanitize event
235 switch (event->type) {
236 case SOUND_MODEL_TYPE_KEYPHRASE:
237 ALOGW_IF(event->data_size != 0 && event->data_offset !=
238 sizeof(struct sound_trigger_phrase_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700239 "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700240 event->data_offset);
241 event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
242 break;
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800243 case SOUND_MODEL_TYPE_GENERIC:
244 ALOGW_IF(event->data_size != 0 && event->data_offset !=
245 sizeof(struct sound_trigger_generic_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700246 "prepareRecognitionEvent(): invalid data offset %u for generic event type",
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800247 event->data_offset);
248 event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
249 break;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700250 case SOUND_MODEL_TYPE_UNKNOWN:
251 ALOGW_IF(event->data_size != 0 && event->data_offset !=
252 sizeof(struct sound_trigger_recognition_event),
Chris Thornton79c56612017-10-25 14:47:44 -0700253 "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700254 event->data_offset);
255 event->data_offset = sizeof(struct sound_trigger_recognition_event);
256 break;
257 default:
Eric Laurent886561f2014-08-28 19:45:37 -0700258 return eventMemory;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700259 }
260
261 size_t size = event->data_offset + event->data_size;
262 eventMemory = mMemoryDealer->allocate(size);
263 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
264 eventMemory.clear();
265 return eventMemory;
266 }
267 memcpy(eventMemory->pointer(), event, size);
268
269 return eventMemory;
270}
271
272void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
273 Module *module)
Chris Thornton79c56612017-10-25 14:47:44 -0700274{
275 if (module == NULL) {
276 return;
277 }
278 sp<IMemory> eventMemory = prepareRecognitionEvent(event);
279 if (eventMemory == 0) {
280 return;
281 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700282
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700283 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
284 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700285 callbackEvent->setModule(module);
286 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700287}
288
289// static
290void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
291 void *cookie)
292{
293 Module *module = (Module *)cookie;
294 if (module == NULL) {
295 return;
296 }
297 sp<SoundTriggerHwService> service = module->service().promote();
298 if (service == 0) {
299 return;
300 }
301
302 service->sendSoundModelEvent(event, module);
303}
304
Chris Thornton79c56612017-10-25 14:47:44 -0700305sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700306{
Chris Thornton79c56612017-10-25 14:47:44 -0700307 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700308 sp<IMemory> eventMemory;
309
310 size_t size = event->data_offset + event->data_size;
311 eventMemory = mMemoryDealer->allocate(size);
312 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
313 eventMemory.clear();
314 return eventMemory;
315 }
316 memcpy(eventMemory->pointer(), event, size);
317
318 return eventMemory;
319}
320
321void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
322 Module *module)
323{
Chris Thornton79c56612017-10-25 14:47:44 -0700324 sp<IMemory> eventMemory = prepareSoundModelEvent(event);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700325 if (eventMemory == 0) {
326 return;
327 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700328 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
329 eventMemory);
Chris Thornton79c56612017-10-25 14:47:44 -0700330 callbackEvent->setModule(module);
331 sendCallbackEvent(callbackEvent);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700332}
333
334
Chris Thornton07405ee2017-11-14 20:45:27 -0800335sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700336{
Chris Thornton79c56612017-10-25 14:47:44 -0700337 AutoMutex lock(mMemoryDealerLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700338 sp<IMemory> eventMemory;
339
340 size_t size = sizeof(sound_trigger_service_state_t);
341 eventMemory = mMemoryDealer->allocate(size);
342 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
343 eventMemory.clear();
344 return eventMemory;
345 }
346 *((sound_trigger_service_state_t *)eventMemory->pointer()) = state;
347 return eventMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700348}
349
Chris Thornton07405ee2017-11-14 20:45:27 -0800350void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700351 Module *module)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700352{
Chris Thornton07405ee2017-11-14 20:45:27 -0800353 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700354 if (eventMemory == 0) {
355 return;
356 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700357 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
358 eventMemory);
Chris Thornton07405ee2017-11-14 20:45:27 -0800359 callbackEvent->setModule(module);
Chris Thornton79c56612017-10-25 14:47:44 -0700360 sendCallbackEvent(callbackEvent);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700361}
362
Chris Thornton07405ee2017-11-14 20:45:27 -0800363void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
364 ModuleClient *moduleClient)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700365{
Chris Thornton07405ee2017-11-14 20:45:27 -0800366 sp<IMemory> eventMemory = prepareServiceStateEvent(state);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700367 if (eventMemory == 0) {
368 return;
369 }
370 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
371 eventMemory);
372 callbackEvent->setModuleClient(moduleClient);
Chris Thornton79c56612017-10-25 14:47:44 -0700373 sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700374}
375
Chris Thornton79c56612017-10-25 14:47:44 -0700376void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700377{
378 mCallbackThread->sendCallbackEvent(event);
379}
380
381void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
382{
383 ALOGV("onCallbackEvent");
Eric Laurentb7a11d82014-04-18 17:40:41 -0700384 sp<Module> module;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700385 sp<ModuleClient> moduleClient;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700386 {
387 AutoMutex lock(mServiceLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700388 //CallbackEvent is either for Module or ModuleClient
Eric Laurentb7a11d82014-04-18 17:40:41 -0700389 module = event->mModule.promote();
390 if (module == 0) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700391 moduleClient = event->mModuleClient.promote();
392 if (moduleClient == 0) {
393 return;
394 }
Chris Thornton79c56612017-10-25 14:47:44 -0700395 } else {
396 // Sanity check on this being a Module we know about.
397 bool foundModule = false;
398 for (size_t i = 0; i < mModules.size(); i++) {
399 if (mModules.valueAt(i).get() == module.get()) {
400 foundModule = true;
401 break;
402 }
403 }
404 if (!foundModule) {
405 ALOGE("onCallbackEvent for unknown module");
406 return;
407 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700408 }
409 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700410 if (module != 0) {
411 ALOGV("onCallbackEvent for module");
412 module->onCallbackEvent(event);
413 } else if (moduleClient != 0) {
414 ALOGV("onCallbackEvent for moduleClient");
415 moduleClient->onCallbackEvent(event);
416 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700417 {
418 AutoMutex lock(mServiceLock);
419 // clear now to execute with mServiceLock locked
420 event->mMemory.clear();
421 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700422}
423
424#undef LOG_TAG
425#define LOG_TAG "SoundTriggerHwService::CallbackThread"
426
427SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
428 : mService(service)
429{
430}
431
432SoundTriggerHwService::CallbackThread::~CallbackThread()
433{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700434 while (!mEventQueue.isEmpty()) {
435 mEventQueue[0]->mMemory.clear();
436 mEventQueue.removeAt(0);
437 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700438}
439
440void SoundTriggerHwService::CallbackThread::onFirstRef()
441{
442 run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
443}
444
445bool SoundTriggerHwService::CallbackThread::threadLoop()
446{
447 while (!exitPending()) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700448 sp<CallbackEvent> event;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700449 sp<SoundTriggerHwService> service;
450 {
451 Mutex::Autolock _l(mCallbackLock);
452 while (mEventQueue.isEmpty() && !exitPending()) {
453 ALOGV("CallbackThread::threadLoop() sleep");
454 mCallbackCond.wait(mCallbackLock);
455 ALOGV("CallbackThread::threadLoop() wake up");
456 }
457 if (exitPending()) {
458 break;
459 }
460 event = mEventQueue[0];
461 mEventQueue.removeAt(0);
462 service = mService.promote();
463 }
464 if (service != 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700465 service->onCallbackEvent(event);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700466 }
467 }
468 return false;
469}
470
471void SoundTriggerHwService::CallbackThread::exit()
472{
473 Mutex::Autolock _l(mCallbackLock);
474 requestExit();
475 mCallbackCond.broadcast();
476}
477
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700478void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
479 const sp<SoundTriggerHwService::CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700480{
481 AutoMutex lock(mCallbackLock);
482 mEventQueue.add(event);
483 mCallbackCond.signal();
484}
485
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700486SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
487 : mType(type), mMemory(memory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700488{
489}
490
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700491SoundTriggerHwService::CallbackEvent::~CallbackEvent()
Eric Laurentb7a11d82014-04-18 17:40:41 -0700492{
493}
494
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700495
Eric Laurentb7a11d82014-04-18 17:40:41 -0700496#undef LOG_TAG
497#define LOG_TAG "SoundTriggerHwService::Module"
498
499SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
Eric Laurent7a544b42016-08-05 19:01:13 -0700500 const sp<SoundTriggerHalInterface>& halInterface,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700501 sound_trigger_module_descriptor descriptor)
Eric Laurent7a544b42016-08-05 19:01:13 -0700502 : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700503 mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700504{
505}
506
507SoundTriggerHwService::Module::~Module() {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700508 mModuleClients.clear();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700509}
510
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700511sp<SoundTriggerHwService::ModuleClient>
jiabin68e0df72019-03-18 17:55:35 -0700512SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
513 const String16& opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700514{
515 AutoMutex lock(mLock);
516 sp<ModuleClient> moduleClient;
517
518 for (size_t i = 0; i < mModuleClients.size(); i++) {
519 if (mModuleClients[i]->client() == client) {
520 // Client already present, reuse client
521 return moduleClient;
522 }
523 }
jiabin68e0df72019-03-18 17:55:35 -0700524 moduleClient = new ModuleClient(this, client, opPackageName);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700525
526 ALOGV("addClient() client %p", moduleClient.get());
527 mModuleClients.add(moduleClient);
528
529 return moduleClient;
530}
531
532void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
533{
534 ALOGV("Module::detach()");
Eric Laurent338e8ba2017-10-05 10:58:38 -0700535 Vector<audio_session_t> releasedSessions;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700536
Eric Laurent338e8ba2017-10-05 10:58:38 -0700537 {
538 AutoMutex lock(mLock);
539 ssize_t index = -1;
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700540
Eric Laurent338e8ba2017-10-05 10:58:38 -0700541 for (size_t i = 0; i < mModuleClients.size(); i++) {
542 if (mModuleClients[i] == moduleClient) {
543 index = i;
544 break;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700545 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700546 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700547 if (index == -1) {
548 return;
549 }
550
551 ALOGV("remove client %p", moduleClient.get());
552 mModuleClients.removeAt(index);
553
554 // Iterate in reverse order as models are removed from list inside the loop.
555 for (size_t i = mModels.size(); i > 0; i--) {
556 sp<Model> model = mModels.valueAt(i - 1);
557 if (moduleClient == model->mModuleClient) {
558 mModels.removeItemsAt(i - 1);
559 ALOGV("detach() unloading model %d", model->mHandle);
560 if (mHalInterface != 0) {
561 if (model->mState == Model::STATE_ACTIVE) {
562 mHalInterface->stopRecognition(model->mHandle);
563 }
564 mHalInterface->unloadSoundModel(model->mHandle);
565 }
566 releasedSessions.add(model->mCaptureSession);
567 }
568 }
569 }
570
571 for (size_t i = 0; i < releasedSessions.size(); i++) {
572 // do not call AudioSystem methods with mLock held
573 AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700574 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700575}
576
577status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700578 sp<ModuleClient> moduleClient,
579 sound_model_handle_t *handle)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700580{
581 ALOGV("loadSoundModel() handle");
Eric Laurent7a544b42016-08-05 19:01:13 -0700582 if (mHalInterface == 0) {
583 return NO_INIT;
584 }
Eric Laurent9b11c022018-06-06 19:19:22 -0700585
Ytai Ben-Tsvic25b0422019-09-18 15:24:09 -0700586 auto immutableMemory = CopyToArray(modelMemory);
587 if (immutableMemory.first == nullptr) {
588 return NO_MEMORY;
589 }
590
591 struct sound_trigger_sound_model* sound_model =
592 (struct sound_trigger_sound_model*) immutableMemory.first.get();
Eric Laurentb7a11d82014-04-18 17:40:41 -0700593
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700594 size_t structSize;
595 if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
596 structSize = sizeof(struct sound_trigger_phrase_sound_model);
597 } else {
598 structSize = sizeof(struct sound_trigger_sound_model);
599 }
600
601 if (sound_model->data_offset < structSize ||
Ytai Ben-Tsvic25b0422019-09-18 15:24:09 -0700602 sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
603 immutableMemory.second < sound_model->data_offset ||
604 sound_model->data_size >
605 (immutableMemory.second - sound_model->data_offset)) {
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700606 android_errorWriteLog(0x534e4554, "30148546");
607 ALOGE("loadSoundModel() data_size is too big");
608 return BAD_VALUE;
609 }
610
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700611 audio_session_t session;
612 audio_io_handle_t ioHandle;
613 audio_devices_t device;
Eric Laurent338e8ba2017-10-05 10:58:38 -0700614 // do not call AudioSystem methods with mLock held
615 status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700616 if (status != NO_ERROR) {
617 return status;
618 }
619
Eric Laurent338e8ba2017-10-05 10:58:38 -0700620 {
621 AutoMutex lock(mLock);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700622
Eric Laurent338e8ba2017-10-05 10:58:38 -0700623 if (mModels.size() >= mDescriptor.properties.max_sound_models) {
624 ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
625 mDescriptor.properties.max_sound_models);
626 status = INVALID_OPERATION;
627 goto exit;
628 }
629
630 status = mHalInterface->loadSoundModel(sound_model,
631 SoundTriggerHwService::soundModelCallback,
632 this, handle);
633 if (status != NO_ERROR) {
634 goto exit;
635 }
636
637 sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
638 moduleClient);
639 mModels.replaceValueFor(*handle, model);
640 }
641exit:
642 if (status != NO_ERROR) {
643 // do not call AudioSystem methods with mLock held
644 AudioSystem::releaseSoundTriggerSession(session);
645 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700646 return status;
647}
648
649status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
650{
651 ALOGV("unloadSoundModel() model handle %d", handle);
Eric Laurent338e8ba2017-10-05 10:58:38 -0700652 status_t status;
653 audio_session_t session;
Eric Laurent02eb47c2014-11-20 10:10:20 -0800654
Eric Laurent338e8ba2017-10-05 10:58:38 -0700655 {
656 AutoMutex lock(mLock);
657 if (mHalInterface == 0) {
658 return NO_INIT;
659 }
660 ssize_t index = mModels.indexOfKey(handle);
661 if (index < 0) {
662 return BAD_VALUE;
663 }
664 sp<Model> model = mModels.valueAt(index);
665 mModels.removeItem(handle);
666 if (model->mState == Model::STATE_ACTIVE) {
667 mHalInterface->stopRecognition(model->mHandle);
668 model->mState = Model::STATE_IDLE;
669 }
670 status = mHalInterface->unloadSoundModel(handle);
671 session = model->mCaptureSession;
Eric Laurent7a544b42016-08-05 19:01:13 -0700672 }
Eric Laurent338e8ba2017-10-05 10:58:38 -0700673 // do not call AudioSystem methods with mLock held
674 AudioSystem::releaseSoundTriggerSession(session);
675 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700676}
677
678status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700679 const sp<IMemory>& dataMemory)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700680{
681 ALOGV("startRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700682 if (mHalInterface == 0) {
683 return NO_INIT;
684 }
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700685
Ytai Ben-Tsvic25b0422019-09-18 15:24:09 -0700686 auto immutableMemory = CopyToArray(dataMemory);
687 if (immutableMemory.first == nullptr) {
688 return NO_MEMORY;
689 }
690
691 struct sound_trigger_recognition_config* config =
692 (struct sound_trigger_recognition_config*) immutableMemory.first.get();
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700693
694 if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
Ytai Ben-Tsvic25b0422019-09-18 15:24:09 -0700695 config->data_size > (UINT_MAX - config->data_offset) ||
696 immutableMemory.second < config->data_offset ||
697 config->data_size >
698 (immutableMemory.second - config->data_offset)) {
Eric Laurentbb00d8f2016-08-17 06:19:32 -0700699 ALOGE("startRecognition() data_size is too big");
700 return BAD_VALUE;
701 }
702
Eric Laurentb7a11d82014-04-18 17:40:41 -0700703 AutoMutex lock(mLock);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700704 if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
705 return INVALID_OPERATION;
706 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700707 sp<Model> model = getModel(handle);
708 if (model == 0) {
709 return BAD_VALUE;
710 }
711
712 if (model->mState == Model::STATE_ACTIVE) {
713 return INVALID_OPERATION;
714 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700715
Eric Laurentb7a11d82014-04-18 17:40:41 -0700716
717 //TODO: get capture handle and device from audio policy service
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700718 config->capture_handle = model->mCaptureIOHandle;
719 config->capture_device = model->mCaptureDevice;
Eric Laurent7a544b42016-08-05 19:01:13 -0700720 status_t status = mHalInterface->startRecognition(handle, config,
Eric Laurentb7a11d82014-04-18 17:40:41 -0700721 SoundTriggerHwService::recognitionCallback,
Eric Laurent0832b2d2014-07-06 16:17:25 -0700722 this);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700723
724 if (status == NO_ERROR) {
725 model->mState = Model::STATE_ACTIVE;
726 model->mConfig = *config;
727 }
728
729 return status;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700730}
731
732status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
733{
734 ALOGV("stopRecognition() model handle %d", handle);
Eric Laurent7a544b42016-08-05 19:01:13 -0700735 if (mHalInterface == 0) {
736 return NO_INIT;
737 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700738 AutoMutex lock(mLock);
739 sp<Model> model = getModel(handle);
740 if (model == 0) {
741 return BAD_VALUE;
742 }
743
744 if (model->mState != Model::STATE_ACTIVE) {
745 return INVALID_OPERATION;
746 }
Eric Laurent7a544b42016-08-05 19:01:13 -0700747 mHalInterface->stopRecognition(handle);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700748 model->mState = Model::STATE_IDLE;
749 return NO_ERROR;
750}
751
mike dooley6e189b12018-11-07 15:44:37 +0100752status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +0000753{
754 ALOGV("getModelState() model handle %d", handle);
755 if (mHalInterface == 0) {
756 return NO_INIT;
757 }
758 AutoMutex lock(mLock);
759 sp<Model> model = getModel(handle);
760 if (model == 0) {
761 return BAD_VALUE;
762 }
763
764 if (model->mState != Model::STATE_ACTIVE) {
765 return INVALID_OPERATION;
766 }
767
mike dooley6e189b12018-11-07 15:44:37 +0100768 return mHalInterface->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +0000769}
770
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700771void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700772{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700773 ALOGV("onCallbackEvent type %d", event->mType);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700774
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700775 sp<IMemory> eventMemory = event->mMemory;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700776
777 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
778 return;
779 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700780 if (mModuleClients.isEmpty()) {
781 ALOGI("%s no clients", __func__);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700782 return;
783 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700784
Chris Thornton02b74212017-11-06 14:45:30 -0800785 Vector< sp<ModuleClient> > clients;
786
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700787 switch (event->mType) {
788 case CallbackEvent::TYPE_RECOGNITION: {
789 struct sound_trigger_recognition_event *recognitionEvent =
790 (struct sound_trigger_recognition_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700791 {
792 AutoMutex lock(mLock);
793 sp<Model> model = getModel(recognitionEvent->model);
794 if (model == 0) {
795 ALOGW("%s model == 0", __func__);
796 return;
797 }
798 if (model->mState != Model::STATE_ACTIVE) {
799 ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
800 return;
801 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700802
Eric Laurent886561f2014-08-28 19:45:37 -0700803 recognitionEvent->capture_session = model->mCaptureSession;
mike dooleyfd018722019-01-04 09:31:31 +0100804 model->mState = Model::STATE_IDLE;
Chris Thornton02b74212017-11-06 14:45:30 -0800805 clients.add(model->mModuleClient);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700806 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700807 } break;
808 case CallbackEvent::TYPE_SOUNDMODEL: {
809 struct sound_trigger_model_event *soundmodelEvent =
810 (struct sound_trigger_model_event *)eventMemory->pointer();
Eric Laurent886561f2014-08-28 19:45:37 -0700811 {
812 AutoMutex lock(mLock);
813 sp<Model> model = getModel(soundmodelEvent->model);
814 if (model == 0) {
815 ALOGW("%s model == 0", __func__);
816 return;
817 }
Chris Thornton02b74212017-11-06 14:45:30 -0800818 clients.add(model->mModuleClient);
Eric Laurent886561f2014-08-28 19:45:37 -0700819 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700820 } break;
821 case CallbackEvent::TYPE_SERVICE_STATE: {
Eric Laurent886561f2014-08-28 19:45:37 -0700822 {
823 AutoMutex lock(mLock);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700824 for (size_t i = 0; i < mModuleClients.size(); i++) {
825 if (mModuleClients[i] != 0) {
Chris Thornton02b74212017-11-06 14:45:30 -0800826 clients.add(mModuleClients[i]);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700827 }
828 }
Eric Laurent886561f2014-08-28 19:45:37 -0700829 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700830 } break;
831 default:
832 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
833 }
Chris Thornton02b74212017-11-06 14:45:30 -0800834
835 for (size_t i = 0; i < clients.size(); i++) {
836 clients[i]->onCallbackEvent(event);
837 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700838}
839
840sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
841 sound_model_handle_t handle)
842{
843 sp<Model> model;
844 ssize_t index = mModels.indexOfKey(handle);
845 if (index >= 0) {
846 model = mModels.valueAt(index);
847 }
848 return model;
849}
850
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700851// Called with mServiceLock held
852void SoundTriggerHwService::Module::setCaptureState_l(bool active)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700853{
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700854 ALOGV("Module::setCaptureState_l %d", active);
855 sp<SoundTriggerHwService> service;
856 sound_trigger_service_state_t state;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700857
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700858 Vector< sp<IMemory> > events;
859 {
860 AutoMutex lock(mLock);
861 state = (active && !mDescriptor.properties.concurrent_capture) ?
862 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
Eric Laurentb7a11d82014-04-18 17:40:41 -0700863
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700864 if (state == mServiceState) {
865 return;
866 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700867
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700868 mServiceState = state;
869
870 service = mService.promote();
871 if (service == 0) {
872 return;
873 }
874
875 if (state == SOUND_TRIGGER_STATE_ENABLED) {
876 goto exit;
877 }
878
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700879 const bool supports_stop_all =
Chris Thorntonde22f8a2017-08-29 16:46:37 -0700880 (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700881
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700882 for (size_t i = 0; i < mModels.size(); i++) {
883 sp<Model> model = mModels.valueAt(i);
884 if (model->mState == Model::STATE_ACTIVE) {
Eric Laurent7a544b42016-08-05 19:01:13 -0700885 if (mHalInterface != 0 && !supports_stop_all) {
886 mHalInterface->stopRecognition(model->mHandle);
Chris Thorntonefcf16c2016-03-27 17:13:28 -0700887 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700888 // keep model in ACTIVE state so that event is processed by onCallbackEvent()
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800889 if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
890 struct sound_trigger_phrase_recognition_event event;
891 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
892 event.num_phrases = model->mConfig.num_phrases;
893 for (size_t i = 0; i < event.num_phrases; i++) {
894 event.phrase_extras[i] = model->mConfig.phrases[i];
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700895 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800896 event.common.status = RECOGNITION_STATUS_ABORT;
897 event.common.type = model->mType;
898 event.common.model = model->mHandle;
899 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700900 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800901 if (eventMemory != 0) {
902 events.add(eventMemory);
903 }
904 } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
905 struct sound_trigger_generic_recognition_event event;
906 memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
907 event.common.status = RECOGNITION_STATUS_ABORT;
908 event.common.type = model->mType;
909 event.common.model = model->mHandle;
910 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700911 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800912 if (eventMemory != 0) {
913 events.add(eventMemory);
914 }
Ryan Bavetta9609a912016-01-28 19:22:29 -0800915 } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
916 struct sound_trigger_phrase_recognition_event event;
917 memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
918 event.common.status = RECOGNITION_STATUS_ABORT;
919 event.common.type = model->mType;
920 event.common.model = model->mHandle;
921 event.common.data_size = 0;
Chris Thornton79c56612017-10-25 14:47:44 -0700922 sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
Ryan Bavetta9609a912016-01-28 19:22:29 -0800923 if (eventMemory != 0) {
924 events.add(eventMemory);
925 }
Ryan Bavetta00a727c2016-01-26 21:56:19 -0800926 } else {
927 goto exit;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700928 }
929 }
930 }
Eric Laurentb7a11d82014-04-18 17:40:41 -0700931 }
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700932
933 for (size_t i = 0; i < events.size(); i++) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700934 sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
935 events[i]);
936 callbackEvent->setModule(this);
Chris Thornton79c56612017-10-25 14:47:44 -0700937 service->sendCallbackEvent(callbackEvent);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700938 }
939
940exit:
Chris Thornton07405ee2017-11-14 20:45:27 -0800941 service->sendServiceStateEvent(state, this);
Eric Laurentb7a11d82014-04-18 17:40:41 -0700942}
943
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700944
945SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
946 audio_io_handle_t ioHandle, audio_devices_t device,
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700947 sound_trigger_sound_model_type_t type,
948 sp<ModuleClient>& moduleClient) :
Eric Laurentdf3dc7e2014-07-27 18:39:40 -0700949 mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700950 mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
951 mModuleClient(moduleClient)
Eric Laurentb7a11d82014-04-18 17:40:41 -0700952{
Eric Laurentb7a11d82014-04-18 17:40:41 -0700953}
954
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700955#undef LOG_TAG
956#define LOG_TAG "SoundTriggerHwService::ModuleClient"
957
958SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
jiabin68e0df72019-03-18 17:55:35 -0700959 const sp<ISoundTriggerClient>& client,
960 const String16& opPackageName)
961 : mModule(module), mClient(client), mOpPackageName(opPackageName)
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700962{
963}
964
965void SoundTriggerHwService::ModuleClient::onFirstRef()
966{
Chris Thorntonc8a9f4a2017-02-06 18:31:42 -0800967 sp<IBinder> binder = IInterface::asBinder(mClient);
968 if (binder != 0) {
969 binder->linkToDeath(this);
970 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700971}
972
973SoundTriggerHwService::ModuleClient::~ModuleClient()
974{
975}
976
977status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
978 const Vector<String16>& args __unused) {
Eric Laurentb7a11d82014-04-18 17:40:41 -0700979 String8 result;
980 return NO_ERROR;
981}
982
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700983void SoundTriggerHwService::ModuleClient::detach() {
984 ALOGV("detach()");
jiabin68e0df72019-03-18 17:55:35 -0700985 if (!captureHotwordAllowed(mOpPackageName,
986 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -0700987 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -0700988 return;
989 }
990
991 {
992 AutoMutex lock(mLock);
993 if (mClient != 0) {
994 IInterface::asBinder(mClient)->unlinkToDeath(this);
995 mClient.clear();
996 }
997 }
998
999 sp<Module> module = mModule.promote();
1000 if (module == 0) {
1001 return;
1002 }
1003 module->detach(this);
1004}
1005
1006status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
1007 sound_model_handle_t *handle)
1008{
1009 ALOGV("loadSoundModel() handle");
jiabin68e0df72019-03-18 17:55:35 -07001010 if (!captureHotwordAllowed(mOpPackageName,
1011 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001012 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001013 return PERMISSION_DENIED;
1014 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001015 if (checkIMemory(modelMemory) != NO_ERROR) {
1016 return BAD_VALUE;
1017 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001018
1019 sp<Module> module = mModule.promote();
1020 if (module == 0) {
1021 return NO_INIT;
1022 }
1023 return module->loadSoundModel(modelMemory, this, handle);
1024}
1025
1026status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
1027{
1028 ALOGV("unloadSoundModel() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001029 if (!captureHotwordAllowed(mOpPackageName,
1030 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001031 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001032 return PERMISSION_DENIED;
1033 }
1034
1035 sp<Module> module = mModule.promote();
1036 if (module == 0) {
1037 return NO_INIT;
1038 }
1039 return module->unloadSoundModel(handle);
1040}
1041
1042status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
1043 const sp<IMemory>& dataMemory)
1044{
1045 ALOGV("startRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001046 if (!captureHotwordAllowed(mOpPackageName,
1047 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001048 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001049 return PERMISSION_DENIED;
1050 }
Eric Laurent9b11c022018-06-06 19:19:22 -07001051 if (checkIMemory(dataMemory) != NO_ERROR) {
1052 return BAD_VALUE;
1053 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001054
1055 sp<Module> module = mModule.promote();
1056 if (module == 0) {
1057 return NO_INIT;
1058 }
1059 return module->startRecognition(handle, dataMemory);
1060}
1061
1062status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
1063{
1064 ALOGV("stopRecognition() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001065 if (!captureHotwordAllowed(mOpPackageName,
1066 IPCThreadState::self()->getCallingPid(),
Eric Laurent7504b9e2017-08-15 18:17:26 -07001067 IPCThreadState::self()->getCallingUid())) {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001068 return PERMISSION_DENIED;
1069 }
1070
1071 sp<Module> module = mModule.promote();
1072 if (module == 0) {
1073 return NO_INIT;
1074 }
1075 return module->stopRecognition(handle);
1076}
1077
mike dooley6e189b12018-11-07 15:44:37 +01001078status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
Michael Dooley67e3d412018-10-16 19:51:16 +00001079{
1080 ALOGV("getModelState() model handle %d", handle);
jiabin68e0df72019-03-18 17:55:35 -07001081 if (!captureHotwordAllowed(mOpPackageName,
1082 IPCThreadState::self()->getCallingPid(),
Michael Dooley67e3d412018-10-16 19:51:16 +00001083 IPCThreadState::self()->getCallingUid())) {
1084 return PERMISSION_DENIED;
1085 }
1086
1087 sp<Module> module = mModule.promote();
1088 if (module == 0) {
1089 return NO_INIT;
1090 }
mike dooley6e189b12018-11-07 15:44:37 +01001091 return module->getModelState(handle);
Michael Dooley67e3d412018-10-16 19:51:16 +00001092}
1093
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001094void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
1095{
1096 ALOGV("ModuleClient::setCaptureState_l %d", active);
1097 sp<SoundTriggerHwService> service;
1098 sound_trigger_service_state_t state;
1099
1100 sp<Module> module = mModule.promote();
1101 if (module == 0) {
1102 return;
1103 }
1104 {
1105 AutoMutex lock(mLock);
1106 state = (active && !module->isConcurrentCaptureAllowed()) ?
1107 SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
1108
1109 service = module->service().promote();
1110 if (service == 0) {
1111 return;
1112 }
1113 }
Chris Thornton07405ee2017-11-14 20:45:27 -08001114 service->sendServiceStateEvent(state, this);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001115}
1116
1117void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
1118{
1119 ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
1120
1121 sp<IMemory> eventMemory = event->mMemory;
1122
1123 if (eventMemory == 0 || eventMemory->pointer() == NULL) {
1124 return;
1125 }
1126
Chris Thornton02b74212017-11-06 14:45:30 -08001127 sp<ISoundTriggerClient> client;
1128 {
1129 AutoMutex lock(mLock);
1130 client = mClient;
1131 }
1132
1133 if (client != 0) {
1134 switch (event->mType) {
1135 case CallbackEvent::TYPE_RECOGNITION: {
1136 client->onRecognitionEvent(eventMemory);
1137 } break;
1138 case CallbackEvent::TYPE_SOUNDMODEL: {
1139 client->onSoundModelEvent(eventMemory);
1140 } break;
1141 case CallbackEvent::TYPE_SERVICE_STATE: {
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001142 client->onServiceStateChange(eventMemory);
Chris Thornton02b74212017-11-06 14:45:30 -08001143 } break;
1144 default:
1145 LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001146 }
Haynes Mathew Georgee52c5002016-10-12 17:27:18 -07001147 }
1148}
1149
1150void SoundTriggerHwService::ModuleClient::binderDied(
1151 const wp<IBinder> &who __unused) {
1152 ALOGW("client binder died for client %p", this);
1153 detach();
1154}
1155
Eric Laurentb7a11d82014-04-18 17:40:41 -07001156}; // namespace android