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