1 /*
2 * Copyright (c) 2025 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 "only_first_engine_manager.h"
16
17 #include <vector>
18 #include <fstream>
19 #include <cstdio>
20 #include "intell_voice_log.h"
21 #include "intell_voice_util.h"
22 #include "string_util.h"
23 #include "iservice_registry.h"
24 #include "intell_voice_generic_factory.h"
25 #include "memory_guard.h"
26 #include "engine_callback_message.h"
27 #include "intell_voice_definitions.h"
28 #include "only_first_wakeup_engine_obj.h"
29
30 #define LOG_TAG "OnlyFirstEngineManager"
31
32 using namespace OHOS::IntellVoiceUtils;
33
34 namespace OHOS {
35 namespace IntellVoiceEngine {
36
OnlyFirstEngineManager()37 OnlyFirstEngineManager::OnlyFirstEngineManager()
38 {
39 }
40
~OnlyFirstEngineManager()41 OnlyFirstEngineManager::~OnlyFirstEngineManager()
42 {
43 }
44
IsEngineExist(IntellVoiceEngineType type)45 bool OnlyFirstEngineManager::IsEngineExist(IntellVoiceEngineType type)
46 {
47 if (type == INTELL_VOICE_WAKEUP) {
48 if (wakeupEngine_ != nullptr) {
49 return true;
50 }
51 }
52
53 return false;
54 }
55
AnyEngineExist(const std::vector<IntellVoiceEngineType> & types)56 bool OnlyFirstEngineManager::AnyEngineExist(const std::vector<IntellVoiceEngineType>& types)
57 {
58 for (const auto &type : types) {
59 if (IsEngineExist(type)) {
60 return true;
61 }
62 }
63
64 return false;
65 }
66
RegisterProxyDeathRecipient(IntellVoiceEngineType type,const sptr<IRemoteObject> & object)67 bool OnlyFirstEngineManager::RegisterProxyDeathRecipient(IntellVoiceEngineType type, const sptr<IRemoteObject> &object)
68 {
69 std::lock_guard<std::mutex> lock(deathMutex_);
70 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
71
72 if (type != INTELL_VOICE_WAKEUP) {
73 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
74 return false;
75 }
76
77 if (proxyDeathRecipient_ != nullptr) {
78 INTELL_VOICE_LOG_ERROR("death recipient is not nullptr, type:%{public}d", type);
79 return false;
80 }
81 deathRecipientObj_ = object;
82 proxyDeathRecipient_ = new (std::nothrow) IntellVoiceDeathRecipient([&]() {
83 INTELL_VOICE_LOG_INFO("receive wakeup proxy death recipient, clear wakeup engine callback");
84 EngineCallbackMessage::CallFunc(HANDLE_CLEAR_WAKEUP_ENGINE_CB);
85 });
86 if (proxyDeathRecipient_ == nullptr) {
87 INTELL_VOICE_LOG_ERROR("create death recipient failed");
88 return false;
89 }
90
91 return deathRecipientObj_->AddDeathRecipient(proxyDeathRecipient_);
92 }
93
DeregisterProxyDeathRecipient(IntellVoiceEngineType type)94 bool OnlyFirstEngineManager::DeregisterProxyDeathRecipient(IntellVoiceEngineType type)
95 {
96 std::lock_guard<std::mutex> lock(deathMutex_);
97 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
98 if (type != INTELL_VOICE_WAKEUP) {
99 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
100 return false;
101 }
102
103 if (deathRecipientObj_ == nullptr) {
104 INTELL_VOICE_LOG_ERROR("death obj is nullptr, type:%{public}d", type);
105 return false;
106 }
107
108 if (proxyDeathRecipient_ == nullptr) {
109 INTELL_VOICE_LOG_ERROR("death recipient is nullptr, type:%{public}d", type);
110 deathRecipientObj_ = nullptr;
111 return false;
112 }
113
114 auto ret = deathRecipientObj_->RemoveDeathRecipient(proxyDeathRecipient_);
115 deathRecipientObj_ = nullptr;
116 proxyDeathRecipient_ = nullptr;
117
118 return ret;
119 }
120
SetParameter(const std::string & keyValueList)121 int32_t OnlyFirstEngineManager::SetParameter(const std::string &keyValueList)
122 {
123 if (wakeupEngine_ != nullptr) {
124 wakeupEngine_->SetParameter(keyValueList);
125 }
126
127 return 0;
128 }
129
GetParameter(const std::string & key)130 std::string OnlyFirstEngineManager::GetParameter(const std::string &key)
131 {
132 std::string val = "";
133
134 if (wakeupEngine_ != nullptr) {
135 val = wakeupEngine_->GetParameter(key);
136 }
137
138 return val;
139 }
140
EngineOnDetected(int32_t uuid)141 void OnlyFirstEngineManager::EngineOnDetected(int32_t uuid)
142 {
143 if (wakeupEngine_ != nullptr) {
144 INTELL_VOICE_LOG_INFO("on engine detected, uuid:%{public}d", uuid);
145 wakeupEngine_->OnDetected(uuid);
146 }
147 }
148
CreateEngineInner(IntellVoiceEngineType type)149 sptr<IIntellVoiceEngine> OnlyFirstEngineManager::CreateEngineInner(IntellVoiceEngineType type)
150 {
151 INTELL_VOICE_LOG_INFO("create engine enter, type: %{public}d", type);
152 OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
153 if (wakeupEngine_ != nullptr) {
154 return wakeupEngine_;
155 }
156
157 wakeupEngine_ = SptrFactory<EngineBase, OnlyFirstWakeupEngineObj>::CreateInstance();
158 if (wakeupEngine_ == nullptr) {
159 INTELL_VOICE_LOG_ERROR("create engine failed, type:%{public}d", type);
160 return nullptr;
161 }
162
163 INTELL_VOICE_LOG_INFO("create engine ok");
164 return wakeupEngine_;
165 }
166
CreateEngine(IntellVoiceEngineType type,const std::string & param)167 sptr<IIntellVoiceEngine> OnlyFirstEngineManager::CreateEngine(IntellVoiceEngineType type, const std::string ¶m)
168 {
169 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
170 if (type != INTELL_VOICE_WAKEUP) {
171 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
172 return nullptr;
173 }
174
175 return CreateEngineInner(type);
176 }
177
CreateOrResetWakeupEngine()178 bool OnlyFirstEngineManager::CreateOrResetWakeupEngine()
179 {
180 if (wakeupEngine_ != nullptr) {
181 INTELL_VOICE_LOG_INFO("wakeup engine is existed");
182 wakeupEngine_->ReleaseAdapter();
183 if (!wakeupEngine_->ResetAdapter()) {
184 INTELL_VOICE_LOG_ERROR("failed to reset adapter");
185 return false;
186 }
187 } else {
188 if (CreateEngineInner(INTELL_VOICE_WAKEUP) == nullptr) {
189 INTELL_VOICE_LOG_ERROR("failed to create wakeup engine");
190 return false;
191 }
192 }
193 return true;
194 }
195
ReleaseEngineInner(IntellVoiceEngineType type)196 int32_t OnlyFirstEngineManager::ReleaseEngineInner(IntellVoiceEngineType type)
197 {
198 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
199 if (type != INTELL_VOICE_WAKEUP) {
200 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
201 return 0;
202 }
203
204 //hap only releases Napi, and does not release sa resources
205 OHOS::IntellVoiceUtils::MemoryGuard memoryGuard;
206 if (wakeupEngine_ != nullptr) {
207 wakeupEngine_->Detach();
208 wakeupEngine_ = nullptr;
209 }
210
211 return 0;
212 }
213
ServiceStopProc()214 int32_t OnlyFirstEngineManager::ServiceStopProc()
215 {
216 INTELL_VOICE_LOG_INFO("enter");
217 if (wakeupEngine_ != nullptr) {
218 INTELL_VOICE_LOG_INFO("clear wakeup engine callback");
219 wakeupEngine_->Detach();
220 }
221
222 return 0;
223 }
224 } // namespace IntellVoiceEngine
225 } // namespace OHOS
226