diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp new file mode 100644 index 0000000000..cc20f91cd5 --- /dev/null +++ b/soundtrigger/2.0/default/Android.bp @@ -0,0 +1,43 @@ +// +// Copyright (C) 2018 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: "android.hardware.soundtrigger@2.0-core", + defaults: ["hidl_defaults"], + vendor_available: true, + vndk: { + enabled: true, + }, + srcs: [ + "SoundTriggerHalImpl.cpp", + ], + + export_include_dirs: ["."], + + shared_libs: [ + "libhidlbase", + "libhidltransport", + "liblog", + "libutils", + "libhardware", + "android.hardware.soundtrigger@2.0", + "android.hardware.audio.common@2.0", + ], + + header_libs: [ + "libaudio_system_headers", + "libhardware_headers", + ], +} diff --git a/soundtrigger/2.0/default/Android.mk b/soundtrigger/2.0/default/Android.mk index 926285862f..835a020800 100644 --- a/soundtrigger/2.0/default/Android.mk +++ b/soundtrigger/2.0/default/Android.mk @@ -18,23 +18,20 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.soundtrigger@2.0-impl -LOCAL_PROPRIETARY_MODULE := true +LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := \ - SoundTriggerHalImpl.cpp + FetchISoundTriggerHw.cpp LOCAL_CFLAGS := -Wall -Werror LOCAL_SHARED_LIBRARIES := \ - libhidlbase \ - libhidltransport \ - liblog \ - libutils \ libhardware \ + libutils \ android.hardware.soundtrigger@2.0 \ - android.hardware.audio.common@2.0 + android.hardware.soundtrigger@2.0-core -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +LOCAL_C_INCLUDE_DIRS := $(LOCAL_PATH) ifeq ($(strip $(AUDIOSERVER_MULTILIB)),) LOCAL_MULTILIB := 32 diff --git a/soundtrigger/2.0/default/FetchISoundTriggerHw.cpp b/soundtrigger/2.0/default/FetchISoundTriggerHw.cpp new file mode 100644 index 0000000000..bd99221b3c --- /dev/null +++ b/soundtrigger/2.0/default/FetchISoundTriggerHw.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 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. + */ + +#include "SoundTriggerHalImpl.h" + +extern "C" ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw( + const char* /* name */) { + return (new ::android::hardware::soundtrigger::V2_0::implementation::SoundTriggerHalImpl()) + ->getInterface(); +} diff --git a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp index bbd97f1aa8..612772cc63 100644 --- a/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp +++ b/soundtrigger/2.0/default/SoundTriggerHalImpl.cpp @@ -39,17 +39,13 @@ void SoundTriggerHalImpl::soundModelCallback(struct sound_trigger_model_event* h ALOGW("soundModelCallback called on stale client"); return; } - if (halEvent->model != client->mHalHandle) { + if (halEvent->model != client->getHalHandle()) { ALOGW("soundModelCallback call with wrong handle %d on client with handle %d", - (int)halEvent->model, (int)client->mHalHandle); + (int)halEvent->model, (int)client->getHalHandle()); return; } - ISoundTriggerHwCallback::ModelEvent event; - convertSoundModelEventFromHal(&event, halEvent); - event.model = client->mId; - - client->mCallback->soundModelCallback(event, client->mCookie); + client->soundModelCallback(halEvent); } // static @@ -66,20 +62,10 @@ void SoundTriggerHalImpl::recognitionCallback(struct sound_trigger_recognition_e return; } - ISoundTriggerHwCallback::RecognitionEvent* event = convertRecognitionEventFromHal(halEvent); - event->model = client->mId; - if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) { - client->mCallback->phraseRecognitionCallback( - *(reinterpret_cast(event)), - client->mCookie); - } else { - client->mCallback->recognitionCallback(*event, client->mCookie); - } - delete event; + client->recognitionCallback(halEvent); } -// Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow. -Return SoundTriggerHalImpl::getProperties(getProperties_cb _hidl_cb) { +Return SoundTriggerHalImpl::getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb) { ALOGV("getProperties() mHwDevice %p", mHwDevice); int ret; struct sound_trigger_properties halProperties; @@ -103,13 +89,9 @@ exit: } int SoundTriggerHalImpl::doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, - const sp& callback, - ISoundTriggerHwCallback::CallbackCookie cookie, - uint32_t* modelId) { + sp client) { int32_t ret = 0; struct sound_trigger_sound_model* halSoundModel; - *modelId = 0; - sp client; ALOGV("doLoadSoundModel() data size %zu", soundModel.data.size()); @@ -124,19 +106,9 @@ int SoundTriggerHalImpl::doLoadSoundModel(const ISoundTriggerHw::SoundModel& sou goto exit; } - { - AutoMutex lock(mLock); - do { - *modelId = nextUniqueId(); - } while (mClients.valueFor(*modelId) != 0 && *modelId != 0); - } - LOG_ALWAYS_FATAL_IF(*modelId == 0, "wrap around in sound model IDs, num loaded models %zu", - mClients.size()); - - client = new SoundModelClient(*modelId, callback, cookie); - + sound_model_handle_t halHandle; ret = mHwDevice->load_sound_model(mHwDevice, halSoundModel, soundModelCallback, client.get(), - &client->mHalHandle); + &halHandle); free(halSoundModel); @@ -144,9 +116,10 @@ int SoundTriggerHalImpl::doLoadSoundModel(const ISoundTriggerHw::SoundModel& sou goto exit; } + client->setHalHandle(halHandle); { AutoMutex lock(mLock); - mClients.add(*modelId, client); + mClients.add(client->getId(), client); } exit: @@ -156,11 +129,9 @@ exit: Return SoundTriggerHalImpl::loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, const sp& callback, ISoundTriggerHwCallback::CallbackCookie cookie, - loadSoundModel_cb _hidl_cb) { - uint32_t modelId = 0; - int32_t ret = doLoadSoundModel(soundModel, callback, cookie, &modelId); - - _hidl_cb(ret, modelId); + ISoundTriggerHw::loadSoundModel_cb _hidl_cb) { + sp client = new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback); + _hidl_cb(doLoadSoundModel(soundModel, client), client->getId()); return Void(); } @@ -168,11 +139,9 @@ Return SoundTriggerHalImpl::loadPhraseSoundModel( const ISoundTriggerHw::PhraseSoundModel& soundModel, const sp& callback, ISoundTriggerHwCallback::CallbackCookie cookie, ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb) { - uint32_t modelId = 0; - int32_t ret = doLoadSoundModel((const ISoundTriggerHw::SoundModel&)soundModel, callback, cookie, - &modelId); - - _hidl_cb(ret, modelId); + sp client = new SoundModelClient_2_0(nextUniqueModelId(), cookie, callback); + _hidl_cb(doLoadSoundModel((const ISoundTriggerHw::SoundModel&)soundModel, client), + client->getId()); return Void(); } @@ -194,7 +163,7 @@ Return SoundTriggerHalImpl::unloadSoundModel(SoundModelHandle modelHand } } - ret = mHwDevice->unload_sound_model(mHwDevice, client->mHalHandle); + ret = mHwDevice->unload_sound_model(mHwDevice, client->getHalHandle()); mClients.removeItem(modelHandle); @@ -203,9 +172,7 @@ exit: } Return SoundTriggerHalImpl::startRecognition( - SoundModelHandle modelHandle, const ISoundTriggerHw::RecognitionConfig& config, - const sp& callback __unused, - ISoundTriggerHwCallback::CallbackCookie cookie __unused) { + SoundModelHandle modelHandle, const ISoundTriggerHw::RecognitionConfig& config) { int32_t ret; sp client; struct sound_trigger_recognition_config* halConfig; @@ -230,7 +197,7 @@ Return SoundTriggerHalImpl::startRecognition( ret = -EINVAL; goto exit; } - ret = mHwDevice->start_recognition(mHwDevice, client->mHalHandle, halConfig, + ret = mHwDevice->start_recognition(mHwDevice, client->getHalHandle(), halConfig, recognitionCallback, client.get()); free(halConfig); @@ -256,7 +223,7 @@ Return SoundTriggerHalImpl::stopRecognition(SoundModelHandle modelHandl } } - ret = mHwDevice->stop_recognition(mHwDevice, client->mHalHandle); + ret = mHwDevice->stop_recognition(mHwDevice, client->getHalHandle()); exit: return ret; @@ -316,9 +283,18 @@ SoundTriggerHalImpl::~SoundTriggerHalImpl() { } } -uint32_t SoundTriggerHalImpl::nextUniqueId() { - return (uint32_t)atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1, - memory_order_acq_rel); +uint32_t SoundTriggerHalImpl::nextUniqueModelId() { + uint32_t modelId = 0; + { + AutoMutex lock(mLock); + do { + modelId = + atomic_fetch_add_explicit(&mNextModelId, (uint_fast32_t)1, memory_order_acq_rel); + } while (mClients.valueFor(modelId) != 0 && modelId != 0); + } + LOG_ALWAYS_FATAL_IF(modelId == 0, "wrap around in sound model IDs, num loaded models %zu", + mClients.size()); + return modelId; } void SoundTriggerHalImpl::convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid) { @@ -464,31 +440,20 @@ void SoundTriggerHalImpl::convertSoundModelEventFromHal( } // static -ISoundTriggerHwCallback::RecognitionEvent* SoundTriggerHalImpl::convertRecognitionEventFromHal( - const struct sound_trigger_recognition_event* halEvent) { - ISoundTriggerHwCallback::RecognitionEvent* event; - - if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) { - const struct sound_trigger_phrase_recognition_event* halPhraseEvent = - reinterpret_cast(halEvent); - ISoundTriggerHwCallback::PhraseRecognitionEvent* phraseEvent = - new ISoundTriggerHwCallback::PhraseRecognitionEvent(); - - PhraseRecognitionExtra* phraseExtras = - new PhraseRecognitionExtra[halPhraseEvent->num_phrases]; - for (unsigned int i = 0; i < halPhraseEvent->num_phrases; i++) { - convertPhraseRecognitionExtraFromHal(&phraseExtras[i], - &halPhraseEvent->phrase_extras[i]); - } - phraseEvent->phraseExtras.setToExternal(phraseExtras, halPhraseEvent->num_phrases); - // FIXME: transfer buffer ownership. should have a method for that in hidl_vec - phraseEvent->phraseExtras.resize(halPhraseEvent->num_phrases); - delete[] phraseExtras; - event = reinterpret_cast(phraseEvent); - } else { - event = new ISoundTriggerHwCallback::RecognitionEvent(); +void SoundTriggerHalImpl::convertPhaseRecognitionEventFromHal( + ISoundTriggerHwCallback::PhraseRecognitionEvent* event, + const struct sound_trigger_phrase_recognition_event* halEvent) { + event->phraseExtras.resize(halEvent->num_phrases); + for (unsigned int i = 0; i < halEvent->num_phrases; i++) { + convertPhraseRecognitionExtraFromHal(&event->phraseExtras[i], &halEvent->phrase_extras[i]); } + convertRecognitionEventFromHal(&event->common, &halEvent->common); +} +// static +void SoundTriggerHalImpl::convertRecognitionEventFromHal( + ISoundTriggerHwCallback::RecognitionEvent* event, + const struct sound_trigger_recognition_event* halEvent) { event->status = static_cast(halEvent->status); event->type = static_cast(halEvent->type); // event->model to be remapped by called @@ -504,8 +469,6 @@ ISoundTriggerHwCallback::RecognitionEvent* SoundTriggerHalImpl::convertRecogniti event->data.setToExternal( const_cast(reinterpret_cast(halEvent)) + halEvent->data_offset, halEvent->data_size); - - return event; } // static @@ -515,20 +478,37 @@ void SoundTriggerHalImpl::convertPhraseRecognitionExtraFromHal( extra->recognitionModes = halExtra->recognition_modes; extra->confidenceLevel = halExtra->confidence_level; - ConfidenceLevel* levels = new ConfidenceLevel[halExtra->num_levels]; - for (unsigned int i = 0; i < halExtra->num_levels; i++) { - levels[i].userId = halExtra->levels[i].user_id; - levels[i].levelPercent = halExtra->levels[i].level; - } - extra->levels.setToExternal(levels, halExtra->num_levels); - // FIXME: transfer buffer ownership. should have a method for that in hidl_vec extra->levels.resize(halExtra->num_levels); - delete[] levels; + for (unsigned int i = 0; i < halExtra->num_levels; i++) { + extra->levels[i].userId = halExtra->levels[i].user_id; + extra->levels[i].levelPercent = halExtra->levels[i].level; + } } -ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* /* name */) { - return new SoundTriggerHalImpl(); +void SoundTriggerHalImpl::SoundModelClient_2_0::recognitionCallback( + struct sound_trigger_recognition_event* halEvent) { + if (halEvent->type == SOUND_MODEL_TYPE_KEYPHRASE) { + ISoundTriggerHwCallback::PhraseRecognitionEvent event; + convertPhaseRecognitionEventFromHal( + &event, reinterpret_cast(halEvent)); + event.common.model = mId; + mCallback->phraseRecognitionCallback(event, mCookie); + } else { + ISoundTriggerHwCallback::RecognitionEvent event; + convertRecognitionEventFromHal(&event, halEvent); + event.model = mId; + mCallback->recognitionCallback(event, mCookie); + } } + +void SoundTriggerHalImpl::SoundModelClient_2_0::soundModelCallback( + struct sound_trigger_model_event* halEvent) { + ISoundTriggerHwCallback::ModelEvent event; + convertSoundModelEventFromHal(&event, halEvent); + event.model = mId; + mCallback->soundModelCallback(event, mCookie); +} + } // namespace implementation } // namespace V2_0 } // namespace soundtrigger diff --git a/soundtrigger/2.0/default/SoundTriggerHalImpl.h b/soundtrigger/2.0/default/SoundTriggerHalImpl.h index 2dd7166ab7..5a9f0e19af 100644 --- a/soundtrigger/2.0/default/SoundTriggerHalImpl.h +++ b/soundtrigger/2.0/default/SoundTriggerHalImpl.h @@ -35,50 +35,115 @@ namespace implementation { using ::android::hardware::audio::common::V2_0::Uuid; using ::android::hardware::soundtrigger::V2_0::ISoundTriggerHwCallback; -class SoundTriggerHalImpl : public ISoundTriggerHw { +class SoundTriggerHalImpl : public RefBase { public: SoundTriggerHalImpl(); + ISoundTriggerHw* getInterface() { return new TrampolineSoundTriggerHw_2_0(this); } - // Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow. - Return getProperties(getProperties_cb _hidl_cb) override; - Return loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, - const sp& callback, - ISoundTriggerHwCallback::CallbackCookie cookie, - loadSoundModel_cb _hidl_cb) override; - Return loadPhraseSoundModel(const ISoundTriggerHw::PhraseSoundModel& soundModel, - const sp& callback, - ISoundTriggerHwCallback::CallbackCookie cookie, - loadPhraseSoundModel_cb _hidl_cb) override; - - Return unloadSoundModel(SoundModelHandle modelHandle) override; - Return startRecognition(SoundModelHandle modelHandle, - const ISoundTriggerHw::RecognitionConfig& config, - const sp& callback, - ISoundTriggerHwCallback::CallbackCookie cookie) override; - Return stopRecognition(SoundModelHandle modelHandle) override; - Return stopAllRecognitions() override; - - // RefBase - virtual void onFirstRef(); - - static void soundModelCallback(struct sound_trigger_model_event* halEvent, void* cookie); - static void recognitionCallback(struct sound_trigger_recognition_event* halEvent, void* cookie); - - private: + protected: class SoundModelClient : public RefBase { public: - SoundModelClient(uint32_t id, sp callback, - ISoundTriggerHwCallback::CallbackCookie cookie) - : mId(id), mCallback(callback), mCookie(cookie) {} + SoundModelClient(uint32_t id, ISoundTriggerHwCallback::CallbackCookie cookie) + : mId(id), mCookie(cookie) {} virtual ~SoundModelClient() {} - uint32_t mId; + uint32_t getId() const { return mId; } + sound_model_handle_t getHalHandle() const { return mHalHandle; } + void setHalHandle(sound_model_handle_t handle) { mHalHandle = handle; } + + virtual void recognitionCallback(struct sound_trigger_recognition_event* halEvent) = 0; + virtual void soundModelCallback(struct sound_trigger_model_event* halEvent) = 0; + + protected: + const uint32_t mId; sound_model_handle_t mHalHandle; - sp mCallback; ISoundTriggerHwCallback::CallbackCookie mCookie; }; - uint32_t nextUniqueId(); + static void convertPhaseRecognitionEventFromHal( + ISoundTriggerHwCallback::PhraseRecognitionEvent* event, + const struct sound_trigger_phrase_recognition_event* halEvent); + static void convertRecognitionEventFromHal( + ISoundTriggerHwCallback::RecognitionEvent* event, + const struct sound_trigger_recognition_event* halEvent); + static void convertSoundModelEventFromHal(ISoundTriggerHwCallback::ModelEvent* event, + const struct sound_trigger_model_event* halEvent); + + virtual ~SoundTriggerHalImpl(); + + Return getProperties(ISoundTriggerHw::getProperties_cb _hidl_cb); + Return loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, + const sp& callback, + ISoundTriggerHwCallback::CallbackCookie cookie, + ISoundTriggerHw::loadSoundModel_cb _hidl_cb); + Return loadPhraseSoundModel(const ISoundTriggerHw::PhraseSoundModel& soundModel, + const sp& callback, + ISoundTriggerHwCallback::CallbackCookie cookie, + ISoundTriggerHw::loadPhraseSoundModel_cb _hidl_cb); + Return unloadSoundModel(SoundModelHandle modelHandle); + Return startRecognition(SoundModelHandle modelHandle, + const ISoundTriggerHw::RecognitionConfig& config); + Return stopRecognition(SoundModelHandle modelHandle); + Return stopAllRecognitions(); + + uint32_t nextUniqueModelId(); + int doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, + sp client); + + // RefBase + void onFirstRef() override; + + private: + struct TrampolineSoundTriggerHw_2_0 : public ISoundTriggerHw { + explicit TrampolineSoundTriggerHw_2_0(sp impl) : mImpl(impl) {} + + // Methods from ::android::hardware::soundtrigger::V2_0::ISoundTriggerHw follow. + Return getProperties(getProperties_cb _hidl_cb) override { + return mImpl->getProperties(_hidl_cb); + } + Return loadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, + const sp& callback, + ISoundTriggerHwCallback::CallbackCookie cookie, + loadSoundModel_cb _hidl_cb) override { + return mImpl->loadSoundModel(soundModel, callback, cookie, _hidl_cb); + } + Return loadPhraseSoundModel(const ISoundTriggerHw::PhraseSoundModel& soundModel, + const sp& callback, + ISoundTriggerHwCallback::CallbackCookie cookie, + loadPhraseSoundModel_cb _hidl_cb) override { + return mImpl->loadPhraseSoundModel(soundModel, callback, cookie, _hidl_cb); + } + Return unloadSoundModel(SoundModelHandle modelHandle) override { + return mImpl->unloadSoundModel(modelHandle); + } + Return startRecognition( + SoundModelHandle modelHandle, const ISoundTriggerHw::RecognitionConfig& config, + const sp& /*callback*/, + ISoundTriggerHwCallback::CallbackCookie /*cookie*/) override { + return mImpl->startRecognition(modelHandle, config); + } + Return stopRecognition(SoundModelHandle modelHandle) override { + return mImpl->stopRecognition(modelHandle); + } + Return stopAllRecognitions() override { return mImpl->stopAllRecognitions(); } + + private: + sp mImpl; + }; + + class SoundModelClient_2_0 : public SoundModelClient { + public: + SoundModelClient_2_0(uint32_t id, ISoundTriggerHwCallback::CallbackCookie cookie, + sp callback) + : SoundModelClient(id, cookie), mCallback(callback) {} + + void recognitionCallback(struct sound_trigger_recognition_event* halEvent) override; + void soundModelCallback(struct sound_trigger_model_event* halEvent) override; + + private: + sp mCallback; + }; + void convertUuidFromHal(Uuid* uuid, const sound_trigger_uuid_t* halUuid); void convertUuidToHal(sound_trigger_uuid_t* halUuid, const Uuid* uuid); void convertPropertiesFromHal(ISoundTriggerHw::Properties* properties, @@ -94,19 +159,12 @@ class SoundTriggerHalImpl : public ISoundTriggerHw { struct sound_trigger_recognition_config* convertRecognitionConfigToHal( const ISoundTriggerHw::RecognitionConfig* config); - static void convertSoundModelEventFromHal(ISoundTriggerHwCallback::ModelEvent* event, - const struct sound_trigger_model_event* halEvent); - static ISoundTriggerHwCallback::RecognitionEvent* convertRecognitionEventFromHal( - const struct sound_trigger_recognition_event* halEvent); static void convertPhraseRecognitionExtraFromHal( PhraseRecognitionExtra* extra, const struct sound_trigger_phrase_recognition_extra* halExtra); - int doLoadSoundModel(const ISoundTriggerHw::SoundModel& soundModel, - const sp& callback, - ISoundTriggerHwCallback::CallbackCookie cookie, uint32_t* modelId); - - virtual ~SoundTriggerHalImpl(); + static void soundModelCallback(struct sound_trigger_model_event* halEvent, void* cookie); + static void recognitionCallback(struct sound_trigger_recognition_event* halEvent, void* cookie); const char* mModuleName; struct sound_trigger_hw_device* mHwDevice; @@ -115,8 +173,6 @@ class SoundTriggerHalImpl : public ISoundTriggerHw { Mutex mLock; }; -extern "C" ISoundTriggerHw* HIDL_FETCH_ISoundTriggerHw(const char* name); - } // namespace implementation } // namespace V2_0 } // namespace soundtrigger