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