• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "setting_provider.h"
17 #include <thread>
18 #include "datashare_predicates.h"
19 #include "datashare_result_set.h"
20 #include "datashare_values_bucket.h"
21 #include "ipc_skeleton.h"
22 #include "iservice_registry.h"
23 #include "window_manager_hilog.h"
24 #include "rdb_errno.h"
25 #include "result_set.h"
26 #include "uri.h"
27 #include "screen_session_manager/include/screen_session_manager.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 SettingProvider* SettingProvider::instance_;
32 std::mutex SettingProvider::mutex_;
33 sptr<IRemoteObject> SettingProvider::remoteObj_;
34 namespace {
35 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
36 const std::string SETTING_COLUMN_VALUE = "VALUE";
37 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
38 const std::string SETTING_MULTI_USER_URI = "datashare:///com.ohos.settingsdata/entry/settingsdata/";
39 const std::string SETTING_MULTI_USER_TABLE = "USER_SETTINGSDATA_";
40 const std::string SETTING_MULTI_USER_PROXY = "?Proxy=true";
41 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
42 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_DISPLAY, "SettingProvider" };
43 constexpr int32_t PARAM_NUM_TEN = 10;
44 } // namespace
45 
~SettingProvider()46 SettingProvider::~SettingProvider()
47 {
48     instance_ = nullptr;
49     remoteObj_ = nullptr;
50 }
51 
GetInstance(int32_t systemAbilityId)52 SettingProvider& SettingProvider::GetInstance(int32_t systemAbilityId)
53 {
54     if (instance_ == nullptr) {
55         std::lock_guard<std::mutex> lock(mutex_);
56         if (instance_ == nullptr) {
57             instance_ = new SettingProvider();
58             Initialize(systemAbilityId);
59         }
60     }
61     return *instance_;
62 }
63 
GetIntValue(const std::string & key,int32_t & value)64 ErrCode SettingProvider::GetIntValue(const std::string& key, int32_t& value)
65 {
66     int64_t valueLong;
67     ErrCode ret = GetLongValue(key, valueLong);
68     if (ret != ERR_OK) {
69         return ret;
70     }
71     value = static_cast<int32_t>(valueLong);
72     return ERR_OK;
73 }
74 
GetLongValue(const std::string & key,int64_t & value)75 ErrCode SettingProvider::GetLongValue(const std::string& key, int64_t& value)
76 {
77     std::string valueStr;
78     ErrCode ret = GetStringValue(key, valueStr);
79     if (ret != ERR_OK) {
80         return ret;
81     }
82     value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, PARAM_NUM_TEN));
83     return ERR_OK;
84 }
85 
GetBoolValue(const std::string & key,bool & value)86 ErrCode SettingProvider::GetBoolValue(const std::string& key, bool& value)
87 {
88     std::string valueStr;
89     ErrCode ret = GetStringValue(key, valueStr);
90     if (ret != ERR_OK) {
91         return ret;
92     }
93     value = (valueStr == "true");
94     return ERR_OK;
95 }
96 
PutIntValue(const std::string & key,int32_t value,bool needNotify)97 ErrCode SettingProvider::PutIntValue(const std::string& key, int32_t value, bool needNotify)
98 {
99     return PutStringValue(key, std::to_string(value), needNotify);
100 }
101 
PutLongValue(const std::string & key,int64_t value,bool needNotify)102 ErrCode SettingProvider::PutLongValue(const std::string& key, int64_t value, bool needNotify)
103 {
104     return PutStringValue(key, std::to_string(value), needNotify);
105 }
106 
PutBoolValue(const std::string & key,bool value,bool needNotify)107 ErrCode SettingProvider::PutBoolValue(const std::string& key, bool value, bool needNotify)
108 {
109     std::string valueStr = value ? "true" : "false";
110     return PutStringValue(key, valueStr, needNotify);
111 }
112 
IsValidKey(const std::string & key)113 bool SettingProvider::IsValidKey(const std::string& key)
114 {
115     std::string value;
116     ErrCode ret = GetStringValue(key, value);
117     return (ret != ERR_NAME_NOT_FOUND) && (!value.empty());
118 }
119 
CreateObserver(const std::string & key,SettingObserver::UpdateFunc & func)120 sptr<SettingObserver> SettingProvider::CreateObserver(const std::string& key, SettingObserver::UpdateFunc& func)
121 {
122     sptr<SettingObserver> observer = new SettingObserver();
123     observer->SetKey(key);
124     observer->SetUpdateFunc(func);
125     return observer;
126 }
127 
ExecRegisterCb(const sptr<SettingObserver> & observer)128 void SettingProvider::ExecRegisterCb(const sptr<SettingObserver>& observer)
129 {
130     if (observer == nullptr) {
131         WLOGFE("observer is nullptr");
132         return;
133     }
134     observer->OnChange();
135 }
136 
RegisterObserver(const sptr<SettingObserver> & observer)137 ErrCode SettingProvider::RegisterObserver(const sptr<SettingObserver>& observer)
138 {
139     if (observer == nullptr) {
140         return ERR_NO_INIT;
141     }
142     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
143     auto uri = AssembleUri(observer->GetKey());
144     auto helper = CreateDataShareHelper();
145     if (helper == nullptr) {
146         IPCSkeleton::SetCallingIdentity(callingIdentity);
147         return ERR_NO_INIT;
148     }
149     helper->RegisterObserver(uri, observer);
150     helper->NotifyChange(uri);
151     std::thread execCb(SettingProvider::ExecRegisterCb, observer);
152     execCb.detach();
153     ReleaseDataShareHelper(helper);
154     IPCSkeleton::SetCallingIdentity(callingIdentity);
155     WLOGFD("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
156     return ERR_OK;
157 }
158 
UnregisterObserver(const sptr<SettingObserver> & observer)159 ErrCode SettingProvider::UnregisterObserver(const sptr<SettingObserver>& observer)
160 {
161     if (observer == nullptr) {
162         return ERR_NO_INIT;
163     }
164     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
165     auto uri = AssembleUri(observer->GetKey());
166     auto helper = CreateDataShareHelper();
167     if (helper == nullptr) {
168         IPCSkeleton::SetCallingIdentity(callingIdentity);
169         return ERR_NO_INIT;
170     }
171     helper->UnregisterObserver(uri, observer);
172     ReleaseDataShareHelper(helper);
173     IPCSkeleton::SetCallingIdentity(callingIdentity);
174     WLOGFD("succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
175     return ERR_OK;
176 }
177 
Initialize(int32_t systemAbilityId)178 void SettingProvider::Initialize(int32_t systemAbilityId)
179 {
180     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
181     if (sam == nullptr) {
182         WLOGFE("GetSystemAbilityManager return nullptr");
183         return;
184     }
185     auto remoteObj = sam->GetSystemAbility(systemAbilityId);
186     if (remoteObj == nullptr) {
187         WLOGFE("GetSystemAbility return nullptr, systemAbilityId=%{public}d", systemAbilityId);
188         return;
189     }
190     remoteObj_ = remoteObj;
191 }
192 
GetStringValue(const std::string & key,std::string & value)193 ErrCode SettingProvider::GetStringValue(const std::string& key, std::string& value)
194 {
195     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
196     auto helper = CreateDataShareHelper();
197     if (helper == nullptr) {
198         IPCSkeleton::SetCallingIdentity(callingIdentity);
199         return ERR_NO_INIT;
200     }
201     std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
202     DataShare::DataSharePredicates predicates;
203     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
204     Uri uri(AssembleUri(key));
205     auto resultSet = helper->Query(uri, predicates, columns);
206     ReleaseDataShareHelper(helper);
207     if (resultSet == nullptr) {
208         WLOGFE("helper->Query return nullptr");
209         IPCSkeleton::SetCallingIdentity(callingIdentity);
210         return ERR_INVALID_OPERATION;
211     }
212     int32_t count;
213     resultSet->GetRowCount(count);
214     if (count == 0) {
215         WLOGFW("not found value, key=%{public}s, count=%{public}d", key.c_str(), count);
216         IPCSkeleton::SetCallingIdentity(callingIdentity);
217         resultSet->Close();
218         return ERR_NAME_NOT_FOUND;
219     }
220     const int32_t INDEX = 0;
221     resultSet->GoToRow(INDEX);
222     int32_t ret = resultSet->GetString(INDEX, value);
223     if (ret != NativeRdb::E_OK) {
224         WLOGFW("resultSet->GetString return not ok, ret=%{public}d", ret);
225         IPCSkeleton::SetCallingIdentity(callingIdentity);
226         resultSet->Close();
227         return ERR_INVALID_VALUE;
228     }
229     resultSet->Close();
230     IPCSkeleton::SetCallingIdentity(callingIdentity);
231     return ERR_OK;
232 }
233 
GetStringValueMultiUser(const std::string & key,std::string & value)234 ErrCode SettingProvider::GetStringValueMultiUser(const std::string& key, std::string& value)
235 {
236     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
237     auto helper = CreateDataShareHelperMultiUser();
238     if (helper == nullptr) {
239         IPCSkeleton::SetCallingIdentity(callingIdentity);
240         return ERR_NO_INIT;
241     }
242     std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
243     DataShare::DataSharePredicates predicates;
244     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
245     Uri uri(AssembleUriMultiUser(key));
246     auto resultSet = helper->Query(uri, predicates, columns);
247     ReleaseDataShareHelper(helper);
248     if (resultSet == nullptr) {
249         WLOGFE("helper->Query return nullptr");
250         IPCSkeleton::SetCallingIdentity(callingIdentity);
251         return ERR_INVALID_OPERATION;
252     }
253     int32_t count;
254     resultSet->GetRowCount(count);
255     if (count == 0) {
256         WLOGFW("not found value, key=%{public}s, count=%{public}d", key.c_str(), count);
257         IPCSkeleton::SetCallingIdentity(callingIdentity);
258         resultSet->Close();
259         return ERR_NAME_NOT_FOUND;
260     }
261     const int32_t INDEX = 0;
262     resultSet->GoToRow(INDEX);
263     int32_t ret = resultSet->GetString(INDEX, value);
264     if (ret != NativeRdb::E_OK) {
265         WLOGFW("resultSet->GetString return not ok, ret=%{public}d", ret);
266         IPCSkeleton::SetCallingIdentity(callingIdentity);
267         resultSet->Close();
268         return ERR_INVALID_VALUE;
269     }
270     resultSet->Close();
271     IPCSkeleton::SetCallingIdentity(callingIdentity);
272     return ERR_OK;
273 }
274 
PutStringValue(const std::string & key,const std::string & value,bool needNotify)275 ErrCode SettingProvider::PutStringValue(const std::string& key, const std::string& value, bool needNotify)
276 {
277     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
278     auto helper = CreateDataShareHelper();
279     if (helper == nullptr) {
280         IPCSkeleton::SetCallingIdentity(callingIdentity);
281         return ERR_NO_INIT;
282     }
283     DataShare::DataShareValueObject keyObj(key);
284     DataShare::DataShareValueObject valueObj(value);
285     DataShare::DataShareValuesBucket bucket;
286     bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
287     bucket.Put(SETTING_COLUMN_VALUE, valueObj);
288     DataShare::DataSharePredicates predicates;
289     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
290     Uri uri(AssembleUri(key));
291     if (helper->Update(uri, predicates, bucket) <= 0) {
292         WLOGFD("no data exist, insert one row");
293         helper->Insert(uri, bucket);
294     }
295     if (needNotify) {
296         helper->NotifyChange(AssembleUri(key));
297     }
298     ReleaseDataShareHelper(helper);
299     IPCSkeleton::SetCallingIdentity(callingIdentity);
300     return ERR_OK;
301 }
302 
CreateDataShareHelper()303 std::shared_ptr<DataShare::DataShareHelper> SettingProvider::CreateDataShareHelper()
304 {
305     auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
306     if (helper == nullptr) {
307         WLOGFW("helper is nullptr, uri=%{public}s", SETTING_URI_PROXY.c_str());
308         return nullptr;
309     }
310     return helper;
311 }
312 
CreateDataShareHelperMultiUser()313 std::shared_ptr<DataShare::DataShareHelper> SettingProvider::CreateDataShareHelperMultiUser()
314 {
315     std::string uriString = "";
316     int32_t userId = ScreenSessionManager::GetInstance().GetCurrentUserId();
317     if (userId > 0) {
318         WLOGFI("current userId: %{public}d", userId);
319         std::string userIdString = std::to_string(userId);
320         uriString = SETTING_MULTI_USER_URI + SETTING_MULTI_USER_TABLE + userIdString +
321             SETTING_MULTI_USER_PROXY;
322     } else {
323         WLOGFE("invalid userId: %{public}d, use default uri", userId);
324         uriString = SETTING_URI_PROXY;
325     }
326     auto helper = DataShare::DataShareHelper::Creator(remoteObj_, uriString, SETTINGS_DATA_EXT_URI);
327     if (helper == nullptr) {
328         WLOGFW("helper is nullptr, uri=%{public}s", uriString.c_str());
329         return nullptr;
330     }
331     return helper;
332 }
333 
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)334 bool SettingProvider::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)
335 {
336     if (!helper->Release()) {
337         WLOGFW("release helper fail");
338         return false;
339     }
340     return true;
341 }
342 
AssembleUri(const std::string & key)343 Uri SettingProvider::AssembleUri(const std::string& key)
344 {
345     Uri uri(SETTING_URI_PROXY + "&key=" + key);
346     return uri;
347 }
348 
AssembleUriMultiUser(const std::string & key)349 Uri SettingProvider::AssembleUriMultiUser(const std::string& key)
350 {
351     std::string uriString = "";
352     int32_t userId = ScreenSessionManager::GetInstance().GetCurrentUserId();
353     if (userId > 0) {
354         WLOGFI("current userId: %{public}d", userId);
355         std::string userIdString = std::to_string(userId);
356         uriString = SETTING_MULTI_USER_URI + SETTING_MULTI_USER_TABLE + userIdString +
357             SETTING_MULTI_USER_PROXY + "&key=" + key;
358     } else {
359         WLOGFE("invalid userId: %{public}d, use default uri", userId);
360         uriString = SETTING_URI_PROXY + "&key=" + key;
361     }
362     Uri uri(uriString);
363     return uri;
364 }
365 
RegisterObserverByTable(const sptr<SettingObserver> & observer,std::string tableName)366 ErrCode SettingProvider::RegisterObserverByTable(const sptr<SettingObserver>& observer, std::string tableName)
367 {
368     if (observer == nullptr) {
369         return ERR_NO_INIT;
370     }
371     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
372     auto uri = AssembleUriMultiUserByTable(observer->GetKey(), tableName);
373     auto helper = CreateDataShareHelperMultiUserByTable(tableName);
374     if (helper == nullptr) {
375         IPCSkeleton::SetCallingIdentity(callingIdentity);
376         return ERR_NO_INIT;
377     }
378     helper->RegisterObserver(uri, observer);
379     helper->NotifyChange(uri);
380     std::thread execCb(SettingProvider::ExecRegisterCb, observer);
381     execCb.detach();
382     ReleaseDataShareHelper(helper);
383     IPCSkeleton::SetCallingIdentity(callingIdentity);
384     WLOGFD("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
385     return ERR_OK;
386 }
387 
UnregisterObserverByTable(const sptr<SettingObserver> & observer,std::string tableName)388 ErrCode SettingProvider::UnregisterObserverByTable(const sptr<SettingObserver>& observer, std::string tableName)
389 {
390     if (observer == nullptr) {
391         return ERR_NO_INIT;
392     }
393     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
394     auto uri = AssembleUriMultiUserByTable(observer->GetKey(), tableName);
395     auto helper = CreateDataShareHelperMultiUserByTable(tableName);
396     if (helper == nullptr) {
397         IPCSkeleton::SetCallingIdentity(callingIdentity);
398         return ERR_NO_INIT;
399     }
400     helper->UnregisterObserver(uri, observer);
401     ReleaseDataShareHelper(helper);
402     IPCSkeleton::SetCallingIdentity(callingIdentity);
403     WLOGFD("succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
404     return ERR_OK;
405 }
406 
GetIntValueMultiUserByTable(const std::string & key,int32_t & value,std::string tableName)407 ErrCode SettingProvider::GetIntValueMultiUserByTable(const std::string& key, int32_t& value, std::string tableName)
408 {
409     int64_t result = 0;
410     ErrCode ret = GetLongValueMultiUserByTable(key, result, tableName);
411     if (ret != ERR_OK) {
412         return ret;
413     }
414     value = static_cast<int32_t>(result);
415     return ERR_OK;
416 }
417 
GetLongValueMultiUserByTable(const std::string & key,int64_t & value,std::string tableName)418 ErrCode SettingProvider::GetLongValueMultiUserByTable(const std::string& key, int64_t& value, std::string tableName)
419 {
420     std::string result = "";
421     ErrCode ret = GetStringValueMultiUserByTable(key, result, tableName);
422     if (ret != ERR_OK) {
423         return ret;
424     }
425     value = static_cast<int64_t>(strtoll(result.c_str(), nullptr, PARAM_NUM_TEN));
426     return ERR_OK;
427 }
428 
GetStringValueMultiUserByTable(const std::string & key,std::string & value,std::string tableName)429 ErrCode SettingProvider::GetStringValueMultiUserByTable(const std::string& key,
430     std::string& value, std::string tableName)
431 {
432     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
433     auto helper = CreateDataShareHelperMultiUserByTable(tableName);
434     if (helper == nullptr) {
435         IPCSkeleton::SetCallingIdentity(callingIdentity);
436         return ERR_NO_INIT;
437     }
438     std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
439     DataShare::DataSharePredicates predicates;
440     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
441     Uri uri(AssembleUriMultiUserByTable(key, tableName));
442     auto resultSet = helper->Query(uri, predicates, columns);
443     ReleaseDataShareHelper(helper);
444     if (resultSet == nullptr) {
445         WLOGFE("helper->Query return nullptr");
446         IPCSkeleton::SetCallingIdentity(callingIdentity);
447         return ERR_INVALID_OPERATION;
448     }
449     int32_t count;
450     resultSet->GetRowCount(count);
451     if (count == 0) {
452         WLOGFW("not found value, key=%{public}s, count=%{public}d", key.c_str(), count);
453         IPCSkeleton::SetCallingIdentity(callingIdentity);
454         resultSet->Close();
455         return ERR_NAME_NOT_FOUND;
456     }
457     const int32_t INDEX = 0;
458     resultSet->GoToRow(INDEX);
459     int32_t ret = resultSet->GetString(INDEX, value);
460     if (ret != NativeRdb::E_OK) {
461         WLOGFW("resultSet->GetString return not ok, ret=%{public}d", ret);
462         IPCSkeleton::SetCallingIdentity(callingIdentity);
463         resultSet->Close();
464         return ERR_INVALID_VALUE;
465     }
466     resultSet->Close();
467     IPCSkeleton::SetCallingIdentity(callingIdentity);
468     return ERR_OK;
469 }
470 
CreateDataShareHelperMultiUserByTable(std::string tableName)471 std::shared_ptr<DataShare::DataShareHelper> SettingProvider::CreateDataShareHelperMultiUserByTable(
472     std::string tableName)
473 {
474     std::string address = "";
475     int32_t userId = ScreenSessionManager::GetInstance().GetCurrentUserId();
476     if (userId > 0) {
477         WLOGFD("current userId: %{public}d", userId);
478         std::string userIdString = std::to_string(userId);
479         address = SETTING_MULTI_USER_URI + tableName + userIdString +
480             SETTING_MULTI_USER_PROXY;
481     } else {
482         WLOGFE("invalid userId: %{public}d, use default uri", userId);
483         address = SETTING_URI_PROXY;
484     }
485     auto helper = DataShare::DataShareHelper::Creator(remoteObj_, address, SETTINGS_DATA_EXT_URI);
486     if (helper == nullptr) {
487         WLOGFW("helper is nullptr, uri=%{public}s", address.c_str());
488         return nullptr;
489     }
490     return helper;
491 }
492 
AssembleUriMultiUserByTable(const std::string & key,std::string tableName)493 Uri SettingProvider::AssembleUriMultiUserByTable(const std::string& key, std::string tableName)
494 {
495     std::string address = "";
496     int32_t userId = ScreenSessionManager::GetInstance().GetCurrentUserId();
497     if (userId > 0) {
498         WLOGFD("current userId: %{public}d", userId);
499         std::string userIdString = std::to_string(userId);
500         address = SETTING_MULTI_USER_URI + tableName + userIdString +
501             SETTING_MULTI_USER_PROXY + "&key=" + key;
502     } else {
503         WLOGFE("invalid userId: %{public}d, use default uri", userId);
504         address = SETTING_URI_PROXY + "&key=" + key;
505     }
506     Uri uri(address);
507     return uri;
508 }
509 } // namespace Rosen
510 } // namespace OHOS