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