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 "dp_device_manager.h"
17
18 #include <chrono>
19 #include <thread>
20
21 #include <unistd.h>
22
23 #include "parameter.h"
24
25 #include "device_profile_log.h"
26 #include "device_profile_manager.h"
27 #include "device_profile_utils.h"
28 #include "distributed_device_profile_service.h"
29 #include "dm_constants.h"
30 #include "event_handler_factory.h"
31 #include "ipc_object_proxy.h"
32 #include "ipc_skeleton.h"
33 #include "iservice_registry.h"
34 #include "profile_cache.h"
35 #include "system_ability_definition.h"
36
37 namespace OHOS {
38 namespace DeviceProfile {
39 using namespace std::chrono_literals;
40 using namespace DistributedHardware;
41
42 namespace {
43 const std::string TAG = "DpDeviceManager";
44
45 constexpr int32_t RETRY_TIMES = 30;
46 constexpr uint8_t MAX_DEVICE_TYPE = 3;
47 constexpr int32_t DEVICE_ID_SIZE = 65;
48 constexpr int32_t MAX_TIMES_CONNECT_DEVICEMANAGER = 10;
49 const std::string PKG_NAME = "ohos.deviceprofile";
50 }
51
52 IMPLEMENT_SINGLE_INSTANCE(DpDeviceManager);
53
GetInitCallback()54 std::shared_ptr<DistributedHardware::DmInitCallback> DpDeviceManager::GetInitCallback()
55 {
56 std::lock_guard<std::mutex> autoLock(initcallbackLock_);
57 if (initCallback_ == nullptr) {
58 initCallback_ = std::make_shared<DeviceInitCallBack>();
59 }
60 return initCallback_;
61 }
62
GetStateCallback()63 std::shared_ptr<DistributedHardware::DeviceStateCallback> DpDeviceManager::GetStateCallback()
64 {
65 std::lock_guard<std::mutex> autoLock(stateCallLock_);
66 if (stateCallback_ == nullptr) {
67 stateCallback_ = std::make_shared<DpDeviceStateCallback>();
68 }
69 return stateCallback_;
70 }
71
GetDevMgrHandler()72 void DpDeviceManager::GetDevMgrHandler()
73 {
74 std::lock_guard<std::mutex> autoLock(devMgrLock_);
75 if (devMgrHandler_ == nullptr) {
76 devMgrHandler_ = DistributedDeviceProfile::EventHandlerFactory::GetInstance().GetEventHandler();
77 }
78 }
79
Init()80 bool DpDeviceManager::Init()
81 {
82 GetInitCallback();
83 GetStateCallback();
84 GetDevMgrHandler();
85 {
86 std::lock_guard<std::mutex> autoLock(devMgrLock_);
87 if (devMgrHandler_ == nullptr) {
88 return false;
89 }
90 }
91 if (!ConnectDeviceManager()) {
92 return false;
93 }
94 return true;
95 }
96
OnRemoteDied()97 void DpDeviceManager::DeviceInitCallBack::OnRemoteDied()
98 {
99 HILOGI("DeviceInitCallBack OnRemoteDied");
100 DpDeviceManager::GetInstance().Init();
101 }
102
GetTrustedDeviceList()103 void DpDeviceManager::GetTrustedDeviceList()
104 {
105 std::vector<DmDeviceInfo> deviceList;
106 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", deviceList);
107 if (ret != ERR_OK) {
108 HILOGE("GetTrustedDeviceList Failed!");
109 return;
110 }
111 if (deviceList.empty()) {
112 HILOGI("deviceList is empty!");
113 return;
114 }
115 for (const DmDeviceInfo& dmDeviceInfo : deviceList) {
116 auto dpDeviceInfo = std::make_shared<DeviceInfo>(
117 dmDeviceInfo.deviceName, dmDeviceInfo.networkId, dmDeviceInfo.deviceTypeId);
118 DpDeviceManager::GetInstance().OnNodeOnline(dpDeviceInfo);
119 }
120 DistributedDeviceProfileService::GetInstance().DeviceOnline();
121 }
122
OnDeviceOnline(const DmDeviceInfo & deviceInfo)123 void DpDeviceManager::DpDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
124 {
125 HILOGI("online called");
126 auto dpDeviceInfo = std::make_shared<DeviceInfo>(
127 deviceInfo.deviceName, deviceInfo.networkId, deviceInfo.deviceTypeId);
128 DpDeviceManager::GetInstance().OnNodeOnline(dpDeviceInfo);
129 DistributedDeviceProfileService::GetInstance().DeviceOnline();
130 std::string networkId = deviceInfo.networkId;
131 DistributedDeviceProfile::ProfileCache::GetInstance().OnNodeOnline(networkId);
132 DistributedDeviceProfile::DeviceProfileManager::GetInstance().OnDeviceOnline(deviceInfo);
133 }
134
OnDeviceOffline(const DmDeviceInfo & deviceInfo)135 void DpDeviceManager::DpDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
136 {
137 HILOGI("offline called");
138 std::string networkId = deviceInfo.networkId;
139 DpDeviceManager::GetInstance().OnNodeOffline(networkId);
140 DistributedDeviceProfile::ProfileCache::GetInstance().OnNodeOffline(networkId);
141 }
142
OnDeviceChanged(const DmDeviceInfo & deviceInfo)143 void DpDeviceManager::DpDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
144 {
145 HILOGD("called");
146 }
147
OnDeviceReady(const DmDeviceInfo & deviceInfo)148 void DpDeviceManager::DpDeviceStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
149 {
150 HILOGD("called");
151 }
152
OnNodeOnline(const std::shared_ptr<DeviceInfo> deviceInfo)153 void DpDeviceManager::OnNodeOnline(const std::shared_ptr<DeviceInfo> deviceInfo)
154 {
155 if (deviceInfo == nullptr) {
156 HILOGE("deviceInfo is nullptr");
157 return;
158 }
159 auto onlineNotifyTask = [this, deviceInfo = deviceInfo]() {
160 HILOGI("online networkId = %{public}s",
161 DeviceProfileUtils::AnonymizeDeviceId(deviceInfo->GetNetworkId()).c_str());
162 RemoveExpiredDeviceIds(deviceInfo->GetNetworkId());
163 AddDeviceIds(deviceInfo->GetNetworkId());
164 {
165 std::string networkId = deviceInfo->GetNetworkId();
166 std::lock_guard<std::mutex> autoLock(deviceLock_);
167 remoteDeviceInfoMap_[networkId] = deviceInfo;
168 }
169 };
170 std::lock_guard<std::mutex> autoLock(devMgrLock_);
171 if (devMgrHandler_ == nullptr) {
172 HILOGE("devMgrHandler is nullptr");
173 return;
174 }
175 if (!devMgrHandler_->PostTask(onlineNotifyTask)) {
176 HILOGE("post task failed");
177 return;
178 }
179 }
180
OnNodeOffline(const std::string & networkId)181 void DpDeviceManager::OnNodeOffline(const std::string& networkId)
182 {
183 auto offlineNotifyTask = [this, networkId = std::move(networkId)]() {
184 HILOGI("offline networkId = %{public}s", DeviceProfileUtils::AnonymizeDeviceId(networkId).c_str());
185 std::lock_guard<std::mutex> autoLock(deviceLock_);
186 remoteDeviceInfoMap_.erase(networkId);
187 };
188 std::lock_guard<std::mutex> autoLock(devMgrLock_);
189 if (devMgrHandler_ == nullptr) {
190 HILOGE("devMgrHandler is nullptr");
191 return;
192 }
193 if (!devMgrHandler_->PostTask(offlineNotifyTask)) {
194 HILOGE("post task failed");
195 return;
196 }
197 }
198
WaitForDnetworkReady()199 bool DpDeviceManager::WaitForDnetworkReady()
200 {
201 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
202 if (samgr == nullptr) {
203 HILOGE("WaitForDnetworkReady failed to get samgr!");
204 return false;
205 }
206 int32_t retryTimeout = RETRY_TIMES;
207 do {
208 auto dnetworkDm = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
209 auto dnetworkSoftBus = samgr->CheckSystemAbility(SOFTBUS_SERVER_SA_ID);
210 if (dnetworkDm != nullptr && dnetworkSoftBus != nullptr) {
211 IPCObjectProxy* dmProxy = reinterpret_cast<IPCObjectProxy*>(dnetworkDm.GetRefPtr());
212 IPCObjectProxy* sbProxy = reinterpret_cast<IPCObjectProxy*>(dnetworkSoftBus.GetRefPtr());
213 // make sure the proxy is not dead
214 if (dmProxy != nullptr && !dmProxy->IsObjectDead() && sbProxy != nullptr && !sbProxy->IsObjectDead()) {
215 return true;
216 }
217 }
218 HILOGI("Waiting for dnentwork service...");
219 std::this_thread::sleep_for(1s);
220 if (--retryTimeout <= 0) {
221 HILOGI("Waiting for dnentwork service timeout(30)s");
222 return false;
223 }
224 } while (true);
225 return false;
226 }
227
ConnectDeviceManager()228 bool DpDeviceManager::ConnectDeviceManager()
229 {
230 HILOGI("ConnectDeviceManager");
231 bool isReady = WaitForDnetworkReady();
232 if (!isReady) {
233 HILOGE("ConnectDeviceManager wait Dnetwork failed!");
234 return false;
235 }
236
237 auto registerTask = [this]() {
238 HILOGD("register task...");
239 int32_t retryTimes = 0;
240 int32_t errCode = ERR_OK;
241 while (retryTimes++ < MAX_TIMES_CONNECT_DEVICEMANAGER) {
242 int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, GetInitCallback());
243 if (ret != 0) {
244 HILOGE("init device manager failed, ret:%{public}d", ret);
245 std::this_thread::sleep_for(1s);
246 continue;
247 }
248 errCode = DeviceManager::GetInstance().RegisterDevStateCallback(
249 PKG_NAME, "", GetStateCallback());
250 if (errCode == ERR_OK) {
251 DpDeviceManager::GetInstance().GetTrustedDeviceList();
252 break;
253 }
254 HILOGE("register errCode = %{public}d, retrying...", errCode);
255
256 errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
257 HILOGI("unregister errCode = %{public}d", errCode);
258 std::this_thread::sleep_for(1s);
259 }
260
261 if (errCode == ERR_OK) {
262 AddLocalDeviceIds();
263 RecoverDevicesIfNeeded();
264 }
265 HILOGI("register %{public}s", (errCode == ERR_OK) ? "success" : "timeout");
266 };
267 std::lock_guard<std::mutex> autoLock(devMgrLock_);
268 if (devMgrHandler_ == nullptr) {
269 HILOGE("devMgrHandler is nullptr");
270 return false;
271 }
272 if (!devMgrHandler_->PostTask(registerTask)) {
273 HILOGE("post task failed");
274 return false;
275 }
276 return true;
277 }
278
RecoverDevicesIfNeeded()279 void DpDeviceManager::RecoverDevicesIfNeeded()
280 {
281 HILOGI("called");
282 std::vector<DmDeviceInfo> deviceList;
283 if (DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", deviceList) != ERR_OK) {
284 HILOGE("get all node info failed");
285 return;
286 }
287 for (DmDeviceInfo dmDeviceInfo : deviceList) {
288 std::string networkId = dmDeviceInfo.networkId;
289 HILOGI("deviceId %{public}s found", DeviceProfileUtils::AnonymizeDeviceId(networkId).c_str());
290 AddDeviceIds(networkId);
291 {
292 auto deviceInfo = std::make_shared<DeviceInfo>(
293 dmDeviceInfo.deviceName, dmDeviceInfo.networkId, dmDeviceInfo.deviceTypeId);
294 std::lock_guard<std::mutex> autoLock(deviceLock_);
295 remoteDeviceInfoMap_.emplace(std::move(networkId), deviceInfo);
296 }
297 }
298 }
299
AddLocalDeviceIds()300 void DpDeviceManager::AddLocalDeviceIds()
301 {
302 HILOGI("called");
303 DmDeviceInfo dmInfo;
304 int32_t errCode = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, dmInfo);
305 if (errCode != ERR_OK) {
306 HILOGW("errCode = %{public}d", errCode);
307 std::string udid;
308 GetLocalDeviceUdid(udid);
309 std::vector<std::string> deviceIds = {"", std::move(udid), ""};
310 std::lock_guard<std::mutex> autoLock(deviceLock_);
311 deviceIdsList_.emplace_back(std::move(deviceIds));
312 } else {
313 AddDeviceIds(dmInfo.networkId);
314 }
315 }
316
AddDeviceIds(const std::string & networkId)317 void DpDeviceManager::AddDeviceIds(const std::string& networkId)
318 {
319 HILOGI("called");
320 std::string udid;
321 if (GetUdidByNetworkId(networkId, udid)) {
322 HILOGI("udid %{public}s", DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
323 }
324 std::string uuid;
325 if (GetUuidByNetworkId(networkId, uuid)) {
326 HILOGI("uuid %{public}s", DeviceProfileUtils::AnonymizeDeviceId(uuid).c_str());
327 }
328 std::vector<std::string> deviceIds = {networkId, std::move(udid), std::move(uuid)};
329 std::lock_guard<std::mutex> autoLock(deviceLock_);
330 deviceIdsList_.emplace_back(std::move(deviceIds));
331 }
332
RemoveExpiredDeviceIds(const std::string & networkId)333 void DpDeviceManager::RemoveExpiredDeviceIds(const std::string& networkId)
334 {
335 HILOGI("called");
336 std::string udid;
337 if (!GetUdidByNetworkId(networkId, udid)) {
338 return;
339 }
340 if (udid.empty()) {
341 return;
342 }
343 RemoveDeviceIdsByUdid(udid);
344 }
345
RemoveDeviceIds(const std::string & networkId)346 void DpDeviceManager::RemoveDeviceIds(const std::string& networkId)
347 {
348 HILOGI("called");
349 std::lock_guard<std::mutex> autoLock(deviceLock_);
350 auto iter = std::find_if(deviceIdsList_.begin(), deviceIdsList_.end(), [&networkId](const auto& deviceIds) {
351 return deviceIds[static_cast<uint8_t>(DeviceIdType::NETWORKID)] == networkId;
352 });
353 if (iter != deviceIdsList_.end()) {
354 deviceIdsList_.erase(iter);
355 }
356 return;
357 }
358
RemoveDeviceIdsByUdid(const std::string & udid)359 void DpDeviceManager::RemoveDeviceIdsByUdid(const std::string& udid)
360 {
361 HILOGI("called");
362 std::lock_guard<std::mutex> autoLock(deviceLock_);
363 auto iter = std::find_if(deviceIdsList_.begin(), deviceIdsList_.end(), [&udid](const auto& deviceIds) {
364 return deviceIds[static_cast<uint8_t>(DeviceIdType::UDID)] == udid;
365 });
366 if (iter != deviceIdsList_.end()) {
367 deviceIdsList_.erase(iter);
368 HILOGI("remove device udid %{public}s", DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
369 }
370 return;
371 }
372
DisconnectDeviceManager()373 bool DpDeviceManager::DisconnectDeviceManager()
374 {
375 int32_t errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
376 if (errCode != ERR_OK) {
377 HILOGE("remove failed, errCode = %{public}d", errCode);
378 return false;
379 }
380 return true;
381 }
382
GetLocalDeviceUdid(std::string & udid)383 void DpDeviceManager::GetLocalDeviceUdid(std::string& udid)
384 {
385 char localDeviceId[DEVICE_ID_SIZE] = {0};
386 GetDevUdid(localDeviceId, DEVICE_ID_SIZE);
387 udid = localDeviceId;
388 }
389
GetUdidByNetworkId(const std::string & networkId,std::string & udid)390 bool DpDeviceManager::GetUdidByNetworkId(const std::string& networkId, std::string& udid)
391 {
392 return ((DeviceManager::GetInstance().GetUdidByNetworkId(
393 PKG_NAME, networkId, udid) == 0) ? true : false);
394 }
395
GetUuidByNetworkId(const std::string & networkId,std::string & uuid)396 bool DpDeviceManager::GetUuidByNetworkId(const std::string& networkId, std::string& uuid)
397 {
398 return ((DeviceManager::GetInstance().GetUuidByNetworkId(
399 PKG_NAME, networkId, uuid) == 0) ? true : false);
400 }
401
TransformDeviceId(const std::string & fromDeviceId,std::string & toDeviceId,DeviceIdType toType)402 bool DpDeviceManager::TransformDeviceId(const std::string& fromDeviceId,
403 std::string& toDeviceId, DeviceIdType toType)
404 {
405 if (fromDeviceId.empty()) {
406 HILOGW("empty device id");
407 return false;
408 }
409
410 uint8_t idx = static_cast<uint8_t>(toType);
411 if (idx > MAX_DEVICE_TYPE - 1) {
412 return false;
413 }
414
415 toDeviceId = "";
416 std::lock_guard<std::mutex> autoLock(deviceLock_);
417 for (const auto& deviceIds : deviceIdsList_) {
418 auto iter = std::find(deviceIds.begin(), deviceIds.end(), fromDeviceId);
419 if (iter != deviceIds.end()) {
420 toDeviceId = deviceIds[idx];
421 return !toDeviceId.empty();
422 }
423 }
424 return false;
425 }
426
GetDeviceIdList(std::list<std::string> & deviceIdList)427 void DpDeviceManager::GetDeviceIdList(std::list<std::string>& deviceIdList)
428 {
429 deviceIdList.clear();
430 std::lock_guard<std::mutex> autoLock(deviceLock_);
431 for (const auto& [_, deviceInfo] : remoteDeviceInfoMap_) {
432 if (deviceInfo == nullptr) {
433 HILOGW("deviceInfo is nullptr");
434 continue;
435 }
436 deviceIdList.emplace_back(deviceInfo->GetNetworkId());
437 }
438 }
439
GetDeviceList(std::list<std::shared_ptr<DeviceInfo>> & deviceList)440 void DpDeviceManager::GetDeviceList(std::list<std::shared_ptr<DeviceInfo>>& deviceList)
441 {
442 deviceList.clear();
443 std::lock_guard<std::mutex> autoLock(deviceLock_);
444 for (const auto& [_, deviceInfo] : remoteDeviceInfoMap_) {
445 if (deviceInfo == nullptr) {
446 HILOGW("deviceInfo is nullptr");
447 continue;
448 }
449 deviceList.emplace_back(deviceInfo);
450 }
451 }
452 } // namespace DeviceProfile
453 } // namespace OHOS
454