• 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 "DevManager"
16 #include "dev_manager.h"
17 #include <thread>
18 #include <unistd.h>
19 #include "device_manager.h"
20 #include "device_manager_callback.h"
21 #include "dm_device_info.h"
22 #include "kvdb_service_client.h"
23 #include "log_print.h"
24 #include "store_util.h"
25 #include "task_executor.h"
26 namespace OHOS::DistributedKv {
27 using namespace OHOS::DistributedHardware;
28 using DevInfo = OHOS::DistributedHardware::DmDeviceInfo;
29 constexpr int32_t DM_OK = 0;
30 constexpr int32_t DM_ERROR = -1;
31 constexpr size_t DevManager::MAX_ID_LEN;
32 constexpr const char *PKG_NAME_EX = "_distributed_data";
33 class DMStateCallback : public DeviceStateCallback {
34 public:
DMStateCallback(DevManager & devManager)35     explicit DMStateCallback(DevManager &devManager) : devManager_(devManager){};
36     void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override;
37     void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override;
38     void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override;
39     void OnDeviceReady(const DmDeviceInfo &deviceInfo) override;
40 
41 private:
42     DevManager &devManager_;
43 };
44 
OnDeviceOnline(const DmDeviceInfo & deviceInfo)45 void DMStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
46 {
47     devManager_.Online(deviceInfo.networkId);
48 }
49 
OnDeviceOffline(const DmDeviceInfo & deviceInfo)50 void DMStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
51 {
52     devManager_.Offline(deviceInfo.networkId);
53 }
54 
OnDeviceChanged(const DmDeviceInfo & deviceInfo)55 void DMStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
56 {
57     devManager_.OnChanged(deviceInfo.networkId);
58 }
59 
OnDeviceReady(const DmDeviceInfo & deviceInfo)60 void DMStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
61 {
62     devManager_.OnReady(deviceInfo.networkId);
63 }
64 
65 class DmDeathCallback : public DmInitCallback {
66 public:
DmDeathCallback(DevManager & devManager)67     explicit DmDeathCallback(DevManager &devManager) : devManager_(devManager){};
68     void OnRemoteDied() override;
69 
70 private:
71     DevManager &devManager_;
72 };
73 
OnRemoteDied()74 void DmDeathCallback::OnRemoteDied()
75 {
76     ZLOGI("dm device manager died, init it again");
77     devManager_.RegisterDevCallback();
78 }
79 
DevManager(const std::string & pkgName)80 DevManager::DevManager(const std::string &pkgName) : PKG_NAME(pkgName + PKG_NAME_EX)
81 {
82     RegisterDevCallback();
83 }
84 
Init()85 int32_t DevManager::Init()
86 {
87     auto &deviceManager = DeviceManager::GetInstance();
88     auto deviceInitCallback = std::make_shared<DmDeathCallback>(*this);
89     auto deviceCallback = std::make_shared<DMStateCallback>(*this);
90     int32_t errNo = deviceManager.InitDeviceManager(PKG_NAME, deviceInitCallback);
91     if (errNo != DM_OK) {
92         return errNo;
93     }
94     errNo = deviceManager.RegisterDevStateCallback(PKG_NAME, "", deviceCallback);
95     return errNo;
96 }
97 
RegisterDevCallback()98 void DevManager::RegisterDevCallback()
99 {
100     auto check = Retry();
101     check();
102 }
103 
Retry()104 std::function<void()> DevManager::Retry()
105 {
106     return [this]() {
107         int32_t errNo = DM_ERROR;
108         errNo = Init();
109         if (errNo == DM_OK) {
110             return;
111         }
112         constexpr int32_t interval = 100;
113         TaskExecutor::GetInstance().Execute(Retry(), interval);
114     };
115 }
116 
GetInstance()117 DevManager &DevManager::GetInstance()
118 {
119     static DevManager instance(std::to_string(getpid()));
120     return instance;
121 }
122 
ToUUID(const std::string & networkId)123 std::string DevManager::ToUUID(const std::string &networkId)
124 {
125     return GetDvInfoFromBucket(networkId).uuid;
126 }
127 
ToNetworkId(const std::string & uuid)128 std::string DevManager::ToNetworkId(const std::string &uuid)
129 {
130     return GetDvInfoFromBucket(uuid).networkId;
131 }
132 
GetDvInfoFromBucket(const std::string & id)133 DevManager::DetailInfo DevManager::GetDvInfoFromBucket(const std::string &id)
134 {
135     DetailInfo dtInfo;
136     if (!deviceInfos_.Get(id, dtInfo)) {
137         UpdateBucket();
138         deviceInfos_.Get(id, dtInfo);
139     }
140     if (dtInfo.uuid.empty()) {
141         ZLOGE("id:%{public}s", StoreUtil::Anonymous(id).c_str());
142     }
143     return dtInfo;
144 }
145 
UpdateBucket()146 void DevManager::UpdateBucket()
147 {
148     auto dtInfos = GetRemoteDevices();
149     if (dtInfos.empty()) {
150         ZLOGD("no remote device");
151     }
152     dtInfos.emplace_back(GetLocalDevice());
153     for (const auto &dtInfo : dtInfos) {
154         if (dtInfo.uuid.empty() || dtInfo.networkId.empty()) {
155             continue;
156         }
157         deviceInfos_.Set(dtInfo.uuid, dtInfo);
158         deviceInfos_.Set(dtInfo.networkId, dtInfo);
159     }
160 }
161 
GetLocalDevice()162 const DevManager::DetailInfo &DevManager::GetLocalDevice()
163 {
164     std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
165     if (!localInfo_.uuid.empty()) {
166         return localInfo_;
167     }
168     DevInfo info;
169     auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info);
170     if (ret != DM_OK) {
171         ZLOGE("get local device info fail");
172         return invalidDetail_;
173     }
174     auto networkId = std::string(info.networkId);
175     std::string uuid;
176     DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid);
177     if (uuid.empty() || networkId.empty()) {
178         return invalidDetail_;
179     }
180     localInfo_.networkId = std::move(networkId);
181     localInfo_.uuid = std::move(uuid);
182     ZLOGI("[LocalDevice] uuid:%{public}s, networkId:%{public}s", StoreUtil::Anonymous(localInfo_.uuid).c_str(),
183         StoreUtil::Anonymous(localInfo_.networkId).c_str());
184     return localInfo_;
185 }
186 
GetRemoteDevices()187 std::vector<DevManager::DetailInfo> DevManager::GetRemoteDevices()
188 {
189     std::vector<DevInfo> dmInfos;
190     auto ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", dmInfos);
191     if (ret != DM_OK) {
192         ZLOGE("get trusted device:%{public}d", ret);
193         return {};
194     }
195     if (dmInfos.empty()) {
196         ZLOGD("no remote device");
197         return {};
198     }
199     std::vector<DetailInfo> dtInfos;
200     for (auto &device : dmInfos) {
201         DetailInfo dtInfo;
202         auto networkId = std::string(device.networkId);
203         std::string uuid;
204         DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid);
205         dtInfo.networkId = std::move(device.networkId);
206         dtInfo.uuid = std::move(uuid);
207         dtInfos.push_back(dtInfo);
208     }
209     return dtInfos;
210 }
211 
Online(const std::string & networkId)212 void DevManager::Online(const std::string &networkId)
213 {
214     // do nothing
215     ZLOGI("%{public}s observers:%{public}zu", StoreUtil::Anonymous(networkId).c_str(), observers_.Size());
216 }
217 
Offline(const std::string & networkId)218 void DevManager::Offline(const std::string &networkId)
219 {
220     DetailInfo deviceInfo;
221     if (deviceInfos_.Get(networkId, deviceInfo)) {
222         deviceInfos_.Delete(networkId);
223         deviceInfos_.Delete(deviceInfo.uuid);
224     }
225     ZLOGI("%{public}s observers:%{public}zu", StoreUtil::Anonymous(networkId).c_str(), observers_.Size());
226     observers_.ForEach([&networkId](const auto &key, auto &value) {
227         value->Offline(networkId);
228         return false;
229     });
230 }
231 
OnChanged(const std::string & networkId)232 void DevManager::OnChanged(const std::string &networkId)
233 {
234     // do nothing
235     ZLOGI("%{public}s observers:%{public}zu", StoreUtil::Anonymous(networkId).c_str(), observers_.Size());
236 }
237 
OnReady(const std::string & networkId)238 void DevManager::OnReady(const std::string &networkId)
239 {
240     ZLOGI("%{public}s observers:%{public}zu", StoreUtil::Anonymous(networkId).c_str(), observers_.Size());
241     observers_.ForEach([&networkId](const auto &key, auto &value) {
242         value->Online(networkId);
243         return false;
244     });
245 }
246 
Register(DevManager::Observer * observer)247 void DevManager::Register(DevManager::Observer *observer)
248 {
249     observers_.Insert(observer, observer);
250 }
251 
Unregister(DevManager::Observer * observer)252 void DevManager::Unregister(DevManager::Observer *observer)
253 {
254     observers_.Erase(observer);
255 }
256 } // namespace OHOS::DistributedKv
257