diff --git a/intelligent_voice/BUILD.gn b/intelligent_voice/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..145c4143b64d7fcbee195cd56843e917eec9e9fd --- /dev/null +++ b/intelligent_voice/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +if (defined(ohos_lite)) { + group("intell_voice_engine_entry") { + deps = [] + } + group("intell_voice_trigger_entry") { + deps = [] + } +} else { + group("intell_voice_engine_entry") { + deps = [ "hdi_service/engine:hdi_intell_voice_engine_service" ] + } + group("intell_voice_trigger_entry") { + deps = [ "hdi_service/trigger:hdi_intell_voice_trigger_service" ] + } +} diff --git a/intelligent_voice/README_zh.md b/intelligent_voice/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..1bc62b325fe95ce8d3c9fda15174e7ca13f1298a --- /dev/null +++ b/intelligent_voice/README_zh.md @@ -0,0 +1,187 @@ +# intelligent_voice + +- [简介](#section11660541593) +- [目录](#section161941989596) + - [接口说明](#section1551164914237) + - [使用说明](#section129654513264) + +- [相关仓](#section1371113476307) + +## 简介 + +intelligent_voice仓下主要包含HDI接口,HDI接口主要用于: + +- 智能音频引擎的注册、管理、回调 +- Trigger模型的管理、加载、卸载,以及回调 + +## 目录 + +该仓下源代码目录结构如下所示 + +``` +drivers/peripheral/intelligent_voice/ +├── hdi_service # hdi服务,虚拟接口实现 +│ └── engine # engine虚拟接口实现 +│ └── trigger # trigger虚拟接口实现 +├── interfaces # intelligent_voice模块定义的虚拟接口 +│ └── include # 接口定义 +``` + +### 接口说明 + +intelligent_voice模块提供给intelligent_voice_framework可直接调用的能力接口,主要功能有:智能音频引擎的注册、管理、回调,Trigger模型的加载卸载,回调,以及管理等。 + +提供的部分接口说明如[表1 intelligent_voice HDI接口](#table1513255710559)所示: + +**表 1** intelligent_voice HDI接口 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

头文件

+

接口名称

+

功能描述

+

i_engine.h

+

+

+

virtual void OnIntellVoiceEvent(const IntellVoiceEngineCallBackEvent &event) = 0;

+

开启智能语音事件

+

virtual IntellVoiceStatus SetListener(std::shared_ptr listener) = 0;

+

设置监听器

+

virtual IntellVoiceStatus Init(const IntellVoiceEngineAdapterInfo &adapterInfo) = 0;

+

初始化

+

virtual IntellVoiceStatus Release() = 0;

+

释放

+

virtual IntellVoiceStatus SetParameter(const std::string &keyValueList) = 0;

+

设置参数

+

virtual IntellVoiceStatus GetParameter(const std::string &keyList, getParameterCb cb) = 0;

+

获取参数

+

virtual IntellVoiceStatus Write(const uint8_t *buffer, uint32_t size) = 0;

+

写入

+

virtual IntellVoiceStatus Start(const StartInfo& info) = 0;

+

启动

+

virtual IntellVoiceStatus Stop() = 0;

+

停止

+

virtual IntellVoiceStatus Cancel() = 0;

+

取消

+

virtual IntellVoiceStatus ReadFileData(const std::string &filePath, getFileDataCb cb) = 0;

+

读取文件数据

+

virtual int32_t CreateAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor, std::unique_ptr &engine) = 0;

+

创建适配器

+

virtual int32_t ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor) = 0;

+

释放适配器

+

+

i_trigger.h

+

+

+

+

+

virtual void OnRecognitionHdiEvent(const IntellVoiceRecognitionEvent &event, int32_t cookie) = 0;

+

开启识别接口事件

+

virtual int32_t GetProperties(IntellVoiceTriggerProperties &properties) = 0;

+

获取属性

+

virtual int32_t LoadIntellVoiceTriggerModel(const TriggerModel &model, + const std::shared_ptr &callback, int32_t cookie, int32_t &handle) = 0;

+

加载智能语音触发模型

+

virtual int32_t UnloadIntellVoiceTriggerModel(int32_t handle) = 0;

+

卸载智能语音触发模型

+

virtual int32_t Start(int32_t handle) = 0;

+

启动

+

virtual int32_t Stop(int32_t handle) = 0;

+

停止

+

virtual int32_t LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor, std::unique_ptr &adapter) = 0;

+

加载适配器

+

virtual int32_t UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor) = 0;

+

卸载适配器

+
+ +### 使用说明 + +该仓核心功能包括两个方面: + +1. 提供intelligent_voice HDI接口供framework层调用,实现智能音频服务的基本功能。 +2. 作为标准南向接口,保证南向OEM产商实现HDI-adapter的规范性,保证生态良性演进。 + +具体接口调用及实现,以接口注释为准。 + +## 相关仓 + +[驱动子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E9%A9%B1%E5%8A%A8%E5%AD%90%E7%B3%BB%E7%BB%9F.md) + +[drivers\_framework](https://gitee.com/openharmony/drivers_framework/blob/master/README_zh.md) + +[drivers\_adapter](https://gitee.com/openharmony/drivers_adapter/blob/master/README_zh.md) + +[drivers\_adapter\_khdf\_linux](https://gitee.com/openharmony/drivers_adapter_khdf_linux/blob/master/README_zh.md) + +[drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral) + diff --git a/intelligent_voice/bundle.json b/intelligent_voice/bundle.json new file mode 100644 index 0000000000000000000000000000000000000000..b36ba4ef95429fe8afcb3e6954118c8f8184b466 --- /dev/null +++ b/intelligent_voice/bundle.json @@ -0,0 +1,40 @@ +{ + "name": "@ohos/drivers_peripheral_intelligent_voice", + "description": "intelligent_voice device driver", + "version": "4.0", + "license": "Apache License 2.0", + "publishAs": "code-segment", + "segment": { + "destPath": "drivers/peripheral/intelligent_voice" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "drivers_peripheral_intelligent_voice", + "subsystem": "hdf", + "features": ["drivers_peripheral_intelligent_voice_feature_community"], + "adapted_system_type": ["standard"], + "rom": "675KB", + "ram": "2048KB", + "deps": { + "components": [ + "c_utils", + "drivers_interface_intelligent_voice", + "hdf_core", + "hilog", + "ipc" + ], + "third_part": [ + "bounds_checking_function", + "googletest" + ] + }, + "build": { + "sub_component": [ + "//drivers/peripheral/intelligent_voice:intell_voice_engine_entry", + "//drivers/peripheral/intelligent_voice:intell_voice_trigger_entry" + ], + "test": [] + } + } +} diff --git a/intelligent_voice/hdi_service/engine/BUILD.gn b/intelligent_voice/hdi_service/engine/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..4a68e5058319a18c640bedc0b26073e55eb71340 --- /dev/null +++ b/intelligent_voice/hdi_service/engine/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("../../intelligent_voice.gni") + +ohos_shared_library("intell_voice_engine_manager_service_1.0") { + include_dirs = [ + "//third_party/bounds_checking_function/include", + "../../interfaces", + "../../utils", + ] + + sources = [ + "intell_voice_engine_adapter_impl.cpp", + "intell_voice_engine_manager_impl.cpp", + ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:intell_voice_engine_idl_headers", + "hilog:libhilog", + "ipc:ipc_single", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} + +ohos_shared_library("intell_voice_engine_driver") { + include_dirs = [ "../../utils" ] + + sources = [ "intell_voice_engine_driver.cpp" ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:libintell_voice_engine_stub_1.0", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hilog:libhilog", + "ipc:ipc_single", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + shlib_type = "hdi" + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} + +group("hdi_intell_voice_engine_service") { + deps = [ + ":intell_voice_engine_driver", + ":intell_voice_engine_manager_service_1.0", + ] + + if (drivers_peripheral_intelligent_voice_feature_community) { + deps += [ "../../passthrough:vendor_intell_voice_engine" ] + } +} diff --git a/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.cpp b/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a9577335ed5690db4ff58e18c6f34a94492e60bc --- /dev/null +++ b/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 "intell_voice_engine_adapter_impl.h" + +#include +#include +#include + +#include "hdf_base.h" +#include "intell_voice_log.h" +#include "securec.h" +#include "scope_guard.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntellVoiceEngineAdapterImpl" + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +IntellVoiceEngineAdapterImpl::IntellVoiceEngineAdapterImpl(std::unique_ptr engine) + : engine_(std::move(engine)) +{} + +IntellVoiceEngineAdapterImpl::~IntellVoiceEngineAdapterImpl() +{ + engine_ = nullptr; +} + +int32_t IntellVoiceEngineAdapterImpl::SetCallback(const sptr &adapterCallback) +{ + if (adapterCallback == nullptr) { + INTELLIGENT_VOICE_LOGE("callback is nullptr"); + return HDF_ERR_MALLOC_FAIL; + } + + std::shared_ptr listener = std::make_shared(adapterCallback); + if (listener == nullptr) { + INTELLIGENT_VOICE_LOGE("listener is nullptr"); + return HDF_ERR_MALLOC_FAIL; + } + + if (engine_->SetListener(listener) != 0) { + INTELLIGENT_VOICE_LOGE("failed to set listener"); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t IntellVoiceEngineAdapterImpl::Attach(const IntellVoiceEngineAdapterInfo& info) +{ + INTELLIGENT_VOICE_LOGD("Attach enter"); + return engine_->Init(info); +} + +int32_t IntellVoiceEngineAdapterImpl::Detach() +{ + INTELLIGENT_VOICE_LOGD("Detach enter"); + return engine_->Release(); +} + +int32_t IntellVoiceEngineAdapterImpl::SetParameter(const std::string &keyValueList) +{ + INTELLIGENT_VOICE_LOGD("SetParameter enter"); + return engine_->SetParameter(keyValueList); +} + +int32_t IntellVoiceEngineAdapterImpl::GetParameter(const std::string &keyList, std::string &valueList) +{ + INTELLIGENT_VOICE_LOGD("GetParameter enter"); + return engine_->GetParameter(keyList, [&](const std::string &retStr) { valueList = retStr; }); +} + +int32_t IntellVoiceEngineAdapterImpl::Start(const StartInfo &info) +{ + INTELLIGENT_VOICE_LOGD("Start enter"); + return engine_->Start(info); +} + +int32_t IntellVoiceEngineAdapterImpl::Stop() +{ + INTELLIGENT_VOICE_LOGD("Stop enter"); + return engine_->Stop(); +} + +int32_t IntellVoiceEngineAdapterImpl::WriteAudio(const std::vector &buffer) +{ + return engine_->Write(buffer.data(), buffer.size()); +} + +int32_t IntellVoiceEngineAdapterImpl::Read(ContentType type, sptr &buffer) +{ + INTELLIGENT_VOICE_LOGD("enter"); + uint8_t *tmp = nullptr; + uint32_t size = 0; + + ReadFileDataInner(type, tmp, size); + if (tmp == nullptr) { + INTELLIGENT_VOICE_LOGE("tmp buffer is nullptr"); + return HDF_ERR_INVALID_OBJECT; + } + + ON_SCOPE_EXIT_WITH_NAME(bufferExit) + { + INTELLIGENT_VOICE_LOGI("now delete buffer"); + delete[] tmp; + tmp = nullptr; + }; + + if (size == 0) { + INTELLIGENT_VOICE_LOGE("size(%{public}u) is invalid", size); + return HDF_ERR_INVALID_OBJECT; + } + + buffer = OHOS::Ashmem::CreateAshmem("ReadContent", size); + if (buffer == nullptr) { + INTELLIGENT_VOICE_LOGE("ashmem buffer is nullptr, size:%{public}u", size); + return HDF_ERR_INVALID_OBJECT; + } + + if (!buffer->MapReadAndWriteAshmem()) { + INTELLIGENT_VOICE_LOGE("failed to map and write ashmem"); + return HDF_FAILURE; + } + + if (!buffer->WriteToAshmem(tmp, size, 0)) { + INTELLIGENT_VOICE_LOGE("failed to write to ashmem"); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t IntellVoiceEngineAdapterImpl::ReadFileDataInner(ContentType type, uint8_t *&buffer, uint32_t &size) +{ + INTELLIGENT_VOICE_LOGD("enter"); + return engine_->ReadFileData(type, [&](std::shared_ptr fileData, uint32_t fileSize) { + buffer = new (std::nothrow) uint8_t[fileSize]; + if (buffer == nullptr) { + INTELLIGENT_VOICE_LOGE("buffer is nullptr"); + return; + } + size = fileSize; + (void)memcpy_s(buffer, size, fileData.get(), fileSize); + }); +} + +EngineListener::EngineListener(const sptr &cb) : cb_(cb) +{ +} + +EngineListener::~EngineListener() +{ + cb_ = nullptr; +} + +void EngineListener::OnIntellVoiceEvent(const IntellVoiceEngineCallBackEvent &event) +{ + if (cb_ == nullptr) { + INTELLIGENT_VOICE_LOGE("cb_ is nullptr"); + return; + } + + cb_->OnIntellVoiceHdiEvent(event); +} +} +} +} diff --git a/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.h b/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..fadfeec8c7944db82ee85a40eda43f6863caa36c --- /dev/null +++ b/intelligent_voice/hdi_service/engine/intell_voice_engine_adapter_impl.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_ADAPTER_SERVICE_H +#define HDI_DEVICE_INTELL_VOICE_ADAPTER_SERVICE_H + +#include +#include +#include + +#include "v1_0/iintell_voice_engine_adapter.h" +#include "i_engine.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineCallback; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent; + +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineAdapter; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineAdapterInfo; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::StartInfo; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType; + +class EngineListener : public IEngineCallback { +public: + explicit EngineListener(const sptr &cb); + ~EngineListener(); + void OnIntellVoiceEvent(const IntellVoiceEngineCallBackEvent &event) override; +private: + sptr cb_; +}; + +class IntellVoiceEngineAdapterImpl : public IIntellVoiceEngineAdapter { +public: + explicit IntellVoiceEngineAdapterImpl(std::unique_ptr engine); + ~IntellVoiceEngineAdapterImpl(); + + int32_t SetCallback(const sptr& engineCallback) override; + int32_t Attach(const IntellVoiceEngineAdapterInfo& info) override; + int32_t Detach() override; + int32_t SetParameter(const std::string& keyValueList) override; + int32_t GetParameter(const std::string& keyList, std::string& valueList) override; + int32_t Start(const StartInfo &info) override; + int32_t Stop() override; + int32_t WriteAudio(const std::vector& buffer) override; + int32_t Read(ContentType type, sptr& buffer) override; + +private: + int32_t ReadFileDataInner(ContentType type, uint8_t *&buffer, uint32_t &size); + +private: + std::unique_ptr engine_ = nullptr; +}; +} +} +} +#endif diff --git a/intelligent_voice/hdi_service/engine/intell_voice_engine_driver.cpp b/intelligent_voice/hdi_service/engine/intell_voice_engine_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..48025ed7166b4066ab0745038c5df286433c7d6e --- /dev/null +++ b/intelligent_voice/hdi_service/engine/intell_voice_engine_driver.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 +#include +#include "intell_voice_log.h" +#include +#include "v1_0/intell_voice_engine_manager_stub.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntellVoiceEngineDriver" + +using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0; + +struct HdfIntellVoiceEngineManagerHost { + struct IDeviceIoService ioService; + OHOS::sptr stub; +}; + +static int32_t IntellVoiceEngineManagerDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + auto *hdfIntellVoiceEngineManagerHost = CONTAINER_OF(client->device->service, + struct HdfIntellVoiceEngineManagerHost, ioService); + + OHOS::MessageParcel *dataParcel = nullptr; + OHOS::MessageParcel *replyParcel = nullptr; + OHOS::MessageOption option; + + if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { + INTELLIGENT_VOICE_LOGE("invalid data sbuf object to dispatch"); + return HDF_ERR_INVALID_PARAM; + } + if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { + INTELLIGENT_VOICE_LOGE("invalid reply sbuf object to dispatch"); + return HDF_ERR_INVALID_PARAM; + } + + return hdfIntellVoiceEngineManagerHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option); +} + +static int HdfIntellVoiceEngineManagerDriverInit(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver init start"); + return HDF_SUCCESS; +} + +static int HdfIntellVoiceEngineManagerDriverBind(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver bind start"); + auto *hdfIntellVoiceEngineManagerHost = new (std::nothrow) HdfIntellVoiceEngineManagerHost; + if (hdfIntellVoiceEngineManagerHost == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to create create HdfIntellVoiceEngineManagerHost object"); + return HDF_FAILURE; + } + + hdfIntellVoiceEngineManagerHost->ioService.Dispatch = IntellVoiceEngineManagerDriverDispatch; + hdfIntellVoiceEngineManagerHost->ioService.Open = NULL; + hdfIntellVoiceEngineManagerHost->ioService.Release = NULL; + + auto serviceImpl = IIntellVoiceEngineManager::Get(true); + if (serviceImpl == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to get of implement service"); + delete hdfIntellVoiceEngineManagerHost; + return HDF_FAILURE; + } + + hdfIntellVoiceEngineManagerHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, + IIntellVoiceEngineManager::GetDescriptor()); + if (hdfIntellVoiceEngineManagerHost->stub == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to get stub object"); + delete hdfIntellVoiceEngineManagerHost; + return HDF_FAILURE; + } + + deviceObject->service = &hdfIntellVoiceEngineManagerHost->ioService; + return HDF_SUCCESS; +} + +static void HdfIntellVoiceEngineManagerDriverRelease(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver release start"); + if (deviceObject->service == nullptr) { + return; + } + + auto *hdfIntellVoiceEngineManagerHost = CONTAINER_OF(deviceObject->service, + struct HdfIntellVoiceEngineManagerHost, ioService); + if (hdfIntellVoiceEngineManagerHost != nullptr) { + delete hdfIntellVoiceEngineManagerHost; + } +} + +struct HdfDriverEntry g_intellvoiceenginemanagerDriverEntry = { + .moduleVersion = 1, + .moduleName = "intell_voice_engine_service", + .Bind = HdfIntellVoiceEngineManagerDriverBind, + .Init = HdfIntellVoiceEngineManagerDriverInit, + .Release = HdfIntellVoiceEngineManagerDriverRelease, +}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +HDF_INIT(g_intellvoiceenginemanagerDriverEntry); +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.cpp b/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0bc4861abc6fba08ea003239c600571dcfae7a3f --- /dev/null +++ b/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 "intell_voice_engine_manager_impl.h" + +#include +#include +#include "hdf_base.h" +#include "intell_voice_log.h" +#include "intell_voice_engine_adapter_impl.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntelligentVoiceEngineManagerImpl" + +using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0; + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +extern "C" IIntellVoiceEngineManager *IntellVoiceEngineManagerImplGetInstance(void) +{ + return new (std::nothrow) IntellVoiceEngineManagerImpl(); +} + +int32_t IntellVoiceEngineManagerImpl::LoadVendorLib() +{ + std::string error; + const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libvendor_intell_voice_engine"); + engineManagerPriv_.handle = dlopen(vendorLibPath, RTLD_LAZY); + if (engineManagerPriv_.handle == nullptr) { + error = dlerror(); + INTELLIGENT_VOICE_LOGE("load path%{public}s, dlopen err=%{public}s", vendorLibPath, error.c_str()); + return -1; + } + + (void)dlerror(); // clear existing error + + engineManagerPriv_.getEngineManagerHalInst = reinterpret_cast(dlsym( + engineManagerPriv_.handle, "GetIntellVoiceEngineManagerHalInst")); + if (engineManagerPriv_.getEngineManagerHalInst == nullptr) { + error = dlerror(); + INTELLIGENT_VOICE_LOGE("dlsym GetIntellVoiceEngineManagerHalInst err=%{public}s", error.c_str()); + dlclose(engineManagerPriv_.handle); + engineManagerPriv_.handle = nullptr; + return -1; + } + + INTELLIGENT_VOICE_LOGI("load vendor lib success"); + + return 0; +} + +void IntellVoiceEngineManagerImpl::UnloadVendorLib() +{ + if (engineManagerPriv_.handle != nullptr) { + dlclose(engineManagerPriv_.handle); + engineManagerPriv_.handle = nullptr; + } +} + +IntellVoiceEngineManagerImpl::IntellVoiceEngineManagerImpl() +{ + if (LoadVendorLib() == 0) { + inst_ = engineManagerPriv_.getEngineManagerHalInst(); + } +} + +IntellVoiceEngineManagerImpl::~IntellVoiceEngineManagerImpl() +{ + UnloadVendorLib(); + adapters_.clear(); + inst_ = nullptr; +} + +int32_t IntellVoiceEngineManagerImpl::GetAdapterDescriptors(std::vector& descs) +{ + return HDF_SUCCESS; +} + +int32_t IntellVoiceEngineManagerImpl::CreateAdapter( + const IntellVoiceEngineAdapterDescriptor &descriptor, sptr &adapter) +{ + std::lock_guard lock(mutex_); + + if (inst_ == nullptr) { + INTELLIGENT_VOICE_LOGE("inst is nullptr"); + return HDF_FAILURE; + } + + std::unique_ptr engine = nullptr; + inst_->CreateAdapter(descriptor, engine); + if (engine == nullptr) { + INTELLIGENT_VOICE_LOGE("get adapter device from hal failed"); + return HDF_FAILURE; + } + + adapter = sptr(new (std::nothrow) IntellVoiceEngineAdapterImpl(std::move(engine))); + if (adapter == nullptr) { + INTELLIGENT_VOICE_LOGE("malloc intell voice adapter server failed "); + return HDF_ERR_MALLOC_FAIL; + } + + adapters_.insert(std::make_pair(descriptor.adapterType, adapter)); + return HDF_SUCCESS; +} + +int32_t IntellVoiceEngineManagerImpl::ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor) +{ + std::lock_guard lock(mutex_); + + if (inst_ == nullptr) { + INTELLIGENT_VOICE_LOGE("inst is nullptr"); + return HDF_FAILURE; + } + + auto it = adapters_.find(descriptor.adapterType); + if (it == adapters_.end()) { + INTELLIGENT_VOICE_LOGW("can not find adapter, %{public}d", descriptor.adapterType); + return HDF_SUCCESS; + } + + inst_->ReleaseAdapter(descriptor); + + it->second = nullptr; + adapters_.erase(it); + return HDF_SUCCESS; +} +} +} +} diff --git a/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.h b/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..01f29e71a589a125b1777540e934eb061f101bd2 --- /dev/null +++ b/intelligent_voice/hdi_service/engine/intell_voice_engine_manager_impl.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_MANAGER_IMPL_H +#define HDI_DEVICE_INTELL_VOICE_MANAGER_IMPL_H + +#include +#include +#include + +#include "v1_0/intell_voice_engine_types.h" +#include "v1_0/iintell_voice_engine_manager.h" +#include "i_engine.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineManager; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineAdapter; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineAdapterType; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineAdapterDescriptor; + +using GetEngineManagerHalInstFunc = IEngineManager *(*)(); + +struct IntellVoiceEngineManagerPriv { + void *handle { nullptr }; + GetEngineManagerHalInstFunc getEngineManagerHalInst { nullptr }; +}; + +class IntellVoiceEngineManagerImpl : public IIntellVoiceEngineManager { +public: + IntellVoiceEngineManagerImpl(); + ~IntellVoiceEngineManagerImpl(); + + int32_t GetAdapterDescriptors(std::vector& descs) override; + int32_t CreateAdapter(const IntellVoiceEngineAdapterDescriptor& descriptor, + sptr& adapter) override; + int32_t ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor& descriptor) override; + +private: + int32_t LoadVendorLib(); + void UnloadVendorLib(); + +private: + std::map> adapters_; + std::mutex mutex_ {}; + IntellVoiceEngineManagerPriv engineManagerPriv_; + IEngineManager *inst_ = nullptr; +}; +} +} +} +#endif \ No newline at end of file diff --git a/intelligent_voice/hdi_service/trigger/BUILD.gn b/intelligent_voice/hdi_service/trigger/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5b48200c91a64950d4ff5102e14d975eec905191 --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/BUILD.gn @@ -0,0 +1,88 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") +import("../../intelligent_voice.gni") + +ohos_shared_library("intell_voice_trigger_manager_service_1.0") { + include_dirs = [ + "//third_party/bounds_checking_function/include", + "../../interfaces", + "../../utils", + ] + + sources = [ + "intell_voice_trigger_adapter_impl.cpp", + "intell_voice_trigger_manager_impl.cpp", + ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:intell_voice_trigger_idl_headers", + "hilog:libhilog", + "ipc:ipc_single", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} + +ohos_shared_library("intell_voice_trigger_driver") { + include_dirs = [ "../../utils" ] + + sources = [ "intell_voice_trigger_driver.cpp" ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:libintell_voice_trigger_stub_1.0", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hilog:libhilog", + "ipc:ipc_single", + ] + } else { + external_deps = [ + "hilog:libhilog", + "ipc:ipc_single", + ] + } + + shlib_type = "hdi" + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} + +group("hdi_intell_voice_trigger_service") { + deps = [ + ":intell_voice_trigger_driver", + ":intell_voice_trigger_manager_service_1.0", + ] + + if (drivers_peripheral_intelligent_voice_feature_community) { + deps += [ "../../passthrough:vendor_intell_voice_trigger" ] + } +} diff --git a/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.cpp b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64485c7c579e09b41e25f8ec9ececf465258d9db --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 "intell_voice_trigger_adapter_impl.h" +#include "hdf_base.h" +#include "intell_voice_log.h" +#include "securec.h" +#include "scope_guard.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "TriggerAdapterImpl" + +using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0; + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +IntellVoiceTriggerCallbackDevice::IntellVoiceTriggerCallbackDevice(OHOS::sptr callback) + : callback_(callback) +{ +} + +IntellVoiceTriggerCallbackDevice::~IntellVoiceTriggerCallbackDevice() +{ + callback_ = nullptr; +} + +void IntellVoiceTriggerCallbackDevice::OnRecognitionHdiEvent(const IntellVoiceRecognitionEvent &event, int32_t cookie) +{ + if (callback_ == nullptr) { + INTELLIGENT_VOICE_LOGE("callback_ is nullptr"); + return; + } + callback_->OnRecognitionHdiEvent(event, cookie); +} + +IntellVoiceTriggerAdapterImpl::IntellVoiceTriggerAdapterImpl(std::unique_ptr adapter) + : adapter_(std::move(adapter)) +{ +} + +IntellVoiceTriggerAdapterImpl::~IntellVoiceTriggerAdapterImpl() +{ + adapter_ = nullptr; +} + +int32_t IntellVoiceTriggerAdapterImpl::GetProperties(IntellVoiceTriggerProperties& properties) +{ + return adapter_->GetProperties(properties); +} + +int32_t IntellVoiceTriggerAdapterImpl::LoadModel(const IntellVoiceTriggerModel &model, + const sptr &triggerCallback, int32_t cookie, int32_t &handle) +{ + std::shared_ptr cb = std::make_shared(triggerCallback); + if (cb == nullptr) { + INTELLIGENT_VOICE_LOGE("callback is nullptr"); + return HDF_ERR_MALLOC_FAIL; + } + + if (model.data == nullptr) { + INTELLIGENT_VOICE_LOGE("model data is nullptr"); + return HDF_ERR_INVALID_PARAM; + } + + ON_SCOPE_EXIT { + INTELLIGENT_VOICE_LOGI("close ashmem"); + model.data->UnmapAshmem(); + model.data->CloseAshmem(); + }; + + std::vector modelData; + if (!GetModelDataFromAshmem(model.data, modelData)) { + return HDF_ERR_INVALID_PARAM; + } + + TriggerModel triggerModel(model.type, model.uid, modelData); + return adapter_->LoadIntellVoiceTriggerModel(triggerModel, cb, cookie, handle); +} + +int32_t IntellVoiceTriggerAdapterImpl::UnloadModel(int32_t handle) +{ + return adapter_->UnloadIntellVoiceTriggerModel(handle); +} + +int32_t IntellVoiceTriggerAdapterImpl::Start(int32_t handle) +{ + return adapter_->Start(handle); +} + +int32_t IntellVoiceTriggerAdapterImpl::Stop(int32_t handle) +{ + return adapter_->Stop(handle); +} + +bool IntellVoiceTriggerAdapterImpl::GetModelDataFromAshmem(sptr ashmem, std::vector &modelData) +{ + if (ashmem == nullptr) { + INTELLIGENT_VOICE_LOGE("ashmem is nullptr"); + return false; + } + + uint32_t size = static_cast(ashmem->GetAshmemSize()); + if (size == 0) { + INTELLIGENT_VOICE_LOGE("size is zero"); + return false; + } + + if (!ashmem->MapReadOnlyAshmem()) { + INTELLIGENT_VOICE_LOGE("map ashmem failed"); + return false; + } + + const uint8_t *buffer = static_cast(ashmem->ReadFromAshmem(size, 0)); + if (buffer == nullptr) { + INTELLIGENT_VOICE_LOGE("read from ashmem failed"); + return false; + } + + modelData.insert(modelData.begin(), buffer, buffer + size); + return true; +} +} +} +} diff --git a/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.h b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..4508155698fc17ed97c36ce87677d26a6fd2826c --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_adapter_impl.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_TRIGGER_ADAPTER_IMPL_H +#define HDI_DEVICE_INTELL_VOICE_TRIGGER_ADAPTER_IMPL_H + +#include + +#include "v1_0/iintell_voice_trigger_adapter.h" +#include "i_trigger.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerProperties; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerModel; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceRecognitionEvent; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerCallback; + +class IntellVoiceTriggerCallbackDevice : public ITriggerCallback { +public: + explicit IntellVoiceTriggerCallbackDevice(OHOS::sptr callback); + ~IntellVoiceTriggerCallbackDevice(); + void OnRecognitionHdiEvent(const IntellVoiceRecognitionEvent &event, int32_t cookie) override; + +private: + OHOS::sptr callback_ = nullptr; +}; + +class IntellVoiceTriggerAdapterImpl : + public OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerAdapter { +public: + explicit IntellVoiceTriggerAdapterImpl(std::unique_ptr adapter); + ~IntellVoiceTriggerAdapterImpl(); + + int32_t GetProperties(IntellVoiceTriggerProperties &properties) override; + int32_t LoadModel(const IntellVoiceTriggerModel &model, const sptr &triggerCallback, + int32_t cookie, int32_t &handle) override; + int32_t UnloadModel(int32_t handle) override; + int32_t Start(int32_t handle) override; + int32_t Stop(int32_t handle) override; + +private: + bool GetModelDataFromAshmem(sptr ashmem, std::vector &modelData); + +private: + std::unique_ptr adapter_ = nullptr; +}; +} +} +} +#endif // HDI_DEVICE_INTELL_VOICE_TRIGGER_ADAPTER_IMPL_H diff --git a/intelligent_voice/hdi_service/trigger/intell_voice_trigger_driver.cpp b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_driver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00a16334425c2fcd6f2211b64e1ea1993e74588c --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_driver.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 +#include +#include "intell_voice_log.h" +#include +#include "v1_0/intell_voice_trigger_manager_stub.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntellVoiceTriggerDriver" + +using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0; + +struct HdfIntellVoiceTriggerManagerHost { + struct IDeviceIoService ioService; + OHOS::sptr stub; +}; + +static int32_t IntellVoiceTriggerManagerDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, + struct HdfSBuf *data, struct HdfSBuf *reply) +{ + auto *hdfIntellVoiceTriggerManagerHost = CONTAINER_OF(client->device->service, + struct HdfIntellVoiceTriggerManagerHost, ioService); + + OHOS::MessageParcel *dataParcel = nullptr; + OHOS::MessageParcel *replyParcel = nullptr; + OHOS::MessageOption option; + + if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) { + INTELLIGENT_VOICE_LOGE("invalid data sbuf object to dispatch"); + return HDF_ERR_INVALID_PARAM; + } + if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) { + INTELLIGENT_VOICE_LOGE("invalid reply sbuf object to dispatch"); + return HDF_ERR_INVALID_PARAM; + } + + return hdfIntellVoiceTriggerManagerHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option); +} + +static int HdfIntellVoiceTriggerManagerDriverInit(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver init start"); + return HDF_SUCCESS; +} + +static int HdfIntellVoiceTriggerManagerDriverBind(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver bind start"); + auto *hdfIntellVoiceTriggerManagerHost = new (std::nothrow) HdfIntellVoiceTriggerManagerHost; + if (hdfIntellVoiceTriggerManagerHost == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to create create HdfIntellVoiceTriggerManagerHost object"); + return HDF_FAILURE; + } + + hdfIntellVoiceTriggerManagerHost->ioService.Dispatch = IntellVoiceTriggerManagerDriverDispatch; + hdfIntellVoiceTriggerManagerHost->ioService.Open = NULL; + hdfIntellVoiceTriggerManagerHost->ioService.Release = NULL; + + auto serviceImpl = IIntellVoiceTriggerManager::Get(true); + if (serviceImpl == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to get of implement service"); + delete hdfIntellVoiceTriggerManagerHost; + return HDF_FAILURE; + } + + hdfIntellVoiceTriggerManagerHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl, + IIntellVoiceTriggerManager::GetDescriptor()); + if (hdfIntellVoiceTriggerManagerHost->stub == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to get stub object"); + delete hdfIntellVoiceTriggerManagerHost; + return HDF_FAILURE; + } + + deviceObject->service = &hdfIntellVoiceTriggerManagerHost->ioService; + return HDF_SUCCESS; +} + +static void HdfIntellVoiceTriggerManagerDriverRelease(struct HdfDeviceObject *deviceObject) +{ + INTELLIGENT_VOICE_LOGD("driver release start"); + if (deviceObject->service == nullptr) { + return; + } + + auto *hdfIntellVoiceTriggerManagerHost = CONTAINER_OF(deviceObject->service, + struct HdfIntellVoiceTriggerManagerHost, ioService); + if (hdfIntellVoiceTriggerManagerHost != nullptr) { + delete hdfIntellVoiceTriggerManagerHost; + } +} + +struct HdfDriverEntry g_intellvoicetriggermanagerDriverEntry = { + .moduleVersion = 1, + .moduleName = "intell_voice_trigger_service", + .Bind = HdfIntellVoiceTriggerManagerDriverBind, + .Init = HdfIntellVoiceTriggerManagerDriverInit, + .Release = HdfIntellVoiceTriggerManagerDriverRelease, +}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +HDF_INIT(g_intellvoicetriggermanagerDriverEntry); +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.cpp b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eafdb8dafa27dbb19bfe9b98ac922c4ba56d1c65 --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 "intell_voice_trigger_manager_impl.h" + +#include + +#include "hdf_base.h" +#include "intell_voice_log.h" +#include "intell_voice_trigger_adapter_impl.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "TriggerManagerImpl" + +using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0; + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +extern "C" IIntellVoiceTriggerManager *IntellVoiceTriggerManagerImplGetInstance(void) +{ + return new (std::nothrow) IntellVoiceTriggerManagerImpl(); +} + +int32_t IntellVoiceTriggerManagerImpl::LoadVendorLib() +{ + std::string error; + const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libvendor_intell_voice_trigger"); + triggerManagerPriv_.handle = dlopen(vendorLibPath, RTLD_LAZY); + if (triggerManagerPriv_.handle == nullptr) { + error = dlerror(); + INTELLIGENT_VOICE_LOGE("load path%{public}s, dlopen err=%{public}s", vendorLibPath, error.c_str()); + return -1; + } + + (void)dlerror(); // clear existing error + + triggerManagerPriv_.getTriggerManagerHalInst = reinterpret_cast(dlsym( + triggerManagerPriv_.handle, "GetIntellVoiceTriggerHalInst")); + if (triggerManagerPriv_.getTriggerManagerHalInst == nullptr) { + error = dlerror(); + INTELLIGENT_VOICE_LOGE("dlsym GetIntellVoiceEngineManagerHalInst err=%{public}s", error.c_str()); + dlclose(triggerManagerPriv_.handle); + triggerManagerPriv_.handle = nullptr; + return -1; + } + + INTELLIGENT_VOICE_LOGI("load vendor lib success"); + return 0; +} + +void IntellVoiceTriggerManagerImpl::UnloadVendorLib() +{ + if (triggerManagerPriv_.handle != nullptr) { + dlclose(triggerManagerPriv_.handle); + triggerManagerPriv_.handle = nullptr; + } +} + +IntellVoiceTriggerManagerImpl::IntellVoiceTriggerManagerImpl() +{ + if (LoadVendorLib() == 0) { + inst_ = triggerManagerPriv_.getTriggerManagerHalInst(); + if (inst_ == nullptr) { + INTELLIGENT_VOICE_LOGE("failed to get trigger manager hal inst"); + } + } +} + +IntellVoiceTriggerManagerImpl::~IntellVoiceTriggerManagerImpl() +{ + UnloadVendorLib(); + inst_ = nullptr; + halAdapters_.clear(); +} + +int32_t IntellVoiceTriggerManagerImpl::LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor, + sptr &adapter) +{ + std::lock_guard lock(mutex_); + + if (inst_ == nullptr) { + INTELLIGENT_VOICE_LOGE("inst is nullptr"); + return HDF_FAILURE; + } + + if (halAdapters_.find(descriptor.adapterName) != halAdapters_.end()) { + INTELLIGENT_VOICE_LOGE("adapter %{public}s already exist", descriptor.adapterName.c_str()); + return HDF_ERR_INVALID_OBJECT; + } + + std::unique_ptr triggerAdapterDevice = nullptr; + int32_t ret = inst_->LoadAdapter(descriptor, triggerAdapterDevice); + if (triggerAdapterDevice == nullptr) { + INTELLIGENT_VOICE_LOGE("get adapter device from hal failed, ret:%{public}d", ret); + return HDF_FAILURE; + } + + adapter = sptr(new (std::nothrow) IntellVoiceTriggerAdapterImpl( + std::move(triggerAdapterDevice))); + if (adapter == nullptr) { + INTELLIGENT_VOICE_LOGE("new adapter failed"); + return HDF_ERR_MALLOC_FAIL; + } + + halAdapters_[descriptor.adapterName] = adapter; + return HDF_SUCCESS; +} + +int32_t IntellVoiceTriggerManagerImpl::UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor) +{ + std::lock_guard lock(mutex_); + if (inst_ == nullptr) { + INTELLIGENT_VOICE_LOGE("inst is nullptr"); + return HDF_FAILURE; + } + + auto adapter = halAdapters_.find(descriptor.adapterName); + if (adapter == halAdapters_.end()) { + INTELLIGENT_VOICE_LOGE("there is no %{public}s adapter", descriptor.adapterName.c_str()); + return HDF_ERR_INVALID_OBJECT; + } + + int32_t ret = inst_->UnloadAdapter(descriptor); + adapter->second = nullptr; + halAdapters_.erase(adapter); + return ret; +} +} +} +} \ No newline at end of file diff --git a/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.h b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..549be7fd1c9560bdd4f9be5e872c203bea6fcd98 --- /dev/null +++ b/intelligent_voice/hdi_service/trigger/intell_voice_trigger_manager_impl.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_TRIGGER_MANAGER_IMPL_H +#define HDI_DEVICE_INTELL_VOICE_TRIGGER_MANAGER_IMPL_H + +#include +#include + +#include "v1_0/iintell_voice_trigger_manager.h" +#include "i_trigger.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerAdapterDsecriptor; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerAdapter; + +using GetTriggerManagerHalInstFunc = ITriggerManager *(*)(); + +struct IntellVoiceTriggerManagerPriv { + void *handle { nullptr }; + GetTriggerManagerHalInstFunc getTriggerManagerHalInst { nullptr }; +}; + +class IntellVoiceTriggerManagerImpl : + public OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerManager { +public: + IntellVoiceTriggerManagerImpl(); + ~IntellVoiceTriggerManagerImpl(); + + int32_t LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor, + sptr &adapter) override; + + int32_t UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor) override; + +private: + int32_t LoadVendorLib(); + void UnloadVendorLib(); + +private: + std::mutex mutex_ {}; + IntellVoiceTriggerManagerPriv triggerManagerPriv_; + ITriggerManager *inst_ = nullptr; + std::unordered_map> halAdapters_; +}; +} +} +} +#endif // HDI_DEVICE_INTELL_VOICE_TRIGGER_MANAGER_IMPL_H \ No newline at end of file diff --git a/intelligent_voice/intelligent_voice.gni b/intelligent_voice/intelligent_voice.gni new file mode 100644 index 0000000000000000000000000000000000000000..6aa6b96bd8fc27fb68d6cde6be9156cbc732d696 --- /dev/null +++ b/intelligent_voice/intelligent_voice.gni @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +declare_args() { + drivers_peripheral_intelligent_voice_feature_community = true +} diff --git a/intelligent_voice/interfaces/i_engine.h b/intelligent_voice/interfaces/i_engine.h new file mode 100644 index 0000000000000000000000000000000000000000..6466425b7c787a71bfdf01e92328d2e6785dc61d --- /dev/null +++ b/intelligent_voice/interfaces/i_engine.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 I_ENGINE_H +#define I_ENGINE_H + +#include +#include +#include "v1_0/intell_voice_engine_types.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineCallBackEvent; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineAdapterInfo; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::StartInfo; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::IntellVoiceEngineAdapterDescriptor; +using OHOS::HDI::IntelligentVoice::Engine::V1_0::ContentType; + +using IntellVoiceStatus = int32_t; + +using getParameterCb = std::function; +using getFileDataCb = std::function data, uint32_t size)>; + +class IEngineCallback { +public: + IEngineCallback() = default; + virtual ~IEngineCallback() = default; + virtual void OnIntellVoiceEvent(const IntellVoiceEngineCallBackEvent &event) = 0; +}; + +class IEngine { +public: + IEngine() {}; + virtual ~IEngine() {}; + virtual IntellVoiceStatus SetListener(std::shared_ptr listener) = 0; + virtual IntellVoiceStatus Init(const IntellVoiceEngineAdapterInfo &adapterInfo) = 0; + virtual IntellVoiceStatus Release() = 0; + virtual IntellVoiceStatus SetParameter(const std::string &keyValueList) = 0; + virtual IntellVoiceStatus GetParameter(const std::string &keyList, getParameterCb cb) = 0; + virtual IntellVoiceStatus Write(const uint8_t *buffer, uint32_t size) = 0; + virtual IntellVoiceStatus Start(const StartInfo &info) = 0; + virtual IntellVoiceStatus Stop() = 0; + virtual IntellVoiceStatus Cancel() = 0; + virtual IntellVoiceStatus ReadFileData(ContentType type, getFileDataCb cb) = 0; +}; + +class IEngineManager { +public: + virtual int32_t CreateAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor, + std::unique_ptr &engine) = 0; + virtual int32_t ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor) = 0; +}; +} +} +} +#endif diff --git a/intelligent_voice/interfaces/i_trigger.h b/intelligent_voice/interfaces/i_trigger.h new file mode 100644 index 0000000000000000000000000000000000000000..ba8accb578a95b79cbd79e1179f1b3d089d0ed32 --- /dev/null +++ b/intelligent_voice/interfaces/i_trigger.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 I_TRIGGER_H +#define I_TRIGGER_H +#include +#include +#include "v1_0/intell_voice_trigger_types.h" + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerAdapterDsecriptor; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerProperties; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerModel; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceTriggerModelType; +using OHOS::HDI::IntelligentVoice::Trigger::V1_0::IntellVoiceRecognitionEvent; + +struct TriggerModel { + TriggerModel(IntellVoiceTriggerModelType typeIn, uint32_t uidIn, std::vector dataIn) : type(typeIn), + uid(uidIn) + { + data.swap(dataIn); + } + IntellVoiceTriggerModelType type; + uint32_t uid; + std::vector data; +}; + +class ITriggerCallback { +public: + virtual ~ITriggerCallback() = default; + virtual void OnRecognitionHdiEvent(const IntellVoiceRecognitionEvent &event, int32_t cookie) = 0; +}; + +class ITrigger { +public: + virtual ~ITrigger() {}; + virtual int32_t GetProperties(IntellVoiceTriggerProperties &properties) = 0; + virtual int32_t LoadIntellVoiceTriggerModel(const TriggerModel &model, + const std::shared_ptr &callback, int32_t cookie, int32_t &handle) = 0; + virtual int32_t UnloadIntellVoiceTriggerModel(int32_t handle) = 0; + virtual int32_t Start(int32_t handle) = 0; + virtual int32_t Stop(int32_t handle) = 0; +}; + +class ITriggerManager { +public: + virtual int32_t LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor, + std::unique_ptr &adapter) = 0; + virtual int32_t UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor) = 0; +}; +} +} +} +#endif diff --git a/intelligent_voice/passthrough/BUILD.gn b/intelligent_voice/passthrough/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..63a9496807927d624ea3aa9c026500bc9aaf9cfe --- /dev/null +++ b/intelligent_voice/passthrough/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# 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. + +import("//build/ohos.gni") + +ohos_shared_library("vendor_intell_voice_trigger") { + include_dirs = [ + "../interfaces", + "../utils", + ] + sources = [ "intell_voice_trigger_manager.cpp" ] + + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:intell_voice_trigger_idl_headers", + "hilog:libhilog", + "ipc:ipc_single", + ] + + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} + +ohos_shared_library("vendor_intell_voice_engine") { + include_dirs = [ + "../interfaces", + "../utils", + ] + sources = [ "intell_voice_engine_manager.cpp" ] + + external_deps = [ + "c_utils:utils", + "drivers_interface_intelligent_voice:intell_voice_engine_idl_headers", + "hilog:libhilog", + "ipc:ipc_single", + ] + + install_enable = true + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_intelligent_voice" +} diff --git a/intelligent_voice/passthrough/intell_voice_engine_manager.cpp b/intelligent_voice/passthrough/intell_voice_engine_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..48acafa34ef36818fb411c1e815783bbedb39e12 --- /dev/null +++ b/intelligent_voice/passthrough/intell_voice_engine_manager.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 +#include "hdf_base.h" +#include "i_engine.h" +#include "intell_voice_log.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntellVoiceEngineMgr" + +using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0; + +namespace OHOS { +namespace IntelligentVoice { +namespace Engine { +class IntellVoiceEngineManager final : public IEngineManager { +public: + int32_t CreateAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor, std::unique_ptr &engine) + { + INTELLIGENT_VOICE_LOGD("create adapter stub"); + return 0; + } + + int32_t ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor) + { + INTELLIGENT_VOICE_LOGD("release adapter stub"); + return 0; + } + + static IntellVoiceEngineManager *GetInstance() + { + static IntellVoiceEngineManager manager; + return &manager; + } + +private: + IntellVoiceEngineManager(){}; + ~IntellVoiceEngineManager(){}; +}; +} +} +} + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((visibility("default"))) OHOS::IntelligentVoice::Engine::IEngineManager *GetIntellVoiceEngineManagerHalInst(void) +{ + INTELLIGENT_VOICE_LOGD("enter to engine manager stub"); + return OHOS::IntelligentVoice::Engine::IntellVoiceEngineManager::GetInstance(); +} + +#ifdef __cplusplus +} +#endif diff --git a/intelligent_voice/passthrough/intell_voice_trigger_manager.cpp b/intelligent_voice/passthrough/intell_voice_trigger_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..29df76532ee75e3d1c21f4ebe00403168504cbec --- /dev/null +++ b/intelligent_voice/passthrough/intell_voice_trigger_manager.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 +#include "hdf_base.h" +#include "i_trigger.h" +#include "intell_voice_log.h" + +#undef HDF_LOG_TAG +#define HDF_LOG_TAG "IntellVoiceTriggerMgr" + +using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0; + +namespace OHOS { +namespace IntelligentVoice { +namespace Trigger { +class IntellVoiceTriggerManager final : public ITriggerManager { +public: + int32_t LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor, + std::unique_ptr &adapter) override + { + INTELLIGENT_VOICE_LOGD("load adapter stub"); + return 0; + } + + int32_t UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor) override + { + INTELLIGENT_VOICE_LOGD("unload adapter stub"); + return 0; + } + + static IntellVoiceTriggerManager *GetInstance() + { + static IntellVoiceTriggerManager trigger; + return &trigger; + } +private: + IntellVoiceTriggerManager() {}; + ~IntellVoiceTriggerManager() {}; +}; +} +} +} + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__ ((visibility ("default"))) OHOS::IntelligentVoice::Trigger::ITriggerManager *GetIntellVoiceTriggerHalInst(void) +{ + INTELLIGENT_VOICE_LOGD("enter to intell voice trigger stub"); + return OHOS::IntelligentVoice::Trigger::IntellVoiceTriggerManager::GetInstance(); +} +#ifdef __cplusplus +} +#endif diff --git a/intelligent_voice/utils/intell_voice_log.h b/intelligent_voice/utils/intell_voice_log.h new file mode 100755 index 0000000000000000000000000000000000000000..6bdd6a853075738f7d9293dd746b602d748fb3fc --- /dev/null +++ b/intelligent_voice/utils/intell_voice_log.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_LOG_H +#define HDI_DEVICE_INTELL_VOICE_LOG_H + +#include +#include "hdf_log.h" + +#define INTELLIGENT_VOICE_LOGD(fmt, arg...) \ + do { \ + HDF_LOGD("[%{public}s][line:%{public}d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define INTELLIGENT_VOICE_LOGI(fmt, arg...) \ + do { \ + HDF_LOGI("[%{public}s][line:%{public}d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + + +#define INTELLIGENT_VOICE_LOGW(fmt, arg...) \ + do { \ + HDF_LOGW("[%{public}s][line:%{public}d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#define INTELLIGENT_VOICE_LOGE(fmt, arg...) \ + do { \ + HDF_LOGE("[%{public}s][line:%{public}d]: " fmt, __func__, __LINE__, ##arg); \ + } while (0) + +#endif \ No newline at end of file diff --git a/intelligent_voice/utils/scope_guard.h b/intelligent_voice/utils/scope_guard.h new file mode 100755 index 0000000000000000000000000000000000000000..cc650a367e020ac72b1fa8213898df2cc3c5fae8 --- /dev/null +++ b/intelligent_voice/utils/scope_guard.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 HDI_DEVICE_INTELL_VOICE_SCOPE_GUARD_H +#define HDI_DEVICE_INTELL_VOICE_SCOPE_GUARD_H + +#include + +namespace OHOS { +namespace IntelligentVoice { +namespace Utils { +template +class ScopeGuard { +public: + ScopeGuard(Func &&f) : mFunc(std::forward(f)), mActive(true) + { + } + + ScopeGuard(ScopeGuard &&rhs) : mFunc(std::move(rhs.mFunc)), mActive(rhs.mActive) + { + rhs.Disable(); + } + + ~ScopeGuard() + { + if (mActive) { + mFunc(); + } + } + + void Disable() + { + mActive = false; + } + + bool Active() const + { + return mActive; + } + + void EarlyExit() + { + if (mActive) { + mFunc(); + } + mActive = false; + } +private: + Func mFunc; + bool mActive; + ScopeGuard() = delete; + ScopeGuard(const ScopeGuard &) = delete; + ScopeGuard &operator=(const ScopeGuard &) = delete; + ScopeGuard &operator=(ScopeGuard &&) = delete; +}; + +// tag dispatch +struct ScopeGuardOnExit {}; + +template +inline ScopeGuard operator+(ScopeGuardOnExit, Func &&fn) +{ + return ScopeGuard(std::forward(fn)); +} +} +} +} + +/* + * ScopeGuard ensure the specified function which is created by ON_SCOPE_EXIT is executed no matter how the current + * scope exit. + * when use ON_SCOPE_EXIT macro, the format is: + * ON_SCOPE_EXIT { + * your code + * }; +*/ +#define ON_SCOPE_EXIT \ + auto __onScopeGuardExit__ = OHOS::IntelligentVoice::Utils::ScopeGuardOnExit() + [&]() + +#define CANCEL_SCOPE_EXIT \ + (__onScopeGuardExit__.Disable()) + +#define EARLY_SCOPE_EXIT \ + (__onScopeGuardExit__.EarlyExit()) + +#define ON_SCOPE_EXIT_WITH_NAME(variable_name) \ + auto variable_name = OHOS::IntelligentVoice::Utils::ScopeGuardOnExit() + [&]() + +#endif