1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "intell_voice_trigger_manager_impl.h"
16 
17 #include <dlfcn.h>
18 
19 #include "hdf_base.h"
20 #include "intell_voice_log.h"
21 #include "intell_voice_trigger_adapter_impl.h"
22 
23 #undef HDF_LOG_TAG
24 #define HDF_LOG_TAG "TriggerManagerImpl"
25 
26 using namespace OHOS::HDI::IntelligentVoice::Trigger::V1_0;
27 
28 namespace OHOS {
29 namespace IntelligentVoice {
30 namespace Trigger {
IntellVoiceTriggerManagerImplGetInstance(void)31 extern "C" IIntellVoiceTriggerManager *IntellVoiceTriggerManagerImplGetInstance(void)
32 {
33     return new (std::nothrow) IntellVoiceTriggerManagerImpl();
34 }
35 
IntellVoiceTriggerManagerImplRelease(IIntellVoiceTriggerManager * mgr)36 extern "C" void IntellVoiceTriggerManagerImplRelease(IIntellVoiceTriggerManager *mgr)
37 {
38     INTELLIGENT_VOICE_LOGI("enter");
39     if (mgr == nullptr) {
40         INTELLIGENT_VOICE_LOGE("mgr is nullptr");
41         return;
42     }
43     delete mgr;
44 }
45 
LoadVendorLib()46 int32_t IntellVoiceTriggerManagerImpl::LoadVendorLib()
47 {
48     std::string error;
49     const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libvendor_intell_voice_trigger");
50     triggerManagerPriv_.handle = dlopen(vendorLibPath, RTLD_LAZY);
51     if (triggerManagerPriv_.handle == nullptr) {
52         error = dlerror();
53         INTELLIGENT_VOICE_LOGE("load path%{public}s, dlopen err=%{public}s", vendorLibPath, error.c_str());
54         return HDF_FAILURE;
55     }
56 
57     (void)dlerror(); // clear existing error
58 
59     triggerManagerPriv_.getTriggerManagerHalInst = reinterpret_cast<GetTriggerManagerHalInstFunc>(dlsym(
60         triggerManagerPriv_.handle, "GetIntellVoiceTriggerHalInst"));
61     if (triggerManagerPriv_.getTriggerManagerHalInst == nullptr) {
62         error = dlerror();
63         INTELLIGENT_VOICE_LOGE("dlsym GetIntellVoiceEngineManagerHalInst err=%{public}s", error.c_str());
64         dlclose(triggerManagerPriv_.handle);
65         triggerManagerPriv_.handle = nullptr;
66         return HDF_FAILURE;
67     }
68 
69     INTELLIGENT_VOICE_LOGI("load vendor lib success");
70     return HDF_SUCCESS;
71 }
72 
UnloadVendorLib()73 void IntellVoiceTriggerManagerImpl::UnloadVendorLib()
74 {
75     if (triggerManagerPriv_.handle != nullptr) {
76         dlclose(triggerManagerPriv_.handle);
77         triggerManagerPriv_.handle = nullptr;
78     }
79 }
80 
IntellVoiceTriggerManagerImpl()81 IntellVoiceTriggerManagerImpl::IntellVoiceTriggerManagerImpl()
82 {
83     if (LoadVendorLib() == static_cast<int32_t>(HDF_SUCCESS)) {
84         inst_ = triggerManagerPriv_.getTriggerManagerHalInst();
85         if (inst_ == nullptr) {
86             INTELLIGENT_VOICE_LOGE("failed to get trigger manager hal inst");
87         }
88     }
89 }
90 
~IntellVoiceTriggerManagerImpl()91 IntellVoiceTriggerManagerImpl::~IntellVoiceTriggerManagerImpl()
92 {
93     UnloadVendorLib();
94     inst_ = nullptr;
95     halAdapters_.clear();
96 }
97 
LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor & descriptor,sptr<OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerAdapter> & adapter)98 int32_t IntellVoiceTriggerManagerImpl::LoadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor,
99     sptr<OHOS::HDI::IntelligentVoice::Trigger::V1_0::IIntellVoiceTriggerAdapter> &adapter)
100 {
101     return LoadIntellVoiceTriggerAdapter(descriptor, adapter);
102 }
103 
LoadAdapter_V1_1(const IntellVoiceTriggerAdapterDsecriptor & descriptor,sptr<OHOS::HDI::IntelligentVoice::Trigger::V1_1::IIntellVoiceTriggerAdapter> & adapter)104 int32_t IntellVoiceTriggerManagerImpl::LoadAdapter_V1_1(const IntellVoiceTriggerAdapterDsecriptor &descriptor,
105     sptr<OHOS::HDI::IntelligentVoice::Trigger::V1_1::IIntellVoiceTriggerAdapter> &adapter)
106 {
107     return LoadIntellVoiceTriggerAdapter(descriptor, adapter);
108 }
109 
110 template<typename T>
LoadIntellVoiceTriggerAdapter(const IntellVoiceTriggerAdapterDsecriptor & descriptor,sptr<T> & adapter)111 int32_t IntellVoiceTriggerManagerImpl::LoadIntellVoiceTriggerAdapter(
112     const IntellVoiceTriggerAdapterDsecriptor &descriptor, sptr<T> &adapter)
113 {
114     std::lock_guard<std::mutex> lock(mutex_);
115     if (inst_ == nullptr) {
116         INTELLIGENT_VOICE_LOGE("inst is nullptr");
117         return HDF_FAILURE;
118     }
119 
120     auto it = halAdapters_.find(descriptor.adapterName);
121     if (it != halAdapters_.end()) {
122         INTELLIGENT_VOICE_LOGW("adapter %{public}s already exist", descriptor.adapterName.c_str());
123         inst_->UnloadAdapter(descriptor);
124         it->second = nullptr;
125         halAdapters_.erase(it);
126     }
127 
128     std::unique_ptr<ITrigger> triggerAdapterDevice = nullptr;
129     int32_t ret = inst_->LoadAdapter(descriptor, triggerAdapterDevice);
130     if (triggerAdapterDevice == nullptr) {
131         INTELLIGENT_VOICE_LOGE("get adapter device from hal failed, ret:%{public}d", ret);
132         return HDF_FAILURE;
133     }
134 
135     adapter = sptr<T>(new (std::nothrow) IntellVoiceTriggerAdapterImpl(std::move(triggerAdapterDevice)));
136     if (adapter == nullptr) {
137         INTELLIGENT_VOICE_LOGE("new adapter failed");
138         return HDF_ERR_MALLOC_FAIL;
139     }
140 
141     halAdapters_[descriptor.adapterName] = adapter;
142     return HDF_SUCCESS;
143 }
144 
UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor & descriptor)145 int32_t IntellVoiceTriggerManagerImpl::UnloadAdapter(const IntellVoiceTriggerAdapterDsecriptor &descriptor)
146 {
147     std::lock_guard<std::mutex> lock(mutex_);
148     if (inst_ == nullptr) {
149         INTELLIGENT_VOICE_LOGE("inst is nullptr");
150         return HDF_FAILURE;
151     }
152 
153     auto adapter = halAdapters_.find(descriptor.adapterName);
154     if (adapter == halAdapters_.end()) {
155         INTELLIGENT_VOICE_LOGE("there is no %{public}s adapter", descriptor.adapterName.c_str());
156         return HDF_ERR_INVALID_OBJECT;
157     }
158 
159     int32_t ret = inst_->UnloadAdapter(descriptor);
160     adapter->second = nullptr;
161     halAdapters_.erase(adapter);
162     return ret;
163 }
164 }
165 }
166 }