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