1 /*
2 * Copyright (c) 2025 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 #include "settings_data_manager.h"
16
17 #include <charconv>
18
19 #include "datashare_helper.h"
20 #include "datashare_errno.h"
21 #include "datashare_result_set.h"
22 #include "dfs_error.h"
23 #include "utils_log.h"
24
25 namespace OHOS::FileManagement::CloudSync {
26 static const std::string SETTING_DATA_QUERY_URI = "datashareproxy://";
27 static const std::string SETTING_DATA_COMMON_URI =
28 "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
29 static const std::string SYNC_SWITCH_KEY = "photos_sync_options"; // "0", "1", "2"
30 static const std::string NETWORK_CONNECTION_KEY = "photo_network_connection_status"; // "on", "off"
31 static const std::string LOCAL_SPACE_FREE_KEY = "photos_local_space_free"; // "1", "0"
32 static const std::string LOCAL_SPACE_DAYS_KEY = "photos_local_space_free_day_count"; // "30"
33 static const std::string MOBILE_DATA_SYNC_KEY = "photos_mobile_data_sync"; // "1", "0"
34 static const std::string AI_FAMILY_STATUS = "2";
35 static const std::string CLOUD_STATUS = "1";
36 static const std::string OPEN_STATUS = "on";
37 static const std::string ALLOW_STATUS = "1";
38 static const std::string LSF_ALLOW_STATUS = "0";
39 static const int32_t LOCAL_SPACE_DAYS_DEFAULT = 30;
40
InitSettingsDataManager()41 void SettingsDataManager::InitSettingsDataManager()
42 {
43 LOGI("InitSettingsDataManager");
44 RegisterObserver(SYNC_SWITCH_KEY);
45 RegisterObserver(NETWORK_CONNECTION_KEY);
46 RegisterObserver(MOBILE_DATA_SYNC_KEY);
47 RegisterObserver(LOCAL_SPACE_FREE_KEY);
48 RegisterObserver(LOCAL_SPACE_DAYS_KEY);
49 QuerySwitchStatus();
50 QueryNetworkConnectionStatus();
51 QueryLocalSpaceFreeStatus();
52 QueryLocalSpaceFreeDays();
53 QueryMobileDataStatus();
54 }
55
QuerySwitchStatus()56 int32_t SettingsDataManager::QuerySwitchStatus()
57 {
58 std::string value;
59 int32_t ret = QueryParamInSettingsData(SYNC_SWITCH_KEY, value);
60 if (ret != E_OK) {
61 LOGE("query SYNC_SWITCH_KEY failed");
62 settingsDataMap_.Erase(SYNC_SWITCH_KEY);
63 return ret;
64 }
65 settingsDataMap_.EnsureInsert(SYNC_SWITCH_KEY, value);
66 return E_OK;
67 }
68
QueryNetworkConnectionStatus()69 int32_t SettingsDataManager::QueryNetworkConnectionStatus()
70 {
71 std::string value;
72 int32_t ret = QueryParamInSettingsData(NETWORK_CONNECTION_KEY, value);
73 if (ret != E_OK) {
74 LOGE("query NETWORK_CONNECTION_KEY failed");
75 settingsDataMap_.Erase(NETWORK_CONNECTION_KEY);
76 return ret;
77 }
78 settingsDataMap_.EnsureInsert(NETWORK_CONNECTION_KEY, value);
79 return E_OK;
80 }
81
QueryMobileDataStatus()82 int32_t SettingsDataManager::QueryMobileDataStatus()
83 {
84 std::string value;
85 int32_t ret = QueryParamInSettingsData(MOBILE_DATA_SYNC_KEY, value);
86 if (ret != E_OK) {
87 LOGE("query MOBILE_DATA_SYNC_KEY failed");
88 settingsDataMap_.Erase(MOBILE_DATA_SYNC_KEY);
89 return ret;
90 }
91 settingsDataMap_.EnsureInsert(MOBILE_DATA_SYNC_KEY, value);
92 return E_OK;
93 }
94
QueryLocalSpaceFreeStatus()95 int32_t SettingsDataManager::QueryLocalSpaceFreeStatus()
96 {
97 std::string value;
98 int32_t ret = QueryParamInSettingsData(LOCAL_SPACE_FREE_KEY, value);
99 if (ret != E_OK) {
100 LOGE("query LOCAL_SPACE_FREE_KEY failed");
101 settingsDataMap_.Erase(LOCAL_SPACE_FREE_KEY);
102 return ret;
103 }
104 settingsDataMap_.EnsureInsert(LOCAL_SPACE_FREE_KEY, value);
105 return E_OK;
106 }
107
QueryLocalSpaceFreeDays()108 int32_t SettingsDataManager::QueryLocalSpaceFreeDays()
109 {
110 std::string value;
111 int32_t ret = QueryParamInSettingsData(LOCAL_SPACE_DAYS_KEY, value);
112 if (ret != E_OK) {
113 LOGE("query LOCAL_SPACE_DAYS_KEY failed");
114 settingsDataMap_.Erase(LOCAL_SPACE_DAYS_KEY);
115 return ret;
116 }
117 settingsDataMap_.EnsureInsert(LOCAL_SPACE_DAYS_KEY, value);
118 return E_OK;
119 }
120
GetSwitchStatus()121 SwitchStatus SettingsDataManager::GetSwitchStatus()
122 {
123 std::string value;
124 int32_t ret = QuerySwitchStatus();
125 if (ret == E_INNER_RDB) {
126 return SwitchStatus::CLOUD_SPACE;
127 } else if (ret == E_RDB) {
128 return SwitchStatus::NONE;
129 }
130
131 value = settingsDataMap_.ReadVal(SYNC_SWITCH_KEY);
132 if (value == AI_FAMILY_STATUS) {
133 return SwitchStatus::AI_FAMILY;
134 } else if (value == CLOUD_STATUS) {
135 return SwitchStatus::CLOUD_SPACE;
136 } else {
137 return SwitchStatus::NONE;
138 }
139 }
140
GetSwitchStatusByCache()141 SwitchStatus SettingsDataManager::GetSwitchStatusByCache()
142 {
143 std::string value;
144 if (!settingsDataMap_.Find(SYNC_SWITCH_KEY, value)) {
145 return GetSwitchStatus();
146 }
147
148 value = settingsDataMap_.ReadVal(SYNC_SWITCH_KEY);
149 if (value == AI_FAMILY_STATUS) {
150 return SwitchStatus::AI_FAMILY;
151 } else if (value == CLOUD_STATUS) {
152 return SwitchStatus::CLOUD_SPACE;
153 } else {
154 return SwitchStatus::NONE;
155 }
156 }
157
GetNetworkConnectionStatus()158 bool SettingsDataManager::GetNetworkConnectionStatus()
159 {
160 std::string value;
161 if (!settingsDataMap_.Find(NETWORK_CONNECTION_KEY, value)) {
162 if (QueryNetworkConnectionStatus() != E_OK) {
163 return true;
164 }
165 }
166
167 value = settingsDataMap_.ReadVal(NETWORK_CONNECTION_KEY);
168 return value == OPEN_STATUS;
169 }
170
GetMobileDataStatus()171 bool SettingsDataManager::GetMobileDataStatus()
172 {
173 std::string value;
174 if (!settingsDataMap_.Find(MOBILE_DATA_SYNC_KEY, value)) {
175 if (QueryMobileDataStatus() != E_OK) {
176 return false;
177 }
178 }
179
180 value = settingsDataMap_.ReadVal(MOBILE_DATA_SYNC_KEY);
181 return value == ALLOW_STATUS;
182 }
183
GetLocalSpaceFreeStatus()184 int32_t SettingsDataManager::GetLocalSpaceFreeStatus()
185 {
186 std::string value;
187 if (!settingsDataMap_.Find(LOCAL_SPACE_FREE_KEY, value)) {
188 if (QueryLocalSpaceFreeStatus() != E_OK) {
189 return 1;
190 }
191 }
192 value = settingsDataMap_.ReadVal(LOCAL_SPACE_FREE_KEY);
193 if (value == LSF_ALLOW_STATUS) {
194 return 0;
195 } else {
196 return 1;
197 }
198 }
199
ConvertToInt(const std::string & str,int32_t & val)200 static bool ConvertToInt(const std::string &str, int32_t &val)
201 {
202 auto [ptr, ec] = std::from_chars(str.c_str(), str.c_str() + str.size(), val);
203 return ec == std::errc() && ptr == str.c_str() + str.size();
204 }
205
GetLocalSpaceFreeDays()206 int32_t SettingsDataManager::GetLocalSpaceFreeDays()
207 {
208 std::string value;
209 if (!settingsDataMap_.Find(LOCAL_SPACE_DAYS_KEY, value)) {
210 if (QueryLocalSpaceFreeDays() != E_OK) {
211 return LOCAL_SPACE_DAYS_DEFAULT;
212 }
213 }
214
215 value = settingsDataMap_.ReadVal(LOCAL_SPACE_DAYS_KEY);
216 int32_t val = 0;
217 if (ConvertToInt(value, val)) {
218 return val;
219 } else {
220 LOGE("ConvertToInt failed, value: %{public}s", value.c_str());
221 return LOCAL_SPACE_DAYS_DEFAULT;
222 }
223 }
224
QueryParamInSettingsData(const std::string & key,std::string & value)225 int32_t SettingsDataManager::QueryParamInSettingsData(const std::string &key, std::string &value)
226 {
227 LOGI("Query key: %{public}s", key.c_str());
228 DataShare::DataSharePredicates predicates;
229 predicates.EqualTo("KEYWORD", key);
230 std::vector<std::string> columns = {"value"};
231 DataShare::CreateOptions options;
232 options.enabled_ = true;
233 auto dataShareHelper = DataShare::DataShareHelper::Creator(SETTING_DATA_QUERY_URI, options);
234 if (dataShareHelper == nullptr) {
235 LOGE("dataShareHelper == nullptr");
236 return E_RDB;
237 }
238
239 std::string queryUri = SETTING_DATA_COMMON_URI + "&key=" + key;
240 Uri uri(queryUri);
241 std::shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper->Query(uri, predicates, columns);
242 dataShareHelper->Release();
243 if (resultSet == nullptr) {
244 LOGE("resultSet == nullptr");
245 return E_RDB;
246 }
247 if (resultSet->GoToFirstRow() != E_OK) {
248 LOGW("not found key: %{public}s", key.c_str());
249 return E_INNER_RDB;
250 }
251 int32_t columnIndex = 0;
252 if (resultSet->GetColumnIndex("value", columnIndex) != E_OK) {
253 LOGE("GetColumnIndex failed");
254 return E_RDB;
255 }
256 if (resultSet->GetString(columnIndex, value) != E_OK) {
257 LOGE("GetString failed");
258 return E_RDB;
259 }
260
261 LOGI("Query success, value: %{public}s", value.c_str());
262 return E_OK;
263 }
264
RegisterObserver(const std::string & key)265 void SettingsDataManager::RegisterObserver(const std::string &key)
266 {
267 LOGD("register key: %{public}s", key.c_str());
268 DataShare::CreateOptions options;
269 options.enabled_ = true;
270 auto dataShareHelper = DataShare::DataShareHelper::Creator(SETTING_DATA_QUERY_URI, options);
271 if (dataShareHelper == nullptr) {
272 LOGE("dataShareHelper == nullptr");
273 return;
274 }
275 sptr<SettingsDataObserver> dataObserver(new (std::nothrow) SettingsDataObserver(key));
276 Uri observerUri(SETTING_DATA_COMMON_URI + "&key=" + key);
277 dataShareHelper->RegisterObserver(observerUri, dataObserver);
278 dataShareHelper->Release();
279 LOGI("Register SettingsDataObserver key: %{public}s finish", key.c_str());
280 }
281
RegisterObserver(const std::string & key,sptr<AAFwk::DataAbilityObserverStub> dataObserver)282 void SettingsDataManager::RegisterObserver(const std::string &key, sptr<AAFwk::DataAbilityObserverStub> dataObserver)
283 {
284 LOGD("register key: %{public}s", key.c_str());
285 DataShare::CreateOptions options;
286 options.enabled_ = true;
287 auto dataShareHelper = DataShare::DataShareHelper::Creator(SETTING_DATA_QUERY_URI, options);
288 if (dataShareHelper == nullptr) {
289 LOGE("dataShareHelper == nullptr");
290 return;
291 }
292
293 Uri observerUri(SETTING_DATA_COMMON_URI + "&key=" + key);
294 dataShareHelper->RegisterObserver(observerUri, dataObserver);
295 dataShareHelper->Release();
296 LOGI("Register SettingsDataObserver key: %{public}s finish", key.c_str());
297 }
298
UnregisterObserver(const std::string & key)299 void SettingsDataManager::UnregisterObserver(const std::string &key)
300 {
301 DataShare::CreateOptions options;
302 options.enabled_ = true;
303 auto dataShareHelper = DataShare::DataShareHelper::Creator(SETTING_DATA_QUERY_URI, options);
304 if (dataShareHelper == nullptr) {
305 LOGE("dataShareHelper == nullptr");
306 return;
307 }
308 sptr<SettingsDataObserver> dataObserver(new (std::nothrow) SettingsDataObserver(key));
309 Uri observerUri(SETTING_DATA_COMMON_URI + "&key=" + key);
310 dataShareHelper->UnregisterObserver(observerUri, dataObserver);
311 dataShareHelper->Release();
312 LOGI("Unregister SettingsDataObserver key: %{public}s finish", key.c_str());
313 }
314
OnChange()315 void SettingsDataObserver::OnChange()
316 {
317 LOGD("change key: %{public}s", key_.c_str());
318 if (key_ == SYNC_SWITCH_KEY) {
319 SettingsDataManager::QuerySwitchStatus();
320 } else if (key_ == NETWORK_CONNECTION_KEY) {
321 SettingsDataManager::QueryNetworkConnectionStatus();
322 } else if (key_ == LOCAL_SPACE_FREE_KEY) {
323 SettingsDataManager::QueryLocalSpaceFreeStatus();
324 } else if (key_ == LOCAL_SPACE_DAYS_KEY) {
325 SettingsDataManager::QueryLocalSpaceFreeDays();
326 } else if (key_ == MOBILE_DATA_SYNC_KEY) {
327 SettingsDataManager::QueryMobileDataStatus();
328 }
329 }
330 }