1 /*
2 * Copyright (c) 2021-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
16 #include "component_manager.h"
17
18 #include <cinttypes>
19 #include <future>
20 #include <pthread.h>
21 #include <string>
22 #include <thread>
23
24 #include "ipc_object_stub.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27
28 #include "anonymous_string.h"
29 #include "capability_info_manager.h"
30 #include "component_disable.h"
31 #include "component_enable.h"
32 #include "component_loader.h"
33 #include "constants.h"
34 #include "device_manager.h"
35 #include "dh_context.h"
36 #include "dh_utils_hitrace.h"
37 #include "dh_utils_hisysevent.h"
38 #include "dh_utils_tool.h"
39 #include "distributed_hardware_errno.h"
40 #include "distributed_hardware_log.h"
41 #include "enabled_comps_dump.h"
42 #include "low_latency.h"
43 #include "publisher.h"
44 #include "task_executor.h"
45 #include "task_factory.h"
46 #include "version_info_manager.h"
47 #include "version_manager.h"
48
49 namespace OHOS {
50 namespace DistributedHardware {
51 #undef DH_LOG_TAG
52 #define DH_LOG_TAG "ComponentManager"
53
54 IMPLEMENT_SINGLE_INSTANCE(ComponentManager);
55
56 namespace {
57 constexpr int32_t ENABLE_RETRY_MAX_TIMES = 3;
58 constexpr int32_t DISABLE_RETRY_MAX_TIMES = 3;
59 constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000;
60 constexpr int32_t INVALID_SA_ID = -1;
61 constexpr int32_t MONITOR_TASK_DELAY_MS = 5 * 1000;
62 constexpr int32_t UNINIT_COMPONENT_TIMEOUT_SECONDS = 2;
63 const std::string MONITOR_TASK_TIMER_ID = "monitor_task_timer_id";
64 }
65
ComponentManager()66 ComponentManager::ComponentManager() : compSource_({}), compSink_({}), compSrcSaId_({}),
67 compMonitorPtr_(std::make_shared<ComponentMonitor>()), lowLatencyListener_(new(std::nothrow) LowLatencyListener),
68 monitorTaskTimer_(std::make_shared<MonitorTaskTimer>(MONITOR_TASK_TIMER_ID, MONITOR_TASK_DELAY_MS)),
69 isUnInitTimeOut_(false)
70 {
71 DHLOGI("Ctor ComponentManager");
72 }
73
~ComponentManager()74 ComponentManager::~ComponentManager()
75 {
76 DHLOGD("Dtor ComponentManager");
77 compMonitorPtr_.reset();
78 compMonitorPtr_ = nullptr;
79 lowLatencyListener_ = nullptr;
80 }
81
Init()82 int32_t ComponentManager::Init()
83 {
84 DHLOGI("start.");
85 DHTraceStart(COMPONENT_INIT_START);
86 if (!InitCompSource()) {
87 DHLOGE("InitCompSource failed.");
88 DHTraceEnd();
89 return ERR_DH_FWK_COMPONENT_INIT_SOURCE_FAILED;
90 }
91 if (!InitCompSink()) {
92 DHLOGE("InitCompSink failed.");
93 compSource_.clear();
94 DHTraceEnd();
95 return ERR_DH_FWK_COMPONENT_INIT_SINK_FAILED;
96 }
97
98 if (compMonitorPtr_ == nullptr) {
99 DHLOGE("compMonitorPtr_ is null.");
100 return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
101 }
102 for (const auto &comp : compSource_) {
103 if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
104 continue;
105 }
106 compMonitorPtr_->AddSAMonitor(compSrcSaId_.at(comp.first));
107 }
108
109 auto sourceResult = StartSource();
110 auto sinkResult = StartSink();
111
112 if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
113 DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue");
114 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
115 "dhfwk start source failed.");
116 }
117 if (!WaitForResult(Action::START_SINK, sinkResult)) {
118 DHLOGE("StartSink failed, some virtual components maybe cannot work, but want to continue");
119 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
120 "dhfwk start sink failed.");
121 }
122 if (monitorTaskTimer_ != nullptr) {
123 monitorTaskTimer_->StartTimer();
124 }
125 #ifdef DHARDWARE_LOW_LATENCY
126 Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
127 #endif
128 DHLOGI("Init component success");
129 DHTraceEnd();
130 return DH_FWK_SUCCESS;
131 }
132
UnInit()133 int32_t ComponentManager::UnInit()
134 {
135 DHLOGI("start.");
136 if (compMonitorPtr_ == nullptr) {
137 DHLOGE("compMonitorPtr_ is null.");
138 return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
139 }
140 for (const auto &comp : compSource_) {
141 if (compSrcSaId_.find(comp.first) == compSrcSaId_.end()) {
142 continue;
143 }
144 compMonitorPtr_->RemoveSAMonitor(compSrcSaId_.at(comp.first));
145 }
146 auto sourceResult = StopSource();
147 auto sinkResult = StopSink();
148
149 if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
150 DHLOGE("StopSource failed, but want to continue");
151 }
152 if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
153 DHLOGE("StopSource failed, but want to continue");
154 }
155
156 compSource_.clear();
157 compSink_.clear();
158
159 if (monitorTaskTimer_ != nullptr) {
160 monitorTaskTimer_->StopTimer();
161 }
162 #ifdef DHARDWARE_LOW_LATENCY
163 Publisher::GetInstance().UnregisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
164 LowLatency::GetInstance().CloseLowLatency();
165 #endif
166 DHLOGI("Release component success");
167
168 if (isUnInitTimeOut_.load()) {
169 DHLOGE("Some component stop timeout, FORCE exit!");
170 _Exit(0);
171 }
172
173 return DH_FWK_SUCCESS;
174 }
175
StartSource()176 ActionResult ComponentManager::StartSource()
177 {
178 DHLOGI("start.");
179 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
180 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
181 for (const auto &item : compSource_) {
182 CompVersion compversion;
183 VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
184 auto params = compversion.sourceVersion;
185 auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSource(params); });
186 futures.emplace(item.first, future.share());
187 }
188 return futures;
189 }
190
StartSource(DHType dhType)191 ActionResult ComponentManager::StartSource(DHType dhType)
192 {
193 DHLOGI("Start Source, dhType: %" PRIu32, (uint32_t)dhType);
194 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
195 if (compSource_.find(dhType) == compSource_.end()) {
196 DHLOGE("Component for DHType: %" PRIu32 " not init source handler", (uint32_t)dhType);
197 return futures;
198 }
199
200 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
201 CompVersion compVersion;
202 VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
203 auto params = compVersion.sourceVersion;
204 auto future = std::async(std::launch::async, [this, dhType, params]() {
205 return compSource_[dhType]->InitSource(params);
206 });
207 futures.emplace(dhType, future.share());
208
209 return futures;
210 }
211
StartSink()212 ActionResult ComponentManager::StartSink()
213 {
214 DHLOGI("start.");
215 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
216 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
217 for (const auto &item : compSink_) {
218 CompVersion compversion;
219 VersionManager::GetInstance().GetCompVersion(uuid, item.first, compversion);
220 auto params = compversion.sinkVersion;
221 auto future = std::async(std::launch::async, [item, params]() { return item.second->InitSink(params); });
222 futures.emplace(item.first, future.share());
223 if (cameraCompPrivacy_ == nullptr && item.first == DHType::CAMERA) {
224 cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
225 item.second->RegisterPrivacyResources(cameraCompPrivacy_);
226 }
227 if (audioCompPrivacy_ == nullptr && item.first == DHType::AUDIO) {
228 audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
229 item.second->RegisterPrivacyResources(audioCompPrivacy_);
230 }
231 }
232 return futures;
233 }
234
StartSink(DHType dhType)235 ActionResult ComponentManager::StartSink(DHType dhType)
236 {
237 DHLOGI("Start Sink, dhType: %" PRIu32, (uint32_t)dhType);
238 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
239 if (compSink_.find(dhType) == compSink_.end()) {
240 DHLOGE("Component for DHType: %" PRIu32 " not init sink handler", (uint32_t)dhType);
241 return futures;
242 }
243
244 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
245 CompVersion compVersion;
246 VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
247 auto params = compVersion.sinkVersion;
248 auto future = std::async(std::launch::async, [this, dhType, params]() {
249 return compSink_[dhType]->InitSink(params);
250 });
251 futures.emplace(dhType, future.share());
252 if (cameraCompPrivacy_ == nullptr && dhType == DHType::CAMERA) {
253 cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
254 compSink_[dhType]->RegisterPrivacyResources(cameraCompPrivacy_);
255 }
256 if (audioCompPrivacy_ == nullptr && dhType == DHType::AUDIO) {
257 audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
258 compSink_[dhType]->RegisterPrivacyResources(audioCompPrivacy_);
259 }
260
261 return futures;
262 }
263
StopSource()264 ActionResult ComponentManager::StopSource()
265 {
266 DHLOGI("start.");
267 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
268 for (const auto &item : compSource_) {
269 auto future = std::async(std::launch::async, [item]() { return item.second->ReleaseSource(); });
270 futures.emplace(item.first, future.share());
271 }
272 return futures;
273 }
274
StopSink()275 ActionResult ComponentManager::StopSink()
276 {
277 DHLOGI("start.");
278 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
279 for (const auto &item : compSink_) {
280 auto future = std::async(std::launch::async, [item]() {
281 int32_t status = item.second->ReleaseSink();
282 IHardwareHandler *hardwareHandler = nullptr;
283 status = ComponentLoader::GetInstance().GetHardwareHandler(item.first, hardwareHandler);
284 if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) {
285 DHLOGE("GetHardwareHandler %#X failed", item.first);
286 return status;
287 }
288 hardwareHandler->UnRegisterPluginListener();
289 return status;
290 });
291
292 futures.emplace(item.first, future.share());
293 }
294 return futures;
295 }
296
WaitForResult(const Action & action,ActionResult actionsResult)297 bool ComponentManager::WaitForResult(const Action &action, ActionResult actionsResult)
298 {
299 DHLOGD("start.");
300 auto ret = true;
301 for (auto &iter : actionsResult) {
302 std::future_status status = iter.second.wait_for(std::chrono::seconds(UNINIT_COMPONENT_TIMEOUT_SECONDS));
303 if (status == std::future_status::ready) {
304 auto result = iter.second.get();
305 DHLOGI("action = %d, compType = %#X, READY, ret = %d.", static_cast<int32_t>(action), iter.first, result);
306 if (result != DH_FWK_SUCCESS) {
307 ret = false;
308 DHLOGE("there is error, but want to continue.");
309 }
310 }
311
312 if (status == std::future_status::timeout) {
313 DHLOGI("action = %d, compType = %#X, TIMEOUT", static_cast<int32_t>(action), iter.first);
314 if (action == Action::STOP_SOURCE || action == Action::STOP_SINK) {
315 isUnInitTimeOut_ = true;
316 }
317 }
318
319 if (status == std::future_status::deferred) {
320 DHLOGI("action = %d, compType = %#X, DEFERRED", static_cast<int32_t>(action), iter.first);
321 }
322 }
323 DHLOGD("end.");
324 return ret;
325 }
326
InitCompSource()327 bool ComponentManager::InitCompSource()
328 {
329 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
330 for (const auto &type : compTypes) {
331 IDistributedHardwareSource *sourcePtr = nullptr;
332 auto ret = ComponentLoader::GetInstance().GetSource(type, sourcePtr);
333 if (ret != DH_FWK_SUCCESS) {
334 DHLOGW("GetSource failed, compType = %#X, ret = %d.", type, ret);
335 continue;
336 }
337 if (sourcePtr == nullptr) {
338 DHLOGW("sourcePtr is null, compType = %#X.", type);
339 continue;
340 }
341 compSource_.insert(std::make_pair(type, sourcePtr));
342
343 int32_t saId = ComponentLoader::GetInstance().GetSourceSaId(type);
344 if (saId != INVALID_SA_ID) {
345 compSrcSaId_.insert(std::make_pair(type, saId));
346 }
347 }
348 return !compSource_.empty();
349 }
350
InitCompSink()351 bool ComponentManager::InitCompSink()
352 {
353 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
354 for (const auto &type : compTypes) {
355 IDistributedHardwareSink *sinkPtr = nullptr;
356 auto ret = ComponentLoader::GetInstance().GetSink(type, sinkPtr);
357 if (ret != DH_FWK_SUCCESS) {
358 DHLOGW("GetSink failed, compType = %#X, ret = %d.", type, ret);
359 continue;
360 }
361 if (sinkPtr == nullptr) {
362 DHLOGW("sinkPtr is null, compType = %#X.", type);
363 continue;
364 }
365 compSink_.insert(std::make_pair(type, sinkPtr));
366 }
367 return !compSink_.empty();
368 }
369
Enable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)370 int32_t ComponentManager::Enable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
371 const DHType dhType)
372 {
373 DHLOGI("start.");
374 auto find = compSource_.find(dhType);
375 if (find == compSource_.end()) {
376 DHLOGE("can not find handler for dhId = %s.", GetAnonyString(dhId).c_str());
377 return ERR_DH_FWK_PARA_INVALID;
378 }
379 EnableParam param;
380 auto ret = GetEnableParam(networkId, uuid, dhId, dhType, param);
381 if (ret != DH_FWK_SUCCESS) {
382 DHLOGE("GetEnableParam failed, uuid = %s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
383 GetAnonyString(dhId).c_str(), ret);
384 if (RetryGetEnableParam(networkId, uuid, dhId, dhType, param) != DH_FWK_SUCCESS) {
385 return ret;
386 }
387 }
388 std::string subtype = param.subtype;
389 std::map<std::string, bool> resourceDesc = ComponentLoader::GetInstance().GetCompResourceDesc();
390 if (resourceDesc.find(subtype) == resourceDesc.end()) {
391 DHLOGE("GetCompResourceDesc failed.");
392 return ERR_DH_FWK_RESOURCE_KEY_IS_EMPTY;
393 }
394 bool sensitiveVal = resourceDesc[subtype];
395 bool isSameAuthForm = IsIdenticalAccount(networkId);
396 if (sensitiveVal && !isSameAuthForm) {
397 DHLOGE("Privacy resources must be logged in with the same account.");
398 return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
399 }
400
401 auto compEnable = std::make_shared<ComponentEnable>();
402 auto result = compEnable->Enable(networkId, dhId, param, find->second);
403 if (result != DH_FWK_SUCCESS) {
404 for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
405 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
406 DHLOGE("device is already offline, no need try enable, uuid = %s", GetAnonyString(uuid).c_str());
407 return result;
408 }
409 if (compEnable->Enable(networkId, dhId, param, find->second) == DH_FWK_SUCCESS) {
410 DHLOGE("enable success, retryCount = %d", retryCount);
411 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
412 return DH_FWK_SUCCESS;
413 }
414 DHLOGE("enable failed, retryCount = %d", retryCount);
415 }
416 return result;
417 }
418 DHLOGI("enable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
419 GetAnonyString(dhId).c_str());
420 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
421
422 return result;
423 }
424
RetryGetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,EnableParam & param)425 int32_t ComponentManager::RetryGetEnableParam(const std::string &networkId, const std::string &uuid,
426 const std::string &dhId, const DHType dhType, EnableParam ¶m)
427 {
428 for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
429 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
430 DHLOGE("device is already offline, no need try GetEnableParam, uuid = %s",
431 GetAnonyString(uuid).c_str());
432 return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
433 }
434 if (GetEnableParam(networkId, uuid, dhId, dhType, param) == DH_FWK_SUCCESS) {
435 DHLOGE("GetEnableParam success, retryCount = %d", retryCount);
436 break;
437 }
438 DHLOGE("GetEnableParam failed, retryCount = %d", retryCount);
439 usleep(ENABLE_PARAM_RETRY_TIME);
440 }
441 return DH_FWK_SUCCESS;
442 }
443
Disable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)444 int32_t ComponentManager::Disable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
445 const DHType dhType)
446 {
447 auto find = compSource_.find(dhType);
448 if (find == compSource_.end()) {
449 DHLOGE("can not find handler for dhId = %s.", dhId.c_str());
450 return ERR_DH_FWK_PARA_INVALID;
451 }
452
453 auto compDisable = std::make_shared<ComponentDisable>();
454 auto result = compDisable->Disable(networkId, dhId, find->second);
455 if (result != DH_FWK_SUCCESS) {
456 for (int32_t retryCount = 0; retryCount < DISABLE_RETRY_MAX_TIMES; retryCount++) {
457 if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
458 DHLOGE("device is already online, no need try disable, uuid = %s", GetAnonyString(uuid).c_str());
459 return result;
460 }
461 if (compDisable->Disable(networkId, dhId, find->second) == DH_FWK_SUCCESS) {
462 DHLOGE("disable success, retryCount = %d", retryCount);
463 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
464 return DH_FWK_SUCCESS;
465 }
466 DHLOGE("disable failed, retryCount = %d", retryCount);
467 }
468 return result;
469 }
470 DHLOGI("disable result is %d, uuid = %s, dhId = %s", result, GetAnonyString(uuid).c_str(),
471 GetAnonyString(dhId).c_str());
472 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
473
474 return result;
475 }
476
GetDHType(const std::string & uuid,const std::string & dhId) const477 DHType ComponentManager::GetDHType(const std::string &uuid, const std::string &dhId) const
478 {
479 std::shared_ptr<CapabilityInfo> capability = nullptr;
480 auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
481 if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
482 return capability->GetDHType();
483 }
484 DHLOGE("get dhType failed, uuid = %s, dhId = %s", GetAnonyString(uuid).c_str(),
485 GetAnonyString(dhId).c_str());
486 return DHType::UNKNOWN;
487 }
488
GetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,DHType dhType,EnableParam & param)489 int32_t ComponentManager::GetEnableParam(const std::string &networkId, const std::string &uuid,
490 const std::string &dhId, DHType dhType, EnableParam ¶m)
491 {
492 std::shared_ptr<CapabilityInfo> capability = nullptr;
493 auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
494 if ((ret != DH_FWK_SUCCESS) || (capability == nullptr)) {
495 DHLOGE("GetCapability failed, uuid =%s, dhId = %s, errCode = %d", GetAnonyString(uuid).c_str(),
496 GetAnonyString(dhId).c_str(), ret);
497 return ret;
498 }
499 DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
500 std::string sourceNetworkId = DHContext::GetInstance().GetNetworkIdByUUID(sourceDeviceInfo.uuid);
501 std::vector<std::shared_ptr<CapabilityInfo>> sourceCapInfos;
502 std::string sourceDHId;
503 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(sourceDeviceInfo.deviceId, sourceCapInfos);
504 for (const auto &capInfo : sourceCapInfos) {
505 if (dhType == capInfo->GetDHType()) {
506 param.sourceAttrs = capInfo->GetDHAttrs();
507 sourceDHId = capInfo->GetDHId();
508 }
509 }
510 std::string sourceVersion("");
511 ret = GetVersion(sourceNetworkId, sourceDeviceInfo.uuid, dhType, sourceVersion, false);
512 if (ret != DH_FWK_SUCCESS) {
513 DHLOGE("Get source version failed, uuid = %s, dhId = %s, dhType = %#X,",
514 GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(), dhType);
515 return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
516 }
517 param.sourceVersion = sourceVersion;
518 param.sinkAttrs = capability->GetDHAttrs();
519 std::string sinkVersion("");
520 ret = GetVersion(networkId, uuid, dhType, sinkVersion, true);
521 if (ret != DH_FWK_SUCCESS) {
522 DHLOGE("Get sink version failed, uuid = %s, dhId = %s, dhType = %#X,", GetAnonyString(uuid).c_str(),
523 GetAnonyString(dhId).c_str(), dhType);
524 return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
525 }
526 param.sinkVersion = sinkVersion;
527 param.subtype = capability->GetDHSubtype();
528 DHLOGI("success. dhType = %#X, sink uuid =%s, sink dhId = %s, sinVersion = %s, source uuid =%s, source dhId = %s, "
529 "sourceVersion = %s, subtype = %s", dhType, GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(),
530 param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(),
531 GetAnonyString(sourceDHId).c_str(), param.sourceVersion.c_str(), param.subtype.c_str());
532
533 return DH_FWK_SUCCESS;
534 }
535
GetVersionFromVerMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)536 int32_t ComponentManager::GetVersionFromVerMgr(const std::string &uuid, const DHType dhType,
537 std::string &version, bool isSink)
538 {
539 CompVersion compversion;
540 int32_t ret = VersionManager::GetInstance().GetCompVersion(uuid, dhType, compversion);
541 if (ret != DH_FWK_SUCCESS) {
542 DHLOGE("Get version Manager failed, uuid =%s, dhType = %#X, errCode = %d",
543 GetAnonyString(uuid).c_str(), dhType, ret);
544 return ret;
545 }
546 DHLOGI("Get version mgr success, sinkVersion = %s, sourceVersion = %s,uuid = %s, dhType = %#X",
547 compversion.sinkVersion.c_str(), compversion.sourceVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
548 version = isSink ? compversion.sinkVersion : compversion.sourceVersion;
549 return DH_FWK_SUCCESS;
550 }
551
GetVersionFromVerInfoMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)552 int32_t ComponentManager::GetVersionFromVerInfoMgr(const std::string &uuid, const DHType dhType,
553 std::string &version, bool isSink)
554 {
555 VersionInfo versionInfo;
556 int32_t ret = VersionInfoManager::GetInstance()->GetVersionInfoByDeviceId(GetDeviceIdByUUID(uuid), versionInfo);
557 if (ret != DH_FWK_SUCCESS) {
558 DHLOGE("Get Version info Manager failed, uuid =%s, dhType = %#X, errCode = %d",
559 GetAnonyString(uuid).c_str(), dhType, ret);
560 return ret;
561 }
562 auto iter = versionInfo.compVersions.find(dhType);
563 if (iter == versionInfo.compVersions.end()) {
564 DHLOGE("can not find component version for dhType = %d", dhType);
565 return ERR_DH_FWK_COMPONENT_DHTYPE_NOT_FOUND;
566 }
567 DHLOGI("Get version info mgr success, sinkVersion = %s, sourceVersion = %s, uuid = %s, dhType = %#X",
568 iter->second.sinkVersion.c_str(), iter->second.sourceVersion.c_str(), GetAnonyString(uuid).c_str(), dhType);
569 UpdateVersionCache(uuid, versionInfo);
570 version = isSink ? iter->second.sinkVersion : iter->second.sourceVersion;
571 return DH_FWK_SUCCESS;
572 }
573
GetVersion(const std::string & networkId,const std::string & uuid,DHType dhType,std::string & version,bool isSink)574 int32_t ComponentManager::GetVersion(const std::string &networkId, const std::string &uuid,
575 DHType dhType, std::string &version, bool isSink)
576 {
577 int32_t ret = GetVersionFromVerMgr(uuid, dhType, version, isSink);
578 if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
579 return DH_FWK_SUCCESS;
580 }
581
582 ret = GetVersionFromVerInfoMgr(uuid, dhType, version, isSink);
583 if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
584 return DH_FWK_SUCCESS;
585 }
586
587 return ret;
588 }
589
UpdateVersionCache(const std::string & uuid,const VersionInfo & versionInfo)590 void ComponentManager::UpdateVersionCache(const std::string &uuid, const VersionInfo &versionInfo)
591 {
592 DHVersion dhVersion;
593 dhVersion.uuid = uuid;
594 dhVersion.dhVersion = versionInfo.dhVersion;
595 dhVersion.compVersions = versionInfo.compVersions;
596 VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
597 }
598
DumpLoadedComps(std::set<DHType> & compSourceType,std::set<DHType> & compSinkType)599 void ComponentManager::DumpLoadedComps(std::set<DHType> &compSourceType, std::set<DHType> &compSinkType)
600 {
601 for (auto compSource : compSource_) {
602 compSourceType.emplace(compSource.first);
603 }
604 for (auto compSink : compSink_) {
605 compSinkType.emplace(compSink.first);
606 }
607 }
608
Recover(DHType dhType)609 void ComponentManager::Recover(DHType dhType)
610 {
611 std::thread(&ComponentManager::DoRecover, this, dhType).detach();
612 }
613
DoRecover(DHType dhType)614 void ComponentManager::DoRecover(DHType dhType)
615 {
616 int32_t ret = pthread_setname_np(pthread_self(), DO_RECOVER);
617 if (ret != DH_FWK_SUCCESS) {
618 DHLOGE("DoRecover setname failed.");
619 }
620 // step1: restart sa process
621 ReStartSA(dhType);
622 // step2: recover distributed hardware virtual driver
623 RecoverDistributedHardware(dhType);
624 }
625
ReStartSA(DHType dhType)626 void ComponentManager::ReStartSA(DHType dhType)
627 {
628 DHLOGI("Restart SA for DHType %" PRIu32, (uint32_t)dhType);
629 auto sourceResult = StartSource(dhType);
630 auto sinkResult = StartSink(dhType);
631
632 if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
633 DHLOGE("ReStartSource failed, DHType: %" PRIu32, (uint32_t)dhType);
634 }
635
636 if (!WaitForResult(Action::START_SINK, sinkResult)) {
637 DHLOGE("ReStartSink failed, DHType: %" PRIu32, (uint32_t)dhType);
638 }
639 DHLOGI("Finish Restart");
640 }
641
RecoverDistributedHardware(DHType dhType)642 void ComponentManager::RecoverDistributedHardware(DHType dhType)
643 {
644 CapabilityInfoMap capabilityMap;
645 CapabilityInfoManager::GetInstance()->GetDataByDHType(dhType, capabilityMap);
646 for (const auto &capInfo : capabilityMap) {
647 std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(capInfo.second->GetDeviceId());
648 if (uuid.empty()) {
649 DHLOGE("Can not find uuid by capability deviceId: %s",
650 GetAnonyString(capInfo.second->GetDeviceId()).c_str());
651 continue;
652 }
653
654 std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
655 if (networkId.empty()) {
656 DHLOGI("Can not find network id by uuid: %s", GetAnonyString(uuid).c_str());
657 continue;
658 }
659
660 TaskParam taskParam = {
661 .networkId = networkId,
662 .uuid = uuid,
663 .dhId = capInfo.second->GetDHId(),
664 .dhType = capInfo.second->GetDHType()
665 };
666 auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
667 TaskExecutor::GetInstance().PushTask(task);
668 }
669 }
670
GetDHSinkInstance()671 std::map<DHType, IDistributedHardwareSink*> ComponentManager::GetDHSinkInstance()
672 {
673 return compSink_;
674 }
675
IsIdenticalAccount(const std::string & networkId)676 bool ComponentManager::IsIdenticalAccount(const std::string &networkId)
677 {
678 DmAuthForm authForm = DmAuthForm::INVALID_TYPE;
679 std::vector<DmDeviceInfo> deviceList;
680 DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
681 if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
682 DHLOGE("DeviceList size is invalid!");
683 return false;
684 }
685 for (const auto &deviceInfo : deviceList) {
686 if (std::string(deviceInfo.networkId) == networkId) {
687 authForm = deviceInfo.authForm;
688 break;
689 }
690 }
691 if (authForm == DmAuthForm::IDENTICAL_ACCOUNT) {
692 return true;
693 }
694 return false;
695 }
696 } // namespace DistributedHardware
697 } // namespace OHOS
698