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 ffrt::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 auto iter = settingObserverMap_.find(key);
264 if (iter != settingObserverMap_.end() && iter->second != nullptr) {
265 HILOG_INFO("observer of key = %{public}s already exist", key.c_str());
266 return RET_OK;
267 }
268 if (RegisterObserver(observer) != ERR_OK) {
269 return RET_ERR_NULLPTR;
270 }
271 std::lock_guard<ffrt::mutex> lock(observerMutex_);
272 settingObserverMap_.insert(std::make_pair(key, observer));
273 return RET_OK;
274 }
275
UnregisterObserver(const sptr<AccessibilitySettingObserver>& observer)276 RetError AccessibilityDatashareHelper::UnregisterObserver(const sptr<AccessibilitySettingObserver>& observer)
277 {
278 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
279 auto uri = AssembleUri(observer->GetKey());
280 #ifdef OHOS_BUILD_ENABLE_DATA_SHARE
281 if (dataShareHelper_ == nullptr) {
282 IPCSkeleton::SetCallingIdentity(callingIdentity);
283 return RET_ERR_NULLPTR;
284 }
285 dataShareHelper_->UnregisterObserver(uri, observer);
286 #endif
287 IPCSkeleton::SetCallingIdentity(callingIdentity);
288 HILOG_DEBUG("succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
289 return RET_OK;
290 }
291
UnregisterObserver(const std::string& key)292 RetError AccessibilityDatashareHelper::UnregisterObserver(const std::string& key)
293 {
294 std::lock_guard<ffrt::mutex> lock(observerMutex_);
295 auto iter = settingObserverMap_.find(key);
296 if (iter != settingObserverMap_.end() && iter->second != nullptr) {
297 sptr<AccessibilitySettingObserver> observer = iter->second;
298 if (UnregisterObserver(observer) == ERR_OK) {
299 settingObserverMap_.erase(iter);
300 HILOG_DEBUG("succeed to unregister observer of key %{public}s", key.c_str());
301 return RET_OK;
302 } else {
303 settingObserverMap_.erase(iter);
304 HILOG_WARN("failed to unregister observer of key %{public}s", key.c_str());
305 return RET_ERR_FAILED;
306 }
307 }
308 HILOG_WARN("failed to find the key %{public}s", key.c_str());
309 return RET_ERR_FAILED;
310 }
311
312 #ifdef OHOS_BUILD_ENABLE_DATA_SHARE
CreateDatashareHelper()313 std::shared_ptr<DataShare::DataShareHelper> AccessibilityDatashareHelper::CreateDatashareHelper()
314 {
315 if (remoteObj_ == nullptr) {
316 return nullptr;
317 }
318 std::pair<int, std::shared_ptr<DataShare::DataShareHelper>> ret = DataShare::DataShareHelper::Create(remoteObj_,
319 uriProxyStr_, SETTINGS_DATA_EXT_URI);
320 HILOG_INFO("create helper ret = %{public}d, uri=%{public}s", ret.first, uriProxyStr_.c_str());
321 if (ret.second == nullptr) {
322 Utils::RecordUnavailableEvent(A11yUnavailableEvent::READ_EVENT, A11yError::ERROR_READ_FAILED);
323 return nullptr;
324 }
325 return ret.second;
326 }
327
DestoryDatashareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)328 bool AccessibilityDatashareHelper::DestoryDatashareHelper(std::shared_ptr<DataShare::DataShareHelper>& helper)
329 {
330 if (helper && !helper->Release()) {
331 HILOG_WARN("release helper fail.");
332 return false;
333 }
334 return true;
335 }
336 #endif
337
AssembleUri(const std::string& key)338 Uri AccessibilityDatashareHelper::AssembleUri(const std::string& key)
339 {
340 Uri uri(uriProxyStr_ + "&key=" + key);
341 return uri;
342 }
343
344 } // namespace Accessibility
345 } // namespace OHOS
346
347