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