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 <unistd.h>
18 #include "device_manager.h"
19 #include "device_manager_callback.h"
20 #include "dm_device_info.h"
21 #include "kvdb_service_client.h"
22 #include "log_print.h"
23 #include "store_util.h"
24 #include "task_executor.h"
25 namespace OHOS::DistributedKv {
26 using namespace OHOS::DistributedHardware;
27 using DevInfo = OHOS::DistributedHardware::DmDeviceInfo;
28 constexpr int32_t DM_OK = 0;
29 constexpr int32_t DM_ERROR = -1;
30 constexpr size_t DevManager::MAX_ID_LEN;
31 constexpr const char *PKG_NAME_EX = "_distributed_data";
32 class DmDeathCallback : public DmInitCallback {
33 public:
DmDeathCallback(DevManager & devManager)34 explicit DmDeathCallback(DevManager &devManager) : devManager_(devManager){};
35 void OnRemoteDied() override;
36
37 private:
38 DevManager &devManager_;
39 };
40
OnRemoteDied()41 void DmDeathCallback::OnRemoteDied()
42 {
43 ZLOGI("dm device manager died, init it again");
44 devManager_.RegisterDevCallback();
45 }
46
DevManager(const std::string & pkgName)47 DevManager::DevManager(const std::string &pkgName) : PKG_NAME(pkgName + PKG_NAME_EX)
48 {
49 RegisterDevCallback();
50 }
51
Init()52 int32_t DevManager::Init()
53 {
54 auto &deviceManager = DeviceManager::GetInstance();
55 auto deviceInitCallback = std::make_shared<DmDeathCallback>(*this);
56 return deviceManager.InitDeviceManager(PKG_NAME, deviceInitCallback);
57 }
58
RegisterDevCallback()59 void DevManager::RegisterDevCallback()
60 {
61 auto check = Retry();
62 check();
63 }
64
Retry()65 std::function<void()> DevManager::Retry()
66 {
67 return [this]() {
68 int32_t errNo = DM_ERROR;
69 errNo = Init();
70 if (errNo == DM_OK) {
71 return;
72 }
73 constexpr int32_t interval = 100;
74 TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(interval), Retry());
75 };
76 }
77
GetInstance()78 DevManager &DevManager::GetInstance()
79 {
80 static DevManager instance(std::to_string(getpid()));
81 return instance;
82 }
83
ToUUID(const std::string & networkId)84 std::string DevManager::ToUUID(const std::string &networkId)
85 {
86 return GetDevInfoFromBucket(networkId).uuid;
87 }
88
ToNetworkId(const std::string & uuid)89 std::string DevManager::ToNetworkId(const std::string &uuid)
90 {
91 return GetDevInfoFromBucket(uuid).networkId;
92 }
93
GetDevInfoFromBucket(const std::string & id)94 DevManager::DetailInfo DevManager::GetDevInfoFromBucket(const std::string &id)
95 {
96 DetailInfo detailInfo;
97 if (!deviceInfos_.Get(id, detailInfo)) {
98 UpdateBucket();
99 deviceInfos_.Get(id, detailInfo);
100 }
101 if (detailInfo.uuid.empty()) {
102 ZLOGE("id:%{public}s", StoreUtil::Anonymous(id).c_str());
103 }
104 return detailInfo;
105 }
106
UpdateBucket()107 void DevManager::UpdateBucket()
108 {
109 auto detailInfos = GetRemoteDevices();
110 if (detailInfos.empty()) {
111 ZLOGD("no remote device");
112 }
113 detailInfos.emplace_back(GetLocalDevice());
114 for (const auto &detailInfo : detailInfos) {
115 if (detailInfo.uuid.empty() || detailInfo.networkId.empty()) {
116 continue;
117 }
118 deviceInfos_.Set(detailInfo.uuid, detailInfo);
119 deviceInfos_.Set(detailInfo.networkId, detailInfo);
120 }
121 }
122
GetUnEncryptedUuid()123 std::string DevManager::GetUnEncryptedUuid()
124 {
125 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
126 if (!UnEncryptedLocalInfo_.uuid.empty()) {
127 return UnEncryptedLocalInfo_.uuid;
128 }
129 DevInfo info;
130 auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info);
131 if (ret != DM_OK) {
132 ZLOGE("get local device info fail");
133 return "";
134 }
135 auto networkId = std::string(info.networkId);
136 if (networkId.empty()) {
137 ZLOGE("networkid empty");
138 return "";
139 }
140 std::string uuid;
141 DeviceManager::GetInstance().GetUuidByNetworkId(PKG_NAME, networkId, uuid);
142 if (uuid.empty()) {
143 ZLOGE("get uuid by networkid fail");
144 return "";
145 }
146 UnEncryptedLocalInfo_.uuid = std::move(uuid);
147 ZLOGI("[GetUnEncryptedUuid] uuid:%{public}s, networkId:%{public}s",
148 StoreUtil::Anonymous(UnEncryptedLocalInfo_.uuid).c_str(),
149 StoreUtil::Anonymous(networkId).c_str());
150 return UnEncryptedLocalInfo_.uuid;
151 }
152
GetLocalDevice()153 const DevManager::DetailInfo &DevManager::GetLocalDevice()
154 {
155 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
156 if (!localInfo_.uuid.empty()) {
157 return localInfo_;
158 }
159 DevInfo info;
160 auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, info);
161 if (ret != DM_OK) {
162 ZLOGE("get local device info fail");
163 return invalidDetail_;
164 }
165 auto networkId = std::string(info.networkId);
166 std::string uuid;
167 DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid);
168 if (uuid.empty() || networkId.empty()) {
169 return invalidDetail_;
170 }
171 localInfo_.networkId = std::move(networkId);
172 localInfo_.uuid = std::move(uuid);
173 ZLOGI("[LocalDevice] uuid:%{public}s, networkId:%{public}s", StoreUtil::Anonymous(localInfo_.uuid).c_str(),
174 StoreUtil::Anonymous(localInfo_.networkId).c_str());
175 return localInfo_;
176 }
177
GetRemoteDevices()178 std::vector<DevManager::DetailInfo> DevManager::GetRemoteDevices()
179 {
180 std::vector<DevInfo> dmInfos;
181 auto ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", dmInfos);
182 if (ret != DM_OK) {
183 ZLOGE("get trusted device:%{public}d", ret);
184 return {};
185 }
186 if (dmInfos.empty()) {
187 ZLOGD("no remote device");
188 return {};
189 }
190 std::vector<DetailInfo> dtInfos;
191 for (auto &device : dmInfos) {
192 DetailInfo dtInfo;
193 auto networkId = std::string(device.networkId);
194 std::string uuid;
195 DeviceManager::GetInstance().GetEncryptedUuidByNetworkId(PKG_NAME, networkId, uuid);
196 dtInfo.networkId = std::move(device.networkId);
197 dtInfo.uuid = std::move(uuid);
198 dtInfos.push_back(dtInfo);
199 }
200 return dtInfos;
201 }
202 } // namespace OHOS::DistributedKv
203