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