1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd. 2023-2023.
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 "update_engine.h"
16 #include <fstream>
17 #include "securec.h"
18 #include "intell_voice_log.h"
19 
20 #include "update_adapter_listener.h"
21 #include "time_util.h"
22 #include "scope_guard.h"
23 #include "trigger_manager.h"
24 #include "adapter_callback_service.h"
25 #include "intell_voice_service_manager.h"
26 #include "update_engine_utils.h"
27 #include "engine_host_manager.h"
28 
29 #define LOG_TAG "UpdateEngine"
30 
31 using namespace OHOS::IntellVoiceTrigger;
32 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
33 using namespace OHOS::IntellVoiceUtils;
34 using namespace OHOS::AudioStandard;
35 
36 namespace OHOS {
37 namespace IntellVoiceEngine {
UpdateEngine()38 UpdateEngine::UpdateEngine()
39 {
40     INTELL_VOICE_LOG_INFO("enter");
41 }
42 
~UpdateEngine()43 UpdateEngine::~UpdateEngine()
44 {
45     INTELL_VOICE_LOG_INFO("enter");
46     callback_ = nullptr;
47 }
48 
OnCommitEnrollComplete(int32_t result)49 void UpdateEngine::OnCommitEnrollComplete(int32_t result)
50 {
51     std::lock_guard<std::mutex> lock(mutex_);
52     INTELL_VOICE_LOG_INFO("commit enroll complete, result %{public}d", result);
53     if (adapter_ == nullptr) {
54         INTELL_VOICE_LOG_INFO("already detach");
55         return;
56     }
57 
58     updateResult_ = (result == 0 ? UpdateState::UPDATE_STATE_COMPLETE_SUCCESS :
59         UpdateState::UPDATE_STATE_COMPLETE_FAIL);
60     if (updateResult_ == UpdateState::UPDATE_STATE_COMPLETE_SUCCESS) {
61         ProcDspModel(OHOS::HDI::IntelligentVoice::Engine::V1_0::DSP_MODLE);
62         /* save new version number */
63         UpdateEngineUtils::SaveWakeupVesion();
64         INTELL_VOICE_LOG_INFO("update save version");
65     }
66 
67     std::thread([=]() {
68         const auto &manager = IntellVoiceServiceManager::GetInstance();
69         if (manager != nullptr) {
70             manager->OnUpdateComplete(updateResult_, param_);
71         }
72     }).detach();
73 }
74 
OnUpdateEvent(int32_t msgId,int32_t result)75 void UpdateEngine::OnUpdateEvent(int32_t msgId, int32_t result)
76 {
77     if (msgId == INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE) {
78         std::thread([this, result]() { this->OnCommitEnrollComplete(result); }).detach();
79     }
80 }
81 
Init(const std::string & param)82 bool UpdateEngine::Init(const std::string &param)
83 {
84     if (!EngineUtil::CreateAdapterInner(EngineHostManager::GetInstance(), UPDATE_ADAPTER_TYPE)) {
85         INTELL_VOICE_LOG_ERROR("failed to create adapter");
86         return false;
87     }
88 
89     SetCallback(nullptr);
90     EngineUtil::SetLanguage();
91     EngineUtil::SetArea();
92     SetDspFeatures();
93 
94     if (!param.empty()) {
95         SetParameter(param);
96     }
97 
98     IntellVoiceEngineInfo info = {
99         .wakeupPhrase = HistoryInfoMgr::GetInstance().GetWakeupPhrase(),
100         .minBufSize = 1280,
101         .sampleChannels = 1,
102         .bitsPerSample = 16,
103         .sampleRate = 16000,
104     };
105     int ret = Attach(info);
106     if (ret != 0) {
107         INTELL_VOICE_LOG_ERROR("attach err");
108         EngineUtil::ReleaseAdapterInner(EngineHostManager::GetInstance());
109         return false;
110     }
111 
112     param_= param;
113     return true;
114 }
115 
SetCallback(sptr<IRemoteObject> object)116 void UpdateEngine::SetCallback(sptr<IRemoteObject> object)
117 {
118     std::lock_guard<std::mutex> lock(mutex_);
119 
120     callback_ = sptr<IIntellVoiceEngineCallback>(new (std::nothrow) UpdateAdapterListener(
121         std::bind(&UpdateEngine::OnUpdateEvent, this, std::placeholders::_1, std::placeholders::_2)));
122     if (callback_ == nullptr) {
123         INTELL_VOICE_LOG_ERROR("callback_ is nullptr");
124         return;
125     }
126 
127     adapter_->SetCallback(callback_);
128 }
129 
Attach(const IntellVoiceEngineInfo & info)130 int32_t UpdateEngine::Attach(const IntellVoiceEngineInfo &info)
131 {
132     std::lock_guard<std::mutex> lock(mutex_);
133     INTELL_VOICE_LOG_INFO("attach");
134     if (adapter_ == nullptr) {
135         INTELL_VOICE_LOG_ERROR("adapter is nullptr");
136         return -1;
137     }
138 
139     IntellVoiceEngineAdapterInfo adapterInfo = {
140         .wakeupPhrase = info.wakeupPhrase,
141         .minBufSize = info.minBufSize,
142         .sampleChannels = info.sampleChannels,
143         .bitsPerSample = info.bitsPerSample,
144         .sampleRate = info.sampleRate,
145     };
146     return adapter_->Attach(adapterInfo);
147 }
148 
Detach(void)149 int32_t UpdateEngine::Detach(void)
150 {
151     INTELL_VOICE_LOG_INFO("enter");
152     std::lock_guard<std::mutex> lock(mutex_);
153     if (adapter_ == nullptr) {
154         INTELL_VOICE_LOG_WARN("already detach");
155         return 0;
156     }
157 
158     int ret =  adapter_->Detach();
159     EngineUtil::ReleaseAdapterInner(EngineHostManager::GetInstance());
160 
161     if (updateResult_ == UpdateState::UPDATE_STATE_DEFAULT) {
162         INTELL_VOICE_LOG_WARN("detach defore receive commit enroll msg");
163         std::string param = param_;
164         std::thread([param]() {
165             const auto &manager = IntellVoiceServiceManager::GetInstance();
166             if (manager != nullptr) {
167                 manager->OnUpdateComplete(UpdateState::UPDATE_STATE_DEFAULT, param);
168             }
169         }).detach();
170     }
171     return ret;
172 }
173 
Start(bool isLast)174 int32_t UpdateEngine::Start(bool isLast)
175 {
176     INTELL_VOICE_LOG_INFO("enter");
177     std::lock_guard<std::mutex> lock(mutex_);
178     return 0;
179 }
180 
Stop()181 int32_t UpdateEngine::Stop()
182 {
183     INTELL_VOICE_LOG_INFO("enter");
184     std::lock_guard<std::mutex> lock(mutex_);
185     return EngineUtil::Stop();
186 }
187 
SetParameter(const std::string & keyValueList)188 int32_t UpdateEngine::SetParameter(const std::string &keyValueList)
189 {
190     INTELL_VOICE_LOG_INFO("enter");
191     std::lock_guard<std::mutex> lock(mutex_);
192     return EngineUtil::SetParameter(keyValueList);
193 }
194 
GetParameter(const std::string & key)195 std::string UpdateEngine::GetParameter(const std::string &key)
196 {
197     INTELL_VOICE_LOG_INFO("enter");
198     std::lock_guard<std::mutex> lock(mutex_);
199     return EngineUtil::GetParameter(key);
200 }
201 }
202 }