1 /*
2 * Copyright (c) 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_preferences.h"
17
18 #include <map>
19
20 #include "ans_log_wrapper.h"
21
22 namespace OHOS {
23 namespace Notification {
24 namespace {
25 const std::string DISTRIBUTED_LABEL = "distributed";
26 const std::string DELIMITER = "|";
27 const std::string MAIN_LABEL = "ans_main";
28 const std::string BUNDLE_LABEL = "bundle";
29 const std::string WITHOUT_APP = "without_app";
30 } // namespace
31
GetBoolFromString(const std::string & str)32 inline bool GetBoolFromString(const std::string &str)
33 {
34 return static_cast<bool>(atoi(str.data()));
35 }
36
DistributedPreferences()37 DistributedPreferences::DistributedPreferences()
38 {
39 database_ = std::make_unique<DistributedPreferencesDatabase>();
40
41 preferencesInfo_ = std::make_unique<DistributedPreferencesInfo>();
42 InitDistributedAllInfo();
43 }
44
~DistributedPreferences()45 DistributedPreferences::~DistributedPreferences()
46 {}
47
InitDistributedAllInfo(void)48 bool DistributedPreferences::InitDistributedAllInfo(void)
49 {
50 std::vector<DistributedPreferencesDatabase::Entry> entries;
51 if (!database_->GetEntriesFromDistributedDB(DISTRIBUTED_LABEL, entries)) {
52 return false;
53 }
54
55 for (auto entry : entries) {
56 if (!ResolveDistributedKey(entry)) {
57 ANS_LOGE("key <%{public}s> is invalid.", entry.key.ToString().c_str());
58 }
59 }
60
61 return true;
62 }
63
GetDistributedMainKey(std::string & key)64 void DistributedPreferences::GetDistributedMainKey(std::string &key)
65 {
66 key = DISTRIBUTED_LABEL + DELIMITER + MAIN_LABEL + DELIMITER;
67 }
68
GetDistributedBundleKey(const sptr<NotificationBundleOption> & bundleOption,std::string & key)69 void DistributedPreferences::GetDistributedBundleKey(
70 const sptr<NotificationBundleOption> &bundleOption, std::string &key)
71 {
72 if (bundleOption) {
73 key = DISTRIBUTED_LABEL + DELIMITER + BUNDLE_LABEL + DELIMITER + bundleOption->GetBundleName() + DELIMITER +
74 std::to_string(bundleOption->GetUid());
75 }
76 }
77
ResolveDistributedKey(const DistributedKv::Entry & entry)78 bool DistributedPreferences::ResolveDistributedKey(const DistributedKv::Entry &entry)
79 {
80 std::string key = entry.key.ToString();
81 std::size_t distributedLabelPosition = 0;
82 std::size_t distributedLabelEndPosition = key.find(DELIMITER, distributedLabelPosition);
83 if (distributedLabelEndPosition == std::string::npos) {
84 return false;
85 }
86 std::size_t typeLabelPosition = distributedLabelEndPosition + DELIMITER.size();
87 std::size_t typeLabelEndPosition = key.find(DELIMITER, typeLabelPosition);
88 if (typeLabelPosition == std::string::npos) {
89 return false;
90 }
91
92 std::string sign = key.substr(typeLabelPosition, typeLabelEndPosition - typeLabelPosition);
93 if (sign == MAIN_LABEL) {
94 return ResolveDistributedEnable(entry.value.ToString());
95 }
96 if (sign == WITHOUT_APP) {
97 return ResolveSyncWithoutAppEnable(key, typeLabelEndPosition, entry.value.ToString());
98 }
99 return ResolveDistributedBundleEnable(key, typeLabelEndPosition, entry.value.ToString());
100 }
101
ResolveDistributedEnable(const std::string & value)102 bool DistributedPreferences::ResolveDistributedEnable(const std::string &value)
103 {
104 int32_t enabled = atoi(value.data());
105 preferencesInfo_->SetDistributedEnable(static_cast<bool>(enabled));
106
107 return true;
108 }
109
ResolveDistributedBundleEnable(const std::string & key,const int32_t startPos,const std::string & value)110 bool DistributedPreferences::ResolveDistributedBundleEnable(const std::string &key,
111 const int32_t startPos, const std::string &value)
112 {
113 std::size_t bundleNamePosition = startPos + DELIMITER.size();
114 std::size_t bundleNameEndPosition = key.find(DELIMITER, bundleNamePosition);
115 if (bundleNameEndPosition == std::string::npos) {
116 return false;
117 }
118
119 std::size_t uidPosition = key.find_last_of(DELIMITER) + DELIMITER.size();
120 if (uidPosition < bundleNameEndPosition) {
121 return false;
122 }
123
124 std::string bundleName = key.substr(bundleNamePosition, bundleNameEndPosition - bundleNamePosition);
125 int32_t uid = atoi(&key[uidPosition]);
126 preferencesInfo_->SetDistributedBundleEnable(bundleName, uid, GetBoolFromString(value));
127
128 return true;
129 }
130
ResolveSyncWithoutAppEnable(const std::string & key,const int32_t startPos,const std::string & value)131 bool DistributedPreferences::ResolveSyncWithoutAppEnable(const std::string &key,
132 const int32_t startPos, const std::string &value)
133 {
134 std::size_t pos = startPos + DELIMITER.size();
135 int32_t userId = atoi(&key[pos]);
136 preferencesInfo_->SetSyncEnabledWithoutApp(userId, GetBoolFromString(value));
137
138 return true;
139 }
140
SetDistributedEnable(bool isEnable)141 ErrCode DistributedPreferences::SetDistributedEnable(bool isEnable)
142 {
143 ANS_LOGI("%{public}s start", __FUNCTION__);
144 std::string key;
145 GetDistributedMainKey(key);
146
147 if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) {
148 ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
149 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
150 }
151
152 preferencesInfo_->SetDistributedEnable(isEnable);
153
154 return ERR_OK;
155 }
156
GetDistributedEnable(bool & isEnable)157 ErrCode DistributedPreferences::GetDistributedEnable(bool &isEnable)
158 {
159 ANS_LOGI("%{public}s start", __FUNCTION__);
160
161 isEnable = preferencesInfo_->GetDistributedEnable();
162
163 return ERR_OK;
164 }
165
SetDistributedBundleEnable(const sptr<NotificationBundleOption> & bundleOption,bool isEnable)166 ErrCode DistributedPreferences::SetDistributedBundleEnable(
167 const sptr<NotificationBundleOption> &bundleOption, bool isEnable)
168 {
169 ANS_LOGI("%{public}s start", __FUNCTION__);
170 if (bundleOption == nullptr) {
171 ANS_LOGE("bundleOption is nullptr.");
172 return ERR_ANS_INVALID_PARAM;
173 }
174
175 std::string key;
176 GetDistributedBundleKey(bundleOption, key);
177
178 if (!database_->PutToDistributedDB(key, std::to_string(isEnable))) {
179 ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
180 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
181 }
182
183 preferencesInfo_->SetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid(), isEnable);
184
185 return ERR_OK;
186 }
187
GetDistributedBundleEnable(const sptr<NotificationBundleOption> & bundleOption,bool & isEnable)188 ErrCode DistributedPreferences::GetDistributedBundleEnable(
189 const sptr<NotificationBundleOption> &bundleOption, bool &isEnable)
190 {
191 ANS_LOGI("%{public}s start", __FUNCTION__);
192 if (bundleOption == nullptr) {
193 ANS_LOGE("bundleOption is nullptr.");
194 return ERR_ANS_INVALID_PARAM;
195 }
196
197 isEnable = preferencesInfo_->GetDistributedBundleEnable(bundleOption->GetBundleName(), bundleOption->GetUid());
198
199 return ERR_OK;
200 }
201
DeleteDistributedBundleInfo(const sptr<NotificationBundleOption> & bundleOption)202 ErrCode DistributedPreferences::DeleteDistributedBundleInfo(const sptr<NotificationBundleOption> &bundleOption)
203 {
204 ANS_LOGI("%{public}s start", __FUNCTION__);
205 if (bundleOption == nullptr) {
206 ANS_LOGE("bundleOption is nullptr.");
207 return ERR_ANS_INVALID_PARAM;
208 }
209
210 std::string key;
211 GetDistributedBundleKey(bundleOption, key);
212
213 if (!database_->DeleteToDistributedDB(key)) {
214 ANS_LOGE("delete to distributed DB failed. key:%{public}s", key.c_str());
215 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
216 }
217
218 preferencesInfo_->DeleteDistributedBundleInfo(bundleOption->GetBundleName(), bundleOption->GetUid());
219
220 return ERR_OK;
221 }
222
ClearDataInRestoreFactorySettings()223 ErrCode DistributedPreferences::ClearDataInRestoreFactorySettings()
224 {
225 if (!database_->ClearDatabase()) {
226 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
227 }
228
229 SetDistributedEnable(false);
230
231 preferencesInfo_ = std::make_unique<DistributedPreferencesInfo>();
232
233 return ERR_OK;
234 }
235
GetEnabledWithoutApp(const int32_t userId,std::string & key)236 void DistributedPreferences::GetEnabledWithoutApp(const int32_t userId, std::string &key)
237 {
238 key = DISTRIBUTED_LABEL + DELIMITER + WITHOUT_APP + DELIMITER + std::to_string(userId) + DELIMITER;
239 }
240
SetSyncEnabledWithoutApp(const int32_t userId,const bool enabled)241 ErrCode DistributedPreferences::SetSyncEnabledWithoutApp(const int32_t userId, const bool enabled)
242 {
243 std::string key;
244 GetEnabledWithoutApp(userId, key);
245
246 if (!database_->PutToDistributedDB(key, std::to_string(enabled))) {
247 ANS_LOGE("put to distributed DB failed. key:%{public}s", key.c_str());
248 return ERR_ANS_DISTRIBUTED_OPERATION_FAILED;
249 }
250
251 preferencesInfo_->SetSyncEnabledWithoutApp(userId, enabled);
252
253 return ERR_OK;
254 }
255
GetSyncEnabledWithoutApp(const int32_t userId,bool & enabled)256 ErrCode DistributedPreferences::GetSyncEnabledWithoutApp(const int32_t userId, bool &enabled)
257 {
258 return preferencesInfo_->GetSyncEnabledWithoutApp(userId, enabled);
259 }
260 } // namespace Notification
261 } // namespace OHOS