1 /*
2 * Copyright (c) 2021-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
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 "ffrt.h"
25 #include "ipc_object_stub.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28
29 #include "anonymous_string.h"
30 #include "capability_info_manager.h"
31 #include "component_disable.h"
32 #include "component_enable.h"
33 #include "component_loader.h"
34 #include "constants.h"
35 #include "device_manager.h"
36 #include "dh_context.h"
37 #include "dh_data_sync_trigger_listener.h"
38 #include "dh_state_listener.h"
39 #include "dh_utils_hitrace.h"
40 #include "dh_utils_hisysevent.h"
41 #include "dh_utils_tool.h"
42 #include "distributed_hardware_errno.h"
43 #include "distributed_hardware_log.h"
44 #include "enabled_comps_dump.h"
45 #include "local_capability_info_manager.h"
46 #include "low_latency.h"
47 #include "meta_info_manager.h"
48 #include "publisher.h"
49 #include "task_executor.h"
50 #include "task_factory.h"
51 #include "version_info_manager.h"
52 #include "version_manager.h"
53
54 namespace OHOS {
55 namespace DistributedHardware {
56 #undef DH_LOG_TAG
57 #define DH_LOG_TAG "ComponentManager"
58
59 IMPLEMENT_SINGLE_INSTANCE(ComponentManager);
60
61 namespace {
62 constexpr int32_t ENABLE_RETRY_MAX_TIMES = 3;
63 constexpr int32_t DISABLE_RETRY_MAX_TIMES = 3;
64 constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000;
65 constexpr int32_t INVALID_SA_ID = -1;
66 constexpr int32_t UNINIT_COMPONENT_TIMEOUT_SECONDS = 2;
67 constexpr int32_t SYNC_DEVICE_INFO_TIMEOUT_MILLISECONDS = 2000;
68 constexpr int32_t SYNC_DEVICE_INFO_INTERVAL_MILLISECONDS = 200;
69 const std::string MONITOR_TASK_TIMER_ID = "monitor_task_timer_id";
70 }
71
ComponentManager()72 ComponentManager::ComponentManager() : compSource_({}), compSink_({}), compSrcSaId_({}),
73 compMonitorPtr_(std::make_shared<ComponentMonitor>()),
74 lowLatencyListener_(sptr<LowLatencyListener>(new(std::nothrow) LowLatencyListener())),
75 isUnInitTimeOut_(false), dhBizStates_({}), dhStateListener_(std::make_shared<DHStateListener>()),
76 dataSyncTriggerListener_(std::make_shared<DHDataSyncTriggerListener>()),
77 dhCommToolPtr_(std::make_shared<DHCommTool>()), needRefreshTaskParams_({})
78 {
79 DHLOGI("Ctor ComponentManager");
80 }
81
~ComponentManager()82 ComponentManager::~ComponentManager()
83 {
84 DHLOGD("Dtor ComponentManager");
85 compMonitorPtr_.reset();
86 compMonitorPtr_ = nullptr;
87 lowLatencyListener_ = nullptr;
88 }
89
Init()90 int32_t ComponentManager::Init()
91 {
92 DHLOGI("start.");
93 DHTraceStart(COMPONENT_INIT_START);
94 #ifdef DHARDWARE_LOW_LATENCY
95 Publisher::GetInstance().RegisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
96 #endif
97 DHLOGI("Init component success");
98 DHTraceEnd();
99 return DH_FWK_SUCCESS;
100 }
101
UnInit()102 int32_t ComponentManager::UnInit()
103 {
104 DHLOGI("start.");
105 StopPrivacy();
106 #ifdef DHARDWARE_LOW_LATENCY
107 Publisher::GetInstance().UnregisterListener(DHTopic::TOPIC_LOW_LATENCY, lowLatencyListener_);
108 LowLatency::GetInstance().CloseLowLatency();
109 #endif
110 DHLOGI("Release component success");
111 if (isUnInitTimeOut_.load()) {
112 DHLOGE("Some component stop timeout, FORCE exit!");
113 _Exit(0);
114 }
115 return DH_FWK_SUCCESS;
116 }
117
StopPrivacy()118 void ComponentManager::StopPrivacy()
119 {
120 // stop privacy
121 if (cameraCompPrivacy_ != nullptr && cameraCompPrivacy_->GetPageFlag()) {
122 cameraCompPrivacy_->StopPrivacePage("camera");
123 cameraCompPrivacy_->SetPageFlagFalse();
124 }
125
126 if (audioCompPrivacy_ != nullptr && audioCompPrivacy_->GetPageFlag()) {
127 audioCompPrivacy_->StopPrivacePage("mic");
128 audioCompPrivacy_->SetPageFlagFalse();
129 }
130 }
131
StartSource(DHType dhType)132 ActionResult ComponentManager::StartSource(DHType dhType)
133 {
134 DHLOGI("Start Source, dhType: %{public}" PRIu32, (uint32_t)dhType);
135 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
136 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
137 if (compSource_.find(dhType) == compSource_.end()) {
138 DHLOGE("Component for DHType: %{public}" PRIu32 " not init source handler", (uint32_t)dhType);
139 return futures;
140 }
141 if (compSource_[dhType] == nullptr) {
142 DHLOGE("comp source ptr is null");
143 return futures;
144 }
145 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
146 CompVersion compVersion;
147 VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
148 auto params = compVersion.sourceVersion;
149 std::promise<int32_t> p;
150 std::future<int32_t> f = p.get_future();
151 std::thread([p = std::move(p), this, dhType, params] () mutable {
152 p.set_value(compSource_[dhType]->InitSource(params));
153 }).detach();
154 futures.emplace(dhType, f.share());
155
156 return futures;
157 }
158
StartSink(DHType dhType)159 ActionResult ComponentManager::StartSink(DHType dhType)
160 {
161 DHLOGI("Start Sink, dhType: %{public}" PRIu32, (uint32_t)dhType);
162 std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
163 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
164 if (compSink_.find(dhType) == compSink_.end()) {
165 DHLOGE("Component for DHType: %{public}" PRIu32 " not init sink handler", (uint32_t)dhType);
166 return futures;
167 }
168 if (compSink_[dhType] == nullptr) {
169 DHLOGE("comp sink ptr is null");
170 return futures;
171 }
172 std::string uuid = DHContext::GetInstance().GetDeviceInfo().uuid;
173 CompVersion compVersion;
174 VersionManager::GetInstance().GetCompVersion(uuid, dhType, compVersion);
175 auto params = compVersion.sinkVersion;
176 std::promise<int32_t> p;
177 std::future<int32_t> f = p.get_future();
178 std::thread([p = std::move(p), this, dhType, params] () mutable {
179 p.set_value(compSink_[dhType]->InitSink(params));
180 }).detach();
181 futures.emplace(dhType, f.share());
182 if (cameraCompPrivacy_ == nullptr && dhType == DHType::CAMERA) {
183 cameraCompPrivacy_ = std::make_shared<ComponentPrivacy>();
184 compSink_[dhType]->RegisterPrivacyResources(cameraCompPrivacy_);
185 }
186 if (audioCompPrivacy_ == nullptr && dhType == DHType::AUDIO) {
187 audioCompPrivacy_ = std::make_shared<ComponentPrivacy>();
188 compSink_[dhType]->RegisterPrivacyResources(audioCompPrivacy_);
189 }
190
191 return futures;
192 }
193
WaitForResult(const Action & action,ActionResult actionsResult)194 bool ComponentManager::WaitForResult(const Action &action, ActionResult actionsResult)
195 {
196 DHLOGD("start.");
197 auto ret = true;
198 for (auto &iter : actionsResult) {
199 std::future_status status = iter.second.wait_for(std::chrono::seconds(UNINIT_COMPONENT_TIMEOUT_SECONDS));
200 if (status == std::future_status::ready) {
201 auto result = iter.second.get();
202 DHLOGI("action = %{public}d, compType = %{public}#X, READY, ret = %{public}d.",
203 static_cast<int32_t>(action), iter.first, result);
204 if (result != DH_FWK_SUCCESS) {
205 ret = false;
206 DHLOGE("there is error, but want to continue.");
207 }
208 }
209
210 if (status == std::future_status::timeout) {
211 DHLOGI("action = %{public}d, compType = %{public}#X, TIMEOUT", static_cast<int32_t>(action), iter.first);
212 if (action == Action::STOP_SOURCE || action == Action::STOP_SINK) {
213 isUnInitTimeOut_ = true;
214 }
215 }
216
217 if (status == std::future_status::deferred) {
218 DHLOGI("action = %{public}d, compType = %{public}#X, DEFERRED", static_cast<int32_t>(action), iter.first);
219 }
220 }
221 DHLOGD("end.");
222 return ret;
223 }
224
Enable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,bool isActive)225 int32_t ComponentManager::Enable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
226 const DHType dhType, bool isActive)
227 {
228 DHLOGI("start.");
229 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
230 return ERR_DH_FWK_PARA_INVALID;
231 }
232 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
233 if (compSource_.find(dhType) == compSource_.end()) {
234 DHLOGE("can not find handler for dhId = %{public}s.", GetAnonyString(dhId).c_str());
235 return ERR_DH_FWK_PARA_INVALID;
236 }
237 EnableParam param;
238 auto ret = GetEnableParam(networkId, uuid, dhId, dhType, param);
239 if (ret != DH_FWK_SUCCESS) {
240 DHLOGE("GetEnableParam failed, uuid = %{public}s, dhId = %{public}s, errCode = %{public}d",
241 GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
242 if (RetryGetEnableParam(networkId, uuid, dhId, dhType, param) != DH_FWK_SUCCESS) {
243 return ret;
244 }
245 }
246 if (!isActive) {
247 ret = CheckSubtypeResource(param.subtype, networkId);
248 if (ret != DH_FWK_SUCCESS) {
249 DHLOGE("CheckSubtypeResource failed, ret = %{public}d.", ret);
250 return ret;
251 }
252 }
253
254 auto compEnable = std::make_shared<ComponentEnable>();
255 auto result = compEnable->Enable(networkId, dhId, param, (compSource_.find(dhType))->second);
256 if (result != DH_FWK_SUCCESS) {
257 for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
258 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
259 DHLOGE("device is already offline, no need try enable, uuid= %{public}s", GetAnonyString(uuid).c_str());
260 return result;
261 }
262 if (compEnable->Enable(networkId, dhId, param, (compSource_.find(dhType))->second) == DH_FWK_SUCCESS) {
263 DHLOGE("enable success, retryCount = %{public}d", retryCount);
264 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
265 return DH_FWK_SUCCESS;
266 }
267 DHLOGE("enable failed, retryCount = %{public}d", retryCount);
268 }
269 return result;
270 }
271 DHLOGI("enable result is %{public}d, uuid = %{public}s, dhId = %{public}s", result, GetAnonyString(uuid).c_str(),
272 GetAnonyString(dhId).c_str());
273 EnabledCompsDump::GetInstance().DumpEnabledComp(networkId, dhType, dhId);
274
275 return result;
276 }
277
CheckSubtypeResource(const std::string & subtype,const std::string & networkId)278 int32_t ComponentManager::CheckSubtypeResource(const std::string &subtype, const std::string &networkId)
279 {
280 #ifdef DHARDWARE_CHECK_RESOURCE
281 std::map<std::string, bool> resourceDesc = ComponentLoader::GetInstance().GetCompResourceDesc();
282 if (resourceDesc.find(subtype) == resourceDesc.end()) {
283 DHLOGE("GetCompResourceDesc failed, subtype: %{public}s", subtype.c_str());
284 return ERR_DH_FWK_RESOURCE_KEY_IS_EMPTY;
285 }
286 if (resourceDesc[subtype] && !IsIdenticalAccount(networkId)) {
287 DHLOGE("Privacy resources must be logged in with the same account.");
288 return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
289 }
290 #endif
291 return DH_FWK_SUCCESS;
292 }
293
RetryGetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType,EnableParam & param)294 int32_t ComponentManager::RetryGetEnableParam(const std::string &networkId, const std::string &uuid,
295 const std::string &dhId, const DHType dhType, EnableParam ¶m)
296 {
297 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
298 return ERR_DH_FWK_PARA_INVALID;
299 }
300 for (int32_t retryCount = 0; retryCount < ENABLE_RETRY_MAX_TIMES; retryCount++) {
301 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
302 DHLOGE("device is already offline, no need try GetEnableParam, uuid = %{public}s",
303 GetAnonyString(uuid).c_str());
304 return ERR_DH_FWK_COMPONENT_ENABLE_FAILED;
305 }
306 if (GetEnableParam(networkId, uuid, dhId, dhType, param) == DH_FWK_SUCCESS) {
307 DHLOGE("GetEnableParam success, retryCount = %{public}d", retryCount);
308 break;
309 }
310 DHLOGE("GetEnableParam failed, retryCount = %{public}d", retryCount);
311 usleep(ENABLE_PARAM_RETRY_TIME);
312 }
313 return DH_FWK_SUCCESS;
314 }
315
Disable(const std::string & networkId,const std::string & uuid,const std::string & dhId,const DHType dhType)316 int32_t ComponentManager::Disable(const std::string &networkId, const std::string &uuid, const std::string &dhId,
317 const DHType dhType)
318 {
319 DHLOGI("start.");
320 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
321 return ERR_DH_FWK_PARA_INVALID;
322 }
323 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
324 auto find = compSource_.find(dhType);
325 if (find == compSource_.end()) {
326 DHLOGE("can not find handler for dhId = %{public}s.", GetAnonyString(dhId).c_str());
327 return ERR_DH_FWK_PARA_INVALID;
328 }
329
330 auto compDisable = std::make_shared<ComponentDisable>();
331 auto result = compDisable->Disable(networkId, dhId, find->second);
332 if (result != DH_FWK_SUCCESS) {
333 for (int32_t retryCount = 0; retryCount < DISABLE_RETRY_MAX_TIMES; retryCount++) {
334 if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
335 DHLOGE("device is already online, no need try disable, uuid = %{public}s",
336 GetAnonyString(uuid).c_str());
337 return result;
338 }
339 if (compDisable->Disable(networkId, dhId, find->second) == DH_FWK_SUCCESS) {
340 DHLOGE("disable success, retryCount = %{public}d", retryCount);
341 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
342 return DH_FWK_SUCCESS;
343 }
344 DHLOGE("disable failed, retryCount = %{public}d", retryCount);
345 }
346 return result;
347 }
348 DHLOGI("disable result is %{public}d, uuid = %{public}s, dhId = %{public}s", result, GetAnonyString(uuid).c_str(),
349 GetAnonyString(dhId).c_str());
350 EnabledCompsDump::GetInstance().DumpDisabledComp(networkId, dhType, dhId);
351
352 return result;
353 }
354
GetDHType(const std::string & uuid,const std::string & dhId) const355 DHType ComponentManager::GetDHType(const std::string &uuid, const std::string &dhId) const
356 {
357 std::shared_ptr<CapabilityInfo> capability = nullptr;
358 auto ret = CapabilityInfoManager::GetInstance()->GetCapability(GetDeviceIdByUUID(uuid), dhId, capability);
359 if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
360 return capability->GetDHType();
361 }
362 DHLOGE("get dhType failed, uuid = %{public}s, dhId = %{public}s", GetAnonyString(uuid).c_str(),
363 GetAnonyString(dhId).c_str());
364 return DHType::UNKNOWN;
365 }
366
GetEnableCapParam(const std::string & networkId,const std::string & uuid,DHType dhType,EnableParam & param,std::shared_ptr<CapabilityInfo> capability)367 int32_t ComponentManager::GetEnableCapParam(const std::string &networkId, const std::string &uuid,
368 DHType dhType, EnableParam ¶m, std::shared_ptr<CapabilityInfo> capability)
369 {
370 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid)) {
371 return ERR_DH_FWK_PARA_INVALID;
372 }
373 DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
374 std::vector<std::shared_ptr<CapabilityInfo>> sourceCapInfos;
375 std::string sourceDHId;
376 CapabilityInfoManager::GetInstance()->GetCapabilitiesByDeviceId(sourceDeviceInfo.deviceId, sourceCapInfos);
377 for (const auto &capInfo : sourceCapInfos) {
378 if (dhType == capInfo->GetDHType()) {
379 param.sourceAttrs = capInfo->GetDHAttrs();
380 sourceDHId = capInfo->GetDHId();
381 }
382 }
383 std::string sourceVersion("");
384 auto ret = GetVersion(sourceDeviceInfo.uuid, dhType, sourceVersion, false);
385 if (ret != DH_FWK_SUCCESS) {
386 DHLOGE("Get source version failed.");
387 return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
388 }
389 param.sourceVersion = sourceVersion;
390
391 param.sinkAttrs = capability->GetDHAttrs();
392 std::string sinkVersion("");
393 ret = GetVersion(uuid, dhType, sinkVersion, true);
394 if (ret != DH_FWK_SUCCESS) {
395 DHLOGE("Get sink version failed.");
396 // If Version DB not sync, try get sink version from meta info
397 std::shared_ptr<MetaCapabilityInfo> metaCapPtr = nullptr;
398 ret = MetaInfoManager::GetInstance()->GetMetaCapInfo(DHContext::GetInstance().GetUdidHashIdByUUID(uuid),
399 capability->GetDHId(), metaCapPtr);
400 if ((ret == DH_FWK_SUCCESS) && (metaCapPtr != nullptr)) {
401 sinkVersion = metaCapPtr->GetSinkVersion();
402 } else {
403 return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
404 }
405 }
406 param.sinkVersion = sinkVersion;
407 param.subtype = capability->GetDHSubtype();
408 DHLOGI("GetEnableCapParam success. dhType = %{public}#X, sink uuid =%{public}s,"
409 "sinVersion = %{public}s, source uuid =%{public}s, source dhId = %{public}s, sourceVersion = %{public}s,"
410 "subtype = %{public}s", dhType, GetAnonyString(uuid).c_str(),
411 param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(),
412 param.sourceVersion.c_str(), param.subtype.c_str());
413 return DH_FWK_SUCCESS;
414 }
415
GetEnableMetaParam(const std::string & networkId,const std::string & uuid,DHType dhType,EnableParam & param,std::shared_ptr<MetaCapabilityInfo> metaCapPtr)416 int32_t ComponentManager::GetEnableMetaParam(const std::string &networkId, const std::string &uuid,
417 DHType dhType, EnableParam ¶m, std::shared_ptr<MetaCapabilityInfo> metaCapPtr)
418 {
419 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid)) {
420 return ERR_DH_FWK_PARA_INVALID;
421 }
422 DeviceInfo sourceDeviceInfo = GetLocalDeviceInfo();
423 std::vector<std::shared_ptr<MetaCapabilityInfo>> sourceMetaInfos;
424 std::string sourceDHId;
425 MetaInfoManager::GetInstance()->GetMetaCapInfosByUdidHash(sourceDeviceInfo.udidHash, sourceMetaInfos);
426 for (const auto &metaInfo : sourceMetaInfos) {
427 if (dhType == metaInfo->GetDHType()) {
428 param.sourceAttrs = metaInfo->GetDHAttrs();
429 sourceDHId = metaInfo->GetDHId();
430 }
431 }
432 std::string sourceVersion("");
433 auto ret = GetVersion(sourceDeviceInfo.uuid, dhType, sourceVersion, false);
434 if (ret != DH_FWK_SUCCESS) {
435 DHLOGE("Get source version failed.");
436 return ERR_DH_FWK_COMPONENT_GET_SINK_VERSION_FAILED;
437 }
438 param.sourceVersion = sourceVersion;
439
440 param.sinkAttrs = metaCapPtr->GetDHAttrs();
441 param.sinkVersion = metaCapPtr->GetSinkVersion();
442 param.subtype = metaCapPtr->GetDHSubtype();
443 DHLOGI("GetEnableCapParam success. dhType = %{public}#X, sink uuid =%{public}s,"
444 "sinVersion = %{public}s, source uuid =%{public}s, source dhId = %{public}s, sourceVersion = %{public}s,"
445 "subtype = %{public}s", dhType, GetAnonyString(uuid).c_str(),
446 param.sinkVersion.c_str(), GetAnonyString(sourceDeviceInfo.uuid).c_str(), GetAnonyString(sourceDHId).c_str(),
447 param.sourceVersion.c_str(), param.subtype.c_str());
448 return DH_FWK_SUCCESS;
449 }
450
GetCapParam(const std::string & uuid,const std::string & dhId,std::shared_ptr<CapabilityInfo> & capability)451 int32_t ComponentManager::GetCapParam(const std::string &uuid, const std::string &dhId,
452 std::shared_ptr<CapabilityInfo> &capability)
453 {
454 if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
455 return ERR_DH_FWK_PARA_INVALID;
456 }
457 std::string deviceId = GetDeviceIdByUUID(uuid);
458 auto ret = CapabilityInfoManager::GetInstance()->GetCapability(deviceId, dhId, capability);
459 if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
460 DHLOGI("GetCapability success, deviceId: %{public}s, uuid: %{public}s, dhId: %{public}s, ret: %{public}d",
461 GetAnonyString(deviceId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
462 return ret;
463 }
464
465 ret = LocalCapabilityInfoManager::GetInstance()->GetCapability(deviceId, dhId, capability);
466 if ((ret == DH_FWK_SUCCESS) && (capability != nullptr)) {
467 DHLOGI("Local GetCaps success, deviceId: %{public}s, uuid: %{public}s, dhId: %{public}s, ret: %{public}d",
468 GetAnonyString(deviceId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
469 return ret;
470 }
471
472 return ret;
473 }
474
GetMetaParam(const std::string & uuid,const std::string & dhId,std::shared_ptr<MetaCapabilityInfo> & metaCapPtr)475 int32_t ComponentManager::GetMetaParam(const std::string &uuid, const std::string &dhId,
476 std::shared_ptr<MetaCapabilityInfo> &metaCapPtr)
477 {
478 if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
479 return ERR_DH_FWK_PARA_INVALID;
480 }
481 auto ret = MetaInfoManager::GetInstance()->GetMetaCapInfo(DHContext::GetInstance().GetUdidHashIdByUUID(uuid),
482 dhId, metaCapPtr);
483 if ((ret == DH_FWK_SUCCESS) && (metaCapPtr != nullptr)) {
484 DHLOGI("GetCapability success, uuid =%{public}s, dhId = %{public}s, errCode = %{public}d",
485 GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), ret);
486 return ret;
487 }
488 return ret;
489 }
490
GetEnableParam(const std::string & networkId,const std::string & uuid,const std::string & dhId,DHType dhType,EnableParam & param)491 int32_t ComponentManager::GetEnableParam(const std::string &networkId, const std::string &uuid,
492 const std::string &dhId, DHType dhType, EnableParam ¶m)
493 {
494 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
495 return ERR_DH_FWK_COMPONENT_GET_ENABLE_PARAM_FAILED;
496 }
497 DHLOGI("GetEnableParam start, networkId= %{public}s, uuid = %{public}s, dhId = %{public}s, dhType = %{public}#X,",
498 GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(dhId).c_str(), dhType);
499 std::shared_ptr<CapabilityInfo> capability = nullptr;
500 if (GetCapParam(uuid, dhId, capability) == DH_FWK_SUCCESS) {
501 auto ret = GetEnableCapParam(networkId, uuid, dhType, param, capability);
502 if (ret == DH_FWK_SUCCESS) {
503 return ret;
504 }
505 DHLOGE("GetEnableCapParam failed.");
506 }
507
508 std::shared_ptr<MetaCapabilityInfo> metaCapPtr = nullptr;
509 if (GetMetaParam(uuid, dhId, metaCapPtr) == DH_FWK_SUCCESS) {
510 auto ret = GetEnableMetaParam(networkId, uuid, dhType, param, metaCapPtr);
511 if (ret == DH_FWK_SUCCESS) {
512 return ret;
513 }
514 DHLOGE("GetEnableMetaParam failed.");
515 }
516 DHLOGE("GetEnableParam is failed.");
517 return ERR_DH_FWK_COMPONENT_GET_ENABLE_PARAM_FAILED;
518 }
519
GetVersionFromVerMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)520 int32_t ComponentManager::GetVersionFromVerMgr(const std::string &uuid, const DHType dhType,
521 std::string &version, bool isSink)
522 {
523 if (!IsIdLengthValid(uuid)) {
524 return ERR_DH_FWK_PARA_INVALID;
525 }
526 CompVersion compversion;
527 int32_t ret = VersionManager::GetInstance().GetCompVersion(uuid, dhType, compversion);
528 if (ret != DH_FWK_SUCCESS) {
529 DHLOGE("Get version Manager failed, uuid =%{public}s, dhType = %{public}#X, errCode = %{public}d",
530 GetAnonyString(uuid).c_str(), dhType, ret);
531 return ret;
532 }
533 DHLOGI("Get version mgr success, sinkVersion = %{public}s, sourceVersion = %{public}s,uuid = %{public}s, "
534 "dhType = %{public}#X", compversion.sinkVersion.c_str(), compversion.sourceVersion.c_str(),
535 GetAnonyString(uuid).c_str(), dhType);
536 version = isSink ? compversion.sinkVersion : compversion.sourceVersion;
537 return DH_FWK_SUCCESS;
538 }
539
GetVersionFromVerInfoMgr(const std::string & uuid,const DHType dhType,std::string & version,bool isSink)540 int32_t ComponentManager::GetVersionFromVerInfoMgr(const std::string &uuid, const DHType dhType,
541 std::string &version, bool isSink)
542 {
543 if (!IsIdLengthValid(uuid)) {
544 return ERR_DH_FWK_PARA_INVALID;
545 }
546 VersionInfo versionInfo;
547 int32_t ret = VersionInfoManager::GetInstance()->GetVersionInfoByDeviceId(GetDeviceIdByUUID(uuid), versionInfo);
548 if (ret != DH_FWK_SUCCESS) {
549 DHLOGE("Get Version info Manager failed, uuid =%{public}s, dhType = %{public}#X, errCode = %{public}d",
550 GetAnonyString(uuid).c_str(), dhType, ret);
551 return ret;
552 }
553 auto iter = versionInfo.compVersions.find(dhType);
554 if (iter == versionInfo.compVersions.end()) {
555 DHLOGE("can not find component version for dhType = %{public}d", dhType);
556 return ERR_DH_FWK_COMPONENT_DHTYPE_NOT_FOUND;
557 }
558 DHLOGI("Get version info mgr success, sinkVersion = %{public}s, sourceVersion = %{public}s, uuid = %{public}s, "
559 "dhType = %{public}#X", iter->second.sinkVersion.c_str(), iter->second.sourceVersion.c_str(),
560 GetAnonyString(uuid).c_str(), dhType);
561 UpdateVersionCache(uuid, versionInfo);
562 version = isSink ? iter->second.sinkVersion : iter->second.sourceVersion;
563 return DH_FWK_SUCCESS;
564 }
565
GetVersion(const std::string & uuid,DHType dhType,std::string & version,bool isSink)566 int32_t ComponentManager::GetVersion(const std::string &uuid, DHType dhType, std::string &version, bool isSink)
567 {
568 if (!IsIdLengthValid(uuid)) {
569 return ERR_DH_FWK_PARA_INVALID;
570 }
571 int32_t ret = GetVersionFromVerMgr(uuid, dhType, version, isSink);
572 if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
573 return DH_FWK_SUCCESS;
574 }
575
576 ret = GetVersionFromVerInfoMgr(uuid, dhType, version, isSink);
577 if ((ret == DH_FWK_SUCCESS) && (!version.empty())) {
578 return DH_FWK_SUCCESS;
579 }
580
581 return ret;
582 }
583
UpdateVersionCache(const std::string & uuid,const VersionInfo & versionInfo)584 void ComponentManager::UpdateVersionCache(const std::string &uuid, const VersionInfo &versionInfo)
585 {
586 if (!IsIdLengthValid(uuid)) {
587 return;
588 }
589 DHVersion dhVersion;
590 dhVersion.uuid = uuid;
591 dhVersion.dhVersion = versionInfo.dhVersion;
592 dhVersion.compVersions = versionInfo.compVersions;
593 VersionManager::GetInstance().AddDHVersion(uuid, dhVersion);
594 }
595
DumpLoadedCompsource(std::set<DHType> & compSourceType)596 void ComponentManager::DumpLoadedCompsource(std::set<DHType> &compSourceType)
597 {
598 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
599 for (auto compSource : compSource_) {
600 compSourceType.emplace(compSource.first);
601 }
602 }
603
DumpLoadedCompsink(std::set<DHType> & compSinkType)604 void ComponentManager::DumpLoadedCompsink(std::set<DHType> &compSinkType)
605 {
606 std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
607 for (auto compSink : compSink_) {
608 compSinkType.emplace(compSink.first);
609 }
610 }
611
Recover(DHType dhType)612 void ComponentManager::Recover(DHType dhType)
613 {
614 ffrt::submit([this, dhType]() { this->DoRecover(dhType); });
615 }
616
DoRecover(DHType dhType)617 void ComponentManager::DoRecover(DHType dhType)
618 {
619 int32_t ret = pthread_setname_np(pthread_self(), DO_RECOVER);
620 if (ret != DH_FWK_SUCCESS) {
621 DHLOGE("DoRecover setname failed.");
622 }
623 // step1: restart sa process
624 ReStartSA(dhType);
625 // step2: recover distributed hardware virtual driver
626 RecoverDistributedHardware(dhType);
627 }
628
ReStartSA(DHType dhType)629 void ComponentManager::ReStartSA(DHType dhType)
630 {
631 DHLOGI("Restart SA for DHType %{public}" PRIu32, (uint32_t)dhType);
632 auto sourceResult = StartSource(dhType);
633 auto sinkResult = StartSink(dhType);
634
635 if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
636 DHLOGE("ReStartSource failed, DHType: %{public}" PRIu32, (uint32_t)dhType);
637 }
638
639 if (!WaitForResult(Action::START_SINK, sinkResult)) {
640 DHLOGE("ReStartSink failed, DHType: %{public}" PRIu32, (uint32_t)dhType);
641 }
642 DHLOGI("Finish Restart");
643 }
644
RecoverDistributedHardware(DHType dhType)645 void ComponentManager::RecoverDistributedHardware(DHType dhType)
646 {
647 MetaCapInfoMap metaInfoMap;
648 MetaInfoManager::GetInstance()->GetMetaDataByDHType(dhType, metaInfoMap);
649 for (const auto &metaInfo : metaInfoMap) {
650 std::string uuid = DHContext::GetInstance().GetUUIDByDeviceId(metaInfo.second->GetDeviceId());
651 if (uuid.empty()) {
652 DHLOGE("Can not find uuid by capability deviceId: %{public}s",
653 GetAnonyString(metaInfo.second->GetDeviceId()).c_str());
654 continue;
655 }
656
657 std::string networkId = DHContext::GetInstance().GetNetworkIdByUUID(uuid);
658 if (networkId.empty()) {
659 DHLOGI("Can not find network id by uuid: %{public}s", GetAnonyString(uuid).c_str());
660 continue;
661 }
662
663 TaskParam taskParam = {
664 .networkId = networkId,
665 .uuid = uuid,
666 .dhId = metaInfo.second->GetDHId(),
667 .dhType = metaInfo.second->GetDHType()
668 };
669 auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
670 TaskExecutor::GetInstance().PushTask(task);
671 }
672 }
673
GetDHSinkInstance()674 std::map<DHType, IDistributedHardwareSink*> ComponentManager::GetDHSinkInstance()
675 {
676 std::shared_lock<std::shared_mutex> lock(compSinkMutex_);
677 return compSink_;
678 }
679
IsIdenticalAccount(const std::string & networkId)680 bool ComponentManager::IsIdenticalAccount(const std::string &networkId)
681 {
682 if (!IsIdLengthValid(networkId)) {
683 return false;
684 }
685 DmAuthForm authForm = DmAuthForm::INVALID_TYPE;
686 std::vector<DmDeviceInfo> deviceList;
687 DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
688 if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
689 DHLOGE("DeviceList size is invalid!");
690 return false;
691 }
692 for (const auto &deviceInfo : deviceList) {
693 if (std::string(deviceInfo.networkId) == networkId) {
694 authForm = deviceInfo.authForm;
695 break;
696 }
697 }
698 if (authForm == DmAuthForm::IDENTICAL_ACCOUNT) {
699 return true;
700 }
701 return false;
702 }
703
UpdateBusinessState(const std::string & networkId,const std::string & dhId,BusinessState state)704 void ComponentManager::UpdateBusinessState(const std::string &networkId, const std::string &dhId, BusinessState state)
705 {
706 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(dhId)) {
707 return;
708 }
709 DHLOGI("UpdateBusinessState, networkId: %{public}s, dhId: %{public}s, state: %{public}" PRIu32,
710 GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str(), (uint32_t)state);
711 {
712 std::lock_guard<std::mutex> lock(bizStateMtx_);
713 dhBizStates_[{networkId, dhId}] = state;
714 }
715
716 if (state == BusinessState::IDLE) {
717 TaskParam taskParam;
718 if (!FetchNeedRefreshTask({networkId, dhId}, taskParam)) {
719 return;
720 }
721 DHLOGI("The dh need refresh, networkId: %{public}s, dhId: %{public}s",
722 GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str());
723 auto task = TaskFactory::GetInstance().CreateTask(TaskType::ENABLE, taskParam, nullptr);
724 TaskExecutor::GetInstance().PushTask(task);
725 }
726 }
727
GetDHSourceInstance(DHType dhType)728 IDistributedHardwareSource* ComponentManager::GetDHSourceInstance(DHType dhType)
729 {
730 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
731 if (compSource_.find(dhType) == compSource_.end()) {
732 DHLOGE("can not find handler for dhType = %{public}d.", dhType);
733 return nullptr;
734 }
735 return compSource_[dhType];
736 }
737
QueryBusinessState(const std::string & uuid,const std::string & dhId)738 BusinessState ComponentManager::QueryBusinessState(const std::string &uuid, const std::string &dhId)
739 {
740 if (!IsIdLengthValid(uuid) || !IsIdLengthValid(dhId)) {
741 return BusinessState::UNKNOWN;
742 }
743 std::lock_guard<std::mutex> lock(bizStateMtx_);
744 std::pair<std::string, std::string> key = {uuid, dhId};
745 if (dhBizStates_.find(key) == dhBizStates_.end()) {
746 return BusinessState::UNKNOWN;
747 }
748
749 return dhBizStates_.at(key);
750 }
751
TriggerFullCapsSync(const std::string & networkId)752 void ComponentManager::TriggerFullCapsSync(const std::string &networkId)
753 {
754 if (!IsIdLengthValid(networkId)) {
755 return;
756 }
757 if (dhCommToolPtr_ == nullptr) {
758 DHLOGE("DH communication tool ptr is null");
759 return;
760 }
761 dhCommToolPtr_->TriggerReqFullDHCaps(networkId);
762 }
763
SaveNeedRefreshTask(const TaskParam & taskParam)764 void ComponentManager::SaveNeedRefreshTask(const TaskParam &taskParam)
765 {
766 std::lock_guard<std::mutex> lock(needRefreshTaskParamsMtx_);
767 needRefreshTaskParams_[{taskParam.networkId, taskParam.dhId}] = taskParam;
768 }
769
FetchNeedRefreshTask(const std::pair<std::string,std::string> & taskKey,TaskParam & taskParam)770 bool ComponentManager::FetchNeedRefreshTask(const std::pair<std::string, std::string> &taskKey, TaskParam &taskParam)
771 {
772 std::lock_guard<std::mutex> lock(needRefreshTaskParamsMtx_);
773 if (needRefreshTaskParams_.find(taskKey) == needRefreshTaskParams_.end()) {
774 return false;
775 }
776
777 taskParam = needRefreshTaskParams_.at(taskKey);
778 needRefreshTaskParams_.erase(taskKey);
779 return true;
780 }
781
ComponentManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> runner)782 ComponentManager::ComponentManagerEventHandler::ComponentManagerEventHandler(
783 const std::shared_ptr<AppExecFwk::EventRunner> runner) : AppExecFwk::EventHandler(runner)
784 {
785 DHLOGI("Ctor ComponentManagerEventHandler");
786 }
787
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)788 void ComponentManager::ComponentManagerEventHandler::ProcessEvent(
789 const AppExecFwk::InnerEvent::Pointer &event)
790 {
791 if (event == nullptr) {
792 DHLOGE("event is nullptr");
793 return;
794 }
795 uint32_t eventId = event->GetInnerEventId();
796 switch (eventId) {
797 case EVENT_DATA_SYNC_MANUAL: {
798 // do muanul sync with remote
799 auto sharedObjPtr = event->GetSharedObject<std::string>();
800 if (sharedObjPtr == nullptr) {
801 DHLOGE("The data sync param invalid!");
802 break;
803 }
804 std::string networkId = *sharedObjPtr;
805 DHLOGI("Try receive full capabiliy info from networkId: %{public}s", GetAnonyString(networkId).c_str());
806 if (networkId.empty()) {
807 DHLOGE("Can not get device uuid by networkId: %{public}s", GetAnonyString(networkId).c_str());
808 break;
809 }
810 ComponentManager::GetInstance().TriggerFullCapsSync(networkId);
811 break;
812 }
813 default:
814 DHLOGE("event is undefined, id is %{public}d", eventId);
815 break;
816 }
817 }
818
GetEventHandler()819 std::shared_ptr<ComponentManager::ComponentManagerEventHandler> ComponentManager::GetEventHandler()
820 {
821 return this->eventHandler_;
822 }
823
CheckDemandStart(const std::string & uuid,const DHType dhType,bool & enableSink,bool & enableSource)824 int32_t ComponentManager::CheckDemandStart(const std::string &uuid,
825 const DHType dhType, bool &enableSink, bool &enableSource)
826 {
827 // Initialize output parameters
828 enableSink = false;
829 enableSource = false;
830
831 // Get remote config
832 CompVersion compVersion;
833 auto ret = GetRemoteVerInfo(compVersion, uuid, dhType);
834 if (ret != DH_FWK_SUCCESS) {
835 DHLOGE("GetRemoteVerInfo fail, errCode = %{public}d!", ret);
836 return ret;
837 }
838
839 // Get local config
840 DHVersion dhVersion;
841 ret = ComponentLoader::GetInstance().GetLocalDHVersion(dhVersion);
842 if (ret != DH_FWK_SUCCESS) {
843 DHLOGE("GetLocalDHVersion fail, errCode = %{public}d!", ret);
844 return ret;
845 }
846
847 auto iterLocal = dhVersion.compVersions.find(dhType);
848 if (iterLocal == dhVersion.compVersions.end()) {
849 DHLOGE("Not find dhType in local: %{public}#X!", dhType);
850 return ERR_DH_FWK_TYPE_NOT_EXIST;
851 }
852
853 // Check local config
854 if (!iterLocal->second.haveFeature) {
855 enableSink = true;
856 enableSource = true;
857 return DH_FWK_SUCCESS;
858 }
859
860 if (iterLocal->second.sinkSupportedFeatures.size()) {
861 enableSink = true;
862 }
863
864 if (iterLocal->second.sourceFeatureFilters.size() == 0) {
865 return DH_FWK_SUCCESS;
866 }
867
868 // Check remote config
869 if (!compVersion.haveFeature) { // Remote config is null, need enable source
870 enableSource = true;
871 return DH_FWK_SUCCESS;
872 }
873
874 if (compVersion.sinkSupportedFeatures.size() == 0) { // Remote sink config is empty, not enable source
875 return DH_FWK_SUCCESS;
876 }
877
878 // Check if the configurations on both ends match
879 enableSource = IsFeatureMatched(iterLocal->second.sourceFeatureFilters, compVersion.sinkSupportedFeatures);
880
881 return DH_FWK_SUCCESS;
882 }
883
RegisterDHStatusListener(sptr<IHDSinkStatusListener> listener,int32_t callingUid,int32_t callingPid)884 int32_t ComponentManager::RegisterDHStatusListener(
885 sptr<IHDSinkStatusListener> listener, int32_t callingUid, int32_t callingPid)
886 {
887 std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
888
889 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
890 for (const auto &type : compTypes) {
891 auto &status = dhSinkStatus_[type];
892 DHStatusCtrlKey ctrlKey {
893 .uid = callingUid,
894 .pid = callingPid
895 };
896 auto &listeners = status.listeners;
897 if (listeners.find(ctrlKey) != listeners.end()) {
898 DHLOGE("Repeat call RegisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
899 ctrlKey.uid, ctrlKey.pid);
900 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
901 }
902 listeners[ctrlKey] = listener;
903 }
904
905 return DH_FWK_SUCCESS;
906 }
907
UnregisterDHStatusListener(sptr<IHDSinkStatusListener> listener,int32_t callingUid,int32_t callingPid)908 int32_t ComponentManager::UnregisterDHStatusListener(
909 sptr<IHDSinkStatusListener> listener, int32_t callingUid, int32_t callingPid)
910 {
911 std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
912
913 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
914 for (const auto &type : compTypes) {
915 auto &status = dhSinkStatus_[type];
916 DHStatusCtrlKey ctrlKey {
917 .uid = callingUid,
918 .pid = callingPid
919 };
920 auto &listeners = status.listeners;
921 auto it = listeners.find(ctrlKey);
922 if (it == listeners.end()) {
923 DHLOGE("Repeat call UnregisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
924 ctrlKey.uid, ctrlKey.pid);
925 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
926 }
927 listeners.erase(it);
928 }
929
930 return DH_FWK_SUCCESS;
931 }
932
RegisterDHStatusListener(const std::string & networkId,sptr<IHDSourceStatusListener> listener,int32_t callingUid,int32_t callingPid)933 int32_t ComponentManager::RegisterDHStatusListener(
934 const std::string &networkId, sptr<IHDSourceStatusListener> listener, int32_t callingUid, int32_t callingPid)
935 {
936 std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
937
938 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
939 for (const auto &type : compTypes) {
940 auto &status = dhSourceStatus_[type];
941 DHStatusCtrlKey ctrlKey {
942 .uid = callingUid,
943 .pid = callingPid
944 };
945 auto &listeners = status.listeners;
946 if (listeners.find(ctrlKey) != listeners.end()) {
947 DHLOGE("Repeat call RegisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
948 ctrlKey.uid, ctrlKey.pid);
949 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
950 }
951 listeners[ctrlKey] = listener;
952 }
953
954 return DH_FWK_SUCCESS;
955 }
956
UnregisterDHStatusListener(const std::string & networkId,sptr<IHDSourceStatusListener> listener,int32_t callingUid,int32_t callingPid)957 int32_t ComponentManager::UnregisterDHStatusListener(
958 const std::string &networkId, sptr<IHDSourceStatusListener> listener, int32_t callingUid, int32_t callingPid)
959 {
960 std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
961
962 auto compTypes = ComponentLoader::GetInstance().GetAllCompTypes();
963 for (const auto &type : compTypes) {
964 auto &status = dhSourceStatus_[type];
965 DHStatusCtrlKey ctrlKey {
966 .uid = callingUid,
967 .pid = callingPid
968 };
969 auto &listeners = status.listeners;
970 auto it = listeners.find(ctrlKey);
971 if (it == listeners.end()) {
972 DHLOGE("Repeat call UnregisterDHStatusListener, uid = %{public}d, pid = %{public}d.",
973 ctrlKey.uid, ctrlKey.pid);
974 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
975 }
976 listeners.erase(it);
977 }
978
979 return DH_FWK_SUCCESS;
980 }
981
EnableSink(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)982 int32_t ComponentManager::EnableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
983 {
984 sptr<IHDSinkStatusListener> listener;
985 int32_t ret = EnableSinkInternal(dhDescriptor, callingUid, callingPid, listener);
986 if (ret == DH_FWK_SUCCESS) {
987 if (listener) {
988 listener->OnEnable(dhDescriptor);
989 DHLOGI("Callback business sink OnEnable.");
990 }
991 }
992 return ret;
993 }
994
DisableSink(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)995 int32_t ComponentManager::DisableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
996 {
997 sptr<IHDSinkStatusListener> listener;
998 int32_t ret = DisableSinkInternal(dhDescriptor, callingUid, callingPid, listener);
999 if (ret == DH_FWK_SUCCESS) {
1000 if (listener) {
1001 listener->OnDisable(dhDescriptor);
1002 DHLOGI("Callback business sink OnDisable.");
1003 }
1004 }
1005 return ret;
1006 }
1007
EnableSource(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)1008 int32_t ComponentManager::EnableSource(const std::string &networkId,
1009 const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
1010 {
1011 sptr<IHDSourceStatusListener> listener;
1012 int32_t ret = EnableSourceInternal(networkId, dhDescriptor, callingUid, callingPid, listener);
1013 if (ret == DH_FWK_SUCCESS) {
1014 if (listener) {
1015 listener->OnEnable(networkId, dhDescriptor);
1016 DHLOGI("Callback business source OnEnable.");
1017 }
1018 }
1019 return ret;
1020 }
1021
DisableSource(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid)1022 int32_t ComponentManager::DisableSource(const std::string &networkId,
1023 const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid)
1024 {
1025 sptr<IHDSourceStatusListener> listener;
1026 int32_t ret = DisableSourceInternal(networkId, dhDescriptor, callingUid, callingPid, listener);
1027 if (ret == DH_FWK_SUCCESS) {
1028 if (listener) {
1029 listener->OnDisable(networkId, dhDescriptor);
1030 DHLOGI("Callback business source OnDisable.");
1031 }
1032 }
1033 return ret;
1034 }
1035
ForceDisableSink(const DHDescriptor & dhDescriptor)1036 int32_t ComponentManager::ForceDisableSink(const DHDescriptor &dhDescriptor)
1037 {
1038 std::vector<sptr<IHDSinkStatusListener>> listeners;
1039 int32_t ret = ForceDisableSinkInternal(dhDescriptor, listeners);
1040 if (ret == DH_FWK_SUCCESS) {
1041 for (auto listener : listeners) {
1042 listener->OnDisable(dhDescriptor);
1043 DHLOGI("Callback business sink OnDisable.");
1044 }
1045 }
1046 return ret;
1047 }
1048
ForceDisableSource(const std::string & networkId,const DHDescriptor & dhDescriptor)1049 int32_t ComponentManager::ForceDisableSource(const std::string &networkId, const DHDescriptor &dhDescriptor)
1050 {
1051 std::vector<sptr<IHDSourceStatusListener>> listeners;
1052 int32_t ret = ForceDisableSourceInternal(networkId, dhDescriptor, listeners);
1053 if (ret == DH_FWK_SUCCESS) {
1054 for (auto listener : listeners) {
1055 listener->OnDisable(networkId, dhDescriptor);
1056 DHLOGI("Callback business source OnDisable.");
1057 }
1058 }
1059 return ret;
1060 }
1061
CheckIdenticalAccount(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor)1062 int32_t ComponentManager::CheckIdenticalAccount(const std::string &networkId,
1063 const std::string &uuid, const DHDescriptor &dhDescriptor)
1064 {
1065 EnableParam param;
1066 auto ret = GetEnableParam(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, param);
1067 if (ret != DH_FWK_SUCCESS) {
1068 DHLOGE("GetEnableParam failed, uuid = %{public}s, dhId = %{public}s, errCode = %{public}d",
1069 GetAnonyString(uuid).c_str(), GetAnonyString(dhDescriptor.id).c_str(), ret);
1070 if (ComponentManager::GetInstance().RetryGetEnableParam(
1071 networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, param) != DH_FWK_SUCCESS) {
1072 return ret;
1073 }
1074 }
1075 ret = CheckSubtypeResource(param.subtype, networkId);
1076 if (ret != DH_FWK_SUCCESS) {
1077 DHLOGE("CheckSubtypeResource failed, ret = %{public}d.", ret);
1078 return ret;
1079 }
1080 return DH_FWK_SUCCESS;
1081 }
1082
GetRemoteVerInfo(CompVersion & compVersion,const std::string & uuid,DHType dhType)1083 int32_t ComponentManager::GetRemoteVerInfo(CompVersion &compVersion, const std::string &uuid, DHType dhType)
1084 {
1085 MetaCapInfoMap metaInfoMap;
1086 auto ret = MetaInfoManager::GetInstance()->GetMetaDataByDHType(dhType, metaInfoMap);
1087 if (ret != DH_FWK_SUCCESS) {
1088 DHLOGE("GetMetaDataByDHType failed, uuid =%{public}s, dhType = %{public}#X, errCode = %{public}d.",
1089 GetAnonyString(uuid).c_str(), dhType, ret);
1090 return ret;
1091 }
1092 for (const auto &metaInfo : metaInfoMap) {
1093 if (DHContext::GetInstance().GetUUIDByDeviceId(metaInfo.second->GetDeviceId()) == uuid) {
1094 compVersion = metaInfo.second->GetCompVersion();
1095 return DH_FWK_SUCCESS;
1096 }
1097 }
1098 DHLOGE("The metaInfo corresponding to uuid was not found, uuid =%{public}s, dhType = %{public}#X.",
1099 GetAnonyString(uuid).c_str(), dhType);
1100 return ERR_DH_FWK_COMPONENT_COMPVERSION_NOT_FOUND;
1101 }
1102
IsFeatureMatched(const std::vector<std::string> & sourceFeatureFilters,const std::vector<std::string> & sinkSupportedFeatures)1103 bool ComponentManager::IsFeatureMatched(const std::vector<std::string> &sourceFeatureFilters,
1104 const std::vector<std::string> &sinkSupportedFeatures)
1105 {
1106 for (const auto &filter : sourceFeatureFilters) {
1107 for (const auto &feature : sinkSupportedFeatures) {
1108 if (feature == filter) {
1109 return true;
1110 }
1111 }
1112 }
1113 return false;
1114 }
1115
EnableSinkInternal(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSinkStatusListener> & listener)1116 int32_t ComponentManager::EnableSinkInternal(const DHDescriptor &dhDescriptor,
1117 int32_t callingUid, int32_t callingPid, sptr<IHDSinkStatusListener> &listener)
1118 {
1119 std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1120
1121 // Check if the input parameters and device type support it
1122 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1123 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1124 return ERR_DH_FWK_TYPE_NOT_EXIST;
1125 }
1126
1127 auto &status = dhSinkStatus_[dhDescriptor.dhType];
1128 auto &enableInfo = status.enableInfos[dhDescriptor.id];
1129
1130 // Check if the business is being called repeatedly
1131 DHStatusCtrlKey ctrlKey {
1132 .uid = callingUid,
1133 .pid = callingPid
1134 };
1135 auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1136 if (statusCtrl.enableState == EnableState::ENABLED) {
1137 DHLOGE("Repeat call EnableSink, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1138 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1139 }
1140
1141 // Get business enable status listener
1142 auto itrListener = status.listeners.find(ctrlKey);
1143 if (itrListener != status.listeners.end()) {
1144 listener = itrListener->second;
1145 }
1146
1147 // Check reference count
1148 if (enableInfo.refEnable || status.refLoad) {
1149 // Change status, we won't call back directly here because there is a lock
1150 statusCtrl.enableState = EnableState::ENABLED;
1151 enableInfo.refEnable++;
1152 status.refLoad++;
1153 return DH_FWK_SUCCESS;
1154 }
1155
1156 // Start enabling hardware sink
1157 auto ret = InitCompSink(dhDescriptor.dhType);
1158 if (ret != DH_FWK_SUCCESS) {
1159 DHLOGE("InitCompSink failed, ret = %{public}d.", ret);
1160 return ret;
1161 }
1162 auto sinkResult = StartSink(dhDescriptor.dhType);
1163 if (!WaitForResult(Action::START_SINK, sinkResult)) {
1164 DHLOGE("StartSink failed, some virtual components maybe cannot work, but want to continue!");
1165 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1166 "dhfwk start sink failed.");
1167 UninitCompSink(dhDescriptor.dhType);
1168 return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT;
1169 }
1170 // Change status, we won't call back directly here because there is a lock
1171 statusCtrl.enableState = EnableState::ENABLED;
1172 enableInfo.refEnable = 1;
1173 status.refLoad = 1;
1174 return DH_FWK_SUCCESS;
1175 }
1176
DisableSinkInternal(const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSinkStatusListener> & listener)1177 int32_t ComponentManager::DisableSinkInternal(const DHDescriptor &dhDescriptor,
1178 int32_t callingUid, int32_t callingPid, sptr<IHDSinkStatusListener> &listener)
1179 {
1180 std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1181
1182 // Check if the input parameters and device type support it
1183 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1184 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1185 return ERR_DH_FWK_TYPE_NOT_EXIST;
1186 }
1187
1188 auto &status = dhSinkStatus_[dhDescriptor.dhType];
1189 auto &enableInfo = status.enableInfos[dhDescriptor.id];
1190
1191 // Check if the business is being called repeatedly
1192 DHStatusCtrlKey ctrlKey {
1193 .uid = callingUid,
1194 .pid = callingPid
1195 };
1196 auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1197 if (statusCtrl.enableState == EnableState::DISABLED) {
1198 DHLOGE("Repeat call DisableSink, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1199 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1200 }
1201
1202 // Get business enable status listener
1203 auto itrListener = status.listeners.find(ctrlKey);
1204 if (itrListener != status.listeners.end()) {
1205 listener = itrListener->second;
1206 }
1207
1208 // Check reference count
1209 if (enableInfo.refEnable > 1 || status.refLoad > 1) {
1210 // Change status, we won't call back directly here because there is a lock
1211 statusCtrl.enableState = EnableState::DISABLED;
1212 enableInfo.refEnable--;
1213 status.refLoad--;
1214 return DH_FWK_SUCCESS;
1215 }
1216
1217 // Start disabling hardware sink
1218 auto sinkResult = StopSink(dhDescriptor.dhType);
1219 if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
1220 DHLOGE("StopSource failed, but want to continue!");
1221 return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1222 }
1223 auto ret = UninitCompSink(dhDescriptor.dhType);
1224 if (ret != DH_FWK_SUCCESS) {
1225 DHLOGE("UninitCompSink failed, ret = %{public}d.", ret);
1226 return ret;
1227 }
1228 // Change status, we won't call back directly here because there is a lock
1229 statusCtrl.enableState = EnableState::DISABLED;
1230 enableInfo.refEnable = 0;
1231 status.refLoad = 0;
1232 return DH_FWK_SUCCESS;
1233 }
1234
EnableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSourceStatusListener> & listener)1235 int32_t ComponentManager::EnableSourceInternal(const std::string &networkId,
1236 const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid, sptr<IHDSourceStatusListener> &listener)
1237 {
1238 // Check if the input parameters and device type support it
1239 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1240 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1241 return ERR_DH_FWK_TYPE_NOT_EXIST;
1242 }
1243
1244 DHStatusSourceEnableInfoKey enableInfoKey { .networkId = networkId, .dhId = dhDescriptor.id };
1245 DHStatusCtrlKey ctrlKey { .uid = callingUid, .pid = callingPid };
1246 auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1247
1248 std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1249
1250 auto &status = dhSourceStatus_[dhDescriptor.dhType];
1251 auto &enableInfo = status.enableInfos[enableInfoKey];
1252
1253 // Check if the business is being called repeatedly
1254 auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1255 if (statusCtrl.enableState == EnableState::ENABLED) {
1256 DHLOGE("Repeat call EnableSource, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1257 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1258 }
1259
1260 // Get business enable status listener
1261 auto itrListener = status.listeners.find(ctrlKey);
1262 if (itrListener != status.listeners.end()) {
1263 listener = itrListener->second;
1264 }
1265
1266 // Check enable reference count
1267 if (enableInfo.refEnable) {
1268 // Change status, we won't call back directly here because there is a lock
1269 statusCtrl.enableState = EnableState::ENABLED;
1270 enableInfo.refEnable++;
1271 status.refLoad++;
1272 return DH_FWK_SUCCESS;
1273 }
1274
1275 // Check load reference count
1276 if (status.refLoad) {
1277 auto ret = Enable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType,
1278 (callingUid != 0) || (callingPid != 0));
1279 if (ret != DH_FWK_SUCCESS) {
1280 DHLOGE("Enable failed, ret = %{public}d.", ret);
1281 return ret;
1282 }
1283 // Change status, we won't call back directly here because there is a lock
1284 statusCtrl.enableState = EnableState::ENABLED;
1285 enableInfo.refEnable++;
1286 status.refLoad++;
1287 return DH_FWK_SUCCESS;
1288 }
1289
1290 auto ret = RealEnableSource(networkId, uuid, dhDescriptor, statusCtrl, enableInfo, status,
1291 (callingUid != 0) || (callingPid != 0));
1292 if (ret != DH_FWK_SUCCESS) {
1293 DHLOGE("RealEnableSource failed, ret = %{public}d.", ret);
1294 return ret;
1295 }
1296
1297 return DH_FWK_SUCCESS;
1298 }
1299
DisableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,int32_t callingUid,int32_t callingPid,sptr<IHDSourceStatusListener> & listener)1300 int32_t ComponentManager::DisableSourceInternal(const std::string &networkId,
1301 const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid, sptr<IHDSourceStatusListener> &listener)
1302 {
1303 // Check if the input parameters and device type support it
1304 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1305 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1306 return ERR_DH_FWK_TYPE_NOT_EXIST;
1307 }
1308
1309 DHStatusSourceEnableInfoKey enableInfoKey {
1310 .networkId = networkId,
1311 .dhId = dhDescriptor.id
1312 };
1313 DHStatusCtrlKey ctrlKey {
1314 .uid = callingUid,
1315 .pid = callingPid
1316 };
1317 auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1318
1319 std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1320
1321 auto &status = dhSourceStatus_[dhDescriptor.dhType];
1322 auto &enableInfo = status.enableInfos[enableInfoKey];
1323
1324 // Check if the business is being called repeatedly
1325 auto &statusCtrl = enableInfo.dhStatusCtrl[ctrlKey];
1326 if (statusCtrl.enableState == EnableState::DISABLED) {
1327 DHLOGE("Repeat call DisableSource, uid = %{public}d, pid = %{public}d.", ctrlKey.uid, ctrlKey.pid);
1328 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1329 }
1330
1331 // Get business enable status listener
1332 auto itrListener = status.listeners.find(ctrlKey);
1333 if (itrListener != status.listeners.end()) {
1334 listener = itrListener->second;
1335 }
1336
1337 // Check enable reference count
1338 if (enableInfo.refEnable > 1) {
1339 // Change status, we won't call back directly here because there is a lock
1340 statusCtrl.enableState = EnableState::DISABLED;
1341 enableInfo.refEnable--;
1342 status.refLoad--;
1343 return DH_FWK_SUCCESS;
1344 }
1345
1346 // Check load reference count
1347 if (status.refLoad > 1) {
1348 auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1349 if (ret != DH_FWK_SUCCESS) {
1350 DHLOGE("Disable failed, ret = %{public}d.", ret);
1351 return ret;
1352 }
1353 // Change status, we won't call back directly here because there is a lock
1354 statusCtrl.enableState = EnableState::DISABLED;
1355 enableInfo.refEnable--;
1356 status.refLoad--;
1357 return DH_FWK_SUCCESS;
1358 }
1359
1360 auto ret = RealDisableSource(networkId, uuid, dhDescriptor, statusCtrl, enableInfo, status);
1361 if (ret != DH_FWK_SUCCESS) {
1362 DHLOGE("RealDisableSource failed, ret = %{public}d.", ret);
1363 return ret;
1364 }
1365
1366 return DH_FWK_SUCCESS;
1367 }
1368
ForceDisableSinkInternal(const DHDescriptor & dhDescriptor,std::vector<sptr<IHDSinkStatusListener>> & listeners)1369 int32_t ComponentManager::ForceDisableSinkInternal(
1370 const DHDescriptor &dhDescriptor, std::vector<sptr<IHDSinkStatusListener>> &listeners)
1371 {
1372 std::lock_guard<std::mutex> lock(dhSinkStatusMtx_);
1373
1374 // Check if the input parameters and device type support it
1375 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1376 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1377 return ERR_DH_FWK_TYPE_NOT_EXIST;
1378 }
1379
1380 auto &status = dhSinkStatus_[dhDescriptor.dhType];
1381 auto itEnableInfo = status.enableInfos.find(dhDescriptor.id);
1382 if (itEnableInfo == status.enableInfos.end()) {
1383 DHLOGE("Repeat call ForceDisableSink, dhType = %{public}u, id = %{public}s.",
1384 dhDescriptor.dhType, dhDescriptor.id.c_str());
1385 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1386 }
1387 auto &enableInfo = itEnableInfo->second;
1388
1389 // Collect listeners and reduce the load count
1390 for (auto &item : enableInfo.dhStatusCtrl) {
1391 if (item.second.enableState != EnableState::DISABLED) {
1392 auto it = status.listeners.find(item.first);
1393 if (it != status.listeners.end()) {
1394 auto listener = it->second;
1395 listeners.push_back(listener);
1396 }
1397 }
1398 }
1399 status.refLoad -= enableInfo.refEnable;
1400 status.enableInfos.erase(itEnableInfo);
1401 if (status.refLoad > 0) {
1402 return DH_FWK_SUCCESS;
1403 }
1404
1405 // Unload component
1406 auto sinkResult = StopSink(dhDescriptor.dhType);
1407 if (!WaitForResult(Action::STOP_SINK, sinkResult)) {
1408 DHLOGE("StopSource failed, but want to continue!");
1409 return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1410 }
1411 auto ret = UninitCompSink(dhDescriptor.dhType);
1412 if (ret != DH_FWK_SUCCESS) {
1413 DHLOGE("UninitCompSink failed, ret = %{public}d.", ret);
1414 return ret;
1415 }
1416 return DH_FWK_SUCCESS;
1417 }
1418
ForceDisableSourceInternal(const std::string & networkId,const DHDescriptor & dhDescriptor,std::vector<sptr<IHDSourceStatusListener>> & listeners)1419 int32_t ComponentManager::ForceDisableSourceInternal(const std::string &networkId,
1420 const DHDescriptor &dhDescriptor, std::vector<sptr<IHDSourceStatusListener>> &listeners)
1421 {
1422 std::lock_guard<std::mutex> lock(dhSourceStatusMtx_);
1423
1424 // Check if the input parameters and device type support it
1425 if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) {
1426 DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType);
1427 return ERR_DH_FWK_TYPE_NOT_EXIST;
1428 }
1429
1430 DHStatusSourceEnableInfoKey enableInfoKey {
1431 .networkId = networkId,
1432 .dhId = dhDescriptor.id
1433 };
1434 auto &status = dhSourceStatus_[dhDescriptor.dhType];
1435 auto itEnableInfo = status.enableInfos.find(enableInfoKey);
1436 if (itEnableInfo == status.enableInfos.end()) {
1437 DHLOGE("Repeat call ForceDisableSource, networkId = %{public}s, dhType = %{public}u, id = %{public}s.",
1438 GetAnonyString(networkId).c_str(), dhDescriptor.dhType, dhDescriptor.id.c_str());
1439 return ERR_DH_FWK_COMPONENT_REPEAT_CALL;
1440 }
1441 auto &enableInfo = itEnableInfo->second;
1442
1443 // First, disable the hardware
1444 auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId);
1445 auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1446 if (ret != DH_FWK_SUCCESS) {
1447 DHLOGE("Disable failed, ret = %{public}d.", ret);
1448 return ret;
1449 }
1450
1451 // Then collect listeners and reduce the load count
1452 for (auto &item : enableInfo.dhStatusCtrl) {
1453 if (item.second.enableState != EnableState::DISABLED) {
1454 auto it = status.listeners.find(item.first);
1455 if (it != status.listeners.end()) {
1456 auto listener = it->second;
1457 listeners.push_back(listener);
1458 }
1459 }
1460 }
1461 status.refLoad -= enableInfo.refEnable;
1462 status.enableInfos.erase(itEnableInfo);
1463 if (status.refLoad > 0) {
1464 return DH_FWK_SUCCESS;
1465 }
1466
1467 // Unload component
1468 auto sourceResult = StopSource(dhDescriptor.dhType);
1469 if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
1470 DHLOGE("StopSource timeout!");
1471 return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1472 }
1473 ret = UninitCompSource(dhDescriptor.dhType);
1474 if (ret != DH_FWK_SUCCESS) {
1475 DHLOGE("UninitCompSource failed, ret = %{public}d.", ret);
1476 return ret;
1477 }
1478 return DH_FWK_SUCCESS;
1479 }
1480
RealEnableSource(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status,bool isActive)1481 int32_t ComponentManager::RealEnableSource(const std::string &networkId, const std::string &uuid,
1482 const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl,
1483 DHStatusEnableInfo &enableInfo, DHSourceStatus &status, bool isActive)
1484 {
1485 auto ret = InitCompSource(dhDescriptor.dhType);
1486 if (ret != DH_FWK_SUCCESS) {
1487 DHLOGE("InitCompSource failed, ret = %{public}d.", ret);
1488 return ret;
1489 }
1490 auto sourceResult = StartSource(dhDescriptor.dhType);
1491 if (!WaitForResult(Action::START_SOURCE, sourceResult)) {
1492 DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue!");
1493 HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
1494 "dhfwk start source failed.");
1495 UninitCompSource(dhDescriptor.dhType);
1496 return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT;
1497 }
1498 ret = Enable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType, isActive);
1499 if (ret != DH_FWK_SUCCESS) {
1500 DHLOGE("Enable failed, ret = %{public}d.", ret);
1501 StopSource(dhDescriptor.dhType);
1502 UninitCompSource(dhDescriptor.dhType);
1503 return ret;
1504 }
1505 // Change status, we won't call back directly here because there is a lock
1506 statusCtrl.enableState = EnableState::ENABLED;
1507 enableInfo.refEnable = 1;
1508 status.refLoad = 1;
1509 return ret;
1510 }
1511
RealDisableSource(const std::string & networkId,const std::string & uuid,const DHDescriptor & dhDescriptor,DHStatusCtrl & statusCtrl,DHStatusEnableInfo & enableInfo,DHSourceStatus & status)1512 int32_t ComponentManager::RealDisableSource(const std::string &networkId, const std::string &uuid,
1513 const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl,
1514 DHStatusEnableInfo &enableInfo, DHSourceStatus &status)
1515 {
1516 auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType);
1517 if (ret != DH_FWK_SUCCESS) {
1518 DHLOGE("Disable failed, ret = %{public}d.", ret);
1519 return ret;
1520 }
1521 auto sourceResult = StopSource(dhDescriptor.dhType);
1522 if (!WaitForResult(Action::STOP_SOURCE, sourceResult)) {
1523 DHLOGE("StopSource timeout!");
1524 return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT;
1525 }
1526 ret = UninitCompSource(dhDescriptor.dhType);
1527 if (ret != DH_FWK_SUCCESS) {
1528 DHLOGE("UninitCompSource failed, ret = %{public}d.", ret);
1529 return ret;
1530 }
1531 // Change status, we won't call back directly here because there is a lock
1532 statusCtrl.enableState = EnableState::DISABLED;
1533 enableInfo.refEnable = 0;
1534 status.refLoad = 0;
1535 return DH_FWK_SUCCESS;
1536 }
1537
InitCompSource(DHType dhType)1538 int32_t ComponentManager::InitCompSource(DHType dhType)
1539 {
1540 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
1541 IDistributedHardwareSource *sourcePtr = nullptr;
1542 auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr);
1543 if (ret != DH_FWK_SUCCESS) {
1544 DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1545 return ret;
1546 }
1547 if (sourcePtr == nullptr) {
1548 DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType);
1549 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1550 }
1551 compSource_.insert(std::make_pair(dhType, sourcePtr));
1552 auto saId = ComponentLoader::GetInstance().GetSourceSaId(dhType);
1553 if (saId != INVALID_SA_ID) {
1554 compSrcSaId_.insert(std::make_pair(dhType, saId));
1555 if (compMonitorPtr_ == nullptr) {
1556 DHLOGE("compMonitorPtr_ is null.");
1557 return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
1558 }
1559 compMonitorPtr_->AddSAMonitor(saId);
1560 } else {
1561 DHLOGE("GetSourceSaId return INVALID_SA_ID, compType = %{public}#X.", dhType);
1562 }
1563 sourcePtr->RegisterDistributedHardwareStateListener(dhStateListener_);
1564 sourcePtr->RegisterDataSyncTriggerListener(dataSyncTriggerListener_);
1565 return DH_FWK_SUCCESS;
1566 }
1567
UninitCompSource(DHType dhType)1568 int32_t ComponentManager::UninitCompSource(DHType dhType)
1569 {
1570 std::unique_lock<std::shared_mutex> lock(compSourceMutex_);
1571 IDistributedHardwareSource *sourcePtr = nullptr;
1572 auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr);
1573 if (ret != DH_FWK_SUCCESS) {
1574 DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1575 return ret;
1576 }
1577 if (sourcePtr == nullptr) {
1578 DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType);
1579 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1580 }
1581 sourcePtr->UnregisterDataSyncTriggerListener();
1582 sourcePtr->UnregisterDistributedHardwareStateListener();
1583 auto it = compSrcSaId_.find(dhType);
1584 if (it != compSrcSaId_.end()) {
1585 if (compMonitorPtr_ == nullptr) {
1586 DHLOGE("compMonitorPtr_ is null.");
1587 return ERR_DH_FWK_COMPONENT_MONITOR_NULL;
1588 }
1589 compMonitorPtr_->RemoveSAMonitor(it->second);
1590 compSrcSaId_.erase(it);
1591 }
1592 ret = ComponentLoader::GetInstance().ReleaseSource(dhType);
1593 if (ret != DH_FWK_SUCCESS) {
1594 DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1595 return ret;
1596 }
1597 compSource_.erase(dhType);
1598 return DH_FWK_SUCCESS;
1599 }
1600
InitCompSink(DHType dhType)1601 int32_t ComponentManager::InitCompSink(DHType dhType)
1602 {
1603 std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
1604 IDistributedHardwareSink *sinkPtr = nullptr;
1605 auto ret = ComponentLoader::GetInstance().GetSink(dhType, sinkPtr);
1606 if (ret != DH_FWK_SUCCESS) {
1607 DHLOGE("GetSink failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1608 return ret;
1609 }
1610 if (sinkPtr == nullptr) {
1611 DHLOGE("sinkPtr is null, compType = %{public}#X.", dhType);
1612 return ERR_DH_FWK_LOADER_HANDLER_IS_NULL;
1613 }
1614 compSink_.insert(std::make_pair(dhType, sinkPtr));
1615 return DH_FWK_SUCCESS;
1616 }
1617
UninitCompSink(DHType dhType)1618 int32_t ComponentManager::UninitCompSink(DHType dhType)
1619 {
1620 std::unique_lock<std::shared_mutex> lock(compSinkMutex_);
1621 auto ret = ComponentLoader::GetInstance().ReleaseSink(dhType);
1622 if (ret != DH_FWK_SUCCESS) {
1623 DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret);
1624 return ret;
1625 }
1626 compSink_.erase(dhType);
1627 return DH_FWK_SUCCESS;
1628 }
1629
StopSource(DHType dhType)1630 ActionResult ComponentManager::StopSource(DHType dhType)
1631 {
1632 std::shared_lock<std::shared_mutex> lock(compSourceMutex_);
1633 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
1634 if (compSource_.find(dhType) == compSource_.end()) {
1635 DHLOGE("Component for DHType: %{public}" PRIu32 " not init source handler.", (uint32_t)dhType);
1636 return futures;
1637 }
1638 auto sourcePtr = compSource_[dhType];
1639 if (sourcePtr == nullptr) {
1640 DHLOGE("comp source ptr is null.");
1641 return futures;
1642 }
1643 std::promise<int32_t> p;
1644 std::future<int32_t> f = p.get_future();
1645 std::thread([p = std::move(p), sourcePtr] () mutable {
1646 p.set_value(sourcePtr->ReleaseSource());
1647 }).detach();
1648 futures.emplace(dhType, f.share());
1649 return futures;
1650 }
1651
StopSink(DHType dhType)1652 ActionResult ComponentManager::StopSink(DHType dhType)
1653 {
1654 std::shared_lock<std::shared_mutex> lock(compSinkMutex_);
1655 std::unordered_map<DHType, std::shared_future<int32_t>> futures;
1656 if (compSink_.find(dhType) == compSink_.end()) {
1657 DHLOGE("Component for DHType: %{public}" PRIu32 " not init sink handler.", (uint32_t)dhType);
1658 return futures;
1659 }
1660 auto sinkPtr = compSink_[dhType];
1661 if (sinkPtr == nullptr) {
1662 DHLOGE("comp sink ptr is null.");
1663 return futures;
1664 }
1665 std::promise<int32_t> p;
1666 std::future<int32_t> f = p.get_future();
1667 std::thread([p = std::move(p), sinkPtr, dhType] () mutable {
1668 p.set_value(sinkPtr->ReleaseSink());
1669 IHardwareHandler *hardwareHandler = nullptr;
1670 int32_t status = ComponentLoader::GetInstance().GetHardwareHandler(dhType, hardwareHandler);
1671 if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) {
1672 DHLOGE("GetHardwareHandler %{public}#X failed.", dhType);
1673 return status;
1674 }
1675 hardwareHandler->UnRegisterPluginListener();
1676 return status;
1677 }).detach();
1678 futures.emplace(dhType, f.share());
1679 return futures;
1680 }
1681 } // namespace DistributedHardware
1682 } // namespace OHOS
1683