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