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