• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "DeviceManagerAdapter"
16 #include "device_manager_adapter.h"
17 #include <thread>
18 #include "log_print.h"
19 #include "kvstore_utils.h"
20 
21 namespace OHOS::DistributedData {
22 using namespace OHOS::DistributedHardware;
23 using namespace OHOS::AppDistributedKv;
24 using KvStoreUtils = OHOS::DistributedKv::KvStoreUtils;
25 constexpr int32_t DM_OK = 0;
26 constexpr const char *PKG_NAME = "ohos.distributeddata.service";
27 class DataMgrDmStateCall final : public DistributedHardware::DeviceStateCallback {
28 public:
DataMgrDmStateCall(DeviceManagerAdapter & dmAdapter)29     explicit DataMgrDmStateCall(DeviceManagerAdapter &dmAdapter) : dmAdapter_(dmAdapter) {}
30     void OnDeviceOnline(const DmDeviceInfo &info) override;
31     void OnDeviceOffline(const DmDeviceInfo &info) override;
32     void OnDeviceChanged(const DmDeviceInfo &info) override;
33     void OnDeviceReady(const DmDeviceInfo &info) override;
34 
35 private:
36     DeviceManagerAdapter &dmAdapter_;
37 };
38 
OnDeviceOnline(const DmDeviceInfo & info)39 void DataMgrDmStateCall::OnDeviceOnline(const DmDeviceInfo &info)
40 {
41     dmAdapter_.Online(info);
42 }
43 
OnDeviceOffline(const DmDeviceInfo & info)44 void DataMgrDmStateCall::OnDeviceOffline(const DmDeviceInfo &info)
45 {
46     dmAdapter_.Offline(info);
47 }
48 
OnDeviceChanged(const DmDeviceInfo & info)49 void DataMgrDmStateCall::OnDeviceChanged(const DmDeviceInfo &info)
50 {
51     dmAdapter_.OnChanged(info);
52 }
53 
OnDeviceReady(const DmDeviceInfo & info)54 void DataMgrDmStateCall::OnDeviceReady(const DmDeviceInfo &info)
55 {
56     dmAdapter_.OnReady(info);
57 }
58 
59 class DataMgrDmInitCall final : public DistributedHardware::DmInitCallback {
60 public:
DataMgrDmInitCall(DeviceManagerAdapter & dmAdapter)61     explicit DataMgrDmInitCall(DeviceManagerAdapter &dmAdapter) : dmAdapter_(dmAdapter) {}
62     void OnRemoteDied() override;
63 
64 private:
65     DeviceManagerAdapter &dmAdapter_;
66 };
67 
OnRemoteDied()68 void DataMgrDmInitCall::OnRemoteDied()
69 {
70     ZLOGI("device manager died, init again");
71     dmAdapter_.Init();
72 }
73 
DeviceManagerAdapter()74 DeviceManagerAdapter::DeviceManagerAdapter()
75 {
76     ZLOGI("construct");
77     threadPool_ = KvStoreThreadPool::GetPool(POOL_SIZE, "DeviceMgr", true);
78 }
79 
~DeviceManagerAdapter()80 DeviceManagerAdapter::~DeviceManagerAdapter()
81 {
82     ZLOGI("Destruct");
83     if (threadPool_ != nullptr) {
84         threadPool_->Stop();
85         threadPool_ = nullptr;
86     }
87 }
88 
GetInstance()89 DeviceManagerAdapter &DeviceManagerAdapter::GetInstance()
90 {
91     static DeviceManagerAdapter dmAdapter;
92     return dmAdapter;
93 }
94 
Init()95 void DeviceManagerAdapter::Init()
96 {
97     ZLOGI("begin");
98     Execute(RegDevCallback());
99 }
100 
RegDevCallback()101 std::function<void()> DeviceManagerAdapter::RegDevCallback()
102 {
103     return [this]() {
104         auto &devManager = DeviceManager::GetInstance();
105         auto dmStateCall = std::make_shared<DataMgrDmStateCall>(*this);
106         auto dmInitCall = std::make_shared<DataMgrDmInitCall>(*this);
107         auto resultInit = devManager.InitDeviceManager(PKG_NAME, dmInitCall);
108         auto resultState = devManager.RegisterDevStateCallback(PKG_NAME, "", dmStateCall);
109         if (resultInit == DM_OK && resultState == DM_OK) {
110             return;
111         }
112         constexpr int32_t INTERVAL = 500;
113         auto time = std::chrono::steady_clock::now() + std::chrono::milliseconds(INTERVAL);
114         scheduler_.At(time, RegDevCallback());
115     };
116 }
117 
StartWatchDeviceChange(const AppDeviceChangeListener * observer,const PipeInfo & pipeInfo)118 Status DeviceManagerAdapter::StartWatchDeviceChange(const AppDeviceChangeListener *observer,
119     __attribute__((unused)) const PipeInfo &pipeInfo)
120 {
121     if (observer == nullptr) {
122         ZLOGE("observer is nullptr");
123         return Status::INVALID_ARGUMENT;
124     }
125     if (!observers_.Insert(observer, observer)) {
126         ZLOGE("insert observer fail");
127         return Status::ERROR;
128     }
129     return Status::SUCCESS;
130 }
131 
StopWatchDeviceChange(const AppDeviceChangeListener * observer,const PipeInfo & pipeInfo)132 Status DeviceManagerAdapter::StopWatchDeviceChange(const AppDeviceChangeListener *observer,
133     __attribute__((unused)) const PipeInfo &pipeInfo)
134 {
135     if (observer == nullptr) {
136         ZLOGE("observer is nullptr");
137         return Status::INVALID_ARGUMENT;
138     }
139     if (!observers_.Erase(observer)) {
140         ZLOGE("erase observer fail");
141         return Status::ERROR;
142     }
143     return Status::SUCCESS;
144 }
145 
Online(const DmDeviceInfo & info)146 void DeviceManagerAdapter::Online(const DmDeviceInfo &info)
147 {
148     DeviceInfo dvInfo;
149     if (!GetDeviceInfo(info, dvInfo)) {
150         ZLOGE("get device info fail");
151         return;
152     }
153     ZLOGI("[online] uuid:%{public}s, name:%{public}s, type:%{public}d",
154         KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType);
155     SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_ONLINE);
156     auto observers = GetObservers();
157     for (const auto &item : observers) { // notify db
158         if (item == nullptr) {
159             continue;
160         }
161         if (item->GetChangeLevelType() == ChangeLevelType::HIGH) {
162             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_OFFLINE);
163             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE);
164         }
165     }
166     for (const auto &item : observers) { // sync meta, get device security level
167         if (item == nullptr) {
168             continue;
169         }
170         if (item->GetChangeLevelType() == ChangeLevelType::LOW) {
171             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE);
172         }
173     }
174     auto time = std::chrono::steady_clock::now() + std::chrono::milliseconds(SYNC_TIMEOUT);
175     scheduler_.At(time, [this, dvInfo]() { TimeOut(dvInfo.uuid); });
176     syncTask_.Insert(dvInfo.uuid, dvInfo.uuid);
177     for (const auto &item : observers) { // set compatible identify, sync service meta
178         if (item == nullptr) {
179             continue;
180         }
181         if (item->GetChangeLevelType() == ChangeLevelType::MIN) {
182             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONLINE);
183         }
184     }
185 }
186 
TimeOut(const std::string uuid)187 void DeviceManagerAdapter::TimeOut(const std::string uuid)
188 {
189     if (uuid.empty()) {
190         ZLOGE("uuid empty!");
191         return;
192     }
193     if (syncTask_.Contains(uuid)) {
194         ZLOGI("[TimeOutReadyEvent] uuid:%{public}s", KvStoreUtils::ToBeAnonymous(uuid).c_str());
195         std::string event = R"({"extra": {"deviceId":")" + uuid + R"(" } })";
196         DeviceManager::GetInstance().NotifyEvent(PKG_NAME, DmNotifyEvent::DM_NOTIFY_EVENT_ONDEVICEREADY, event);
197     }
198     syncTask_.Erase(uuid);
199 }
200 
NotifyReadyEvent(const std::string & uuid)201 void DeviceManagerAdapter::NotifyReadyEvent(const std::string &uuid)
202 {
203     if (uuid.empty() || !syncTask_.Contains(uuid)) {
204         return;
205     }
206 
207     syncTask_.Erase(uuid);
208     ZLOGI("[NotifyReadyEvent] uuid:%{public}s", KvStoreUtils::ToBeAnonymous(uuid).c_str());
209     std::string event = R"({"extra": {"deviceId":")" + uuid + R"(" } })";
210     DeviceManager::GetInstance().NotifyEvent(PKG_NAME, DmNotifyEvent::DM_NOTIFY_EVENT_ONDEVICEREADY, event);
211 }
212 
GetObservers()213 std::vector<const AppDeviceChangeListener *> DeviceManagerAdapter::GetObservers()
214 {
215     std::vector<const AppDeviceChangeListener *> observers;
216     observers.resize(observers_.Size());
217     observers_.ForEach([&observers](const auto &key, auto &value) {
218         observers.emplace_back(value);
219         return false;
220     });
221     return observers;
222 }
223 
Offline(const DmDeviceInfo & info)224 void DeviceManagerAdapter::Offline(const DmDeviceInfo &info)
225 {
226     DeviceInfo dvInfo;
227     if (!GetDeviceInfo(info, dvInfo)) {
228         ZLOGE("get device info fail");
229         return;
230     }
231     syncTask_.Erase(dvInfo.uuid);
232     ZLOGI("[offline] uuid:%{public}s, name:%{public}s, type:%{public}d",
233         KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType);
234     SaveDeviceInfo(dvInfo, DeviceChangeType::DEVICE_OFFLINE);
235     KvStoreTask task([this, dvInfo]() {
236         auto observers = GetObservers();
237         for (const auto &item : observers) {
238             if (item == nullptr) {
239                 continue;
240             }
241             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_OFFLINE);
242         }
243     }, "deviceOffline");
244     Execute(std::move(task));
245 }
246 
OnChanged(const DmDeviceInfo & info)247 void DeviceManagerAdapter::OnChanged(const DmDeviceInfo &info)
248 {
249     DeviceInfo dvInfo;
250     if (!GetDeviceInfo(info, dvInfo)) {
251         ZLOGE("get device info fail");
252         return;
253     }
254     ZLOGI("[OnChanged] uuid:%{public}s, name:%{public}s, type:%{public}d",
255         KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType);
256 }
257 
OnReady(const DmDeviceInfo & info)258 void DeviceManagerAdapter::OnReady(const DmDeviceInfo &info)
259 {
260     DeviceInfo dvInfo;
261     if (!GetDeviceInfo(info, dvInfo)) {
262         ZLOGE("get device info fail");
263         return;
264     }
265     ZLOGI("[OnReady] uuid:%{public}s, name:%{public}s, type:%{public}d",
266         KvStoreUtils::ToBeAnonymous(dvInfo.uuid).c_str(), dvInfo.deviceName.c_str(), dvInfo.deviceType);
267     KvStoreTask task([this, dvInfo]() {
268         auto observers = GetObservers();
269         for (const auto &item : observers) {
270             if (item == nullptr) {
271                 continue;
272             }
273             item->OnDeviceChanged(dvInfo, DeviceChangeType::DEVICE_ONREADY);
274         }
275     }, "deviceReady");
276     Execute(std::move(task));
277 }
278 
GetDeviceInfo(const DmDeviceInfo & dmInfo,DeviceInfo & dvInfo)279 bool DeviceManagerAdapter::GetDeviceInfo(const DmDeviceInfo &dmInfo, DeviceInfo &dvInfo)
280 {
281     std::string networkId = std::string(dmInfo.networkId);
282     if (networkId.empty()) {
283         return false;
284     }
285     auto uuid = GetUuidByNetworkId(networkId);
286     auto udid = GetUdidByNetworkId(networkId);
287     if (uuid.empty() || udid.empty()) {
288         return false;
289     }
290     dvInfo = { uuid, udid, networkId, std::string(dmInfo.deviceName), dmInfo.deviceTypeId };
291     return true;
292 }
293 
SaveDeviceInfo(const DeviceInfo & dvInfo,const DeviceChangeType & type)294 void DeviceManagerAdapter::SaveDeviceInfo(const DeviceInfo &dvInfo, const DeviceChangeType &type)
295 {
296     switch (type) {
297         case DeviceChangeType::DEVICE_ONLINE: {
298             deviceInfos_.Set(dvInfo.networkId, dvInfo);
299             deviceInfos_.Set(dvInfo.uuid, dvInfo);
300             deviceInfos_.Set(dvInfo.udid, dvInfo);
301             break;
302         }
303         case DeviceChangeType::DEVICE_OFFLINE: {
304             deviceInfos_.Delete(dvInfo.networkId);
305             deviceInfos_.Delete(dvInfo.uuid);
306             deviceInfos_.Delete(dvInfo.udid);
307             break;
308         }
309         default: {
310             ZLOGW("unknown type.");
311             break;
312         }
313     }
314 }
315 
GetLocalDevice()316 DeviceInfo DeviceManagerAdapter::GetLocalDevice()
317 {
318     std::lock_guard<decltype(devInfoMutex_)> lock(devInfoMutex_);
319     if (!localInfo_.uuid.empty()) {
320         return localInfo_;
321     }
322 
323     DmDeviceInfo info;
324     auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info);
325     if (ret != DM_OK) {
326         ZLOGE("get local device info fail");
327         return {};
328     }
329     auto networkId = std::string(info.networkId);
330     auto uuid = GetUuidByNetworkId(networkId);
331     auto udid = GetUdidByNetworkId(networkId);
332     if (uuid.empty() || udid.empty()) {
333         return {};
334     }
335     ZLOGI("[LocalDevice] uuid:%{public}s, name:%{public}s, type:%{public}d",
336         KvStoreUtils::ToBeAnonymous(uuid).c_str(), info.deviceName, info.deviceTypeId);
337     localInfo_ = { std::move(uuid), std::move(udid), std::move(networkId),
338                    std::string(info.deviceName), info.deviceTypeId };
339     return localInfo_;
340 }
341 
GetRemoteDevices()342 std::vector<DeviceInfo> DeviceManagerAdapter::GetRemoteDevices()
343 {
344     std::vector<DmDeviceInfo> dmInfos;
345     auto ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", dmInfos);
346     if (ret != DM_OK) {
347         ZLOGE("get trusted device:%{public}d", ret);
348         return {};
349     }
350 
351     std::vector<DeviceInfo> dvInfos;
352     for (const auto &dmInfo : dmInfos) {
353         auto networkId = std::string(dmInfo.networkId);
354         auto uuid = GetUuidByNetworkId(networkId);
355         auto udid = GetUdidByNetworkId(networkId);
356         DeviceInfo dvInfo = { std::move(uuid), std::move(udid), std::move(networkId),
357                               std::string(dmInfo.deviceName), dmInfo.deviceTypeId };
358         dvInfos.emplace_back(std::move(dvInfo));
359     }
360     return dvInfos;
361 }
362 
GetDeviceInfo(const std::string & id)363 DeviceInfo DeviceManagerAdapter::GetDeviceInfo(const std::string &id)
364 {
365     return GetDeviceInfoFromCache(id);
366 }
367 
GetDeviceInfoFromCache(const std::string & id)368 DeviceInfo DeviceManagerAdapter::GetDeviceInfoFromCache(const std::string &id)
369 {
370     DeviceInfo dvInfo;
371     if (!deviceInfos_.Get(id, dvInfo)) {
372         UpdateDeviceInfo();
373         deviceInfos_.Get(id, dvInfo);
374     }
375     if (dvInfo.uuid.empty()) {
376         ZLOGE("invalid id:%{public}s", KvStoreUtils::ToBeAnonymous(id).c_str());
377     }
378     return dvInfo;
379 }
380 
Execute(KvStoreTask && task)381 bool DeviceManagerAdapter::Execute(KvStoreTask &&task)
382 {
383     if (threadPool_ == nullptr) {
384         return false;
385     }
386     threadPool_->AddTask(std::move(task));
387     return true;
388 }
389 
UpdateDeviceInfo()390 void DeviceManagerAdapter::UpdateDeviceInfo()
391 {
392     std::vector<DeviceInfo> dvInfos = GetRemoteDevices();
393     if (dvInfos.empty()) {
394         ZLOGW("there is no trusted device!");
395         return;
396     }
397     dvInfos.emplace_back(GetLocalDevice());
398     for (const auto &info : dvInfos) {
399         if (info.networkId.empty() || info.uuid.empty() || info.udid.empty()) {
400             ZLOGE("networkId:%{public}s, uuid:%{public}d, udid:%{public}d",
401                 KvStoreUtils::ToBeAnonymous(info.networkId).c_str(), info.uuid.empty(), info.udid.empty());
402             continue;
403         }
404         deviceInfos_.Set(info.networkId, info);
405         deviceInfos_.Set(info.uuid, info);
406         deviceInfos_.Set(info.udid, info);
407     }
408 }
409 
GetUuidByNetworkId(const std::string & networkId)410 std::string DeviceManagerAdapter::GetUuidByNetworkId(const std::string &networkId)
411 {
412     if (networkId.empty()) {
413         return "";
414     }
415     DeviceInfo dvInfo;
416     if (deviceInfos_.Get(networkId, dvInfo)) {
417         return dvInfo.uuid;
418     }
419     std::string uuid;
420     auto ret = DeviceManager::GetInstance().GetUuidByNetworkId(PKG_NAME, networkId, uuid);
421     if (ret != DM_OK || uuid.empty()) {
422         ZLOGE("failed, result:%{public}d, networkId:%{public}s", ret, KvStoreUtils::ToBeAnonymous(networkId).c_str());
423         return "";
424     }
425     return uuid;
426 }
427 
GetUdidByNetworkId(const std::string & networkId)428 std::string DeviceManagerAdapter::GetUdidByNetworkId(const std::string &networkId)
429 {
430     if (networkId.empty()) {
431         return "";
432     }
433     DeviceInfo dvInfo;
434     if (deviceInfos_.Get(networkId, dvInfo)) {
435         return dvInfo.udid;
436     }
437     std::string udid;
438     auto ret = DeviceManager::GetInstance().GetUdidByNetworkId(PKG_NAME, networkId, udid);
439     if (ret != DM_OK || udid.empty()) {
440         ZLOGE("failed, result:%{public}d, networkId:%{public}s", ret, KvStoreUtils::ToBeAnonymous(networkId).c_str());
441         return "";
442     }
443     return udid;
444 }
445 
GetLocalBasicInfo()446 DeviceInfo DeviceManagerAdapter::GetLocalBasicInfo()
447 {
448     return GetLocalDevice();
449 }
450 
ToUUID(const std::string & id)451 std::string DeviceManagerAdapter::ToUUID(const std::string &id)
452 {
453     return GetDeviceInfoFromCache(id).uuid;
454 }
455 
ToUDID(const std::string & id)456 std::string DeviceManagerAdapter::ToUDID(const std::string &id)
457 {
458     return GetDeviceInfoFromCache(id).udid;
459 }
460 
ToUUID(const std::vector<std::string> & devices)461 std::vector<std::string> DeviceManagerAdapter::ToUUID(const std::vector<std::string> &devices)
462 {
463     std::vector<std::string> uuids;
464     for (auto &device : devices) {
465         auto uuid = DeviceManagerAdapter::GetInstance().ToUUID(device);
466         if (uuid.empty()) {
467             continue ;
468         }
469         uuids.push_back(std::move(uuid));
470     }
471     return uuids;
472 }
473 
ToUUID(std::vector<DeviceInfo> devices)474 std::vector<std::string> DeviceManagerAdapter::ToUUID(std::vector<DeviceInfo> devices)
475 {
476     std::vector<std::string> uuids;
477     for (auto &device : devices) {
478         if (device.uuid.empty()) {
479             continue ;
480         }
481         uuids.push_back(std::move(device.uuid));
482     }
483     return uuids;
484 }
485 
ToNetworkID(const std::string & id)486 std::string DeviceManagerAdapter::ToNetworkID(const std::string &id)
487 {
488     return GetDeviceInfoFromCache(id).networkId;
489 }
490 
CalcClientUuid(const std::string & appId,const std::string & uuid)491 std::string DeviceManagerAdapter::CalcClientUuid(const std::string &appId, const std::string &uuid)
492 {
493     if (uuid.empty()) {
494         return "";
495     }
496     std::string encryptedUuid;
497     auto ret = DeviceManager::GetInstance().GenerateEncryptedUuid(PKG_NAME, uuid, appId, encryptedUuid);
498     if (ret != DM_OK) {
499         ZLOGE("failed, result:%{public}d", ret);
500         return "";
501     }
502     return encryptedUuid;
503 }
504 } // namespace OHOS::DistributedData
505