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 41namespace OHOS { 42namespace MiscServices { 43namespace { 44using namespace OHOS::AppExecFwk; 45using namespace Global::Resource; 46using namespace OHOS::AAFwk; 47constexpr const char *SUBTYPE_PROFILE_METADATA_NAME = "ohos.extension.input_method"; 48constexpr const char *TEMPORARY_INPUT_METHOD_METADATA_NAME = "ohos.extension.temporary_input_method"; 49constexpr uint32_t SUBTYPE_PROFILE_NUM = 1; 50constexpr const char *DEFAULT_IME_KEY = "persist.sys.default_ime"; 51constexpr int32_t CONFIG_LEN = 128; 52constexpr uint32_t DEFAULT_BMS_VALUE = 0; 53} // namespace 54ImeInfoInquirer &ImeInfoInquirer::GetInstance() 55{ 56 static ImeInfoInquirer instance; 57 return instance; 58} 59 60void ImeInfoInquirer::InitSystemConfig() 61{ 62 auto ret = SysCfgParser::ParseSystemConfig(systemConfig_); 63 if (!ret) { 64 IMSA_HILOGE("parse systemConfig failed!"); 65 return; 66 } 67} 68 69bool ImeInfoInquirer::IsEnableInputMethod() 70{ 71 return systemConfig_.enableInputMethodFeature; 72} 73 74bool ImeInfoInquirer::IsEnableSecurityMode() 75{ 76 return systemConfig_.enableFullExperienceFeature; 77} 78 79bool 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 94int32_t ImeInfoInquirer::GetExtInfosByBundleName(const int32_t userId, const std::string &bundleName, 95 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 115std::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 124std::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 157std::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 203std::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 229std::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 254int32_t ImeInfoInquirer::ListInputMethod(int32_t userId, InputMethodStatus status, std::vector<Property> &props, 255 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 270int32_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 305int32_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 332int32_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 362int32_t ImeInfoInquirer::GetSwitchInfoBySwitchCount(SwitchInfo &switchInfo, int32_t userId, bool enableOn, 363 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 390int32_t ImeInfoInquirer::ListInputMethodSubtype(int32_t userId, const std::string &bundleName, 391 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 413int32_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 420bool 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 431int32_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 459int32_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 481int32_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 526int32_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 578int32_t ImeInfoInquirer::ParseSubtype(const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo, 579 std::vector<Subtype> &subtypes) 580{ 581 if (extInfo.metadata.empty()) { 582 IMSA_HILOGE("metadata is empty!"); 583 return ErrorCode::ERROR_BAD_PARAMETERS; 584 } 585 auto iter = std::find_if(extInfo.metadata.begin(), extInfo.metadata.end(), 586 [](const Metadata &metadata) { return metadata.name == SUBTYPE_PROFILE_METADATA_NAME; }); 587 if (iter == extInfo.metadata.end()) { 588 IMSA_HILOGE("find metadata name: SUBTYPE_PROFILE_METADATA_NAME failed!"); 589 return ErrorCode::ERROR_BAD_PARAMETERS; 590 } 591 OHOS::AppExecFwk::BundleMgrClientImpl clientImpl; 592 std::vector<std::string> profiles; 593 if (!clientImpl.GetResConfigFile(extInfo, iter->name, profiles)) { 594 IMSA_HILOGE("failed to GetProfileFromExtension!"); 595 return ErrorCode::ERROR_PACKAGE_MANAGER; 596 } 597 SubtypeCfg subtypeCfg; 598 if (!ParseSubtypeProfile(profiles, subtypeCfg)) { 599 IMSA_HILOGE("failed to ParseSubTypeCfg!"); 600 return ErrorCode::ERROR_BAD_PARAMETERS; 601 } 602 subtypes = subtypeCfg.subtypes; 603 IMSA_HILOGD("success."); 604 return ErrorCode::NO_ERROR; 605} 606 607void ImeInfoInquirer::CovertToLanguage(const std::string &locale, std::string &language) 608{ 609 language = locale; 610 auto pos = locale.find('-'); 611 if (pos != std::string::npos) { 612 language = locale.substr(0, pos); 613 } 614 // compatible with the locale configuration of original ime 615 pos = locale.find('_'); 616 if (pos != std::string::npos) { 617 language = locale.substr(0, pos); 618 } 619 if (language == "en") { 620 language = "english"; 621 } 622 if (language == "zh") { 623 language = "chinese"; 624 } 625} 626 627std::string ImeInfoInquirer::GetStringById(const std::string &bundleName, const std::string &moduleName, 628 uint32_t labelId, int32_t userId) 629{ 630 auto bundleMgr = GetBundleMgr(); 631 return bundleMgr == nullptr ? "" : bundleMgr->GetStringById(bundleName, moduleName, labelId, userId); 632} 633 634SubProperty ImeInfoInquirer::GetExtends(const std::vector<Metadata> &metaData) 635{ 636 SubProperty property; 637 for (const auto &data : metaData) { 638 if (data.name == "language") { 639 property.language = data.value; 640 continue; 641 } 642 if (data.name == "mode") { 643 property.mode = data.value; 644 continue; 645 } 646 if (data.name == "locale") { 647 property.locale = data.value; 648 continue; 649 } 650 if (data.name == "icon") { 651 property.icon = data.value; 652 } 653 } 654 return property; 655} 656 657std::shared_ptr<Property> ImeInfoInquirer::GetImeProperty( 658 int32_t userId, const std::string &bundleName, const std::string &extName) 659{ 660 IMSA_HILOGD("start, bundleName: %{public}s", bundleName.c_str()); 661 std::vector<AppExecFwk::ExtensionAbilityInfo> extInfos; 662 auto ret = ImeInfoInquirer::GetInstance().GetExtInfosByBundleName(userId, bundleName, extInfos); 663 if (ret != ErrorCode::NO_ERROR || extInfos.empty()) { 664 IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed!", userId, bundleName.c_str()); 665 return nullptr; 666 } 667 Property prop = { .name = extInfos[0].bundleName, 668 .id = extName.empty() ? extInfos[0].name : extName, 669 .label = GetTargetString(extInfos[0], ImeTargetString::LABEL, userId), 670 .labelId = extInfos[0].applicationInfo.labelId, 671 .iconId = extInfos[0].applicationInfo.iconId }; 672 return std::make_shared<Property>(prop); 673} 674 675std::shared_ptr<Property> ImeInfoInquirer::GetCurrentInputMethod(int32_t userId) 676{ 677 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 678 IMSA_HILOGD("currentIme: %{public}s.", currentImeCfg->imeId.c_str()); 679 auto infos = FullImeInfoManager::GetInstance().Get(userId); 680 auto it = std::find_if(infos.begin(), infos.end(), 681 [¤tImeCfg](const FullImeInfo &info) { return info.prop.name == currentImeCfg->bundleName; }); 682 if (it != infos.end()) { 683 auto prop = std::make_shared<Property>((*it).prop); 684 prop->id = currentImeCfg->extName; 685 return prop; 686 } 687 688 IMSA_HILOGD("%{public}d get %{public}s prop form bms.", userId, currentImeCfg->bundleName.c_str()); 689 return GetImeProperty(userId, currentImeCfg->bundleName, currentImeCfg->extName); 690} 691 692std::shared_ptr<SubProperty> ImeInfoInquirer::GetCurrentSubtype(int32_t userId) 693{ 694 auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 695 IMSA_HILOGD("currentIme: %{public}s.", currentIme->imeId.c_str()); 696 auto infos = FullImeInfoManager::GetInstance().Get(userId); 697 auto it = std::find_if(infos.begin(), infos.end(), 698 [¤tIme](const FullImeInfo &info) { return info.prop.name == currentIme->bundleName; }); 699 if (it != infos.end() && !it->subProps.empty()) { 700 auto iter = std::find_if(it->subProps.begin(), it->subProps.end(), 701 [¤tIme](const SubProperty &subProp) { return subProp.id == currentIme->subName; }); 702 if (iter != it->subProps.end()) { 703 return std::make_shared<SubProperty>(*iter); 704 } 705 IMSA_HILOGW("subtype %{public}s not found.", currentIme->subName.c_str()); 706 ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme->imeId, it->subProps[0].id, false }); 707 return std::make_shared<SubProperty>(it->subProps[0]); 708 } 709 710 IMSA_HILOGD("%{public}d get [%{public}s, %{public}s] form bms.", userId, currentIme->bundleName.c_str(), 711 currentIme->subName.c_str()); 712 std::vector<ExtensionAbilityInfo> extInfos; 713 auto ret = GetExtInfosByBundleName(userId, currentIme->bundleName, extInfos); 714 if (ret != ErrorCode::NO_ERROR) { 715 IMSA_HILOGE("failed to GetExtInfosByBundleName: %{public}s, ret: %{public}d", currentIme->bundleName.c_str(), 716 ret); 717 return nullptr; 718 } 719 SubProperty subProp; 720 ret = IsNewExtInfos(extInfos) ? GetSubProperty(userId, currentIme->subName, extInfos[0], subProp) 721 : GetSubProperty(userId, currentIme->subName, extInfos, subProp); 722 if (ret != ErrorCode::NO_ERROR) { 723 IMSA_HILOGE("get %{public}s property failed, ret: %{public}d!", currentIme->subName.c_str(), ret); 724 return nullptr; 725 } 726 return std::make_shared<SubProperty>(subProp); 727} 728 729bool ImeInfoInquirer::IsImeInstalled(const int32_t userId, const std::string &bundleName, const std::string &extName) 730{ 731 IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, extName: %{public}s.", userId, bundleName.c_str(), 732 extName.c_str()); 733 std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> extInfos; 734 GetExtInfosByBundleName(userId, bundleName, extInfos); 735 auto iter = std::find_if(extInfos.begin(), extInfos.end(), 736 [&bundleName, &extName](const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo) { 737 return extInfo.bundleName == bundleName && extName == extInfo.name; 738 }); 739 if (iter == extInfos.end()) { 740 IMSA_HILOGE("false"); 741 return false; 742 } 743 IMSA_HILOGI("true"); 744 return true; 745} 746 747std::shared_ptr<ImeNativeCfg> ImeInfoInquirer::GetImeToStart(int32_t userId) 748{ 749 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 750 IMSA_HILOGD("userId: %{public}d, currentIme: %{public}s.", userId, currentImeCfg->imeId.c_str()); 751 if (currentImeCfg->imeId.empty() || !IsImeInstalled(userId, currentImeCfg->bundleName, currentImeCfg->extName)) { 752 auto newIme = GetDefaultIme(); 753 auto info = GetDefaultImeInfo(userId); 754 if (info == nullptr) { 755 IMSA_HILOGW("failed to GetDefaultImeInfo"); 756 newIme.subName = ""; 757 } else { 758 newIme.subName = info->subProp.id; 759 } 760 currentImeCfg->imeId.empty() 761 ? ImeCfgManager::GetInstance().AddImeCfg({ userId, newIme.imeId, newIme.subName, false }) 762 : ImeCfgManager::GetInstance().ModifyImeCfg({ userId, newIme.imeId, newIme.subName, false}); 763 return std::make_shared<ImeNativeCfg>(newIme); 764 } 765 return currentImeCfg; 766} 767 768int32_t ImeInfoInquirer::GetInputMethodConfig(const int32_t userId, AppExecFwk::ElementName &inputMethodConfig) 769{ 770 IMSA_HILOGD("userId: %{public}d.", userId); 771 if (systemConfig_.systemInputMethodConfigAbility.empty()) { 772 IMSA_HILOGW("inputMethodConfig systemInputMethodConfigAbility is nullptr"); 773 return ErrorCode::NO_ERROR; 774 } 775 std::string bundleName = systemConfig_.systemInputMethodConfigAbility; 776 std::string moduleName; 777 std::string abilityName; 778 auto pos = bundleName.find('/'); 779 if (pos != std::string::npos) { 780 abilityName = (pos + 1 < bundleName.size()) ? bundleName.substr(pos + 1) : ""; 781 bundleName = bundleName.substr(0, pos); 782 } 783 pos = abilityName.find('/'); 784 if (pos != std::string::npos) { 785 moduleName = abilityName.substr(0, pos); 786 abilityName = (pos + 1 < abilityName.size()) ? abilityName.substr(pos + 1) : ""; 787 } 788 inputMethodConfig.SetBundleName(std::move(bundleName)); 789 inputMethodConfig.SetModuleName(std::move(moduleName)); 790 inputMethodConfig.SetAbilityName(std::move(abilityName)); 791 return ErrorCode::NO_ERROR; 792} 793 794int32_t ImeInfoInquirer::GetDefaultInputMethod(const int32_t userId, std::shared_ptr<Property> &prop, bool isBrief) 795{ 796 IMSA_HILOGD("userId: %{public}d.", userId); 797 auto defaultIme = GetDefaultImeCfgProp(); 798 if (defaultIme == nullptr) { 799 IMSA_HILOGE("abnormal default ime cfg!"); 800 return ErrorCode::ERROR_NULL_POINTER; 801 } 802 auto infos = FullImeInfoManager::GetInstance().Get(userId); 803 auto it = std::find_if(infos.begin(), infos.end(), 804 [&defaultIme](const FullImeInfo &info) { return info.prop.name == defaultIme->name; }); 805 if (it != infos.end()) { 806 prop = std::make_shared<Property>((*it).prop); 807 prop->id = defaultIme->id; 808 return ErrorCode::NO_ERROR; 809 } 810 811 IMSA_HILOGD("%{public}d get %{public}s form bms.", userId, defaultIme->name.c_str()); 812 if (isBrief) { 813 IMSA_HILOGD("get brief info."); 814 if (prop == nullptr) { 815 prop = std::make_shared<Property>(); 816 } 817 prop->name = defaultIme->name; 818 prop->id = defaultIme->id; 819 return ErrorCode::NO_ERROR; 820 } 821 prop = GetImeProperty(userId, defaultIme->name, defaultIme->id); 822 return ErrorCode::NO_ERROR; 823} 824 825std::shared_ptr<ImeInfo> ImeInfoInquirer::GetDefaultImeInfo(int32_t userId) 826{ 827 auto defaultIme = GetDefaultImeCfgProp(); 828 if (defaultIme == nullptr) { 829 IMSA_HILOGE("defaultIme is nullptr!"); 830 return nullptr; 831 } 832 auto info = GetImeInfo(userId, defaultIme->name, ""); 833 if (info == nullptr) { 834 IMSA_HILOGE("userId: %{public}d, bundleName: %{public}s getImeInfoFromBundleMgr failed!", userId, 835 defaultIme->name.c_str()); 836 return nullptr; 837 } 838 if (!info->isNewIme) { 839 info->prop.id = defaultIme->id; 840 auto it = std::find_if(info->subProps.begin(), info->subProps.end(), 841 [defaultIme](const SubProperty &subProp) { return subProp.id == defaultIme->id; }); 842 if (it != info->subProps.end()) { 843 info->subProp = *it; 844 } 845 } 846 return info; 847} 848 849ImeNativeCfg ImeInfoInquirer::GetDefaultIme() 850{ 851 ImeNativeCfg imeCfg; 852 if (!systemConfig_.defaultInputMethod.empty()) { 853 IMSA_HILOGI("defaultInputMethod: %{public}s.", systemConfig_.defaultInputMethod.c_str()); 854 imeCfg.imeId = systemConfig_.defaultInputMethod; 855 } else { 856 char value[CONFIG_LEN] = { 0 }; 857 auto code = GetParameter(DEFAULT_IME_KEY, "", value, CONFIG_LEN); 858 imeCfg.imeId = code > 0 ? value : ""; 859 } 860 auto pos = imeCfg.imeId.find('/'); 861 if (pos == std::string::npos || pos + 1 >= imeCfg.imeId.size()) { 862 IMSA_HILOGE("defaultIme: %{public}s is abnormal!", imeCfg.imeId.c_str()); 863 return {}; 864 } 865 imeCfg.bundleName = imeCfg.imeId.substr(0, pos); 866 imeCfg.extName = imeCfg.imeId.substr(pos + 1); 867 return imeCfg; 868} 869 870sptr<OHOS::AppExecFwk::IBundleMgr> ImeInfoInquirer::GetBundleMgr() 871{ 872 sptr<ISystemAbilityManager> systemAbilityManager = 873 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 874 if (systemAbilityManager == nullptr) { 875 IMSA_HILOGE("systemAbilityManager is nullptr!"); 876 return nullptr; 877 } 878 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 879 if (remoteObject == nullptr) { 880 IMSA_HILOGE("remoteObject is nullptr!"); 881 return nullptr; 882 } 883 return iface_cast<AppExecFwk::IBundleMgr>(remoteObject); 884} 885 886std::shared_ptr<SubProperty> ImeInfoInquirer::FindTargetSubtypeByCondition(const std::vector<SubProperty> &subProps, 887 const Condition &condition) 888{ 889 auto it = subProps.end(); 890 switch (condition) { 891 case Condition::UPPER: { 892 it = std::find_if(subProps.begin(), subProps.end(), 893 [](const SubProperty &subProp) { return subProp.mode == "upper"; }); 894 break; 895 } 896 case Condition::LOWER: { 897 it = std::find_if(subProps.begin(), subProps.end(), 898 [](const SubProperty &subProp) { return subProp.mode == "lower"; }); 899 break; 900 } 901 case Condition::ENGLISH: { 902 it = std::find_if(subProps.begin(), subProps.end(), 903 [](const SubProperty &subProp) { return subProp.language == "english" && subProp.mode == "lower"; }); 904 break; 905 } 906 case Condition::CHINESE: { 907 it = std::find_if(subProps.begin(), subProps.end(), 908 [](const SubProperty &subProp) { return subProp.language == "chinese"; }); 909 break; 910 } 911 default: { 912 break; 913 } 914 } 915 if (it == subProps.end()) { 916 return nullptr; 917 } 918 return std::make_shared<SubProperty>(*it); 919} 920 921bool ImeInfoInquirer::ParseSubtypeProfile(const std::vector<std::string> &profiles, SubtypeCfg &subtypeCfg) 922{ 923 if (profiles.empty() || profiles.size() != SUBTYPE_PROFILE_NUM) { 924 IMSA_HILOGE("profiles size: %{public}zu!", profiles.size()); 925 return false; 926 } 927 return subtypeCfg.Unmarshall(profiles[0]); 928} 929 930std::shared_ptr<Property> ImeInfoInquirer::GetDefaultImeCfgProp() 931{ 932 auto ime = GetDefaultIme(); 933 if (ime.bundleName.empty() || ime.extName.empty()) { 934 IMSA_HILOGE("defaultIme is abnormal!"); 935 return nullptr; 936 } 937 auto defaultIme = std::make_shared<Property>(); 938 defaultIme->name = ime.bundleName; 939 defaultIme->id = ime.extName; 940 return defaultIme; 941} 942 943std::shared_ptr<ResourceManager> ImeInfoInquirer::GetResMgr(const std::string &resourcePath) 944{ 945 if (resourcePath.empty()) { 946 IMSA_HILOGE("resourcePath is empty!"); 947 return nullptr; 948 } 949 std::shared_ptr<ResourceManager> resMgr(CreateResourceManager()); 950 if (resMgr == nullptr) { 951 IMSA_HILOGE("resMgr is nullptr!"); 952 return nullptr; 953 } 954 resMgr->AddResource(resourcePath.c_str()); 955 std::unique_ptr<ResConfig> resConfig(CreateResConfig()); 956 if (resConfig == nullptr) { 957 IMSA_HILOGE("resConfig is nullptr!"); 958 return nullptr; 959 } 960 std::map<std::string, std::string> configs; 961 OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale(), configs); 962 resConfig->SetLocaleInfo(locale.GetLanguage().c_str(), locale.GetScript().c_str(), locale.GetRegion().c_str()); 963 resMgr->UpdateResConfig(*resConfig); 964 return resMgr; 965} 966 967int32_t ImeInfoInquirer::QueryFullImeInfo(std::vector<std::pair<int32_t, std::vector<FullImeInfo>>> &fullImeInfos) 968{ 969 auto userIds = OsAccountAdapter::QueryActiveOsAccountIds(); 970 if (userIds.empty()) { 971 return ErrorCode::ERROR_OS_ACCOUNT; 972 } 973 for (auto &userId : userIds) { 974 std::vector<FullImeInfo> infos; 975 auto errNo = QueryFullImeInfo(userId, infos); 976 if (errNo != ErrorCode::NO_ERROR) { 977 continue; 978 } 979 fullImeInfos.emplace_back(userId, infos); 980 } 981 if (fullImeInfos.empty()) { 982 return ErrorCode::ERROR_PACKAGE_MANAGER; 983 } 984 return ErrorCode::NO_ERROR; 985} 986 987int32_t ImeInfoInquirer::QueryFullImeInfo(int32_t userId, std::vector<FullImeInfo> &imeInfo) 988{ 989 std::vector<ExtensionAbilityInfo> extInfos; 990 auto ret = ImeInfoInquirer::GetInstance().QueryImeExtInfos(userId, extInfos); 991 if (!ret || extInfos.empty()) { 992 IMSA_HILOGE("%{public}d QueryImeExtInfos failed!", userId); 993 return ErrorCode::ERROR_PACKAGE_MANAGER; 994 } 995 std::map<std::string, std::vector<ExtensionAbilityInfo>> tempExtInfos; 996 for (const auto &extInfo : extInfos) { 997 if (IsTempInputMethod(extInfo)) { 998 continue; 999 } 1000 auto it = tempExtInfos.find(extInfo.bundleName); 1001 if (it != tempExtInfos.end()) { 1002 it->second.push_back(extInfo); 1003 continue; 1004 } 1005 tempExtInfos.insert({ extInfo.bundleName, { extInfo } }); 1006 } 1007 1008 for (const auto &extInfo : tempExtInfos) { 1009 FullImeInfo info; 1010 auto errNo = GetFullImeInfo(userId, extInfo.second, info); 1011 if (errNo != ErrorCode::NO_ERROR) { 1012 return errNo; 1013 } 1014 imeInfo.push_back(info); 1015 } 1016 return ErrorCode::NO_ERROR; 1017} 1018 1019int32_t ImeInfoInquirer::GetFullImeInfo(int32_t userId, const std::string &bundleName, FullImeInfo &imeInfo) 1020{ 1021 std::vector<ExtensionAbilityInfo> extInfos; 1022 auto ret = ImeInfoInquirer::GetInstance().QueryImeExtInfos(userId, extInfos); 1023 if (!ret || extInfos.empty()) { 1024 return ErrorCode::ERROR_PACKAGE_MANAGER; 1025 } 1026 std::vector<ExtensionAbilityInfo> tempExtInfos; 1027 for (const auto &extInfo : extInfos) { 1028 if (IsTempInputMethod(extInfo)) { 1029 continue; 1030 } 1031 if (extInfo.bundleName == bundleName) { 1032 tempExtInfos.push_back(extInfo); 1033 } 1034 } 1035 return GetFullImeInfo(userId, tempExtInfos, imeInfo); 1036} 1037 1038int32_t ImeInfoInquirer::GetFullImeInfo( 1039 int32_t userId, const std::vector<OHOS::AppExecFwk::ExtensionAbilityInfo> &extInfos, FullImeInfo &imeInfo) 1040{ 1041 if (extInfos.empty()) { 1042 return ErrorCode::ERROR_PACKAGE_MANAGER; 1043 } 1044 imeInfo.isNewIme = IsNewExtInfos(extInfos); 1045 auto ret = imeInfo.isNewIme ? ListInputMethodSubtype(userId, extInfos[0], imeInfo.subProps) 1046 : ListInputMethodSubtype(userId, extInfos, imeInfo.subProps); 1047 if (ret != ErrorCode::NO_ERROR) { 1048 IMSA_HILOGE("[%{public}d,%{public}s] list Subtype failed!", userId, extInfos[0].bundleName.c_str()); 1049 return ret; 1050 } 1051 imeInfo.tokenId = extInfos[0].applicationInfo.accessTokenId; 1052 imeInfo.prop.name = extInfos[0].bundleName; 1053 imeInfo.prop.id = extInfos[0].name; 1054 imeInfo.prop.label = GetTargetString(extInfos[0], ImeTargetString::LABEL, userId); 1055 imeInfo.prop.labelId = extInfos[0].applicationInfo.labelId; 1056 imeInfo.prop.iconId = extInfos[0].applicationInfo.iconId; 1057 BundleInfo bundleInfo; 1058 if (GetBundleInfoByBundleName(userId, imeInfo.prop.name, bundleInfo)) { 1059 imeInfo.appId = bundleInfo.signatureInfo.appIdentifier; 1060 imeInfo.versionCode = bundleInfo.versionCode; 1061 } 1062 return ErrorCode::NO_ERROR; 1063} 1064 1065bool ImeInfoInquirer::IsInputMethod(int32_t userId, const std::string &bundleName) 1066{ 1067 auto bmg = GetBundleMgr(); 1068 if (bmg == nullptr) { 1069 return false; 1070 } 1071 BundleInfo bundleInfo; 1072 auto ret = bmg->GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId); 1073 if (!ret) { 1074 return false; 1075 } 1076 for (const auto &extInfo : bundleInfo.extensionInfos) { 1077 if (extInfo.type == ExtensionAbilityType::INPUTMETHOD) { 1078 return true; 1079 } 1080 } 1081 return false; 1082} 1083 1084bool ImeInfoInquirer::IsTempInputMethod(const ExtensionAbilityInfo &extInfo) 1085{ 1086 auto iter = std::find_if(extInfo.metadata.begin(), extInfo.metadata.end(), 1087 [](const Metadata &metadata) { 1088 return metadata.name == TEMPORARY_INPUT_METHOD_METADATA_NAME; 1089 }); 1090 return iter != extInfo.metadata.end(); 1091} 1092 1093std::vector<std::string> ImeInfoInquirer::GetRunningIme(int32_t userId) 1094{ 1095 std::vector<std::string> bundleNames; 1096 std::vector<RunningProcessInfo> infos; 1097 AppMgrClient client; 1098 auto ret = client.GetProcessRunningInfosByUserId(infos, userId); 1099 if (ret != ErrorCode::NO_ERROR) { 1100 IMSA_HILOGE("GetAllRunningProcesses failed, ret: %{public}d!", ret); 1101 return bundleNames; 1102 } 1103 for (const auto &info : infos) { 1104 if (info.extensionType_ == ExtensionAbilityType::INPUTMETHOD && !info.bundleNames.empty()) { 1105 bundleNames.push_back(info.bundleNames[0]); 1106 } 1107 } 1108 return bundleNames; 1109} 1110 1111bool ImeInfoInquirer::IsDefaultImeSet(int32_t userId) 1112{ 1113 return ImeCfgManager::GetInstance().IsDefaultImeSet(userId); 1114} 1115 1116bool ImeInfoInquirer::IsRunningIme(int32_t userId, const std::string &bundleName) 1117{ 1118 auto bundleNames = GetRunningIme(userId); 1119 auto it = std::find_if(bundleNames.begin(), bundleNames.end(), 1120 [&bundleName](const std::string &bundleNameTemp) { return bundleName == bundleNameTemp; }); 1121 return it != bundleNames.end(); 1122} 1123 1124bool ImeInfoInquirer::GetImeAppId(int32_t userId, const std::string &bundleName, std::string &appId) 1125{ 1126 FullImeInfo imeInfo; 1127 if (FullImeInfoManager::GetInstance().Get(bundleName, userId, imeInfo) && !imeInfo.appId.empty()) { 1128 appId = imeInfo.appId; 1129 return true; 1130 } 1131 BundleInfo bundleInfo; 1132 if (!GetBundleInfoByBundleName(userId, bundleName, bundleInfo)) { 1133 return false; 1134 } 1135 appId = bundleInfo.signatureInfo.appIdentifier; 1136 return !appId.empty(); 1137} 1138 1139bool ImeInfoInquirer::GetImeVersionCode(int32_t userId, const std::string &bundleName, uint32_t &versionCode) 1140{ 1141 FullImeInfo imeInfo; 1142 if (FullImeInfoManager::GetInstance().Get(bundleName, userId, imeInfo)) { 1143 versionCode = imeInfo.versionCode; 1144 return true; 1145 } 1146 BundleInfo bundleInfo; 1147 if (!GetBundleInfoByBundleName(userId, bundleName, bundleInfo)) { 1148 return false; 1149 } 1150 versionCode = bundleInfo.versionCode; 1151 return true; 1152} 1153 1154bool ImeInfoInquirer::GetBundleInfoByBundleName( 1155 int32_t userId, const std::string &bundleName, AppExecFwk::BundleInfo &bundleInfo) 1156{ 1157 auto bundleMgr = GetBundleMgr(); 1158 if (bundleMgr == nullptr) { 1159 IMSA_HILOGE("failed to get bundleMgr!"); 1160 return false; 1161 } 1162 auto ret = bundleMgr->GetBundleInfo( 1163 bundleName, static_cast<int32_t>(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO), bundleInfo, userId); 1164 if (!ret) { 1165 IMSA_HILOGE("failed to get bundle info"); 1166 return false; 1167 } 1168 return true; 1169} 1170 1171std::string ImeInfoInquirer::GetTargetString( 1172 const AppExecFwk::ExtensionAbilityInfo &extension, ImeTargetString target, int32_t userId) 1173{ 1174 if (target == ImeTargetString::LABEL) { 1175 if (extension.labelId != DEFAULT_BMS_VALUE) { 1176 return GetStringById(extension.bundleName, extension.moduleName, extension.labelId, userId); 1177 } 1178 IMSA_HILOGD("Extension label is empty, get application label"); 1179 return GetStringById(extension.bundleName, extension.applicationInfo.labelResource.moduleName, 1180 extension.applicationInfo.labelResource.id, userId); 1181 } 1182 if (target == ImeTargetString::DESCRIPTION) { 1183 if (extension.descriptionId != DEFAULT_BMS_VALUE) { 1184 return GetStringById(extension.bundleName, extension.moduleName, extension.descriptionId, userId); 1185 } 1186 IMSA_HILOGD("extension description is empty, get application description"); 1187 return GetStringById(extension.bundleName, extension.applicationInfo.descriptionResource.moduleName, 1188 extension.applicationInfo.descriptionResource.id, userId); 1189 } 1190 IMSA_HILOGD("No match target string"); 1191 return ""; 1192} 1193} // namespace MiscServices 1194} // namespace OHOS