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