1 /*
2 * Copyright (c) 2021-2024 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 "dtbschedmgr_device_info_storage.h"
17
18 #include <chrono>
19 #include <thread>
20
21 #include "distributed_device_node_listener.h"
22 #include "distributed_sched_service.h"
23 #include "dtbschedmgr_log.h"
24 #include "ipc_object_proxy.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28
29 using namespace std;
30 namespace OHOS {
31 namespace DistributedSchedule {
32 using namespace std::chrono_literals;
33 using namespace DistributedHardware;
34
35 namespace {
36 constexpr int32_t RETRY_TIMES = 30;
37 constexpr int32_t CONNECT_SOFTBUS_RETRY_TIMES = 60;
38 const std::string TAG = "DtbschedmgrDeviceInfoStorage";
39 }
40
41 IMPLEMENT_SINGLE_INSTANCE(DtbschedmgrDeviceInfoStorage);
42
Init()43 bool DtbschedmgrDeviceInfoStorage::Init()
44 {
45 if (initHandler_ == nullptr) {
46 auto deviceInfoStorageRunner = AppExecFwk::EventRunner::Create("DmsDeviceInfoStorageManager");
47 initHandler_ = std::make_shared<AppExecFwk::EventHandler>(deviceInfoStorageRunner);
48 }
49
50 auto func = [this]() {
51 HILOGI("begin connect softbus");
52 for (int32_t retryTimes = 0; retryTimes <= CONNECT_SOFTBUS_RETRY_TIMES; retryTimes++) {
53 if (ConnectSoftbus()) {
54 return;
55 }
56 HILOGE("retry connect softbus %{public}d times", retryTimes);
57 std::this_thread::sleep_for(1s);
58 }
59 HILOGE("connect softbus 60times * 30s, error!!");
60 };
61 if (!initHandler_->PostTask(func)) {
62 HILOGE("Init handler postTask failed");
63 return false;
64 }
65 return true;
66 }
67
ConnectSoftbus()68 bool DtbschedmgrDeviceInfoStorage::ConnectSoftbus()
69 {
70 ClearAllDevices();
71 bool isReady = WaitForDnetworkReady();
72 if (!isReady) {
73 HILOGE("ConnectSoftbus wait Dnetwork failed!");
74 return false;
75 }
76 std::shared_ptr<DnetworkAdapter> dnetworkAdapter = DnetworkAdapter::GetInstance();
77 if (dnetworkAdapter == nullptr) {
78 HILOGE("DnetworkAdapter::GetInstance() null");
79 return false;
80 }
81 if (!InitNetworkIdManager(dnetworkAdapter)) {
82 HILOGE("InitNetworkIdManager failed");
83 return false;
84 }
85 HILOGI("ConnectSoftbus success");
86 return true;
87 }
88
InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)89 bool DtbschedmgrDeviceInfoStorage::InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)
90 {
91 if (networkIdMgrHandler_ == nullptr) {
92 auto runner = AppExecFwk::EventRunner::Create("DmsNetworkIdManager");
93 networkIdMgrHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
94 }
95
96 deviceNodeListener_ = std::make_shared<DistributedDeviceNodeListener>();
97 if (!dnetworkAdapter->AddDeviceChangeListener(deviceNodeListener_)) {
98 deviceNodeListener_ = nullptr;
99 HILOGE("AddDeviceChangeListener failed!");
100 return false;
101 }
102 return true;
103 }
104
Stop()105 void DtbschedmgrDeviceInfoStorage::Stop()
106 {
107 ClearAllDevices();
108 if (deviceNodeListener_ != nullptr) {
109 DnetworkAdapter::GetInstance()->RemoveDeviceChangeListener(deviceNodeListener_);
110 deviceNodeListener_ = nullptr;
111 }
112 }
113
WaitForDnetworkReady()114 bool DtbschedmgrDeviceInfoStorage::WaitForDnetworkReady()
115 {
116 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
117 if (samgr == nullptr) {
118 HILOGE("WaitForDnetworkReady failed to get samgr!");
119 return false;
120 }
121 int32_t retryTimeout = RETRY_TIMES;
122 do {
123 auto dnetwork = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
124 if (dnetwork != nullptr) {
125 IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(dnetwork.GetRefPtr());
126 // make sure the proxy is not dead
127 if (proxy != nullptr && !proxy->IsObjectDead()) {
128 return true;
129 }
130 }
131 HILOGI("Waiting for dnentwork service...");
132 std::this_thread::sleep_for(1s);
133 if (--retryTimeout <= 0) {
134 HILOGI("Waiting for dnentwork service timeout(30)s");
135 return false;
136 }
137 } while (true);
138 return false;
139 }
140
RegisterUuidNetworkIdMap(const std::string & networkId)141 void DtbschedmgrDeviceInfoStorage::RegisterUuidNetworkIdMap(const std::string& networkId)
142 {
143 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
144 if (uuid.empty()) {
145 HILOGE("GetUuidByNetworkId return an empty uuid!");
146 return;
147 }
148 {
149 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
150 uuidNetworkIdMap_[uuid] = networkId;
151 }
152 }
153
UnregisterUuidNetworkIdMap(const std::string & networkId)154 void DtbschedmgrDeviceInfoStorage::UnregisterUuidNetworkIdMap(const std::string& networkId)
155 {
156 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
157 if (uuid.empty()) {
158 HILOGE("GetUuidByNetworkId return an empty uuid");
159 return;
160 }
161 {
162 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
163 uuidNetworkIdMap_.erase(uuid);
164 }
165 }
166
GetDeviceIdSet(std::set<std::string> & deviceIdSet)167 void DtbschedmgrDeviceInfoStorage::GetDeviceIdSet(std::set<std::string>& deviceIdSet)
168 {
169 deviceIdSet.clear();
170 lock_guard<mutex> autoLock(deviceLock_);
171 for (const auto& device : remoteDevices_) {
172 deviceIdSet.emplace(device.first);
173 }
174 }
175
UpdateDeviceInfoStorage(const std::vector<DmDeviceInfo> & dmDeviceInfoList)176 void DtbschedmgrDeviceInfoStorage::UpdateDeviceInfoStorage(
177 const std::vector<DmDeviceInfo>& dmDeviceInfoList)
178 {
179 for (const auto& dmDeviceInfo : dmDeviceInfoList) {
180 auto deviceInfo = std::make_shared<DmsDeviceInfo>(
181 dmDeviceInfo.deviceName, dmDeviceInfo.deviceTypeId, dmDeviceInfo.networkId);
182 std::string networkId = deviceInfo->GetNetworkId();
183 RegisterUuidNetworkIdMap(networkId);
184 {
185 HILOGI("remoteDevices networkId = %{public}s", DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
186 lock_guard<mutex> autoLock(deviceLock_);
187 remoteDevices_[networkId] = deviceInfo;
188 }
189 }
190 }
191
GetLocalDeviceId(std::string & networkId)192 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceId(std::string& networkId)
193 {
194 return GetLocalDeviceFromDnet(networkId);
195 }
196
GetLocalUdid(std::string & udid)197 bool DtbschedmgrDeviceInfoStorage::GetLocalUdid(std::string& udid)
198 {
199 return GetLocalDeviceUdid(udid);
200 }
201
GetLocalDeviceFromDnet(std::string & networkId)202 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceFromDnet(std::string& networkId)
203 {
204 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
205 if (dnetworkAdapter == nullptr) {
206 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
207 return false;
208 }
209 DmDeviceInfo dmDeviceInfo;
210 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
211 HILOGE("GetLocalBasicInfo error");
212 return false;
213 }
214 networkId = dmDeviceInfo.networkId;
215 HILOGI("get local networkId from DnetworkAdapter, networkId = %{public}s",
216 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
217 return true;
218 }
219
GetLocalDeviceUdid(std::string & udid)220 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceUdid(std::string& udid)
221 {
222 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
223 if (dnetworkAdapter == nullptr) {
224 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
225 return false;
226 }
227 DmDeviceInfo dmDeviceInfo;
228 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
229 HILOGE("GetLocalBasicInfo error");
230 return false;
231 }
232 udid = GetUuidByNetworkId(dmDeviceInfo.networkId);
233 HILOGI("GetLocalDeviceUdid = %{public}s", DnetworkAdapter::AnonymizeNetworkId(udid).c_str());
234 return true;
235 }
236
ClearAllDevices()237 void DtbschedmgrDeviceInfoStorage::ClearAllDevices()
238 {
239 lock_guard<mutex> autoLock(deviceLock_);
240 remoteDevices_.clear();
241 }
242
GetDeviceInfoById(const string & networkId)243 std::shared_ptr<DmsDeviceInfo> DtbschedmgrDeviceInfoStorage::GetDeviceInfoById(const string& networkId)
244 {
245 lock_guard<mutex> autoLock(deviceLock_);
246 auto iter = remoteDevices_.find(networkId);
247 if (iter == remoteDevices_.end()) {
248 return nullptr;
249 }
250 return iter->second;
251 }
252
GetUuidByNetworkId(const std::string & networkId)253 std::string DtbschedmgrDeviceInfoStorage::GetUuidByNetworkId(const std::string& networkId)
254 {
255 if (networkId.empty()) {
256 HILOGW("GetUuidByNetworkId networkId empty!");
257 return "";
258 }
259 {
260 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
261 auto iter = uuidNetworkIdMap_.begin();
262 while (iter != uuidNetworkIdMap_.end()) {
263 if (iter->second == networkId) {
264 return iter->first;
265 } else {
266 ++iter;
267 }
268 }
269 }
270 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
271 return uuid;
272 }
273
GetUdidByNetworkId(const std::string & networkId)274 std::string DtbschedmgrDeviceInfoStorage::GetUdidByNetworkId(const std::string& networkId)
275 {
276 if (networkId.empty()) {
277 HILOGW("GetUdidByNetworkId networkId empty!");
278 return "";
279 }
280 std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(networkId);
281 return udid;
282 }
283
GetNetworkIdByUuid(const std::string & uuid)284 std::string DtbschedmgrDeviceInfoStorage::GetNetworkIdByUuid(const std::string& uuid)
285 {
286 if (uuid.empty()) {
287 HILOGW("GetNetworkIdByUuid uuid empty!");
288 return "";
289 }
290 {
291 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
292 auto iter = uuidNetworkIdMap_.find(uuid);
293 if (iter != uuidNetworkIdMap_.end()) {
294 return iter->second;
295 }
296 return "";
297 }
298 }
DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)299 void DtbschedmgrDeviceInfoStorage::DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)
300 {
301 if (devInfo == nullptr) {
302 HILOGE("DeviceOnlineNotify devInfo null");
303 return;
304 }
305
306 if (networkIdMgrHandler_ == nullptr) {
307 HILOGE("networkIdMgrHandler null");
308 return;
309 }
310 auto nodeOnline = [this, devInfo]() {
311 std::string networkId = devInfo->GetNetworkId();
312 RegisterUuidNetworkIdMap(networkId);
313 std::string uuid = GetUuidByNetworkId(networkId);
314 HILOGI("networkId = %{public}s, uuid = %{public}s, deviceName = %{public}s",
315 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str(),
316 DnetworkAdapter::AnonymizeNetworkId(uuid).c_str(), devInfo->GetDeviceName().c_str());
317 {
318 lock_guard<mutex> autoLock(deviceLock_);
319 remoteDevices_[networkId] = devInfo;
320 }
321 DistributedSchedService::GetInstance().DeviceOnlineNotify(networkId);
322 };
323 if (!networkIdMgrHandler_->PostTask(nodeOnline)) {
324 HILOGE("DeviceOnlineNotify handler postTask failed");
325 }
326 }
327
DeviceOfflineNotify(const std::string & networkId)328 void DtbschedmgrDeviceInfoStorage::DeviceOfflineNotify(const std::string& networkId)
329 {
330 if (networkId.empty()) {
331 HILOGE("DeviceOfflineNotify networkId empty");
332 return;
333 }
334 HILOGD("DeviceOfflineNotify networkId = %{public}s",
335 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
336 if (networkIdMgrHandler_ == nullptr) {
337 HILOGE("DeviceOfflineNotify networkIdMgrHandler null");
338 return;
339 }
340 auto nodeOffline = [this, networkId]() {
341 std::string uuid = GetUuidByNetworkId(networkId);
342 HILOGI("DeviceOfflineNotify process networkId = %{public}s, uuid = %{public}s",
343 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str(), DnetworkAdapter::AnonymizeNetworkId(uuid).c_str());
344 DistributedSchedService::GetInstance().DeviceOfflineNotify(networkId);
345 UnregisterUuidNetworkIdMap(networkId);
346 lock_guard<mutex> autoLock(deviceLock_);
347 remoteDevices_.erase(networkId);
348 };
349 if (!networkIdMgrHandler_->PostTask(nodeOffline)) {
350 HILOGE("DeviceOfflineNotify handler postTask failed");
351 }
352 }
353
OnDeviceInfoChanged(const std::string & deviceId)354 void DtbschedmgrDeviceInfoStorage::OnDeviceInfoChanged(const std::string& deviceId)
355 {
356 HILOGI("OnDeviceInfoChanged called");
357 }
358
OnRemoteDied(const wptr<IRemoteObject> & remote)359 void DnetServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
360 {
361 HILOGI("OnRemoteDied dnetwork service died");
362 DtbschedmgrDeviceInfoStorage::GetInstance().Init();
363 }
364 }
365 }
366