• 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 
16 #include "enable_ime_data_parser.h"
17 
18 #include "ime_info_inquirer.h"
19 #include "iservice_registry.h"
20 #include "nlohmann/json.hpp"
21 #include "settings_data_utils.h"
22 #include "system_ability_definition.h"
23 
24 namespace OHOS {
25 namespace MiscServices {
26 using json = nlohmann::json;
27 std::mutex EnableImeDataParser::instanceMutex_;
28 sptr<EnableImeDataParser> EnableImeDataParser::instance_ = nullptr;
~EnableImeDataParser()29 EnableImeDataParser::~EnableImeDataParser()
30 {
31 }
32 
GetInstance()33 sptr<EnableImeDataParser> EnableImeDataParser::GetInstance()
34 {
35     if (instance_ == nullptr) {
36         std::lock_guard<std::mutex> autoLock(instanceMutex_);
37         if (instance_ == nullptr) {
38             IMSA_HILOGI("GetInstance need new EnableImeDataParser");
39             instance_ = new (std::nothrow) EnableImeDataParser();
40             if (instance_ == nullptr) {
41                 IMSA_HILOGI("instance is nullptr.");
42                 return instance_;
43             }
44         }
45     }
46     return instance_;
47 }
48 
Initialize(const int32_t userId)49 int32_t EnableImeDataParser::Initialize(const int32_t userId)
50 {
51     currrentUserId_ = userId;
52     enableList_.insert({ std::string(ENABLE_IME), {} });
53     enableList_.insert({ std::string(ENABLE_KEYBOARD), {} });
54 
55     if (GetEnableData(ENABLE_IME, enableList_[std::string(ENABLE_IME)], userId) != ErrorCode::NO_ERROR) {
56         IMSA_HILOGW("get enable ime list failed");
57     }
58     if (GetEnableData(ENABLE_KEYBOARD, enableList_[std::string(ENABLE_KEYBOARD)], userId) != ErrorCode::NO_ERROR) {
59         IMSA_HILOGW("get enable keyboard list failed");
60     }
61     GetDefaultIme();
62     return ErrorCode::NO_ERROR;
63 }
64 
OnUserChanged(const int32_t targetUserId)65 void EnableImeDataParser::OnUserChanged(const int32_t targetUserId)
66 {
67     std::lock_guard<std::mutex> autoLock(listMutex_);
68     IMSA_HILOGD("Current userId %{public}d, switch to %{public}d", currrentUserId_, targetUserId);
69     currrentUserId_ = targetUserId;
70     if (GetEnableData(ENABLE_IME, enableList_[std::string(ENABLE_IME)], targetUserId) != ErrorCode::NO_ERROR
71         || GetEnableData(ENABLE_KEYBOARD, enableList_[std::string(ENABLE_KEYBOARD)], targetUserId)
72            != ErrorCode::NO_ERROR) {
73         IMSA_HILOGE("get enable list failed.");
74         return;
75     }
76 }
77 
CheckNeedSwitch(const std::string & key,SwitchInfo & switchInfo,const int32_t userId)78 bool EnableImeDataParser::CheckNeedSwitch(const std::string &key, SwitchInfo &switchInfo, const int32_t userId)
79 {
80     IMSA_HILOGD("Run in, data changed.");
81     auto currentIme = ImeInfoInquirer::GetInstance().GetCurrentInputMethod(userId);
82     auto defaultIme = GetDefaultIme();
83     switchInfo.bundleName = defaultIme->name;
84     switchInfo.subName = "";
85     if (key == std::string(ENABLE_IME)) {
86         if (currentIme->name == defaultIme->name) {
87             GetEnableData(key, enableList_[key], userId);
88             IMSA_HILOGD("Current ime is default, do not need switch ime.");
89             return false;
90         }
91         return CheckTargetEnableName(key, currentIme->name, switchInfo.bundleName, userId);
92     } else if (key == std::string(ENABLE_KEYBOARD)) {
93         if (currentIme->name != defaultIme->name || currentIme->id == defaultIme->id) {
94             IMSA_HILOGD("Current ime is not default or id is default.");
95             GetEnableData(key, enableList_[key], userId);
96             return false;
97         }
98         switchInfo.subName = defaultIme->id;
99         return CheckTargetEnableName(key, currentIme->id, switchInfo.subName, userId);
100     }
101     IMSA_HILOGW("Invalid key! key: %{public}s", key.c_str());
102     return false;
103 }
104 
CheckNeedSwitch(const SwitchInfo & info,const int32_t userId)105 bool EnableImeDataParser::CheckNeedSwitch(const SwitchInfo &info, const int32_t userId)
106 {
107     IMSA_HILOGD("Current userId %{public}d, target userId %{public}d, check bundleName %{public}s", currrentUserId_,
108         userId, info.bundleName.c_str());
109     if (info.bundleName == GetDefaultIme()->name) {
110         IMSA_HILOGD("Default ime, permit to switch");
111         return true;
112     }
113     IMSA_HILOGD("Check ime.");
114     std::vector<std::string> enableVec;
115     int32_t ret = GetEnableData(ENABLE_IME, enableVec, userId);
116     if (ret != ErrorCode::NO_ERROR || enableVec.empty()) {
117         IMSA_HILOGD("Get enable list failed, or enable list is empty.");
118         return false;
119     }
120 
121     auto iter = std::find_if(
122         enableVec.begin(), enableVec.end(), [&info](const std::string &ime) { return info.bundleName == ime; });
123     if (iter != enableVec.end()) {
124         IMSA_HILOGD("In enable list.");
125         return true;
126     }
127     return false;
128 }
129 
CheckTargetEnableName(const std::string & key,const std::string & targetName,std::string & nextIme,const int32_t userId)130 bool EnableImeDataParser::CheckTargetEnableName(
131     const std::string &key, const std::string &targetName, std::string &nextIme, const int32_t userId)
132 {
133     IMSA_HILOGD("Run in.");
134     std::vector<std::string> enableVec;
135     int32_t ret = GetEnableData(key, enableVec, userId);
136     if (ret != ErrorCode::NO_ERROR) {
137         IMSA_HILOGE("Get enable list abnormal.");
138         return false;
139     }
140 
141     if (enableVec.empty()) {
142         IMSA_HILOGE("Enable empty, switch default ime.");
143         return true;
144     }
145     std::lock_guard<std::mutex> autoLock(listMutex_);
146     auto iter = std::find_if(
147         enableVec.begin(), enableVec.end(), [&targetName](const std::string &ime) { return ime == targetName; });
148     if (iter != enableVec.end()) {
149         IMSA_HILOGD("Enable list has current ime, do not need switch.");
150         enableList_[key].assign(enableVec.begin(), enableVec.end());
151         return false;
152     }
153 
154     auto it = std::find_if(enableList_[key].begin(), enableList_[key].end(),
155         [&targetName](const std::string &ime) { return ime == targetName; });
156     if (it == enableList_[key].end()) {
157         enableList_[key].assign(enableVec.begin(), enableVec.end());
158         return true;
159     }
160 
161     std::rotate(enableList_[key].begin(), it, enableList_[key].end());
162     auto result =
163         std::find_first_of(enableList_[key].begin(), enableList_[key].end(), enableVec.begin(), enableVec.end());
164     if (result != enableList_[key].end()) {
165         IMSA_HILOGD("Found the next cached ime in enable ime list.");
166         nextIme = *result;
167     }
168     enableList_[key].assign(enableVec.begin(), enableVec.end());
169     return true;
170 }
171 
GetEnableData(const std::string & key,std::vector<std::string> & enableVec,const int32_t userId)172 int32_t EnableImeDataParser::GetEnableData(
173     const std::string &key, std::vector<std::string> &enableVec, const int32_t userId)
174 {
175     if (key != std::string(ENABLE_IME) && key != std::string(ENABLE_KEYBOARD)) {
176         IMSA_HILOGD("Invalid key: %{public}s.", key.c_str());
177         return ErrorCode::ERROR_ENABLE_IME;
178     }
179 
180     IMSA_HILOGD("userId: %{public}d, key: %{public}s.", userId, key.c_str());
181     std::string valueStr;
182     int32_t ret = SettingsDataUtils::GetInstance()->GetStringValue(key, valueStr);
183     if (ret == ErrorCode::ERROR_KEYWORD_NOT_FOUND) {
184         IMSA_HILOGW("No keyword exist");
185         enableVec.clear();
186         return ErrorCode::NO_ERROR;
187     }
188     if (ret != ErrorCode::NO_ERROR || valueStr.empty()) {
189         IMSA_HILOGW("Get value failed, or valueStr is empty");
190         return ErrorCode::ERROR_ENABLE_IME;
191     }
192 
193     if (!ParseJsonData(key, valueStr, enableVec, userId)) {
194         IMSA_HILOGE("valueStr is empty");
195         return ErrorCode::ERROR_ENABLE_IME;
196     }
197     return ErrorCode::NO_ERROR;
198 }
199 
ParseJsonData(const std::string & key,const std::string & valueStr,std::vector<std::string> & enableVec,const int32_t userId)200 bool EnableImeDataParser::ParseJsonData(
201     const std::string &key, const std::string &valueStr, std::vector<std::string> &enableVec, const int32_t userId)
202 {
203     IMSA_HILOGD("valueStr: %{public}s.", valueStr.c_str());
204     json jsonEnableData = json::parse(valueStr.c_str());
205     if (jsonEnableData.is_null() || jsonEnableData.is_discarded()) {
206         IMSA_HILOGE("json parse failed.");
207         return false;
208     }
209     std::string listName = GetJsonListName(key);
210     if (listName.empty()) {
211         IMSA_HILOGE("Get list name failed.");
212         return false;
213     }
214 
215     if (!jsonEnableData.contains(listName) || !jsonEnableData[listName].is_object()) {
216         IMSA_HILOGE("listName not find or abnormal");
217         return false;
218     }
219 
220     std::string id = std::to_string(userId);
221     if (!jsonEnableData[listName].contains(id) || !jsonEnableData[listName][id].is_array()) {
222         IMSA_HILOGE("user id not find or abnormal");
223         return false;
224     }
225     std::vector<std::string> enableVecTemp;
226     for (const auto &bundleName : jsonEnableData[listName][id]) {
227         IMSA_HILOGD("enable ime string: %{public}s", std::string(bundleName).c_str());
228         enableVecTemp.push_back(bundleName);
229     }
230     enableVec.assign(enableVecTemp.begin(), enableVecTemp.end());
231     return true;
232 }
233 
GetJsonListName(const std::string & key)234 const std::string EnableImeDataParser::GetJsonListName(const std::string &key)
235 {
236     if (key == std::string(ENABLE_IME)) {
237         return "enableImeList";
238     } else if (key == std::string(ENABLE_KEYBOARD)) {
239         return "enableKeyboardList";
240     }
241     return "";
242 }
243 
GetDefaultIme()244 std::shared_ptr<Property> EnableImeDataParser::GetDefaultIme()
245 {
246     std::lock_guard<std::mutex> lock(defaultImeMutex_);
247     if (defaultImeInfo_ == nullptr) {
248         defaultImeInfo_ = std::make_shared<Property>();
249     }
250     if (!defaultImeInfo_->name.empty() && !defaultImeInfo_->id.empty()) {
251         IMSA_HILOGD("defaultImeInfo_ has cached defaultime: %{public}s", defaultImeInfo_->name.c_str());
252         return defaultImeInfo_;
253     }
254 
255     auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp();
256     if (defaultIme == nullptr) {
257         IMSA_HILOGE("GetDefaultImeCfgProp return nullptr");
258         return defaultImeInfo_;
259     }
260     defaultImeInfo_->name = defaultIme->name;
261     defaultImeInfo_->id = defaultIme->id;
262     return defaultImeInfo_;
263 }
264 } // namespace MiscServices
265 } // namespace OHOS