1 /*
2 * Copyright (c) 2023 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 #include "settings_data_utils.h"
16
17 #include <sstream>
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20
21 namespace OHOS {
22 namespace MiscServices {
~SettingsDataUtils()23 SettingsDataUtils::~SettingsDataUtils()
24 {
25 {
26 std::lock_guard<std::mutex> autoLock(remoteObjMutex_);
27 remoteObj_ = nullptr;
28 }
29 }
30
Release()31 void SettingsDataUtils::Release()
32 {
33 std::list<sptr<SettingsDataObserver>> observerList;
34 {
35 std::lock_guard<decltype(observerListMutex_)> lock(observerListMutex_);
36 observerList = observerList_;
37 observerList_.clear();
38 }
39 if (!observerList.empty()) {
40 for (auto &observer : observerList) {
41 UnregisterObserver(observer);
42 }
43 }
44 }
45
GetInstance()46 SettingsDataUtils &SettingsDataUtils::GetInstance()
47 {
48 static SettingsDataUtils instance;
49 return instance;
50 }
51
CreateAndRegisterObserver(const std::string & uriProxy,const std::string & key,const SettingsDataObserver::CallbackFunc & func)52 int32_t SettingsDataUtils::CreateAndRegisterObserver(
53 const std::string &uriProxy, const std::string &key, const SettingsDataObserver::CallbackFunc &func)
54 {
55 IMSA_HILOGD("uriProxy:%{public}s, key: %{public}s.", uriProxy.c_str(), key.c_str());
56 sptr<SettingsDataObserver> observer = new (std::nothrow) SettingsDataObserver(uriProxy, key, func);
57 if (observer == nullptr) {
58 IMSA_HILOGE("observer is nullptr!");
59 return ErrorCode::ERROR_NULL_POINTER;
60 }
61 return RegisterObserver(observer);
62 }
63 // LCOV_EXCL_START
RegisterObserver(const std::string & uriProxy,const std::string & key,const SettingsDataObserver::CallbackFunc & func,sptr<SettingsDataObserver> & observer)64 int32_t SettingsDataUtils::RegisterObserver(const std::string &uriProxy, const std::string &key,
65 const SettingsDataObserver::CallbackFunc &func, sptr<SettingsDataObserver> &observer)
66 {
67 observer = new (std::nothrow) SettingsDataObserver(uriProxy, key, func);
68 if (observer == nullptr) {
69 IMSA_HILOGE("observer is nullptr!");
70 return ErrorCode::ERROR_NULL_POINTER;
71 }
72 return RegisterObserver(observer);
73 }
74 // LCOV_EXCL_STOP
RegisterObserver(const sptr<SettingsDataObserver> & observer)75 int32_t SettingsDataUtils::RegisterObserver(const sptr<SettingsDataObserver> &observer)
76 {
77 if (observer == nullptr) {
78 IMSA_HILOGE("observer is nullptr!");
79 return ErrorCode::ERROR_NULL_POINTER;
80 }
81 auto uri = GenerateTargetUri(observer->GetUriProxy(), observer->GetKey());
82 auto helper = SettingsDataUtils::CreateDataShareHelper(observer->GetUriProxy());
83 if (helper == nullptr) {
84 IMSA_HILOGE("helper is nullptr!");
85 return ErrorCode::ERROR_NULL_POINTER;
86 }
87 helper->RegisterObserver(uri, observer);
88 ReleaseDataShareHelper(helper);
89 IMSA_HILOGD("succeed to register observer of uri: %{public}s.", uri.ToString().c_str());
90
91 std::lock_guard<decltype(observerListMutex_)> lock(observerListMutex_);
92 observerList_.push_back(observer);
93 return ErrorCode::NO_ERROR;
94 }
95
UnregisterObserver(const sptr<SettingsDataObserver> & observer)96 int32_t SettingsDataUtils::UnregisterObserver(const sptr<SettingsDataObserver> &observer)
97 {
98 if (observer == nullptr) {
99 IMSA_HILOGE("observer is nullptr!");
100 return ErrorCode::ERROR_NULL_POINTER;
101 }
102 auto uri = GenerateTargetUri(observer->GetUriProxy(), observer->GetKey());
103 auto helper = SettingsDataUtils::CreateDataShareHelper(observer->GetUriProxy());
104 if (helper == nullptr) {
105 IMSA_HILOGE("helper is nullptr!");
106 return ErrorCode::ERROR_NULL_POINTER;
107 }
108 helper->UnregisterObserver(uri, observer);
109 ReleaseDataShareHelper(helper);
110 IMSA_HILOGD("succeed to unregister observer of uri: %{public}s.", uri.ToString().c_str());
111
112 std::lock_guard<decltype(observerListMutex_)> lock(observerListMutex_);
113 observerList_.remove(observer);
114 return ErrorCode::NO_ERROR;
115 }
116
CreateDataShareHelper(const std::string & uriProxy)117 std::shared_ptr<DataShare::DataShareHelper> SettingsDataUtils::CreateDataShareHelper(const std::string &uriProxy)
118 {
119 auto remoteObj = GetToken();
120 if (remoteObj == nullptr) {
121 IMSA_HILOGE("remoteObk is nullptr!");
122 return nullptr;
123 }
124
125 auto helper = DataShare::DataShareHelper::Creator(remoteObj_, uriProxy, std::string(SETTINGS_DATA_EXT_URI));
126 if (helper == nullptr) {
127 IMSA_HILOGE("create helper failed, uri: %{public}s!", uriProxy.c_str());
128 return nullptr;
129 }
130 return helper;
131 }
132
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)133 bool SettingsDataUtils::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
134 {
135 if (helper == nullptr) {
136 IMSA_HILOGW("helper is nullptr.");
137 return true;
138 }
139 if (!helper->Release()) {
140 IMSA_HILOGE("release data share helper failed.");
141 return false;
142 }
143 return true;
144 }
145
GenerateTargetUri(const std::string & uriProxy,const std::string & key)146 Uri SettingsDataUtils::GenerateTargetUri(const std::string &uriProxy, const std::string &key)
147 {
148 Uri uri(uriProxy + "&key=" + key);
149 return uri;
150 }
151 // LCOV_EXCL_START
SetStringValue(const std::string & uriProxy,const std::string & key,const std::string & value)152 bool SettingsDataUtils::SetStringValue(const std::string &uriProxy, const std::string &key, const std::string &value)
153 {
154 IMSA_HILOGD("start.");
155 auto helper = CreateDataShareHelper(uriProxy);
156 if (helper == nullptr) {
157 IMSA_HILOGE("helper is nullptr.");
158 return false;
159 }
160 DataShare::DataShareValueObject keyObj(key);
161 DataShare::DataShareValueObject valueObj(value);
162 DataShare::DataShareValuesBucket bucket;
163 bucket.Put(SETTING_COLUMN_KEYWORD, keyObj);
164 bucket.Put(SETTING_COLUMN_VALUE, valueObj);
165 DataShare::DataSharePredicates predicates;
166 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
167 Uri uri(GenerateTargetUri(uriProxy, key));
168 if (helper->Update(uri, predicates, bucket) <= 0) {
169 int index = helper->Insert(uri, bucket);
170 IMSA_HILOGI("no data exists, insert ret index: %{public}d", index);
171 } else {
172 IMSA_HILOGI("data exits");
173 }
174 bool ret = ReleaseDataShareHelper(helper);
175 IMSA_HILOGI("ReleaseDataShareHelper isSuccess: %{public}d", ret);
176 return ret;
177 }
178
GetStringValue(const std::string & uriProxy,const std::string & key,std::string & value)179 int32_t SettingsDataUtils::GetStringValue(const std::string &uriProxy, const std::string &key, std::string &value)
180 {
181 IMSA_HILOGD("start.");
182 auto helper = CreateDataShareHelper(uriProxy);
183 if (helper == nullptr) {
184 IMSA_HILOGE("helper is nullptr.");
185 return ErrorCode::ERROR_NULL_POINTER;
186 }
187 std::vector<std::string> columns = { SETTING_COLUMN_VALUE };
188 DataShare::DataSharePredicates predicates;
189 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
190 Uri uri(GenerateTargetUri(uriProxy, key));
191 auto resultSet = helper->Query(uri, predicates, columns);
192 ReleaseDataShareHelper(helper);
193 if (resultSet == nullptr) {
194 IMSA_HILOGE("resultSet is nullptr.");
195 return ErrorCode::ERROR_NULL_POINTER;
196 }
197
198 int32_t count = 0;
199 resultSet->GetRowCount(count);
200 if (count <= 0) {
201 IMSA_HILOGW("not found keyword, key: %{public}s, count: %{public}d.", key.c_str(), count);
202 resultSet->Close();
203 return ErrorCode::ERROR_KEYWORD_NOT_FOUND;
204 }
205
206 int32_t columIndex = 0;
207 resultSet->GoToFirstRow();
208 resultSet->GetColumnIndex(SETTING_COLUMN_VALUE, columIndex);
209 int32_t ret = resultSet->GetString(columIndex, value);
210 if (ret != DataShare::E_OK) {
211 IMSA_HILOGE("failed to GetString, ret: %{public}d!", ret);
212 }
213 resultSet->Close();
214 return ret;
215 }
216 // LCOV_EXCL_STOP
GetToken()217 sptr<IRemoteObject> SettingsDataUtils::GetToken()
218 {
219 std::lock_guard<std::mutex> autoLock(remoteObjMutex_);
220 if (remoteObj_ != nullptr) {
221 return remoteObj_;
222 }
223 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
224 if (samgr == nullptr) {
225 IMSA_HILOGE("system ability manager is nullptr!");
226 return nullptr;
227 }
228 auto remoteObj = samgr->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
229 if (remoteObj == nullptr) {
230 IMSA_HILOGE("system ability is nullptr!");
231 return nullptr;
232 }
233 remoteObj_ = remoteObj;
234 return remoteObj_;
235 }
236
NotifyDataShareReady()237 void SettingsDataUtils::NotifyDataShareReady()
238 {
239 isDataShareReady_.store(true);
240 }
241
IsDataShareReady()242 bool SettingsDataUtils::IsDataShareReady()
243 {
244 return isDataShareReady_.load();
245 }
246 } // namespace MiscServices
247 } // namespace OHOS