• 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 "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         [&currentImeBundle](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         [&currentImeCfg](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         [&currentIme](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             [&currentIme](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