1 /*
2 * Copyright (c) 2021-2022 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_screen_status_manager.h"
17
18 #include "ans_inner_errors.h"
19 #include "ans_log_wrapper.h"
20
21 namespace OHOS {
22 namespace Notification {
23 namespace {
24 const std::string APP_ID = "advanced_notification_service";
25 const std::string STORE_ID = "distributed_screen_status";
26 const std::string DELIMITER = "|";
27 const std::string SCREEN_STATUS_LABEL = "screen_status";
28 const std::string SCREEN_STATUS_VALUE_ON = "on";
29 const std::string SCREEN_STATUS_VALUE_OFF = "off";
30 } // namespace
31
DistributedScreenStatusManager()32 DistributedScreenStatusManager::DistributedScreenStatusManager() : DistributedFlowControl()
33 {
34 DistributedDeviceCallback::IDeviceChange callback = {
35 .OnConnected = std::bind(&DistributedScreenStatusManager::OnDeviceConnected, this, std::placeholders::_1),
36 .OnDisconnected = std::bind(&DistributedScreenStatusManager::OnDeviceDisconnected, this, std::placeholders::_1),
37 };
38 deviceCb_ = std::make_shared<DistributedDeviceCallback>(callback);
39 GetKvDataManager();
40 GetKvStore();
41 }
42
~DistributedScreenStatusManager()43 DistributedScreenStatusManager::~DistributedScreenStatusManager()
44 {}
45
OnDeviceConnected(const std::string & deviceId)46 void DistributedScreenStatusManager::OnDeviceConnected(const std::string &deviceId)
47 {
48 ANS_LOGI("deviceId");
49 }
50
OnDeviceDisconnected(const std::string & deviceId)51 void DistributedScreenStatusManager::OnDeviceDisconnected(const std::string &deviceId)
52 {
53 std::lock_guard<std::recursive_mutex> lock(mutex_);
54 if (!CheckKvDataManager()) {
55 return;
56 }
57
58 std::vector<DistributedKv::DeviceInfo> devInfoList;
59 DistributedKv::Status status =
60 kvDataManager_->GetDeviceList(devInfoList, DistributedKv::DeviceFilterStrategy::NO_FILTER);
61 if (status != DistributedKv::Status::SUCCESS) {
62 ANS_LOGE("kvDataManager GetDeviceList() failed ret = 0x%{public}x", status);
63 kvDataManager_.reset();
64 return;
65 }
66
67 if (!devInfoList.empty()) {
68 return;
69 }
70
71 kvStore_.reset();
72
73 DistributedKv::AppId appId = {.appId = APP_ID};
74 DistributedKv::StoreId storeId = {.storeId = STORE_ID};
75 kvDataManager_->DeleteKvStore(appId, storeId);
76
77 if (!CheckKvStore()) {
78 return;
79 }
80
81 SetLocalScreenStatus(localScreenOn_);
82 }
83
GetKvDataManager(void)84 void DistributedScreenStatusManager::GetKvDataManager(void)
85 {
86 kvDataManager_ = std::make_unique<DistributedKv::DistributedKvDataManager>();
87 if (kvDataManager_ != nullptr) {
88 DistributedKv::Status status = kvDataManager_->StartWatchDeviceChange(deviceCb_);
89 if (status != DistributedKv::Status::SUCCESS) {
90 ANS_LOGW("kvDataManager StartWatchDeviceChange failed ret = 0x%{public}x", status);
91 kvDataManager_.reset();
92 }
93 }
94
95 KvManagerFlowControlClear();
96 }
97
CheckKvDataManager(void)98 bool DistributedScreenStatusManager::CheckKvDataManager(void)
99 {
100 if (kvDataManager_ == nullptr) {
101 GetKvDataManager();
102 }
103 if (kvDataManager_ == nullptr) {
104 ANS_LOGE("kvDataManager is nullptr.");
105 return false;
106 }
107 return true;
108 }
109
GetKvStore(void)110 void DistributedScreenStatusManager::GetKvStore(void)
111 {
112 if (!CheckKvDataManager()) {
113 return;
114 }
115
116 DistributedKv::Status status;
117 DistributedKv::Options options;
118 options.createIfMissing = true;
119 options.autoSync = true;
120 options.kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION;
121
122 DistributedKv::AppId appId = {.appId = APP_ID};
123 DistributedKv::StoreId storeId = {.storeId = STORE_ID};
124 status = kvDataManager_->GetSingleKvStore(options, appId, storeId, kvStore_);
125 if (status != DistributedKv::Status::SUCCESS) {
126 ANS_LOGE("kvDataManager GetSingleKvStore failed ret = 0x%{public}x", status);
127 kvStore_.reset();
128 kvDataManager_->StopWatchDeviceChange(deviceCb_);
129 kvDataManager_.reset();
130 return;
131 }
132
133 KvStoreFlowControlClear();
134 }
135
CheckKvStore(void)136 bool DistributedScreenStatusManager::CheckKvStore(void)
137 {
138 if (kvStore_ == nullptr) {
139 GetKvStore();
140 }
141 if (kvStore_ == nullptr) {
142 ANS_LOGE("kvStore is nullptr.");
143 return false;
144 }
145 return true;
146 }
147
GenerateDistributedKey(const std::string & deviceId)148 std::string DistributedScreenStatusManager::GenerateDistributedKey(const std::string &deviceId)
149 {
150 return deviceId + DELIMITER + SCREEN_STATUS_LABEL;
151 }
152
CheckRemoteDevicesIsUsing(bool & isUsing)153 ErrCode DistributedScreenStatusManager::CheckRemoteDevicesIsUsing(bool &isUsing)
154 {
155 std::lock_guard<std::recursive_mutex> lock(mutex_);
156 if (!CheckKvDataManager() || !CheckKvStore()) {
157 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
158 }
159
160 if (!KvManagerFlowControl() || !KvStoreFlowControl()) {
161 ANS_LOGE("flow control.");
162 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
163 }
164
165 std::vector<DistributedKv::DeviceInfo> devInfoList;
166 DistributedKv::Status status =
167 kvDataManager_->GetDeviceList(devInfoList, DistributedKv::DeviceFilterStrategy::NO_FILTER);
168 if (status != DistributedKv::Status::SUCCESS) {
169 ANS_LOGE("kvDataManager GetDeviceList() failed ret = 0x%{public}x", status);
170 kvDataManager_.reset();
171 return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
172 }
173
174 DistributedKv::Key prefixKey("");
175 std::vector<DistributedKv::Entry> entries;
176 status = kvStore_->GetEntries(prefixKey, entries);
177 if (status != DistributedKv::Status::SUCCESS) {
178 ANS_LOGE("kvStore GetEntries() failed ret = 0x%{public}x", status);
179 kvStore_.reset();
180 return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
181 }
182
183 for (auto entry : entries) {
184 std::string key = entry.key.ToString();
185 std::string deviceId = key.substr(0, key.find_first_of(DELIMITER));
186 ANS_LOGD("value:%{public}s", entry.value.ToString().c_str());
187 for (auto devInfo : devInfoList) {
188 if (devInfo.deviceId == deviceId) {
189 isUsing = isUsing || (entry.value.ToString() == SCREEN_STATUS_VALUE_ON);
190 break;
191 }
192 }
193 if (isUsing) {
194 break;
195 }
196 }
197
198 ANS_LOGI("%{public}s, isUsing:%{public}s", __FUNCTION__, isUsing ? "true" : "false");
199 return ERR_OK;
200 }
201
SetLocalScreenStatus(bool screenOn)202 ErrCode DistributedScreenStatusManager::SetLocalScreenStatus(bool screenOn)
203 {
204 std::lock_guard<std::recursive_mutex> lock(mutex_);
205 ANS_LOGI("%{public}s, screenOn:%{public}s", __FUNCTION__, screenOn ? "true" : "false");
206 localScreenOn_ = screenOn;
207 if (!CheckKvStore()) {
208 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
209 }
210
211 if (!KvManagerFlowControl() || !KvStoreFlowControl()) {
212 ANS_LOGE("flow control.");
213 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
214 }
215
216 DistributedKv::DeviceInfo localDevice;
217 DistributedKv::Status status = kvDataManager_->GetLocalDevice(localDevice);
218 if (status != DistributedKv::Status::SUCCESS) {
219 ANS_LOGE("kvDataManager GetLocalDevice() failed ret = 0x%{public}x", status);
220 return ERR_ANS_DISTRIBUTED_GET_INFO_FAILED;
221 }
222
223 DistributedKv::Key kvStoreKey = GenerateDistributedKey(localDevice.deviceId);
224 DistributedKv::Value kvStoreValue = screenOn ? SCREEN_STATUS_VALUE_ON : SCREEN_STATUS_VALUE_OFF;
225 status = kvStore_->Put(kvStoreKey, kvStoreValue);
226 if (status != DistributedKv::Status::SUCCESS) {
227 ANS_LOGE("kvStore Put() failed ret = 0x%{public}x", status);
228 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
229 }
230
231 return ERR_OK;
232 }
233 } // namespace Notification
234 } // namespace OHOS
235