1 /*
2 * Copyright (c) 2021-2023 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 "dm_device_info.h"
26
27 #include "anonymous_string.h"
28 #include "constants.h"
29 #include "device_manager.h"
30 #include "dh_context.h"
31 #include "dh_utils_hisysevent.h"
32 #include "dh_utils_hitrace.h"
33 #include "dh_utils_tool.h"
34 #include "distributed_hardware_errno.h"
35 #include "distributed_hardware_log.h"
36 #include "distributed_hardware_manager.h"
37 #include "iservice_registry.h"
38 #include "system_ability_definition.h"
39
40 namespace OHOS {
41 namespace DistributedHardware {
42 #undef DH_LOG_TAG
43 #define DH_LOG_TAG "DistributedHardwareManagerFactory"
44
45 IMPLEMENT_SINGLE_INSTANCE(DistributedHardwareManagerFactory);
Init()46 bool DistributedHardwareManagerFactory::Init()
47 {
48 DHLOGI("start");
49 isInit = true;
50 auto initResult = DistributedHardwareManager::GetInstance().Initialize();
51 if (initResult != DH_FWK_SUCCESS) {
52 DHLOGE("Initialize failed, errCode = %d", initResult);
53 return false;
54 }
55 DHLOGD("success");
56 return true;
57 }
58
UnInit()59 void DistributedHardwareManagerFactory::UnInit()
60 {
61 DHLOGI("start");
62 DHTraceStart(COMPONENT_UNLOAD_START);
63 HiSysEventWriteMsg(DHFWK_EXIT_BEGIN, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
64 "dhfwk sa exit begin.");
65
66 // release all the resources synchronously
67 DistributedHardwareManager::GetInstance().Release();
68 isInit = false;
69 DHTraceEnd();
70 CheckExitSAOrNot();
71 }
72
CheckExitSAOrNot()73 void DistributedHardwareManagerFactory::CheckExitSAOrNot()
74 {
75 std::vector<DmDeviceInfo> deviceList;
76 DeviceManager::GetInstance().GetTrustedDeviceList(DH_FWK_PKG_NAME, "", deviceList);
77 if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
78 DHLOGI("DM report devices offline or deviceList is over size, exit sa process");
79 HiSysEventWriteMsg(DHFWK_EXIT_END, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
80 "dhfwk sa exit end.");
81
82 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83 if (systemAbilityMgr == nullptr) {
84 DHLOGE("systemAbilityMgr is null");
85 return;
86 }
87 int32_t ret = systemAbilityMgr->UnloadSystemAbility(DISTRIBUTED_HARDWARE_SA_ID);
88 if (ret != DH_FWK_SUCCESS) {
89 DHLOGE("systemAbilityMgr UnLoadSystemAbility failed, ret: %d", ret);
90 return;
91 }
92 DHLOGI("systemAbilityMgr UnLoadSystemAbility success");
93 return;
94 }
95
96 DHLOGI("After uninit, DM report devices online, reinit");
97 Init();
98 for (const auto &deviceInfo : deviceList) {
99 const auto networkId = std::string(deviceInfo.networkId);
100 const auto uuid = GetUUIDBySoftBus(networkId);
101 DHLOGI("Send trusted device online, networkId = %s, uuid = %s", GetAnonyString(networkId).c_str(),
102 GetAnonyString(uuid).c_str());
103 std::thread(&DistributedHardwareManagerFactory::SendOnLineEvent, this, networkId, uuid,
104 deviceInfo.deviceTypeId).detach();
105 }
106 }
107
IsInit()108 bool DistributedHardwareManagerFactory::IsInit()
109 {
110 return isInit.load();
111 }
112
SendOnLineEvent(const std::string & networkId,const std::string & uuid,uint16_t deviceType)113 int32_t DistributedHardwareManagerFactory::SendOnLineEvent(const std::string &networkId, const std::string &uuid,
114 uint16_t deviceType)
115 {
116 int32_t ret = pthread_setname_np(pthread_self(), SEND_ONLINE);
117 if (ret != DH_FWK_SUCCESS) {
118 DHLOGE("SendOnLineEvent setname failed.");
119 }
120 if (networkId.size() == 0 || networkId.size() > MAX_ID_LEN || uuid.size() == 0 || uuid.size() > MAX_ID_LEN) {
121 DHLOGE("NetworkId or uuid is invalid");
122 return ERR_DH_FWK_PARA_INVALID;
123 }
124
125 if (DHContext::GetInstance().IsDeviceOnline(uuid)) {
126 DHLOGW("device is already online, uuid = %s", GetAnonyString(uuid).c_str());
127 return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_ONLINE;
128 }
129
130 DHContext::GetInstance().AddOnlineDevice(uuid, networkId);
131
132 if (!isInit && !Init()) {
133 DHLOGE("distributedHardwareMgr is null");
134 return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
135 }
136
137 auto onlineResult = DistributedHardwareManager::GetInstance().SendOnLineEvent(networkId, uuid, deviceType);
138 if (onlineResult != DH_FWK_SUCCESS) {
139 DHLOGE("online failed, errCode = %d", onlineResult);
140 return onlineResult;
141 }
142 return DH_FWK_SUCCESS;
143 }
144
SendOffLineEvent(const std::string & networkId,const std::string & uuid,uint16_t deviceType)145 int32_t DistributedHardwareManagerFactory::SendOffLineEvent(const std::string &networkId, const std::string &uuid,
146 uint16_t deviceType)
147 {
148 if (networkId.empty() || networkId.size() > MAX_ID_LEN || uuid.empty() || uuid.size() > MAX_ID_LEN) {
149 DHLOGE("NetworkId or uuid is invalid");
150 return ERR_DH_FWK_PARA_INVALID;
151 }
152
153 if (!isInit && !Init()) {
154 DHLOGE("distributedHardwareMgr is null");
155 return ERR_DH_FWK_HARDWARE_MANAGER_INIT_FAILED;
156 }
157
158 if (!DHContext::GetInstance().IsDeviceOnline(uuid)) {
159 DHLOGE("Device not online, networkId: %s, uuid: %s",
160 GetAnonyString(networkId).c_str(), GetAnonyString(uuid).c_str());
161 return ERR_DH_FWK_HARDWARE_MANAGER_DEVICE_REPEAT_OFFLINE;
162 }
163
164 auto offlineResult = DistributedHardwareManager::GetInstance().SendOffLineEvent(networkId, uuid, deviceType);
165 if (offlineResult != DH_FWK_SUCCESS) {
166 DHLOGE("offline failed, errCode = %d", offlineResult);
167 return offlineResult;
168 }
169
170 DHContext::GetInstance().RemoveOnlineDevice(uuid);
171 if (DistributedHardwareManager::GetInstance().GetOnLineCount() == 0) {
172 DHLOGI("all devices are offline, start to free the resource");
173 UnInit();
174 }
175 return DH_FWK_SUCCESS;
176 }
177
GetComponentVersion(std::unordered_map<DHType,std::string> & versionMap)178 int32_t DistributedHardwareManagerFactory::GetComponentVersion(std::unordered_map<DHType, std::string> &versionMap)
179 {
180 DHLOGI("start");
181 return DistributedHardwareManager::GetInstance().GetComponentVersion(versionMap);
182 }
183
Dump(const std::vector<std::string> & argsStr,std::string & result)184 int32_t DistributedHardwareManagerFactory::Dump(const std::vector<std::string> &argsStr, std::string &result)
185 {
186 return DistributedHardwareManager::GetInstance().Dump(argsStr, result);
187 }
188 } // namespace DistributedHardware
189 } // namespace OHOS
190