diff --git a/common/utils/include/dhardware_descriptor.h b/common/utils/include/dhardware_descriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..8ead0889c41dc7e320a06cdabc91f2b1a86ed816 --- /dev/null +++ b/common/utils/include/dhardware_descriptor.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_HARDWARE_DESCRIPTOR_H +#define OHOS_DISTRIBUTED_HARDWARE_DESCRIPTOR_H + +#include +#include + +#include "device_type.h" + +namespace OHOS { +namespace DistributedHardware { + +struct DHDescriptor { + std::string id; + DHType dhType; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_HARDWARE_DESCRIPTOR_H diff --git a/common/utils/include/distributed_hardware_errno.h b/common/utils/include/distributed_hardware_errno.h index a2894d5d0231f16abcbc92fae5aca1ff8000768b..c3d4069aa56f5ac6b7602984f56505a876139a66 100644 --- a/common/utils/include/distributed_hardware_errno.h +++ b/common/utils/include/distributed_hardware_errno.h @@ -49,6 +49,8 @@ namespace DistributedHardware { constexpr int32_t ERR_DH_FWK_COMPONENT_MONITOR_NULL = -10011; constexpr int32_t ERR_DH_FWK_COMPONENT_TRANSPORT_OPT_FAILED = -10012; constexpr int32_t ERR_DH_FWK_COMPONENT_GET_ENABLE_PARAM_FAILED = -10013; + constexpr int32_t ERR_DH_FWK_COMPONENT_LIMIT_DEMAND_START = -10014; + constexpr int32_t ERR_DH_FWK_COMPONENT_REPEAT_CALL = -10015; /* ResourceManager errno, range: [-10400, -10499] */ constexpr int32_t ERR_DH_FWK_RESOURCE_DB_ADAPTER_POINTER_NULL = -10400; @@ -79,6 +81,12 @@ namespace DistributedHardware { constexpr int32_t ERR_DH_FWK_LOADER_GET_LOCAL_VERSION_FAIL = -10602; constexpr int32_t ERR_DH_FWK_LOADER_DLCLOSE_FAIL = -10603; constexpr int32_t ERR_DH_FWK_LOADER_PROFILE_PATH_IS_NULL = -10604; + constexpr int32_t ERR_DH_FWK_LOADER_SINK_IS_LOADED = -10605; + constexpr int32_t ERR_DH_FWK_LOADER_SOURCE_IS_LOADED = -10606; + constexpr int32_t ERR_DH_FWK_LOADER_HANDLER_IS_LOADED = -10607; + constexpr int32_t ERR_DH_FWK_LOADER_SINK_NOT_LOADED = -10608; + constexpr int32_t ERR_DH_FWK_LOADER_SOURCE_NOT_LOADED = -10609; + constexpr int32_t ERR_DH_FWK_LOADER_HANDLER_NOT_LOADED = -10610; /* Task errno, range: [-10700, -10799] */ constexpr int32_t ERR_DH_FWK_TASK_TIMEOUT = -10700; diff --git a/common/utils/include/idistributed_hardware.h b/common/utils/include/idistributed_hardware.h index f7390e53ddedeee9c1432880d110ad6dbb1869e3..e0f406c385bc402354fd94dfac532e11c174e899 100644 --- a/common/utils/include/idistributed_hardware.h +++ b/common/utils/include/idistributed_hardware.h @@ -22,6 +22,8 @@ #include "iremote_broker.h" #include "device_type.h" +#include "dhardware_descriptor.h" +#include "ihardware_status_listener.h" #include "distributed_hardware_fwk_kit_paras.h" #include "iav_trans_control_center_callback.h" diff --git a/common/utils/include/ihardware_status_listener.h b/common/utils/include/ihardware_status_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..17e355ebe7985863696c340c998e41871f037a11 --- /dev/null +++ b/common/utils/include/ihardware_status_listener.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_IHARDWARE_STATUS_LISTENER_H +#define OHOS_IHARDWARE_STATUS_LISTENER_H + +#include +#include + +#include + +#include "dhardware_descriptor.h" + +namespace OHOS { +namespace DistributedHardware { +class IHDSinkStatusListener : public IRemoteBroker { +public: + virtual void OnEnable(const DHDescriptor &dhDescriptor) = 0; + virtual void OnDisable(const DHDescriptor &dhDescriptor) = 0; + + enum class Message : uint32_t { + ON_ENABLE, + ON_DISABLE + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.DistributedHardware.DistributedHardwareFwk.IHDSinkStatusListener"); +}; + +class IHDSourceStatusListener : public IRemoteBroker { +public: + virtual void OnEnable(const std::string &networkId, const DHDescriptor &dhDescriptor) = 0; + virtual void OnDisable(const std::string &networkId, const DHDescriptor &dhDescriptor) = 0; + + enum class Message : uint32_t { + ON_ENABLE, + ON_DISABLE + }; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.DistributedHardware.DistributedHardwareFwk.IHDSourceStatusListener"); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_IHARDWARE_STATUS_LISTENER_H \ No newline at end of file diff --git a/services/distributedhardwarefwkservice/include/componentloader/component_loader.h b/services/distributedhardwarefwkservice/include/componentloader/component_loader.h index bc5315e7d6b9caf236d99317466f1ee465850546..6009f2a8a309e0b9ded2d1339a10395563aca8b9 100644 --- a/services/distributedhardwarefwkservice/include/componentloader/component_loader.h +++ b/services/distributedhardwarefwkservice/include/componentloader/component_loader.h @@ -84,6 +84,7 @@ public: int32_t GetSourceSaId(const DHType dhType); DHType GetDHTypeBySrcSaId(const int32_t saId); std::map GetCompResourceDesc(); + bool IsDHTypeSupport(DHType dhType); private: void *GetHandler(const std::string &soName); diff --git a/services/distributedhardwarefwkservice/include/componentmanager/component_manager.h b/services/distributedhardwarefwkservice/include/componentmanager/component_manager.h index 4a7ee0a973fb8d4032e1f1578099f33fcdded43b..6af28617afeb9a75e0b83552bc4c21bdb814e2ab 100644 --- a/services/distributedhardwarefwkservice/include/componentmanager/component_manager.h +++ b/services/distributedhardwarefwkservice/include/componentmanager/component_manager.h @@ -79,6 +79,22 @@ public: */ bool FetchNeedRefreshTask(const std::pair &taskKey, TaskParam &taskParam); + int32_t CheckDemandStart(const std::string &uuid, const DHType dhType, bool &enableSink, bool &enableSource); + int32_t RegisterDHStatusListener(sptr listener, int32_t callingUid, int32_t callingPid); + int32_t UnregisterDHStatusListener(sptr listener, int32_t callingUid, int32_t callingPid); + int32_t RegisterDHStatusListener(const std::string &networkId, + sptr listener, int32_t callingUid, int32_t callingPid); + int32_t UnregisterDHStatusListener(const std::string &networkId, + sptr listener, int32_t callingUid, int32_t callingPid); + int32_t EnableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid); + int32_t DisableSink(const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid); + int32_t EnableSource(const std::string &networkId, + const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid); + int32_t DisableSource(const std::string &networkId, + const DHDescriptor &dhDescriptor, int32_t callingUid, int32_t callingPid); + int32_t ForceDisableSink(const DHDescriptor &dhDescriptor); + int32_t ForceDisableSource(const std::string &networkId, const DHDescriptor &dhDescriptor); + class ComponentManagerEventHandler : public AppExecFwk::EventHandler { public: ComponentManagerEventHandler(const std::shared_ptr runner); @@ -95,15 +111,101 @@ private: STOP_SINK }; + enum class EnableState : int32_t { + DISABLED, + ENABLED + }; + + struct DHStatusCtrlKey { + int32_t uid; + int32_t pid; + + bool operator == (const DHStatusCtrlKey &other) const + { + return (uid == other.uid) && (pid == other.pid); + } + + bool operator < (const DHStatusCtrlKey &other) const + { + if (uid < other.uid) { + return true; + } else if (uid > other.uid) { + return false; + } + return pid < other.pid; + } + }; + + struct DHStatusCtrl { + EnableState enableState; + DHStatusCtrl() + { + enableState = EnableState::DISABLED; + } + }; + + struct DHStatusEnableInfo { + int32_t refEnable; + std::map dhStatusCtrl; + DHStatusEnableInfo() + { + refEnable = 0; + } + }; + + struct DHStatusSourceEnableInfoKey { + std::string networkId; + std::string dhId; + bool operator == (const DHStatusSourceEnableInfoKey &other) const + { + return (networkId == other.networkId) && (dhId == other.dhId); + } + bool operator < (const DHStatusSourceEnableInfoKey &other) const + { + if (networkId < other.networkId) { + return true; + } else if (networkId > other.networkId) { + return false; + } + return dhId < other.dhId; + } + }; + + struct DHSinkStatus { + int32_t refLoad; + std::map enableInfos; + std::map> listeners; + DHSinkStatus() + { + refLoad = 0; + } + }; + + struct DHSourceStatus { + int32_t refLoad; + std::map enableInfos; + std::map> listeners; + DHSourceStatus() + { + refLoad = 0; + } + }; + DHType GetDHType(const std::string &uuid, const std::string &dhId) const; bool InitCompSource(); + int32_t InitCompSource(DHType dhType); + int32_t UninitCompSource(DHType dhType); bool InitCompSink(); + int32_t InitCompSink(DHType dhType); + int32_t UninitCompSink(DHType dhType); ActionResult StartSource(); ActionResult StartSource(DHType dhType); ActionResult StopSource(); + ActionResult StopSource(DHType dhType); ActionResult StartSink(); ActionResult StartSink(DHType dhType); ActionResult StopSink(); + ActionResult StopSink(DHType dhType); bool WaitForResult(const Action &action, ActionResult result); int32_t GetEnableParam(const std::string &networkId, const std::string &uuid, const std::string &dhId, DHType dhType, EnableParam ¶m); @@ -140,6 +242,26 @@ private: std::shared_ptr &metaCapPtr); int32_t CheckSubtypeResource(const std::string &subtype, const std::string &networkId); + int32_t GetRemoteVerInfo(VersionInfo &versionInfo, const std::string &uuid, DHType dhType); + bool IsFeatureMatched(const std::vector &sourceFeatureFilters, + const std::vector &sinkSupportedFeatures); + int32_t EnableSinkInternal(const DHDescriptor &dhDescriptor, + int32_t callingUid, int32_t callingPid, sptr &listener); + int32_t DisableSinkInternal(const DHDescriptor &dhDescriptor, + int32_t callingUid, int32_t callingPid, sptr &listener); + int32_t EnableSourceInternal(const std::string &networkId, const DHDescriptor &dhDescriptor, + int32_t callingUid, int32_t callingPid, sptr &listener); + int32_t DisableSourceInternal(const std::string &networkId, const DHDescriptor &dhDescriptor, + int32_t callingUid, int32_t callingPid, sptr &listener); + int32_t ForceDisableSinkInternal( + const DHDescriptor &dhDescriptor, std::vector> &listeners); + int32_t ForceDisableSourceInternal(const std::string &networkId, + const DHDescriptor &dhDescriptor, std::vector> &listeners); + int32_t RealEnableSource(const std::string &networkId, const std::string &uuid, const DHDescriptor &dhDescriptor, + DHStatusCtrl &statusCtrl, DHStatusEnableInfo &enableInfo, DHSourceStatus &status); + int32_t RealDisableSource(const std::string &networkId, const std::string &uuid, const DHDescriptor &dhDescriptor, + DHStatusCtrl &statusCtrl, DHStatusEnableInfo &enableInfo, DHSourceStatus &status); + private: std::map compSource_; std::shared_mutex compSourceMutex_; @@ -164,6 +286,12 @@ private: // save those remote dh that need refresh by full capability, {{device networkId, dhId}, TaskParam}. std::map, TaskParam> needRefreshTaskParams_; std::mutex needRefreshTaskParamsMtx_; + + // distributed hardware enable status maintenance. + std::map dhSinkStatus_; + std::mutex dhSinkStatusMtx_; + std::map dhSourceStatus_; + std::mutex dhSourceStatusMtx_; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/distributedhardwarefwkservice/include/utils/impl_utils.h b/services/distributedhardwarefwkservice/include/utils/impl_utils.h index b3b5a18b08397c92db13463225401e2de029c3de..51bd6ce116b3a2dbb3ae248b96cfe963dcc9a1cf 100644 --- a/services/distributedhardwarefwkservice/include/utils/impl_utils.h +++ b/services/distributedhardwarefwkservice/include/utils/impl_utils.h @@ -60,6 +60,9 @@ struct CompVersion { std::string handlerVersion; std::string sourceVersion; std::string sinkVersion; + bool haveFeature; + std::vector sourceFeatureFilters; + std::vector sinkSupportedFeatures; }; struct DHVersion { diff --git a/services/distributedhardwarefwkservice/src/componentloader/component_loader.cpp b/services/distributedhardwarefwkservice/src/componentloader/component_loader.cpp index ed54b9c8c4c0057e48b81d5e049e4436238c341e..c8e686bc35da4d9eb07c1d381626ad67305b1502 100644 --- a/services/distributedhardwarefwkservice/src/componentloader/component_loader.cpp +++ b/services/distributedhardwarefwkservice/src/componentloader/component_loader.cpp @@ -675,5 +675,10 @@ std::map ComponentLoader::GetCompResourceDesc() { return resDescMap_; } + +bool ComponentLoader::IsDHTypeSupport(DHType dhType) +{ + return IsDHTypeExist(dhType); +} } // namespace DistributedHardware } // namespace OHOS diff --git a/services/distributedhardwarefwkservice/src/componentmanager/component_manager.cpp b/services/distributedhardwarefwkservice/src/componentmanager/component_manager.cpp index aaf3d25703a53ea346181fcd097d7fe96cb40616..6a4c88071ed804a4494921d19824640d691db721 100644 --- a/services/distributedhardwarefwkservice/src/componentmanager/component_manager.cpp +++ b/services/distributedhardwarefwkservice/src/componentmanager/component_manager.cpp @@ -64,6 +64,8 @@ namespace { constexpr int32_t ENABLE_PARAM_RETRY_TIME = 500 * 1000; constexpr int32_t INVALID_SA_ID = -1; constexpr int32_t UNINIT_COMPONENT_TIMEOUT_SECONDS = 2; + constexpr int32_t SYNC_DEVICE_INFO_TIMEOUT_MILLISECONDS = 2000; + constexpr int32_t SYNC_DEVICE_INFO_INTERVAL_MILLISECONDS = 200; const std::string MONITOR_TASK_TIMER_ID = "monitor_task_timer_id"; } @@ -1138,5 +1140,306 @@ std::shared_ptr ComponentManager return this->eventHandler_; } +int32_t ComponentManager::ForceDisableSinkInternal( + const DHDescriptor &dhDescriptor, std::vector> &listeners) +{ + std::lock_guard lock(dhSinkStatusMtx_); + + // Check if the input parameters and device type support it + if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) { + DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType); + return ERR_DH_FWK_TYPE_NOT_EXIST; + } + + auto &status = dhSinkStatus_[dhDescriptor.dhType]; + auto itEnableInfo = status.enableInfos.find(dhDescriptor.id); + if (itEnableInfo == status.enableInfos.end()) { + DHLOGE("Repeat call ForceDisableSink, dhType = %{public}u, id = %{public}s.", + dhDescriptor.dhType, dhDescriptor.id.c_str()); + return ERR_DH_FWK_COMPONENT_REPEAT_CALL; + } + auto &enableInfo = itEnableInfo->second; + + // Collect listeners and reduce the load count + for (auto &item : enableInfo.dhStatusCtrl) { + if (item.second.enableState != EnableState::DISABLED) { + auto it = status.listeners.find(item.first); + if (it != status.listeners.end()) { + auto listener = it->second; + listeners.push_back(listener); + } + } + } + status.refLoad -= enableInfo.refEnable; + status.enableInfos.erase(itEnableInfo); + if (status.refLoad > 0) { + return DH_FWK_SUCCESS; + } + + // Unload component + auto sinkResult = StopSink(dhDescriptor.dhType); + if (!WaitForResult(Action::STOP_SINK, sinkResult)) { + DHLOGE("StopSource failed, but want to continue!"); + return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT; + } + auto ret = UninitCompSink(dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("UninitCompSink failed, ret = %{public}d.", ret); + return ret; + } + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::ForceDisableSourceInternal(const std::string &networkId, + const DHDescriptor &dhDescriptor, std::vector> &listeners) +{ + std::lock_guard lock(dhSourceStatusMtx_); + + // Check if the input parameters and device type support it + if (!ComponentLoader::GetInstance().IsDHTypeSupport(dhDescriptor.dhType)) { + DHLOGE("Not support dhType: %{public}#X!", dhDescriptor.dhType); + return ERR_DH_FWK_TYPE_NOT_EXIST; + } + + DHStatusSourceEnableInfoKey enableInfoKey { + .networkId = networkId, + .dhId = dhDescriptor.id + }; + auto &status = dhSourceStatus_[dhDescriptor.dhType]; + auto itEnableInfo = status.enableInfos.find(enableInfoKey); + if (itEnableInfo == status.enableInfos.end()) { + DHLOGE("Repeat call ForceDisableSource, networkId = %{public}s, dhType = %{public}u, id = %{public}s.", + GetAnonyString(networkId).c_str(), dhDescriptor.dhType, dhDescriptor.id.c_str()); + return ERR_DH_FWK_COMPONENT_REPEAT_CALL; + } + auto &enableInfo = itEnableInfo->second; + + // First, disable the hardware + auto uuid = DHContext::GetInstance().GetUUIDByNetworkId(networkId); + auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("Disable failed, ret = %{public}d.", ret); + return ret; + } + + // Then collect listeners and reduce the load count + for (auto &item : enableInfo.dhStatusCtrl) { + if (item.second.enableState != EnableState::DISABLED) { + auto it = status.listeners.find(item.first); + if (it != status.listeners.end()) { + auto listener = it->second; + listeners.push_back(listener); + } + } + } + status.refLoad -= enableInfo.refEnable; + status.enableInfos.erase(itEnableInfo); + if (status.refLoad > 0) { + return DH_FWK_SUCCESS; + } + + // Unload component + auto sinkResult = StopSource(dhDescriptor.dhType); + if (!WaitForResult(Action::STOP_SINK, sinkResult)) { + DHLOGE("StopSource timeout!"); + return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT; + } + ret = UninitCompSource(dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("UninitCompSource failed, ret = %{public}d.", ret); + return ret; + } + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::RealEnableSource(const std::string &networkId, const std::string &uuid, + const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl, + DHStatusEnableInfo &enableInfo, DHSourceStatus &status) +{ + auto ret = InitCompSource(dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("InitCompSource failed, ret = %{public}d.", ret); + return ret; + } + auto sourceResult = StartSource(dhDescriptor.dhType); + if (!WaitForResult(Action::START_SOURCE, sourceResult)) { + DHLOGE("StartSource failed, some virtual components maybe cannot work, but want to continue!"); + HiSysEventWriteMsg(DHFWK_INIT_FAIL, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, + "dhfwk start source failed."); + UninitCompSource(dhDescriptor.dhType); + return ERR_DH_FWK_COMPONENT_ENABLE_TIMEOUT; + } + ret = Enable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("Enable failed, ret = %{public}d.", ret); + StopSource(dhDescriptor.dhType); + UninitCompSource(dhDescriptor.dhType); + return ret; + } + // Change status, we won't call back directly here because there is a lock + statusCtrl.enableState = EnableState::ENABLED; + enableInfo.refEnable = 1; + status.refLoad = 1; + return ret; +} + +int32_t ComponentManager::RealDisableSource(const std::string &networkId, const std::string &uuid, + const DHDescriptor &dhDescriptor, DHStatusCtrl &statusCtrl, + DHStatusEnableInfo &enableInfo, DHSourceStatus &status) +{ + auto ret = Disable(networkId, uuid, dhDescriptor.id, dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("Disable failed, ret = %{public}d.", ret); + return ret; + } + auto sinkResult = StopSource(dhDescriptor.dhType); + if (!WaitForResult(Action::STOP_SINK, sinkResult)) { + DHLOGE("StopSource timeout!"); + return ERR_DH_FWK_COMPONENT_DISABLE_TIMEOUT; + } + ret = UninitCompSource(dhDescriptor.dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("UninitCompSource failed, ret = %{public}d.", ret); + return ret; + } + // Change status, we won't call back directly here because there is a lock + statusCtrl.enableState = EnableState::DISABLED; + enableInfo.refEnable = 0; + status.refLoad = 0; + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::InitCompSource(DHType dhType) +{ + std::unique_lock lock(compSourceMutex_); + IDistributedHardwareSource *sourcePtr = nullptr; + auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret); + return ret; + } + if (sourcePtr == nullptr) { + DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType); + return ERR_DH_FWK_LOADER_HANDLER_IS_NULL; + } + compSource_.insert(std::make_pair(dhType, sourcePtr)); + auto saId = ComponentLoader::GetInstance().GetSourceSaId(dhType); + if (saId != INVALID_SA_ID) { + compSrcSaId_.insert(std::make_pair(dhType, saId)); + compMonitorPtr_->AddSAMonitor(saId); + } else { + DHLOGE("GetSourceSaId return INVALID_SA_ID, compType = %{public}#X.", dhType); + } + sourcePtr->RegisterDistributedHardwareStateListener(dhStateListener_); + sourcePtr->RegisterDataSyncTriggerListener(dataSyncTriggerListener_); + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::UninitCompSource(DHType dhType) +{ + std::unique_lock lock(compSourceMutex_); + IDistributedHardwareSource *sourcePtr = nullptr; + auto ret = ComponentLoader::GetInstance().GetSource(dhType, sourcePtr); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret); + return ret; + } + if (sourcePtr == nullptr) { + DHLOGE("sourcePtr is null, compType = %{public}#X.", dhType); + return ERR_DH_FWK_LOADER_HANDLER_IS_NULL; + } + sourcePtr->UnregisterDataSyncTriggerListener(); + sourcePtr->UnregisterDistributedHardwareStateListener(); + compMonitorPtr_->RemoveSAMonitor(compSrcSaId_.at(dhType)); + ret = ComponentLoader::GetInstance().ReleaseSource(dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret); + return ret; + } + compSrcSaId_.erase(dhType); + compSource_.erase(dhType); + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::InitCompSink(DHType dhType) +{ + std::unique_lock lock(compSinkMutex_); + IDistributedHardwareSink *sinkPtr = nullptr; + auto ret = ComponentLoader::GetInstance().GetSink(dhType, sinkPtr); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("GetSink failed, compType = %{public}#X, ret = %{public}d.", dhType, ret); + return ret; + } + if (sinkPtr == nullptr) { + DHLOGE("sinkPtr is null, compType = %{public}#X.", dhType); + return ERR_DH_FWK_LOADER_HANDLER_IS_NULL; + } + compSink_.insert(std::make_pair(dhType, sinkPtr)); + return DH_FWK_SUCCESS; +} + +int32_t ComponentManager::UninitCompSink(DHType dhType) +{ + std::unique_lock lock(compSinkMutex_); + auto ret = ComponentLoader::GetInstance().ReleaseSink(dhType); + if (ret != DH_FWK_SUCCESS) { + DHLOGE("GetSource failed, compType = %{public}#X, ret = %{public}d.", dhType, ret); + return ret; + } + compSink_.erase(dhType); + return DH_FWK_SUCCESS; +} + +ActionResult ComponentManager::StopSource(DHType dhType) +{ + std::shared_lock lock(compSourceMutex_); + std::unordered_map> futures; + if (compSource_.find(dhType) == compSource_.end()) { + DHLOGE("Component for DHType: %{public}" PRIu32 " not init source handler.", (uint32_t)dhType); + return futures; + } + auto sourcePtr = compSource_[dhType]; + if (sourcePtr == nullptr) { + DHLOGE("comp source ptr is null."); + return futures; + } + std::promise p; + std::future f = p.get_future(); + std::thread([p = std::move(p), sourcePtr] () mutable { + p.set_value(sourcePtr->ReleaseSource()); + }).detach(); + futures.emplace(dhType, f.share()); + return futures; +} + +ActionResult ComponentManager::StopSink(DHType dhType) +{ + std::shared_lock lock(compSinkMutex_); + std::unordered_map> futures; + if (compSink_.find(dhType) == compSink_.end()) { + DHLOGE("Component for DHType: %{public}" PRIu32 " not init sink handler.", (uint32_t)dhType); + return futures; + } + auto sinkPtr = compSink_[dhType]; + if (sinkPtr == nullptr) { + DHLOGE("comp sink ptr is null."); + return futures; + } + std::promise p; + std::future f = p.get_future(); + std::thread([p = std::move(p), sinkPtr, dhType] () mutable { + p.set_value(sinkPtr->ReleaseSink()); + IHardwareHandler *hardwareHandler = nullptr; + int32_t status = ComponentLoader::GetInstance().GetHardwareHandler(dhType, hardwareHandler); + if (status != DH_FWK_SUCCESS || hardwareHandler == nullptr) { + DHLOGE("GetHardwareHandler %{public}#X failed.", dhType); + return status; + } + hardwareHandler->UnRegisterPluginListener(); + return status; + }).detach(); + futures.emplace(dhType, f.share()); + return futures; +} } // namespace DistributedHardware } // namespace OHOS