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