1 /*
2 * Copyright (c) 2022-2023 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 #include "device/dm_adapter.h"
16
17 #include "pasteboard_hilog.h"
18 #include "pasteboard_error.h"
19 #ifdef PB_DEVICE_MANAGER_ENABLE
20 #include "device_manager.h"
21 #include "device_manager_callback.h"
22 #endif
23 namespace OHOS::MiscServices {
24 constexpr size_t DMAdapter::MAX_ID_LEN;
25 constexpr const char *PKG_NAME = "pasteboard_service";
26
27 #ifdef PB_DEVICE_MANAGER_ENABLE
28 class DmStateObserver : public DeviceStateCallback {
29 public:
DmStateObserver(const std::function<void (const DmDeviceInfo &)> online,const std::function<void (const DmDeviceInfo &)> onReady,const std::function<void (const DmDeviceInfo &)> offline)30 DmStateObserver(const std::function<void(const DmDeviceInfo &)> online,
31 const std::function<void(const DmDeviceInfo &)> onReady,
32 const std::function<void(const DmDeviceInfo &)> offline)
33 :online_(std::move(online)), onReady_(std::move(onReady)), offline_(std::move(offline))
34 {
35 }
OnDeviceOnline(const DmDeviceInfo & deviceInfo)36 void OnDeviceOnline(const DmDeviceInfo &deviceInfo) override
37 {
38 if (online_ == nullptr || deviceInfo.authForm != IDENTICAL_ACCOUNT) {
39 return;
40 }
41 online_(deviceInfo);
42 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "device on:%{public}.6s", deviceInfo.networkId);
43 }
44
OnDeviceOffline(const DmDeviceInfo & deviceInfo)45 void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override
46 {
47 if (offline_ == nullptr || deviceInfo.authForm != IDENTICAL_ACCOUNT) {
48 return;
49 }
50 offline_(deviceInfo);
51 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "device off:%{public}.6s", deviceInfo.networkId);
52 }
53
OnDeviceChanged(const DmDeviceInfo & deviceInfo)54 void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override
55 {
56 // authForm not vaild use networkId
57 if (DeviceManager::GetInstance().IsSameAccount(deviceInfo.networkId)) {
58 online_(deviceInfo);
59 }
60 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "device config changed:%{public}.6s", deviceInfo.networkId);
61 }
62
OnDeviceReady(const DmDeviceInfo & deviceInfo)63 void OnDeviceReady(const DmDeviceInfo &deviceInfo) override
64 {
65 if (onReady_ == nullptr || deviceInfo.authForm != IDENTICAL_ACCOUNT) {
66 return;
67 }
68 onReady_(deviceInfo);
69 }
70
71 private:
72 std::function<void(const DmDeviceInfo &)> online_;
73 std::function<void(const DmDeviceInfo &)> onReady_;
74 std::function<void(const DmDeviceInfo &)> offline_;
75 };
76
77 class DmDeath : public DmInitCallback, public std::enable_shared_from_this<DmDeath> {
78 public:
DmDeath(std::shared_ptr<DmStateObserver> observer,std::string pkgName)79 DmDeath(std::shared_ptr<DmStateObserver> observer, std::string pkgName)
80 : observer_(observer), pkgName_(std::move(pkgName))
81 {
82 }
OnRemoteDied()83 void OnRemoteDied() override
84 {
85 DeviceManager::GetInstance().InitDeviceManager(pkgName_, shared_from_this());
86 DeviceManager::GetInstance().RegisterDevStateCallback(pkgName_, "", observer_);
87 }
88
89 private:
90 std::shared_ptr<DmStateObserver> observer_;
91 std::string pkgName_;
92 };
93 #endif
94
DMAdapter()95 DMAdapter::DMAdapter()
96 {
97 }
98
~DMAdapter()99 DMAdapter::~DMAdapter()
100 {
101 }
102
GetInstance()103 DMAdapter &DMAdapter::GetInstance()
104 {
105 static DMAdapter instance;
106 return instance;
107 }
108
Initialize(const std::string & pkgName)109 bool DMAdapter::Initialize(const std::string &pkgName)
110 {
111 #ifdef PB_DEVICE_MANAGER_ENABLE
112 auto stateObserver = std::make_shared<DmStateObserver>([this](const DmDeviceInfo &deviceInfo) {
113 observers_.ForEachCopies([&deviceInfo](auto &key, auto &value) {
114 DMAdapter::GetInstance().SetDevices();
115 value->Online(deviceInfo.networkId);
116 return false;
117 });
118 }, [this](const DmDeviceInfo &deviceInfo) {
119 observers_.ForEachCopies([&deviceInfo](auto &key, auto &value) {
120 value->OnReady(deviceInfo.networkId);
121 return false;
122 });
123 }, [this](const DmDeviceInfo &deviceInfo) {
124 observers_.ForEachCopies([&deviceInfo](auto &key, auto &value) {
125 DMAdapter::GetInstance().SetDevices();
126 value->Offline(deviceInfo.networkId);
127 return false;
128 });
129 });
130 pkgName_ = pkgName + NAME_EX;
131 auto deathObserver = std::make_shared<DmDeath>(stateObserver, pkgName_);
132 deathObserver->OnRemoteDied();
133 SetDevices();
134 #endif
135 return false;
136 }
137
UnInitialize()138 void DMAdapter::UnInitialize()
139 {
140 auto& deviceManager = DeviceManager::GetInstance();
141 deviceManager.UnRegisterDevStateCallback(pkgName_);
142 deviceManager.UnInitDeviceManager(pkgName_);
143 }
144
GetLocalDeviceUdid()145 const std::string &DMAdapter::GetLocalDeviceUdid()
146 {
147 #ifdef PB_DEVICE_MANAGER_ENABLE
148 std::lock_guard<decltype(mutex_)> lockGuard(mutex_);
149 if (!localDeviceUdid_.empty()) {
150 return localDeviceUdid_;
151 }
152
153 DmDeviceInfo info;
154 int32_t ret = DeviceManager::GetInstance().GetLocalDeviceInfo(pkgName_, info);
155 if (ret != 0) {
156 return invalidDeviceUdid_;
157 }
158 DeviceManager::GetInstance().GetUdidByNetworkId(pkgName_, info.networkId, localDeviceUdid_);
159 if (!localDeviceUdid_.empty()) {
160 return localDeviceUdid_;
161 }
162 #endif
163 return invalidDeviceUdid_;
164 }
165
GetDeviceName(const std::string & networkId)166 std::string DMAdapter::GetDeviceName(const std::string &networkId)
167 {
168 #ifdef PB_DEVICE_MANAGER_ENABLE
169 auto devices = GetDevices();
170 for (auto &device : devices) {
171 if (device.networkId == networkId) {
172 return device.deviceName;
173 }
174 }
175 #endif
176 return DEVICE_INVALID_NAME;
177 }
178
GetLocalNetworkId()179 const std::string DMAdapter::GetLocalNetworkId()
180 {
181 #ifdef PB_DEVICE_MANAGER_ENABLE
182 DmDeviceInfo info;
183 int32_t ret = DeviceManager::GetInstance().GetLocalDeviceInfo(pkgName_, info);
184 auto networkId = std::string(info.networkId);
185 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "ret: %{public}d, networkId:%{public}s", ret, networkId.c_str());
186 if (ret == 0 && !networkId.empty()) {
187 return networkId;
188 }
189 #endif
190 return invalidNetworkId_;
191 }
192
GetRemoteDeviceInfo(const std::string & networkId,DmDeviceInfo & remoteDevice)193 int32_t DMAdapter::GetRemoteDeviceInfo(const std::string &networkId, DmDeviceInfo &remoteDevice)
194 {
195 #ifdef PB_DEVICE_MANAGER_ENABLE
196 auto devices = GetDevices();
197 for (auto &device : devices) {
198 if (device.networkId == networkId) {
199 remoteDevice = device;
200 return static_cast<int32_t>(PasteboardError::E_OK);
201 }
202 }
203 #endif
204 return static_cast<int32_t>(PasteboardError::NO_TRUST_DEVICE_ERROR);
205 }
206
GetUdidByNetworkId(const std::string & networkId)207 std::string DMAdapter::GetUdidByNetworkId(const std::string &networkId)
208 {
209 #ifdef PB_DEVICE_MANAGER_ENABLE
210 std::string udid;
211 int32_t ret = DeviceManager::GetInstance().GetUdidByNetworkId(pkgName_, networkId, udid);
212 if (ret == 0 && !udid.empty()) {
213 return udid;
214 }
215 #endif
216 return invalidUdid_;
217 }
218
Register(DMObserver * observer)219 void DMAdapter::Register(DMObserver *observer)
220 {
221 observers_.Insert(observer, observer);
222 }
223
Unregister(DMObserver * observer)224 void DMAdapter::Unregister(DMObserver *observer)
225 {
226 observers_.Erase(observer);
227 }
228
GetNetworkIds()229 std::vector<std::string> DMAdapter::GetNetworkIds()
230 {
231 #ifdef PB_DEVICE_MANAGER_ENABLE
232 auto devices = GetDevices();
233 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "devicesNums = %{public}zu.", devices.size());
234 if (devices.empty()) {
235 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no device online!");
236 return {};
237 }
238 std::vector<std::string> networkIds;
239 for (auto &item : devices) {
240 if (DeviceManager::GetInstance().IsSameAccount(item.networkId)) {
241 networkIds.emplace_back(item.networkId);
242 }
243 }
244 return networkIds;
245 #else
246 return {};
247 #endif
248 }
249
GetLocalDeviceType()250 int32_t DMAdapter::GetLocalDeviceType()
251 {
252 #ifdef PB_DEVICE_MANAGER_ENABLE
253 int32_t deviceType = DmDeviceType::DEVICE_TYPE_UNKNOWN;
254 int32_t ret = DeviceManager::GetInstance().GetLocalDeviceType(PKG_NAME, deviceType);
255 if (ret != 0) {
256 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get type failed, ret is %{public}d!", ret);
257 }
258 return deviceType;
259 #else
260 return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
261 #endif
262 }
263
IsSameAccount(const std::string & networkId)264 bool DMAdapter::IsSameAccount(const std::string &networkId)
265 {
266 #ifdef PB_DEVICE_MANAGER_ENABLE
267 auto devices = GetDevices();
268 for (auto &device : devices) {
269 if (device.networkId == networkId) {
270 return device.authForm == IDENTICAL_ACCOUNT;
271 }
272 }
273 #endif
274 return false;
275 }
276
SetDevices()277 void DMAdapter::SetDevices()
278 {
279 std::vector<DmDeviceInfo> devices;
280 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", devices);
281 if (ret != 0) {
282 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Get device list failed, errCode: %{public}d", ret);
283 return;
284 }
285 std::unique_lock<std::shared_mutex> lock(dmMutex_);
286 devices_ = std::move(devices);
287 }
288
GetDevices()289 std::vector<DmDeviceInfo> DMAdapter::GetDevices()
290 {
291 std::shared_lock<std::shared_mutex> lock(dmMutex_);
292 return devices_;
293 }
294 } // namespace OHOS::MiscServices