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