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