122736c2fSopenharmony_ci /* 222736c2fSopenharmony_ci * Copyright (C) 2021 Huawei Device Co., Ltd. 322736c2fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 422736c2fSopenharmony_ci * you may not use this file except in compliance with the License. 522736c2fSopenharmony_ci * You may obtain a copy of the License at 622736c2fSopenharmony_ci * 722736c2fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 822736c2fSopenharmony_ci * 922736c2fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1022736c2fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1122736c2fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1222736c2fSopenharmony_ci * See the License for the specific language governing permissions and 1322736c2fSopenharmony_ci * limitations under the License. 1422736c2fSopenharmony_ci */ 1522736c2fSopenharmony_ci 1622736c2fSopenharmony_ci#include "input_method_system_ability.h" 1722736c2fSopenharmony_ci 1822736c2fSopenharmony_ci#include <unistd.h> 1922736c2fSopenharmony_ci 2022736c2fSopenharmony_ci#include "ability_manager_client.h" 2122736c2fSopenharmony_ci#include "application_info.h" 2222736c2fSopenharmony_ci#include "combination_key.h" 2322736c2fSopenharmony_ci#include "common_event_support.h" 2422736c2fSopenharmony_ci#include "errors.h" 2522736c2fSopenharmony_ci#include "full_ime_info_manager.h" 2622736c2fSopenharmony_ci#include "global.h" 2722736c2fSopenharmony_ci#include "im_common_event_manager.h" 2822736c2fSopenharmony_ci#include "ime_cfg_manager.h" 2922736c2fSopenharmony_ci#include "ime_info_inquirer.h" 3022736c2fSopenharmony_ci#include "input_client_info.h" 3122736c2fSopenharmony_ci#include "input_method_utils.h" 3222736c2fSopenharmony_ci#include "input_type_manager.h" 3322736c2fSopenharmony_ci#include "ipc_skeleton.h" 3422736c2fSopenharmony_ci#include "iservice_registry.h" 3522736c2fSopenharmony_ci#include "itypes_util.h" 3622736c2fSopenharmony_ci#include "key_event.h" 3722736c2fSopenharmony_ci#include "mem_mgr_client.h" 3822736c2fSopenharmony_ci#include "message_handler.h" 3922736c2fSopenharmony_ci#include "native_token_info.h" 4022736c2fSopenharmony_ci#include "os_account_adapter.h" 4122736c2fSopenharmony_ci#include "scene_board_judgement.h" 4222736c2fSopenharmony_ci#include "system_ability_definition.h" 4322736c2fSopenharmony_ci#ifdef IMF_SCREENLOCK_MGR_ENABLE 4422736c2fSopenharmony_ci#include "screenlock_manager.h" 4522736c2fSopenharmony_ci#endif 4622736c2fSopenharmony_ci#include "system_language_observer.h" 4722736c2fSopenharmony_ci#include "user_session_manager.h" 4822736c2fSopenharmony_ci#include "wms_connection_observer.h" 4922736c2fSopenharmony_ci 5022736c2fSopenharmony_cinamespace OHOS { 5122736c2fSopenharmony_cinamespace MiscServices { 5222736c2fSopenharmony_ciusing namespace MessageID; 5322736c2fSopenharmony_ciusing namespace AppExecFwk; 5422736c2fSopenharmony_ciusing namespace Security::AccessToken; 5522736c2fSopenharmony_ciREGISTER_SYSTEM_ABILITY_BY_ID(InputMethodSystemAbility, INPUT_METHOD_SYSTEM_ABILITY_ID, true); 5622736c2fSopenharmony_ciconstexpr std::int32_t INIT_INTERVAL = 10000L; 5722736c2fSopenharmony_ciconstexpr const char *UNDEFINED = "undefined"; 5822736c2fSopenharmony_cistatic const std::string PERMISSION_CONNECT_IME_ABILITY = "ohos.permission.CONNECT_IME_ABILITY"; 5922736c2fSopenharmony_cistd::shared_ptr<AppExecFwk::EventHandler> InputMethodSystemAbility::serviceHandler_; 6022736c2fSopenharmony_ci 6122736c2fSopenharmony_ciInputMethodSystemAbility::InputMethodSystemAbility(int32_t systemAbilityId, bool runOnCreate) 6222736c2fSopenharmony_ci : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START) 6322736c2fSopenharmony_ci{ 6422736c2fSopenharmony_ci} 6522736c2fSopenharmony_ci 6622736c2fSopenharmony_ciInputMethodSystemAbility::InputMethodSystemAbility() : state_(ServiceRunningState::STATE_NOT_START) 6722736c2fSopenharmony_ci{ 6822736c2fSopenharmony_ci} 6922736c2fSopenharmony_ci 7022736c2fSopenharmony_ciInputMethodSystemAbility::~InputMethodSystemAbility() 7122736c2fSopenharmony_ci{ 7222736c2fSopenharmony_ci stop_ = true; 7322736c2fSopenharmony_ci Message *msg = new Message(MessageID::MSG_ID_QUIT_WORKER_THREAD, nullptr); 7422736c2fSopenharmony_ci MessageHandler::Instance()->SendMessage(msg); 7522736c2fSopenharmony_ci if (workThreadHandler.joinable()) { 7622736c2fSopenharmony_ci workThreadHandler.join(); 7722736c2fSopenharmony_ci } 7822736c2fSopenharmony_ci} 7922736c2fSopenharmony_ci 8022736c2fSopenharmony_civoid InputMethodSystemAbility::OnStart() 8122736c2fSopenharmony_ci{ 8222736c2fSopenharmony_ci IMSA_HILOGI("InputMethodSystemAbility::OnStart start."); 8322736c2fSopenharmony_ci if (!InputMethodSysEvent::GetInstance().StartTimerForReport()) { 8422736c2fSopenharmony_ci IMSA_HILOGE("start sysevent timer failed!"); 8522736c2fSopenharmony_ci } 8622736c2fSopenharmony_ci if (state_ == ServiceRunningState::STATE_RUNNING) { 8722736c2fSopenharmony_ci IMSA_HILOGI("imsa service is already running."); 8822736c2fSopenharmony_ci return; 8922736c2fSopenharmony_ci } 9022736c2fSopenharmony_ci InitServiceHandler(); 9122736c2fSopenharmony_ci Initialize(); 9222736c2fSopenharmony_ci int32_t ret = Init(); 9322736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 9422736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().ServiceFaultReporter("imf", ret); 9522736c2fSopenharmony_ci auto callback = [=]() { Init(); }; 9622736c2fSopenharmony_ci serviceHandler_->PostTask(callback, INIT_INTERVAL); 9722736c2fSopenharmony_ci IMSA_HILOGE("init failed. try again 10s later!"); 9822736c2fSopenharmony_ci } 9922736c2fSopenharmony_ci InitHiTrace(); 10022736c2fSopenharmony_ci InputMethodSyncTrace tracer("InputMethodController Attach trace."); 10122736c2fSopenharmony_ci InputmethodDump::GetInstance().AddDumpAllMethod([this](int fd) { this->DumpAllMethod(fd); }); 10222736c2fSopenharmony_ci IMSA_HILOGI("start imsa service success."); 10322736c2fSopenharmony_ci return; 10422736c2fSopenharmony_ci} 10522736c2fSopenharmony_ci 10622736c2fSopenharmony_ciint InputMethodSystemAbility::Dump(int fd, const std::vector<std::u16string> &args) 10722736c2fSopenharmony_ci{ 10822736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility::Dump start."); 10922736c2fSopenharmony_ci std::vector<std::string> argsStr; 11022736c2fSopenharmony_ci for (auto item : args) { 11122736c2fSopenharmony_ci argsStr.emplace_back(Str16ToStr8(item)); 11222736c2fSopenharmony_ci } 11322736c2fSopenharmony_ci InputmethodDump::GetInstance().Dump(fd, argsStr); 11422736c2fSopenharmony_ci return ERR_OK; 11522736c2fSopenharmony_ci} 11622736c2fSopenharmony_ci 11722736c2fSopenharmony_civoid InputMethodSystemAbility::DumpAllMethod(int fd) 11822736c2fSopenharmony_ci{ 11922736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility::DumpAllMethod start."); 12022736c2fSopenharmony_ci auto ids = OsAccountAdapter::QueryActiveOsAccountIds(); 12122736c2fSopenharmony_ci if (ids.empty()) { 12222736c2fSopenharmony_ci dprintf(fd, "\n - InputMethodSystemAbility::DumpAllMethod get Active Id failed.\n"); 12322736c2fSopenharmony_ci return; 12422736c2fSopenharmony_ci } 12522736c2fSopenharmony_ci dprintf(fd, "\n - DumpAllMethod get Active Id succeed,count=%zu,", ids.size()); 12622736c2fSopenharmony_ci for (auto id : ids) { 12722736c2fSopenharmony_ci const auto ¶ms = ImeInfoInquirer::GetInstance().GetDumpInfo(id); 12822736c2fSopenharmony_ci if (params.empty()) { 12922736c2fSopenharmony_ci IMSA_HILOGD("userId: %{public}d the IME properties is empty.", id); 13022736c2fSopenharmony_ci dprintf(fd, "\n - The IME properties about the Active Id %d is empty.\n", id); 13122736c2fSopenharmony_ci continue; 13222736c2fSopenharmony_ci } 13322736c2fSopenharmony_ci dprintf(fd, "\n - The Active Id:%d get input method:\n%s\n", id, params.c_str()); 13422736c2fSopenharmony_ci } 13522736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility::DumpAllMethod end."); 13622736c2fSopenharmony_ci} 13722736c2fSopenharmony_ci 13822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::Init() 13922736c2fSopenharmony_ci{ 14022736c2fSopenharmony_ci bool isSuccess = Publish(this); 14122736c2fSopenharmony_ci if (!isSuccess) { 14222736c2fSopenharmony_ci return -1; 14322736c2fSopenharmony_ci } 14422736c2fSopenharmony_ci state_ = ServiceRunningState::STATE_RUNNING; 14522736c2fSopenharmony_ci ImeCfgManager::GetInstance().Init(); 14622736c2fSopenharmony_ci ImeInfoInquirer::GetInstance().InitSystemConfig(); 14722736c2fSopenharmony_ci InitMonitors(); 14822736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 14922736c2fSopenharmony_ci} 15022736c2fSopenharmony_ci 15122736c2fSopenharmony_civoid InputMethodSystemAbility::UpdateUserInfo(int32_t userId) 15222736c2fSopenharmony_ci{ 15322736c2fSopenharmony_ci IMSA_HILOGI("%{public}d switch to %{public}d.", userId_, userId); 15422736c2fSopenharmony_ci userId_ = userId; 15522736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId_); 15622736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().SetUserId(userId_); 15722736c2fSopenharmony_ci if (enableImeOn_.load()) { 15822736c2fSopenharmony_ci EnableImeDataParser::GetInstance()->OnUserChanged(userId_); 15922736c2fSopenharmony_ci } 16022736c2fSopenharmony_ci if (enableSecurityMode_.load()) { 16122736c2fSopenharmony_ci SecurityModeParser::GetInstance()->UpdateFullModeList(userId_); 16222736c2fSopenharmony_ci } 16322736c2fSopenharmony_ci} 16422736c2fSopenharmony_ci 16522736c2fSopenharmony_civoid InputMethodSystemAbility::OnStop() 16622736c2fSopenharmony_ci{ 16722736c2fSopenharmony_ci IMSA_HILOGI("OnStop start."); 16822736c2fSopenharmony_ci FreezeManager::SetEventHandler(nullptr); 16922736c2fSopenharmony_ci serviceHandler_ = nullptr; 17022736c2fSopenharmony_ci state_ = ServiceRunningState::STATE_NOT_START; 17122736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, INPUT_METHOD_SYSTEM_ABILITY_ID); 17222736c2fSopenharmony_ci} 17322736c2fSopenharmony_ci 17422736c2fSopenharmony_civoid InputMethodSystemAbility::InitServiceHandler() 17522736c2fSopenharmony_ci{ 17622736c2fSopenharmony_ci IMSA_HILOGI("InitServiceHandler start."); 17722736c2fSopenharmony_ci if (serviceHandler_ != nullptr) { 17822736c2fSopenharmony_ci IMSA_HILOGE("InputMethodSystemAbility already init!"); 17922736c2fSopenharmony_ci return; 18022736c2fSopenharmony_ci } 18122736c2fSopenharmony_ci std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("OS_InputMethodSystemAbility"); 18222736c2fSopenharmony_ci serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner); 18322736c2fSopenharmony_ci FreezeManager::SetEventHandler(serviceHandler_); 18422736c2fSopenharmony_ci 18522736c2fSopenharmony_ci IMSA_HILOGI("InitServiceHandler succeeded."); 18622736c2fSopenharmony_ci} 18722736c2fSopenharmony_ci 18822736c2fSopenharmony_ci/** 18922736c2fSopenharmony_ci * Initialization of Input method management service 19022736c2fSopenharmony_ci * \n It's called after the service starts, before any transaction. 19122736c2fSopenharmony_ci */ 19222736c2fSopenharmony_civoid InputMethodSystemAbility::Initialize() 19322736c2fSopenharmony_ci{ 19422736c2fSopenharmony_ci IMSA_HILOGI("InputMethodSystemAbility::Initialize."); 19522736c2fSopenharmony_ci // init work thread to handle the messages 19622736c2fSopenharmony_ci workThreadHandler = std::thread([this] { this->WorkThread(); }); 19722736c2fSopenharmony_ci identityChecker_ = std::make_shared<IdentityCheckerImpl>(); 19822736c2fSopenharmony_ci userId_ = OsAccountAdapter::MAIN_USER_ID; 19922736c2fSopenharmony_ci UserSessionManager::GetInstance().SetEventHandler(serviceHandler_); 20022736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId_); 20122736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().SetUserId(userId_); 20222736c2fSopenharmony_ci isScbEnable_.store(Rosen::SceneBoardJudgement::IsSceneBoardEnabled()); 20322736c2fSopenharmony_ci} 20422736c2fSopenharmony_ci 20522736c2fSopenharmony_civoid InputMethodSystemAbility::SubscribeCommonEvent() 20622736c2fSopenharmony_ci{ 20722736c2fSopenharmony_ci sptr<ImCommonEventManager> imCommonEventManager = ImCommonEventManager::GetInstance(); 20822736c2fSopenharmony_ci bool isSuccess = imCommonEventManager->SubscribeEvent(); 20922736c2fSopenharmony_ci if (isSuccess) { 21022736c2fSopenharmony_ci IMSA_HILOGI("initialize subscribe service event success."); 21122736c2fSopenharmony_ci return; 21222736c2fSopenharmony_ci } 21322736c2fSopenharmony_ci 21422736c2fSopenharmony_ci IMSA_HILOGE("failed, try again 10s later!"); 21522736c2fSopenharmony_ci auto callback = [this]() { SubscribeCommonEvent(); }; 21622736c2fSopenharmony_ci serviceHandler_->PostTask(callback, INIT_INTERVAL); 21722736c2fSopenharmony_ci} 21822736c2fSopenharmony_ci 21922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::PrepareInput(int32_t userId, InputClientInfo &clientInfo) 22022736c2fSopenharmony_ci{ 22122736c2fSopenharmony_ci auto ret = GenerateClientInfo(userId, clientInfo); 22222736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 22322736c2fSopenharmony_ci return ret; 22422736c2fSopenharmony_ci } 22522736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 22622736c2fSopenharmony_ci if (session == nullptr) { 22722736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 22822736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 22922736c2fSopenharmony_ci } 23022736c2fSopenharmony_ci return session->OnPrepareInput(clientInfo); 23122736c2fSopenharmony_ci} 23222736c2fSopenharmony_ci 23322736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GenerateClientInfo(int32_t userId, InputClientInfo &clientInfo) 23422736c2fSopenharmony_ci{ 23522736c2fSopenharmony_ci if (clientInfo.client == nullptr || clientInfo.channel == nullptr) { 23622736c2fSopenharmony_ci IMSA_HILOGE("client or channel is nullptr!"); 23722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 23822736c2fSopenharmony_ci } 23922736c2fSopenharmony_ci auto deathRecipient = new (std::nothrow) InputDeathRecipient(); 24022736c2fSopenharmony_ci if (deathRecipient == nullptr) { 24122736c2fSopenharmony_ci IMSA_HILOGE("failed to new deathRecipient!"); 24222736c2fSopenharmony_ci return ErrorCode::ERROR_EX_NULL_POINTER; 24322736c2fSopenharmony_ci } 24422736c2fSopenharmony_ci clientInfo.pid = IPCSkeleton::GetCallingPid(); 24522736c2fSopenharmony_ci clientInfo.uid = IPCSkeleton::GetCallingUid(); 24622736c2fSopenharmony_ci clientInfo.userID = userId; 24722736c2fSopenharmony_ci clientInfo.deathRecipient = deathRecipient; 24822736c2fSopenharmony_ci auto tokenId = IPCSkeleton::GetCallingTokenID(); 24922736c2fSopenharmony_ci if (identityChecker_->IsFocusedUIExtension(tokenId)) { 25022736c2fSopenharmony_ci clientInfo.uiExtensionTokenId = tokenId; 25122736c2fSopenharmony_ci } 25222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 25322736c2fSopenharmony_ci} 25422736c2fSopenharmony_ci 25522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ReleaseInput(sptr<IInputClient> client) 25622736c2fSopenharmony_ci{ 25722736c2fSopenharmony_ci if (client == nullptr) { 25822736c2fSopenharmony_ci IMSA_HILOGE("client is nullptr!"); 25922736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 26022736c2fSopenharmony_ci } 26122736c2fSopenharmony_ci auto userId = GetCallingUserId(); 26222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 26322736c2fSopenharmony_ci if (session == nullptr) { 26422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 26522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 26622736c2fSopenharmony_ci } 26722736c2fSopenharmony_ci return session->OnReleaseInput(client); 26822736c2fSopenharmony_ci} 26922736c2fSopenharmony_ci 27022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::StartInput(InputClientInfo &inputClientInfo, sptr<IRemoteObject> &agent) 27122736c2fSopenharmony_ci{ 27222736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 27322736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId) && !identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId)) { 27422736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 27522736c2fSopenharmony_ci } 27622736c2fSopenharmony_ci auto userId = GetCallingUserId(); 27722736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 27822736c2fSopenharmony_ci if (session == nullptr) { 27922736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 28022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 28122736c2fSopenharmony_ci } 28222736c2fSopenharmony_ci if (session->GetCurrentClientPid() != IPCSkeleton::GetCallingPid() 28322736c2fSopenharmony_ci && session->GetInactiveClientPid() != IPCSkeleton::GetCallingPid()) { 28422736c2fSopenharmony_ci // notify inputStart when caller pid different from both current client and inactive client 28522736c2fSopenharmony_ci inputClientInfo.isNotifyInputStart = true; 28622736c2fSopenharmony_ci } 28722736c2fSopenharmony_ci if (inputClientInfo.isNotifyInputStart) { 28822736c2fSopenharmony_ci inputClientInfo.needHide = session->CheckPwdInputPatternConv(inputClientInfo); 28922736c2fSopenharmony_ci } 29022736c2fSopenharmony_ci if (!session->IsProxyImeEnable()) { 29122736c2fSopenharmony_ci auto ret = CheckInputTypeOption(userId, inputClientInfo); 29222736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 29322736c2fSopenharmony_ci IMSA_HILOGE("%{public}d failed to CheckInputTypeOption!", userId); 29422736c2fSopenharmony_ci return ret; 29522736c2fSopenharmony_ci } 29622736c2fSopenharmony_ci } 29722736c2fSopenharmony_ci int32_t ret = PrepareInput(userId, inputClientInfo); 29822736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 29922736c2fSopenharmony_ci IMSA_HILOGE("failed to PrepareInput!"); 30022736c2fSopenharmony_ci return ret; 30122736c2fSopenharmony_ci } 30222736c2fSopenharmony_ci session->SetInputType(); 30322736c2fSopenharmony_ci return session->OnStartInput(inputClientInfo, agent); 30422736c2fSopenharmony_ci} 30522736c2fSopenharmony_ci 30622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::CheckInputTypeOption(int32_t userId, InputClientInfo &inputClientInfo) 30722736c2fSopenharmony_ci{ 30822736c2fSopenharmony_ci IMSA_HILOGI("SecurityFlag: %{public}d, IsSameTextInput: %{public}d, IsStarted: %{public}d, " 30922736c2fSopenharmony_ci "IsSecurityImeStarted: %{public}d.", 31022736c2fSopenharmony_ci inputClientInfo.config.inputAttribute.GetSecurityFlag(), !inputClientInfo.isNotifyInputStart, 31122736c2fSopenharmony_ci InputTypeManager::GetInstance().IsStarted(), InputTypeManager::GetInstance().IsSecurityImeStarted()); 31222736c2fSopenharmony_ci if (inputClientInfo.config.inputAttribute.GetSecurityFlag()) { 31322736c2fSopenharmony_ci if (!InputTypeManager::GetInstance().IsStarted()) { 31422736c2fSopenharmony_ci IMSA_HILOGD("SecurityFlag, input type is not started, start."); 31522736c2fSopenharmony_ci // if need to switch ime, no need to hide panel first. 31622736c2fSopenharmony_ci NeedHideWhenSwitchInputType(userId, inputClientInfo.needHide); 31722736c2fSopenharmony_ci return StartInputType(userId, InputType::SECURITY_INPUT); 31822736c2fSopenharmony_ci } 31922736c2fSopenharmony_ci if (!inputClientInfo.isNotifyInputStart) { 32022736c2fSopenharmony_ci IMSA_HILOGD("SecurityFlag, same textField, input type is started, not deal."); 32122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 32222736c2fSopenharmony_ci } 32322736c2fSopenharmony_ci if (!InputTypeManager::GetInstance().IsSecurityImeStarted()) { 32422736c2fSopenharmony_ci IMSA_HILOGD("SecurityFlag, new textField, input type is started, but it is not security, switch."); 32522736c2fSopenharmony_ci NeedHideWhenSwitchInputType(userId, inputClientInfo.needHide); 32622736c2fSopenharmony_ci return StartInputType(userId, InputType::SECURITY_INPUT); 32722736c2fSopenharmony_ci } 32822736c2fSopenharmony_ci IMSA_HILOGD("SecurityFlag, other condition, not deal."); 32922736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 33022736c2fSopenharmony_ci } 33122736c2fSopenharmony_ci if (!inputClientInfo.isNotifyInputStart) { 33222736c2fSopenharmony_ci IMSA_HILOGD("NormalFlag, same textField, not deal."); 33322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 33422736c2fSopenharmony_ci } 33522736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 33622736c2fSopenharmony_ci if (session == nullptr) { 33722736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 33822736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 33922736c2fSopenharmony_ci } 34022736c2fSopenharmony_ci if (InputTypeManager::GetInstance().IsStarted()) { 34122736c2fSopenharmony_ci IMSA_HILOGD("NormalFlag, diff textField, input type started, restore."); 34222736c2fSopenharmony_ci session->RestoreCurrentImeSubType(); 34322736c2fSopenharmony_ci } 34422736c2fSopenharmony_ci return session->RestoreCurrentIme(); 34522736c2fSopenharmony_ci} 34622736c2fSopenharmony_ci 34722736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ShowInput(sptr<IInputClient> client) 34822736c2fSopenharmony_ci{ 34922736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 35022736c2fSopenharmony_ci auto userId = GetCallingUserId(); 35122736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 35222736c2fSopenharmony_ci if (session == nullptr) { 35322736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 35422736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 35522736c2fSopenharmony_ci } 35622736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId)) { 35722736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, session->GetCurrentClientPid())) { 35822736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 35922736c2fSopenharmony_ci } 36022736c2fSopenharmony_ci } 36122736c2fSopenharmony_ci if (client == nullptr) { 36222736c2fSopenharmony_ci IMSA_HILOGE("client is nullptr!"); 36322736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 36422736c2fSopenharmony_ci } 36522736c2fSopenharmony_ci return session->OnShowInput(client); 36622736c2fSopenharmony_ci} 36722736c2fSopenharmony_ci 36822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::HideInput(sptr<IInputClient> client) 36922736c2fSopenharmony_ci{ 37022736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 37122736c2fSopenharmony_ci auto userId = GetCallingUserId(); 37222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 37322736c2fSopenharmony_ci if (session == nullptr) { 37422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 37522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 37622736c2fSopenharmony_ci } 37722736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId)) { 37822736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, session->GetCurrentClientPid())) { 37922736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 38022736c2fSopenharmony_ci } 38122736c2fSopenharmony_ci } 38222736c2fSopenharmony_ci if (client == nullptr) { 38322736c2fSopenharmony_ci IMSA_HILOGE("client is nullptr!"); 38422736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 38522736c2fSopenharmony_ci } 38622736c2fSopenharmony_ci return session->OnHideInput(client); 38722736c2fSopenharmony_ci} 38822736c2fSopenharmony_ci 38922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::StopInputSession() 39022736c2fSopenharmony_ci{ 39122736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 39222736c2fSopenharmony_ci auto userId = GetCallingUserId(); 39322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 39422736c2fSopenharmony_ci if (session == nullptr) { 39522736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 39622736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 39722736c2fSopenharmony_ci } 39822736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId)) { 39922736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, session->GetCurrentClientPid())) { 40022736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 40122736c2fSopenharmony_ci } 40222736c2fSopenharmony_ci } 40322736c2fSopenharmony_ci return session->OnHideCurrentInput(); 40422736c2fSopenharmony_ci} 40522736c2fSopenharmony_ci 40622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::RequestShowInput() 40722736c2fSopenharmony_ci{ 40822736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 40922736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId) && 41022736c2fSopenharmony_ci !identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 41122736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 41222736c2fSopenharmony_ci } 41322736c2fSopenharmony_ci auto userId = GetCallingUserId(); 41422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 41522736c2fSopenharmony_ci if (session == nullptr) { 41622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 41722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 41822736c2fSopenharmony_ci } 41922736c2fSopenharmony_ci return session->OnRequestShowInput(); 42022736c2fSopenharmony_ci} 42122736c2fSopenharmony_ci 42222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::RequestHideInput() 42322736c2fSopenharmony_ci{ 42422736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 42522736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId) && 42622736c2fSopenharmony_ci !identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 42722736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 42822736c2fSopenharmony_ci } 42922736c2fSopenharmony_ci auto userId = GetCallingUserId(); 43022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 43122736c2fSopenharmony_ci if (session == nullptr) { 43222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 43322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 43422736c2fSopenharmony_ci } 43522736c2fSopenharmony_ci return session->OnRequestHideInput(); 43622736c2fSopenharmony_ci} 43722736c2fSopenharmony_ci 43822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent) 43922736c2fSopenharmony_ci{ 44022736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility start."); 44122736c2fSopenharmony_ci auto userId = GetCallingUserId(); 44222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 44322736c2fSopenharmony_ci if (session == nullptr) { 44422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 44522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 44622736c2fSopenharmony_ci } 44722736c2fSopenharmony_ci if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { 44822736c2fSopenharmony_ci return session->OnRegisterProxyIme(core, agent); 44922736c2fSopenharmony_ci } 45022736c2fSopenharmony_ci if (!IsCurrentIme(userId)) { 45122736c2fSopenharmony_ci IMSA_HILOGE("not current ime, userId:%{public}d", userId); 45222736c2fSopenharmony_ci return ErrorCode::ERROR_NOT_CURRENT_IME; 45322736c2fSopenharmony_ci } 45422736c2fSopenharmony_ci return session->OnSetCoreAndAgent(core, agent); 45522736c2fSopenharmony_ci} 45622736c2fSopenharmony_ci 45722736c2fSopenharmony_ciint32_t InputMethodSystemAbility::InitConnect() 45822736c2fSopenharmony_ci{ 45922736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility init connect."); 46022736c2fSopenharmony_ci auto userId = GetCallingUserId(); 46122736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 46222736c2fSopenharmony_ci if (session == nullptr) { 46322736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 46422736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 46522736c2fSopenharmony_ci } 46622736c2fSopenharmony_ci if (!IsCurrentIme(userId)) { 46722736c2fSopenharmony_ci return ErrorCode::ERROR_NOT_CURRENT_IME; 46822736c2fSopenharmony_ci } 46922736c2fSopenharmony_ci return session->InitConnect(IPCSkeleton::GetCallingPid()); 47022736c2fSopenharmony_ci} 47122736c2fSopenharmony_ci 47222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::HideCurrentInput() 47322736c2fSopenharmony_ci{ 47422736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 47522736c2fSopenharmony_ci auto userId = GetCallingUserId(); 47622736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 47722736c2fSopenharmony_ci if (session == nullptr) { 47822736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 47922736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 48022736c2fSopenharmony_ci } 48122736c2fSopenharmony_ci if (identityChecker_->IsBroker(tokenId)) { 48222736c2fSopenharmony_ci return session->OnHideCurrentInput(); 48322736c2fSopenharmony_ci } 48422736c2fSopenharmony_ci if (!identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 48522736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 48622736c2fSopenharmony_ci } 48722736c2fSopenharmony_ci return session->OnHideCurrentInput(); 48822736c2fSopenharmony_ci} 48922736c2fSopenharmony_ci 49022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ShowCurrentInput() 49122736c2fSopenharmony_ci{ 49222736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 49322736c2fSopenharmony_ci auto userId = GetCallingUserId(); 49422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 49522736c2fSopenharmony_ci if (session == nullptr) { 49622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 49722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 49822736c2fSopenharmony_ci } 49922736c2fSopenharmony_ci if (identityChecker_->IsBroker(tokenId)) { 50022736c2fSopenharmony_ci return session->OnShowCurrentInput(); 50122736c2fSopenharmony_ci } 50222736c2fSopenharmony_ci if (!identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 50322736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 50422736c2fSopenharmony_ci } 50522736c2fSopenharmony_ci return session->OnShowCurrentInput(); 50622736c2fSopenharmony_ci} 50722736c2fSopenharmony_ci 50822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::PanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) 50922736c2fSopenharmony_ci{ 51022736c2fSopenharmony_ci auto userId = GetCallingUserId(); 51122736c2fSopenharmony_ci if (!IsCurrentIme(userId)) { 51222736c2fSopenharmony_ci IMSA_HILOGE("not current ime!"); 51322736c2fSopenharmony_ci return ErrorCode::ERROR_NOT_CURRENT_IME; 51422736c2fSopenharmony_ci } 51522736c2fSopenharmony_ci auto commonEventManager = ImCommonEventManager::GetInstance(); 51622736c2fSopenharmony_ci if (commonEventManager != nullptr) { 51722736c2fSopenharmony_ci auto ret = ImCommonEventManager::GetInstance()->PublishPanelStatusChangeEvent(userId, status, info); 51822736c2fSopenharmony_ci IMSA_HILOGD("public panel status change event: %{public}d", ret); 51922736c2fSopenharmony_ci } 52022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 52122736c2fSopenharmony_ci if (session == nullptr) { 52222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 52322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 52422736c2fSopenharmony_ci } 52522736c2fSopenharmony_ci return session->OnPanelStatusChange(status, info); 52622736c2fSopenharmony_ci} 52722736c2fSopenharmony_ci 52822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::UpdateListenEventFlag(InputClientInfo &clientInfo, uint32_t eventFlag) 52922736c2fSopenharmony_ci{ 53022736c2fSopenharmony_ci IMSA_HILOGI("finalEventFlag: %{public}u, eventFlag: %{public}u.", clientInfo.eventFlag, eventFlag); 53122736c2fSopenharmony_ci if (EventStatusManager::IsImeHideOn(eventFlag) || EventStatusManager::IsImeShowOn(eventFlag)) { 53222736c2fSopenharmony_ci if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID()) && 53322736c2fSopenharmony_ci !identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { 53422736c2fSopenharmony_ci IMSA_HILOGE("not system application!"); 53522736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; 53622736c2fSopenharmony_ci } 53722736c2fSopenharmony_ci } 53822736c2fSopenharmony_ci auto userId = GetCallingUserId(); 53922736c2fSopenharmony_ci auto ret = GenerateClientInfo(userId, clientInfo); 54022736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 54122736c2fSopenharmony_ci return ret; 54222736c2fSopenharmony_ci } 54322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 54422736c2fSopenharmony_ci if (session == nullptr) { 54522736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 54622736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 54722736c2fSopenharmony_ci } 54822736c2fSopenharmony_ci return session->OnUpdateListenEventFlag(clientInfo); 54922736c2fSopenharmony_ci} 55022736c2fSopenharmony_ci 55122736c2fSopenharmony_cibool InputMethodSystemAbility::IsCurrentIme() 55222736c2fSopenharmony_ci{ 55322736c2fSopenharmony_ci return IsCurrentIme(GetCallingUserId()); 55422736c2fSopenharmony_ci} 55522736c2fSopenharmony_ci 55622736c2fSopenharmony_cibool InputMethodSystemAbility::IsInputTypeSupported(InputType type) 55722736c2fSopenharmony_ci{ 55822736c2fSopenharmony_ci return InputTypeManager::GetInstance().IsSupported(type); 55922736c2fSopenharmony_ci} 56022736c2fSopenharmony_ci 56122736c2fSopenharmony_ciint32_t InputMethodSystemAbility::StartInputType(InputType type) 56222736c2fSopenharmony_ci{ 56322736c2fSopenharmony_ci return StartInputType(GetCallingUserId(), type); 56422736c2fSopenharmony_ci} 56522736c2fSopenharmony_ci 56622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ExitCurrentInputType() 56722736c2fSopenharmony_ci{ 56822736c2fSopenharmony_ci auto userId = GetCallingUserId(); 56922736c2fSopenharmony_ci auto ret = IsDefaultImeFromTokenId(userId, IPCSkeleton::GetCallingTokenID()); 57022736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 57122736c2fSopenharmony_ci IMSA_HILOGE("not default ime!"); 57222736c2fSopenharmony_ci return ErrorCode::ERROR_NOT_DEFAULT_IME; 57322736c2fSopenharmony_ci } 57422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 57522736c2fSopenharmony_ci if (session == nullptr) { 57622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 57722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 57822736c2fSopenharmony_ci } 57922736c2fSopenharmony_ci if (session->CheckSecurityMode()) { 58022736c2fSopenharmony_ci return StartInputType(userId, InputType::SECURITY_INPUT); 58122736c2fSopenharmony_ci } 58222736c2fSopenharmony_ci auto typeIme = InputTypeManager::GetInstance().GetCurrentIme(); 58322736c2fSopenharmony_ci auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 58422736c2fSopenharmony_ci if (cfgIme->bundleName == typeIme.bundleName) { 58522736c2fSopenharmony_ci return session->RestoreCurrentImeSubType(); 58622736c2fSopenharmony_ci } 58722736c2fSopenharmony_ci return session->RestoreCurrentIme(); 58822736c2fSopenharmony_ci} 58922736c2fSopenharmony_ci 59022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::IsDefaultIme() 59122736c2fSopenharmony_ci{ 59222736c2fSopenharmony_ci return IsDefaultImeFromTokenId(GetCallingUserId(), IPCSkeleton::GetCallingTokenID()); 59322736c2fSopenharmony_ci} 59422736c2fSopenharmony_ci 59522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::IsDefaultImeFromTokenId(int32_t userId, uint32_t tokenId) 59622736c2fSopenharmony_ci{ 59722736c2fSopenharmony_ci auto prop = std::make_shared<Property>(); 59822736c2fSopenharmony_ci auto ret = ImeInfoInquirer::GetInstance().GetDefaultInputMethod(userId, prop); 59922736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR || prop == nullptr) { 60022736c2fSopenharmony_ci IMSA_HILOGE("failed to get default ime!"); 60122736c2fSopenharmony_ci return ErrorCode::ERROR_PERSIST_CONFIG; 60222736c2fSopenharmony_ci } 60322736c2fSopenharmony_ci if (!identityChecker_->IsBundleNameValid(tokenId, prop->name)) { 60422736c2fSopenharmony_ci return ErrorCode::ERROR_NOT_DEFAULT_IME; 60522736c2fSopenharmony_ci } 60622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 60722736c2fSopenharmony_ci} 60822736c2fSopenharmony_ci 60922736c2fSopenharmony_cibool InputMethodSystemAbility::IsCurrentImeByPid(int32_t pid) 61022736c2fSopenharmony_ci{ 61122736c2fSopenharmony_ci if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID()) && 61222736c2fSopenharmony_ci !identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { 61322736c2fSopenharmony_ci IMSA_HILOGE("not system application or system ability!"); 61422736c2fSopenharmony_ci return false; 61522736c2fSopenharmony_ci } 61622736c2fSopenharmony_ci auto userId = GetCallingUserId(); 61722736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 61822736c2fSopenharmony_ci if (session == nullptr) { 61922736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 62022736c2fSopenharmony_ci return false; 62122736c2fSopenharmony_ci } 62222736c2fSopenharmony_ci return session->IsCurrentImeByPid(pid); 62322736c2fSopenharmony_ci} 62422736c2fSopenharmony_ci 62522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::IsPanelShown(const PanelInfo &panelInfo, bool &isShown) 62622736c2fSopenharmony_ci{ 62722736c2fSopenharmony_ci if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID())) { 62822736c2fSopenharmony_ci IMSA_HILOGE("not system application!"); 62922736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; 63022736c2fSopenharmony_ci } 63122736c2fSopenharmony_ci auto userId = GetCallingUserId(); 63222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 63322736c2fSopenharmony_ci if (session == nullptr) { 63422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 63522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 63622736c2fSopenharmony_ci } 63722736c2fSopenharmony_ci return session->IsPanelShown(panelInfo, isShown); 63822736c2fSopenharmony_ci} 63922736c2fSopenharmony_ci 64022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::DisplayOptionalInputMethod() 64122736c2fSopenharmony_ci{ 64222736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility start."); 64322736c2fSopenharmony_ci return OnDisplayOptionalInputMethod(); 64422736c2fSopenharmony_ci} 64522736c2fSopenharmony_ci 64622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleName, const std::string &subName, 64722736c2fSopenharmony_ci SwitchTrigger trigger) 64822736c2fSopenharmony_ci{ 64922736c2fSopenharmony_ci // IMSA not check permission, add this verify for prevent counterfeit 65022736c2fSopenharmony_ci if (trigger == SwitchTrigger::IMSA) { 65122736c2fSopenharmony_ci IMSA_HILOGW("caller counterfeit!"); 65222736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 65322736c2fSopenharmony_ci } 65422736c2fSopenharmony_ci SwitchInfo switchInfo = { std::chrono::system_clock::now(), bundleName, subName }; 65522736c2fSopenharmony_ci int32_t userId = GetCallingUserId(); 65622736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 65722736c2fSopenharmony_ci if (session == nullptr) { 65822736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 65922736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 66022736c2fSopenharmony_ci } 66122736c2fSopenharmony_ci if (enableImeOn_.load() && !EnableImeDataParser::GetInstance()->CheckNeedSwitch(switchInfo, userId)) { 66222736c2fSopenharmony_ci IMSA_HILOGW("Enable mode off or switch is not enable, stopped!"); 66322736c2fSopenharmony_ci return ErrorCode::ERROR_ENABLE_IME; 66422736c2fSopenharmony_ci } 66522736c2fSopenharmony_ci auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 66622736c2fSopenharmony_ci if (switchInfo.subName.empty() && switchInfo.bundleName == currentImeCfg->bundleName) { 66722736c2fSopenharmony_ci switchInfo.subName = currentImeCfg->subName; 66822736c2fSopenharmony_ci } 66922736c2fSopenharmony_ci switchInfo.timestamp = std::chrono::system_clock::now(); 67022736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 67122736c2fSopenharmony_ci return InputTypeManager::GetInstance().IsInputType({ bundleName, subName }) 67222736c2fSopenharmony_ci ? OnStartInputType(userId, switchInfo, true) 67322736c2fSopenharmony_ci : OnSwitchInputMethod(userId, switchInfo, trigger); 67422736c2fSopenharmony_ci} 67522736c2fSopenharmony_ci 67622736c2fSopenharmony_cibool InputMethodSystemAbility::EnableIme(const std::string &bundleName) 67722736c2fSopenharmony_ci{ 67822736c2fSopenharmony_ci if (CheckEnableAndSwitchPermission() != ErrorCode::NO_ERROR) { 67922736c2fSopenharmony_ci IMSA_HILOGE("Check enable ime value failed!"); 68022736c2fSopenharmony_ci return false; 68122736c2fSopenharmony_ci } 68222736c2fSopenharmony_ci int32_t userId = GetCallingUserId(); 68322736c2fSopenharmony_ci return SettingsDataUtils::GetInstance()->EnableIme(userId, bundleName); 68422736c2fSopenharmony_ci} 68522736c2fSopenharmony_ci 68622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnSwitchInputMethod(int32_t userId, const SwitchInfo &switchInfo, 68722736c2fSopenharmony_ci SwitchTrigger trigger) 68822736c2fSopenharmony_ci{ 68922736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::CHANGE_IME); 69022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 69122736c2fSopenharmony_ci if (session == nullptr) { 69222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 69322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 69422736c2fSopenharmony_ci } 69522736c2fSopenharmony_ci if (!session->GetSwitchQueue().IsReady(switchInfo)) { 69622736c2fSopenharmony_ci IMSA_HILOGD("start wait."); 69722736c2fSopenharmony_ci session->GetSwitchQueue().Wait(switchInfo); 69822736c2fSopenharmony_ci } 69922736c2fSopenharmony_ci IMSA_HILOGI("start switch %{public}s|%{public}s.", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); 70022736c2fSopenharmony_ci int32_t ret = CheckSwitchPermission(userId, switchInfo, trigger); 70122736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 70222736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ErrorCode::ERROR_STATUS_PERMISSION_DENIED, 70322736c2fSopenharmony_ci switchInfo.bundleName, "switch input method failed!"); 70422736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 70522736c2fSopenharmony_ci return ret; 70622736c2fSopenharmony_ci } 70722736c2fSopenharmony_ci auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId, switchInfo.bundleName, switchInfo.subName); 70822736c2fSopenharmony_ci if (info == nullptr) { 70922736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 71022736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 71122736c2fSopenharmony_ci } 71222736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 71322736c2fSopenharmony_ci { 71422736c2fSopenharmony_ci InputMethodSyncTrace tracer("InputMethodSystemAbility_OnSwitchInputMethod"); 71522736c2fSopenharmony_ci std::string targetImeName = info->prop.name + "/" + info->prop.id; 71622736c2fSopenharmony_ci ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id, true }); 71722736c2fSopenharmony_ci auto targetIme = std::make_shared<ImeNativeCfg>(ImeNativeCfg { 71822736c2fSopenharmony_ci targetImeName, info->prop.name, switchInfo.subName.empty() ? "" : info->subProp.id, info->prop.id }); 71922736c2fSopenharmony_ci if (!session->StartIme(targetIme)) { 72022736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ret, switchInfo.bundleName, 72122736c2fSopenharmony_ci "switch input method failed!"); 72222736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 72322736c2fSopenharmony_ci return ErrorCode::ERROR_IME_START_FAILED; 72422736c2fSopenharmony_ci } 72522736c2fSopenharmony_ci GetValidSubtype(switchInfo.subName, info); 72622736c2fSopenharmony_ci session->NotifyImeChangeToClients(info->prop, info->subProp); 72722736c2fSopenharmony_ci ret = session->SwitchSubtype(info->subProp); 72822736c2fSopenharmony_ci } 72922736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 73022736c2fSopenharmony_ci ret = info->isSpecificSubName ? ret : ErrorCode::NO_ERROR; 73122736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 73222736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ret, switchInfo.bundleName, 73322736c2fSopenharmony_ci "switch input method subtype failed!"); 73422736c2fSopenharmony_ci } 73522736c2fSopenharmony_ci return ret; 73622736c2fSopenharmony_ci} 73722736c2fSopenharmony_ci 73822736c2fSopenharmony_civoid InputMethodSystemAbility::GetValidSubtype(const std::string &subName, const std::shared_ptr<ImeInfo> &info) 73922736c2fSopenharmony_ci{ 74022736c2fSopenharmony_ci if (subName.empty()) { 74122736c2fSopenharmony_ci IMSA_HILOGW("undefined subtype"); 74222736c2fSopenharmony_ci info->subProp.id = UNDEFINED; 74322736c2fSopenharmony_ci info->subProp.name = UNDEFINED; 74422736c2fSopenharmony_ci } 74522736c2fSopenharmony_ci} 74622736c2fSopenharmony_ci 74722736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnStartInputType(int32_t userId, const SwitchInfo &switchInfo, 74822736c2fSopenharmony_ci bool isCheckPermission) 74922736c2fSopenharmony_ci{ 75022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 75122736c2fSopenharmony_ci if (session == nullptr) { 75222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 75322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 75422736c2fSopenharmony_ci } 75522736c2fSopenharmony_ci if (!session->GetSwitchQueue().IsReady(switchInfo)) { 75622736c2fSopenharmony_ci IMSA_HILOGD("start wait."); 75722736c2fSopenharmony_ci session->GetSwitchQueue().Wait(switchInfo); 75822736c2fSopenharmony_ci } 75922736c2fSopenharmony_ci IMSA_HILOGD("start switch %{public}s|%{public}s.", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); 76022736c2fSopenharmony_ci if (isCheckPermission && !IsStartInputTypePermitted(userId)) { 76122736c2fSopenharmony_ci IMSA_HILOGE("not permitted to start input type!"); 76222736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 76322736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 76422736c2fSopenharmony_ci } 76522736c2fSopenharmony_ci if (!IsNeedSwitch(userId, switchInfo.bundleName, switchInfo.subName)) { 76622736c2fSopenharmony_ci IMSA_HILOGI("no need to switch."); 76722736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 76822736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 76922736c2fSopenharmony_ci } 77022736c2fSopenharmony_ci int32_t ret = SwitchInputType(userId, switchInfo); 77122736c2fSopenharmony_ci session->GetSwitchQueue().Pop(); 77222736c2fSopenharmony_ci return ret; 77322736c2fSopenharmony_ci} 77422736c2fSopenharmony_ci 77522736c2fSopenharmony_cibool InputMethodSystemAbility::IsNeedSwitch(int32_t userId, const std::string &bundleName, 77622736c2fSopenharmony_ci const std::string &subName) 77722736c2fSopenharmony_ci{ 77822736c2fSopenharmony_ci if (InputTypeManager::GetInstance().IsStarted()) { 77922736c2fSopenharmony_ci ImeIdentification target = { bundleName, subName }; 78022736c2fSopenharmony_ci return !(target == InputTypeManager::GetInstance().GetCurrentIme()); 78122736c2fSopenharmony_ci } 78222736c2fSopenharmony_ci auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 78322736c2fSopenharmony_ci IMSA_HILOGI("currentIme: %{public}s/%{public}s, targetIme: %{public}s/%{public}s.", 78422736c2fSopenharmony_ci currentImeCfg->bundleName.c_str(), currentImeCfg->subName.c_str(), bundleName.c_str(), subName.c_str()); 78522736c2fSopenharmony_ci if ((subName.empty() && bundleName == currentImeCfg->bundleName) || 78622736c2fSopenharmony_ci (!subName.empty() && subName == currentImeCfg->subName && currentImeCfg->bundleName == bundleName)) { 78722736c2fSopenharmony_ci IMSA_HILOGI("no need to switch."); 78822736c2fSopenharmony_ci return false; 78922736c2fSopenharmony_ci } 79022736c2fSopenharmony_ci return true; 79122736c2fSopenharmony_ci} 79222736c2fSopenharmony_ci 79322736c2fSopenharmony_ciint32_t InputMethodSystemAbility::Switch(int32_t userId, const std::string &bundleName, 79422736c2fSopenharmony_ci const std::shared_ptr<ImeInfo> &info) 79522736c2fSopenharmony_ci{ 79622736c2fSopenharmony_ci auto currentImeBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; 79722736c2fSopenharmony_ci if (bundleName != currentImeBundleName) { 79822736c2fSopenharmony_ci IMSA_HILOGI("switch input method to: %{public}s", bundleName.c_str()); 79922736c2fSopenharmony_ci return SwitchExtension(userId, info); 80022736c2fSopenharmony_ci } 80122736c2fSopenharmony_ci auto currentInputType = InputTypeManager::GetInstance().GetCurrentIme(); 80222736c2fSopenharmony_ci auto isInputTypeStarted = InputTypeManager::GetInstance().IsStarted(); 80322736c2fSopenharmony_ci if (isInputTypeStarted && bundleName != currentInputType.bundleName) { 80422736c2fSopenharmony_ci IMSA_HILOGI("right click on state, switch input method to: %{public}s", bundleName.c_str()); 80522736c2fSopenharmony_ci return SwitchExtension(userId, info); 80622736c2fSopenharmony_ci } 80722736c2fSopenharmony_ci return SwitchSubType(userId, info); 80822736c2fSopenharmony_ci} 80922736c2fSopenharmony_ci 81022736c2fSopenharmony_ci// Switch the current InputMethodExtension to the new InputMethodExtension 81122736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchExtension(int32_t userId, const std::shared_ptr<ImeInfo> &info) 81222736c2fSopenharmony_ci{ 81322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 81422736c2fSopenharmony_ci if (session == nullptr) { 81522736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 81622736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 81722736c2fSopenharmony_ci } 81822736c2fSopenharmony_ci std::string targetImeName = info->prop.name + "/" + info->prop.id; 81922736c2fSopenharmony_ci ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id, false }); 82022736c2fSopenharmony_ci ImeNativeCfg targetIme = { targetImeName, info->prop.name, info->subProp.id, info->prop.id }; 82122736c2fSopenharmony_ci if (!session->StartIme(std::make_shared<ImeNativeCfg>(targetIme))) { 82222736c2fSopenharmony_ci IMSA_HILOGE("start input method failed!"); 82322736c2fSopenharmony_ci return ErrorCode::ERROR_IME_START_FAILED; 82422736c2fSopenharmony_ci } 82522736c2fSopenharmony_ci session->NotifyImeChangeToClients(info->prop, info->subProp); 82622736c2fSopenharmony_ci GetValidSubtype("", info); 82722736c2fSopenharmony_ci session->SwitchSubtype(info->subProp); 82822736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 82922736c2fSopenharmony_ci} 83022736c2fSopenharmony_ci 83122736c2fSopenharmony_ci// Inform current InputMethodExtension to switch subtype 83222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchSubType(int32_t userId, const std::shared_ptr<ImeInfo> &info) 83322736c2fSopenharmony_ci{ 83422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 83522736c2fSopenharmony_ci if (session == nullptr) { 83622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 83722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 83822736c2fSopenharmony_ci } 83922736c2fSopenharmony_ci auto ret = session->SwitchSubtype(info->subProp); 84022736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 84122736c2fSopenharmony_ci IMSA_HILOGE("failed to inform ime to switch subtype, ret: %{public}d!", ret); 84222736c2fSopenharmony_ci return ret; 84322736c2fSopenharmony_ci } 84422736c2fSopenharmony_ci auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->imeId; 84522736c2fSopenharmony_ci ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme, info->subProp.id, false }); 84622736c2fSopenharmony_ci session->NotifyImeChangeToClients(info->prop, info->subProp); 84722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 84822736c2fSopenharmony_ci} 84922736c2fSopenharmony_ci 85022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchInputType(int32_t userId, const SwitchInfo &switchInfo) 85122736c2fSopenharmony_ci{ 85222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 85322736c2fSopenharmony_ci if (session == nullptr) { 85422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 85522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 85622736c2fSopenharmony_ci } 85722736c2fSopenharmony_ci auto targetImeProperty = ImeInfoInquirer::GetInstance().GetImeProperty(userId, switchInfo.bundleName); 85822736c2fSopenharmony_ci if (targetImeProperty == nullptr) { 85922736c2fSopenharmony_ci IMSA_HILOGE("GetImeProperty [%{public}d, %{public}s] failed!", userId, switchInfo.bundleName.c_str()); 86022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 86122736c2fSopenharmony_ci } 86222736c2fSopenharmony_ci std::string targetName = switchInfo.bundleName + "/" + targetImeProperty->id; 86322736c2fSopenharmony_ci ImeNativeCfg targetIme = { targetName, switchInfo.bundleName, switchInfo.subName, targetImeProperty->id }; 86422736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(true, { switchInfo.bundleName, switchInfo.subName }); 86522736c2fSopenharmony_ci if (!session->StartIme(std::make_shared<ImeNativeCfg>(targetIme))) { 86622736c2fSopenharmony_ci IMSA_HILOGE("start input method failed!"); 86722736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 86822736c2fSopenharmony_ci return ErrorCode::ERROR_IME_START_FAILED; 86922736c2fSopenharmony_ci } 87022736c2fSopenharmony_ci int32_t ret = session->SwitchSubtype({ .name = switchInfo.bundleName, .id = switchInfo.subName }); 87122736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 87222736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 87322736c2fSopenharmony_ci IMSA_HILOGE("switch subtype failed!"); 87422736c2fSopenharmony_ci return ret; 87522736c2fSopenharmony_ci } 87622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 87722736c2fSopenharmony_ci} 87822736c2fSopenharmony_ci 87922736c2fSopenharmony_ci// Deprecated because of no permission check, kept for compatibility 88022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::HideCurrentInputDeprecated() 88122736c2fSopenharmony_ci{ 88222736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 88322736c2fSopenharmony_ci int32_t userId = GetCallingUserId(); 88422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 88522736c2fSopenharmony_ci if (session == nullptr) { 88622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 88722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 88822736c2fSopenharmony_ci } 88922736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId)) { 89022736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, session->GetCurrentClientPid())) { 89122736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 89222736c2fSopenharmony_ci } 89322736c2fSopenharmony_ci } 89422736c2fSopenharmony_ci return session->OnHideCurrentInput(); 89522736c2fSopenharmony_ci} 89622736c2fSopenharmony_ci 89722736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ShowCurrentInputDeprecated() 89822736c2fSopenharmony_ci{ 89922736c2fSopenharmony_ci AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); 90022736c2fSopenharmony_ci int32_t userId = GetCallingUserId(); 90122736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 90222736c2fSopenharmony_ci if (session == nullptr) { 90322736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 90422736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 90522736c2fSopenharmony_ci } 90622736c2fSopenharmony_ci if (!identityChecker_->IsBroker(tokenId)) { 90722736c2fSopenharmony_ci if (!identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, session->GetCurrentClientPid())) { 90822736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 90922736c2fSopenharmony_ci } 91022736c2fSopenharmony_ci } 91122736c2fSopenharmony_ci return session->OnShowCurrentInput(); 91222736c2fSopenharmony_ci} 91322736c2fSopenharmony_ci 91422736c2fSopenharmony_cistd::shared_ptr<Property> InputMethodSystemAbility::GetCurrentInputMethod() 91522736c2fSopenharmony_ci{ 91622736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().GetCurrentInputMethod(GetCallingUserId()); 91722736c2fSopenharmony_ci} 91822736c2fSopenharmony_ci 91922736c2fSopenharmony_cibool InputMethodSystemAbility::IsDefaultImeSet() 92022736c2fSopenharmony_ci{ 92122736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().IsDefaultImeSet(GetCallingUserId()); 92222736c2fSopenharmony_ci} 92322736c2fSopenharmony_ci 92422736c2fSopenharmony_cistd::shared_ptr<SubProperty> InputMethodSystemAbility::GetCurrentInputMethodSubtype() 92522736c2fSopenharmony_ci{ 92622736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().GetCurrentSubtype(GetCallingUserId()); 92722736c2fSopenharmony_ci} 92822736c2fSopenharmony_ci 92922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GetDefaultInputMethod(std::shared_ptr<Property> &prop, bool isBrief) 93022736c2fSopenharmony_ci{ 93122736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().GetDefaultInputMethod(GetCallingUserId(), prop, isBrief); 93222736c2fSopenharmony_ci} 93322736c2fSopenharmony_ci 93422736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GetInputMethodConfig(OHOS::AppExecFwk::ElementName &inputMethodConfig) 93522736c2fSopenharmony_ci{ 93622736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().GetInputMethodConfig(GetCallingUserId(), inputMethodConfig); 93722736c2fSopenharmony_ci} 93822736c2fSopenharmony_ci 93922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ListInputMethod(InputMethodStatus status, std::vector<Property> &props) 94022736c2fSopenharmony_ci{ 94122736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().ListInputMethod(GetCallingUserId(), status, props, enableImeOn_.load()); 94222736c2fSopenharmony_ci} 94322736c2fSopenharmony_ci 94422736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ListCurrentInputMethodSubtype(std::vector<SubProperty> &subProps) 94522736c2fSopenharmony_ci{ 94622736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().ListCurrentInputMethodSubtype(GetCallingUserId(), subProps); 94722736c2fSopenharmony_ci} 94822736c2fSopenharmony_ci 94922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ListInputMethodSubtype(const std::string &bundleName, 95022736c2fSopenharmony_ci std::vector<SubProperty> &subProps) 95122736c2fSopenharmony_ci{ 95222736c2fSopenharmony_ci return ImeInfoInquirer::GetInstance().ListInputMethodSubtype(GetCallingUserId(), bundleName, subProps); 95322736c2fSopenharmony_ci} 95422736c2fSopenharmony_ci 95522736c2fSopenharmony_ci/** 95622736c2fSopenharmony_ci * Work Thread of input method management service 95722736c2fSopenharmony_ci * \n Remote commands which may change the state or data in the service will be handled sequentially in this thread. 95822736c2fSopenharmony_ci */ 95922736c2fSopenharmony_civoid InputMethodSystemAbility::WorkThread() 96022736c2fSopenharmony_ci{ 96122736c2fSopenharmony_ci pthread_setname_np(pthread_self(), "OS_IMSAWorkThread"); 96222736c2fSopenharmony_ci while (!stop_) { 96322736c2fSopenharmony_ci Message *msg = MessageHandler::Instance()->GetMessage(); 96422736c2fSopenharmony_ci switch (msg->msgId_) { 96522736c2fSopenharmony_ci case MSG_ID_USER_START: { 96622736c2fSopenharmony_ci OnUserStarted(msg); 96722736c2fSopenharmony_ci break; 96822736c2fSopenharmony_ci } 96922736c2fSopenharmony_ci case MSG_ID_USER_REMOVED: { 97022736c2fSopenharmony_ci OnUserRemoved(msg); 97122736c2fSopenharmony_ci break; 97222736c2fSopenharmony_ci } 97322736c2fSopenharmony_ci case MSG_ID_USER_STOP: { 97422736c2fSopenharmony_ci OnUserStop(msg); 97522736c2fSopenharmony_ci break; 97622736c2fSopenharmony_ci } 97722736c2fSopenharmony_ci case MSG_ID_HIDE_KEYBOARD_SELF: { 97822736c2fSopenharmony_ci OnHideKeyboardSelf(msg); 97922736c2fSopenharmony_ci break; 98022736c2fSopenharmony_ci } 98122736c2fSopenharmony_ci case MSG_ID_BUNDLE_SCAN_FINISHED: { 98222736c2fSopenharmony_ci RegisterDataShareObserver(); 98322736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Init(); 98422736c2fSopenharmony_ci break; 98522736c2fSopenharmony_ci } 98622736c2fSopenharmony_ci case MSG_ID_PACKAGE_ADDED: 98722736c2fSopenharmony_ci case MSG_ID_PACKAGE_CHANGED: 98822736c2fSopenharmony_ci case MSG_ID_PACKAGE_REMOVED: { 98922736c2fSopenharmony_ci HandlePackageEvent(msg); 99022736c2fSopenharmony_ci break; 99122736c2fSopenharmony_ci } 99222736c2fSopenharmony_ci case MSG_ID_SYS_LANGUAGE_CHANGED: { 99322736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Update(); 99422736c2fSopenharmony_ci break; 99522736c2fSopenharmony_ci } 99622736c2fSopenharmony_ci case MSG_ID_BOOT_COMPLETED: 99722736c2fSopenharmony_ci case MSG_ID_OS_ACCOUNT_STARTED: { 99822736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Init(); 99922736c2fSopenharmony_ci break; 100022736c2fSopenharmony_ci } 100122736c2fSopenharmony_ci default: { 100222736c2fSopenharmony_ci IMSA_HILOGD("the message is %{public}d.", msg->msgId_); 100322736c2fSopenharmony_ci break; 100422736c2fSopenharmony_ci } 100522736c2fSopenharmony_ci } 100622736c2fSopenharmony_ci delete msg; 100722736c2fSopenharmony_ci } 100822736c2fSopenharmony_ci} 100922736c2fSopenharmony_ci 101022736c2fSopenharmony_ci/** 101122736c2fSopenharmony_ci * Called when a user is started. (EVENT_USER_STARTED is received) 101222736c2fSopenharmony_ci * \n Run in work thread of input method management service 101322736c2fSopenharmony_ci * \param msg the parameters are saved in msg->msgContent_ 101422736c2fSopenharmony_ci * \return ErrorCode 101522736c2fSopenharmony_ci */ 101622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnUserStarted(const Message *msg) 101722736c2fSopenharmony_ci{ 101822736c2fSopenharmony_ci if (msg->msgContent_ == nullptr) { 101922736c2fSopenharmony_ci IMSA_HILOGE("msgContent_ is nullptr!"); 102022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 102122736c2fSopenharmony_ci } 102222736c2fSopenharmony_ci auto newUserId = msg->msgContent_->ReadInt32(); 102322736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Add(newUserId); 102422736c2fSopenharmony_ci // if scb enable, deal when receive wmsConnected. 102522736c2fSopenharmony_ci if (isScbEnable_.load()) { 102622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 102722736c2fSopenharmony_ci } 102822736c2fSopenharmony_ci if (newUserId == userId_) { 102922736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 103022736c2fSopenharmony_ci } 103122736c2fSopenharmony_ci HandleUserSwitched(newUserId); 103222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 103322736c2fSopenharmony_ci} 103422736c2fSopenharmony_ci 103522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnUserRemoved(const Message *msg) 103622736c2fSopenharmony_ci{ 103722736c2fSopenharmony_ci if (msg == nullptr || msg->msgContent_ == nullptr) { 103822736c2fSopenharmony_ci IMSA_HILOGE("Aborted! Message is nullptr!"); 103922736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 104022736c2fSopenharmony_ci } 104122736c2fSopenharmony_ci auto userId = msg->msgContent_->ReadInt32(); 104222736c2fSopenharmony_ci IMSA_HILOGI("start: %{public}d", userId); 104322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 104422736c2fSopenharmony_ci if (session != nullptr) { 104522736c2fSopenharmony_ci session->StopCurrentIme(); 104622736c2fSopenharmony_ci UserSessionManager::GetInstance().RemoveUserSession(userId); 104722736c2fSopenharmony_ci } 104822736c2fSopenharmony_ci ImeCfgManager::GetInstance().DeleteImeCfg(userId); 104922736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Delete(userId); 105022736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 105122736c2fSopenharmony_ci} 105222736c2fSopenharmony_ci 105322736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnUserStop(const Message *msg) 105422736c2fSopenharmony_ci{ 105522736c2fSopenharmony_ci if (msg == nullptr || msg->msgContent_ == nullptr) { 105622736c2fSopenharmony_ci IMSA_HILOGE("Aborted! Message is nullptr!"); 105722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 105822736c2fSopenharmony_ci } 105922736c2fSopenharmony_ci auto userId = msg->msgContent_->ReadInt32(); 106022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 106122736c2fSopenharmony_ci if (session == nullptr) { 106222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 106322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 106422736c2fSopenharmony_ci } 106522736c2fSopenharmony_ci session->StopCurrentIme(); 106622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 106722736c2fSopenharmony_ci} 106822736c2fSopenharmony_ci 106922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnHideKeyboardSelf(const Message *msg) 107022736c2fSopenharmony_ci{ 107122736c2fSopenharmony_ci if (msg == nullptr || msg->msgContent_ == nullptr) { 107222736c2fSopenharmony_ci IMSA_HILOGE("Aborted! Message is nullptr!"); 107322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 107422736c2fSopenharmony_ci } 107522736c2fSopenharmony_ci auto userId = msg->msgContent_->ReadInt32(); 107622736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 107722736c2fSopenharmony_ci if (session == nullptr) { 107822736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 107922736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 108022736c2fSopenharmony_ci } 108122736c2fSopenharmony_ci session->OnHideSoftKeyBoardSelf(); 108222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 108322736c2fSopenharmony_ci} 108422736c2fSopenharmony_ci 108522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::HandlePackageEvent(const Message *msg) 108622736c2fSopenharmony_ci{ 108722736c2fSopenharmony_ci MessageParcel *data = msg->msgContent_; 108822736c2fSopenharmony_ci if (data == nullptr) { 108922736c2fSopenharmony_ci IMSA_HILOGD("data is nullptr"); 109022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 109122736c2fSopenharmony_ci } 109222736c2fSopenharmony_ci int32_t userId = 0; 109322736c2fSopenharmony_ci std::string packageName; 109422736c2fSopenharmony_ci if (!ITypesUtil::Unmarshal(*data, userId, packageName)) { 109522736c2fSopenharmony_ci IMSA_HILOGE("Failed to read message parcel!"); 109622736c2fSopenharmony_ci return ErrorCode::ERROR_EX_PARCELABLE; 109722736c2fSopenharmony_ci } 109822736c2fSopenharmony_ci if (msg->msgId_ == MSG_ID_PACKAGE_CHANGED) { 109922736c2fSopenharmony_ci return FullImeInfoManager::GetInstance().Update(userId, packageName); 110022736c2fSopenharmony_ci } 110122736c2fSopenharmony_ci if (msg->msgId_ == MSG_ID_PACKAGE_ADDED) { 110222736c2fSopenharmony_ci return FullImeInfoManager::GetInstance().Add(userId, packageName); 110322736c2fSopenharmony_ci } 110422736c2fSopenharmony_ci if (msg->msgId_ == MSG_ID_PACKAGE_REMOVED) { 110522736c2fSopenharmony_ci return OnPackageRemoved(userId, packageName); 110622736c2fSopenharmony_ci } 110722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 110822736c2fSopenharmony_ci} 110922736c2fSopenharmony_ci 111022736c2fSopenharmony_ci/** 111122736c2fSopenharmony_ci * Called when a package is removed. 111222736c2fSopenharmony_ci * \n Run in work thread of input method management service 111322736c2fSopenharmony_ci * \param msg the parameters are saved in msg->msgContent_ 111422736c2fSopenharmony_ci * \return ErrorCode::NO_ERROR 111522736c2fSopenharmony_ci * \return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked 111622736c2fSopenharmony_ci * \return ErrorCode::ERROR_BAD_PARAMETERS bad parameter 111722736c2fSopenharmony_ci */ 111822736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnPackageRemoved(int32_t userId, const std::string &packageName) 111922736c2fSopenharmony_ci{ 112022736c2fSopenharmony_ci FullImeInfoManager::GetInstance().Delete(userId, packageName); 112122736c2fSopenharmony_ci // if the app that doesn't belong to current user is removed, ignore it 112222736c2fSopenharmony_ci if (userId != userId_) { 112322736c2fSopenharmony_ci IMSA_HILOGD("userId: %{public}d, currentUserId: %{public}d.", userId, userId_); 112422736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 112522736c2fSopenharmony_ci } 112622736c2fSopenharmony_ci auto currentImeBundle = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; 112722736c2fSopenharmony_ci if (packageName == currentImeBundle) { 112822736c2fSopenharmony_ci // Switch to the default ime 112922736c2fSopenharmony_ci IMSA_HILOGI("user[%{public}d] ime: %{public}s is uninstalled.", userId, packageName.c_str()); 113022736c2fSopenharmony_ci auto info = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId); 113122736c2fSopenharmony_ci if (info == nullptr) { 113222736c2fSopenharmony_ci return ErrorCode::ERROR_PERSIST_CONFIG; 113322736c2fSopenharmony_ci } 113422736c2fSopenharmony_ci int32_t ret = SwitchExtension(userId, info); 113522736c2fSopenharmony_ci IMSA_HILOGI("switch ret: %{public}d", ret); 113622736c2fSopenharmony_ci } 113722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 113822736c2fSopenharmony_ci} 113922736c2fSopenharmony_ci 114022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::OnDisplayOptionalInputMethod() 114122736c2fSopenharmony_ci{ 114222736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility::OnDisplayOptionalInputMethod start."); 114322736c2fSopenharmony_ci AAFwk::Want want; 114422736c2fSopenharmony_ci want.SetAction(SELECT_DIALOG_ACTION); 114522736c2fSopenharmony_ci want.SetElementName(SELECT_DIALOG_HAP, SELECT_DIALOG_ABILITY); 114622736c2fSopenharmony_ci int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want); 114722736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR && ret != START_SERVICE_ABILITY_ACTIVATING) { 114822736c2fSopenharmony_ci IMSA_HILOGE("start InputMethod ability failed, err: %{public}d", ret); 114922736c2fSopenharmony_ci return ErrorCode::ERROR_EX_SERVICE_SPECIFIC; 115022736c2fSopenharmony_ci } 115122736c2fSopenharmony_ci IMSA_HILOGI("start InputMethod ability success."); 115222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 115322736c2fSopenharmony_ci} 115422736c2fSopenharmony_ci 115522736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchByCombinationKey(uint32_t state) 115622736c2fSopenharmony_ci{ 115722736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility::SwitchByCombinationKey start."); 115822736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 115922736c2fSopenharmony_ci if (session == nullptr) { 116022736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 116122736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 116222736c2fSopenharmony_ci } 116322736c2fSopenharmony_ci if (session->IsProxyImeEnable()) { 116422736c2fSopenharmony_ci IMSA_HILOGI("proxy enable, not switch."); 116522736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 116622736c2fSopenharmony_ci } 116722736c2fSopenharmony_ci if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_MODE, state)) { 116822736c2fSopenharmony_ci IMSA_HILOGI("switch mode."); 116922736c2fSopenharmony_ci return SwitchMode(); 117022736c2fSopenharmony_ci } 117122736c2fSopenharmony_ci if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_LANGUAGE, state)) { 117222736c2fSopenharmony_ci IMSA_HILOGI("switch language."); 117322736c2fSopenharmony_ci return SwitchLanguage(); 117422736c2fSopenharmony_ci } 117522736c2fSopenharmony_ci bool isScreenLocked = false; 117622736c2fSopenharmony_ci#ifdef IMF_SCREENLOCK_MGR_ENABLE 117722736c2fSopenharmony_ci if (ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked()) { 117822736c2fSopenharmony_ci IMSA_HILOGI("isScreenLocked now."); 117922736c2fSopenharmony_ci isScreenLocked = true; 118022736c2fSopenharmony_ci } 118122736c2fSopenharmony_ci#endif 118222736c2fSopenharmony_ci if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_IME, state) && !isScreenLocked) { 118322736c2fSopenharmony_ci IMSA_HILOGI("switch ime."); 118422736c2fSopenharmony_ci DealSwitchRequest(); 118522736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 118622736c2fSopenharmony_ci } 118722736c2fSopenharmony_ci IMSA_HILOGE("keycode is undefined!"); 118822736c2fSopenharmony_ci return ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION; 118922736c2fSopenharmony_ci} 119022736c2fSopenharmony_ci 119122736c2fSopenharmony_civoid InputMethodSystemAbility::DealSecurityChange() 119222736c2fSopenharmony_ci{ 119322736c2fSopenharmony_ci { 119422736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(modeChangeMutex_); 119522736c2fSopenharmony_ci if (isChangeHandling_) { 119622736c2fSopenharmony_ci IMSA_HILOGI("already has mode change task."); 119722736c2fSopenharmony_ci hasPendingChanges_ = true; 119822736c2fSopenharmony_ci return; 119922736c2fSopenharmony_ci } else { 120022736c2fSopenharmony_ci isChangeHandling_ = true; 120122736c2fSopenharmony_ci hasPendingChanges_ = true; 120222736c2fSopenharmony_ci } 120322736c2fSopenharmony_ci } 120422736c2fSopenharmony_ci auto changeTask = [this]() { 120522736c2fSopenharmony_ci pthread_setname_np(pthread_self(), "SecurityChange"); 120622736c2fSopenharmony_ci auto checkChangeCount = [this]() { 120722736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(modeChangeMutex_); 120822736c2fSopenharmony_ci if (hasPendingChanges_) { 120922736c2fSopenharmony_ci return true; 121022736c2fSopenharmony_ci } 121122736c2fSopenharmony_ci isChangeHandling_ = false; 121222736c2fSopenharmony_ci return false; 121322736c2fSopenharmony_ci }; 121422736c2fSopenharmony_ci do { 121522736c2fSopenharmony_ci OnSecurityModeChange(); 121622736c2fSopenharmony_ci } while (checkChangeCount()); 121722736c2fSopenharmony_ci }; 121822736c2fSopenharmony_ci std::thread(changeTask).detach(); 121922736c2fSopenharmony_ci} 122022736c2fSopenharmony_ci 122122736c2fSopenharmony_civoid InputMethodSystemAbility::DealSwitchRequest() 122222736c2fSopenharmony_ci{ 122322736c2fSopenharmony_ci { 122422736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(switchImeMutex_); 122522736c2fSopenharmony_ci // 0 means current swich ime task count. 122622736c2fSopenharmony_ci if (switchTaskExecuting_.load()) { 122722736c2fSopenharmony_ci IMSA_HILOGI("already has switch ime task."); 122822736c2fSopenharmony_ci ++targetSwitchCount_; 122922736c2fSopenharmony_ci return; 123022736c2fSopenharmony_ci } else { 123122736c2fSopenharmony_ci switchTaskExecuting_.store(true); 123222736c2fSopenharmony_ci ++targetSwitchCount_; 123322736c2fSopenharmony_ci } 123422736c2fSopenharmony_ci } 123522736c2fSopenharmony_ci auto switchTask = [this]() { 123622736c2fSopenharmony_ci auto checkSwitchCount = [this]() { 123722736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(switchImeMutex_); 123822736c2fSopenharmony_ci if (targetSwitchCount_ > 0) { 123922736c2fSopenharmony_ci return true; 124022736c2fSopenharmony_ci } 124122736c2fSopenharmony_ci switchTaskExecuting_.store(false); 124222736c2fSopenharmony_ci return false; 124322736c2fSopenharmony_ci }; 124422736c2fSopenharmony_ci do { 124522736c2fSopenharmony_ci SwitchType(); 124622736c2fSopenharmony_ci } while (checkSwitchCount()); 124722736c2fSopenharmony_ci }; 124822736c2fSopenharmony_ci // 0 means delay time is 0. 124922736c2fSopenharmony_ci serviceHandler_->PostTask(switchTask, "SwitchImeTask", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); 125022736c2fSopenharmony_ci} 125122736c2fSopenharmony_ci 125222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchMode() 125322736c2fSopenharmony_ci{ 125422736c2fSopenharmony_ci auto bundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; 125522736c2fSopenharmony_ci auto subName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->subName; 125622736c2fSopenharmony_ci auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName); 125722736c2fSopenharmony_ci if (info == nullptr) { 125822736c2fSopenharmony_ci IMSA_HILOGE("current ime is abnormal!"); 125922736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 126022736c2fSopenharmony_ci } 126122736c2fSopenharmony_ci if (info->isNewIme) { 126222736c2fSopenharmony_ci IMSA_HILOGD("the switching operation is handed over to ime."); 126322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 126422736c2fSopenharmony_ci } 126522736c2fSopenharmony_ci auto condition = info->subProp.mode == "upper" ? Condition::LOWER : Condition::UPPER; 126622736c2fSopenharmony_ci auto target = ImeInfoInquirer::GetInstance().FindTargetSubtypeByCondition(info->subProps, condition); 126722736c2fSopenharmony_ci if (target == nullptr) { 126822736c2fSopenharmony_ci IMSA_HILOGE("target is empty!"); 126922736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 127022736c2fSopenharmony_ci } 127122736c2fSopenharmony_ci SwitchInfo switchInfo = { std::chrono::system_clock::now(), target->name, target->id }; 127222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 127322736c2fSopenharmony_ci if (session == nullptr) { 127422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 127522736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 127622736c2fSopenharmony_ci } 127722736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 127822736c2fSopenharmony_ci return OnSwitchInputMethod(userId_, switchInfo, SwitchTrigger::IMSA); 127922736c2fSopenharmony_ci} 128022736c2fSopenharmony_ci 128122736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchLanguage() 128222736c2fSopenharmony_ci{ 128322736c2fSopenharmony_ci auto bundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; 128422736c2fSopenharmony_ci auto subName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->subName; 128522736c2fSopenharmony_ci auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName); 128622736c2fSopenharmony_ci if (info == nullptr) { 128722736c2fSopenharmony_ci IMSA_HILOGE("current ime is abnormal!"); 128822736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 128922736c2fSopenharmony_ci } 129022736c2fSopenharmony_ci if (info->isNewIme) { 129122736c2fSopenharmony_ci IMSA_HILOGD("the switching operation is handed over to ime."); 129222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 129322736c2fSopenharmony_ci } 129422736c2fSopenharmony_ci if (info->subProp.language != "chinese" && info->subProp.language != "english") { 129522736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 129622736c2fSopenharmony_ci } 129722736c2fSopenharmony_ci auto condition = info->subProp.language == "chinese" ? Condition::ENGLISH : Condition::CHINESE; 129822736c2fSopenharmony_ci auto target = ImeInfoInquirer::GetInstance().FindTargetSubtypeByCondition(info->subProps, condition); 129922736c2fSopenharmony_ci if (target == nullptr) { 130022736c2fSopenharmony_ci IMSA_HILOGE("target is empty!"); 130122736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 130222736c2fSopenharmony_ci } 130322736c2fSopenharmony_ci SwitchInfo switchInfo = { std::chrono::system_clock::now(), target->name, target->id }; 130422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 130522736c2fSopenharmony_ci if (session == nullptr) { 130622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 130722736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 130822736c2fSopenharmony_ci } 130922736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 131022736c2fSopenharmony_ci return OnSwitchInputMethod(userId_, switchInfo, SwitchTrigger::IMSA); 131122736c2fSopenharmony_ci} 131222736c2fSopenharmony_ci 131322736c2fSopenharmony_ciint32_t InputMethodSystemAbility::SwitchType() 131422736c2fSopenharmony_ci{ 131522736c2fSopenharmony_ci SwitchInfo switchInfo = { std::chrono::system_clock::now(), "", "" }; 131622736c2fSopenharmony_ci uint32_t cacheCount = 0; 131722736c2fSopenharmony_ci { 131822736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(switchImeMutex_); 131922736c2fSopenharmony_ci cacheCount = targetSwitchCount_.exchange(0); 132022736c2fSopenharmony_ci } 132122736c2fSopenharmony_ci int32_t ret = 132222736c2fSopenharmony_ci ImeInfoInquirer::GetInstance().GetSwitchInfoBySwitchCount(switchInfo, userId_, enableImeOn_.load(), cacheCount); 132322736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 132422736c2fSopenharmony_ci IMSA_HILOGE("get next SwitchInfo failed, stop switching ime."); 132522736c2fSopenharmony_ci return ret; 132622736c2fSopenharmony_ci } 132722736c2fSopenharmony_ci IMSA_HILOGD("switch to: %{public}s.", switchInfo.bundleName.c_str()); 132822736c2fSopenharmony_ci switchInfo.timestamp = std::chrono::system_clock::now(); 132922736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 133022736c2fSopenharmony_ci if (session == nullptr) { 133122736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 133222736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 133322736c2fSopenharmony_ci } 133422736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 133522736c2fSopenharmony_ci return OnSwitchInputMethod(userId_, switchInfo, SwitchTrigger::IMSA); 133622736c2fSopenharmony_ci} 133722736c2fSopenharmony_ci 133822736c2fSopenharmony_civoid InputMethodSystemAbility::InitMonitors() 133922736c2fSopenharmony_ci{ 134022736c2fSopenharmony_ci int32_t ret = InitAccountMonitor(); 134122736c2fSopenharmony_ci IMSA_HILOGI("init account monitor, ret: %{public}d.", ret); 134222736c2fSopenharmony_ci SubscribeCommonEvent(); 134322736c2fSopenharmony_ci ret = InitMemMgrMonitor(); 134422736c2fSopenharmony_ci IMSA_HILOGI("init MemMgr monitor, ret: %{public}d.", ret); 134522736c2fSopenharmony_ci ret = InitKeyEventMonitor(); 134622736c2fSopenharmony_ci IMSA_HILOGI("init KeyEvent monitor, ret: %{public}d.", ret); 134722736c2fSopenharmony_ci ret = InitWmsMonitor(); 134822736c2fSopenharmony_ci IMSA_HILOGI("init wms monitor, ret: %{public}d.", ret); 134922736c2fSopenharmony_ci InitSystemLanguageMonitor(); 135022736c2fSopenharmony_ci if (ImeInfoInquirer::GetInstance().IsEnableInputMethod()) { 135122736c2fSopenharmony_ci IMSA_HILOGW("Enter enable mode."); 135222736c2fSopenharmony_ci EnableImeDataParser::GetInstance()->Initialize(userId_); 135322736c2fSopenharmony_ci enableImeOn_.store(true); 135422736c2fSopenharmony_ci } 135522736c2fSopenharmony_ci if (ImeInfoInquirer::GetInstance().IsEnableSecurityMode()) { 135622736c2fSopenharmony_ci IMSA_HILOGW("Enter security mode."); 135722736c2fSopenharmony_ci enableSecurityMode_.store(true); 135822736c2fSopenharmony_ci } 135922736c2fSopenharmony_ci RegisterDataShareObserver(); 136022736c2fSopenharmony_ci} 136122736c2fSopenharmony_ci 136222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::RegisterDataShareObserver() 136322736c2fSopenharmony_ci{ 136422736c2fSopenharmony_ci IMSA_HILOGD("start."); 136522736c2fSopenharmony_ci if (ImeInfoInquirer::GetInstance().IsEnableInputMethod()) { 136622736c2fSopenharmony_ci RegisterEnableImeObserver(); 136722736c2fSopenharmony_ci } 136822736c2fSopenharmony_ci if (ImeInfoInquirer::GetInstance().IsEnableSecurityMode()) { 136922736c2fSopenharmony_ci RegisterSecurityModeObserver(); 137022736c2fSopenharmony_ci } 137122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 137222736c2fSopenharmony_ci} 137322736c2fSopenharmony_ci 137422736c2fSopenharmony_ciint32_t InputMethodSystemAbility::InitAccountMonitor() 137522736c2fSopenharmony_ci{ 137622736c2fSopenharmony_ci IMSA_HILOGI("InputMethodSystemAbility::InitAccountMonitor start."); 137722736c2fSopenharmony_ci return ImCommonEventManager::GetInstance()->SubscribeAccountManagerService([this]() { HandleOsAccountStarted(); }); 137822736c2fSopenharmony_ci} 137922736c2fSopenharmony_ci 138022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::InitKeyEventMonitor() 138122736c2fSopenharmony_ci{ 138222736c2fSopenharmony_ci IMSA_HILOGI("InputMethodSystemAbility::InitKeyEventMonitor start."); 138322736c2fSopenharmony_ci bool ret = ImCommonEventManager::GetInstance()->SubscribeKeyboardEvent( 138422736c2fSopenharmony_ci [this](uint32_t keyCode) { return SwitchByCombinationKey(keyCode); }); 138522736c2fSopenharmony_ci return ret ? ErrorCode::NO_ERROR : ErrorCode::ERROR_SERVICE_START_FAILED; 138622736c2fSopenharmony_ci} 138722736c2fSopenharmony_ci 138822736c2fSopenharmony_cibool InputMethodSystemAbility::InitWmsMonitor() 138922736c2fSopenharmony_ci{ 139022736c2fSopenharmony_ci return ImCommonEventManager::GetInstance()->SubscribeWindowManagerService([this]() { HandleWmsStarted(); }); 139122736c2fSopenharmony_ci} 139222736c2fSopenharmony_ci 139322736c2fSopenharmony_cibool InputMethodSystemAbility::InitMemMgrMonitor() 139422736c2fSopenharmony_ci{ 139522736c2fSopenharmony_ci return ImCommonEventManager::GetInstance()->SubscribeMemMgrService([this]() { HandleMemStarted(); }); 139622736c2fSopenharmony_ci} 139722736c2fSopenharmony_ci 139822736c2fSopenharmony_civoid InputMethodSystemAbility::InitWmsConnectionMonitor() 139922736c2fSopenharmony_ci{ 140022736c2fSopenharmony_ci WmsConnectionMonitorManager::GetInstance().RegisterWMSConnectionChangedListener( 140122736c2fSopenharmony_ci [this](bool isConnected, int32_t userId, int32_t screenId) { 140222736c2fSopenharmony_ci isConnected ? HandleWmsConnected(userId, screenId) : HandleWmsDisconnected(userId, screenId); 140322736c2fSopenharmony_ci }); 140422736c2fSopenharmony_ci} 140522736c2fSopenharmony_ci 140622736c2fSopenharmony_civoid InputMethodSystemAbility::InitSystemLanguageMonitor() 140722736c2fSopenharmony_ci{ 140822736c2fSopenharmony_ci SystemLanguageObserver::GetInstance().Watch(); 140922736c2fSopenharmony_ci} 141022736c2fSopenharmony_ci 141122736c2fSopenharmony_civoid InputMethodSystemAbility::InitFocusChangedMonitor() 141222736c2fSopenharmony_ci{ 141322736c2fSopenharmony_ci FocusMonitorManager::GetInstance().RegisterFocusChangedListener( 141422736c2fSopenharmony_ci [this](bool isOnFocused, int32_t pid, int32_t uid) { HandleFocusChanged(isOnFocused, pid, uid); }); 141522736c2fSopenharmony_ci} 141622736c2fSopenharmony_ci 141722736c2fSopenharmony_civoid InputMethodSystemAbility::RegisterEnableImeObserver() 141822736c2fSopenharmony_ci{ 141922736c2fSopenharmony_ci int32_t ret = SettingsDataUtils::GetInstance()->CreateAndRegisterObserver(EnableImeDataParser::ENABLE_IME, 142022736c2fSopenharmony_ci [this]() { DatashareCallback(EnableImeDataParser::ENABLE_IME); }); 142122736c2fSopenharmony_ci IMSA_HILOGI("register enable ime observer, ret: %{public}d.", ret); 142222736c2fSopenharmony_ci ret = SettingsDataUtils::GetInstance()->CreateAndRegisterObserver(EnableImeDataParser::ENABLE_KEYBOARD, 142322736c2fSopenharmony_ci [this]() { DatashareCallback(EnableImeDataParser::ENABLE_KEYBOARD); }); 142422736c2fSopenharmony_ci IMSA_HILOGI("register enable keyboard observer, ret: %{public}d.", ret); 142522736c2fSopenharmony_ci} 142622736c2fSopenharmony_ci 142722736c2fSopenharmony_civoid InputMethodSystemAbility::RegisterSecurityModeObserver() 142822736c2fSopenharmony_ci{ 142922736c2fSopenharmony_ci int32_t ret = SettingsDataUtils::GetInstance()->CreateAndRegisterObserver(SecurityModeParser::SECURITY_MODE, 143022736c2fSopenharmony_ci [this]() { DatashareCallback(SecurityModeParser::SECURITY_MODE); }); 143122736c2fSopenharmony_ci IMSA_HILOGI("register security mode observer, ret: %{public}d", ret); 143222736c2fSopenharmony_ci} 143322736c2fSopenharmony_ci 143422736c2fSopenharmony_civoid InputMethodSystemAbility::DatashareCallback(const std::string &key) 143522736c2fSopenharmony_ci{ 143622736c2fSopenharmony_ci IMSA_HILOGI("start."); 143722736c2fSopenharmony_ci if (key == EnableImeDataParser::ENABLE_KEYBOARD || key == EnableImeDataParser::ENABLE_IME) { 143822736c2fSopenharmony_ci EnableImeDataParser::GetInstance()->OnConfigChanged(userId_, key); 143922736c2fSopenharmony_ci std::lock_guard<std::mutex> autoLock(checkMutex_); 144022736c2fSopenharmony_ci SwitchInfo switchInfo; 144122736c2fSopenharmony_ci if (EnableImeDataParser::GetInstance()->CheckNeedSwitch(key, switchInfo, userId_)) { 144222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 144322736c2fSopenharmony_ci if (session == nullptr) { 144422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 144522736c2fSopenharmony_ci return; 144622736c2fSopenharmony_ci } 144722736c2fSopenharmony_ci switchInfo.timestamp = std::chrono::system_clock::now(); 144822736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 144922736c2fSopenharmony_ci OnSwitchInputMethod(userId_, switchInfo, SwitchTrigger::IMSA); 145022736c2fSopenharmony_ci } 145122736c2fSopenharmony_ci } 145222736c2fSopenharmony_ci if (key == SecurityModeParser::SECURITY_MODE) { 145322736c2fSopenharmony_ci DealSecurityChange(); 145422736c2fSopenharmony_ci } 145522736c2fSopenharmony_ci} 145622736c2fSopenharmony_ci 145722736c2fSopenharmony_civoid InputMethodSystemAbility::OnSecurityModeChange() 145822736c2fSopenharmony_ci{ 145922736c2fSopenharmony_ci { 146022736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(modeChangeMutex_); 146122736c2fSopenharmony_ci hasPendingChanges_ = false; 146222736c2fSopenharmony_ci } 146322736c2fSopenharmony_ci auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 146422736c2fSopenharmony_ci auto oldMode = SecurityModeParser::GetInstance()->GetSecurityMode(currentIme->bundleName, userId_); 146522736c2fSopenharmony_ci SecurityModeParser::GetInstance()->UpdateFullModeList(userId_); 146622736c2fSopenharmony_ci auto newMode = SecurityModeParser::GetInstance()->GetSecurityMode(currentIme->bundleName, userId_); 146722736c2fSopenharmony_ci if (oldMode == newMode) { 146822736c2fSopenharmony_ci IMSA_HILOGD("current ime mode not changed."); 146922736c2fSopenharmony_ci return; 147022736c2fSopenharmony_ci } 147122736c2fSopenharmony_ci IMSA_HILOGI("ime: %{public}s securityMode change to: %{public}d.", currentIme->bundleName.c_str(), 147222736c2fSopenharmony_ci static_cast<int32_t>(newMode)); 147322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 147422736c2fSopenharmony_ci if (session == nullptr) { 147522736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 147622736c2fSopenharmony_ci return; 147722736c2fSopenharmony_ci } 147822736c2fSopenharmony_ci session->OnSecurityChange(static_cast<int32_t>(newMode)); 147922736c2fSopenharmony_ci session->AddRestartIme(); 148022736c2fSopenharmony_ci} 148122736c2fSopenharmony_ci 148222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GetSecurityMode(int32_t &security) 148322736c2fSopenharmony_ci{ 148422736c2fSopenharmony_ci IMSA_HILOGD("InputMethodSystemAbility start."); 148522736c2fSopenharmony_ci if (!enableSecurityMode_.load()) { 148622736c2fSopenharmony_ci security = static_cast<int32_t>(SecurityMode::FULL); 148722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 148822736c2fSopenharmony_ci } 148922736c2fSopenharmony_ci auto userId = GetCallingUserId(); 149022736c2fSopenharmony_ci auto bundleName = FullImeInfoManager::GetInstance().Get(userId, IPCSkeleton::GetCallingTokenID()); 149122736c2fSopenharmony_ci if (bundleName.empty()) { 149222736c2fSopenharmony_ci bundleName = identityChecker_->GetBundleNameByToken(IPCSkeleton::GetCallingTokenID()); 149322736c2fSopenharmony_ci IMSA_HILOGW("%{public}s tokenId not find.", bundleName.c_str()); 149422736c2fSopenharmony_ci } 149522736c2fSopenharmony_ci SecurityMode mode = SecurityModeParser::GetInstance()->GetSecurityMode(bundleName, userId); 149622736c2fSopenharmony_ci security = static_cast<int32_t>(mode); 149722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 149822736c2fSopenharmony_ci} 149922736c2fSopenharmony_ci 150022736c2fSopenharmony_ciint32_t InputMethodSystemAbility::UnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core) 150122736c2fSopenharmony_ci{ 150222736c2fSopenharmony_ci if (!identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { 150322736c2fSopenharmony_ci IMSA_HILOGE("not native sa!"); 150422736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 150522736c2fSopenharmony_ci } 150622736c2fSopenharmony_ci auto userId = GetCallingUserId(); 150722736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 150822736c2fSopenharmony_ci if (session == nullptr) { 150922736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 151022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 151122736c2fSopenharmony_ci } 151222736c2fSopenharmony_ci if (type == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) { 151322736c2fSopenharmony_ci int32_t ret = ErrorCode::NO_ERROR; 151422736c2fSopenharmony_ci if (session->CheckSecurityMode()) { 151522736c2fSopenharmony_ci ret = StartInputType(userId, InputType::SECURITY_INPUT); 151622736c2fSopenharmony_ci } else { 151722736c2fSopenharmony_ci ret = session->RestoreCurrentIme(); 151822736c2fSopenharmony_ci } 151922736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 152022736c2fSopenharmony_ci return ret; 152122736c2fSopenharmony_ci } 152222736c2fSopenharmony_ci } 152322736c2fSopenharmony_ci return session->OnUnRegisteredProxyIme(type, core); 152422736c2fSopenharmony_ci} 152522736c2fSopenharmony_ci 152622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::CheckEnableAndSwitchPermission() 152722736c2fSopenharmony_ci{ 152822736c2fSopenharmony_ci if (!identityChecker_->IsNativeSa(IPCSkeleton::GetCallingFullTokenID())) { 152922736c2fSopenharmony_ci IMSA_HILOGE("not native sa!"); 153022736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; 153122736c2fSopenharmony_ci } 153222736c2fSopenharmony_ci if (!identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY)) { 153322736c2fSopenharmony_ci IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); 153422736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 153522736c2fSopenharmony_ci } 153622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 153722736c2fSopenharmony_ci} 153822736c2fSopenharmony_ci 153922736c2fSopenharmony_ciint32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const SwitchInfo &switchInfo, 154022736c2fSopenharmony_ci SwitchTrigger trigger) 154122736c2fSopenharmony_ci{ 154222736c2fSopenharmony_ci IMSA_HILOGD("trigger: %{public}d.", static_cast<int32_t>(trigger)); 154322736c2fSopenharmony_ci if (trigger == SwitchTrigger::IMSA) { 154422736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 154522736c2fSopenharmony_ci } 154622736c2fSopenharmony_ci if (trigger == SwitchTrigger::NATIVE_SA) { 154722736c2fSopenharmony_ci return CheckEnableAndSwitchPermission(); 154822736c2fSopenharmony_ci } 154922736c2fSopenharmony_ci if (trigger == SwitchTrigger::SYSTEM_APP) { 155022736c2fSopenharmony_ci if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID())) { 155122736c2fSopenharmony_ci IMSA_HILOGE("not system app!"); 155222736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; 155322736c2fSopenharmony_ci } 155422736c2fSopenharmony_ci if (!identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY)) { 155522736c2fSopenharmony_ci IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); 155622736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 155722736c2fSopenharmony_ci } 155822736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 155922736c2fSopenharmony_ci } 156022736c2fSopenharmony_ci if (trigger == SwitchTrigger::CURRENT_IME) { 156122736c2fSopenharmony_ci // PERMISSION_CONNECT_IME_ABILITY check temporarily reserved for application adaptation, will be deleted soon 156222736c2fSopenharmony_ci if (identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), PERMISSION_CONNECT_IME_ABILITY)) { 156322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 156422736c2fSopenharmony_ci } 156522736c2fSopenharmony_ci IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); 156622736c2fSopenharmony_ci // switchInfo.subName.empty() check temporarily reserved for application adaptation, will be deleted soon 156722736c2fSopenharmony_ci auto currentBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; 156822736c2fSopenharmony_ci if (identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentBundleName) && 156922736c2fSopenharmony_ci !switchInfo.subName.empty()) { 157022736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 157122736c2fSopenharmony_ci } 157222736c2fSopenharmony_ci IMSA_HILOGE("not current ime!"); 157322736c2fSopenharmony_ci /* return ErrorCode::ERROR_STATUS_PERMISSION_DENIED temporarily reserved for application adaptation, 157422736c2fSopenharmony_ci will be replaced by ERROR_NOT_CURRENT_IME soon */ 157522736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; 157622736c2fSopenharmony_ci } 157722736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 157822736c2fSopenharmony_ci} 157922736c2fSopenharmony_ci 158022736c2fSopenharmony_cibool InputMethodSystemAbility::IsStartInputTypePermitted(int32_t userId) 158122736c2fSopenharmony_ci{ 158222736c2fSopenharmony_ci auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeInfo(userId); 158322736c2fSopenharmony_ci if (defaultIme == nullptr) { 158422736c2fSopenharmony_ci IMSA_HILOGE("failed to get default ime!"); 158522736c2fSopenharmony_ci return false; 158622736c2fSopenharmony_ci } 158722736c2fSopenharmony_ci auto tokenId = IPCSkeleton::GetCallingTokenID(); 158822736c2fSopenharmony_ci if (identityChecker_->IsBundleNameValid(tokenId, defaultIme->prop.name)) { 158922736c2fSopenharmony_ci return true; 159022736c2fSopenharmony_ci } 159122736c2fSopenharmony_ci if (identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 159222736c2fSopenharmony_ci return true; 159322736c2fSopenharmony_ci } 159422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 159522736c2fSopenharmony_ci if (session == nullptr) { 159622736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 159722736c2fSopenharmony_ci return false; 159822736c2fSopenharmony_ci } 159922736c2fSopenharmony_ci return identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId) && session->IsBoundToClient(); 160022736c2fSopenharmony_ci} 160122736c2fSopenharmony_ci 160222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::ConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent) 160322736c2fSopenharmony_ci{ 160422736c2fSopenharmony_ci auto tokenId = IPCSkeleton::GetCallingTokenID(); 160522736c2fSopenharmony_ci if (!identityChecker_->HasPermission(tokenId, PERMISSION_CONNECT_IME_ABILITY)) { 160622736c2fSopenharmony_ci IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); 160722736c2fSopenharmony_ci return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; 160822736c2fSopenharmony_ci } 160922736c2fSopenharmony_ci auto userId = GetCallingUserId(); 161022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 161122736c2fSopenharmony_ci if (session == nullptr) { 161222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 161322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 161422736c2fSopenharmony_ci } 161522736c2fSopenharmony_ci return session->OnConnectSystemCmd(channel, agent); 161622736c2fSopenharmony_ci} 161722736c2fSopenharmony_ci 161822736c2fSopenharmony_civoid InputMethodSystemAbility::HandleWmsConnected(int32_t userId, int32_t screenId) 161922736c2fSopenharmony_ci{ 162022736c2fSopenharmony_ci if (userId == userId_) { 162122736c2fSopenharmony_ci // device boot or scb in foreground reboot 162222736c2fSopenharmony_ci HandleScbStarted(userId, screenId); 162322736c2fSopenharmony_ci return; 162422736c2fSopenharmony_ci } 162522736c2fSopenharmony_ci // user switched 162622736c2fSopenharmony_ci HandleUserSwitched(userId); 162722736c2fSopenharmony_ci} 162822736c2fSopenharmony_ci 162922736c2fSopenharmony_civoid InputMethodSystemAbility::HandleScbStarted(int32_t userId, int32_t screenId) 163022736c2fSopenharmony_ci{ 163122736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 163222736c2fSopenharmony_ci if (session == nullptr) { 163322736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId); 163422736c2fSopenharmony_ci } 163522736c2fSopenharmony_ci session = UserSessionManager::GetInstance().GetUserSession(userId); 163622736c2fSopenharmony_ci if (session == nullptr) { 163722736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 163822736c2fSopenharmony_ci return; 163922736c2fSopenharmony_ci } 164022736c2fSopenharmony_ci session->AddRestartIme(); 164122736c2fSopenharmony_ci} 164222736c2fSopenharmony_ci 164322736c2fSopenharmony_civoid InputMethodSystemAbility::HandleUserSwitched(int32_t userId) 164422736c2fSopenharmony_ci{ 164522736c2fSopenharmony_ci UpdateUserInfo(userId); 164622736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 164722736c2fSopenharmony_ci if (session == nullptr) { 164822736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId); 164922736c2fSopenharmony_ci } 165022736c2fSopenharmony_ci session = UserSessionManager::GetInstance().GetUserSession(userId); 165122736c2fSopenharmony_ci if (session == nullptr) { 165222736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 165322736c2fSopenharmony_ci return; 165422736c2fSopenharmony_ci } 165522736c2fSopenharmony_ci auto imeData = session->GetReadyImeData(ImeType::IME); 165622736c2fSopenharmony_ci if (imeData == nullptr && session->IsWmsReady()) { 165722736c2fSopenharmony_ci session->StartCurrentIme(); 165822736c2fSopenharmony_ci } 165922736c2fSopenharmony_ci} 166022736c2fSopenharmony_ci 166122736c2fSopenharmony_civoid InputMethodSystemAbility::HandleWmsDisconnected(int32_t userId, int32_t screenId) 166222736c2fSopenharmony_ci{ 166322736c2fSopenharmony_ci // clear client 166422736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 166522736c2fSopenharmony_ci if (session != nullptr) { 166622736c2fSopenharmony_ci session->RemoveCurrentClient(); 166722736c2fSopenharmony_ci } 166822736c2fSopenharmony_ci 166922736c2fSopenharmony_ci if (userId == userId_) { 167022736c2fSopenharmony_ci // user switched or scb in foreground died, not deal 167122736c2fSopenharmony_ci return; 167222736c2fSopenharmony_ci } 167322736c2fSopenharmony_ci // scb in background died, stop ime 167422736c2fSopenharmony_ci if (session == nullptr) { 167522736c2fSopenharmony_ci return; 167622736c2fSopenharmony_ci } 167722736c2fSopenharmony_ci session->StopCurrentIme(); 167822736c2fSopenharmony_ci} 167922736c2fSopenharmony_ci 168022736c2fSopenharmony_civoid InputMethodSystemAbility::HandleWmsStarted() 168122736c2fSopenharmony_ci{ 168222736c2fSopenharmony_ci // singleton, device boot, wms reboot 168322736c2fSopenharmony_ci IMSA_HILOGI("Wms start."); 168422736c2fSopenharmony_ci InitFocusChangedMonitor(); 168522736c2fSopenharmony_ci if (isScbEnable_.load()) { 168622736c2fSopenharmony_ci IMSA_HILOGI("scb enable, register WMS connection listener."); 168722736c2fSopenharmony_ci InitWmsConnectionMonitor(); 168822736c2fSopenharmony_ci return; 168922736c2fSopenharmony_ci } 169022736c2fSopenharmony_ci // clear client 169122736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 169222736c2fSopenharmony_ci if (session != nullptr) { 169322736c2fSopenharmony_ci session->RemoveCurrentClient(); 169422736c2fSopenharmony_ci } 169522736c2fSopenharmony_ci if (session == nullptr) { 169622736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId_); 169722736c2fSopenharmony_ci } 169822736c2fSopenharmony_ci session = UserSessionManager::GetInstance().GetUserSession(userId_); 169922736c2fSopenharmony_ci if (session == nullptr) { 170022736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 170122736c2fSopenharmony_ci return; 170222736c2fSopenharmony_ci } 170322736c2fSopenharmony_ci session->AddRestartIme(); 170422736c2fSopenharmony_ci StopImeInBackground(); 170522736c2fSopenharmony_ci} 170622736c2fSopenharmony_ci 170722736c2fSopenharmony_civoid InputMethodSystemAbility::HandleFocusChanged(bool isFocused, int32_t pid, int32_t uid) 170822736c2fSopenharmony_ci{ 170922736c2fSopenharmony_ci int32_t userId = GetUserId(uid); 171022736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 171122736c2fSopenharmony_ci if (session == nullptr) { 171222736c2fSopenharmony_ci IMSA_HILOGE("[%{public}d, %{public}d] session is nullptr!", uid, userId); 171322736c2fSopenharmony_ci return; 171422736c2fSopenharmony_ci } 171522736c2fSopenharmony_ci isFocused ? session->OnFocused(pid, uid) : session->OnUnfocused(pid, uid); 171622736c2fSopenharmony_ci} 171722736c2fSopenharmony_ci 171822736c2fSopenharmony_civoid InputMethodSystemAbility::HandleMemStarted() 171922736c2fSopenharmony_ci{ 172022736c2fSopenharmony_ci // singleton 172122736c2fSopenharmony_ci IMSA_HILOGI("MemMgr start."); 172222736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 1, INPUT_METHOD_SYSTEM_ABILITY_ID); 172322736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId_); 172422736c2fSopenharmony_ci if (session == nullptr) { 172522736c2fSopenharmony_ci UserSessionManager::GetInstance().AddUserSession(userId_); 172622736c2fSopenharmony_ci } 172722736c2fSopenharmony_ci session = UserSessionManager::GetInstance().GetUserSession(userId_); 172822736c2fSopenharmony_ci if (session == nullptr) { 172922736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId_); 173022736c2fSopenharmony_ci return; 173122736c2fSopenharmony_ci } 173222736c2fSopenharmony_ci session->AddRestartIme(); 173322736c2fSopenharmony_ci StopImeInBackground(); 173422736c2fSopenharmony_ci} 173522736c2fSopenharmony_ci 173622736c2fSopenharmony_civoid InputMethodSystemAbility::HandleOsAccountStarted() 173722736c2fSopenharmony_ci{ 173822736c2fSopenharmony_ci auto userId = OsAccountAdapter::GetForegroundOsAccountLocalId(); 173922736c2fSopenharmony_ci if (userId_ != userId) { 174022736c2fSopenharmony_ci UpdateUserInfo(userId); 174122736c2fSopenharmony_ci } 174222736c2fSopenharmony_ci Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_OS_ACCOUNT_STARTED, nullptr); 174322736c2fSopenharmony_ci if (msg == nullptr) { 174422736c2fSopenharmony_ci return; 174522736c2fSopenharmony_ci } 174622736c2fSopenharmony_ci MessageHandler::Instance()->SendMessage(msg); 174722736c2fSopenharmony_ci} 174822736c2fSopenharmony_ci 174922736c2fSopenharmony_civoid InputMethodSystemAbility::StopImeInBackground() 175022736c2fSopenharmony_ci{ 175122736c2fSopenharmony_ci auto task = [this]() { 175222736c2fSopenharmony_ci auto sessions = UserSessionManager::GetInstance().GetUserSessions(); 175322736c2fSopenharmony_ci for (const auto &tempSession : sessions) { 175422736c2fSopenharmony_ci if (tempSession.first != userId_) { 175522736c2fSopenharmony_ci tempSession.second->StopCurrentIme(); 175622736c2fSopenharmony_ci } 175722736c2fSopenharmony_ci } 175822736c2fSopenharmony_ci }; 175922736c2fSopenharmony_ci serviceHandler_->PostTask(task, "StopImeInBackground", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); 176022736c2fSopenharmony_ci} 176122736c2fSopenharmony_ci 176222736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GetUserId(int32_t uid) 176322736c2fSopenharmony_ci{ 176422736c2fSopenharmony_ci IMSA_HILOGD("uid:%{public}d", uid); 176522736c2fSopenharmony_ci auto userId = OsAccountAdapter::GetOsAccountLocalIdFromUid(uid); 176622736c2fSopenharmony_ci // 0 represents user 0 in the system 176722736c2fSopenharmony_ci if (userId == 0) { 176822736c2fSopenharmony_ci IMSA_HILOGI("user 0"); 176922736c2fSopenharmony_ci return userId_; 177022736c2fSopenharmony_ci } 177122736c2fSopenharmony_ci return userId; 177222736c2fSopenharmony_ci} 177322736c2fSopenharmony_ci 177422736c2fSopenharmony_ciint32_t InputMethodSystemAbility::GetCallingUserId() 177522736c2fSopenharmony_ci{ 177622736c2fSopenharmony_ci auto uid = IPCSkeleton::GetCallingUid(); 177722736c2fSopenharmony_ci return GetUserId(uid); 177822736c2fSopenharmony_ci} 177922736c2fSopenharmony_ci 178022736c2fSopenharmony_cibool InputMethodSystemAbility::IsCurrentIme(int32_t userId) 178122736c2fSopenharmony_ci{ 178222736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 178322736c2fSopenharmony_ci if (session == nullptr) { 178422736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 178522736c2fSopenharmony_ci return false; 178622736c2fSopenharmony_ci } 178722736c2fSopenharmony_ci auto bundleName = FullImeInfoManager::GetInstance().Get(userId, IPCSkeleton::GetCallingTokenID()); 178822736c2fSopenharmony_ci if (bundleName.empty()) { 178922736c2fSopenharmony_ci IMSA_HILOGW("user:%{public}d tokenId:%{public}d not find.", userId, IPCSkeleton::GetCallingTokenID()); 179022736c2fSopenharmony_ci bundleName = identityChecker_->GetBundleNameByToken(IPCSkeleton::GetCallingTokenID()); 179122736c2fSopenharmony_ci } 179222736c2fSopenharmony_ci auto imeData = session->GetImeData(ImeType::IME); 179322736c2fSopenharmony_ci return imeData != nullptr && bundleName == imeData->ime.first; 179422736c2fSopenharmony_ci} 179522736c2fSopenharmony_ci 179622736c2fSopenharmony_ciint32_t InputMethodSystemAbility::StartInputType(int32_t userId, InputType type) 179722736c2fSopenharmony_ci{ 179822736c2fSopenharmony_ci auto session = UserSessionManager::GetInstance().GetUserSession(userId); 179922736c2fSopenharmony_ci if (session == nullptr) { 180022736c2fSopenharmony_ci IMSA_HILOGE("%{public}d session is nullptr!", userId); 180122736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 180222736c2fSopenharmony_ci } 180322736c2fSopenharmony_ci ImeIdentification ime; 180422736c2fSopenharmony_ci int32_t ret = InputTypeManager::GetInstance().GetImeByInputType(type, ime); 180522736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 180622736c2fSopenharmony_ci IMSA_HILOGW("not find input type: %{public}d.", type); 180722736c2fSopenharmony_ci // add for not adapter for SECURITY_INPUT 180822736c2fSopenharmony_ci if (type == InputType::SECURITY_INPUT) { 180922736c2fSopenharmony_ci return session->RestoreCurrentIme(); 181022736c2fSopenharmony_ci } 181122736c2fSopenharmony_ci return ret; 181222736c2fSopenharmony_ci } 181322736c2fSopenharmony_ci SwitchInfo switchInfo = { std::chrono::system_clock::now(), ime.bundleName, ime.subName }; 181422736c2fSopenharmony_ci session->GetSwitchQueue().Push(switchInfo); 181522736c2fSopenharmony_ci IMSA_HILOGI("start input type: %{public}d.", type); 181622736c2fSopenharmony_ci return type == InputType::SECURITY_INPUT ? OnStartInputType(userId, switchInfo, false) 181722736c2fSopenharmony_ci : OnStartInputType(userId, switchInfo, true); 181822736c2fSopenharmony_ci} 181922736c2fSopenharmony_ci 182022736c2fSopenharmony_civoid InputMethodSystemAbility::NeedHideWhenSwitchInputType(int32_t userId, bool &needHide) 182122736c2fSopenharmony_ci{ 182222736c2fSopenharmony_ci ImeIdentification ime; 182322736c2fSopenharmony_ci InputTypeManager::GetInstance().GetImeByInputType(InputType::SECURITY_INPUT, ime); 182422736c2fSopenharmony_ci auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); 182522736c2fSopenharmony_ci if (currentImeCfg == nullptr) { 182622736c2fSopenharmony_ci IMSA_HILOGI("currentImeCfg is nullptr"); 182722736c2fSopenharmony_ci return; 182822736c2fSopenharmony_ci } 182922736c2fSopenharmony_ci needHide = currentImeCfg->bundleName == ime.bundleName; 183022736c2fSopenharmony_ci} 183122736c2fSopenharmony_ci} // namespace MiscServices 183222736c2fSopenharmony_ci} // namespace OHOS