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 "device_manager.h"
22 #include "ipc_object_proxy.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26
27 #include "distributed_device_node_listener.h"
28 #include "distributed_sched_service.h"
29 #include "distributed_sched_utils.h"
30 #include "dtbschedmgr_log.h"
31 #include "mission/dms_continue_recv_manager.h"
32
33 using namespace std;
34 namespace OHOS {
35 namespace DistributedSchedule {
36 using namespace std::chrono_literals;
37 using namespace DistributedHardware;
38
39 namespace {
40 constexpr int32_t RETRY_TIMES = 30;
41 constexpr int32_t CONNECT_SOFTBUS_RETRY_TIMES = 60;
42 const std::string TAG = "DtbschedmgrDeviceInfoStorage";
43 const std::string PKG_NAME = "DBinderBus_Dms_" + std::to_string(getprocpid());
44 }
45
46 IMPLEMENT_SINGLE_INSTANCE(DtbschedmgrDeviceInfoStorage);
47
Init()48 bool DtbschedmgrDeviceInfoStorage::Init()
49 {
50 if (initHandler_ == nullptr) {
51 auto deviceInfoStorageRunner = AppExecFwk::EventRunner::Create("DmsDeviceInfoStorageManager");
52 initHandler_ = std::make_shared<AppExecFwk::EventHandler>(deviceInfoStorageRunner);
53 }
54
55 auto func = [this]() {
56 HILOGI("begin connect softbus");
57 for (int32_t retryTimes = 0; retryTimes <= CONNECT_SOFTBUS_RETRY_TIMES; retryTimes++) {
58 if (ConnectSoftbus()) {
59 return;
60 }
61 HILOGE("retry connect softbus %{public}d times", retryTimes);
62 std::this_thread::sleep_for(1s);
63 }
64 HILOGE("connect softbus 60times * 30s, error!!");
65 };
66 if (!initHandler_->PostTask(func)) {
67 HILOGE("Init handler postTask failed");
68 return false;
69 }
70 return true;
71 }
72
ConnectSoftbus()73 bool DtbschedmgrDeviceInfoStorage::ConnectSoftbus()
74 {
75 ClearAllDevices();
76 bool isReady = WaitForDnetworkReady();
77 if (!isReady) {
78 HILOGE("ConnectSoftbus wait Dnetwork failed!");
79 return false;
80 }
81 std::shared_ptr<DnetworkAdapter> dnetworkAdapter = DnetworkAdapter::GetInstance();
82 if (dnetworkAdapter == nullptr) {
83 HILOGE("DnetworkAdapter::GetInstance is null");
84 return false;
85 }
86 if (!InitNetworkIdManager(dnetworkAdapter)) {
87 HILOGE("InitNetworkIdManager failed");
88 return false;
89 }
90 HILOGI("ConnectSoftbus success");
91 return true;
92 }
93
InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)94 bool DtbschedmgrDeviceInfoStorage::InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)
95 {
96 if (dnetworkAdapter == nullptr) {
97 HILOGE("dnetworkAdapter is null");
98 return false;
99 }
100 if (networkIdMgrHandler_ == nullptr) {
101 auto runner = AppExecFwk::EventRunner::Create("DmsNetworkIdManager");
102 networkIdMgrHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
103 }
104
105 deviceNodeListener_ = std::make_shared<DistributedDeviceNodeListener>();
106 if (!dnetworkAdapter->AddDeviceChangeListener(deviceNodeListener_)) {
107 deviceNodeListener_ = nullptr;
108 HILOGE("AddDeviceChangeListener failed!");
109 return false;
110 }
111 return true;
112 }
113
Stop()114 void DtbschedmgrDeviceInfoStorage::Stop()
115 {
116 ClearAllDevices();
117 if (deviceNodeListener_ != nullptr) {
118 DnetworkAdapter::GetInstance()->RemoveDeviceChangeListener(deviceNodeListener_);
119 deviceNodeListener_ = nullptr;
120 }
121 }
122
WaitForDnetworkReady()123 bool DtbschedmgrDeviceInfoStorage::WaitForDnetworkReady()
124 {
125 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
126 if (samgr == nullptr) {
127 HILOGE("WaitForDnetworkReady failed to get samgr!");
128 return false;
129 }
130 int32_t retryTimeout = RETRY_TIMES;
131 do {
132 auto dnetwork = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
133 if (dnetwork != nullptr) {
134 IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(dnetwork.GetRefPtr());
135 // make sure the proxy is not dead
136 if (proxy != nullptr && !proxy->IsObjectDead()) {
137 return true;
138 }
139 }
140 HILOGI("Waiting for dnentwork service...");
141 std::this_thread::sleep_for(1s);
142 if (--retryTimeout <= 0) {
143 HILOGI("Waiting for dnentwork service timeout(30)s");
144 return false;
145 }
146 } while (true);
147 return false;
148 }
149
RegisterUuidNetworkIdMap(const std::string& networkId)150 void DtbschedmgrDeviceInfoStorage::RegisterUuidNetworkIdMap(const std::string& networkId)
151 {
152 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
153 if (uuid.empty()) {
154 HILOGE("GetUuidByNetworkId return an empty uuid!");
155 return;
156 }
157 {
158 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
159 uuidNetworkIdMap_[uuid] = networkId;
160 }
161 }
162
UnregisterUuidNetworkIdMap(const std::string& networkId)163 void DtbschedmgrDeviceInfoStorage::UnregisterUuidNetworkIdMap(const std::string& networkId)
164 {
165 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
166 if (uuid.empty()) {
167 HILOGE("GetUuidByNetworkId return an empty uuid");
168 return;
169 }
170 {
171 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
172 uuidNetworkIdMap_.erase(uuid);
173 }
174 }
175
GetDeviceIdSet(std::set<std::string>& deviceIdSet)176 void DtbschedmgrDeviceInfoStorage::GetDeviceIdSet(std::set<std::string>& deviceIdSet)
177 {
178 deviceIdSet.clear();
179 lock_guard<mutex> autoLock(deviceLock_);
180 for (const auto& device : remoteDevices_) {
181 deviceIdSet.emplace(device.first);
182 }
183 }
184
UpdateDeviceInfoStorage()185 bool DtbschedmgrDeviceInfoStorage::UpdateDeviceInfoStorage()
186 {
187 std::vector<DistributedHardware::DmDeviceInfo> dmDeviceInfoList;
188 int32_t errCode = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", dmDeviceInfoList);
189 if (errCode != ERR_OK) {
190 HILOGE("Get device manager trusted device list fail, errCode %{public}d", errCode);
191 return false;
192 }
193 for (const auto& dmDeviceInfo : dmDeviceInfoList) {
194 int32_t osType = Constants::OH_OS_TYPE;
195 std::string osVersion = "";
196 if (!GetOsInfoFromDM(dmDeviceInfo.extraData, osType, osVersion)) {
197 HILOGE("Get Os info from DM device info fail, extraData %{public}s.", dmDeviceInfo.extraData.c_str());
198 }
199 auto deviceInfo = std::make_shared<DmsDeviceInfo>(dmDeviceInfo.deviceName, dmDeviceInfo.deviceTypeId,
200 dmDeviceInfo.networkId, ONLINE, osType, osVersion);
201 std::string networkId = deviceInfo->GetNetworkId();
202 RegisterUuidNetworkIdMap(networkId);
203 {
204 HILOGI("Add remote device networkId %{public}s", GetAnonymStr(networkId).c_str());
205 lock_guard<mutex> autoLock(deviceLock_);
206 remoteDevices_[networkId] = deviceInfo;
207 }
208 }
209 HILOGI("Update remote devices info storage success.");
210 return true;
211 }
212
GetLocalDeviceId(std::string& networkId)213 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceId(std::string& networkId)
214 {
215 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
216 if (dnetworkAdapter == nullptr) {
217 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
218 return false;
219 }
220 DmDeviceInfo dmDeviceInfo;
221 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
222 HILOGE("GetLocalBasicInfo error");
223 return false;
224 }
225 networkId = dmDeviceInfo.networkId;
226 HILOGI("get local networkId from DnetworkAdapter, networkId = %{public}s", GetAnonymStr(networkId).c_str());
227 return true;
228 }
229
GetLocalUdid(std::string& udid)230 bool DtbschedmgrDeviceInfoStorage::GetLocalUdid(std::string& udid)
231 {
232 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
233 if (dnetworkAdapter == nullptr) {
234 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
235 return false;
236 }
237 DmDeviceInfo dmDeviceInfo;
238 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
239 HILOGE("GetLocalBasicInfo error");
240 return false;
241 }
242 udid = GetUdidByNetworkId(dmDeviceInfo.networkId);
243 HILOGD("GetLocalDeviceUdid = %{public}s", GetAnonymStr(udid).c_str());
244 return true;
245 }
246
GetLocalUuid(std::string& uuid)247 bool DtbschedmgrDeviceInfoStorage::GetLocalUuid(std::string& uuid)
248 {
249 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
250 if (dnetworkAdapter == nullptr) {
251 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
252 return false;
253 }
254 DmDeviceInfo dmDeviceInfo;
255 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
256 HILOGE("GetLocalBasicInfo error");
257 return false;
258 }
259 uuid = GetUuidByNetworkId(dmDeviceInfo.networkId);
260 HILOGD("GetLocalDeviceUuid = %{public}s", GetAnonymStr(uuid).c_str());
261 return true;
262 }
263
ClearAllDevices()264 void DtbschedmgrDeviceInfoStorage::ClearAllDevices()
265 {
266 lock_guard<mutex> autoLock(deviceLock_);
267 remoteDevices_.clear();
268 }
269
FindDeviceInfoInStorage(const std::string& networkId)270 std::shared_ptr<DmsDeviceInfo> DtbschedmgrDeviceInfoStorage::FindDeviceInfoInStorage(const std::string& networkId)
271 {
272 lock_guard<mutex> autoLock(deviceLock_);
273 auto iter = remoteDevices_.find(networkId);
274 if (iter == remoteDevices_.end()) {
275 HILOGE("Get remote device info from storage fail, networkId %{public}s.", GetAnonymStr(networkId).c_str());
276 return nullptr;
277 }
278 HILOGI("Get remote device info from storage success, networkId %{public}s.", GetAnonymStr(networkId).c_str());
279 return iter->second;
280 }
281
GetDeviceInfoById(const std::string& networkId)282 std::shared_ptr<DmsDeviceInfo> DtbschedmgrDeviceInfoStorage::GetDeviceInfoById(const std::string& networkId)
283 {
284 HILOGI("Get device info by networkId %{public}s start.", GetAnonymStr(networkId).c_str());
285 auto devInfo = FindDeviceInfoInStorage(networkId);
286 if (devInfo != nullptr) {
287 return devInfo;
288 }
289
290 HILOGI("NetworkId %{public}s not in storage, update devices info from device manager.",
291 GetAnonymStr(networkId).c_str());
292 if (!UpdateDeviceInfoStorage()) {
293 HILOGE("Update device info storage from device manager trusted device list fail.");
294 return nullptr;
295 }
296
297 devInfo = FindDeviceInfoInStorage(networkId);
298 return devInfo;
299 }
300
GetUuidByNetworkId(const std::string& networkId)301 std::string DtbschedmgrDeviceInfoStorage::GetUuidByNetworkId(const std::string& networkId)
302 {
303 if (networkId.empty()) {
304 HILOGW("GetUuidByNetworkId networkId empty!");
305 return "";
306 }
307 {
308 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
309 auto iter = uuidNetworkIdMap_.begin();
310 while (iter != uuidNetworkIdMap_.end()) {
311 if (iter->second == networkId) {
312 return iter->first;
313 } else {
314 ++iter;
315 }
316 }
317 }
318 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
319 return uuid;
320 }
321
GetUdidByNetworkId(const std::string& networkId)322 std::string DtbschedmgrDeviceInfoStorage::GetUdidByNetworkId(const std::string& networkId)
323 {
324 if (networkId.empty()) {
325 HILOGW("GetUdidByNetworkId networkId empty!");
326 return "";
327 }
328 std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(networkId);
329 return udid;
330 }
331
GetNetworkIdByUuid(const std::string& uuid)332 std::string DtbschedmgrDeviceInfoStorage::GetNetworkIdByUuid(const std::string& uuid)
333 {
334 if (uuid.empty()) {
335 HILOGW("GetNetworkIdByUuid uuid empty!");
336 return "";
337 }
338 {
339 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
340 auto iter = uuidNetworkIdMap_.find(uuid);
341 if (iter != uuidNetworkIdMap_.end()) {
342 return iter->second;
343 }
344 return "";
345 }
346 }
347
DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)348 void DtbschedmgrDeviceInfoStorage::DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)
349 {
350 if (devInfo == nullptr) {
351 HILOGE("DeviceOnlineNotify devInfo null");
352 return;
353 }
354
355 if (networkIdMgrHandler_ == nullptr) {
356 HILOGE("networkIdMgrHandler null");
357 return;
358 }
359 auto nodeOnline = [this, devInfo]() {
360 std::string networkId = devInfo->GetNetworkId();
361 RegisterUuidNetworkIdMap(networkId);
362 std::string uuid = GetUuidByNetworkId(networkId);
363 HILOGI("networkId: %{public}s, uuid: %{public}s, deviceName: %{public}s, osType: %{public}d, "
364 "osVersion: %{public}s.", GetAnonymStr(networkId).c_str(), GetAnonymStr(uuid).c_str(),
365 devInfo->GetDeviceName().c_str(), devInfo->GetDeviceOSType(), devInfo->GetGetDeviceOSVersion().c_str());
366 {
367 lock_guard<mutex> autoLock(deviceLock_);
368 remoteDevices_[networkId] = devInfo;
369 }
370 DistributedSchedService::GetInstance().DeviceOnlineNotify(networkId);
371 };
372 if (!networkIdMgrHandler_->PostTask(nodeOnline)) {
373 HILOGE("DeviceOnlineNotify handler postTask failed");
374 }
375 }
376
DeviceOfflineNotify(const std::string& networkId)377 void DtbschedmgrDeviceInfoStorage::DeviceOfflineNotify(const std::string& networkId)
378 {
379 if (networkId.empty()) {
380 HILOGE("DeviceOfflineNotify networkId empty");
381 return;
382 }
383 HILOGD("DeviceOfflineNotify networkId: %{public}s", GetAnonymStr(networkId).c_str());
384 if (networkIdMgrHandler_ == nullptr) {
385 HILOGE("DeviceOfflineNotify networkIdMgrHandler null");
386 return;
387 }
388 auto nodeOffline = [this, networkId]() {
389 std::string uuid = GetUuidByNetworkId(networkId);
390 HILOGI("DeviceOfflineNotify process networkId: %{public}s, uuid: %{public}s",
391 GetAnonymStr(networkId).c_str(), GetAnonymStr(uuid).c_str());
392 DistributedSchedService::GetInstance().DeviceOfflineNotify(networkId);
393 UnregisterUuidNetworkIdMap(networkId);
394 lock_guard<mutex> autoLock(deviceLock_);
395 remoteDevices_.erase(networkId);
396 };
397 if (!networkIdMgrHandler_->PostTask(nodeOffline)) {
398 HILOGE("DeviceOfflineNotify handler postTask failed");
399 }
400 }
401
OnDeviceInfoChanged(const std::string& deviceId)402 void DtbschedmgrDeviceInfoStorage::OnDeviceInfoChanged(const std::string& deviceId)
403 {
404 HILOGI("OnDeviceInfoChanged called");
405 if (!DMSContinueRecvMgr::GetInstance().CheckRegSoftbusListener() &&
406 DistributedHardware::DeviceManager::GetInstance().IsSameAccount(deviceId)) {
407 HILOGI("DMSContinueRecvMgr need init");
408 DMSContinueRecvMgr::GetInstance().Init();
409 }
410 }
411
OnRemoteDied(const wptr<IRemoteObject>& remote)412 void DnetServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
413 {
414 HILOGI("OnRemoteDied dnetwork service died");
415 DtbschedmgrDeviceInfoStorage::GetInstance().Init();
416 }
417
GetDeviceName(std::string netWorkId)418 std::string DtbschedmgrDeviceInfoStorage::GetDeviceName(std::string netWorkId)
419 {
420 for (auto device = remoteDevices_.begin(); device != remoteDevices_.end(); ++device) {
421 if (device->second != nullptr && device->second->GetNetworkId() == netWorkId) {
422 HILOGI("deviceName = %{public}s", device->second->GetDeviceName().c_str());
423 return device->second->GetDeviceName();
424 }
425 }
426 return "";
427 }
428
GetNetworkIdList()429 std::vector<std::string> DtbschedmgrDeviceInfoStorage::GetNetworkIdList()
430 {
431 std::vector<std::string> devices;
432 for (auto device = remoteDevices_.begin(); device != remoteDevices_.end(); ++device) {
433 if (device->second != nullptr) {
434 HILOGI("NetworkId: %{public}s", GetAnonymStr(device->second->GetNetworkId()).c_str());
435 devices.push_back(device->second->GetNetworkId());
436 }
437 }
438 return devices;
439 }
440 }
441 }
442