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