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
16 #include "settings_data_utils.h"
17
18 #include "ime_info_inquirer.h"
19 #include "iservice_registry.h"
20 #include "nlohmann/json.hpp"
21 #include "system_ability_definition.h"
22
23 namespace OHOS {
24 namespace MiscServices {
25 using json = nlohmann::json;
26 std::mutex SettingsDataUtils::instanceMutex_;
27 sptr<SettingsDataUtils> SettingsDataUtils::instance_ = nullptr;
28 constexpr const char *SETTING_COLUMN_KEYWORD = "KEYWORD";
29 constexpr const char *SETTING_COLUMN_VALUE = "VALUE";
30 constexpr const char *SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/"
31 "SETTINGSDATA?Proxy=true";
32 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
~SettingsDataUtils()33 SettingsDataUtils::~SettingsDataUtils()
34 {
35 remoteObj_ = nullptr;
36 if (!observerList_.empty()) {
37 for (auto &iter : observerList_) {
38 UnregisterObserver(iter);
39 }
40 observerList_.clear();
41 }
42 }
43
GetInstance()44 sptr<SettingsDataUtils> SettingsDataUtils::GetInstance()
45 {
46 if (instance_ == nullptr) {
47 std::lock_guard<std::mutex> autoLock(instanceMutex_);
48 if (instance_ == nullptr) {
49 IMSA_HILOGI("GetInstance need new SettingsDataUtils");
50 instance_ = new (std::nothrow) SettingsDataUtils();
51 if (instance_ == nullptr) {
52 IMSA_HILOGE("instance is nullptr.");
53 return instance_;
54 }
55 }
56 }
57 return instance_;
58 }
59
CreateAndRegisterObserver(const std::string & key,SettingsDataObserver::CallbackFunc func)60 int32_t SettingsDataUtils::CreateAndRegisterObserver(const std::string &key, SettingsDataObserver::CallbackFunc func)
61 {
62 IMSA_HILOGD("key: %{public}s.", key.c_str());
63 sptr<SettingsDataObserver> observer = new (std::nothrow) SettingsDataObserver(key, func);
64 if (observer == nullptr) {
65 IMSA_HILOGE("new observer is nullptr.");
66 return ErrorCode::ERROR_NULL_POINTER;
67 }
68 return RegisterObserver(observer);
69 }
70
RegisterObserver(const sptr<SettingsDataObserver> & observer)71 int32_t SettingsDataUtils::RegisterObserver(const sptr<SettingsDataObserver> &observer)
72 {
73 if (observer == nullptr) {
74 IMSA_HILOGE("observer is nullptr.");
75 return ErrorCode::ERROR_NULL_POINTER;
76 }
77
78 auto uri = GenerateTargetUri(observer->GetKey());
79 auto helper = SettingsDataUtils::CreateDataShareHelper();
80 if (helper == nullptr) {
81 IMSA_HILOGE("CreateDataShareHelper return nullptr.");
82 return ErrorCode::ERROR_NULL_POINTER;
83 }
84 helper->RegisterObserver(uri, observer);
85 ReleaseDataShareHelper(helper);
86 IMSA_HILOGD("succeed to register observer of uri=%{public}s", uri.ToString().c_str());
87 observerList_.push_back(observer);
88 return ErrorCode::NO_ERROR;
89 }
90
UnregisterObserver(const sptr<SettingsDataObserver> & observer)91 int32_t SettingsDataUtils::UnregisterObserver(const sptr<SettingsDataObserver> &observer)
92 {
93 auto uri = GenerateTargetUri(observer->GetKey());
94 auto helper = SettingsDataUtils::CreateDataShareHelper();
95 if (helper == nullptr) {
96 return ErrorCode::ERROR_ENABLE_IME;
97 }
98 helper->UnregisterObserver(uri, observer);
99 ReleaseDataShareHelper(helper);
100 IMSA_HILOGD("succeed to unregister observer of uri=%{public}s", uri.ToString().c_str());
101 return ErrorCode::NO_ERROR;
102 }
103
CreateDataShareHelper()104 std::shared_ptr<DataShare::DataShareHelper> SettingsDataUtils::CreateDataShareHelper()
105 {
106 auto remoteObj = GetToken();
107 if (remoteObj == nullptr) {
108 IMSA_HILOGE("remoteObk is nullptr.");
109 return nullptr;
110 }
111
112 auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
113 if (helper == nullptr) {
114 IMSA_HILOGE("Create helper failed, uri=%{public}s", SETTING_URI_PROXY);
115 return nullptr;
116 }
117 return helper;
118 }
119
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)120 bool SettingsDataUtils::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
121 {
122 if (helper == nullptr) {
123 IMSA_HILOGW("helper is nullptr.");
124 return true;
125 }
126 if (!helper->Release()) {
127 IMSA_HILOGE("Release data share helper failed.");
128 return false;
129 }
130 return true;
131 }
132
GenerateTargetUri(const std::string & key)133 Uri SettingsDataUtils::GenerateTargetUri(const std::string &key)
134 {
135 Uri uri(std::string(SETTING_URI_PROXY) + "&key=" + key);
136 return uri;
137 }
138
139
GetStringValue(const std::string & key,std::string & value)140 int32_t SettingsDataUtils::GetStringValue(const std::string &key, std::string &value)
141 {
142 IMSA_HILOGD("Run in.");
143 auto helper = CreateDataShareHelper();
144 if (helper == nullptr) {
145 IMSA_HILOGE("CreateDataShareHelper return nullptr.");
146 return ErrorCode::ERROR_NULL_POINTER;
147 }
148 std::vector<std::string> columns = { SETTING_COLUMN_VALUE };
149 DataShare::DataSharePredicates predicates;
150 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
151 Uri uri(GenerateTargetUri(key));
152 auto resultSet = helper->Query(uri, predicates, columns);
153 ReleaseDataShareHelper(helper);
154 if (resultSet == nullptr) {
155 IMSA_HILOGE("helper->Query return nullptr.");
156 return ErrorCode::ERROR_NULL_POINTER;
157 }
158
159 int32_t count = 0;
160 resultSet->GetRowCount(count);
161 if (count <= 0) {
162 IMSA_HILOGW("Not found keyword, key=%{public}s, count=%{public}d", key.c_str(), count);
163 resultSet->Close();
164 return ErrorCode::ERROR_KEYWORD_NOT_FOUND;
165 }
166
167 int32_t columIndex = 0;
168 resultSet->GoToFirstRow();
169 resultSet->GetColumnIndex(SETTING_COLUMN_VALUE, columIndex);
170 int32_t ret = resultSet->GetString(columIndex, value);
171 if (ret != DataShare::E_OK) {
172 IMSA_HILOGE("GetString failed, ret=%{public}d", ret);
173 }
174 resultSet->Close();
175 return ret;
176 }
177
GetToken()178 sptr<IRemoteObject> SettingsDataUtils::GetToken()
179 {
180 std::lock_guard<std::mutex> autoLock(tokenMutex_);
181 if (remoteObj_ != nullptr) {
182 return remoteObj_;
183 }
184 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
185 if (samgr == nullptr) {
186 IMSA_HILOGE("GetSystemAbilityManager return nullptr");
187 return nullptr;
188 }
189 auto remoteObj = samgr->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
190 if (remoteObj == nullptr) {
191 IMSA_HILOGE("GetSystemAbility return nullptr");
192 return nullptr;
193 }
194 remoteObj_ = remoteObj;
195 return remoteObj_;
196 }
197 } // namespace MiscServices
198 } // namespace OHOS