Migrate to new sound trigger middleware service
This change:
- Removes the old ISoundTriggerHw service and removes its code.
- Connects AudioPolicyManager to the new service via AIDL RPC (using
a new utility, BinderProxy).
Change-Id: I00366e2c5f252708e903b2311816d9eceb132a05
Bug: 142070343
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 00f14e1..c5cdc25 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -403,6 +403,12 @@
std::vector<effect_descriptor_t> effects,
audio_patch_handle_t patchHandle,
audio_source_t source) = 0;
+
+ // Used to notify the sound trigger module that an audio capture is about to
+ // take place. This should typically result in any active recognition
+ // sessions to be preempted on modules that do not support sound trigger
+ // recognition concurrently with audio capture.
+ virtual void setSoundTriggerCaptureState(bool active) = 0;
};
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
index 1fa0d19..577b42f 100644
--- a/services/audiopolicy/managerdefault/Android.bp
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -15,7 +15,6 @@
"libutils",
"liblog",
"libaudiopolicy",
- "libsoundtrigger",
"libmedia_helper",
"libmediametrics",
"libbinder",
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 9d80a16..2124646 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -46,7 +46,6 @@
#include <utils/Log.h>
#include <media/AudioParameter.h>
#include <private/android_filesystem_config.h>
-#include <soundtrigger/SoundTrigger.h>
#include <system/audio.h>
#include "AudioPolicyManager.h"
#include <Serializer.h>
@@ -2277,7 +2276,7 @@
DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if (primaryInputDevices.contains(device) &&
mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
- SoundTrigger::setCaptureState(true);
+ mpClientInterface->setSoundTriggerCaptureState(true);
}
// automatically enable the remote submix output when input is started if not
@@ -2360,7 +2359,7 @@
DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if (primaryInputDevices.contains(inputDesc->getDevice()) &&
mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
- SoundTrigger::setCaptureState(false);
+ mpClientInterface->setSoundTriggerCaptureState(false);
}
inputDesc->clearPreemptedSessions();
}
@@ -5075,7 +5074,7 @@
DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
if (primaryInputDevices.contains(device) &&
mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
- SoundTrigger::setCaptureState(false);
+ mpClientInterface->setSoundTriggerCaptureState(false);
}
cleanUpEffectsForIo(input);
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
index fdf3eae..80f4eab 100644
--- a/services/audiopolicy/service/Android.mk
+++ b/services/audiopolicy/service/Android.mk
@@ -31,7 +31,8 @@
libmediametrics \
libmediautils \
libeffectsconfig \
- libsensorprivacy
+ libsensorprivacy \
+ soundtrigger_middleware-aidl-cpp
LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
libsensorprivacy
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 6de0c80..5b81b9d 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -17,10 +17,13 @@
#define LOG_TAG "AudioPolicyClientImpl"
//#define LOG_NDEBUG 0
-#include <soundtrigger/SoundTrigger.h>
-#include <utils/Log.h>
#include "AudioPolicyService.h"
+#include <android/media/soundtrigger_middleware/ISoundTriggerMiddlewareService.h>
+#include <utils/Log.h>
+
+#include "BinderProxy.h"
+
namespace android {
/* implementation of the client interface from the policy manager */
@@ -239,4 +242,12 @@
return AudioSystem::newAudioUniqueId(use);
}
+void AudioPolicyService::AudioPolicyClient::setSoundTriggerCaptureState(bool active) {
+ using media::soundtrigger_middleware::ISoundTriggerMiddlewareService;
+
+ static BinderProxy<ISoundTriggerMiddlewareService>
+ proxy("soundtrigger_middleware");
+ proxy.waitServiceOrDie()->setExternalCaptureState(active);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c6fff63..135b3ac 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -717,6 +717,8 @@
virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
+ void setSoundTriggerCaptureState(bool active) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/service/BinderProxy.h b/services/audiopolicy/service/BinderProxy.h
new file mode 100644
index 0000000..516e84d
--- /dev/null
+++ b/services/audiopolicy/service/BinderProxy.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <type_traits>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// A simple utility that caches a proxy for a service and handles death notification.
+// Typically, intended to be used as a static-lifetime object.
+//
+// Example usage:
+// static BinderProxy<IMyInterface> myInterface("my_interface_svc");
+// ...
+// myInterface.waitServiceOrDie()->doSomething();
+//
+// If the service is unavailable, will wait until it becomes available.
+// Will die if the service doesn't implement the requested interface, or cannot be used for
+// permission reasons.
+template<typename ServiceType>
+class BinderProxy {
+public:
+ static_assert(std::is_base_of_v<IInterface, ServiceType>,
+ "Service type must be a sub-type of IInterface.");
+
+ explicit BinderProxy(std::string_view serviceName)
+ : mServiceName(serviceName), mDeathRecipient(new DeathRecipient(this)) {}
+
+ ~BinderProxy() {
+ if (mDelegate != nullptr) {
+ sp<IBinder> binder = IInterface::asBinder(mDelegate);
+ if (binder != nullptr) {
+ binder->unlinkToDeath(mDeathRecipient);
+ }
+ }
+ }
+
+ sp<ServiceType> waitServiceOrDie() {
+ std::lock_guard<std::mutex> _l(mDelegateMutex);
+ if (mDelegate == nullptr) {
+ mDelegate = waitForService<ServiceType>(String16(mServiceName.c_str()));
+ LOG_ALWAYS_FATAL_IF(mDelegate == nullptr,
+ "Service %s doesn't implement the required interface.",
+ mServiceName.c_str());
+ sp<IBinder> binder = IInterface::asBinder(mDelegate);
+ if (binder != nullptr) {
+ binder->linkToDeath(mDeathRecipient);
+ }
+ }
+ return mDelegate;
+ }
+
+private:
+ sp<ServiceType> mDelegate;
+ std::mutex mDelegateMutex;
+ const std::string mServiceName;
+ sp<IBinder::DeathRecipient> mDeathRecipient;
+
+ class DeathRecipient : public IBinder::DeathRecipient {
+ public:
+ DeathRecipient(BinderProxy* proxy) : mProxy(proxy) {}
+
+ void binderDied(const wp<IBinder>&) override {
+ mProxy->binderDied();
+ }
+
+ private:
+ BinderProxy* const mProxy;
+ };
+
+ void binderDied() {
+ std::lock_guard<std::mutex> _l(mDelegateMutex);
+ mDelegate.clear();
+ ALOGW("Binder died: %s", mServiceName.c_str());
+ }
+};
+
+} // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index b92a2e6..c628e70 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -86,6 +86,7 @@
void setEffectSuspended(int effectId __unused,
audio_session_t sessionId __unused,
bool suspended __unused) {}
+ void setSoundTriggerCaptureState(bool active __unused) override {};
};
} // namespace android
diff --git a/services/soundtrigger/Android.bp b/services/soundtrigger/Android.bp
deleted file mode 100644
index 600f4a3..0000000
--- a/services/soundtrigger/Android.bp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_library_shared {
- name: "libsoundtriggerservice",
-
- srcs: [
- "SoundTriggerHwService.cpp",
- "SoundTriggerHalHidl.cpp",
- ],
-
- shared_libs: [
- "liblog",
- "libutils",
- "libbinder",
- "libcutils",
- "libhardware",
- "libsoundtrigger",
- "libaudioclient",
- "libaudioutils",
- "libmediautils",
-
- "libhidlbase",
- "libhidlmemory",
- "libbase",
- "libaudiohal",
- "libaudiohal_deathhandler",
- "android.hardware.soundtrigger@2.0",
- "android.hardware.soundtrigger@2.1",
- "android.hardware.soundtrigger@2.2",
- "android.hardware.soundtrigger@2.3",
- "android.hardware.audio.common@2.0",
- "android.hidl.allocator@1.0",
- "android.hidl.memory@1.0",
- ],
-
- include_dirs: ["frameworks/av/services/audioflinger"],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-}
diff --git a/services/soundtrigger/OWNERS b/services/soundtrigger/OWNERS
deleted file mode 100644
index e83f6b9..0000000
--- a/services/soundtrigger/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-thorntonc@google.com
diff --git a/services/soundtrigger/SoundTriggerHalHidl.cpp b/services/soundtrigger/SoundTriggerHalHidl.cpp
deleted file mode 100644
index b1d34df..0000000
--- a/services/soundtrigger/SoundTriggerHalHidl.cpp
+++ /dev/null
@@ -1,999 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SoundTriggerHalHidl"
-//#define LOG_NDEBUG 0
-
-#include <android/hidl/allocator/1.0/IAllocator.h>
-#include <media/audiohal/hidl/HalDeathHandler.h>
-#include <utils/Log.h>
-#include "SoundTriggerHalHidl.h"
-#include <hidlmemory/mapping.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
-
-namespace android {
-
-using ::android::hardware::ProcessState;
-using ::android::hardware::Return;
-using ::android::hardware::Status;
-using ::android::hardware::Void;
-using ::android::hardware::audio::common::V2_0::AudioDevice;
-using ::android::hardware::hidl_memory;
-using ::android::hidl::allocator::V1_0::IAllocator;
-using ::android::hidl::memory::V1_0::IMemory;
-
-namespace {
-
-// Backs up by the vector with the contents of shared memory.
-// It is assumed that the passed hidl_vector is empty, so it's
-// not cleared if the memory is a null object.
-// The caller needs to keep the returned sp<IMemory> as long as
-// the data is needed.
-std::pair<bool, sp<IMemory>> memoryAsVector(const hidl_memory& m, hidl_vec<uint8_t>* vec) {
- sp<IMemory> memory;
- if (m.size() == 0) {
- return std::make_pair(true, memory);
- }
- memory = mapMemory(m);
- if (memory != nullptr) {
- memory->read();
- vec->setToExternal(static_cast<uint8_t*>(static_cast<void*>(memory->getPointer())),
- memory->getSize());
- return std::make_pair(true, memory);
- }
- ALOGE("%s: Could not map HIDL memory to IMemory", __func__);
- return std::make_pair(false, memory);
-}
-
-// Moves the data from the vector into allocated shared memory,
-// emptying the vector.
-// It is assumed that the passed hidl_memory is a null object, so it's
-// not reset if the vector is empty.
-// The caller needs to keep the returned sp<IMemory> as long as
-// the data is needed.
-std::pair<bool, sp<IMemory>> moveVectorToMemory(hidl_vec<uint8_t>* v, hidl_memory* mem) {
- sp<IMemory> memory;
- if (v->size() == 0) {
- return std::make_pair(true, memory);
- }
- sp<IAllocator> ashmem = IAllocator::getService("ashmem");
- if (ashmem == 0) {
- ALOGE("Failed to retrieve ashmem allocator service");
- return std::make_pair(false, memory);
- }
- bool success = false;
- Return<void> r = ashmem->allocate(v->size(), [&](bool s, const hidl_memory& m) {
- success = s;
- if (success) *mem = m;
- });
- if (r.isOk() && success) {
- memory = hardware::mapMemory(*mem);
- if (memory != 0) {
- memory->update();
- memcpy(memory->getPointer(), v->data(), v->size());
- memory->commit();
- v->resize(0);
- return std::make_pair(true, memory);
- } else {
- ALOGE("Failed to map allocated ashmem");
- }
- } else {
- ALOGE("Failed to allocate %llu bytes from ashmem", (unsigned long long)v->size());
- }
- return std::make_pair(false, memory);
-}
-
-} // namespace
-
-/* static */
-sp<SoundTriggerHalInterface> SoundTriggerHalInterface::connectModule(const char *moduleName)
-{
- return new SoundTriggerHalHidl(moduleName);
-}
-
-int SoundTriggerHalHidl::getProperties(struct sound_trigger_properties *properties)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- ISoundTriggerHw::Properties halProperties;
- Return<void> hidlReturn;
- int ret;
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->getProperties([&](int rc, auto res) {
- ret = rc;
- halProperties = res;
- ALOGI("getProperties res implementor %s", res.implementor.c_str());
- });
- }
-
- if (hidlReturn.isOk()) {
- if (ret == 0) {
- convertPropertiesFromHal(properties, &halProperties);
- }
- } else {
- ALOGE("getProperties error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
- ALOGI("getProperties ret %d", ret);
- return ret;
-}
-
-int SoundTriggerHalHidl::loadSoundModel(struct sound_trigger_sound_model *sound_model,
- sound_model_callback_t callback,
- void *cookie,
- sound_model_handle_t *handle)
-{
- if (handle == NULL) {
- return -EINVAL;
- }
-
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- uint32_t modelId;
- {
- AutoMutex lock(mLock);
- do {
- modelId = nextUniqueId();
- ALOGI("loadSoundModel modelId %u", modelId);
- sp<SoundModel> model = mSoundModels.valueFor(modelId);
- ALOGI("loadSoundModel model %p", model.get());
- } while (mSoundModels.valueFor(modelId) != 0 && modelId != 0);
- }
- LOG_ALWAYS_FATAL_IF(modelId == 0,
- "loadSoundModel(): wrap around in sound model IDs, num loaded models %zd",
- mSoundModels.size());
-
- Return<void> hidlReturn;
- int ret;
- SoundModelHandle halHandle;
- sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
- sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
- if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
- if (soundtrigger_2_2) {
- V2_2_ISoundTriggerHw::PhraseSoundModel halSoundModel;
- auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_2->loadPhraseSoundModel_2_1(
- halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- } else {
- return NO_MEMORY;
- }
- } else if (soundtrigger_2_1) {
- V2_1_ISoundTriggerHw::PhraseSoundModel halSoundModel;
- auto result = convertPhraseSoundModelToHal(&halSoundModel, sound_model);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_1->loadPhraseSoundModel_2_1(
- halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- } else {
- return NO_MEMORY;
- }
- } else {
- ISoundTriggerHw::PhraseSoundModel halSoundModel;
- convertPhraseSoundModelToHal(&halSoundModel, sound_model);
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->loadPhraseSoundModel(
- halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- }
- } else {
- if (soundtrigger_2_2) {
- V2_2_ISoundTriggerHw::SoundModel halSoundModel;
- auto result = convertSoundModelToHal(&halSoundModel, sound_model);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_2->loadSoundModel_2_1(halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- } else {
- return NO_MEMORY;
- }
- } else if (soundtrigger_2_1) {
- V2_1_ISoundTriggerHw::SoundModel halSoundModel;
- auto result = convertSoundModelToHal(&halSoundModel, sound_model);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_1->loadSoundModel_2_1(halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- } else {
- return NO_MEMORY;
- }
- } else {
- ISoundTriggerHw::SoundModel halSoundModel;
- convertSoundModelToHal(&halSoundModel, sound_model);
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->loadSoundModel(halSoundModel,
- this, modelId, [&](int32_t retval, auto res) {
- ret = retval;
- halHandle = res;
- });
- }
- }
-
- if (hidlReturn.isOk()) {
- if (ret == 0) {
- AutoMutex lock(mLock);
- *handle = (sound_model_handle_t)modelId;
- sp<SoundModel> model = new SoundModel(*handle, callback, cookie, halHandle);
- mSoundModels.add(*handle, model);
- }
- } else {
- ALOGE("loadSoundModel error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
-
- return ret;
-}
-
-int SoundTriggerHalHidl::unloadSoundModel(sound_model_handle_t handle)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- sp<SoundModel> model = removeModel(handle);
- if (model == 0) {
- ALOGE("unloadSoundModel model not found for handle %u", handle);
- return -EINVAL;
- }
-
- Return<int32_t> hidlReturn(0);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->unloadSoundModel(model->mHalHandle);
- }
-
- if (!hidlReturn.isOk()) {
- ALOGE("unloadSoundModel error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
-
- return hidlReturn;
-}
-
-int SoundTriggerHalHidl::startRecognition(sound_model_handle_t handle,
- const struct sound_trigger_recognition_config *config,
- recognition_callback_t callback,
- void *cookie)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (model == 0) {
- ALOGE("startRecognition model not found for handle %u", handle);
- return -EINVAL;
- }
-
- model->mRecognitionCallback = callback;
- model->mRecognitionCookie = cookie;
-
- sp<V2_1_ISoundTriggerHw> soundtrigger_2_1 = toService2_1(soundtrigger);
- sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
- Return<int32_t> hidlReturn(0);
-
- if (soundtrigger_2_2) {
- V2_2_ISoundTriggerHw::RecognitionConfig halConfig;
- auto result = convertRecognitionConfigToHal(&halConfig, config);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_2->startRecognition_2_1(
- model->mHalHandle, halConfig, this, handle);
- } else {
- return NO_MEMORY;
- }
- } else if (soundtrigger_2_1) {
- V2_1_ISoundTriggerHw::RecognitionConfig halConfig;
- auto result = convertRecognitionConfigToHal(&halConfig, config);
- if (result.first) {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_1->startRecognition_2_1(
- model->mHalHandle, halConfig, this, handle);
- } else {
- return NO_MEMORY;
- }
- } else {
- ISoundTriggerHw::RecognitionConfig halConfig;
- convertRecognitionConfigToHal(&halConfig, config);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->startRecognition(model->mHalHandle, halConfig, this, handle);
- }
- }
-
- if (!hidlReturn.isOk()) {
- ALOGE("startRecognition error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
- return hidlReturn;
-}
-
-int SoundTriggerHalHidl::stopRecognition(sound_model_handle_t handle)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (model == 0) {
- ALOGE("stopRecognition model not found for handle %u", handle);
- return -EINVAL;
- }
-
- Return<int32_t> hidlReturn(0);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->stopRecognition(model->mHalHandle);
- }
-
- if (!hidlReturn.isOk()) {
- ALOGE("stopRecognition error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
- return hidlReturn;
-}
-
-int SoundTriggerHalHidl::stopAllRecognitions()
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- Return<int32_t> hidlReturn(0);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger->stopAllRecognitions();
- }
-
- if (!hidlReturn.isOk()) {
- ALOGE("stopAllRecognitions error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
- return hidlReturn;
-}
-
-int SoundTriggerHalHidl::getModelState(sound_model_handle_t handle)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (soundtrigger == 0) {
- return -ENODEV;
- }
-
- sp<V2_2_ISoundTriggerHw> soundtrigger_2_2 = toService2_2(soundtrigger);
- if (soundtrigger_2_2 == 0) {
- ALOGE("getModelState not supported");
- return -ENODEV;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (model == 0) {
- ALOGE("getModelState model not found for handle %u", handle);
- return -EINVAL;
- }
-
- int ret = NO_ERROR;
- Return<int32_t> hidlReturn(0);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_2->getModelState(model->mHalHandle);
- }
- if (!hidlReturn.isOk()) {
- ALOGE("getModelState error %s", hidlReturn.description().c_str());
- ret = FAILED_TRANSACTION;
- }
- return ret;
-}
-
-int SoundTriggerHalHidl::setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param, int32_t value)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (!soundtrigger) {
- return -ENODEV;
- }
-
- sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
- if (!soundtrigger_2_3) {
- ALOGE("setParameter not supported");
- return -ENOSYS;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (!model) {
- ALOGE("setParameter model not found for handle %u", handle);
- return -EINVAL;
- }
-
- V2_3_ModelParameter halParam;
- convertModelParameterToHal(&halParam, model_param);
-
- Return<int32_t> hidlReturn(0);
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_3->setParameter(model->mHalHandle, halParam, value);
- }
- if (!hidlReturn.isOk()) {
- ALOGE("getModelState error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
-
- return hidlReturn;
-}
-
-int SoundTriggerHalHidl::getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param, int32_t* value)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (!soundtrigger) {
- return -ENODEV;
- }
-
- sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
- if (!soundtrigger_2_3) {
- ALOGE("getParameter not supported");
- return -ENOSYS;
- }
-
- if (value == NULL) {
- ALOGE("getParameter invalid value pointer");
- return -EINVAL;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (!model) {
- ALOGE("getParameter model not found for handle %u", handle);
- return -EINVAL;
- }
-
- V2_3_ModelParameter halParam;
- convertModelParameterToHal(&halParam, model_param);
-
- Return<void> hidlReturn;
- int32_t hidlStatus;
- int32_t hidlValue;
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_3->getParameter(model->mHalHandle, halParam,
- [&](int32_t retStatus, int32_t retValue) {
- hidlStatus = retStatus;
- hidlValue = retValue;
- });
- }
- if (!hidlReturn.isOk()) {
- ALOGE("getModelState error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
-
- *value = hidlValue;
- return hidlStatus;
-}
-
-int SoundTriggerHalHidl::queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param,
- sound_trigger_model_parameter_range_t* param_range)
-{
- sp<ISoundTriggerHw> soundtrigger = getService();
- if (!soundtrigger) {
- return -ENODEV;
- }
-
- sp<V2_3_ISoundTriggerHw> soundtrigger_2_3 = toService2_3(soundtrigger);
- if (!soundtrigger_2_3) {
- ALOGE("queryParameter not supported");
- return -ENOSYS;
- }
-
- sp<SoundModel> model = getModel(handle);
- if (!model) {
- ALOGE("queryParameter model not found for handle %u", handle);
- return -EINVAL;
- }
-
- V2_3_ModelParameter halParam;
- convertModelParameterToHal(&halParam, model_param);
-
- Return<void> hidlReturn;
- int32_t hidlStatus;
- V2_3_OptionalModelParameterRange hidlValue;
- {
- AutoMutex lock(mHalLock);
- hidlReturn = soundtrigger_2_3->queryParameter(model->mHalHandle, halParam,
- [&](int32_t retStatus, V2_3_OptionalModelParameterRange retValue) {
- hidlStatus = retStatus;
- hidlValue = retValue;
- });
- }
- if (!hidlReturn.isOk()) {
- ALOGE("queryParameter error %s", hidlReturn.description().c_str());
- return FAILED_TRANSACTION;
- }
-
- if (hidlStatus != 0) {
- ALOGE("queryParameter error code: %d", hidlStatus);
- return hidlStatus;
- }
-
- if (hidlValue.getDiscriminator() ==
- V2_3_OptionalModelParameterRange::hidl_discriminator::noinit) {
- return -1;
- }
-
- param_range->start = hidlValue.range().start;
- param_range->end = hidlValue.range().end;
-
- return 0;
-}
-
-SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
- : mModuleName(moduleName), mNextUniqueId(1)
-{
- LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
- "Treble soundtrigger only supports primary module");
-}
-
-SoundTriggerHalHidl::~SoundTriggerHalHidl()
-{
-}
-
-sp<ISoundTriggerHw> SoundTriggerHalHidl::getService()
-{
- AutoMutex lock(mLock);
- if (mISoundTrigger == 0) {
- if (mModuleName == NULL) {
- mModuleName = "primary";
- }
- mISoundTrigger = ISoundTriggerHw::getService();
- if (mISoundTrigger != 0) {
- mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
- }
- }
- return mISoundTrigger;
-}
-
-sp<V2_1_ISoundTriggerHw> SoundTriggerHalHidl::toService2_1(const sp<ISoundTriggerHw>& s)
-{
- auto castResult_2_1 = V2_1_ISoundTriggerHw::castFrom(s);
- return castResult_2_1.isOk() ? static_cast<sp<V2_1_ISoundTriggerHw>>(castResult_2_1) : nullptr;
-}
-
-sp<V2_2_ISoundTriggerHw> SoundTriggerHalHidl::toService2_2(const sp<ISoundTriggerHw>& s)
-{
- auto castResult_2_2 = V2_2_ISoundTriggerHw::castFrom(s);
- return castResult_2_2.isOk() ? static_cast<sp<V2_2_ISoundTriggerHw>>(castResult_2_2) : nullptr;
-}
-
-sp<V2_3_ISoundTriggerHw> SoundTriggerHalHidl::toService2_3(const sp<ISoundTriggerHw>& s)
-{
- auto castResult_3_0 = V2_3_ISoundTriggerHw::castFrom(s);
- return castResult_3_0.isOk() ? static_cast<sp<V2_3_ISoundTriggerHw>>(castResult_3_0) : nullptr;
-}
-
-sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::getModel(sound_model_handle_t handle)
-{
- AutoMutex lock(mLock);
- return mSoundModels.valueFor(handle);
-}
-
-sp<SoundTriggerHalHidl::SoundModel> SoundTriggerHalHidl::removeModel(sound_model_handle_t handle)
-{
- AutoMutex lock(mLock);
- sp<SoundModel> model = mSoundModels.valueFor(handle);
- mSoundModels.removeItem(handle);
- return model;
-}
-
-uint32_t SoundTriggerHalHidl::nextUniqueId()
-{
- return (uint32_t) atomic_fetch_add_explicit(&mNextUniqueId,
- (uint_fast32_t) 1, memory_order_acq_rel);
-}
-
-void SoundTriggerHalHidl::convertUuidToHal(Uuid *halUuid,
- const sound_trigger_uuid_t *uuid)
-{
- halUuid->timeLow = uuid->timeLow;
- halUuid->timeMid = uuid->timeMid;
- halUuid->versionAndTimeHigh = uuid->timeHiAndVersion;
- halUuid->variantAndClockSeqHigh = uuid->clockSeq;
- memcpy(halUuid->node.data(), &uuid->node[0], sizeof(uuid->node));
-}
-
-void SoundTriggerHalHidl::convertUuidFromHal(sound_trigger_uuid_t *uuid,
- const Uuid *halUuid)
-{
- uuid->timeLow = halUuid->timeLow;
- uuid->timeMid = halUuid->timeMid;
- uuid->timeHiAndVersion = halUuid->versionAndTimeHigh;
- uuid->clockSeq = halUuid->variantAndClockSeqHigh;
- memcpy(&uuid->node[0], halUuid->node.data(), sizeof(uuid->node));
-}
-
-void SoundTriggerHalHidl::convertPropertiesFromHal(
- struct sound_trigger_properties *properties,
- const ISoundTriggerHw::Properties *halProperties)
-{
- strlcpy(properties->implementor,
- halProperties->implementor.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
- strlcpy(properties->description,
- halProperties->description.c_str(), SOUND_TRIGGER_MAX_STRING_LEN);
- properties->version = halProperties->version;
- convertUuidFromHal(&properties->uuid, &halProperties->uuid);
- properties->max_sound_models = halProperties->maxSoundModels;
- properties->max_key_phrases = halProperties->maxKeyPhrases;
- properties->max_users = halProperties->maxUsers;
- properties->recognition_modes = halProperties->recognitionModes;
- properties->capture_transition = (bool)halProperties->captureTransition;
- properties->max_buffer_ms = halProperties->maxBufferMs;
- properties->concurrent_capture = (bool)halProperties->concurrentCapture;
- properties->trigger_in_event = (bool)halProperties->triggerInEvent;
- properties->power_consumption_mw = halProperties->powerConsumptionMw;
-}
-
-// static
-void SoundTriggerHalHidl::convertModelParameterToHal(V2_3_ModelParameter* halParam,
- sound_trigger_model_parameter_t param)
-{
- switch (param) {
- case MODEL_PARAMETER_THRESHOLD_FACTOR:
- *halParam = V2_3_ModelParameter::THRESHOLD_FACTOR;
- return;
- case MODEL_PARAMETER_INVALID:
- default:
- *halParam = V2_3_ModelParameter::INVALID;
- }
-}
-
-void SoundTriggerHalHidl::convertTriggerPhraseToHal(
- ISoundTriggerHw::Phrase *halTriggerPhrase,
- const struct sound_trigger_phrase *triggerPhrase)
-{
- halTriggerPhrase->id = triggerPhrase->id;
- halTriggerPhrase->recognitionModes = triggerPhrase->recognition_mode;
- halTriggerPhrase->users.setToExternal((uint32_t *)&triggerPhrase->users[0], triggerPhrase->num_users);
- halTriggerPhrase->locale = triggerPhrase->locale;
- halTriggerPhrase->text = triggerPhrase->text;
-}
-
-
-void SoundTriggerHalHidl::convertTriggerPhrasesToHal(
- hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
- struct sound_trigger_phrase_sound_model *keyPhraseModel)
-{
- halTriggerPhrases->resize(keyPhraseModel->num_phrases);
- for (unsigned int i = 0; i < keyPhraseModel->num_phrases; i++) {
- convertTriggerPhraseToHal(&(*halTriggerPhrases)[i], &keyPhraseModel->phrases[i]);
- }
-}
-
-void SoundTriggerHalHidl::convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
- const struct sound_trigger_sound_model *soundModel)
-{
- halModel->type = (SoundModelType)soundModel->type;
- convertUuidToHal(&halModel->uuid, &soundModel->uuid);
- convertUuidToHal(&halModel->vendorUuid, &soundModel->vendor_uuid);
- halModel->data.setToExternal((uint8_t *)soundModel + soundModel->data_offset, soundModel->data_size);
-}
-
-std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertSoundModelToHal(
- V2_1_ISoundTriggerHw::SoundModel *halModel,
- const struct sound_trigger_sound_model *soundModel)
-{
- convertSoundModelToHal(&halModel->header, soundModel);
- return moveVectorToMemory(&halModel->header.data, &halModel->data);
-}
-
-void SoundTriggerHalHidl::convertPhraseSoundModelToHal(
- ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
- const struct sound_trigger_sound_model *soundModel)
-{
- struct sound_trigger_phrase_sound_model *keyPhraseModel =
- (struct sound_trigger_phrase_sound_model *)soundModel;
- convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
- convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
-}
-
-std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertPhraseSoundModelToHal(
- V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
- const struct sound_trigger_sound_model *soundModel)
-{
- struct sound_trigger_phrase_sound_model *keyPhraseModel =
- (struct sound_trigger_phrase_sound_model *)soundModel;
- convertTriggerPhrasesToHal(&halKeyPhraseModel->phrases, keyPhraseModel);
- return convertSoundModelToHal(&halKeyPhraseModel->common, soundModel);
-}
-
-void SoundTriggerHalHidl::convertPhraseRecognitionExtraToHal(
- PhraseRecognitionExtra *halExtra,
- const struct sound_trigger_phrase_recognition_extra *extra)
-{
- halExtra->id = extra->id;
- halExtra->recognitionModes = extra->recognition_modes;
- halExtra->confidenceLevel = extra->confidence_level;
- halExtra->levels.resize(extra->num_levels);
- for (unsigned int i = 0; i < extra->num_levels; i++) {
- halExtra->levels[i].userId = extra->levels[i].user_id;
- halExtra->levels[i].levelPercent = extra->levels[i].level;
- }
-}
-
-void SoundTriggerHalHidl::convertRecognitionConfigToHal(
- ISoundTriggerHw::RecognitionConfig *halConfig,
- const struct sound_trigger_recognition_config *config)
-{
- halConfig->captureHandle = config->capture_handle;
- halConfig->captureDevice = (AudioDevice)config->capture_device;
- halConfig->captureRequested = (uint32_t)config->capture_requested;
-
- halConfig->phrases.resize(config->num_phrases);
- for (unsigned int i = 0; i < config->num_phrases; i++) {
- convertPhraseRecognitionExtraToHal(&halConfig->phrases[i],
- &config->phrases[i]);
- }
-
- halConfig->data.setToExternal((uint8_t *)config + config->data_offset, config->data_size);
-}
-
-std::pair<bool, sp<IMemory>> SoundTriggerHalHidl::convertRecognitionConfigToHal(
- V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
- const struct sound_trigger_recognition_config *config)
-{
- convertRecognitionConfigToHal(&halConfig->header, config);
- return moveVectorToMemory(&halConfig->header.data, &halConfig->data);
-}
-
-
-// ISoundTriggerHwCallback
-::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback(
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent& halEvent,
- CallbackCookie cookie)
-{
- sp<SoundModel> model;
- {
- AutoMutex lock(mLock);
- model = mSoundModels.valueFor((SoundModelHandle)cookie);
- if (model == 0) {
- return Return<void>();
- }
- }
- struct sound_trigger_recognition_event *event = convertRecognitionEventFromHal(&halEvent);
- if (event == NULL) {
- return Return<void>();
- }
- event->model = model->mHandle;
- model->mRecognitionCallback(event, model->mRecognitionCookie);
-
- free(event);
-
- return Return<void>();
-}
-
-::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback(
- const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& halEvent,
- CallbackCookie cookie)
-{
- sp<SoundModel> model;
- {
- AutoMutex lock(mLock);
- model = mSoundModels.valueFor((SoundModelHandle)cookie);
- if (model == 0) {
- return Return<void>();
- }
- }
-
- struct sound_trigger_phrase_recognition_event *event =
- convertPhraseRecognitionEventFromHal(&halEvent);
- if (event == NULL) {
- return Return<void>();
- }
- event->common.model = model->mHandle;
- model->mRecognitionCallback(&event->common, model->mRecognitionCookie);
-
- free(event);
-
- return Return<void>();
-}
-
-::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback(
- const V2_0_ISoundTriggerHwCallback::ModelEvent& halEvent,
- CallbackCookie cookie)
-{
- sp<SoundModel> model;
- {
- AutoMutex lock(mLock);
- model = mSoundModels.valueFor((SoundModelHandle)cookie);
- if (model == 0) {
- return Return<void>();
- }
- }
-
- struct sound_trigger_model_event *event = convertSoundModelEventFromHal(&halEvent);
- if (event == NULL) {
- return Return<void>();
- }
-
- event->model = model->mHandle;
- model->mSoundModelCallback(event, model->mSoundModelCookie);
-
- free(event);
-
- return Return<void>();
-}
-
-::android::hardware::Return<void> SoundTriggerHalHidl::recognitionCallback_2_1(
- const ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie) {
- // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
- V2_0_ISoundTriggerHwCallback::RecognitionEvent event_2_0 = event.header;
- auto result = memoryAsVector(event.data, &event_2_0.data);
- return result.first ? recognitionCallback(event_2_0, cookie) : Void();
-}
-
-::android::hardware::Return<void> SoundTriggerHalHidl::phraseRecognitionCallback_2_1(
- const ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie) {
- V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent event_2_0;
- // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
- event_2_0.common = event.common.header;
- event_2_0.phraseExtras.setToExternal(
- const_cast<PhraseRecognitionExtra*>(event.phraseExtras.data()),
- event.phraseExtras.size());
- auto result = memoryAsVector(event.common.data, &event_2_0.common.data);
- return result.first ? phraseRecognitionCallback(event_2_0, cookie) : Void();
-}
-
-::android::hardware::Return<void> SoundTriggerHalHidl::soundModelCallback_2_1(
- const ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie) {
- // The data vector in the 'header' part of V2.1 structure is empty, thus copying is cheap.
- V2_0_ISoundTriggerHwCallback::ModelEvent event_2_0 = event.header;
- auto result = memoryAsVector(event.data, &event_2_0.data);
- return result.first ? soundModelCallback(event_2_0, cookie) : Void();
-}
-
-
-struct sound_trigger_model_event *SoundTriggerHalHidl::convertSoundModelEventFromHal(
- const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent)
-{
- struct sound_trigger_model_event *event = (struct sound_trigger_model_event *)malloc(
- sizeof(struct sound_trigger_model_event) +
- halEvent->data.size());
- if (event == NULL) {
- return NULL;
- }
-
- event->status = (int)halEvent->status;
- // event->model to be set by caller
- event->data_offset = sizeof(struct sound_trigger_model_event);
- event->data_size = halEvent->data.size();
- uint8_t *dst = (uint8_t *)event + event->data_offset;
- uint8_t *src = (uint8_t *)&halEvent->data[0];
- memcpy(dst, src, halEvent->data.size());
-
- return event;
-}
-
-void SoundTriggerHalHidl::convertPhraseRecognitionExtraFromHal(
- struct sound_trigger_phrase_recognition_extra *extra,
- const PhraseRecognitionExtra *halExtra)
-{
- extra->id = halExtra->id;
- extra->recognition_modes = halExtra->recognitionModes;
- extra->confidence_level = halExtra->confidenceLevel;
-
- size_t i;
- for (i = 0; i < halExtra->levels.size() && i < SOUND_TRIGGER_MAX_USERS; i++) {
- extra->levels[i].user_id = halExtra->levels[i].userId;
- extra->levels[i].level = halExtra->levels[i].levelPercent;
- }
- extra->num_levels = (unsigned int)i;
-}
-
-
-struct sound_trigger_phrase_recognition_event* SoundTriggerHalHidl::convertPhraseRecognitionEventFromHal(
- const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent)
-{
- if (halPhraseEvent->common.type != SoundModelType::KEYPHRASE) {
- ALOGE("Received non-keyphrase event type as PhraseRecognitionEvent");
- return NULL;
- }
- struct sound_trigger_phrase_recognition_event *phraseEvent =
- (struct sound_trigger_phrase_recognition_event *)malloc(
- sizeof(struct sound_trigger_phrase_recognition_event) +
- halPhraseEvent->common.data.size());
- if (phraseEvent == NULL) {
- return NULL;
- }
- phraseEvent->common.data_offset = sizeof(sound_trigger_phrase_recognition_event);
-
- for (unsigned int i = 0; i < halPhraseEvent->phraseExtras.size(); i++) {
- convertPhraseRecognitionExtraFromHal(&phraseEvent->phrase_extras[i],
- &halPhraseEvent->phraseExtras[i]);
- }
- phraseEvent->num_phrases = halPhraseEvent->phraseExtras.size();
-
- fillRecognitionEventFromHal(&phraseEvent->common, &halPhraseEvent->common);
- return phraseEvent;
-}
-
-struct sound_trigger_recognition_event *SoundTriggerHalHidl::convertRecognitionEventFromHal(
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
-{
- if (halEvent->type == SoundModelType::KEYPHRASE) {
- ALOGE("Received keyphrase event type as RecognitionEvent");
- return NULL;
- }
- struct sound_trigger_recognition_event *event;
- event = (struct sound_trigger_recognition_event *)malloc(
- sizeof(struct sound_trigger_recognition_event) + halEvent->data.size());
- if (event == NULL) {
- return NULL;
- }
- event->data_offset = sizeof(sound_trigger_recognition_event);
-
- fillRecognitionEventFromHal(event, halEvent);
- return event;
-}
-
-void SoundTriggerHalHidl::fillRecognitionEventFromHal(
- struct sound_trigger_recognition_event *event,
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent)
-{
- event->status = (int)halEvent->status;
- event->type = (sound_trigger_sound_model_type_t)halEvent->type;
- // event->model to be set by caller
- event->capture_available = (bool)halEvent->captureAvailable;
- event->capture_session = halEvent->captureSession;
- event->capture_delay_ms = halEvent->captureDelayMs;
- event->capture_preamble_ms = halEvent->capturePreambleMs;
- event->trigger_in_data = (bool)halEvent->triggerInData;
- event->audio_config.sample_rate = halEvent->audioConfig.sampleRateHz;
- event->audio_config.channel_mask = (audio_channel_mask_t)halEvent->audioConfig.channelMask;
- event->audio_config.format = (audio_format_t)halEvent->audioConfig.format;
-
- event->data_size = halEvent->data.size();
- uint8_t *dst = (uint8_t *)event + event->data_offset;
- uint8_t *src = (uint8_t *)&halEvent->data[0];
- memcpy(dst, src, halEvent->data.size());
-}
-
-} // namespace android
diff --git a/services/soundtrigger/SoundTriggerHalHidl.h b/services/soundtrigger/SoundTriggerHalHidl.h
deleted file mode 100644
index 25878d0..0000000
--- a/services/soundtrigger/SoundTriggerHalHidl.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_HIDL_H
-#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_HIDL_H
-
-#include <utility>
-
-#include <stdatomic.h>
-#include <utils/RefBase.h>
-#include <utils/KeyedVector.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-#include "SoundTriggerHalInterface.h"
-#include <android/hardware/soundtrigger/2.0/types.h>
-#include <android/hardware/soundtrigger/2.3/types.h>
-#include <android/hardware/soundtrigger/2.1/ISoundTriggerHw.h>
-#include <android/hardware/soundtrigger/2.2/ISoundTriggerHw.h>
-#include <android/hardware/soundtrigger/2.3/ISoundTriggerHw.h>
-#include <android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h>
-#include <android/hardware/soundtrigger/2.1/ISoundTriggerHwCallback.h>
-
-namespace android {
-
-using ::android::hardware::audio::common::V2_0::Uuid;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::soundtrigger::V2_0::ConfidenceLevel;
-using ::android::hardware::soundtrigger::V2_0::PhraseRecognitionExtra;
-using ::android::hardware::soundtrigger::V2_0::SoundModelType;
-using ::android::hardware::soundtrigger::V2_0::SoundModelHandle;
-using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
-using V2_0_ISoundTriggerHwCallback =
- ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback;
-using V2_1_ISoundTriggerHw =
- ::android::hardware::soundtrigger::V2_1::ISoundTriggerHw;
-using V2_1_ISoundTriggerHwCallback =
- ::android::hardware::soundtrigger::V2_1::ISoundTriggerHwCallback;
-using ::android::hidl::memory::V1_0::IMemory;
-using V2_2_ISoundTriggerHw =
- ::android::hardware::soundtrigger::V2_2::ISoundTriggerHw;
-using V2_3_ISoundTriggerHw =
- ::android::hardware::soundtrigger::V2_3::ISoundTriggerHw;
-using V2_3_ModelParameter =
- ::android::hardware::soundtrigger::V2_3::ModelParameter;
-using V2_3_OptionalModelParameterRange =
- ::android::hardware::soundtrigger::V2_3::OptionalModelParameterRange;
-
-class SoundTriggerHalHidl : public SoundTriggerHalInterface,
- public virtual V2_1_ISoundTriggerHwCallback
-
-{
-public:
- virtual int getProperties(struct sound_trigger_properties *properties);
-
- /*
- * Load a sound model. Once loaded, recognition of this model can be started and stopped.
- * Only one active recognition per model at a time. The SoundTrigger service will handle
- * concurrent recognition requests by different users/applications on the same model.
- * The implementation returns a unique handle used by other functions (unload_sound_model(),
- * start_recognition(), etc...
- */
- virtual int loadSoundModel(struct sound_trigger_sound_model *sound_model,
- sound_model_callback_t callback,
- void *cookie,
- sound_model_handle_t *handle);
-
- /*
- * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome
- * implementation limitations.
- */
- virtual int unloadSoundModel(sound_model_handle_t handle);
-
- /* Start recognition on a given model. Only one recognition active at a time per model.
- * Once recognition succeeds of fails, the callback is called.
- * TODO: group recognition configuration parameters into one struct and add key phrase options.
- */
- virtual int startRecognition(sound_model_handle_t handle,
- const struct sound_trigger_recognition_config *config,
- recognition_callback_t callback,
- void *cookie);
-
- /* Stop recognition on a given model.
- * The implementation does not have to call the callback when stopped via this method.
- */
- virtual int stopRecognition(sound_model_handle_t handle);
-
- /* Stop recognition on all models.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_1 or above.
- * If no implementation is provided, stop_recognition will be called for each running model.
- */
- virtual int stopAllRecognitions();
-
- /* Get the current state of a given model.
- * Returns 0 or an error code. If successful the state will be returned asynchronously
- * via a recognition event in the callback method that was registered in the
- * startRecognition() method.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
- */
- virtual int getModelState(sound_model_handle_t handle);
-
- /* Set a model specific ModelParameter with the given value. This parameter
- * will keep its value for the duration the model is loaded regardless of starting and
- * stopping recognition. Once the model is unloaded, the value will be lost.
- * Returns 0 or an error code.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_3 or above.
- */
- int setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param, int32_t value);
-
- /* Get a model specific ModelParameter. This parameter will keep its value
- * for the duration the model is loaded regardless of starting and stopping recognition.
- * Once the model is unloaded, the value will be lost. If the value is not set, a default
- * value is returned. See sound_trigger_model_parameter_t for parameter default values.
- * Returns 0 or an error code. On return 0, value pointer will be set.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_3 or above.
- */
- int getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param, int32_t* value);
-
- /* Get supported parameter attributes with respect to the provided model
- * handle. Along with determining the valid range, this API is also used
- * to determine if a given parameter ID is supported at all by the
- * modelHandle for use with getParameter and setParameter APIs.
- */
- int queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param,
- sound_trigger_model_parameter_range_t* param_range);
-
- // ISoundTriggerHwCallback
- virtual ::android::hardware::Return<void> recognitionCallback(
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent& event, CallbackCookie cookie);
- virtual ::android::hardware::Return<void> phraseRecognitionCallback(
- const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent& event, int32_t cookie);
- virtual ::android::hardware::Return<void> soundModelCallback(
- const V2_0_ISoundTriggerHwCallback::ModelEvent& event, CallbackCookie cookie);
- virtual ::android::hardware::Return<void> recognitionCallback_2_1(
- const RecognitionEvent& event, CallbackCookie cookie);
- virtual ::android::hardware::Return<void> phraseRecognitionCallback_2_1(
- const PhraseRecognitionEvent& event, int32_t cookie);
- virtual ::android::hardware::Return<void> soundModelCallback_2_1(
- const ModelEvent& event, CallbackCookie cookie);
-private:
- class SoundModel : public RefBase {
- public:
- SoundModel(sound_model_handle_t handle, sound_model_callback_t callback,
- void *cookie, android::hardware::soundtrigger::V2_0::SoundModelHandle halHandle)
- : mHandle(handle), mHalHandle(halHandle),
- mSoundModelCallback(callback), mSoundModelCookie(cookie),
- mRecognitionCallback(NULL), mRecognitionCookie(NULL) {}
- ~SoundModel() {}
-
- sound_model_handle_t mHandle;
- android::hardware::soundtrigger::V2_0::SoundModelHandle mHalHandle;
- sound_model_callback_t mSoundModelCallback;
- void * mSoundModelCookie;
- recognition_callback_t mRecognitionCallback;
- void * mRecognitionCookie;
- };
-
- friend class SoundTriggerHalInterface;
-
- explicit SoundTriggerHalHidl(const char *moduleName = NULL);
- virtual ~SoundTriggerHalHidl();
-
- void convertUuidToHal(Uuid *halUuid,
- const sound_trigger_uuid_t *uuid);
- void convertUuidFromHal(sound_trigger_uuid_t *uuid,
- const Uuid *halUuid);
-
- void convertPropertiesFromHal(
- struct sound_trigger_properties *properties,
- const ISoundTriggerHw::Properties *halProperties);
- static void convertModelParameterToHal(V2_3_ModelParameter* halParam,
- sound_trigger_model_parameter_t param);
-
- void convertTriggerPhraseToHal(
- ISoundTriggerHw::Phrase *halTriggerPhrase,
- const struct sound_trigger_phrase *triggerPhrase);
- void convertTriggerPhrasesToHal(
- hidl_vec<ISoundTriggerHw::Phrase> *halTriggerPhrases,
- struct sound_trigger_phrase_sound_model *keyPhraseModel);
- void convertSoundModelToHal(ISoundTriggerHw::SoundModel *halModel,
- const struct sound_trigger_sound_model *soundModel);
- std::pair<bool, sp<IMemory>> convertSoundModelToHal(
- V2_1_ISoundTriggerHw::SoundModel *halModel,
- const struct sound_trigger_sound_model *soundModel)
- __attribute__((warn_unused_result));
- void convertPhraseSoundModelToHal(ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
- const struct sound_trigger_sound_model *soundModel);
- std::pair<bool, sp<IMemory>> convertPhraseSoundModelToHal(
- V2_1_ISoundTriggerHw::PhraseSoundModel *halKeyPhraseModel,
- const struct sound_trigger_sound_model *soundModel)
- __attribute__((warn_unused_result));
-
- void convertPhraseRecognitionExtraToHal(
- PhraseRecognitionExtra *halExtra,
- const struct sound_trigger_phrase_recognition_extra *extra);
- void convertRecognitionConfigToHal(ISoundTriggerHw::RecognitionConfig *halConfig,
- const struct sound_trigger_recognition_config *config);
- std::pair<bool, sp<IMemory>> convertRecognitionConfigToHal(
- V2_1_ISoundTriggerHw::RecognitionConfig *halConfig,
- const struct sound_trigger_recognition_config *config)
- __attribute__((warn_unused_result));
-
- struct sound_trigger_model_event *convertSoundModelEventFromHal(
- const V2_0_ISoundTriggerHwCallback::ModelEvent *halEvent);
- void convertPhraseRecognitionExtraFromHal(
- struct sound_trigger_phrase_recognition_extra *extra,
- const PhraseRecognitionExtra *halExtra);
- struct sound_trigger_phrase_recognition_event* convertPhraseRecognitionEventFromHal(
- const V2_0_ISoundTriggerHwCallback::PhraseRecognitionEvent *halPhraseEvent);
- struct sound_trigger_recognition_event *convertRecognitionEventFromHal(
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent);
- void fillRecognitionEventFromHal(
- struct sound_trigger_recognition_event *event,
- const V2_0_ISoundTriggerHwCallback::RecognitionEvent *halEvent);
-
- uint32_t nextUniqueId();
- sp<ISoundTriggerHw> getService();
- sp<V2_1_ISoundTriggerHw> toService2_1(const sp<ISoundTriggerHw>& s);
- sp<V2_2_ISoundTriggerHw> toService2_2(const sp<ISoundTriggerHw>& s);
- sp<V2_3_ISoundTriggerHw> toService2_3(const sp<ISoundTriggerHw>& s);
- sp<SoundModel> getModel(sound_model_handle_t handle);
- sp<SoundModel> removeModel(sound_model_handle_t handle);
-
- static pthread_once_t sOnceControl;
- static void sOnceInit();
-
- Mutex mLock;
- Mutex mHalLock;
- const char *mModuleName;
- volatile atomic_uint_fast32_t mNextUniqueId;
- // Effect chains without a valid thread
- DefaultKeyedVector< sound_model_handle_t , sp<SoundModel> > mSoundModels;
- sp<::android::hardware::soundtrigger::V2_0::ISoundTriggerHw> mISoundTrigger;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_HIDL_H
diff --git a/services/soundtrigger/SoundTriggerHalInterface.h b/services/soundtrigger/SoundTriggerHalInterface.h
deleted file mode 100644
index e1fffff..0000000
--- a/services/soundtrigger/SoundTriggerHalInterface.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_INTERFACE_H
-#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_INTERFACE_H
-
-#include <utils/RefBase.h>
-#include <system/sound_trigger.h>
-#include <hardware/sound_trigger.h>
-
-namespace android {
-
-class SoundTriggerHalInterface : public virtual RefBase
-{
-public:
- /* get a sound trigger HAL instance */
- static sp<SoundTriggerHalInterface> connectModule(const char *moduleName);
-
- virtual ~SoundTriggerHalInterface() {}
-
- virtual int getProperties(struct sound_trigger_properties *properties) = 0;
-
- /*
- * Load a sound model. Once loaded, recognition of this model can be started and stopped.
- * Only one active recognition per model at a time. The SoundTrigger service will handle
- * concurrent recognition requests by different users/applications on the same model.
- * The implementation returns a unique handle used by other functions (unload_sound_model(),
- * start_recognition(), etc...
- */
- virtual int loadSoundModel(struct sound_trigger_sound_model *sound_model,
- sound_model_callback_t callback,
- void *cookie,
- sound_model_handle_t *handle) = 0;
-
- /*
- * Unload a sound model. A sound model can be unloaded to make room for a new one to overcome
- * implementation limitations.
- */
- virtual int unloadSoundModel(sound_model_handle_t handle) = 0;
-
- /* Start recognition on a given model. Only one recognition active at a time per model.
- * Once recognition succeeds of fails, the callback is called.
- * TODO: group recognition configuration parameters into one struct and add key phrase options.
- */
- virtual int startRecognition(sound_model_handle_t handle,
- const struct sound_trigger_recognition_config *config,
- recognition_callback_t callback,
- void *cookie) = 0;
-
- /* Stop recognition on a given model.
- * The implementation does not have to call the callback when stopped via this method.
- */
- virtual int stopRecognition(sound_model_handle_t handle) = 0;
-
- /* Stop recognition on all models.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_1 or above.
- * If no implementation is provided, stop_recognition will be called for each running model.
- */
- virtual int stopAllRecognitions() = 0;
-
- /* Get the current state of a given model.
- * Returns 0 or an error code. If successful the state will be returned asynchronously
- * via a recognition event in the callback method that was registered in the
- * startRecognition() method.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_2 or above.
- */
- virtual int getModelState(sound_model_handle_t handle) = 0;
-
- /* Set a model specific ModelParameter with the given value. This parameter
- * will keep its value for the duration the model is loaded regardless of starting and stopping
- * recognition. Once the model is unloaded, the value will be lost.
- * Returns 0 or an error code.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_3 or above.
- */
- virtual int setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t model_param, int32_t value) = 0;
-
- /* Get a model specific ModelParameter. This parameter will keep its value
- * for the duration the model is loaded regardless of starting and stopping recognition.
- * Once the model is unloaded, the value will be lost. If the value is not set, a default
- * value is returned. See sound_trigger_model_parameter_t for parameter default values.
- * Returns 0 or an error code. On return 0, value pointer will be set.
- * Only supported for device api versions SOUND_TRIGGER_DEVICE_API_VERSION_1_3 or above.
- */
- virtual int getParameter(sound_model_handle_t sound_model_handle,
- sound_trigger_model_parameter_t model_param, int32_t* value) = 0;
-
- /* Get supported parameter attributes with respect to the provided model
- * handle. Along with determining the valid range, this API is also used
- * to determine if a given parameter ID is supported at all by the
- * modelHandle for use with getParameter and setParameter APIs.
- */
- virtual int queryParameter(sound_model_handle_t sound_model_handle,
- sound_trigger_model_parameter_t model_param,
- sound_trigger_model_parameter_range_t* param_range) = 0;
-
-protected:
- SoundTriggerHalInterface() {}
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_INTERFACE_H
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
deleted file mode 100644
index 4d8b0da..0000000
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SoundTriggerHwService"
-//#define LOG_NDEBUG 0
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <pthread.h>
-
-#include <audio_utils/clock.h>
-#include <system/sound_trigger.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <hardware/hardware.h>
-#include <media/AudioSystem.h>
-#include <mediautils/ServiceUtilities.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IServiceManager.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <system/sound_trigger.h>
-#include "SoundTriggerHwService.h"
-
-#define HW_MODULE_PREFIX "primary"
-namespace android {
-
-namespace {
-
-// Given an IMemory, returns a copy of its content along with its size.
-// Returns nullptr on failure or if input is nullptr.
-std::pair<std::unique_ptr<uint8_t[]>,
- size_t> CopyToArray(const sp<IMemory>& mem) {
- if (mem == nullptr) {
- return std::make_pair(nullptr, 0);
- }
-
- const size_t size = mem->size();
- if (size == 0) {
- return std::make_pair(nullptr, 0);
- }
-
- std::unique_ptr<uint8_t[]> ar = std::make_unique<uint8_t[]>(size);
- if (ar == nullptr) {
- return std::make_pair(nullptr, 0);
- }
-
- memcpy(ar.get(), mem->unsecurePointer(), size);
- return std::make_pair(std::move(ar), size);
-}
-
-}
-
-SoundTriggerHwService::SoundTriggerHwService()
- : BnSoundTriggerHwService(),
- mNextUniqueId(1),
- mMemoryDealer(new MemoryDealer(1024 * 1024, "SoundTriggerHwService")),
- mCaptureState(false)
-{
-}
-
-void SoundTriggerHwService::onFirstRef()
-{
- int rc;
-
- sp<SoundTriggerHalInterface> halInterface =
- SoundTriggerHalInterface::connectModule(HW_MODULE_PREFIX);
-
- if (halInterface == 0) {
- ALOGW("could not connect to HAL");
- return;
- }
- sound_trigger_module_descriptor descriptor;
- rc = halInterface->getProperties(&descriptor.properties);
- if (rc != 0) {
- ALOGE("could not read implementation properties");
- return;
- }
- descriptor.handle =
- (sound_trigger_module_handle_t)android_atomic_inc(&mNextUniqueId);
- ALOGI("loaded default module %s, handle %d", descriptor.properties.description,
- descriptor.handle);
-
- sp<Module> module = new Module(this, halInterface, descriptor);
- mModules.add(descriptor.handle, module);
- mCallbackThread = new CallbackThread(this);
-}
-
-SoundTriggerHwService::~SoundTriggerHwService()
-{
- if (mCallbackThread != 0) {
- mCallbackThread->exit();
- }
-}
-
-status_t SoundTriggerHwService::listModules(const String16& opPackageName,
- struct sound_trigger_module_descriptor *modules,
- uint32_t *numModules)
-{
- ALOGV("listModules");
- if (!captureHotwordAllowed(opPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- AutoMutex lock(mServiceLock);
- if (numModules == NULL || (*numModules != 0 && modules == NULL)) {
- return BAD_VALUE;
- }
- size_t maxModules = *numModules;
- *numModules = mModules.size();
- for (size_t i = 0; i < mModules.size() && i < maxModules; i++) {
- modules[i] = mModules.valueAt(i)->descriptor();
- }
- return NO_ERROR;
-}
-
-status_t SoundTriggerHwService::attach(const String16& opPackageName,
- const sound_trigger_module_handle_t handle,
- const sp<ISoundTriggerClient>& client,
- sp<ISoundTrigger>& moduleInterface)
-{
- ALOGV("attach module %d", handle);
- if (!captureHotwordAllowed(opPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- AutoMutex lock(mServiceLock);
- moduleInterface.clear();
- if (client == 0) {
- return BAD_VALUE;
- }
- ssize_t index = mModules.indexOfKey(handle);
- if (index < 0) {
- return BAD_VALUE;
- }
- sp<Module> module = mModules.valueAt(index);
-
- sp<ModuleClient> moduleClient = module->addClient(client, opPackageName);
- if (moduleClient == 0) {
- return NO_INIT;
- }
-
- moduleClient->setCaptureState_l(mCaptureState);
- moduleInterface = moduleClient;
-
- return NO_ERROR;
-}
-
-status_t SoundTriggerHwService::setCaptureState(bool active)
-{
- ALOGV("setCaptureState %d", active);
- AutoMutex lock(mServiceLock);
- mCaptureState = active;
- for (size_t i = 0; i < mModules.size(); i++) {
- mModules.valueAt(i)->setCaptureState_l(active);
- }
- return NO_ERROR;
-}
-
-
-static const int kDumpLockTimeoutNs = 1 * NANOS_PER_SECOND;
-
-static bool dumpTryLock(Mutex& mutex)
-{
- status_t err = mutex.timedLock(kDumpLockTimeoutNs);
- return err == NO_ERROR;
-}
-
-status_t SoundTriggerHwService::dump(int fd, const Vector<String16>& args __unused) {
- String8 result;
- if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
- result.appendFormat("Permission Denial: can't dump SoundTriggerHwService");
- write(fd, result.string(), result.size());
- } else {
- bool locked = dumpTryLock(mServiceLock);
- // failed to lock - SoundTriggerHwService is probably deadlocked
- if (!locked) {
- result.append("SoundTriggerHwService may be deadlocked\n");
- write(fd, result.string(), result.size());
- }
-
- if (locked) mServiceLock.unlock();
- }
- return NO_ERROR;
-}
-
-status_t SoundTriggerHwService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- return BnSoundTriggerHwService::onTransact(code, data, reply, flags);
-}
-
-
-// static
-void SoundTriggerHwService::recognitionCallback(struct sound_trigger_recognition_event *event,
- void *cookie)
-{
- Module *module = (Module *)cookie;
- if (module == NULL) {
- return;
- }
- sp<SoundTriggerHwService> service = module->service().promote();
- if (service == 0) {
- return;
- }
-
- service->sendRecognitionEvent(event, module);
-}
-
-sp<IMemory> SoundTriggerHwService::prepareRecognitionEvent(
- struct sound_trigger_recognition_event *event)
-{
- AutoMutex lock(mMemoryDealerLock);
- sp<IMemory> eventMemory;
-
- //sanitize event
- switch (event->type) {
- case SOUND_MODEL_TYPE_KEYPHRASE:
- ALOGW_IF(event->data_size != 0 && event->data_offset !=
- sizeof(struct sound_trigger_phrase_recognition_event),
- "prepareRecognitionEvent(): invalid data offset %u for keyphrase event type",
- event->data_offset);
- event->data_offset = sizeof(struct sound_trigger_phrase_recognition_event);
- break;
- case SOUND_MODEL_TYPE_GENERIC:
- ALOGW_IF(event->data_size != 0 && event->data_offset !=
- sizeof(struct sound_trigger_generic_recognition_event),
- "prepareRecognitionEvent(): invalid data offset %u for generic event type",
- event->data_offset);
- event->data_offset = sizeof(struct sound_trigger_generic_recognition_event);
- break;
- case SOUND_MODEL_TYPE_UNKNOWN:
- ALOGW_IF(event->data_size != 0 && event->data_offset !=
- sizeof(struct sound_trigger_recognition_event),
- "prepareRecognitionEvent(): invalid data offset %u for unknown event type",
- event->data_offset);
- event->data_offset = sizeof(struct sound_trigger_recognition_event);
- break;
- default:
- return eventMemory;
- }
-
- size_t size = event->data_offset + event->data_size;
- eventMemory = mMemoryDealer->allocate(size);
- if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
- eventMemory.clear();
- return eventMemory;
- }
- memcpy(eventMemory->unsecurePointer(), event, size);
-
- return eventMemory;
-}
-
-void SoundTriggerHwService::sendRecognitionEvent(struct sound_trigger_recognition_event *event,
- Module *module)
-{
- if (module == NULL) {
- return;
- }
- sp<IMemory> eventMemory = prepareRecognitionEvent(event);
- if (eventMemory == 0) {
- return;
- }
-
- sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
- eventMemory);
- callbackEvent->setModule(module);
- sendCallbackEvent(callbackEvent);
-}
-
-// static
-void SoundTriggerHwService::soundModelCallback(struct sound_trigger_model_event *event,
- void *cookie)
-{
- Module *module = (Module *)cookie;
- if (module == NULL) {
- return;
- }
- sp<SoundTriggerHwService> service = module->service().promote();
- if (service == 0) {
- return;
- }
-
- service->sendSoundModelEvent(event, module);
-}
-
-sp<IMemory> SoundTriggerHwService::prepareSoundModelEvent(struct sound_trigger_model_event *event)
-{
- AutoMutex lock(mMemoryDealerLock);
- sp<IMemory> eventMemory;
-
- size_t size = event->data_offset + event->data_size;
- eventMemory = mMemoryDealer->allocate(size);
- if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
- eventMemory.clear();
- return eventMemory;
- }
- memcpy(eventMemory->unsecurePointer(), event, size);
-
- return eventMemory;
-}
-
-void SoundTriggerHwService::sendSoundModelEvent(struct sound_trigger_model_event *event,
- Module *module)
-{
- sp<IMemory> eventMemory = prepareSoundModelEvent(event);
- if (eventMemory == 0) {
- return;
- }
- sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SOUNDMODEL,
- eventMemory);
- callbackEvent->setModule(module);
- sendCallbackEvent(callbackEvent);
-}
-
-
-sp<IMemory> SoundTriggerHwService::prepareServiceStateEvent(sound_trigger_service_state_t state)
-{
- AutoMutex lock(mMemoryDealerLock);
- sp<IMemory> eventMemory;
-
- size_t size = sizeof(sound_trigger_service_state_t);
- eventMemory = mMemoryDealer->allocate(size);
- if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
- eventMemory.clear();
- return eventMemory;
- }
- *((sound_trigger_service_state_t *)eventMemory->unsecurePointer()) = state;
- return eventMemory;
-}
-
-void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
- Module *module)
-{
- sp<IMemory> eventMemory = prepareServiceStateEvent(state);
- if (eventMemory == 0) {
- return;
- }
- sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
- eventMemory);
- callbackEvent->setModule(module);
- sendCallbackEvent(callbackEvent);
-}
-
-void SoundTriggerHwService::sendServiceStateEvent(sound_trigger_service_state_t state,
- ModuleClient *moduleClient)
-{
- sp<IMemory> eventMemory = prepareServiceStateEvent(state);
- if (eventMemory == 0) {
- return;
- }
- sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_SERVICE_STATE,
- eventMemory);
- callbackEvent->setModuleClient(moduleClient);
- sendCallbackEvent(callbackEvent);
-}
-
-void SoundTriggerHwService::sendCallbackEvent(const sp<CallbackEvent>& event)
-{
- mCallbackThread->sendCallbackEvent(event);
-}
-
-void SoundTriggerHwService::onCallbackEvent(const sp<CallbackEvent>& event)
-{
- ALOGV("onCallbackEvent");
- sp<Module> module;
- sp<ModuleClient> moduleClient;
- {
- AutoMutex lock(mServiceLock);
- //CallbackEvent is either for Module or ModuleClient
- module = event->mModule.promote();
- if (module == 0) {
- moduleClient = event->mModuleClient.promote();
- if (moduleClient == 0) {
- return;
- }
- } else {
- // Sanity check on this being a Module we know about.
- bool foundModule = false;
- for (size_t i = 0; i < mModules.size(); i++) {
- if (mModules.valueAt(i).get() == module.get()) {
- foundModule = true;
- break;
- }
- }
- if (!foundModule) {
- ALOGE("onCallbackEvent for unknown module");
- return;
- }
- }
- }
- if (module != 0) {
- ALOGV("onCallbackEvent for module");
- module->onCallbackEvent(event);
- } else if (moduleClient != 0) {
- ALOGV("onCallbackEvent for moduleClient");
- moduleClient->onCallbackEvent(event);
- }
- {
- AutoMutex lock(mServiceLock);
- // clear now to execute with mServiceLock locked
- event->mMemory.clear();
- }
-}
-
-#undef LOG_TAG
-#define LOG_TAG "SoundTriggerHwService::CallbackThread"
-
-SoundTriggerHwService::CallbackThread::CallbackThread(const wp<SoundTriggerHwService>& service)
- : mService(service)
-{
-}
-
-SoundTriggerHwService::CallbackThread::~CallbackThread()
-{
- while (!mEventQueue.isEmpty()) {
- mEventQueue[0]->mMemory.clear();
- mEventQueue.removeAt(0);
- }
-}
-
-void SoundTriggerHwService::CallbackThread::onFirstRef()
-{
- run("soundTrigger cbk", ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-bool SoundTriggerHwService::CallbackThread::threadLoop()
-{
- while (!exitPending()) {
- sp<CallbackEvent> event;
- sp<SoundTriggerHwService> service;
- {
- Mutex::Autolock _l(mCallbackLock);
- while (mEventQueue.isEmpty() && !exitPending()) {
- ALOGV("CallbackThread::threadLoop() sleep");
- mCallbackCond.wait(mCallbackLock);
- ALOGV("CallbackThread::threadLoop() wake up");
- }
- if (exitPending()) {
- break;
- }
- event = mEventQueue[0];
- mEventQueue.removeAt(0);
- service = mService.promote();
- }
- if (service != 0) {
- service->onCallbackEvent(event);
- }
- }
- return false;
-}
-
-void SoundTriggerHwService::CallbackThread::exit()
-{
- Mutex::Autolock _l(mCallbackLock);
- requestExit();
- mCallbackCond.broadcast();
-}
-
-void SoundTriggerHwService::CallbackThread::sendCallbackEvent(
- const sp<SoundTriggerHwService::CallbackEvent>& event)
-{
- AutoMutex lock(mCallbackLock);
- mEventQueue.add(event);
- mCallbackCond.signal();
-}
-
-SoundTriggerHwService::CallbackEvent::CallbackEvent(event_type type, sp<IMemory> memory)
- : mType(type), mMemory(memory)
-{
-}
-
-SoundTriggerHwService::CallbackEvent::~CallbackEvent()
-{
-}
-
-
-#undef LOG_TAG
-#define LOG_TAG "SoundTriggerHwService::Module"
-
-SoundTriggerHwService::Module::Module(const sp<SoundTriggerHwService>& service,
- const sp<SoundTriggerHalInterface>& halInterface,
- sound_trigger_module_descriptor descriptor)
- : mService(service), mHalInterface(halInterface), mDescriptor(descriptor),
- mServiceState(SOUND_TRIGGER_STATE_NO_INIT)
-{
-}
-
-SoundTriggerHwService::Module::~Module() {
- mModuleClients.clear();
-}
-
-sp<SoundTriggerHwService::ModuleClient>
-SoundTriggerHwService::Module::addClient(const sp<ISoundTriggerClient>& client,
- const String16& opPackageName)
-{
- AutoMutex lock(mLock);
- sp<ModuleClient> moduleClient;
-
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i]->client() == client) {
- // Client already present, reuse client
- return moduleClient;
- }
- }
- moduleClient = new ModuleClient(this, client, opPackageName);
-
- ALOGV("addClient() client %p", moduleClient.get());
- mModuleClients.add(moduleClient);
-
- return moduleClient;
-}
-
-void SoundTriggerHwService::Module::detach(const sp<ModuleClient>& moduleClient)
-{
- ALOGV("Module::detach()");
- Vector<audio_session_t> releasedSessions;
-
- {
- AutoMutex lock(mLock);
- ssize_t index = -1;
-
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i] == moduleClient) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- return;
- }
-
- ALOGV("remove client %p", moduleClient.get());
- mModuleClients.removeAt(index);
-
- // Iterate in reverse order as models are removed from list inside the loop.
- for (size_t i = mModels.size(); i > 0; i--) {
- sp<Model> model = mModels.valueAt(i - 1);
- if (moduleClient == model->mModuleClient) {
- mModels.removeItemsAt(i - 1);
- ALOGV("detach() unloading model %d", model->mHandle);
- if (mHalInterface != 0) {
- if (model->mState == Model::STATE_ACTIVE) {
- mHalInterface->stopRecognition(model->mHandle);
- }
- mHalInterface->unloadSoundModel(model->mHandle);
- }
- releasedSessions.add(model->mCaptureSession);
- }
- }
- }
-
- for (size_t i = 0; i < releasedSessions.size(); i++) {
- // do not call AudioSystem methods with mLock held
- AudioSystem::releaseSoundTriggerSession(releasedSessions[i]);
- }
-}
-
-status_t SoundTriggerHwService::Module::loadSoundModel(const sp<IMemory>& modelMemory,
- sp<ModuleClient> moduleClient,
- sound_model_handle_t *handle)
-{
- ALOGV("loadSoundModel() handle");
- if (mHalInterface == 0) {
- return NO_INIT;
- }
-
- auto immutableMemory = CopyToArray(modelMemory);
- if (immutableMemory.first == nullptr) {
- return NO_MEMORY;
- }
-
- struct sound_trigger_sound_model* sound_model =
- (struct sound_trigger_sound_model*) immutableMemory.first.get();
-
- size_t structSize;
- if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
- structSize = sizeof(struct sound_trigger_phrase_sound_model);
- } else {
- structSize = sizeof(struct sound_trigger_sound_model);
- }
-
- if (sound_model->data_offset < structSize ||
- sound_model->data_size > (UINT_MAX - sound_model->data_offset) ||
- immutableMemory.second < sound_model->data_offset ||
- sound_model->data_size >
- (immutableMemory.second - sound_model->data_offset)) {
- android_errorWriteLog(0x534e4554, "30148546");
- ALOGE("loadSoundModel() data_size is too big");
- return BAD_VALUE;
- }
-
- audio_session_t session;
- audio_io_handle_t ioHandle;
- audio_devices_t device;
- // do not call AudioSystem methods with mLock held
- status_t status = AudioSystem::acquireSoundTriggerSession(&session, &ioHandle, &device);
- if (status != NO_ERROR) {
- return status;
- }
-
- {
- AutoMutex lock(mLock);
-
- if (mModels.size() >= mDescriptor.properties.max_sound_models) {
- ALOGW("loadSoundModel(): Not loading, max number of models (%d) would be exceeded",
- mDescriptor.properties.max_sound_models);
- status = INVALID_OPERATION;
- goto exit;
- }
-
- status = mHalInterface->loadSoundModel(sound_model,
- SoundTriggerHwService::soundModelCallback,
- this, handle);
- if (status != NO_ERROR) {
- goto exit;
- }
-
- sp<Model> model = new Model(*handle, session, ioHandle, device, sound_model->type,
- moduleClient);
- mModels.replaceValueFor(*handle, model);
- }
-exit:
- if (status != NO_ERROR) {
- // do not call AudioSystem methods with mLock held
- AudioSystem::releaseSoundTriggerSession(session);
- }
- return status;
-}
-
-status_t SoundTriggerHwService::Module::unloadSoundModel(sound_model_handle_t handle)
-{
- ALOGV("unloadSoundModel() model handle %d", handle);
- status_t status;
- audio_session_t session;
-
- {
- AutoMutex lock(mLock);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
- ssize_t index = mModels.indexOfKey(handle);
- if (index < 0) {
- return BAD_VALUE;
- }
- sp<Model> model = mModels.valueAt(index);
- mModels.removeItem(handle);
- if (model->mState == Model::STATE_ACTIVE) {
- mHalInterface->stopRecognition(model->mHandle);
- model->mState = Model::STATE_IDLE;
- }
- status = mHalInterface->unloadSoundModel(handle);
- session = model->mCaptureSession;
- }
- // do not call AudioSystem methods with mLock held
- AudioSystem::releaseSoundTriggerSession(session);
- return status;
-}
-
-status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
- const sp<IMemory>& dataMemory)
-{
- ALOGV("startRecognition() model handle %d", handle);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
-
- auto immutableMemory = CopyToArray(dataMemory);
- if (immutableMemory.first == nullptr) {
- return NO_MEMORY;
- }
-
- struct sound_trigger_recognition_config* config =
- (struct sound_trigger_recognition_config*) immutableMemory.first.get();
-
- if (config->data_offset < sizeof(struct sound_trigger_recognition_config) ||
- config->data_size > (UINT_MAX - config->data_offset) ||
- immutableMemory.second < config->data_offset ||
- config->data_size >
- (immutableMemory.second - config->data_offset)) {
- ALOGE("startRecognition() data_size is too big");
- return BAD_VALUE;
- }
-
- AutoMutex lock(mLock);
- if (mServiceState == SOUND_TRIGGER_STATE_DISABLED) {
- return INVALID_OPERATION;
- }
- sp<Model> model = getModel(handle);
- if (model == 0) {
- return BAD_VALUE;
- }
-
- if (model->mState == Model::STATE_ACTIVE) {
- return INVALID_OPERATION;
- }
-
-
- //TODO: get capture handle and device from audio policy service
- config->capture_handle = model->mCaptureIOHandle;
- config->capture_device = model->mCaptureDevice;
- status_t status = mHalInterface->startRecognition(handle, config,
- SoundTriggerHwService::recognitionCallback,
- this);
-
- if (status == NO_ERROR) {
- model->mState = Model::STATE_ACTIVE;
- model->mConfig = *config;
- }
-
- return status;
-}
-
-status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)
-{
- ALOGV("stopRecognition() model handle %d", handle);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
- AutoMutex lock(mLock);
- sp<Model> model = getModel(handle);
- if (model == 0) {
- return BAD_VALUE;
- }
-
- if (model->mState != Model::STATE_ACTIVE) {
- return INVALID_OPERATION;
- }
- mHalInterface->stopRecognition(handle);
- model->mState = Model::STATE_IDLE;
- return NO_ERROR;
-}
-
-status_t SoundTriggerHwService::Module::getModelState(sound_model_handle_t handle)
-{
- ALOGV("getModelState() model handle %d", handle);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
- AutoMutex lock(mLock);
- sp<Model> model = getModel(handle);
- if (model == 0) {
- return BAD_VALUE;
- }
-
- if (model->mState != Model::STATE_ACTIVE) {
- return INVALID_OPERATION;
- }
-
- return mHalInterface->getModelState(handle);
-}
-
-status_t SoundTriggerHwService::Module::setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t value)
-{
- ALOGV("setParameter() handle=%d, param=%d, value=%d", handle, param, value);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
-
- AutoMutex lock(mLock);
- return mHalInterface->setParameter(handle, param, value);
-}
-
-status_t SoundTriggerHwService::Module::getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t* value)
-{
- ALOGV("getParameter() handle=%d, param=%d", handle, param);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
-
- AutoMutex lock(mLock);
- return mHalInterface->getParameter(handle, param, value);
-}
-
-status_t SoundTriggerHwService::Module::queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- sound_trigger_model_parameter_range_t* param_range)
-{
- ALOGV("queryParameter() handle=%d, param=%d", handle, param);
- if (mHalInterface == 0) {
- return NO_INIT;
- }
-
- AutoMutex lock(mLock);
- return mHalInterface->queryParameter(handle, param, param_range);
-}
-
-void SoundTriggerHwService::Module::onCallbackEvent(const sp<CallbackEvent>& event)
-{
- ALOGV("onCallbackEvent type %d", event->mType);
-
- // Memory is coming from a trusted process.
- sp<IMemory> eventMemory = event->mMemory;
-
- if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
- return;
- }
- if (mModuleClients.isEmpty()) {
- ALOGI("%s no clients", __func__);
- return;
- }
-
- Vector< sp<ModuleClient> > clients;
-
- switch (event->mType) {
- case CallbackEvent::TYPE_RECOGNITION: {
- struct sound_trigger_recognition_event *recognitionEvent =
- (struct sound_trigger_recognition_event *)eventMemory->unsecurePointer();
- {
- AutoMutex lock(mLock);
- sp<Model> model = getModel(recognitionEvent->model);
- if (model == 0) {
- ALOGW("%s model == 0", __func__);
- return;
- }
- if (model->mState != Model::STATE_ACTIVE) {
- ALOGV("onCallbackEvent model->mState %d != Model::STATE_ACTIVE", model->mState);
- return;
- }
-
- recognitionEvent->capture_session = model->mCaptureSession;
- model->mState = Model::STATE_IDLE;
- clients.add(model->mModuleClient);
- }
- } break;
- case CallbackEvent::TYPE_SOUNDMODEL: {
- struct sound_trigger_model_event *soundmodelEvent =
- (struct sound_trigger_model_event *)eventMemory->unsecurePointer();
- {
- AutoMutex lock(mLock);
- sp<Model> model = getModel(soundmodelEvent->model);
- if (model == 0) {
- ALOGW("%s model == 0", __func__);
- return;
- }
- clients.add(model->mModuleClient);
- }
- } break;
- case CallbackEvent::TYPE_SERVICE_STATE: {
- {
- AutoMutex lock(mLock);
- for (size_t i = 0; i < mModuleClients.size(); i++) {
- if (mModuleClients[i] != 0) {
- clients.add(mModuleClients[i]);
- }
- }
- }
- } break;
- default:
- LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
- }
-
- for (size_t i = 0; i < clients.size(); i++) {
- clients[i]->onCallbackEvent(event);
- }
-}
-
-sp<SoundTriggerHwService::Model> SoundTriggerHwService::Module::getModel(
- sound_model_handle_t handle)
-{
- sp<Model> model;
- ssize_t index = mModels.indexOfKey(handle);
- if (index >= 0) {
- model = mModels.valueAt(index);
- }
- return model;
-}
-
-// Called with mServiceLock held
-void SoundTriggerHwService::Module::setCaptureState_l(bool active)
-{
- ALOGV("Module::setCaptureState_l %d", active);
- sp<SoundTriggerHwService> service;
- sound_trigger_service_state_t state;
-
- Vector< sp<IMemory> > events;
- {
- AutoMutex lock(mLock);
- state = (active && !mDescriptor.properties.concurrent_capture) ?
- SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
-
- if (state == mServiceState) {
- return;
- }
-
- mServiceState = state;
-
- service = mService.promote();
- if (service == 0) {
- return;
- }
-
- if (state == SOUND_TRIGGER_STATE_ENABLED) {
- goto exit;
- }
-
- const bool supports_stop_all =
- (mHalInterface != 0) && (mHalInterface->stopAllRecognitions() != -ENOSYS);
-
- for (size_t i = 0; i < mModels.size(); i++) {
- sp<Model> model = mModels.valueAt(i);
- if (model->mState == Model::STATE_ACTIVE) {
- if (mHalInterface != 0 && !supports_stop_all) {
- mHalInterface->stopRecognition(model->mHandle);
- }
- // keep model in ACTIVE state so that event is processed by onCallbackEvent()
- if (model->mType == SOUND_MODEL_TYPE_KEYPHRASE) {
- struct sound_trigger_phrase_recognition_event event;
- memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
- event.num_phrases = model->mConfig.num_phrases;
- for (size_t i = 0; i < event.num_phrases; i++) {
- event.phrase_extras[i] = model->mConfig.phrases[i];
- }
- event.common.status = RECOGNITION_STATUS_ABORT;
- event.common.type = model->mType;
- event.common.model = model->mHandle;
- event.common.data_size = 0;
- sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
- if (eventMemory != 0) {
- events.add(eventMemory);
- }
- } else if (model->mType == SOUND_MODEL_TYPE_GENERIC) {
- struct sound_trigger_generic_recognition_event event;
- memset(&event, 0, sizeof(struct sound_trigger_generic_recognition_event));
- event.common.status = RECOGNITION_STATUS_ABORT;
- event.common.type = model->mType;
- event.common.model = model->mHandle;
- event.common.data_size = 0;
- sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
- if (eventMemory != 0) {
- events.add(eventMemory);
- }
- } else if (model->mType == SOUND_MODEL_TYPE_UNKNOWN) {
- struct sound_trigger_phrase_recognition_event event;
- memset(&event, 0, sizeof(struct sound_trigger_phrase_recognition_event));
- event.common.status = RECOGNITION_STATUS_ABORT;
- event.common.type = model->mType;
- event.common.model = model->mHandle;
- event.common.data_size = 0;
- sp<IMemory> eventMemory = service->prepareRecognitionEvent(&event.common);
- if (eventMemory != 0) {
- events.add(eventMemory);
- }
- } else {
- goto exit;
- }
- }
- }
- }
-
- for (size_t i = 0; i < events.size(); i++) {
- sp<CallbackEvent> callbackEvent = new CallbackEvent(CallbackEvent::TYPE_RECOGNITION,
- events[i]);
- callbackEvent->setModule(this);
- service->sendCallbackEvent(callbackEvent);
- }
-
-exit:
- service->sendServiceStateEvent(state, this);
-}
-
-
-SoundTriggerHwService::Model::Model(sound_model_handle_t handle, audio_session_t session,
- audio_io_handle_t ioHandle, audio_devices_t device,
- sound_trigger_sound_model_type_t type,
- sp<ModuleClient>& moduleClient) :
- mHandle(handle), mState(STATE_IDLE), mCaptureSession(session),
- mCaptureIOHandle(ioHandle), mCaptureDevice(device), mType(type),
- mModuleClient(moduleClient)
-{
-}
-
-#undef LOG_TAG
-#define LOG_TAG "SoundTriggerHwService::ModuleClient"
-
-SoundTriggerHwService::ModuleClient::ModuleClient(const sp<Module>& module,
- const sp<ISoundTriggerClient>& client,
- const String16& opPackageName)
- : mModule(module), mClient(client), mOpPackageName(opPackageName)
-{
-}
-
-void SoundTriggerHwService::ModuleClient::onFirstRef()
-{
- sp<IBinder> binder = IInterface::asBinder(mClient);
- if (binder != 0) {
- binder->linkToDeath(this);
- }
-}
-
-SoundTriggerHwService::ModuleClient::~ModuleClient()
-{
-}
-
-status_t SoundTriggerHwService::ModuleClient::dump(int fd __unused,
- const Vector<String16>& args __unused) {
- String8 result;
- return NO_ERROR;
-}
-
-void SoundTriggerHwService::ModuleClient::detach() {
- ALOGV("detach()");
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return;
- }
-
- {
- AutoMutex lock(mLock);
- if (mClient != 0) {
- IInterface::asBinder(mClient)->unlinkToDeath(this);
- mClient.clear();
- }
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return;
- }
- module->detach(this);
-}
-
-status_t SoundTriggerHwService::ModuleClient::loadSoundModel(const sp<IMemory>& modelMemory,
- sound_model_handle_t *handle)
-{
- ALOGV("loadSoundModel() handle");
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
- if (checkIMemory(modelMemory) != NO_ERROR) {
- return BAD_VALUE;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->loadSoundModel(modelMemory, this, handle);
-}
-
-status_t SoundTriggerHwService::ModuleClient::unloadSoundModel(sound_model_handle_t handle)
-{
- ALOGV("unloadSoundModel() model handle %d", handle);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->unloadSoundModel(handle);
-}
-
-status_t SoundTriggerHwService::ModuleClient::startRecognition(sound_model_handle_t handle,
- const sp<IMemory>& dataMemory)
-{
- ALOGV("startRecognition() model handle %d", handle);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
- if (checkIMemory(dataMemory) != NO_ERROR) {
- return BAD_VALUE;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->startRecognition(handle, dataMemory);
-}
-
-status_t SoundTriggerHwService::ModuleClient::stopRecognition(sound_model_handle_t handle)
-{
- ALOGV("stopRecognition() model handle %d", handle);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->stopRecognition(handle);
-}
-
-status_t SoundTriggerHwService::ModuleClient::getModelState(sound_model_handle_t handle)
-{
- ALOGV("getModelState() model handle %d", handle);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->getModelState(handle);
-}
-
-status_t SoundTriggerHwService::ModuleClient::setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param, int32_t value)
-{
- ALOGV("setParameter() handle=%d, param=%d, value=%d", handle, param, value);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->setParameter(handle, param, value);
-}
-
-status_t SoundTriggerHwService::ModuleClient::getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param, int32_t* value)
-{
- ALOGV("getParameter() handle=%d, param=%d", handle, param);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->getParameter(handle, param, value);
-}
-
-status_t SoundTriggerHwService::ModuleClient::queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- sound_trigger_model_parameter_range_t* param_range)
-{
- ALOGV("isParameterSupported() handle=%d, param=%d", handle, param);
- if (!captureHotwordAllowed(mOpPackageName,
- IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid())) {
- return PERMISSION_DENIED;
- }
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return NO_INIT;
- }
- return module->queryParameter(handle, param, param_range);
-}
-
-void SoundTriggerHwService::ModuleClient::setCaptureState_l(bool active)
-{
- ALOGV("ModuleClient::setCaptureState_l %d", active);
- sp<SoundTriggerHwService> service;
- sound_trigger_service_state_t state;
-
- sp<Module> module = mModule.promote();
- if (module == 0) {
- return;
- }
- {
- AutoMutex lock(mLock);
- state = (active && !module->isConcurrentCaptureAllowed()) ?
- SOUND_TRIGGER_STATE_DISABLED : SOUND_TRIGGER_STATE_ENABLED;
-
- service = module->service().promote();
- if (service == 0) {
- return;
- }
- }
- service->sendServiceStateEvent(state, this);
-}
-
-void SoundTriggerHwService::ModuleClient::onCallbackEvent(const sp<CallbackEvent>& event)
-{
- ALOGV("ModuleClient onCallbackEvent type %d", event->mType);
-
- sp<IMemory> eventMemory = event->mMemory;
-
- // Memory is coming from a trusted process.
- if (eventMemory == 0 || eventMemory->unsecurePointer() == NULL) {
- return;
- }
-
- sp<ISoundTriggerClient> client;
- {
- AutoMutex lock(mLock);
- client = mClient;
- }
-
- if (client != 0) {
- switch (event->mType) {
- case CallbackEvent::TYPE_RECOGNITION: {
- client->onRecognitionEvent(eventMemory);
- } break;
- case CallbackEvent::TYPE_SOUNDMODEL: {
- client->onSoundModelEvent(eventMemory);
- } break;
- case CallbackEvent::TYPE_SERVICE_STATE: {
- client->onServiceStateChange(eventMemory);
- } break;
- default:
- LOG_ALWAYS_FATAL("onCallbackEvent unknown event type %d", event->mType);
- }
- }
-}
-
-void SoundTriggerHwService::ModuleClient::binderDied(
- const wp<IBinder> &who __unused) {
- ALOGW("client binder died for client %p", this);
- detach();
-}
-
-}; // namespace android
diff --git a/services/soundtrigger/SoundTriggerHwService.h b/services/soundtrigger/SoundTriggerHwService.h
deleted file mode 100644
index 4057e14..0000000
--- a/services/soundtrigger/SoundTriggerHwService.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
-#define ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H
-
-#include <utils/Vector.h>
-//#include <binder/AppOpsManager.h>
-#include <binder/MemoryDealer.h>
-#include <binder/BinderService.h>
-#include <binder/IAppOpsCallback.h>
-#include <soundtrigger/ISoundTriggerHwService.h>
-#include <soundtrigger/ISoundTrigger.h>
-#include <soundtrigger/ISoundTriggerClient.h>
-#include <system/sound_trigger.h>
-#include "SoundTriggerHalInterface.h"
-
-namespace android {
-
-class MemoryHeapBase;
-
-class SoundTriggerHwService :
- public BinderService<SoundTriggerHwService>,
- public BnSoundTriggerHwService
-{
- friend class BinderService<SoundTriggerHwService>;
-public:
- class Module;
- class ModuleClient;
-
- static char const* getServiceName() { return "media.sound_trigger_hw"; }
-
- SoundTriggerHwService();
- virtual ~SoundTriggerHwService();
-
- // ISoundTriggerHwService
- virtual status_t listModules(const String16& opPackageName,
- struct sound_trigger_module_descriptor *modules,
- uint32_t *numModules);
-
- virtual status_t attach(const String16& opPackageName,
- const sound_trigger_module_handle_t handle,
- const sp<ISoundTriggerClient>& client,
- sp<ISoundTrigger>& module);
-
- virtual status_t setCaptureState(bool active);
-
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- class Model : public RefBase {
- public:
-
- enum {
- STATE_IDLE,
- STATE_ACTIVE
- };
-
- Model(sound_model_handle_t handle, audio_session_t session, audio_io_handle_t ioHandle,
- audio_devices_t device, sound_trigger_sound_model_type_t type,
- sp<ModuleClient>& moduleClient);
- ~Model() {}
-
- sound_model_handle_t mHandle;
- int mState;
- audio_session_t mCaptureSession;
- audio_io_handle_t mCaptureIOHandle;
- audio_devices_t mCaptureDevice;
- sound_trigger_sound_model_type_t mType;
- struct sound_trigger_recognition_config mConfig;
- sp<ModuleClient> mModuleClient;
- };
-
- class CallbackEvent : public RefBase {
- public:
- typedef enum {
- TYPE_RECOGNITION,
- TYPE_SOUNDMODEL,
- TYPE_SERVICE_STATE,
- } event_type;
- CallbackEvent(event_type type, sp<IMemory> memory);
-
- virtual ~CallbackEvent();
-
- void setModule(wp<Module> module) { mModule = module; }
- void setModuleClient(wp<ModuleClient> moduleClient) { mModuleClient = moduleClient; }
-
- event_type mType;
- sp<IMemory> mMemory;
- wp<Module> mModule;
- wp<ModuleClient> mModuleClient;
- };
-
- class Module : public RefBase {
- public:
-
- Module(const sp<SoundTriggerHwService>& service,
- const sp<SoundTriggerHalInterface>& halInterface,
- sound_trigger_module_descriptor descriptor);
-
- virtual ~Module();
-
- virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
- sp<ModuleClient> moduleClient,
- sound_model_handle_t *handle);
-
- virtual status_t unloadSoundModel(sound_model_handle_t handle);
-
- virtual status_t startRecognition(sound_model_handle_t handle,
- const sp<IMemory>& dataMemory);
- virtual status_t stopRecognition(sound_model_handle_t handle);
- virtual status_t getModelState(sound_model_handle_t handle);
- virtual status_t setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t value);
- virtual status_t getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t* value);
- virtual status_t queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- sound_trigger_model_parameter_range_t* param_range);
-
- sp<SoundTriggerHalInterface> halInterface() const { return mHalInterface; }
- struct sound_trigger_module_descriptor descriptor() { return mDescriptor; }
- wp<SoundTriggerHwService> service() const { return mService; }
- bool isConcurrentCaptureAllowed() const { return mDescriptor.properties.concurrent_capture; }
-
- sp<Model> getModel(sound_model_handle_t handle);
-
- void setCaptureState_l(bool active);
-
- sp<ModuleClient> addClient(const sp<ISoundTriggerClient>& client,
- const String16& opPackageName);
-
- void detach(const sp<ModuleClient>& moduleClient);
-
- void onCallbackEvent(const sp<CallbackEvent>& event);
-
- private:
-
- Mutex mLock;
- wp<SoundTriggerHwService> mService;
- sp<SoundTriggerHalInterface> mHalInterface;
- struct sound_trigger_module_descriptor mDescriptor;
- Vector< sp<ModuleClient> > mModuleClients;
- DefaultKeyedVector< sound_model_handle_t, sp<Model> > mModels;
- sound_trigger_service_state_t mServiceState;
- }; // class Module
-
- class ModuleClient : public virtual RefBase,
- public BnSoundTrigger,
- public IBinder::DeathRecipient {
- public:
-
- ModuleClient(const sp<Module>& module,
- const sp<ISoundTriggerClient>& client,
- const String16& opPackageName);
-
- virtual ~ModuleClient();
-
- virtual void detach();
-
- virtual status_t loadSoundModel(const sp<IMemory>& modelMemory,
- sound_model_handle_t *handle);
-
- virtual status_t unloadSoundModel(sound_model_handle_t handle);
-
- virtual status_t startRecognition(sound_model_handle_t handle,
- const sp<IMemory>& dataMemory);
- virtual status_t stopRecognition(sound_model_handle_t handle);
- virtual status_t getModelState(sound_model_handle_t handle);
- virtual status_t setParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t value);
- virtual status_t getParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- int32_t* value);
- virtual status_t queryParameter(sound_model_handle_t handle,
- sound_trigger_model_parameter_t param,
- sound_trigger_model_parameter_range_t* param_range);
-
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- virtual void onFirstRef();
-
- // IBinder::DeathRecipient implementation
- virtual void binderDied(const wp<IBinder> &who);
-
- void onCallbackEvent(const sp<CallbackEvent>& event);
-
- void setCaptureState_l(bool active);
-
- sp<ISoundTriggerClient> client() const { return mClient; }
-
- private:
-
- mutable Mutex mLock;
- wp<Module> mModule;
- sp<ISoundTriggerClient> mClient;
- const String16 mOpPackageName;
- }; // class ModuleClient
-
- class CallbackThread : public Thread {
- public:
-
- explicit CallbackThread(const wp<SoundTriggerHwService>& service);
-
- virtual ~CallbackThread();
-
- // Thread virtuals
- virtual bool threadLoop();
-
- // RefBase
- virtual void onFirstRef();
-
- void exit();
- void sendCallbackEvent(const sp<CallbackEvent>& event);
-
- private:
- wp<SoundTriggerHwService> mService;
- Condition mCallbackCond;
- Mutex mCallbackLock;
- Vector< sp<CallbackEvent> > mEventQueue;
- };
-
- static void recognitionCallback(struct sound_trigger_recognition_event *event, void *cookie);
- sp<IMemory> prepareRecognitionEvent(struct sound_trigger_recognition_event *event);
- void sendRecognitionEvent(struct sound_trigger_recognition_event *event, Module *module);
-
- static void soundModelCallback(struct sound_trigger_model_event *event, void *cookie);
- sp<IMemory> prepareSoundModelEvent(struct sound_trigger_model_event *event);
- void sendSoundModelEvent(struct sound_trigger_model_event *event, Module *module);
-
- sp<IMemory> prepareServiceStateEvent(sound_trigger_service_state_t state);
- void sendServiceStateEvent(sound_trigger_service_state_t state, Module *module);
- void sendServiceStateEvent(sound_trigger_service_state_t state,
- ModuleClient *moduleClient);
-
- void sendCallbackEvent(const sp<CallbackEvent>& event);
- void onCallbackEvent(const sp<CallbackEvent>& event);
-
-private:
-
- virtual void onFirstRef();
-
- Mutex mServiceLock;
- volatile int32_t mNextUniqueId;
- DefaultKeyedVector< sound_trigger_module_handle_t, sp<Module> > mModules;
- sp<CallbackThread> mCallbackThread;
- sp<MemoryDealer> mMemoryDealer;
- Mutex mMemoryDealerLock;
- bool mCaptureState;
-};
-
-} // namespace android
-
-#endif // ANDROID_HARDWARE_SOUNDTRIGGER_HAL_SERVICE_H