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