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