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