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 "local_capability_info_manager.h"
42 #include "meta_info_manager.h"
43
44 namespace OHOS {
45 namespace DistributedHardware {
46 namespace {
47 constexpr int32_t OLD_HO_DEVICE_TYPE = -1;
48 constexpr int32_t NEW_HO_DEVICE_TYPE = 11;
49 }
50 #undef DH_LOG_TAG
51 #define DH_LOG_TAG "DistributedHardwareManagerFactory"
52
53 IMPLEMENT_SINGLE_INSTANCE(DistributedHardwareManagerFactory);
InitLocalDevInfo()54 bool DistributedHardwareManagerFactory::InitLocalDevInfo()
55 {
56 DHLOGI("InitLocalDevInfo start");
57 std::vector<DmDeviceInfo> deviceList;
58 DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
59 if (deviceList.size() > 0 && deviceList.size() <= MAX_ONLINE_DEVICE_SIZE) {
60 DHLOGI("There is other device online, on need just init db, use normal logic");
61 return true;
62 }
63 auto initResult = DistributedHardwareManager::GetInstance().LocalInit();
64 if (initResult != DH_FWK_SUCCESS) {
65 DHLOGE("InitLocalDevInfo failed, errCode = %{public}d", initResult);
66 return false;
67 }
68 DHLOGI("InitLocalDevInfo success, check is need exit");
69
70 deviceList.clear();
71 DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
72 if ((deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) &&
73 DHContext::GetInstance().GetIsomerismConnectCount() == 0) {
74 DHLOGI("After InitLocalDevInfo, no device online, exit dhfwk");
75 ExitDHFWK();
76 }
77 return true;
78 }
79
Init()80 bool DistributedHardwareManagerFactory::Init()
81 {
82 DHLOGI("start");
83 auto initResult = DistributedHardwareManager::GetInstance().Initialize();
84 if (initResult != DH_FWK_SUCCESS) {
85 DHLOGE("Initialize failed, errCode = %{public}d", initResult);
86 return false;
87 }
88 isInit_.store(true);
89 releaseStatus_.store(false);
90 DHLOGI("success");
91 return true;
92 }
93
UnInit()94 void DistributedHardwareManagerFactory::UnInit()
95 {
96 DHLOGI("start");
97 std::lock_guard<std::mutex> lock(releaseProcessMutex_);
98 if (releaseStatus_.load()) {
99 DHLOGE("Releasing resources is complete, not need to be released again.");
100 return;
101 }
102 releaseStatus_.store(true);
103 DHTraceStart(COMPONENT_UNLOAD_START);
104 HiSysEventWriteMsg(DHFWK_EXIT_BEGIN, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
105 "dhfwk sa exit begin.");
106
107 // release all the resources synchronously
108 DistributedHardwareManager::GetInstance().Release();
109 isInit_.store(false);
110 flagUnInit_.store(false);
111 DHTraceEnd();
112 CheckExitSAOrNot();
113 }
114
ExitDHFWK()115 void DistributedHardwareManagerFactory::ExitDHFWK()
116 {
117 DHLOGI("No device online or deviceList is over size, exit sa process");
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 ExitDHFWK();
140 return;
141 }
142
143 DHLOGI("After uninit, DM report devices online, reinit");
144 Init();
145 for (const auto &deviceInfo : deviceList) {
146 const auto networkId = std::string(deviceInfo.networkId);
147 const auto uuid = GetUUIDByDm(networkId);
148 const auto udid = GetUDIDByDm(networkId);
149 DHLOGI("Send trusted device online, networkId = %{public}s, uuid = %{public}s",
150 GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str());
151 uint16_t deviceType = deviceInfo.deviceTypeId;
152 int32_t osType = GetDeviceSystemType(deviceInfo.extraData);
153 std::thread([this, networkId, uuid, udid, deviceType, osType]() {
154 this->SendOnLineEvent(networkId, uuid, udid, deviceType, osType);
155 }).detach();
156 }
157 }
158
IsInit()159 bool DistributedHardwareManagerFactory::IsInit()
160 {
161 return isInit_.load();
162 }
163
SendOnLineEvent(const std::string & networkId,const std::string & uuid,const std::string & udid,uint16_t deviceType,int32_t osType)164 int32_t DistributedHardwareManagerFactory::SendOnLineEvent(const std::string &networkId, const std::string &uuid,
165 const std::string &udid, uint16_t deviceType, int32_t osType)
166 {
167 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(udid)) {
168 return ERR_DH_FWK_PARA_INVALID;
169 }
170 int32_t ret = pthread_setname_np(pthread_self(), SEND_ONLINE);
171 if (ret != DH_FWK_SUCCESS) {
172 DHLOGE("SendOnLineEvent setname failed.");
173 }
174
175 if (flagUnInit_.load()) {
176 DHLOGE("is in uniniting, can not process online event.");
177 return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
178 }
179
180 if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
181 DHLOGW("device is already online, uuid = %{public}s", GetAnonyString(uuid).c_str());
182 return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_ONLINE;
183 }
184
185 DHContext::GetInstance().AddOnlineDevice(udid, uuid, networkId);
186 DHContext::GetInstance().AddRealTimeOnlineDeviceNetworkId(networkId);
187
188 if (!isInit_.load() && !Init()) {
189 DHLOGE("distributedHardwareMgr is null");
190 return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
191 }
192
193 if (DeviceParamMgr::GetInstance().IsDeviceE2ESync()) {
194 DHLOGI("e2e device, need initiative sync data.");
195 MetaInfoManager::GetInstance()->SyncDataByNetworkId(networkId);
196 }
197
198 if (osType == OLD_HO_DEVICE_TYPE || osType == NEW_HO_DEVICE_TYPE) {
199 DHLOGE("double frame device, networkId = %{public}s, uuid = %{public}s, udid = %{public}s, need clear data.",
200 GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str(), GetAnonyString(udid).c_str());
201 ClearRemoteDeviceMetaInfoData(udid, uuid);
202 ClearRemoteDeviceLocalInfoData(uuid);
203 }
204 auto onlineResult = DistributedHardwareManager::GetInstance().SendOnLineEvent(networkId, uuid, udid, deviceType);
205 if (onlineResult != DH_FWK_SUCCESS) {
206 DHLOGE("online failed, errCode = %{public}d", onlineResult);
207 return onlineResult;
208 }
209 return DH_FWK_SUCCESS;
210 }
211
SendOffLineEvent(const std::string & networkId,const std::string & uuid,const std::string & udid,uint16_t deviceType)212 int32_t DistributedHardwareManagerFactory::SendOffLineEvent(const std::string &networkId, const std::string &uuid,
213 const std::string &udid, uint16_t deviceType)
214 {
215 if (!IsIdLengthValid(networkId) || !IsIdLengthValid(uuid) || !IsIdLengthValid(udid)) {
216 return ERR_DH_FWK_PARA_INVALID;
217 }
218 if (!isInit_.load() && !Init()) {
219 DHLOGE("distributedHardwareMgr is null");
220 return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
221 }
222
223 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
224 DHLOGE("Device not online, networkId: %{public}s, uuid: %{public}s",
225 GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str());
226 return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_OFFLINE;
227 }
228
229 DHContext::GetInstance().DeleteRealTimeOnlineDeviceNetworkId(networkId);
230 if (DHContext::GetInstance().GetRealTimeOnlineDeviceCount() == 0 &&
231 DHContext::GetInstance().GetIsomerismConnectCount() == 0) {
232 flagUnInit_.store(true);
233 DHLOGI("no online device, set uninit flag true");
234 }
235
236 auto offlineResult = DistributedHardwareManager::GetInstance().SendOffLineEvent(networkId, uuid, udid, deviceType);
237 if (offlineResult != DH_FWK_SUCCESS) {
238 DHLOGE("offline failed, errCode = %{public}d", offlineResult);
239 }
240 return DH_FWK_SUCCESS;
241 }
242
GetComponentVersion(std::unordered_map<DHType,std::string> & versionMap)243 int32_t DistributedHardwareManagerFactory::GetComponentVersion(std::unordered_map<DHType, std::string> &versionMap)
244 {
245 DHLOGI("start");
246 return DistributedHardwareManager::GetInstance().GetComponentVersion(versionMap);
247 }
248
Dump(const std::vector<std::string> & argsStr,std::string & result)249 int32_t DistributedHardwareManagerFactory::Dump(const std::vector<std::string> &argsStr, std::string &result)
250 {
251 return DistributedHardwareManager::GetInstance().Dump(argsStr, result);
252 }
253
GetUnInitFlag()254 bool DistributedHardwareManagerFactory::GetUnInitFlag()
255 {
256 return flagUnInit_.load();
257 }
258
ClearRemoteDeviceMetaInfoData(const std::string & peerudid,const std::string & peeruuid)259 void DistributedHardwareManagerFactory::ClearRemoteDeviceMetaInfoData(const std::string &peerudid,
260 const std::string &peeruuid)
261 {
262 MetaInfoManager::GetInstance()->ClearRemoteDeviceMetaInfoData(peerudid, peeruuid);
263 }
264
ClearRemoteDeviceLocalInfoData(const std::string & peeruuid)265 void DistributedHardwareManagerFactory::ClearRemoteDeviceLocalInfoData(const std::string &peeruuid)
266 {
267 LocalCapabilityInfoManager::GetInstance()->ClearRemoteDeviceLocalInfoData(peeruuid);
268 }
269 } // namespace DistributedHardware
270 } // namespace OHOS
271