• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 
16 #include "distributed_device_service.h"
17 
18 #include "state_box.h"
19 #include "analytics_util.h"
20 #include "distributed_client.h"
21 #include "distributed_data_define.h"
22 #include "distributed_device_data.h"
23 #include "notification_helper.h"
24 #include "distributed_observer_service.h"
25 #include "distributed_service.h"
26 #include "distributed_send_adapter.h"
27 
28 namespace OHOS {
29 namespace Notification {
30 
31 static const int32_t MAX_CONNECTED_TYR = 5;
32 static const uint32_t DEFAULT_LOCK_SCREEN_FLAG = 2;
33 
GetInstance()34 DistributedDeviceService& DistributedDeviceService::GetInstance()
35 {
36     static DistributedDeviceService distributedDeviceService;
37     return distributedDeviceService;
38 }
39 
DeviceTypeToTypeString(uint16_t deviceType)40 std::string DistributedDeviceService::DeviceTypeToTypeString(uint16_t deviceType)
41 {
42     switch (deviceType) {
43         case DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH: {
44             return DistributedService::WEARABLE_DEVICE_TYPE;
45         }
46         case DistributedHardware::DmDeviceType::DEVICE_TYPE_PAD: {
47             return DistributedService::PAD_DEVICE_TYPE;
48         }
49         case DistributedHardware::DmDeviceType::DEVICE_TYPE_PC: {
50             return DistributedService::PC_DEVICE_TYPE;
51         }
52         case DistributedHardware::DmDeviceType::DEVICE_TYPE_2IN1: {
53             return DistributedService::PC_DEVICE_TYPE;
54         }
55         case DistributedHardware::DmDeviceType::DEVICE_TYPE_PHONE: {
56             return DistributedService::PHONE_DEVICE_TYPE;
57         }
58         default:
59             return "";
60     }
61 }
62 
DeviceTypeConversion(const std::string & deviceType)63 static std::string DeviceTypeConversion(const std::string& deviceType)
64 {
65     if (deviceType == DistributedService::PAD_DEVICE_TYPE) {
66         return "pad";
67     }
68 
69     if (deviceType == DistributedService::PC_DEVICE_TYPE) {
70         return "pc";
71     }
72     return deviceType;
73 }
74 
InitLocalDevice(const std::string & deviceId,uint16_t deviceType)75 void DistributedDeviceService::InitLocalDevice(const std::string &deviceId, uint16_t deviceType)
76 {
77     localDevice_.deviceId_ = deviceId;
78     localDevice_.deviceType_ = deviceType;
79 }
80 
GetLocalDevice()81 DistributedDeviceInfo DistributedDeviceService::GetLocalDevice()
82 {
83     return localDevice_;
84 }
85 
IsLocalPadOrPC()86 bool DistributedDeviceService::IsLocalPadOrPC()
87 {
88     return localDevice_.IsPadOrPc();
89 }
90 
IsReportDataByHa()91 bool DistributedDeviceService::IsReportDataByHa()
92 {
93     return localDevice_.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH;
94 }
95 
SetSubscribeAllConnect(bool subscribe)96 void DistributedDeviceService::SetSubscribeAllConnect(bool subscribe)
97 {
98     subscribeAllConnect = subscribe;
99 }
100 
IsSubscribeAllConnect()101 bool DistributedDeviceService::IsSubscribeAllConnect()
102 {
103     return subscribeAllConnect;
104 }
105 
CheckNeedSubscribeAllConnect()106 bool DistributedDeviceService::CheckNeedSubscribeAllConnect()
107 {
108     std::lock_guard<ffrt::mutex> lock(mapLock_);
109     for (auto& device : peerDevice_) {
110         if (device.second.IsPadOrPc()) {
111             return true;
112         }
113     }
114     return false;
115 }
116 
IsSyncLiveView(const std::string & deviceId,bool forceSync)117 bool DistributedDeviceService::IsSyncLiveView(const std::string& deviceId, bool forceSync)
118 {
119     std::lock_guard<ffrt::mutex> lock(mapLock_);
120     auto iter = peerDevice_.find(deviceId);
121     if (iter == peerDevice_.end()) {
122         ANS_LOGE("Dans unknown device is data %{public}s.", StringAnonymous(deviceId).c_str());
123         return false;
124     }
125 
126     if (iter->second.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_PC ||
127         iter->second.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_2IN1) {
128         ANS_LOGI("Dans device pc no need sync %{public}s.", StringAnonymous(deviceId).c_str());
129         return false;
130     }
131     if (iter->second.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_PAD) {
132         if (!iter->second.deviceUsage || iter->second.peerState_ == DeviceState::STATE_SYNC) {
133             ANS_LOGI("Dans pad sync %{public}d %{public}d.", iter->second.peerState_,
134                 iter->second.deviceUsage);
135             return false;
136         }
137     }
138 
139     if (!forceSync && iter->second.liveViewSync) {
140         ANS_LOGI("Dans live view sync %{public}d %{public}d.", forceSync, iter->second.liveViewSync);
141         return false;
142     }
143     return true;
144 }
145 
IsSyncIcons(const std::string & deviceId,bool forceSync)146 bool DistributedDeviceService::IsSyncIcons(const std::string& deviceId, bool forceSync)
147 {
148     std::lock_guard<ffrt::mutex> lock(mapLock_);
149     auto iter = peerDevice_.find(deviceId);
150     if (iter == peerDevice_.end()) {
151         ANS_LOGE("Dans unknown device is data %{public}s.", StringAnonymous(deviceId).c_str());
152         return false;
153     }
154     if (iter->second.deviceType_ != DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH) {
155         return false;
156     }
157 
158     if (!forceSync && iter->second.iconSync) {
159         ANS_LOGI("Dans icon sync %{public}d %{public}d.", forceSync, iter->second.iconSync);
160         return false;
161     }
162     return true;
163 }
164 
IsSyncInstalledBundle(const std::string & deviceId,bool forceSync)165 bool DistributedDeviceService::IsSyncInstalledBundle(const std::string& deviceId, bool forceSync)
166 {
167     std::lock_guard<ffrt::mutex> lock(mapLock_);
168     auto iter = peerDevice_.find(deviceId);
169     if (iter == peerDevice_.end()) {
170         ANS_LOGE("Dans unknown device is data %{public}s.", StringAnonymous(deviceId).c_str());
171         return false;
172     }
173 
174     if (iter->second.deviceType_ == DistributedHardware::DmDeviceType::DEVICE_TYPE_WATCH) {
175         return false;
176     }
177 
178     if (!forceSync && iter->second.installedBundlesSync) {
179         ANS_LOGI("Dans bundle sync %{public}d %{public}d.", forceSync, iter->second.installedBundlesSync);
180         return false;
181     }
182     return true;
183 }
184 
SetDeviceSyncData(const std::string & deviceId,int32_t type,bool syncData)185 void DistributedDeviceService::SetDeviceSyncData(const std::string& deviceId, int32_t type, bool syncData)
186 {
187     std::lock_guard<ffrt::mutex> lock(mapLock_);
188     auto iter = peerDevice_.find(deviceId);
189     if (iter == peerDevice_.end()) {
190         ANS_LOGE("Dans unknown device set data %{public}s.", StringAnonymous(deviceId).c_str());
191         return;
192     }
193     if (type == SYNC_BUNDLE_ICONS) {
194         iter->second.iconSync = syncData;
195     }
196     if (type == SYNC_LIVE_VIEW) {
197         iter->second.liveViewSync = syncData;
198     }
199     if (type == SYNC_INSTALLED_BUNDLE) {
200         iter->second.installedBundlesSync = syncData;
201     }
202     if (type == DEVICE_USAGE) {
203         iter->second.deviceUsage = syncData;
204     }
205 }
206 
ResetDeviceInfo(const std::string & deviceId,int32_t peerState)207 void DistributedDeviceService::ResetDeviceInfo(const std::string& deviceId, int32_t peerState)
208 {
209     std::lock_guard<ffrt::mutex> lock(mapLock_);
210     auto deviceIter = peerDevice_.find(deviceId);
211     if (deviceIter == peerDevice_.end()) {
212         ANS_LOGI("Dans unknown device %{public}s.", StringAnonymous(deviceId).c_str());
213         return;
214     }
215     deviceIter->second.connectedTry_ = 0;
216     deviceIter->second.deviceUsage = false;
217     deviceIter->second.liveViewSync = false;
218     deviceIter->second.iconSync = false;
219     deviceIter->second.installedBundlesSync = false;
220     deviceIter->second.peerState_ = peerState;
221 }
222 
SetDeviceState(const std::string & deviceId,int32_t state)223 void DistributedDeviceService::SetDeviceState(const std::string& deviceId, int32_t state)
224 {
225     std::lock_guard<ffrt::mutex> lock(mapLock_);
226     auto iter = peerDevice_.find(deviceId);
227     if (iter == peerDevice_.end()) {
228         ANS_LOGE("Dans unknown device set status %{public}s.", StringAnonymous(deviceId).c_str());
229         return;
230     }
231     iter->second.peerState_ = state;
232 }
233 
CheckDeviceExist(const std::string & deviceId)234 bool DistributedDeviceService::CheckDeviceExist(const std::string& deviceId)
235 {
236     std::lock_guard<ffrt::mutex> lock(mapLock_);
237     if (peerDevice_.find(deviceId) == peerDevice_.end()) {
238         ANS_LOGI("Dans unknown device %{public}s.", StringAnonymous(deviceId).c_str());
239         return false;
240     }
241     return true;
242 }
243 
GetDeviceInfo(const std::string & deviceId,DistributedDeviceInfo & device)244 bool DistributedDeviceService::GetDeviceInfo(const std::string& deviceId, DistributedDeviceInfo& device)
245 {
246     std::lock_guard<ffrt::mutex> lock(mapLock_);
247     auto iter = peerDevice_.find(deviceId);
248     if (iter == peerDevice_.end()) {
249         ANS_LOGI("Dans get deviceId unknonw %{public}s.", StringAnonymous(deviceId).c_str());
250         return false;
251     }
252     device = iter->second;
253     return true;
254 }
255 
GetDeviceInfoByUdid(const std::string & udid,DistributedDeviceInfo & device)256 bool DistributedDeviceService::GetDeviceInfoByUdid(const std::string& udid, DistributedDeviceInfo& device)
257 {
258     std::lock_guard<ffrt::mutex> lock(mapLock_);
259     for (auto deviceItem : peerDevice_) {
260         if (udid == deviceItem.second.udid_) {
261             device = deviceItem.second;
262             return true;
263         }
264     }
265     ANS_LOGI("Dans get deviceId unknonw %{public}s.", StringAnonymous(udid).c_str());
266     return false;
267 }
268 
CheckDeviceNeedSync(const std::string & deviceId)269 bool DistributedDeviceService::CheckDeviceNeedSync(const std::string& deviceId)
270 {
271     std::lock_guard<ffrt::mutex> lock(mapLock_);
272     auto iter = peerDevice_.find(deviceId);
273     if (iter == peerDevice_.end()) {
274         ANS_LOGE("Dans unknown device connected %{public}s.", StringAnonymous(deviceId).c_str());
275         return false;
276     }
277     if (iter->second.connectedTry_ >= MAX_CONNECTED_TYR || iter->second.peerState_ != DeviceState::STATE_SYNC) {
278         ANS_LOGI("Dans no need try %{public}d %{public}d.", iter->second.connectedTry_,
279             iter->second.peerState_);
280         iter->second.connectedTry_ = 0;
281         return false;
282     }
283     return true;
284 }
285 
IncreaseDeviceSyncCount(const std::string & deviceId)286 void DistributedDeviceService::IncreaseDeviceSyncCount(const std::string& deviceId)
287 {
288     std::lock_guard<ffrt::mutex> lock(mapLock_);
289     auto iter = peerDevice_.find(deviceId);
290     if (iter == peerDevice_.end()) {
291         ANS_LOGE("Dans unknown device count %{public}s.", StringAnonymous(deviceId).c_str());
292         return;
293     }
294     iter->second.connectedTry_ = iter->second.connectedTry_ + 1;
295     ANS_LOGI("Dans sync device count %{public}s %{public}d.", StringAnonymous(deviceId).c_str(),
296         iter->second.connectedTry_);
297 }
298 
AddDeviceInfo(DistributedDeviceInfo deviceItem)299 void DistributedDeviceService::AddDeviceInfo(DistributedDeviceInfo deviceItem)
300 {
301     std::lock_guard<ffrt::mutex> lock(mapLock_);
302     peerDevice_[deviceItem.deviceId_] = deviceItem;
303 }
304 
DeleteDeviceInfo(const std::string & deviceId)305 void DistributedDeviceService::DeleteDeviceInfo(const std::string& deviceId)
306 {
307     std::lock_guard<ffrt::mutex> lock(mapLock_);
308     auto deviceIter = peerDevice_.find(deviceId);
309     if (deviceIter != peerDevice_.end()) {
310         ANS_LOGI("Delete device %{public}s.", StringAnonymous(deviceId).c_str());
311         peerDevice_.erase(deviceId);
312     }
313 }
314 
GetDeviceList()315 std::map<std::string, DistributedDeviceInfo>& DistributedDeviceService::GetDeviceList()
316 {
317     std::lock_guard<ffrt::mutex> lock(mapLock_);
318     return peerDevice_;
319 }
320 
GetDeviceList(std::map<std::string,DistributedDeviceInfo> & peerDevices)321 void DistributedDeviceService::GetDeviceList(std::map<std::string, DistributedDeviceInfo>& peerDevices)
322 {
323     std::lock_guard<ffrt::mutex> lock(mapLock_);
324     for (auto deviceItem : peerDevice_) {
325         peerDevices[deviceItem.first] = deviceItem.second;
326     }
327 }
328 
SyncDeviceMatch(const DistributedDeviceInfo peerDevice,MatchType type)329 void DistributedDeviceService::SyncDeviceMatch(const DistributedDeviceInfo peerDevice, MatchType type)
330 {
331     std::shared_ptr<NotifticationMatchBox> matchBox = std::make_shared<NotifticationMatchBox>();
332     matchBox->SetVersion(CURRENT_VERSION);
333     matchBox->SetMatchType(type);
334     matchBox->SetLocalDeviceId(localDevice_.deviceId_);
335     matchBox->SetLocalDeviceType(localDevice_.deviceType_);
336     if (type == MatchType::MATCH_ACK) {
337         matchBox->SetPeerDeviceId(peerDevice.deviceId_);
338         matchBox->SetPeerDeviceType(peerDevice.deviceType_);
339     }
340     if (!matchBox->Serialize()) {
341         ANS_LOGW("Dans SyncDeviceMatch serialize failed.");
342         return;
343     }
344 
345     std::shared_ptr<PackageInfo> packageInfo = std::make_shared<PackageInfo>(matchBox, peerDevice,
346         TransDataType::DATA_TYPE_MESSAGE, MODIFY_ERROR_EVENT_CODE);
347     DistributedSendAdapter::GetInstance().SendPackage(packageInfo);
348     ANS_LOGI("Dans SyncDeviceMatch %{public}s %{public}d.",
349         StringAnonymous(peerDevice.deviceId_).c_str(), peerDevice.deviceType_);
350 }
351 
352 #ifdef DISTRIBUTED_FEATURE_MASTER
SetDeviceStatus(const std::shared_ptr<TlvBox> & boxMessage)353 void DistributedDeviceService::SetDeviceStatus(const std::shared_ptr<TlvBox>& boxMessage)
354 {
355     std::string deviceId;
356     NotifticationStateBox stateBox = NotifticationStateBox(boxMessage);
357     if (!stateBox.GetDeviceId(deviceId)) {
358         ANS_LOGW("Dans unbox deviceId and name failed.");
359         return;
360     }
361 
362     DistributedDeviceInfo device;
363     if (!GetDeviceInfo(deviceId, device)) {
364         ANS_LOGW("Dans get device failed %{public}s.", StringAnonymous(deviceId).c_str());
365         return;
366     }
367     int32_t status;
368     std::string deviceName = DistributedDeviceService::DeviceTypeToTypeString(device.deviceType_);
369     if (stateBox.GetState(status)) {
370         int32_t result = NotificationHelper::SetTargetDeviceStatus(deviceName, status,
371             DEFAULT_LOCK_SCREEN_FLAG, device.udid_);
372         ANS_LOGI("Dans set state %{public}s %{public}s %{public}d %{public}d.", deviceName.c_str(),
373             StringAnonymous(deviceId).c_str(), status, result);
374     }
375 
376     bool liveViewEnable;
377     bool notificationEnable;
378     if (stateBox.GetLiveViewEnable(liveViewEnable) && stateBox.GetNotificationEnable(notificationEnable)) {
379         int32_t result = NotificationHelper::SetTargetDeviceSwitch(deviceName, device.udid_,
380             notificationEnable, liveViewEnable);
381         ANS_LOGI("Dans set enable %{public}s %{public}s %{public}d %{public}d %{public}d.", deviceName.c_str(),
382             StringAnonymous(deviceId).c_str(), liveViewEnable, notificationEnable, result);
383     }
384 }
385 #else
InitCurrentDeviceStatus()386 void DistributedDeviceService::InitCurrentDeviceStatus()
387 {
388     bool notificationEnable = false;
389     bool liveViewEnable = false;
390     std::string localType = DeviceTypeToTypeString(localDevice_.deviceType_);
391     int32_t status = OberverService::GetInstance().IsScreenLocked();
392     auto result = NotificationHelper::IsDistributedEnabledBySlot(NotificationConstant::SlotType::LIVE_VIEW,
393         localType, liveViewEnable);
394     if (result != ERR_OK) {
395         ANS_LOGW("Dans get live view enable failed.");
396     }
397     result = NotificationHelper::IsDistributedEnabled(localType, notificationEnable);
398     if (result != ERR_OK) {
399         ANS_LOGW("Dans get notification enable failed.");
400     }
401     SyncDeviceStatus(STATE_TYPE_BOTH, status, notificationEnable, liveViewEnable);
402 }
403 
SyncDeviceStatus(int32_t type,int32_t status,bool notificationEnable,bool liveViewEnable)404 void DistributedDeviceService::SyncDeviceStatus(int32_t type, int32_t status,
405     bool notificationEnable, bool liveViewEnable)
406 {
407     std::shared_ptr<NotifticationStateBox> stateBox = std::make_shared<NotifticationStateBox>();
408     std::string deviceType = DeviceTypeToTypeString(localDevice_.deviceType_);
409     deviceType = DeviceTypeConversion(deviceType);
410     stateBox->SetDeviceType(deviceType);
411     stateBox->SetDeviceId(localDevice_.deviceId_);
412     if (type == STATE_TYPE_LOCKSCREEN || type == STATE_TYPE_BOTH) {
413         stateBox->SetState(status);
414     }
415     if (type == STATE_TYPE_SWITCH || type == STATE_TYPE_BOTH) {
416         stateBox->SetLiveViewEnable(liveViewEnable);
417         stateBox->SetNotificationEnable(notificationEnable);
418     }
419 
420     if (!stateBox->Serialize()) {
421         ANS_LOGW("Dans SyncDeviceState serialize failed.");
422         return;
423     }
424     bool isPad = IsLocalPadOrPC();
425     std::lock_guard<ffrt::mutex> lock(mapLock_);
426     for (const auto& peer : peerDevice_) {
427         if (isPad && peer.second.peerState_ != DeviceState::STATE_ONLINE) {
428             ANS_LOGI("DeviceState %{public}d %{public}d %{public}d %{public}d %{public}s.",
429                 status, notificationEnable, liveViewEnable, peer.second.deviceType_,
430                 StringAnonymous(peer.second.deviceId_).c_str());
431             continue;
432         }
433         std::shared_ptr<PackageInfo> packageInfo = std::make_shared<PackageInfo>(stateBox, peer.second,
434             TransDataType::DATA_TYPE_MESSAGE, MODIFY_ERROR_EVENT_CODE);
435         DistributedSendAdapter::GetInstance().SendPackage(packageInfo);
436         ANS_LOGI("DeviceState %{public}d %{public}d %{public}d %{public}d %{public}lu.",
437             type, status, liveViewEnable, notificationEnable, peerDevice_.size());
438     }
439 }
440 #endif
441 }
442 }
443 
444