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