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 [¤tImeBundle](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 [¤tIme](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