• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "distributed_hardware_manager_factory.h"
17 
18 #include <cstdlib>
19 #include <dlfcn.h>
20 #include <pthread.h>
21 #include <string>
22 #include <thread>
23 #include <vector>
24 
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 
28 #include "dm_device_info.h"
29 #include "device_manager.h"
30 
31 #include "anonymous_string.h"
32 #include "constants.h"
33 #include "dh_context.h"
34 #include "dh_utils_hisysevent.h"
35 #include "dh_utils_hitrace.h"
36 #include "dh_utils_tool.h"
37 #include "distributed_hardware_errno.h"
38 #include "distributed_hardware_log.h"
39 #include "distributed_hardware_manager.h"
40 #include "device_param_mgr.h"
41 #include "hdf_operate.h"
42 #include "local_capability_info_manager.h"
43 #include "meta_info_manager.h"
44 #include "task_board.h"
45 #include "task_executor.h"
46 #include "task_factory.h"
47 
48 namespace OHOS {
49 namespace DistributedHardware {
50 namespace {
51     constexpr int32_t OLD_HO_DEVICE_TYPE = -1;
52     constexpr int32_t NEW_HO_DEVICE_TYPE = 11;
53 }
54 #undef DH_LOG_TAG
55 #define DH_LOG_TAG "DistributedHardwareManagerFactory"
56 
57 IMPLEMENT_SINGLE_INSTANCE(DistributedHardwareManagerFactory);
InitLocalDevInfo()58 bool DistributedHardwareManagerFactory::InitLocalDevInfo()
59 {
60     DHLOGI("InitLocalDevInfo start");
61     std::vector<DmDeviceInfo> deviceList;
62     DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
63     if (deviceList.size() > 0 && deviceList.size() <= MAX_ONLINE_DEVICE_SIZE) {
64         DHLOGI("There is other device online, on need just init db, use normal logic");
65         return true;
66     }
67     auto initResult = DistributedHardwareManager::GetInstance().LocalInit();
68     if (initResult != DH_FWK_SUCCESS) {
69         DHLOGE("InitLocalDevInfo failed, errCode = %{public}d", initResult);
70         return false;
71     }
72     DHLOGI("init local dev info, create exit dfwk task!");
73     TaskParam taskParam;
74     auto task = TaskFactory::GetInstance().CreateTask(TaskType::EXIT_DFWK, taskParam, nullptr);
75     TaskExecutor::GetInstance().PushTask(task);
76     return true;
77 }
78 
Init()79 bool DistributedHardwareManagerFactory::Init()
80 {
81     DHLOGI("start");
82     auto initResult = DistributedHardwareManager::GetInstance().Initialize();
83     if (initResult != DH_FWK_SUCCESS) {
84         DHLOGE("Initialize failed, errCode = %{public}d", initResult);
85         return false;
86     }
87     isInit_.store(true);
88     releaseStatus_.store(false);
89     DHLOGI("success");
90     return true;
91 }
92 
UnInit()93 void DistributedHardwareManagerFactory::UnInit()
94 {
95     DHLOGI("start");
96     std::lock_guard<std::mutex> lock(releaseProcessMutex_);
97     if (releaseStatus_.load()) {
98         DHLOGE("Releasing resources is complete, not need to be released again.");
99         return;
100     }
101     releaseStatus_.store(true);
102     DHTraceStart(COMPONENT_UNLOAD_START);
103     HiSysEventWriteMsg(DHFWK_EXIT_BEGIN, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
104         "dhfwk sa exit begin.");
105 
106     // release all the resources synchronously
107     DistributedHardwareManager::GetInstance().Release();
108     isInit_.store(false);
109     flagUnInit_.store(false);
110     DHTraceEnd();
111     CheckExitSAOrNot();
112 }
113 
ExitDHFWK()114 void DistributedHardwareManagerFactory::ExitDHFWK()
115 {
116     DHLOGI("No device online or deviceList is over size, exit sa process");
117     SetSAProcessState(true);
118     HiSysEventWriteMsg(DHFWK_EXIT_END, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
119         "dhfwk sa exit end.");
120     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
121     if (systemAbilityMgr == nullptr) {
122         DHLOGE("systemAbilityMgr is null");
123         return;
124     }
125     int32_t ret = systemAbilityMgr->UnloadSystemAbility(DISTRIBUTED_HARDWARE_SA_ID);
126     if (ret != DH_FWK_SUCCESS) {
127         DHLOGE("systemAbilityMgr UnLoadSystemAbility failed, ret: %{public}d", ret);
128         return;
129     }
130     DHLOGI("systemAbilityMgr UnLoadSystemAbility success");
131 }
132 
CheckExitSAOrNot()133 void DistributedHardwareManagerFactory::CheckExitSAOrNot()
134 {
135     std::vector<DmDeviceInfo> deviceList;
136     DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
137     if ((deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) &&
138         DHContext::GetInstance().GetIsomerismConnectCount() == 0 &&
139         HdfOperateManager::GetInstance().IsAnyHdfInuse() == false) {
140         ExitDHFWK();
141         return;
142     }
143 
144     DHLOGI("After uninit, DM report devices online, reinit");
145     Init();
146     for (const auto &deviceInfo : deviceList) {
147         const auto networkId = std::string(deviceInfo.networkId);
148         const auto uuid = GetUUIDByDm(networkId);
149         const auto udid = GetUDIDByDm(networkId);
150         DHLOGI("Send trusted device online, networkId = %{public}s, uuid = %{public}s",
151             GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str());
152         uint16_t deviceType = deviceInfo.deviceTypeId;
153         int32_t osType = GetDeviceSystemType(deviceInfo.extraData);
154         std::thread([this, networkId, uuid, udid, deviceType, osType]() {
155             this->SendOnLineEvent(networkId, uuid, udid, deviceType, osType);
156         }).detach();
157     }
158 }
159 
IsInit()160 bool DistributedHardwareManagerFactory::IsInit()
161 {
162     return isInit_.load();
163 }
164 
SendOnLineEvent(const std::string & networkId,const std::string & uuid,const std::string & udid,uint16_t deviceType,int32_t osType)165 int32_t DistributedHardwareManagerFactory::SendOnLineEvent(const std::string &networkId, const std::string &uuid,
166     const std::string &udid, uint16_t deviceType, int32_t osType)
167 {
168     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(udid)) {
169         return ERR_DH_FWK_PARA_INVALID;
170     }
171     int32_t ret = pthread_setname_np(pthread_self(), SEND_ONLINE);
172     if (ret != DH_FWK_SUCCESS) {
173         DHLOGE("SendOnLineEvent setname failed.");
174     }
175 
176     if (flagUnInit_.load()) {
177         DHLOGE("is in uniniting, can not process online event.");
178         return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
179     }
180 
181     if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
182         DHLOGW("device is already online, uuid = %{public}s", GetAnonyString(uuid).c_str());
183         return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_ONLINE;
184     }
185 
186     DHContext::GetInstance().AddOnlineDevice(udid, uuid, networkId);
187     DHContext::GetInstance().AddRealTimeOnlineDeviceNetworkId(networkId);
188     DHContext::GetInstance().AddOnlineDeviceType(networkId, deviceType);
189 
190     if (!isInit_.load() && !Init()) {
191         DHLOGE("distributedHardwareMgr is null");
192         return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
193     }
194 
195     if (DeviceParamMgr::GetInstance().IsDeviceE2ESync()) {
196         if (osType != OLD_HO_DEVICE_TYPE && osType != NEW_HO_DEVICE_TYPE) {
197             DHLOGI("local device is e2e device and remote is single frame device, need initiative sync data.");
198             MetaInfoManager::GetInstance()->SyncDataByNetworkId(networkId);
199         }
200     }
201 
202     if (osType == OLD_HO_DEVICE_TYPE || osType == NEW_HO_DEVICE_TYPE) {
203         DHLOGE("double frame device, networkId = %{public}s, uuid = %{public}s, udid = %{public}s, need clear data.",
204             GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(udid).c_str());
205         ClearRemoteDeviceMetaInfoData(udid, uuid);
206         ClearRemoteDeviceLocalInfoData(uuid);
207     }
208     auto onlineResult = DistributedHardwareManager::GetInstance().SendOnLineEvent(networkId, uuid, udid, deviceType);
209     if (onlineResult != DH_FWK_SUCCESS) {
210         DHLOGE("online failed, errCode = %{public}d", onlineResult);
211         return onlineResult;
212     }
213     return DH_FWK_SUCCESS;
214 }
215 
SendOffLineEvent(const std::string & networkId,const std::string & uuid,const std::string & udid,uint16_t deviceType)216 int32_t DistributedHardwareManagerFactory::SendOffLineEvent(const std::string &networkId, const std::string &uuid,
217     const std::string &udid, uint16_t deviceType)
218 {
219     if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(udid)) {
220         return ERR_DH_FWK_PARA_INVALID;
221     }
222     if (!isInit_.load() && !Init()) {
223         DHLOGE("distributedHardwareMgr is null");
224         return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
225     }
226 
227     if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
228         DHLOGE("Device not online, networkId: %{public}s, uuid: %{public}s",
229             GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str());
230         return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_OFFLINE;
231     }
232 
233     DHContext::GetInstance().DeleteRealTimeOnlineDeviceNetworkId(networkId);
234     if (DHContext::GetInstance().GetRealTimeOnlineDeviceCount() == 0 &&
235         DHContext::GetInstance().GetIsomerismConnectCount() == 0) {
236         flagUnInit_.store(true);
237         DHLOGI("no online device, set uninit flag true");
238     }
239 
240     auto offlineResult = DistributedHardwareManager::GetInstance().SendOffLineEvent(networkId, uuid, udid, deviceType);
241     if (offlineResult != DH_FWK_SUCCESS) {
242         DHLOGE("offline failed, errCode = %{public}d", offlineResult);
243     }
244     return DH_FWK_SUCCESS;
245 }
246 
GetComponentVersion(std::unordered_map<DHType,std::string> & versionMap)247 int32_t DistributedHardwareManagerFactory::GetComponentVersion(std::unordered_map<DHType, std::string> &versionMap)
248 {
249     DHLOGI("start");
250     return DistributedHardwareManager::GetInstance().GetComponentVersion(versionMap);
251 }
252 
Dump(const std::vector<std::string> & argsStr,std::string & result)253 int32_t DistributedHardwareManagerFactory::Dump(const std::vector<std::string> &argsStr, std::string &result)
254 {
255     return DistributedHardwareManager::GetInstance().Dump(argsStr, result);
256 }
257 
GetUnInitFlag()258 bool DistributedHardwareManagerFactory::GetUnInitFlag()
259 {
260     return flagUnInit_.load();
261 }
262 
ClearRemoteDeviceMetaInfoData(const std::string & peerudid,const std::string & peeruuid)263 void DistributedHardwareManagerFactory::ClearRemoteDeviceMetaInfoData(const std::string &peerudid,
264     const std::string &peeruuid)
265 {
266     MetaInfoManager::GetInstance()->ClearRemoteDeviceMetaInfoData(peerudid, peeruuid);
267 }
268 
ClearRemoteDeviceLocalInfoData(const std::string & peeruuid)269 void DistributedHardwareManagerFactory::ClearRemoteDeviceLocalInfoData(const std::string &peeruuid)
270 {
271     LocalCapabilityInfoManager::GetInstance()->ClearRemoteDeviceLocalInfoData(peeruuid);
272 }
273 
SetSAProcessState(bool saState)274 void DistributedHardwareManagerFactory::SetSAProcessState(bool saState)
275 {
276     DHLOGI("Set SA process state: %{public}d", saState);
277     isIdle_.store(saState);
278 }
279 
GetSAProcessState()280 bool DistributedHardwareManagerFactory::GetSAProcessState()
281 {
282     return isIdle_.load();
283 }
284 } // namespace DistributedHardware
285 } // namespace OHOS
286