• 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_datashare.h"
17 
18 #include <thread>
19 
20 #include "datashare_predicates.h"
21 #include "datashare_result_set.h"
22 #include "datashare_values_bucket.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "mmi_log.h"
26 #include "rdb_errno.h"
27 #include "result_set.h"
28 #include "uri.h"
29 
30 namespace OHOS {
31 namespace MMI {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "setting_DataShare" };
33 SettingDataShare* SettingDataShare::instance_;
34 std::mutex SettingDataShare::mutex_;
35 sptr<IRemoteObject> SettingDataShare::remoteObj_;
36 namespace {
37 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
38 const std::string SETTING_COLUMN_VALUE = "VALUE";
39 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
40 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
41 constexpr int32_t LONG_CAST_NUM = 10;
42 } // namespace
43 
~SettingDataShare()44 SettingDataShare::~SettingDataShare()
45 {
46     if (instance_ != nullptr) {
47         delete instance_;
48     }
49     instance_ = nullptr;
50     remoteObj_ = nullptr;
51 }
52 
GetInstance(int32_t systemAbilityId)53 SettingDataShare& SettingDataShare::GetInstance(int32_t systemAbilityId)
54 {
55     if (instance_ == nullptr) {
56         std::lock_guard<std::mutex> lock(mutex_);
57         if (instance_ == nullptr) {
58             instance_ = new SettingDataShare();
59             Initialize(systemAbilityId);
60         }
61     }
62     return *instance_;
63 }
64 
GetIntValue(const std::string & key,int32_t & value)65 ErrCode SettingDataShare::GetIntValue(const std::string& key, int32_t& value)
66 {
67     int64_t valueLong;
68     ErrCode ret = GetLongValue(key, valueLong);
69     if (ret != ERR_OK) {
70         MMI_HILOGE("Get int value fail");
71         return ret;
72     }
73     value = static_cast<int32_t>(valueLong);
74     return ERR_OK;
75 }
76 
GetLongValue(const std::string & key,int64_t & value)77 ErrCode SettingDataShare::GetLongValue(const std::string& key, int64_t& value)
78 {
79     std::string valueStr;
80     ErrCode ret = GetStringValue(key, valueStr);
81     if (ret != ERR_OK) {
82         MMI_HILOGE("Get long value fail");
83         return ret;
84     }
85     value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, LONG_CAST_NUM));
86     return ERR_OK;
87 }
88 
GetBoolValue(const std::string & key,bool & value)89 ErrCode SettingDataShare::GetBoolValue(const std::string& key, bool& value)
90 {
91     std::string valueStr;
92     ErrCode ret = GetStringValue(key, valueStr);
93     if (ret != ERR_OK) {
94         MMI_HILOGE("Get bool value fail");
95         return ret;
96     }
97     value = (valueStr == "true");
98     return ERR_OK;
99 }
100 
PutIntValue(const std::string & key,int32_t value,bool needNotify)101 ErrCode SettingDataShare::PutIntValue(const std::string& key, int32_t value, bool needNotify)
102 {
103     return PutStringValue(key, std::to_string(value), needNotify);
104 }
105 
PutLongValue(const std::string & key,int64_t value,bool needNotify)106 ErrCode SettingDataShare::PutLongValue(const std::string& key, int64_t value, bool needNotify)
107 {
108     return PutStringValue(key, std::to_string(value), needNotify);
109 }
110 
PutBoolValue(const std::string & key,bool value,bool needNotify)111 ErrCode SettingDataShare::PutBoolValue(const std::string& key, bool value, bool needNotify)
112 {
113     std::string valueStr = value ? "true" : "false";
114     return PutStringValue(key, valueStr, needNotify);
115 }
116 
IsValidKey(const std::string & key)117 bool SettingDataShare::IsValidKey(const std::string& key)
118 {
119     std::string value;
120     ErrCode ret = GetStringValue(key, value);
121     return (ret != ERR_NAME_NOT_FOUND) && (!value.empty());
122 }
123 
CreateObserver(const std::string & key,SettingObserver::UpdateFunc & func)124 sptr<SettingObserver> SettingDataShare::CreateObserver(const std::string& key, SettingObserver::UpdateFunc& func)
125 {
126     sptr<SettingObserver> observer = new SettingObserver();
127     observer->SetKey(key);
128     observer->SetUpdateFunc(func);
129     return observer;
130 }
131 
ExecRegisterCb(const sptr<SettingObserver> & observer)132 void SettingDataShare::ExecRegisterCb(const sptr<SettingObserver>& observer)
133 {
134     if (observer == nullptr) {
135         MMI_HILOGE("observer is null");
136         return;
137     }
138     observer->OnChange();
139 }
140 
RegisterObserver(const sptr<SettingObserver> & observer)141 ErrCode SettingDataShare::RegisterObserver(const sptr<SettingObserver>& observer)
142 {
143     if (observer == nullptr) {
144         MMI_HILOGE("observer is null");
145         return RET_ERR;
146     }
147     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
148     auto uri = AssembleUri(observer->GetKey());
149     auto helper = CreateDataShareHelper();
150     if (helper == nullptr) {
151         IPCSkeleton::SetCallingIdentity(callingIdentity);
152         return ERR_NO_INIT;
153     }
154     helper->RegisterObserver(uri, observer);
155     helper->NotifyChange(uri);
156     std::thread execCb(SettingDataShare::ExecRegisterCb, observer);
157     execCb.detach();
158     ReleaseDataShareHelper(helper);
159     IPCSkeleton::SetCallingIdentity(callingIdentity);
160     return ERR_OK;
161 }
162 
UnregisterObserver(const sptr<SettingObserver> & observer)163 ErrCode SettingDataShare::UnregisterObserver(const sptr<SettingObserver>& observer)
164 {
165     if (observer == nullptr) {
166         MMI_HILOGE("observer is null");
167         return RET_ERR;
168     }
169     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
170     auto uri = AssembleUri(observer->GetKey());
171     auto helper = CreateDataShareHelper();
172     if (helper == nullptr) {
173         IPCSkeleton::SetCallingIdentity(callingIdentity);
174         return ERR_NO_INIT;
175     }
176     helper->UnregisterObserver(uri, observer);
177     ReleaseDataShareHelper(helper);
178     IPCSkeleton::SetCallingIdentity(callingIdentity);
179     return ERR_OK;
180 }
181 
Initialize(int32_t systemAbilityId)182 void SettingDataShare::Initialize(int32_t systemAbilityId)
183 {
184     auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
185     if (sam == nullptr) {
186         return;
187     }
188     auto remoteObj = sam->GetSystemAbility(systemAbilityId);
189     if (remoteObj == nullptr) {
190         return;
191     }
192     remoteObj_ = remoteObj;
193 }
194 
GetStringValue(const std::string & key,std::string & value)195 ErrCode SettingDataShare::GetStringValue(const std::string& key, std::string& value)
196 {
197     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
198     auto helper = CreateDataShareHelper();
199     if (helper == nullptr) {
200         IPCSkeleton::SetCallingIdentity(callingIdentity);
201         return ERR_NO_INIT;
202     }
203     std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
204     DataShare::DataSharePredicates predicates;
205     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
206     Uri uri(AssembleUri(key));
207     auto resultSet = helper->Query(uri, predicates, columns);
208     ReleaseDataShareHelper(helper);
209     if (resultSet == nullptr) {
210         IPCSkeleton::SetCallingIdentity(callingIdentity);
211         return ERR_INVALID_OPERATION;
212     }
213     int32_t count;
214     resultSet->GetRowCount(count);
215     if (count == 0) {
216         IPCSkeleton::SetCallingIdentity(callingIdentity);
217         return ERR_NAME_NOT_FOUND;
218     }
219     const int32_t INDEX = 0;
220     resultSet->GoToRow(INDEX);
221     int32_t ret = resultSet->GetString(INDEX, value);
222     if (ret != NativeRdb::E_OK) {
223         IPCSkeleton::SetCallingIdentity(callingIdentity);
224         return ERR_INVALID_VALUE;
225     }
226     resultSet->Close();
227     IPCSkeleton::SetCallingIdentity(callingIdentity);
228     return ERR_OK;
229 }
230 
PutStringValue(const std::string & key,const std::string & value,bool needNotify)231 ErrCode SettingDataShare::PutStringValue(const std::string& key, const std::string& value, bool needNotify)
232 {
233     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
234     auto helper = CreateDataShareHelper();
235     if (helper == nullptr) {
236         IPCSkeleton::SetCallingIdentity(callingIdentity);
237         return ERR_NO_INIT;
238     }
239     DataShare::DataShareValueObject keyObj(key);
240     DataShare::DataShareValueObject valueObj(value);
241     DataShare::DataShareValuesBucket bucket;
242     bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
243     bucket.Put(SETTING_COLUMN_VALUE, valueObj);
244     DataShare::DataSharePredicates predicates;
245     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
246     Uri uri(AssembleUri(key));
247     if (helper->Update(uri, predicates, bucket) <= 0) {
248         helper->Insert(uri, bucket);
249     }
250     if (needNotify) {
251         helper->NotifyChange(AssembleUri(key));
252     }
253     ReleaseDataShareHelper(helper);
254     IPCSkeleton::SetCallingIdentity(callingIdentity);
255     return ERR_OK;
256 }
257 
CreateDataShareHelper()258 std::shared_ptr<DataShare::DataShareHelper> SettingDataShare::CreateDataShareHelper()
259 {
260     auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
261     if (helper == nullptr) {
262         return nullptr;
263     }
264     return helper;
265 }
266 
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)267 bool SettingDataShare::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)
268 {
269     if (!helper->Release()) {
270         return false;
271     }
272     return true;
273 }
274 
AssembleUri(const std::string & key)275 Uri SettingDataShare::AssembleUri(const std::string& key)
276 {
277     Uri uri(SETTING_URI_PROXY + "&key=" + key);
278     return uri;
279 }
280 }
281 } // namespace OHOS