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 "ime_info_inquirer.h"
17 #include "app_mgr_client.h"
18 #include "bundle_mgr_client_impl.h"
19 #include "full_ime_info_manager.h"
20 #include "input_type_manager.h"
21 #include "iservice_registry.h"
22 #include "locale_config.h"
23 #include "os_account_adapter.h"
24 #include "parameter.h"
25 #include "system_ability_definition.h"
26
27 namespace OHOS {
28 namespace MiscServices {
29 namespace {
30 using namespace OHOS::AppExecFwk;
31 using namespace Global::Resource;
32 using namespace OHOS::AAFwk;
33 constexpr const char *SUBTYPE_PROFILE_METADATA_NAME = "ohos.extension.input_method";
34 constexpr const char *TEMPORARY_INPUT_METHOD_METADATA_NAME = "ohos.extension.temporary_input_method";
35 constexpr uint32_t SUBTYPE_PROFILE_NUM = 1;
36 constexpr const char *DEFAULT_IME_KEY = "persist.sys.default_ime";
37 constexpr int32_t CONFIG_LEN = 128;
38 constexpr uint32_t DEFAULT_BMS_VALUE = 0;
39 } // namespace
GetInstance()40 ImeInfoInquirer &ImeInfoInquirer::GetInstance()
41 {
42 static ImeInfoInquirer instance;
43 return instance;
44 }
45
InitSystemConfig()46 void ImeInfoInquirer::InitSystemConfig()
47 {
48 auto ret = SysCfgParser::ParseSystemConfig(systemConfig_);
49 if (!ret) {
50 IMSA_HILOGE("parse systemConfig failed!");
51 return;
52 }
53 }
54
IsEnableInputMethod()55 bool ImeInfoInquirer::IsEnableInputMethod()
56 {
57 return systemConfig_.enableInputMethodFeature;
58 }
59
IsEnableSecurityMode()60 bool ImeInfoInquirer::IsEnableSecurityMode()
61 {
62 return systemConfig_.enableFullExperienceFeature;
63 }
64
GetSystemInitEnabledState()65 EnabledStatus ImeInfoInquirer::GetSystemInitEnabledState()
66 {
67 return systemConfig_.initEnabledState;
68 }
69
QueryImeExtInfos(const int32_t userId,std::vector<ExtensionAbilityInfo> & infos)70 bool ImeInfoInquirer::QueryImeExtInfos(const int32_t userId, std::vector<ExtensionAbilityInfo> &infos)
71 {
72 IMSA_HILOGD("userId: %{public}d.", userId);
73 auto bundleMgr = GetBundleMgr();
74 if (bundleMgr == nullptr) {
75 IMSA_HILOGE("failed to GetBundleMgr!");
76 return false;
77 }
78 if (!bundleMgr->QueryExtensionAbilityInfos(ExtensionAbilityType::INPUTMETHOD, userId, infos)) {
79 IMSA_HILOGF("query extension infos failed from bundleMgr!");
80 return false;
81 }
82 return true;
83 }
84
GetExtInfosByBundleName(const int32_t userId,const std::string & bundleName,std::vector<AppExecFwk::ExtensionAbilityInfo> & extInfos)85 int32_t ImeInfoInquirer::GetExtInfosByBundleName(const int32_t userId, const std::string &bundleName,
86 std::vector<AppExecFwk::ExtensionAbilityInfo> &extInfos)
87 {
88 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s.", userId, bundleName.c_str());
89 std::vector<AppExecFwk::ExtensionAbilityInfo> tempExtInfos;
90 if (!QueryImeExtInfos(userId, tempExtInfos)) {
91 IMSA_HILOGE("failed to QueryImeExtInfos!");
92 return ErrorCode::ERROR_BAD_PARAMETERS;
93 }
94 for (const auto &extInfo : tempExtInfos) {
95 if (extInfo.bundleName == bundleName) {
96 extInfos.emplace_back(extInfo);
97 }
98 }
99 if (extInfos.empty()) {
100 IMSA_HILOGE("bundleName: %{public}s extInfos is empty!", bundleName.c_str());
101 return ErrorCode::ERROR_BAD_PARAMETERS;
102 }
103 return ErrorCode::NO_ERROR;
104 }
105
GetImeInfo(int32_t userId,const std::string & bundleName,const std::string & subName)106 std::shared_ptr<ImeInfo> ImeInfoInquirer::GetImeInfo(int32_t userId, const std::string &bundleName,
107 const std::string &subName)
108 {
109 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, subName: %{public}s.", userId, bundleName.c_str(),
110 subName.c_str());
111 auto info = GetImeInfoFromCache(userId, bundleName, subName);
112 return info == nullptr ? GetImeInfoFromBundleMgr(userId, bundleName, subName) : info;
113 }
114
GetImeInfoFromCache(const int32_t userId,const std::string & bundleName,const std::string & subName)115 std::shared_ptr<ImeInfo> ImeInfoInquirer::GetImeInfoFromCache(const int32_t userId, const std::string &bundleName,
116 const std::string &subName)
117 {
118 auto fullInfo = FullImeInfoManager::GetInstance().Get(userId);
119 auto it = std::find_if(fullInfo.begin(), fullInfo.end(),
120 [&bundleName](const FullImeInfo &info) { return info.prop.name == bundleName; });
121 if (it == fullInfo.end()) {
122 return nullptr;
123 }
124 auto info = std::make_shared<ImeInfo>();
125 auto subProps = it->subProps;
126 info->isSpecificSubName = !subName.empty();
127 if (subName.empty() && !subProps.empty()) {
128 info->subProp = subProps[0];
129 } else {
130 auto iter = std::find_if(subProps.begin(), subProps.end(),
131 [&subName](const SubProperty &subProp) { return subProp.id == subName; });
132 if (iter == subProps.end()) {
133 IMSA_HILOGE("find subName: %{public}s failed!", subName.c_str());
134 return nullptr;
135 }
136 info->subProp = *iter;
137 }
138 info->isNewIme = it->isNewIme;
139 info->subProps = it->subProps;
140 info->prop = it->prop;
141 if (!info->isNewIme) {
142 // old ime, make the id of prop same with the id of subProp.
143 info->prop.id = info->subProp.id;
144 }
145 return info;
146 }
147
GetImeInfoFromBundleMgr(const int32_t userId,const std::string & bundleName,const std::string & subName)148 std::shared_ptr<ImeInfo> ImeInfoInquirer::GetImeInfoFromBundleMgr(const int32_t userId, const std::string &bundleName,
149 const std::string &subName)
150 {
151 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, subName: %{public}s.", userId, bundleName.c_str(),
152 subName.c_str());
153 std::vector<AppExecFwk::ExtensionAbilityInfo> extInfos;
154 auto ret = ImeInfoInquirer::GetInstance().GetExtInfosByBundleName(userId, bundleName, extInfos);
155 if (ret != ErrorCode::NO_ERROR || extInfos.empty()) {
156 IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed!", userId, bundleName.c_str());
157 return nullptr;
158 }
159 auto info = std::make_shared<ImeInfo>();
160 info->prop.name = extInfos[0].bundleName;
161 info->prop.id = extInfos[0].name;
162 info->prop.label = GetTargetString(extInfos[0], ImeTargetString::LABEL, userId);
163 info->prop.labelId = extInfos[0].applicationInfo.labelId;
164 info->prop.iconId = extInfos[0].applicationInfo.iconId;
165
166 std::vector<SubProperty> subProps;
167 info->isNewIme = IsNewExtInfos(extInfos);
168 ret = info->isNewIme ? ListInputMethodSubtype(userId, extInfos[0], subProps)
169 : ListInputMethodSubtype(userId, extInfos, subProps);
170 if (ret != ErrorCode::NO_ERROR || subProps.empty()) {
171 IMSA_HILOGE("userId: %{public}d listInputMethodSubtype failed!", userId);
172 return nullptr;
173 }
174 info->subProps = subProps;
175 if (subName.empty()) {
176 info->isSpecificSubName = false;
177 info->subProp = subProps[0];
178 } else {
179 auto it = std::find_if(subProps.begin(), subProps.end(),
180 [&subName](const SubProperty &subProp) { return subProp.id == subName; });
181 if (it == subProps.end()) {
182 IMSA_HILOGE("find subName: %{public}s failed!", subName.c_str());
183 return nullptr;
184 }
185 info->subProp = *it;
186 }
187 // old ime, make the id of prop same with the id of subProp.
188 if (!info->isNewIme) {
189 info->prop.id = info->subProp.id;
190 }
191 return info;
192 }
193
GetDumpInfo(int32_t userId)194 std::string ImeInfoInquirer::GetDumpInfo(int32_t userId)
195 {
196 auto properties = ListInputMethodInfo(userId);
197 if (properties.empty()) {
198 return "";
199 }
200 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId);
201 bool isBegin = true;
202 std::string params = "{\"imeList\":[";
203 for (const auto &property : properties) {
204 params += isBegin ? "" : "},";
205 isBegin = false;
206
207 std::string imeId = property.mPackageName + "/" + property.mAbilityName;
208 params += "{\"ime\": \"" + imeId + "\",";
209 params += "\"labelId\": \"" + std::to_string(property.labelId) + "\",";
210 params += "\"descriptionId\": \"" + std::to_string(property.descriptionId) + "\",";
211 std::string isCurrentIme = currentImeCfg->imeId == imeId ? "true" : "false";
212 params += "\"isCurrentIme\": \"" + isCurrentIme + "\",";
213 params += "\"label\": \"" + property.label + "\",";
214 params += "\"description\": \"" + property.description + "\"";
215 }
216 params += "}]}";
217 return params;
218 }
219
ListInputMethodInfo(const int32_t userId)220 std::vector<InputMethodInfo> ImeInfoInquirer::ListInputMethodInfo(const int32_t userId)
221 {
222 IMSA_HILOGD("userId: %{public}d.", userId);
223 std::vector<ExtensionAbilityInfo> extensionInfos;
224 if (!QueryImeExtInfos(userId, extensionInfos)) {
225 IMSA_HILOGE("userId: %{public}d queryImeExtInfos failed!", userId);
226 return {};
227 }
228 std::vector<InputMethodInfo> properties;
229 for (const auto &extension : extensionInfos) {
230 auto applicationInfo = extension.applicationInfo;
231 auto label = GetTargetString(extension, ImeTargetString::LABEL, userId);
232 auto description = GetTargetString(extension, ImeTargetString::DESCRIPTION, userId);
233 InputMethodInfo property;
234 property.mPackageName = extension.bundleName;
235 property.mAbilityName = extension.name;
236 property.labelId = applicationInfo.labelId;
237 property.descriptionId = applicationInfo.descriptionId;
238 property.label = label;
239 property.description = description;
240 properties.emplace_back(property);
241 }
242 return properties;
243 }
244
ListInputMethod(int32_t userId,InputMethodStatus status,std::vector<Property> & props,bool enableOn)245 int32_t ImeInfoInquirer::ListInputMethod(int32_t userId, InputMethodStatus status, std::vector<Property> &props,
246 bool enableOn)
247 {
248 IMSA_HILOGD("userId: %{public}d, status: %{public}d.", userId, status);
249 if (status == InputMethodStatus::ALL) {
250 return ListInputMethod(userId, props);
251 }
252 if (status == InputMethodStatus::ENABLE) {
253 return ListEnabledInputMethod(userId, props, enableOn);
254 }
255 if (status == InputMethodStatus::DISABLE) {
256 return ListDisabledInputMethod(userId, props, enableOn);
257 }
258 return ErrorCode::ERROR_BAD_PARAMETERS;
259 }
260
ListInputMethod(const int32_t userId,std::vector<Property> & props)261 int32_t ImeInfoInquirer::ListInputMethod(const int32_t userId, std::vector<Property> &props)
262 {
263 IMSA_HILOGD("userId: %{public}d.", userId);
264 auto infos = FullImeInfoManager::GetInstance().Get(userId);
265 for (const auto &info : infos) {
266 props.push_back(info.prop);
267 }
268 if (!props.empty()) {
269 return ErrorCode::NO_ERROR;
270 }
271
272 IMSA_HILOGD("%{public}d get all prop form bms.", userId);
273 std::vector<ExtensionAbilityInfo> extensionInfos;
274 if (!QueryImeExtInfos(userId, extensionInfos)) {
275 IMSA_HILOGE("failed to QueryImeExtInfos!");
276 return ErrorCode::ERROR_BAD_PARAMETERS;
277 }
278 for (const auto &extension : extensionInfos) {
279 auto it = std::find_if(props.begin(), props.end(),
280 [&extension](const Property &prop) { return prop.name == extension.bundleName; });
281 if (it != props.end()) {
282 continue;
283 }
284 if (IsTempInputMethod(extension)) {
285 continue;
286 }
287 props.push_back({ .name = extension.bundleName,
288 .id = extension.name,
289 .label = GetTargetString(extension, ImeTargetString::LABEL, userId),
290 .labelId = extension.applicationInfo.labelId,
291 .iconId = extension.applicationInfo.iconId });
292 }
293 return ErrorCode::NO_ERROR;
294 }
295
ListEnabledInputMethod(const int32_t userId,std::vector<Property> & props,bool enableOn)296 int32_t ImeInfoInquirer::ListEnabledInputMethod(const int32_t userId, std::vector<Property> &props, bool enableOn)
297 {
298 IMSA_HILOGD("userId: %{public}d.", userId);
299 int32_t ret = ListInputMethod(userId, props);
300 if (ret != ErrorCode::NO_ERROR) {
301 IMSA_HILOGE("userId: %{public}d listInputMethod failed!", userId);
302 return ret;
303 }
304 if (enableOn) {
305 IMSA_HILOGD("enable on.");
306 std::vector<std::string> enableVec;
307 ret = EnableImeDataParser::GetInstance()->GetEnableIme(userId, enableVec);
308 if (ret != ErrorCode::NO_ERROR) {
309 IMSA_HILOGE("get enable data failed!");
310 return ret;
311 }
312 auto info = GetDefaultIme();
313 enableVec.insert(enableVec.begin(), info.bundleName);
314
315 auto newEnd = std::remove_if(props.begin(), props.end(), [&enableVec](const auto &prop) {
316 return std::find(enableVec.begin(), enableVec.end(), prop.name) == enableVec.end();
317 });
318 props.erase(newEnd, props.end());
319 }
320 return ErrorCode::NO_ERROR;
321 }
322
ListDisabledInputMethod(const int32_t userId,std::vector<Property> & props,bool enableOn)323 int32_t ImeInfoInquirer::ListDisabledInputMethod(const int32_t userId, std::vector<Property> &props, bool enableOn)
324 {
325 IMSA_HILOGD("userId: %{public}d.", userId);
326 if (!enableOn) {
327 IMSA_HILOGD("enable mode off, get disabled ime.");
328 return ErrorCode::NO_ERROR;
329 }
330
331 auto ret = ListInputMethod(userId, props);
332 if (ret != ErrorCode::NO_ERROR) {
333 IMSA_HILOGE("userId: %{public}d listInputMethod failed!", userId);
334 return ret;
335 }
336
337 std::vector<std::string> enableVec;
338 ret = EnableImeDataParser::GetInstance()->GetEnableIme(userId, enableVec);
339 if (ret != ErrorCode::NO_ERROR) {
340 IMSA_HILOGE("get enable data failed!");
341 return ret;
342 }
343 auto info = GetDefaultIme();
344 enableVec.insert(enableVec.begin(), info.bundleName);
345
346 auto newEnd = std::remove_if(props.begin(), props.end(), [&enableVec](const auto &prop) {
347 return std::find(enableVec.begin(), enableVec.end(), prop.name) != enableVec.end();
348 });
349 props.erase(newEnd, props.end());
350 return ErrorCode::NO_ERROR;
351 }
352
GetSwitchInfoBySwitchCount(SwitchInfo & switchInfo,int32_t userId,bool enableOn,uint32_t cacheCount)353 int32_t ImeInfoInquirer::GetSwitchInfoBySwitchCount(SwitchInfo &switchInfo, int32_t userId, bool enableOn,
354 uint32_t cacheCount)
355 {
356 std::vector<Property> props;
357 auto ret = ListEnabledInputMethod(userId, props, enableOn);
358 if (ret != ErrorCode::NO_ERROR) {
359 IMSA_HILOGE("userId: %{public}d ListEnabledInputMethod failed!", userId);
360 return ret;
361 }
362 auto currentImeBundle = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName;
363 auto iter = std::find_if(props.begin(), props.end(),
364 [¤tImeBundle](const Property &property) { return property.name == currentImeBundle; });
365 if (iter == props.end()) {
366 IMSA_HILOGE("can not found current ime in enable list!");
367 auto info = GetDefaultImeInfo(userId);
368 if (info != nullptr) {
369 switchInfo.bundleName = info->prop.name;
370 return ErrorCode::NO_ERROR;
371 }
372 IMSA_HILOGE("bundle manager error!");
373 return ErrorCode::ERROR_PACKAGE_MANAGER;
374 }
375 uint32_t nextIndex = (cacheCount + static_cast<uint32_t>(std::distance(props.begin(), iter))) % props.size();
376 switchInfo.bundleName = props[nextIndex].name;
377 IMSA_HILOGD("next ime: %{public}s", switchInfo.bundleName.c_str());
378 return ErrorCode::NO_ERROR;
379 }
380
ListInputMethodSubtype(int32_t userId,const std::string & bundleName,std::vector<SubProperty> & subProps)381 int32_t ImeInfoInquirer::ListInputMethodSubtype(int32_t userId, const std::string &bundleName,
382 std::vector<SubProperty> &subProps)
383 {
384 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s.", userId, bundleName.c_str());
385 auto infos = FullImeInfoManager::GetInstance().Get(userId);
386 auto it = std::find_if(
387 infos.begin(), infos.end(), [&bundleName](const FullImeInfo &info) { return info.prop.name == bundleName; });
388 if (it != infos.end()) {
389 subProps = (*it).subProps;
390 return ErrorCode::NO_ERROR;
391 }
392
393 IMSA_HILOGD("%{public}d get %{public}s all subProp form bms.", userId, bundleName.c_str());
394 std::vector<ExtensionAbilityInfo> extInfos;
395 auto ret = GetExtInfosByBundleName(userId, bundleName, extInfos);
396 if (ret != ErrorCode::NO_ERROR) {
397 IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed!", userId, bundleName.c_str());
398 return ret;
399 }
400 return IsNewExtInfos(extInfos) ? ListInputMethodSubtype(userId, extInfos[0], subProps)
401 : ListInputMethodSubtype(userId, extInfos, subProps);
402 }
403
ListCurrentInputMethodSubtype(int32_t userId,std::vector<SubProperty> & subProps)404 int32_t ImeInfoInquirer::ListCurrentInputMethodSubtype(int32_t userId, std::vector<SubProperty> &subProps)
405 {
406 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId);
407 IMSA_HILOGD("currentIme: %{public}s.", currentImeCfg->imeId.c_str());
408 return ListInputMethodSubtype(userId, currentImeCfg->bundleName, subProps);
409 }
410
IsNewExtInfos(const std::vector<ExtensionAbilityInfo> & extInfos)411 bool ImeInfoInquirer::IsNewExtInfos(const std::vector<ExtensionAbilityInfo> &extInfos)
412 {
413 if (extInfos.empty()) {
414 IMSA_HILOGE("extInfos is empty!");
415 return false;
416 }
417 auto iter = std::find_if(extInfos[0].metadata.begin(), extInfos[0].metadata.end(),
418 [](const Metadata &metadata) { return metadata.name == SUBTYPE_PROFILE_METADATA_NAME; });
419 return iter != extInfos[0].metadata.end();
420 }
421
GetSubProperty(int32_t userId,const std::string & subName,const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> & extInfos,SubProperty & subProp)422 int32_t ImeInfoInquirer::GetSubProperty(int32_t userId, const std::string &subName,
423 const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> &extInfos, SubProperty &subProp)
424 {
425 IMSA_HILOGD("oldIme, userId: %{public}d.", userId);
426 if (extInfos.empty()) {
427 IMSA_HILOGE("extInfos is empty!");
428 return ErrorCode::ERROR_PACKAGE_MANAGER;
429 }
430 auto extInfo = std::find_if(extInfos.begin(), extInfos.end(),
431 [&subName](const ExtensionAbilityInfo &info) { return info.name == subName; });
432 if (extInfo == extInfos.end()) {
433 IMSA_HILOGE("subtype %{public}s not found!", subName.c_str());
434 extInfo = extInfos.begin();
435 }
436 subProp.labelId = extInfo->labelId;
437 subProp.label = GetStringById(extInfo->bundleName, extInfo->moduleName, extInfo->labelId, userId);
438 subProp.id = extInfo->name;
439 subProp.name = extInfo->bundleName;
440 subProp.iconId = extInfo->iconId;
441 std::vector<Metadata> extends = extInfo->metadata;
442 auto property = GetExtends(extends);
443 subProp.language = property.language;
444 subProp.mode = property.mode;
445 subProp.locale = property.locale;
446 subProp.icon = property.icon;
447 return ErrorCode::NO_ERROR;
448 }
449
ListInputMethodSubtype(const int32_t userId,const std::vector<ExtensionAbilityInfo> & extInfos,std::vector<SubProperty> & subProps)450 int32_t ImeInfoInquirer::ListInputMethodSubtype(const int32_t userId,
451 const std::vector<ExtensionAbilityInfo> &extInfos, std::vector<SubProperty> &subProps)
452 {
453 IMSA_HILOGD("oldIme, userId: %{public}d.", userId);
454 for (const auto &extInfo : extInfos) {
455 SubProperty subProperty;
456 subProperty.labelId = extInfo.labelId;
457 subProperty.label = GetStringById(extInfo.bundleName, extInfo.moduleName, extInfo.labelId, userId);
458 subProperty.id = extInfo.name;
459 subProperty.name = extInfo.bundleName;
460 subProperty.iconId = extInfo.iconId;
461 std::vector<Metadata> extends = extInfo.metadata;
462 auto property = GetExtends(extends);
463 subProperty.language = property.language;
464 subProperty.mode = property.mode;
465 subProperty.locale = property.locale;
466 subProperty.icon = property.icon;
467 subProps.emplace_back(subProperty);
468 }
469 return ErrorCode::NO_ERROR;
470 }
471
GetSubProperty(int32_t userId,const std::string & subName,const OHOS::AppExecFwk::ExtensionAbilityInfo & extInfo,SubProperty & subProp)472 int32_t ImeInfoInquirer::GetSubProperty(int32_t userId, const std::string &subName,
473 const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo, SubProperty &subProp)
474 {
475 IMSA_HILOGD("newIme, userId: %{public}d.", userId);
476 std::vector<Subtype> subtypes;
477 auto ret = ParseSubtype(extInfo, subtypes);
478 if (ret != ErrorCode::NO_ERROR) {
479 IMSA_HILOGE("failed to parse subtype!");
480 return ret;
481 }
482 if (subtypes.empty()) {
483 IMSA_HILOGE("subtypes is empty!");
484 return ErrorCode::ERROR_PACKAGE_MANAGER;
485 }
486 auto subtype = std::find_if(
487 subtypes.begin(), subtypes.end(), [&subName](const Subtype &subtype) { return subtype.id == subName; });
488 if (subtype == subtypes.end()) {
489 IMSA_HILOGE("subtype %{public}s not found!", subName.c_str());
490 subtype = subtypes.begin();
491 }
492 subProp.label = subtype->label;
493 subProp.name = extInfo.bundleName;
494 subProp.id = subtype->id;
495 subProp.mode = subtype->mode;
496 subProp.locale = subtype->locale;
497 subProp.icon = subtype->icon;
498 auto pos = subProp.label.find(':');
499 if (pos != std::string::npos && pos + 1 < subProp.label.size()) {
500 int32_t labelId = atoi(subProp.label.substr(pos + 1).c_str());
501 if (labelId > 0) {
502 subProp.labelId = static_cast<uint32_t>(labelId);
503 subProp.label = GetStringById(extInfo.bundleName, extInfo.moduleName, subProp.labelId, userId);
504 }
505 }
506 pos = subProp.icon.find(':');
507 if (pos != std::string::npos && pos + 1 < subProp.icon.size()) {
508 int32_t iconId = atoi(subProp.icon.substr(pos + 1).c_str());
509 if (iconId > 0) {
510 subProp.iconId = static_cast<uint32_t>(iconId);
511 }
512 }
513 CovertToLanguage(subProp.locale, subProp.language);
514 return ErrorCode::NO_ERROR;
515 }
516
ListInputMethodSubtype(const int32_t userId,const ExtensionAbilityInfo & extInfo,std::vector<SubProperty> & subProps)517 int32_t ImeInfoInquirer::ListInputMethodSubtype(const int32_t userId, const ExtensionAbilityInfo &extInfo,
518 std::vector<SubProperty> &subProps)
519 {
520 IMSA_HILOGD("newIme, userId: %{public}d.", userId);
521 std::vector<Subtype> subtypes;
522 auto ret = ParseSubtype(extInfo, subtypes);
523 if (ret != ErrorCode::NO_ERROR) {
524 IMSA_HILOGE("failed to parse subtype!");
525 return ret;
526 }
527
528 std::string resPath = extInfo.hapPath.empty() ? extInfo.resourcePath : extInfo.hapPath;
529 auto resMgr = GetResMgr(resPath);
530 IMSA_HILOGD("subtypes size: %{public}zu.", subtypes.size());
531 for (const auto &subtype : subtypes) {
532 // subtype which provides a particular input type should not appear in the subtype list
533 if (InputTypeManager::GetInstance().IsInputType({ extInfo.bundleName, subtype.id })) {
534 continue;
535 }
536 SubProperty subProp{ .label = subtype.label,
537 .name = extInfo.bundleName,
538 .id = subtype.id,
539 .mode = subtype.mode,
540 .locale = subtype.locale,
541 .icon = subtype.icon };
542 auto pos = subProp.label.find(':');
543 if (pos != std::string::npos && pos + 1 < subProp.label.size()) {
544 int32_t labelId = atoi(subProp.label.substr(pos + 1).c_str());
545 if (labelId > 0) {
546 subProp.labelId = static_cast<uint32_t>(labelId);
547 }
548 }
549 if (resMgr != nullptr) {
550 auto errValue = resMgr->GetStringById(subProp.labelId, subProp.label);
551 if (errValue != RState::SUCCESS) {
552 IMSA_HILOGE("GetStringById failed, bundleName:%{public}s, id:%{public}d.", extInfo.bundleName.c_str(),
553 subProp.labelId);
554 }
555 }
556 pos = subProp.icon.find(':');
557 if (pos != std::string::npos && pos + 1 < subProp.icon.size()) {
558 int32_t iconId = atoi(subProp.icon.substr(pos + 1).c_str());
559 if (iconId > 0) {
560 subProp.iconId = static_cast<uint32_t>(iconId);
561 }
562 }
563 CovertToLanguage(subProp.locale, subProp.language);
564 subProps.emplace_back(subProp);
565 }
566 return ErrorCode::NO_ERROR;
567 }
568
ParseSubtype(const OHOS::AppExecFwk::ExtensionAbilityInfo & extInfo,std::vector<Subtype> & subtypes)569 int32_t ImeInfoInquirer::ParseSubtype(const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo,
570 std::vector<Subtype> &subtypes)
571 {
572 if (extInfo.metadata.empty()) {
573 IMSA_HILOGE("metadata is empty!");
574 return ErrorCode::ERROR_BAD_PARAMETERS;
575 }
576 auto iter = std::find_if(extInfo.metadata.begin(), extInfo.metadata.end(),
577 [](const Metadata &metadata) { return metadata.name == SUBTYPE_PROFILE_METADATA_NAME; });
578 if (iter == extInfo.metadata.end()) {
579 IMSA_HILOGE("find metadata name: SUBTYPE_PROFILE_METADATA_NAME failed!");
580 return ErrorCode::ERROR_BAD_PARAMETERS;
581 }
582 OHOS::AppExecFwk::BundleMgrClientImpl clientImpl;
583 std::vector<std::string> profiles;
584 if (!clientImpl.GetResConfigFile(extInfo, iter->name, profiles)) {
585 IMSA_HILOGE("failed to GetProfileFromExtension!");
586 return ErrorCode::ERROR_PACKAGE_MANAGER;
587 }
588 SubtypeCfg subtypeCfg;
589 if (!ParseSubtypeProfile(profiles, subtypeCfg)) {
590 IMSA_HILOGE("failed to ParseSubTypeCfg!");
591 return ErrorCode::ERROR_BAD_PARAMETERS;
592 }
593 subtypes = subtypeCfg.subtypes;
594 IMSA_HILOGD("success.");
595 return ErrorCode::NO_ERROR;
596 }
597
CovertToLanguage(const std::string & locale,std::string & language)598 void ImeInfoInquirer::CovertToLanguage(const std::string &locale, std::string &language)
599 {
600 language = locale;
601 auto pos = locale.find('-');
602 if (pos != std::string::npos) {
603 language = locale.substr(0, pos);
604 }
605 // compatible with the locale configuration of original ime
606 pos = locale.find('_');
607 if (pos != std::string::npos) {
608 language = locale.substr(0, pos);
609 }
610 if (language == "en") {
611 language = "english";
612 }
613 if (language == "zh") {
614 language = "chinese";
615 }
616 }
617
GetStringById(const std::string & bundleName,const std::string & moduleName,uint32_t labelId,int32_t userId)618 std::string ImeInfoInquirer::GetStringById(const std::string &bundleName, const std::string &moduleName,
619 uint32_t labelId, int32_t userId)
620 {
621 auto bundleMgr = GetBundleMgr();
622 return bundleMgr == nullptr ? "" : bundleMgr->GetStringById(bundleName, moduleName, labelId, userId);
623 }
624
GetExtends(const std::vector<Metadata> & metaData)625 SubProperty ImeInfoInquirer::GetExtends(const std::vector<Metadata> &metaData)
626 {
627 SubProperty property;
628 for (const auto &data : metaData) {
629 if (data.name == "language") {
630 property.language = data.value;
631 continue;
632 }
633 if (data.name == "mode") {
634 property.mode = data.value;
635 continue;
636 }
637 if (data.name == "locale") {
638 property.locale = data.value;
639 continue;
640 }
641 if (data.name == "icon") {
642 property.icon = data.value;
643 }
644 }
645 return property;
646 }
647
GetImeProperty(int32_t userId,const std::string & bundleName,const std::string & extName)648 std::shared_ptr<Property> ImeInfoInquirer::GetImeProperty(
649 int32_t userId, const std::string &bundleName, const std::string &extName)
650 {
651 IMSA_HILOGD("start, bundleName: %{public}s", bundleName.c_str());
652 std::vector<AppExecFwk::ExtensionAbilityInfo> extInfos;
653 auto ret = ImeInfoInquirer::GetInstance().GetExtInfosByBundleName(userId, bundleName, extInfos);
654 if (ret != ErrorCode::NO_ERROR || extInfos.empty()) {
655 IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed!", userId, bundleName.c_str());
656 return nullptr;
657 }
658 Property prop = { .name = extInfos[0].bundleName,
659 .id = extName.empty() ? extInfos[0].name : extName,
660 .label = GetTargetString(extInfos[0], ImeTargetString::LABEL, userId),
661 .labelId = extInfos[0].applicationInfo.labelId,
662 .iconId = extInfos[0].applicationInfo.iconId };
663 return std::make_shared<Property>(prop);
664 }
665
GetCurrentInputMethod(int32_t userId)666 std::shared_ptr<Property> ImeInfoInquirer::GetCurrentInputMethod(int32_t userId)
667 {
668 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId);
669 IMSA_HILOGD("currentIme: %{public}s.", currentImeCfg->imeId.c_str());
670 auto infos = FullImeInfoManager::GetInstance().Get(userId);
671 auto it = std::find_if(infos.begin(), infos.end(),
672 [¤tImeCfg](const FullImeInfo &info) { return info.prop.name == currentImeCfg->bundleName; });
673 if (it != infos.end()) {
674 auto prop = std::make_shared<Property>((*it).prop);
675 prop->id = currentImeCfg->extName;
676 return prop;
677 }
678
679 IMSA_HILOGD("%{public}d get %{public}s prop form bms.", userId, currentImeCfg->bundleName.c_str());
680 return GetImeProperty(userId, currentImeCfg->bundleName, currentImeCfg->extName);
681 }
682
GetCurrentSubtype(int32_t userId)683 std::shared_ptr<SubProperty> ImeInfoInquirer::GetCurrentSubtype(int32_t userId)
684 {
685 auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId);
686 IMSA_HILOGD("currentIme: %{public}s.", currentIme->imeId.c_str());
687 auto infos = FullImeInfoManager::GetInstance().Get(userId);
688 auto it = std::find_if(infos.begin(), infos.end(),
689 [¤tIme](const FullImeInfo &info) { return info.prop.name == currentIme->bundleName; });
690 if (it != infos.end() && !it->subProps.empty()) {
691 auto iter = std::find_if(it->subProps.begin(), it->subProps.end(),
692 [¤tIme](const SubProperty &subProp) { return subProp.id == currentIme->subName; });
693 if (iter != it->subProps.end()) {
694 return std::make_shared<SubProperty>(*iter);
695 }
696 IMSA_HILOGW("subtype %{public}s not found.", currentIme->subName.c_str());
697 ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme->imeId, it->subProps[0].id, false });
698 return std::make_shared<SubProperty>(it->subProps[0]);
699 }
700
701 IMSA_HILOGD("%{public}d get [%{public}s, %{public}s] form bms.", userId, currentIme->bundleName.c_str(),
702 currentIme->subName.c_str());
703 std::vector<ExtensionAbilityInfo> extInfos;
704 auto ret = GetExtInfosByBundleName(userId, currentIme->bundleName, extInfos);
705 if (ret != ErrorCode::NO_ERROR) {
706 IMSA_HILOGE("failed to GetExtInfosByBundleName: %{public}s, ret: %{public}d", currentIme->bundleName.c_str(),
707 ret);
708 return nullptr;
709 }
710 SubProperty subProp;
711 ret = IsNewExtInfos(extInfos) ? GetSubProperty(userId, currentIme->subName, extInfos[0], subProp)
712 : GetSubProperty(userId, currentIme->subName, extInfos, subProp);
713 if (ret != ErrorCode::NO_ERROR) {
714 IMSA_HILOGE("get %{public}s property failed, ret: %{public}d!", currentIme->subName.c_str(), ret);
715 return nullptr;
716 }
717 return std::make_shared<SubProperty>(subProp);
718 }
719
IsImeInstalled(const int32_t userId,const std::string & bundleName,const std::string & extName)720 bool ImeInfoInquirer::IsImeInstalled(const int32_t userId, const std::string &bundleName, const std::string &extName)
721 {
722 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, extName: %{public}s.", userId, bundleName.c_str(),
723 extName.c_str());
724 std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> extInfos;
725 GetExtInfosByBundleName(userId, bundleName, extInfos);
726 auto iter = std::find_if(extInfos.begin(), extInfos.end(),
727 [&bundleName, &extName](const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo) {
728 return extInfo.bundleName == bundleName && extName == extInfo.name;
729 });
730 if (iter == extInfos.end()) {
731 IMSA_HILOGE("false");
732 return false;
733 }
734 IMSA_HILOGI("true");
735 return true;
736 }
737
GetImeToStart(int32_t userId)738 std::shared_ptr<ImeNativeCfg> ImeInfoInquirer::GetImeToStart(int32_t userId)
739 {
740 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId);
741 IMSA_HILOGD("userId: %{public}d, currentIme: %{public}s.", userId, currentImeCfg->imeId.c_str());
742 if (currentImeCfg->imeId.empty() || !IsImeInstalled(userId, currentImeCfg->bundleName, currentImeCfg->extName)) {
743 auto newIme = GetDefaultIme();
744 auto info = GetDefaultImeInfo(userId);
745 if (info == nullptr) {
746 IMSA_HILOGW("failed to GetDefaultImeInfo");
747 newIme.subName = "";
748 } else {
749 newIme.subName = info->subProp.id;
750 }
751 currentImeCfg->imeId.empty()
752 ? ImeCfgManager::GetInstance().AddImeCfg({ userId, newIme.imeId, newIme.subName, false })
753 : ImeCfgManager::GetInstance().ModifyImeCfg({ userId, newIme.imeId, newIme.subName, false});
754 return std::make_shared<ImeNativeCfg>(newIme);
755 }
756 return currentImeCfg;
757 }
758
GetInputMethodConfig(const int32_t userId,AppExecFwk::ElementName & inputMethodConfig)759 int32_t ImeInfoInquirer::GetInputMethodConfig(const int32_t userId, AppExecFwk::ElementName &inputMethodConfig)
760 {
761 IMSA_HILOGD("userId: %{public}d.", userId);
762 if (systemConfig_.systemInputMethodConfigAbility.empty()) {
763 IMSA_HILOGW("inputMethodConfig systemInputMethodConfigAbility is nullptr");
764 return ErrorCode::NO_ERROR;
765 }
766 std::string bundleName = systemConfig_.systemInputMethodConfigAbility;
767 std::string moduleName;
768 std::string abilityName;
769 auto pos = bundleName.find('/');
770 if (pos != std::string::npos) {
771 abilityName = (pos + 1 < bundleName.size()) ? bundleName.substr(pos + 1) : "";
772 bundleName = bundleName.substr(0, pos);
773 }
774 pos = abilityName.find('/');
775 if (pos != std::string::npos) {
776 moduleName = abilityName.substr(0, pos);
777 abilityName = (pos + 1 < abilityName.size()) ? abilityName.substr(pos + 1) : "";
778 }
779 inputMethodConfig.SetBundleName(std::move(bundleName));
780 inputMethodConfig.SetModuleName(std::move(moduleName));
781 inputMethodConfig.SetAbilityName(std::move(abilityName));
782 return ErrorCode::NO_ERROR;
783 }
784
GetDefaultInputMethod(const int32_t userId,std::shared_ptr<Property> & prop,bool isBrief)785 int32_t ImeInfoInquirer::GetDefaultInputMethod(const int32_t userId, std::shared_ptr<Property> &prop, bool isBrief)
786 {
787 IMSA_HILOGD("userId: %{public}d.", userId);
788 auto defaultIme = GetDefaultImeCfgProp();
789 if (defaultIme == nullptr) {
790 IMSA_HILOGE("abnormal default ime cfg!");
791 return ErrorCode::ERROR_NULL_POINTER;
792 }
793 auto infos = FullImeInfoManager::GetInstance().Get(userId);
794 auto it = std::find_if(infos.begin(), infos.end(),
795 [&defaultIme](const FullImeInfo &info) { return info.prop.name == defaultIme->name; });
796 if (it != infos.end()) {
797 prop = std::make_shared<Property>((*it).prop);
798 prop->id = defaultIme->id;
799 return ErrorCode::NO_ERROR;
800 }
801
802 IMSA_HILOGD("%{public}d get %{public}s form bms.", userId, defaultIme->name.c_str());
803 if (isBrief) {
804 IMSA_HILOGD("get brief info.");
805 if (prop == nullptr) {
806 prop = std::make_shared<Property>();
807 }
808 prop->name = defaultIme->name;
809 prop->id = defaultIme->id;
810 return ErrorCode::NO_ERROR;
811 }
812 prop = GetImeProperty(userId, defaultIme->name, defaultIme->id);
813 return ErrorCode::NO_ERROR;
814 }
815
GetDefaultImeInfo(int32_t userId)816 std::shared_ptr<ImeInfo> ImeInfoInquirer::GetDefaultImeInfo(int32_t userId)
817 {
818 auto defaultIme = GetDefaultImeCfgProp();
819 if (defaultIme == nullptr) {
820 IMSA_HILOGE("defaultIme is nullptr!");
821 return nullptr;
822 }
823 auto info = GetImeInfo(userId, defaultIme->name, "");
824 if (info == nullptr) {
825 IMSA_HILOGE("userId: %{public}d, bundleName: %{public}s getImeInfoFromBundleMgr failed!", userId,
826 defaultIme->name.c_str());
827 return nullptr;
828 }
829 if (!info->isNewIme) {
830 info->prop.id = defaultIme->id;
831 auto it = std::find_if(info->subProps.begin(), info->subProps.end(),
832 [defaultIme](const SubProperty &subProp) { return subProp.id == defaultIme->id; });
833 if (it != info->subProps.end()) {
834 info->subProp = *it;
835 }
836 }
837 return info;
838 }
839
GetDefaultIme()840 ImeNativeCfg ImeInfoInquirer::GetDefaultIme()
841 {
842 ImeNativeCfg imeCfg;
843 if (!systemConfig_.defaultInputMethod.empty()) {
844 IMSA_HILOGI("defaultInputMethod: %{public}s.", systemConfig_.defaultInputMethod.c_str());
845 imeCfg.imeId = systemConfig_.defaultInputMethod;
846 } else {
847 char value[CONFIG_LEN] = { 0 };
848 auto code = GetParameter(DEFAULT_IME_KEY, "", value, CONFIG_LEN);
849 imeCfg.imeId = code > 0 ? value : "";
850 }
851 auto pos = imeCfg.imeId.find('/');
852 if (pos == std::string::npos || pos + 1 >= imeCfg.imeId.size()) {
853 IMSA_HILOGE("defaultIme: %{public}s is abnormal!", imeCfg.imeId.c_str());
854 return {};
855 }
856 imeCfg.bundleName = imeCfg.imeId.substr(0, pos);
857 imeCfg.extName = imeCfg.imeId.substr(pos + 1);
858 return imeCfg;
859 }
860
GetBundleMgr()861 sptr<OHOS::AppExecFwk::IBundleMgr> ImeInfoInquirer::GetBundleMgr()
862 {
863 sptr<ISystemAbilityManager> systemAbilityManager =
864 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
865 if (systemAbilityManager == nullptr) {
866 IMSA_HILOGE("systemAbilityManager is nullptr!");
867 return nullptr;
868 }
869 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
870 if (remoteObject == nullptr) {
871 IMSA_HILOGE("remoteObject is nullptr!");
872 return nullptr;
873 }
874 return iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
875 }
876
FindTargetSubtypeByCondition(const std::vector<SubProperty> & subProps,const Condition & condition)877 std::shared_ptr<SubProperty> ImeInfoInquirer::FindTargetSubtypeByCondition(const std::vector<SubProperty> &subProps,
878 const Condition &condition)
879 {
880 auto it = subProps.end();
881 switch (condition) {
882 case Condition::UPPER: {
883 it = std::find_if(subProps.begin(), subProps.end(),
884 [](const SubProperty &subProp) { return subProp.mode == "upper"; });
885 break;
886 }
887 case Condition::LOWER: {
888 it = std::find_if(subProps.begin(), subProps.end(),
889 [](const SubProperty &subProp) { return subProp.mode == "lower"; });
890 break;
891 }
892 case Condition::ENGLISH: {
893 it = std::find_if(subProps.begin(), subProps.end(),
894 [](const SubProperty &subProp) { return subProp.language == "english" && subProp.mode == "lower"; });
895 break;
896 }
897 case Condition::CHINESE: {
898 it = std::find_if(subProps.begin(), subProps.end(),
899 [](const SubProperty &subProp) { return subProp.language == "chinese"; });
900 break;
901 }
902 default: {
903 break;
904 }
905 }
906 if (it == subProps.end()) {
907 return nullptr;
908 }
909 return std::make_shared<SubProperty>(*it);
910 }
911
ParseSubtypeProfile(const std::vector<std::string> & profiles,SubtypeCfg & subtypeCfg)912 bool ImeInfoInquirer::ParseSubtypeProfile(const std::vector<std::string> &profiles, SubtypeCfg &subtypeCfg)
913 {
914 if (profiles.empty() || profiles.size() != SUBTYPE_PROFILE_NUM) {
915 IMSA_HILOGE("profiles size: %{public}zu!", profiles.size());
916 return false;
917 }
918 return subtypeCfg.Unmarshall(profiles[0]);
919 }
920
GetDefaultImeCfgProp()921 std::shared_ptr<Property> ImeInfoInquirer::GetDefaultImeCfgProp()
922 {
923 auto ime = GetDefaultIme();
924 if (ime.bundleName.empty() || ime.extName.empty()) {
925 IMSA_HILOGE("defaultIme is abnormal!");
926 return nullptr;
927 }
928 auto defaultIme = std::make_shared<Property>();
929 defaultIme->name = ime.bundleName;
930 defaultIme->id = ime.extName;
931 return defaultIme;
932 }
933
GetDefaultImeCfg()934 std::shared_ptr<ImeNativeCfg> ImeInfoInquirer::GetDefaultImeCfg()
935 {
936 auto ime = GetDefaultIme();
937 if (ime.bundleName.empty() || ime.extName.empty()) {
938 IMSA_HILOGE("defaultIme is abnormal!");
939 return nullptr;
940 }
941 return std::make_shared<ImeNativeCfg>(ime);
942 }
943
GetResMgr(const std::string & resourcePath)944 std::shared_ptr<ResourceManager> ImeInfoInquirer::GetResMgr(const std::string &resourcePath)
945 {
946 if (resourcePath.empty()) {
947 IMSA_HILOGE("resourcePath is empty!");
948 return nullptr;
949 }
950 std::shared_ptr<ResourceManager> resMgr(CreateResourceManager());
951 if (resMgr == nullptr) {
952 IMSA_HILOGE("resMgr is nullptr!");
953 return nullptr;
954 }
955 resMgr->AddResource(resourcePath.c_str());
956 std::unique_ptr<ResConfig> resConfig(CreateResConfig());
957 if (resConfig == nullptr) {
958 IMSA_HILOGE("resConfig is nullptr!");
959 return nullptr;
960 }
961 std::map<std::string, std::string> configs;
962 OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale(), configs);
963 resConfig->SetLocaleInfo(locale.GetLanguage().c_str(), locale.GetScript().c_str(), locale.GetRegion().c_str());
964 resMgr->UpdateResConfig(*resConfig);
965 return resMgr;
966 }
967
QueryFullImeInfo(std::vector<std::pair<int32_t,std::vector<FullImeInfo>>> & fullImeInfos)968 int32_t ImeInfoInquirer::QueryFullImeInfo(std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> &fullImeInfos)
969 {
970 auto userIds = OsAccountAdapter::QueryActiveOsAccountIds();
971 if (userIds.empty()) {
972 return ErrorCode::ERROR_OS_ACCOUNT;
973 }
974 for (auto &userId : userIds) {
975 std::vector<FullImeInfo> infos;
976 auto errNo = QueryFullImeInfo(userId, infos);
977 if (errNo != ErrorCode::NO_ERROR) {
978 continue;
979 }
980 fullImeInfos.emplace_back(userId, infos);
981 }
982 if (fullImeInfos.empty()) {
983 return ErrorCode::ERROR_PACKAGE_MANAGER;
984 }
985 return ErrorCode::NO_ERROR;
986 }
987
QueryFullImeInfo(int32_t userId,std::vector<FullImeInfo> & imeInfo)988 int32_t ImeInfoInquirer::QueryFullImeInfo(int32_t userId, std::vector<FullImeInfo> &imeInfo)
989 {
990 std::vector<ExtensionAbilityInfo> extInfos;
991 auto ret = ImeInfoInquirer::GetInstance().QueryImeExtInfos(userId, extInfos);
992 if (!ret || extInfos.empty()) {
993 IMSA_HILOGE("%{public}d QueryImeExtInfos failed!", userId);
994 return ErrorCode::ERROR_PACKAGE_MANAGER;
995 }
996 std::map<std::string, std::vector<ExtensionAbilityInfo>> tempExtInfos;
997 for (const auto &extInfo : extInfos) {
998 if (IsTempInputMethod(extInfo)) {
999 continue;
1000 }
1001 auto it = tempExtInfos.find(extInfo.bundleName);
1002 if (it != tempExtInfos.end()) {
1003 it->second.push_back(extInfo);
1004 continue;
1005 }
1006 tempExtInfos.insert({ extInfo.bundleName, { extInfo } });
1007 }
1008
1009 for (const auto &extInfo : tempExtInfos) {
1010 FullImeInfo info;
1011 auto errNo = GetFullImeInfo(userId, extInfo.second, info);
1012 if (errNo != ErrorCode::NO_ERROR) {
1013 return errNo;
1014 }
1015 imeInfo.push_back(info);
1016 }
1017 return ErrorCode::NO_ERROR;
1018 }
1019
GetFullImeInfo(int32_t userId,const std::string & bundleName,FullImeInfo & imeInfo)1020 int32_t ImeInfoInquirer::GetFullImeInfo(int32_t userId, const std::string &bundleName, FullImeInfo &imeInfo)
1021 {
1022 std::vector<ExtensionAbilityInfo> extInfos;
1023 auto ret = ImeInfoInquirer::GetInstance().QueryImeExtInfos(userId, extInfos);
1024 if (!ret || extInfos.empty()) {
1025 return ErrorCode::ERROR_PACKAGE_MANAGER;
1026 }
1027 std::vector<ExtensionAbilityInfo> tempExtInfos;
1028 for (const auto &extInfo : extInfos) {
1029 if (IsTempInputMethod(extInfo)) {
1030 continue;
1031 }
1032 if (extInfo.bundleName == bundleName) {
1033 tempExtInfos.push_back(extInfo);
1034 }
1035 }
1036 return GetFullImeInfo(userId, tempExtInfos, imeInfo);
1037 }
1038
GetFullImeInfo(int32_t userId,const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> & extInfos,FullImeInfo & imeInfo)1039 int32_t ImeInfoInquirer::GetFullImeInfo(
1040 int32_t userId, const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> &extInfos, FullImeInfo &imeInfo)
1041 {
1042 if (extInfos.empty()) {
1043 return ErrorCode::ERROR_PACKAGE_MANAGER;
1044 }
1045 imeInfo.isNewIme = IsNewExtInfos(extInfos);
1046 auto ret = imeInfo.isNewIme ? ListInputMethodSubtype(userId, extInfos[0], imeInfo.subProps)
1047 : ListInputMethodSubtype(userId, extInfos, imeInfo.subProps);
1048 if (ret != ErrorCode::NO_ERROR) {
1049 IMSA_HILOGE("[%{public}d,%{public}s] list Subtype failed!", userId, extInfos[0].bundleName.c_str());
1050 return ret;
1051 }
1052 imeInfo.tokenId = extInfos[0].applicationInfo.accessTokenId;
1053 imeInfo.prop.name = extInfos[0].bundleName;
1054 imeInfo.prop.id = extInfos[0].name;
1055 imeInfo.prop.label = GetTargetString(extInfos[0], ImeTargetString::LABEL, userId);
1056 imeInfo.prop.labelId = extInfos[0].applicationInfo.labelId;
1057 imeInfo.prop.iconId = extInfos[0].applicationInfo.iconId;
1058 BundleInfo bundleInfo;
1059 if (GetBundleInfoByBundleName(userId, imeInfo.prop.name, bundleInfo)) {
1060 imeInfo.appId = bundleInfo.signatureInfo.appIdentifier;
1061 imeInfo.versionCode = bundleInfo.versionCode;
1062 }
1063 return ErrorCode::NO_ERROR;
1064 }
1065
IsInputMethod(int32_t userId,const std::string & bundleName)1066 bool ImeInfoInquirer::IsInputMethod(int32_t userId, const std::string &bundleName)
1067 {
1068 auto bmg = GetBundleMgr();
1069 if (bmg == nullptr) {
1070 return false;
1071 }
1072 BundleInfo bundleInfo;
1073 auto ret = bmg->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
1074 if (!ret) {
1075 return false;
1076 }
1077 for (const auto &extInfo : bundleInfo.extensionInfos) {
1078 if (extInfo.type == ExtensionAbilityType::INPUTMETHOD) {
1079 return true;
1080 }
1081 }
1082 return false;
1083 }
1084
IsTempInputMethod(const ExtensionAbilityInfo & extInfo)1085 bool ImeInfoInquirer::IsTempInputMethod(const ExtensionAbilityInfo &extInfo)
1086 {
1087 auto iter = std::find_if(extInfo.metadata.begin(), extInfo.metadata.end(),
1088 [](const Metadata &metadata) {
1089 return metadata.name == TEMPORARY_INPUT_METHOD_METADATA_NAME;
1090 });
1091 return iter != extInfo.metadata.end();
1092 }
1093
GetRunningIme(int32_t userId)1094 std::vector<std::string> ImeInfoInquirer::GetRunningIme(int32_t userId)
1095 {
1096 std::vector<std::string> bundleNames;
1097 std::vector<RunningProcessInfo> infos;
1098 AppMgrClient client;
1099 auto ret = client.GetProcessRunningInfosByUserId(infos, userId);
1100 if (ret != ErrorCode::NO_ERROR) {
1101 IMSA_HILOGE("GetAllRunningProcesses failed, ret: %{public}d!", ret);
1102 return bundleNames;
1103 }
1104 for (const auto &info : infos) {
1105 if (info.extensionType_ == ExtensionAbilityType::INPUTMETHOD && !info.bundleNames.empty()) {
1106 bundleNames.push_back(info.bundleNames[0]);
1107 }
1108 }
1109 return bundleNames;
1110 }
1111
IsDefaultImeSet(int32_t userId)1112 bool ImeInfoInquirer::IsDefaultImeSet(int32_t userId)
1113 {
1114 return ImeCfgManager::GetInstance().IsDefaultImeSet(userId);
1115 }
1116
IsRunningIme(int32_t userId,const std::string & bundleName)1117 bool ImeInfoInquirer::IsRunningIme(int32_t userId, const std::string &bundleName)
1118 {
1119 auto bundleNames = GetRunningIme(userId);
1120 auto it = std::find_if(bundleNames.begin(), bundleNames.end(),
1121 [&bundleName](const std::string &bundleNameTemp) { return bundleName == bundleNameTemp; });
1122 return it != bundleNames.end();
1123 }
1124
GetImeAppId(int32_t userId,const std::string & bundleName,std::string & appId)1125 bool ImeInfoInquirer::GetImeAppId(int32_t userId, const std::string &bundleName, std::string &appId)
1126 {
1127 FullImeInfo imeInfo;
1128 if (FullImeInfoManager::GetInstance().Get(bundleName, userId, imeInfo) && !imeInfo.appId.empty()) {
1129 appId = imeInfo.appId;
1130 return true;
1131 }
1132 BundleInfo bundleInfo;
1133 if (!GetBundleInfoByBundleName(userId, bundleName, bundleInfo)) {
1134 return false;
1135 }
1136 appId = bundleInfo.signatureInfo.appIdentifier;
1137 return !appId.empty();
1138 }
1139
GetImeVersionCode(int32_t userId,const std::string & bundleName,uint32_t & versionCode)1140 bool ImeInfoInquirer::GetImeVersionCode(int32_t userId, const std::string &bundleName, uint32_t &versionCode)
1141 {
1142 FullImeInfo imeInfo;
1143 if (FullImeInfoManager::GetInstance().Get(bundleName, userId, imeInfo)) {
1144 versionCode = imeInfo.versionCode;
1145 return true;
1146 }
1147 BundleInfo bundleInfo;
1148 if (!GetBundleInfoByBundleName(userId, bundleName, bundleInfo)) {
1149 return false;
1150 }
1151 versionCode = bundleInfo.versionCode;
1152 return true;
1153 }
1154
GetBundleInfoByBundleName(int32_t userId,const std::string & bundleName,AppExecFwk::BundleInfo & bundleInfo)1155 bool ImeInfoInquirer::GetBundleInfoByBundleName(
1156 int32_t userId, const std::string &bundleName, AppExecFwk::BundleInfo &bundleInfo)
1157 {
1158 auto bundleMgr = GetBundleMgr();
1159 if (bundleMgr == nullptr) {
1160 IMSA_HILOGE("failed to get bundleMgr!");
1161 return false;
1162 }
1163 auto ret = bundleMgr->GetBundleInfo(
1164 bundleName, static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), bundleInfo, userId);
1165 if (!ret) {
1166 IMSA_HILOGE("failed to get bundle info");
1167 return false;
1168 }
1169 return true;
1170 }
1171
GetTargetString(const AppExecFwk::ExtensionAbilityInfo & extension,ImeTargetString target,int32_t userId)1172 std::string ImeInfoInquirer::GetTargetString(
1173 const AppExecFwk::ExtensionAbilityInfo &extension, ImeTargetString target, int32_t userId)
1174 {
1175 if (target == ImeTargetString::LABEL) {
1176 if (extension.labelId != DEFAULT_BMS_VALUE) {
1177 return GetStringById(extension.bundleName, extension.moduleName, extension.labelId, userId);
1178 }
1179 IMSA_HILOGD("Extension label is empty, get application label");
1180 return GetStringById(extension.bundleName, extension.applicationInfo.labelResource.moduleName,
1181 extension.applicationInfo.labelResource.id, userId);
1182 }
1183 if (target == ImeTargetString::DESCRIPTION) {
1184 if (extension.descriptionId != DEFAULT_BMS_VALUE) {
1185 return GetStringById(extension.bundleName, extension.moduleName, extension.descriptionId, userId);
1186 }
1187 IMSA_HILOGD("extension description is empty, get application description");
1188 return GetStringById(extension.bundleName, extension.applicationInfo.descriptionResource.moduleName,
1189 extension.applicationInfo.descriptionResource.id, userId);
1190 }
1191 IMSA_HILOGD("No match target string");
1192 return "";
1193 }
1194 } // namespace MiscServices
1195 } // namespace OHOS