1 /*
2 * Copyright (c) 2024 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_status.h"
17
18 #include "distributed_data_define.h"
19 #ifdef ALL_SCENARIO_COLLABORATION
20 #include "distributed_extension_service.h"
21 #endif
22 #include "ans_inner_errors.h"
23
24 namespace OHOS {
25 namespace Notification {
26 namespace {
27 const static std::string WEARABLE = "wearable";
28 const static std::string LITEWEARABLE = "liteWearable";
29 }
30
31 DistributedDeviceStatus::DistributedDeviceStatus() = default;
32
33 DistributedDeviceStatus::~DistributedDeviceStatus() = default;
34
SetDeviceStatus(const std::string & deviceType,const uint32_t status,const uint32_t controlFlag)35 ErrCode DistributedDeviceStatus::SetDeviceStatus(const std::string &deviceType, const uint32_t status,
36 const uint32_t controlFlag)
37 {
38 std::lock_guard<ffrt::mutex> lock(mapLock_);
39 uint32_t oldStatus = deviceStatus_.ReadVal(deviceType);
40 for (uint32_t i = 0; i < STATUS_SIZE; i++) {
41 if (((1 << i) & controlFlag) && ((1 << i) & status)) {
42 oldStatus |= (1 << i);
43 }
44 if (((1 << i) & controlFlag) && !((1 << i) & status)) {
45 oldStatus &= ~(1 << i);
46 }
47 }
48 if (deviceType == LITEWEARABLE) {
49 uint32_t wearableStatus = deviceStatus_.ReadVal(WEARABLE);
50 for (uint32_t i = 0; i < STATUS_SIZE; i++) {
51 if (((1 << i) & controlFlag) && ((1 << i) & status)) {
52 wearableStatus |= (1 << i);
53 }
54 if (((1 << i) & controlFlag) && !((1 << i) & status)) {
55 wearableStatus &= ~(1 << i);
56 }
57 }
58 deviceStatus_.EnsureInsert(WEARABLE, wearableStatus);
59 ANS_LOGI("update lite wearable status %{public}u %{public}u", wearableStatus, status);
60 }
61 deviceStatus_.EnsureInsert(deviceType, oldStatus);
62 ANS_LOGI("update %{public}s status %{public}u %{public}u", deviceType.c_str(), oldStatus, status);
63 return ERR_OK;
64 }
65
ChangeStatus(DeviceStatus & device,const std::string & deviceType,const uint32_t status,const uint32_t controlFlag,int32_t userId)66 void ChangeStatus(DeviceStatus& device, const std::string &deviceType, const uint32_t status,
67 const uint32_t controlFlag, int32_t userId)
68 {
69 uint32_t beforeStatus = device.status;
70 if ((1 << DistributedDeviceStatus::USERID_FLAG) & controlFlag) {
71 device.userId = userId;
72 }
73 for (uint32_t i = 0; i < DistributedDeviceStatus::STATUS_SIZE; i++) {
74 if (((1 << i) & controlFlag) && ((1 << i) & status)) {
75 device.status |= (1 << i);
76 }
77 if (((1 << i) & controlFlag) && !((1 << i) & status)) {
78 device.status &= ~(1 << i);
79 }
80 }
81
82 #ifdef ALL_SCENARIO_COLLABORATION
83 if (deviceType == NotificationConstant::PAD_DEVICE_TYPE ||
84 deviceType == NotificationConstant::PC_DEVICE_TYPE) {
85 DeviceStatueChangeInfo changeInfo;
86 changeInfo.deviceId = device.deviceId;
87 if (((1 << DistributedDeviceStatus::USING_FLAG) & controlFlag) &&
88 ((1 << DistributedDeviceStatus::USING_FLAG) & device.status)) {
89 changeInfo.changeType = DeviceStatueChangeType::DEVICE_USING_ONLINE;
90 DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo);
91 ANS_LOGI("notify %{public}s %{public}s using change.", device.deviceType.c_str(),
92 StringAnonymous(device.deviceId).c_str());
93 } else if (((1 << DistributedDeviceStatus::USING_FLAG) & controlFlag) &&
94 ((1 << DistributedDeviceStatus::USING_FLAG) & device.status) == 0) {
95 changeInfo.changeType = DeviceStatueChangeType::DEVICE_USING_CLOSE;
96 DistributedExtensionService::GetInstance().DeviceStatusChange(changeInfo);
97 }
98 }
99 #endif
100
101 ANS_LOGI("update %{public}s %{public}s %{public}d status %{public}d %{public}u %{public}u",
102 device.deviceType.c_str(), StringAnonymous(device.deviceId).c_str(), userId, controlFlag,
103 beforeStatus, device.status);
104 }
105
SetDeviceStatus(const std::string & deviceType,const uint32_t status,const uint32_t controlFlag,const std::string deviceId,int32_t userId)106 ErrCode DistributedDeviceStatus::SetDeviceStatus(const std::string &deviceType, const uint32_t status,
107 const uint32_t controlFlag, const std::string deviceId, int32_t userId)
108 {
109 bool existFlag = false;
110 std::string deviceStatusId = deviceId;
111 uint32_t finalStatus = 0;
112 bool allConnect = ((1 << NETWORKID_FLAG) & controlFlag);
113 #ifdef ALL_SCENARIO_COLLABORATION
114 if (allConnect) {
115 std::string udid;
116 int32_t result = DistributedExtensionService::GetInstance().TransDeviceIdToUdid(deviceId, udid);
117 if (result != ERR_OK) {
118 ANS_LOGI("Get udid failed %{public}s %{public}s %{public}d ", deviceType.c_str(),
119 StringAnonymous(deviceStatusId).c_str(), result);
120 return ERR_ANS_TASK_ERR;
121 }
122 deviceStatusId = udid;
123 }
124 #endif
125
126 std::lock_guard<ffrt::mutex> lock(mapLock_);
127 for (auto device = deviceInfo_.begin(); device != deviceInfo_.end(); device++) {
128 if (device->deviceType != deviceType || device->deviceId != deviceStatusId) {
129 continue;
130 }
131
132 if (allConnect && ((1 << DistributedDeviceStatus::USING_FLAG) & device->status) == 0) {
133 ANS_LOGI("No change %{public}s %{public}s", deviceType.c_str(), StringAnonymous(deviceStatusId).c_str());
134 continue;
135 }
136 ChangeStatus(*device, deviceType, status, controlFlag, userId);
137 ANS_LOGI("update sttuas %{public}s %{public}u", StringAnonymous(device->deviceId).c_str(), device->status);
138 existFlag = true;
139 break;
140 }
141
142 // for allconnect release device
143 if (allConnect) {
144 ANS_LOGI("Not need %{public}s %{public}s", deviceType.c_str(), StringAnonymous(deviceStatusId).c_str());
145 return ERR_OK;
146 }
147
148 if (!existFlag) {
149 DeviceStatus device = DeviceStatus(deviceType, deviceStatusId);
150 ChangeStatus(device, deviceType, status, controlFlag, userId);
151 deviceInfo_.emplace_back(device);
152 ANS_LOGI("Add device %{public}s %{public}s", deviceType.c_str(), StringAnonymous(deviceStatusId).c_str());
153 }
154 return ERR_OK;
155 }
156
GetDeviceStatus(const std::string & deviceType)157 uint32_t DistributedDeviceStatus::GetDeviceStatus(const std::string &deviceType)
158 {
159 std::lock_guard<ffrt::mutex> lock(mapLock_);
160 return deviceStatus_.ReadVal(deviceType);
161 }
162
GetMultiDeviceStatus(const std::string & deviceType,const uint32_t status)163 DeviceStatus DistributedDeviceStatus::GetMultiDeviceStatus(
164 const std::string &deviceType, const uint32_t status)
165 {
166 std::lock_guard<ffrt::mutex> lock(mapLock_);
167 for (DeviceStatus device : deviceInfo_) {
168 if (device.deviceType == deviceType && (device.status & status) == status) {
169 return device;
170 }
171 }
172 return DeviceStatus("", "");
173 }
174 } // namespace Notification
175 } // namespace OHOS
176