1 /*
2 * Copyright (C) 2024-2024 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 "accessibility_datashare_helper.h"
17
18 #include "datashare_errno.h"
19 #include "datashare_predicates.h"
20 #include "datashare_result_set.h"
21 #include "datashare_values_bucket.h"
22 #include "hilog_wrapper.h"
23 #include "ipc_skeleton.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26 #include "uri.h"
27 #include "utils.h"
28
29 namespace OHOS {
30 namespace Accessibility {
31 ffrt::mutex AccessibilityDatashareHelper::observerMutex_;
32 namespace {
33 constexpr int32_t INDEX = 0;
34 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
35 const std::string SETTING_COLUMN_VALUE = "VALUE";
36 constexpr int32_t DECIMAL_NOTATION = 10;
37 const std::string SETTINGS_DATA_EXT_URI = "datashare_ext";
38 const std::string SETTING_GLOBAL_URI = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA";
39 const std::string SETTING_SYSTEM_URI = "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_";
40 const std::string SETTING_SECURE_URI =
41 "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_";
42 }
43
AccessibilityDatashareHelper(DATASHARE_TYPE type,int32_t accountId)44 AccessibilityDatashareHelper::AccessibilityDatashareHelper(DATASHARE_TYPE type, int32_t accountId)
45 :type_(type), accountId_(accountId)
46 {
47 HILOG_DEBUG();
48 }
49
~AccessibilityDatashareHelper()50 AccessibilityDatashareHelper::~AccessibilityDatashareHelper()
51 {
52 if (dataShareHelper_ != nullptr) {
53 DestoryDatashareHelper(dataShareHelper_);
54 dataShareHelper_ = nullptr;
55 }
56 }
57
GetStringValue(const std::string & key,const std::string & defaultValue)58 std::string AccessibilityDatashareHelper::GetStringValue(const std::string& key, const std::string& defaultValue)
59 {
60 std::string resultStr = defaultValue;
61 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
62 std::shared_ptr<DataShare::DataShareResultSet> resultSet = nullptr;
63 do {
64 std::vector<std::string> columns = { SETTING_COLUMN_VALUE };
65 DataShare::DataSharePredicates predicates;
66 Uri uri(AssembleUri(key));
67 int32_t count = 0;
68 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
69 if (dataShareHelper_ == nullptr) {
70 break;
71 }
72 resultSet = dataShareHelper_->Query(uri, predicates, columns);
73 if (resultSet == nullptr) {
74 break;
75 }
76 resultSet->GetRowCount(count);
77 if (count == 0) {
78 RetError ret = PutStringValue(key, defaultValue);
79 if (ret != RET_OK) {
80 HILOG_WARN("put default key failed key = %{public}s", key.c_str());
81 }
82 break;
83 }
84 resultSet->GoToRow(INDEX);
85 int32_t rtn = resultSet->GetString(INDEX, resultStr);
86 if (rtn != DataShare::E_OK) {
87 break;
88 }
89 } while (0);
90 if (resultSet != nullptr) {
91 resultSet->Close();
92 resultSet = nullptr;
93 }
94 IPCSkeleton::SetCallingIdentity(callingIdentity);
95 return resultStr;
96 }
97
GetLongValue(const std::string & key,const int64_t & defaultValue)98 int64_t AccessibilityDatashareHelper::GetLongValue(const std::string& key, const int64_t& defaultValue)
99 {
100 int64_t result = defaultValue;
101 std::string valueStr = GetStringValue(key, std::to_string(result));
102 if (valueStr != "") {
103 result = static_cast<int64_t>(std::strtoll(valueStr.c_str(), nullptr, DECIMAL_NOTATION));
104 }
105 return result;
106 }
107
GetIntValue(const std::string & key,const int32_t & defaultValue)108 int32_t AccessibilityDatashareHelper::GetIntValue(const std::string& key, const int32_t& defaultValue)
109 {
110 int64_t valueLong = GetLongValue(key, defaultValue);
111 return static_cast<int32_t>(valueLong);
112 }
113
GetBoolValue(const std::string & key,const bool & defaultValue)114 bool AccessibilityDatashareHelper::GetBoolValue(const std::string& key, const bool& defaultValue)
115 {
116 bool result = defaultValue;
117 std::string valueStr = GetStringValue(key, result ? "1" : "0");
118 if (valueStr != "") {
119 result = (valueStr == "1" || valueStr == "true");
120 }
121 return result;
122 }
123
GetFloatValue(const std::string & key,const float & defaultValue)124 float AccessibilityDatashareHelper::GetFloatValue(const std::string& key, const float& defaultValue)
125 {
126 float result = defaultValue;
127 std::string valueStr = GetStringValue(key, std::to_string(result));
128 if (valueStr != "") {
129 result = std::stof(valueStr);
130 }
131 return result;
132 }
133
PutStringValue(const std::string & key,const std::string & value,bool needNotify)134 RetError AccessibilityDatashareHelper::PutStringValue(const std::string& key, const std::string& value, bool needNotify)
135 {
136 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
137 RetError rtn = RET_OK;
138 do {
139 if (dataShareHelper_ == nullptr) {
140 rtn = RET_ERR_NULLPTR;
141 break;
142 }
143 DataShare::DataShareValueObject keyObj(key);
144 DataShare::DataShareValueObject valueObj(value);
145 DataShare::DataShareValuesBucket bucket;
146 bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
147 bucket.Put(SETTING_COLUMN_VALUE, valueObj);
148 DataShare::DataSharePredicates predicates;
149 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
150 Uri uri(AssembleUri(key));
151 if (dataShareHelper_->Update(uri, predicates, bucket) <= 0) {
152 HILOG_DEBUG("no data exist, insert one row");
153 auto ret = dataShareHelper_->Insert(uri, bucket);
154 HILOG_INFO("helper insert %{public}s ret(%{public}d).", key.c_str(), static_cast<int>(ret));
155 }
156 if (needNotify) {
157 dataShareHelper_->NotifyChange(AssembleUri(key));
158 }
159 } while (0);
160 IPCSkeleton::SetCallingIdentity(callingIdentity);
161 return rtn;
162 }
163
PutIntValue(const std::string & key,int32_t value,bool needNotify)164 RetError AccessibilityDatashareHelper::PutIntValue(const std::string& key, int32_t value, bool needNotify)
165 {
166 return PutStringValue(key, std::to_string(value), needNotify);
167 }
168
PutLongValue(const std::string & key,int64_t value,bool needNotify)169 RetError AccessibilityDatashareHelper::PutLongValue(const std::string& key, int64_t value, bool needNotify)
170 {
171 return PutStringValue(key, std::to_string(value), needNotify);
172 }
173
PutBoolValue(const std::string & key,bool value,bool needNotify)174 RetError AccessibilityDatashareHelper::PutBoolValue(const std::string& key, bool value, bool needNotify)
175 {
176 std::string valueStr = value ? "1" : "0";
177 return PutStringValue(key, valueStr, needNotify);
178 }
179
PutFloatValue(const std::string & key,float value,bool needNotify)180 RetError AccessibilityDatashareHelper::PutFloatValue(const std::string& key, float value, bool needNotify)
181 {
182 return PutStringValue(key, std::to_string(value), needNotify);
183 }
184
Initialize(int32_t systemAbilityId)185 void AccessibilityDatashareHelper::Initialize(int32_t systemAbilityId)
186 {
187 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
188 if (systemAbilityManager == nullptr) {
189 HILOG_ERROR("get sam return nullptr");
190 return;
191 }
192 auto remoteObj = systemAbilityManager->GetSystemAbility(systemAbilityId);
193 if (remoteObj == nullptr) {
194 HILOG_ERROR("Get remoteObj return nullptr, systemAbilityId=%{public}d", systemAbilityId);
195 return;
196 }
197 remoteObj_ = remoteObj;
198 switch (type_) {
199 case DATASHARE_TYPE::GLOBAL:
200 uriProxyStr_ = SETTING_GLOBAL_URI + "?Proxy=true";
201 break;
202 case DATASHARE_TYPE::SYSTEM:
203 uriProxyStr_ = SETTING_SYSTEM_URI + std::to_string(accountId_) + "?Proxy=true";
204 break;
205 case DATASHARE_TYPE::SECURE:
206 uriProxyStr_ = SETTING_SECURE_URI + std::to_string(accountId_) + "?Proxy=true";
207 break;
208 default:
209 uriProxyStr_ = SETTING_GLOBAL_URI + "?Proxy=true";
210 HILOG_WARN("undefined DATASHARE_TYPE, use global table");
211 break;
212 }
213 dataShareHelper_ = CreateDatashareHelper();
214 if (dataShareHelper_ == nullptr) {
215 HILOG_ERROR("create dataShareHelper_ failed");
216 }
217 }
218
CreateObserver(const std::string & key,AccessibilitySettingObserver::UpdateFunc & func)219 sptr<AccessibilitySettingObserver> AccessibilityDatashareHelper::CreateObserver(const std::string& key,
220 AccessibilitySettingObserver::UpdateFunc& func)
221 {
222 sptr<AccessibilitySettingObserver> observer = new AccessibilitySettingObserver();
223 observer->SetKey(key);
224 observer->SetUpdateFunc(func);
225 return observer;
226 }
227
RegisterObserver(const sptr<AccessibilitySettingObserver> & observer)228 RetError AccessibilityDatashareHelper::RegisterObserver(const sptr<AccessibilitySettingObserver>& observer)
229 {
230 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
231 auto uri = AssembleUri(observer->GetKey());
232 if (dataShareHelper_ == nullptr) {
233 IPCSkeleton::SetCallingIdentity(callingIdentity);
234 return RET_ERR_NULLPTR;
235 }
236 dataShareHelper_->RegisterObserver(uri, observer);
237 IPCSkeleton::SetCallingIdentity(callingIdentity);
238 HILOG_DEBUG("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
239 return RET_OK;
240 }
241
RegisterObserver(const std::string & key,AccessibilitySettingObserver::UpdateFunc & func)242 RetError AccessibilityDatashareHelper::RegisterObserver(const std::string& key,
243 AccessibilitySettingObserver::UpdateFunc& func)
244 {
245 sptr<AccessibilitySettingObserver> observer = CreateObserver(key, func);
246 if (observer == nullptr) {
247 return RET_ERR_NULLPTR;
248 }
249 auto iter = settingObserverMap_.find(key);
250 if (iter != settingObserverMap_.end() && iter->second != nullptr) {
251 HILOG_INFO("observer of key = %{public}s already exist", key.c_str());
252 return RET_OK;
253 }
254 if (RegisterObserver(observer) != ERR_OK) {
255 return RET_ERR_NULLPTR;
256 }
257 std::lock_guard<ffrt::mutex> lock(observerMutex_);
258 settingObserverMap_.insert(std::make_pair(key, observer));
259 return RET_OK;
260 }
261
UnregisterObserver(const sptr<AccessibilitySettingObserver> & observer)262 RetError AccessibilityDatashareHelper::UnregisterObserver(const sptr<AccessibilitySettingObserver>& observer)
263 {
264 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
265 auto uri = AssembleUri(observer->GetKey());
266 if (dataShareHelper_ == nullptr) {
267 IPCSkeleton::SetCallingIdentity(callingIdentity);
268 return RET_ERR_NULLPTR;
269 }
270 dataShareHelper_->UnregisterObserver(uri, observer);
271 IPCSkeleton::SetCallingIdentity(callingIdentity);
272 HILOG_DEBUG("succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
273 return RET_OK;
274 }
275
UnregisterObserver(const std::string & key)276 RetError AccessibilityDatashareHelper::UnregisterObserver(const std::string& key)
277 {
278 std::lock_guard<ffrt::mutex> lock(observerMutex_);
279 auto iter = settingObserverMap_.find(key);
280 if (iter != settingObserverMap_.end() && iter->second != nullptr) {
281 sptr<AccessibilitySettingObserver> observer = iter->second;
282 if (UnregisterObserver(observer) == ERR_OK) {
283 settingObserverMap_.erase(iter);
284 HILOG_DEBUG("succeed to unregister observer of key %{public}s", key.c_str());
285 return RET_OK;
286 } else {
287 settingObserverMap_.erase(iter);
288 HILOG_WARN("failed to unregister observer of key %{public}s", key.c_str());
289 return RET_ERR_FAILED;
290 }
291 }
292 HILOG_WARN("failed to find the key %{public}s", key.c_str());
293 return RET_ERR_FAILED;
294 }
295
CreateDatashareHelper()296 std::shared_ptr<DataShare::DataShareHelper> AccessibilityDatashareHelper::CreateDatashareHelper()
297 {
298 if (remoteObj_ == nullptr) {
299 return nullptr;
300 }
301 std::pair<int, std::shared_ptr<DataShare::DataShareHelper>> ret = DataShare::DataShareHelper::Create(remoteObj_,
302 uriProxyStr_, SETTINGS_DATA_EXT_URI);
303 HILOG_INFO("create helper ret = %{public}d, uri=%{public}s", ret.first, uriProxyStr_.c_str());
304 if (ret.second == nullptr) {
305 Utils::RecordUnavailableEvent(A11yUnavailableEvent::READ_EVENT, A11yError::ERROR_READ_FAILED);
306 return nullptr;
307 }
308 return ret.second;
309 }
310
DestoryDatashareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)311 bool AccessibilityDatashareHelper::DestoryDatashareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)
312 {
313 if (helper && !helper->Release()) {
314 HILOG_WARN("release helper fail.");
315 return false;
316 }
317 return true;
318 }
319
AssembleUri(const std::string & key)320 Uri AccessibilityDatashareHelper::AssembleUri(const std::string& key)
321 {
322 Uri uri(uriProxyStr_ + "&key=" + key);
323 return uri;
324 }
325
326 } // namespace Accessibility
327 } // namespace OHOS
328
329