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