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 "peruser_session.h" 1722736c2fSopenharmony_ci 1822736c2fSopenharmony_ci#include <chrono> 1922736c2fSopenharmony_ci#include <vector> 2022736c2fSopenharmony_ci 2122736c2fSopenharmony_ci#include "ability_manager_client.h" 2222736c2fSopenharmony_ci#include "app_mgr_client.h" 2322736c2fSopenharmony_ci#include "element_name.h" 2422736c2fSopenharmony_ci#include "identity_checker_impl.h" 2522736c2fSopenharmony_ci#include "ime_cfg_manager.h" 2622736c2fSopenharmony_ci#include "ime_connection.h" 2722736c2fSopenharmony_ci#include "ime_info_inquirer.h" 2822736c2fSopenharmony_ci#include "input_control_channel_stub.h" 2922736c2fSopenharmony_ci#include "input_type_manager.h" 3022736c2fSopenharmony_ci#include "ipc_skeleton.h" 3122736c2fSopenharmony_ci#include "iservice_registry.h" 3222736c2fSopenharmony_ci#include "mem_mgr_client.h" 3322736c2fSopenharmony_ci#include "message_parcel.h" 3422736c2fSopenharmony_ci#include "os_account_adapter.h" 3522736c2fSopenharmony_ci#include "parcel.h" 3622736c2fSopenharmony_ci#include "running_process_info.h" 3722736c2fSopenharmony_ci#include "scene_board_judgement.h" 3822736c2fSopenharmony_ci#include "security_mode_parser.h" 3922736c2fSopenharmony_ci#include "system_ability_definition.h" 4022736c2fSopenharmony_ci#include "unistd.h" 4122736c2fSopenharmony_ci#include "wms_connection_observer.h" 4222736c2fSopenharmony_ci 4322736c2fSopenharmony_cinamespace OHOS { 4422736c2fSopenharmony_cinamespace MiscServices { 4522736c2fSopenharmony_ciusing namespace std::chrono; 4622736c2fSopenharmony_ciusing namespace MessageID; 4722736c2fSopenharmony_ciusing namespace OHOS::AppExecFwk; 4822736c2fSopenharmony_ciconstexpr int64_t INVALID_PID = -1; 4922736c2fSopenharmony_ciconstexpr uint32_t STOP_IME_TIME = 600; 5022736c2fSopenharmony_ciconstexpr const char *STRICT_MODE = "strictMode"; 5122736c2fSopenharmony_ciconstexpr const char *ISOLATED_SANDBOX = "isolatedSandbox"; 5222736c2fSopenharmony_ciconstexpr uint32_t CHECK_IME_RUNNING_RETRY_INTERVAL = 60; 5322736c2fSopenharmony_ciconstexpr uint32_t CHECK_IME_RUNNING_RETRY_TIMES = 10; 5422736c2fSopenharmony_ciPerUserSession::PerUserSession(int userId) : userId_(userId) 5522736c2fSopenharmony_ci{ 5622736c2fSopenharmony_ci} 5722736c2fSopenharmony_ci 5822736c2fSopenharmony_ciPerUserSession::PerUserSession(int32_t userId, const std::shared_ptr<AppExecFwk::EventHandler> &eventHandler) 5922736c2fSopenharmony_ci : userId_(userId), eventHandler_(eventHandler) 6022736c2fSopenharmony_ci{ 6122736c2fSopenharmony_ci auto bundleNames = ImeInfoInquirer::GetInstance().GetRunningIme(userId_); 6222736c2fSopenharmony_ci if (!bundleNames.empty()) { 6322736c2fSopenharmony_ci runningIme_ = bundleNames[0]; // one user only has one ime at present 6422736c2fSopenharmony_ci } 6522736c2fSopenharmony_ci} 6622736c2fSopenharmony_ci 6722736c2fSopenharmony_ciPerUserSession::~PerUserSession() 6822736c2fSopenharmony_ci{ 6922736c2fSopenharmony_ci} 7022736c2fSopenharmony_ci 7122736c2fSopenharmony_ciint PerUserSession::AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo, 7222736c2fSopenharmony_ci ClientAddEvent event) 7322736c2fSopenharmony_ci{ 7422736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession start."); 7522736c2fSopenharmony_ci auto cacheInfo = GetClientInfo(inputClient); 7622736c2fSopenharmony_ci if (cacheInfo != nullptr) { 7722736c2fSopenharmony_ci IMSA_HILOGD("info is existed."); 7822736c2fSopenharmony_ci if (cacheInfo->uiExtensionTokenId == IMF_INVALID_TOKENID && 7922736c2fSopenharmony_ci clientInfo.uiExtensionTokenId != IMF_INVALID_TOKENID) { 8022736c2fSopenharmony_ci UpdateClientInfo(inputClient, { { UpdateFlag::UIEXTENSION_TOKENID, clientInfo.uiExtensionTokenId } }); 8122736c2fSopenharmony_ci } 8222736c2fSopenharmony_ci UpdateClientInfo(inputClient, { { UpdateFlag::TEXT_CONFIG, clientInfo.config } }); 8322736c2fSopenharmony_ci if (event == START_LISTENING) { 8422736c2fSopenharmony_ci UpdateClientInfo(inputClient, { { UpdateFlag::EVENTFLAG, clientInfo.eventFlag } }); 8522736c2fSopenharmony_ci } 8622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 8722736c2fSopenharmony_ci } 8822736c2fSopenharmony_ci auto info = std::make_shared<InputClientInfo>(clientInfo); 8922736c2fSopenharmony_ci std::weak_ptr<InputClientInfo> weakClientInfo = info; 9022736c2fSopenharmony_ci info->deathRecipient->SetDeathRecipient([this, weakClientInfo](const wptr<IRemoteObject> &) { 9122736c2fSopenharmony_ci auto clientInfo = weakClientInfo.lock(); 9222736c2fSopenharmony_ci if (clientInfo == nullptr) { 9322736c2fSopenharmony_ci IMSA_HILOGD("clientInfo is nullptr."); 9422736c2fSopenharmony_ci return; 9522736c2fSopenharmony_ci } 9622736c2fSopenharmony_ci this->OnClientDied(clientInfo->client); 9722736c2fSopenharmony_ci }); 9822736c2fSopenharmony_ci auto obj = info->client->AsObject(); 9922736c2fSopenharmony_ci if (obj == nullptr) { 10022736c2fSopenharmony_ci IMSA_HILOGE("client obj is nullptr!"); 10122736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 10222736c2fSopenharmony_ci } 10322736c2fSopenharmony_ci if (obj->IsProxyObject() && !obj->AddDeathRecipient(info->deathRecipient)) { 10422736c2fSopenharmony_ci IMSA_HILOGE("failed to add client death recipient!"); 10522736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_ADD_FAILED; 10622736c2fSopenharmony_ci } 10722736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 10822736c2fSopenharmony_ci mapClients_.insert({ inputClient, info }); 10922736c2fSopenharmony_ci IMSA_HILOGI("add client end."); 11022736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 11122736c2fSopenharmony_ci} 11222736c2fSopenharmony_ci 11322736c2fSopenharmony_civoid PerUserSession::RemoveClientInfo(const sptr<IRemoteObject> &client, bool isClientDied) 11422736c2fSopenharmony_ci{ 11522736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 11622736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client); 11722736c2fSopenharmony_ci if (clientInfo == nullptr) { 11822736c2fSopenharmony_ci IMSA_HILOGD("client already removed."); 11922736c2fSopenharmony_ci return; 12022736c2fSopenharmony_ci } 12122736c2fSopenharmony_ci // if client is subscriber and the release is not because of the client died, do not remove 12222736c2fSopenharmony_ci if (clientInfo->eventFlag != NO_EVENT_ON && !isClientDied) { 12322736c2fSopenharmony_ci IMSA_HILOGD("is subscriber, do not remove."); 12422736c2fSopenharmony_ci auto isShowKeyboard = false; 12522736c2fSopenharmony_ci auto bindImeType = ImeType::NONE; 12622736c2fSopenharmony_ci UpdateClientInfo(client, 12722736c2fSopenharmony_ci { { UpdateFlag::BINDIMETYPE, bindImeType }, { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); 12822736c2fSopenharmony_ci return; 12922736c2fSopenharmony_ci } 13022736c2fSopenharmony_ci if (clientInfo->deathRecipient != nullptr) { 13122736c2fSopenharmony_ci IMSA_HILOGD("deathRecipient remove."); 13222736c2fSopenharmony_ci client->RemoveDeathRecipient(clientInfo->deathRecipient); 13322736c2fSopenharmony_ci } 13422736c2fSopenharmony_ci mapClients_.erase(client); 13522736c2fSopenharmony_ci IMSA_HILOGI("client[%{public}d] is removed.", clientInfo->pid); 13622736c2fSopenharmony_ci} 13722736c2fSopenharmony_ci 13822736c2fSopenharmony_civoid PerUserSession::UpdateClientInfo(const sptr<IRemoteObject> &client, const std::unordered_map<UpdateFlag, 13922736c2fSopenharmony_ci std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig>> &updateInfos) 14022736c2fSopenharmony_ci{ 14122736c2fSopenharmony_ci if (client == nullptr) { 14222736c2fSopenharmony_ci IMSA_HILOGE("client is nullptr!"); 14322736c2fSopenharmony_ci return; 14422736c2fSopenharmony_ci } 14522736c2fSopenharmony_ci auto info = GetClientInfo(client); 14622736c2fSopenharmony_ci if (info == nullptr) { 14722736c2fSopenharmony_ci IMSA_HILOGE("client info is not exist!"); 14822736c2fSopenharmony_ci return; 14922736c2fSopenharmony_ci } 15022736c2fSopenharmony_ci for (const auto &updateInfo : updateInfos) { 15122736c2fSopenharmony_ci switch (updateInfo.first) { 15222736c2fSopenharmony_ci case UpdateFlag::EVENTFLAG: { 15322736c2fSopenharmony_ci info->eventFlag = std::get<uint32_t>(updateInfo.second); 15422736c2fSopenharmony_ci break; 15522736c2fSopenharmony_ci } 15622736c2fSopenharmony_ci case UpdateFlag::ISSHOWKEYBOARD: { 15722736c2fSopenharmony_ci info->isShowKeyboard = std::get<bool>(updateInfo.second); 15822736c2fSopenharmony_ci break; 15922736c2fSopenharmony_ci } 16022736c2fSopenharmony_ci case UpdateFlag::BINDIMETYPE: { 16122736c2fSopenharmony_ci info->bindImeType = std::get<ImeType>(updateInfo.second); 16222736c2fSopenharmony_ci break; 16322736c2fSopenharmony_ci } 16422736c2fSopenharmony_ci case UpdateFlag::STATE: { 16522736c2fSopenharmony_ci info->state = std::get<ClientState>(updateInfo.second); 16622736c2fSopenharmony_ci break; 16722736c2fSopenharmony_ci } 16822736c2fSopenharmony_ci case UpdateFlag::TEXT_CONFIG: { 16922736c2fSopenharmony_ci info->config = std::get<TextTotalConfig>(updateInfo.second); 17022736c2fSopenharmony_ci break; 17122736c2fSopenharmony_ci } 17222736c2fSopenharmony_ci case UpdateFlag::UIEXTENSION_TOKENID: { 17322736c2fSopenharmony_ci info->uiExtensionTokenId = std::get<uint32_t>(updateInfo.second); 17422736c2fSopenharmony_ci break; 17522736c2fSopenharmony_ci } 17622736c2fSopenharmony_ci default: 17722736c2fSopenharmony_ci break; 17822736c2fSopenharmony_ci } 17922736c2fSopenharmony_ci } 18022736c2fSopenharmony_ci} 18122736c2fSopenharmony_ci 18222736c2fSopenharmony_ciint32_t PerUserSession::HideKeyboard(const sptr<IInputClient> ¤tClient) 18322736c2fSopenharmony_ci{ 18422736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::HideKeyboard start."); 18522736c2fSopenharmony_ci auto clientInfo = GetClientInfo(currentClient->AsObject()); 18622736c2fSopenharmony_ci if (clientInfo == nullptr) { 18722736c2fSopenharmony_ci IMSA_HILOGE("client info is nullptr!"); 18822736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 18922736c2fSopenharmony_ci } 19022736c2fSopenharmony_ci auto data = GetReadyImeData(clientInfo->bindImeType); 19122736c2fSopenharmony_ci if (data == nullptr) { 19222736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType); 19322736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 19422736c2fSopenharmony_ci } 19522736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::NORMAL, [&data] { return data->core->HideKeyboard(false); }); 19622736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 19722736c2fSopenharmony_ci IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret); 19822736c2fSopenharmony_ci return ErrorCode::ERROR_KBD_HIDE_FAILED; 19922736c2fSopenharmony_ci } 20022736c2fSopenharmony_ci bool isShowKeyboard = false; 20122736c2fSopenharmony_ci UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); 20222736c2fSopenharmony_ci RestoreCurrentImeSubType(); 20322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 20422736c2fSopenharmony_ci} 20522736c2fSopenharmony_ci 20622736c2fSopenharmony_ciint32_t PerUserSession::ShowKeyboard(const sptr<IInputClient> ¤tClient) 20722736c2fSopenharmony_ci{ 20822736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::ShowKeyboard start."); 20922736c2fSopenharmony_ci auto clientInfo = GetClientInfo(currentClient->AsObject()); 21022736c2fSopenharmony_ci if (clientInfo == nullptr) { 21122736c2fSopenharmony_ci IMSA_HILOGE("client info is nullptr!"); 21222736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 21322736c2fSopenharmony_ci } 21422736c2fSopenharmony_ci auto data = GetReadyImeData(clientInfo->bindImeType); 21522736c2fSopenharmony_ci if (data == nullptr) { 21622736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType); 21722736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 21822736c2fSopenharmony_ci } 21922736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); }); 22022736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 22122736c2fSopenharmony_ci IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret); 22222736c2fSopenharmony_ci return ErrorCode::ERROR_KBD_SHOW_FAILED; 22322736c2fSopenharmony_ci } 22422736c2fSopenharmony_ci bool isShowKeyboard = true; 22522736c2fSopenharmony_ci UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); 22622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 22722736c2fSopenharmony_ci} 22822736c2fSopenharmony_ci 22922736c2fSopenharmony_ci/** Handle the situation a remote input client died. 23022736c2fSopenharmony_ci * It's called when a remote input client died 23122736c2fSopenharmony_ci * @param the remote object handler of the input client died. 23222736c2fSopenharmony_ci */ 23322736c2fSopenharmony_civoid PerUserSession::OnClientDied(sptr<IInputClient> remote) 23422736c2fSopenharmony_ci{ 23522736c2fSopenharmony_ci if (remote == nullptr) { 23622736c2fSopenharmony_ci return; 23722736c2fSopenharmony_ci } 23822736c2fSopenharmony_ci auto clientInfo = GetClientInfo(remote->AsObject()); 23922736c2fSopenharmony_ci IMSA_HILOGI("userId: %{public}d.", userId_); 24022736c2fSopenharmony_ci if (IsSameClient(remote, GetCurrentClient())) { 24122736c2fSopenharmony_ci if (clientInfo != nullptr) { 24222736c2fSopenharmony_ci StopImeInput(clientInfo->bindImeType, clientInfo->channel); 24322736c2fSopenharmony_ci } 24422736c2fSopenharmony_ci SetCurrentClient(nullptr); 24522736c2fSopenharmony_ci RestoreCurrentImeSubType(); 24622736c2fSopenharmony_ci } 24722736c2fSopenharmony_ci if (IsSameClient(remote, GetInactiveClient())) { 24822736c2fSopenharmony_ci if (clientInfo != nullptr) { 24922736c2fSopenharmony_ci StopImeInput(clientInfo->bindImeType, clientInfo->channel); 25022736c2fSopenharmony_ci } 25122736c2fSopenharmony_ci SetInactiveClient(nullptr); 25222736c2fSopenharmony_ci RestoreCurrentImeSubType(); 25322736c2fSopenharmony_ci } 25422736c2fSopenharmony_ci RemoveClientInfo(remote->AsObject(), true); 25522736c2fSopenharmony_ci} 25622736c2fSopenharmony_ci 25722736c2fSopenharmony_ci/** Handle the situation that an ime died 25822736c2fSopenharmony_ci * It's called when an ime died 25922736c2fSopenharmony_ci * @param the remote object handler of the ime who died. 26022736c2fSopenharmony_ci */ 26122736c2fSopenharmony_civoid PerUserSession::OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type) 26222736c2fSopenharmony_ci{ 26322736c2fSopenharmony_ci if (remote == nullptr) { 26422736c2fSopenharmony_ci return; 26522736c2fSopenharmony_ci } 26622736c2fSopenharmony_ci IMSA_HILOGI("type: %{public}d.", type); 26722736c2fSopenharmony_ci auto imeData = GetImeData(type); 26822736c2fSopenharmony_ci auto ime = InputTypeManager::GetInstance().GetCurrentIme(); 26922736c2fSopenharmony_ci if (ime.bundleName == imeData->ime.first) { 27022736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 27122736c2fSopenharmony_ci } 27222736c2fSopenharmony_ci if (imeData != nullptr && imeData->imeStatus == ImeStatus::EXITING) { 27322736c2fSopenharmony_ci RemoveImeData(type, true); 27422736c2fSopenharmony_ci NotifyImeStopFinished(); 27522736c2fSopenharmony_ci IMSA_HILOGI("%{public}d not current imeData.", type); 27622736c2fSopenharmony_ci return; 27722736c2fSopenharmony_ci } 27822736c2fSopenharmony_ci RemoveImeData(type, true); 27922736c2fSopenharmony_ci if (!OsAccountAdapter::IsOsAccountForeground(userId_)) { 28022736c2fSopenharmony_ci IMSA_HILOGW("userId:%{public}d in background, no need to restart ime.", userId_); 28122736c2fSopenharmony_ci return; 28222736c2fSopenharmony_ci } 28322736c2fSopenharmony_ci auto client = GetCurrentClient(); 28422736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 28522736c2fSopenharmony_ci if (clientInfo != nullptr && clientInfo->bindImeType == type) { 28622736c2fSopenharmony_ci StopClientInput(clientInfo); 28722736c2fSopenharmony_ci if (type == ImeType::IME) { 28822736c2fSopenharmony_ci StartImeInImeDied(); 28922736c2fSopenharmony_ci } 29022736c2fSopenharmony_ci return; 29122736c2fSopenharmony_ci } 29222736c2fSopenharmony_ci auto currentImeInfo = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 29322736c2fSopenharmony_ci if (currentImeInfo == nullptr) { 29422736c2fSopenharmony_ci IMSA_HILOGE("currentImeInfo is nullptr!"); 29522736c2fSopenharmony_ci return; 29622736c2fSopenharmony_ci } 29722736c2fSopenharmony_ci auto defaultImeInfo = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp(); 29822736c2fSopenharmony_ci if (defaultImeInfo == nullptr) { 29922736c2fSopenharmony_ci IMSA_HILOGE("defaultImeInfo is nullptr!"); 30022736c2fSopenharmony_ci return; 30122736c2fSopenharmony_ci } 30222736c2fSopenharmony_ci if (type == ImeType::IME && currentImeInfo->bundleName == defaultImeInfo->name) { 30322736c2fSopenharmony_ci StartImeInImeDied(); 30422736c2fSopenharmony_ci } 30522736c2fSopenharmony_ci} 30622736c2fSopenharmony_ci 30722736c2fSopenharmony_ciint32_t PerUserSession::RemoveIme(const sptr<IInputMethodCore> &core, ImeType type) 30822736c2fSopenharmony_ci{ 30922736c2fSopenharmony_ci if (core == nullptr) { 31022736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 31122736c2fSopenharmony_ci } 31222736c2fSopenharmony_ci auto data = GetReadyImeData(type); 31322736c2fSopenharmony_ci if (data == nullptr || data->core->AsObject() != core->AsObject()) { 31422736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 31522736c2fSopenharmony_ci } 31622736c2fSopenharmony_ci 31722736c2fSopenharmony_ci auto client = GetCurrentClient(); 31822736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 31922736c2fSopenharmony_ci if (clientInfo != nullptr && clientInfo->bindImeType == type) { 32022736c2fSopenharmony_ci UnBindClientWithIme(clientInfo); 32122736c2fSopenharmony_ci } 32222736c2fSopenharmony_ci RemoveImeData(type, true); 32322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 32422736c2fSopenharmony_ci} 32522736c2fSopenharmony_ci 32622736c2fSopenharmony_ciint32_t PerUserSession::OnHideCurrentInput() 32722736c2fSopenharmony_ci{ 32822736c2fSopenharmony_ci sptr<IInputClient> client = GetCurrentClient(); 32922736c2fSopenharmony_ci if (client == nullptr) { 33022736c2fSopenharmony_ci IMSA_HILOGE("current client is nullptr!"); 33122736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 33222736c2fSopenharmony_ci } 33322736c2fSopenharmony_ci return HideKeyboard(client); 33422736c2fSopenharmony_ci} 33522736c2fSopenharmony_ci 33622736c2fSopenharmony_ciint32_t PerUserSession::OnShowCurrentInput() 33722736c2fSopenharmony_ci{ 33822736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnShowCurrentInput start."); 33922736c2fSopenharmony_ci sptr<IInputClient> client = GetCurrentClient(); 34022736c2fSopenharmony_ci if (client == nullptr) { 34122736c2fSopenharmony_ci IMSA_HILOGE("current client is nullptr!"); 34222736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 34322736c2fSopenharmony_ci } 34422736c2fSopenharmony_ci return ShowKeyboard(client); 34522736c2fSopenharmony_ci} 34622736c2fSopenharmony_ci 34722736c2fSopenharmony_ciint32_t PerUserSession::OnHideInput(sptr<IInputClient> client) 34822736c2fSopenharmony_ci{ 34922736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnHideInput start."); 35022736c2fSopenharmony_ci if (!IsSameClient(client, GetCurrentClient())) { 35122736c2fSopenharmony_ci IMSA_HILOGE("client is not current client!"); 35222736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 35322736c2fSopenharmony_ci } 35422736c2fSopenharmony_ci return HideKeyboard(client); 35522736c2fSopenharmony_ci} 35622736c2fSopenharmony_ci 35722736c2fSopenharmony_ciint32_t PerUserSession::OnShowInput(sptr<IInputClient> client) 35822736c2fSopenharmony_ci{ 35922736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnShowInput start."); 36022736c2fSopenharmony_ci if (!IsSameClient(client, GetCurrentClient())) { 36122736c2fSopenharmony_ci IMSA_HILOGE("client is not current client!"); 36222736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; 36322736c2fSopenharmony_ci } 36422736c2fSopenharmony_ci return ShowKeyboard(client); 36522736c2fSopenharmony_ci} 36622736c2fSopenharmony_ci 36722736c2fSopenharmony_civoid PerUserSession::OnHideSoftKeyBoardSelf() 36822736c2fSopenharmony_ci{ 36922736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnHideSoftKeyBoardSel start."); 37022736c2fSopenharmony_ci sptr<IInputClient> client = GetCurrentClient(); 37122736c2fSopenharmony_ci if (client == nullptr) { 37222736c2fSopenharmony_ci IMSA_HILOGE("current client is nullptr!"); 37322736c2fSopenharmony_ci return; 37422736c2fSopenharmony_ci } 37522736c2fSopenharmony_ci UpdateClientInfo(client->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } }); 37622736c2fSopenharmony_ci RestoreCurrentImeSubType(); 37722736c2fSopenharmony_ci} 37822736c2fSopenharmony_ci 37922736c2fSopenharmony_ciint32_t PerUserSession::OnRequestShowInput() 38022736c2fSopenharmony_ci{ 38122736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnRequestShowInput start."); 38222736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::IME); 38322736c2fSopenharmony_ci if (data == nullptr) { 38422736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d doesn't exist!", ImeType::IME); 38522736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 38622736c2fSopenharmony_ci } 38722736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); }); 38822736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 38922736c2fSopenharmony_ci IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret); 39022736c2fSopenharmony_ci return ErrorCode::ERROR_KBD_SHOW_FAILED; 39122736c2fSopenharmony_ci } 39222736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().ReportImeState(ImeState::BIND, data->pid, 39322736c2fSopenharmony_ci ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName); 39422736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID); 39522736c2fSopenharmony_ci auto currentClient = GetCurrentClient(); 39622736c2fSopenharmony_ci if (currentClient != nullptr) { 39722736c2fSopenharmony_ci UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, true } }); 39822736c2fSopenharmony_ci } 39922736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 40022736c2fSopenharmony_ci} 40122736c2fSopenharmony_ci 40222736c2fSopenharmony_ciint32_t PerUserSession::OnRequestHideInput() 40322736c2fSopenharmony_ci{ 40422736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnRequestHideInput start."); 40522736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::IME); 40622736c2fSopenharmony_ci if (data == nullptr) { 40722736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d doesn't exist!", ImeType::IME); 40822736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 40922736c2fSopenharmony_ci } 41022736c2fSopenharmony_ci 41122736c2fSopenharmony_ci bool isForce = false; 41222736c2fSopenharmony_ci if (!data->freezeMgr->IsIpcNeeded(RequestType::REQUEST_HIDE)) { 41322736c2fSopenharmony_ci IMSA_HILOGD("need to force hide"); 41422736c2fSopenharmony_ci isForce = true; 41522736c2fSopenharmony_ci } 41622736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::REQUEST_HIDE, 41722736c2fSopenharmony_ci [&data, isForce] { return data->core->HideKeyboard(isForce); }); 41822736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 41922736c2fSopenharmony_ci IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret); 42022736c2fSopenharmony_ci return ErrorCode::ERROR_KBD_HIDE_FAILED; 42122736c2fSopenharmony_ci } 42222736c2fSopenharmony_ci auto currentClient = GetCurrentClient(); 42322736c2fSopenharmony_ci if (currentClient != nullptr) { 42422736c2fSopenharmony_ci UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } }); 42522736c2fSopenharmony_ci } 42622736c2fSopenharmony_ci auto inactiveClient = GetInactiveClient(); 42722736c2fSopenharmony_ci if (inactiveClient != nullptr) { 42822736c2fSopenharmony_ci RemoveClient(inactiveClient, false, true); 42922736c2fSopenharmony_ci } 43022736c2fSopenharmony_ci RestoreCurrentImeSubType(); 43122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 43222736c2fSopenharmony_ci} 43322736c2fSopenharmony_ci 43422736c2fSopenharmony_ci/** Get ClientInfo 43522736c2fSopenharmony_ci * @param inputClient the IRemoteObject remote handler of given input client 43622736c2fSopenharmony_ci * @return a pointer of ClientInfo if client is found 43722736c2fSopenharmony_ci * null if client is not found 43822736c2fSopenharmony_ci * @note the clientInfo pointer should not be freed by caller 43922736c2fSopenharmony_ci */ 44022736c2fSopenharmony_cistd::shared_ptr<InputClientInfo> PerUserSession::GetClientInfo(sptr<IRemoteObject> inputClient) 44122736c2fSopenharmony_ci{ 44222736c2fSopenharmony_ci if (inputClient == nullptr) { 44322736c2fSopenharmony_ci IMSA_HILOGE("inputClient is nullptr!"); 44422736c2fSopenharmony_ci return nullptr; 44522736c2fSopenharmony_ci } 44622736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 44722736c2fSopenharmony_ci auto it = mapClients_.find(inputClient); 44822736c2fSopenharmony_ci if (it == mapClients_.end()) { 44922736c2fSopenharmony_ci IMSA_HILOGD("client not found."); 45022736c2fSopenharmony_ci return nullptr; 45122736c2fSopenharmony_ci } 45222736c2fSopenharmony_ci return it->second; 45322736c2fSopenharmony_ci} 45422736c2fSopenharmony_ci 45522736c2fSopenharmony_cistd::shared_ptr<InputClientInfo> PerUserSession::GetClientInfo(pid_t pid) 45622736c2fSopenharmony_ci{ 45722736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 45822736c2fSopenharmony_ci auto iter = std::find_if(mapClients_.begin(), mapClients_.end(), 45922736c2fSopenharmony_ci [pid](const auto &mapClient) { return mapClient.second->pid == pid; }); 46022736c2fSopenharmony_ci if (iter == mapClients_.end()) { 46122736c2fSopenharmony_ci IMSA_HILOGD("not found."); 46222736c2fSopenharmony_ci return nullptr; 46322736c2fSopenharmony_ci } 46422736c2fSopenharmony_ci return iter->second; 46522736c2fSopenharmony_ci} 46622736c2fSopenharmony_ci 46722736c2fSopenharmony_ciint32_t PerUserSession::OnPrepareInput(const InputClientInfo &clientInfo) 46822736c2fSopenharmony_ci{ 46922736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnPrepareInput start"); 47022736c2fSopenharmony_ci return AddClientInfo(clientInfo.client->AsObject(), clientInfo, PREPARE_INPUT); 47122736c2fSopenharmony_ci} 47222736c2fSopenharmony_ci 47322736c2fSopenharmony_ci/** Release input. Called by an input client.Run in work thread of this user 47422736c2fSopenharmony_ci * @param the parameters from remote client 47522736c2fSopenharmony_ci * @return ErrorCode 47622736c2fSopenharmony_ci */ 47722736c2fSopenharmony_ciint32_t PerUserSession::OnReleaseInput(const sptr<IInputClient> &client) 47822736c2fSopenharmony_ci{ 47922736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::OnReleaseInput start"); 48022736c2fSopenharmony_ci return RemoveClient(client, true); 48122736c2fSopenharmony_ci} 48222736c2fSopenharmony_ci 48322736c2fSopenharmony_ciint32_t PerUserSession::RemoveClient(const sptr<IInputClient> &client, bool isUnbindFromClient, bool isInactiveClient) 48422736c2fSopenharmony_ci{ 48522736c2fSopenharmony_ci if (client == nullptr) { 48622736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 48722736c2fSopenharmony_ci } 48822736c2fSopenharmony_ci // if client is current client, unbind firstly 48922736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 49022736c2fSopenharmony_ci if (IsSameClient(client, GetCurrentClient())) { 49122736c2fSopenharmony_ci UnBindClientWithIme(clientInfo, isUnbindFromClient); 49222736c2fSopenharmony_ci SetCurrentClient(nullptr); 49322736c2fSopenharmony_ci RestoreCurrentImeSubType(); 49422736c2fSopenharmony_ci StopClientInput(clientInfo); 49522736c2fSopenharmony_ci } 49622736c2fSopenharmony_ci if (IsSameClient(client, GetInactiveClient())) { 49722736c2fSopenharmony_ci SetInactiveClient(nullptr); 49822736c2fSopenharmony_ci StopClientInput(clientInfo, isInactiveClient); 49922736c2fSopenharmony_ci } 50022736c2fSopenharmony_ci RemoveClientInfo(client->AsObject()); 50122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 50222736c2fSopenharmony_ci} 50322736c2fSopenharmony_ci 50422736c2fSopenharmony_civoid PerUserSession::DeactivateClient(const sptr<IInputClient> &client) 50522736c2fSopenharmony_ci{ 50622736c2fSopenharmony_ci if (client == nullptr) { 50722736c2fSopenharmony_ci IMSA_HILOGD("client is nullptr."); 50822736c2fSopenharmony_ci return; 50922736c2fSopenharmony_ci } 51022736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 51122736c2fSopenharmony_ci if (clientInfo == nullptr) { 51222736c2fSopenharmony_ci return; 51322736c2fSopenharmony_ci } 51422736c2fSopenharmony_ci IMSA_HILOGI("deactivate client[%{public}d].", clientInfo->pid); 51522736c2fSopenharmony_ci UpdateClientInfo(client->AsObject(), { { UpdateFlag::STATE, ClientState::INACTIVE } }); 51622736c2fSopenharmony_ci if (IsSameClient(client, GetCurrentClient())) { 51722736c2fSopenharmony_ci SetCurrentClient(nullptr); 51822736c2fSopenharmony_ci } 51922736c2fSopenharmony_ci SetInactiveClient(client); 52022736c2fSopenharmony_ci client->DeactivateClient(); 52122736c2fSopenharmony_ci if (InputTypeManager::GetInstance().IsStarted()) { 52222736c2fSopenharmony_ci RestoreCurrentImeSubType(); 52322736c2fSopenharmony_ci return; 52422736c2fSopenharmony_ci } 52522736c2fSopenharmony_ci auto data = GetReadyImeData(clientInfo->bindImeType); 52622736c2fSopenharmony_ci if (data == nullptr) { 52722736c2fSopenharmony_ci IMSA_HILOGE("ime %{public}d doesn't exist!", clientInfo->bindImeType); 52822736c2fSopenharmony_ci return; 52922736c2fSopenharmony_ci } 53022736c2fSopenharmony_ci RequestIme(data, RequestType::NORMAL, [&data, &clientInfo] { 53122736c2fSopenharmony_ci data->core->OnClientInactive(clientInfo->channel); 53222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 53322736c2fSopenharmony_ci }); 53422736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().ReportImeState(ImeState::UNBIND, data->pid, 53522736c2fSopenharmony_ci ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName); 53622736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID); 53722736c2fSopenharmony_ci} 53822736c2fSopenharmony_ci 53922736c2fSopenharmony_cibool PerUserSession::IsProxyImeEnable() 54022736c2fSopenharmony_ci{ 54122736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::PROXY_IME); 54222736c2fSopenharmony_ci return data != nullptr && data->core != nullptr && data->core->IsEnable(); 54322736c2fSopenharmony_ci} 54422736c2fSopenharmony_ci 54522736c2fSopenharmony_ciint32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, sptr<IRemoteObject> &agent) 54622736c2fSopenharmony_ci{ 54722736c2fSopenharmony_ci const sptr<IInputClient> &client = inputClientInfo.client; 54822736c2fSopenharmony_ci if (client == nullptr) { 54922736c2fSopenharmony_ci IMSA_HILOGE("client is nullptr!"); 55022736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 55122736c2fSopenharmony_ci } 55222736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 55322736c2fSopenharmony_ci if (clientInfo == nullptr) { 55422736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 55522736c2fSopenharmony_ci } 55622736c2fSopenharmony_ci IMSA_HILOGD("start input with keyboard[%{public}d].", inputClientInfo.isShowKeyboard); 55722736c2fSopenharmony_ci if (IsSameClient(client, GetCurrentClient()) && IsImeBindChanged(clientInfo->bindImeType)) { 55822736c2fSopenharmony_ci UnBindClientWithIme(clientInfo); 55922736c2fSopenharmony_ci } 56022736c2fSopenharmony_ci InputClientInfo infoTemp = *clientInfo; 56122736c2fSopenharmony_ci infoTemp.isShowKeyboard = inputClientInfo.isShowKeyboard; 56222736c2fSopenharmony_ci infoTemp.isNotifyInputStart = inputClientInfo.isNotifyInputStart; 56322736c2fSopenharmony_ci infoTemp.needHide = inputClientInfo.needHide; 56422736c2fSopenharmony_ci auto imeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME; 56522736c2fSopenharmony_ci int32_t ret = BindClientWithIme(std::make_shared<InputClientInfo>(infoTemp), imeType, true); 56622736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 56722736c2fSopenharmony_ci IMSA_HILOGE("bind failed, ret: %{public}d!", ret); 56822736c2fSopenharmony_ci return ret; 56922736c2fSopenharmony_ci } 57022736c2fSopenharmony_ci auto data = GetReadyImeData(imeType); 57122736c2fSopenharmony_ci if (data == nullptr || data->agent == nullptr) { 57222736c2fSopenharmony_ci IMSA_HILOGE("data or agent is nullptr!"); 57322736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 57422736c2fSopenharmony_ci } 57522736c2fSopenharmony_ci agent = data->agent; 57622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 57722736c2fSopenharmony_ci} 57822736c2fSopenharmony_ci 57922736c2fSopenharmony_ciint32_t PerUserSession::BindClientWithIme(const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type, 58022736c2fSopenharmony_ci bool isBindFromClient) 58122736c2fSopenharmony_ci{ 58222736c2fSopenharmony_ci if (clientInfo == nullptr) { 58322736c2fSopenharmony_ci IMSA_HILOGE("clientInfo is nullptr!"); 58422736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 58522736c2fSopenharmony_ci } 58622736c2fSopenharmony_ci IMSA_HILOGD("imeType: %{public}d, isShowKeyboard: %{public}d, isBindFromClient: %{public}d.", type, 58722736c2fSopenharmony_ci clientInfo->isShowKeyboard, isBindFromClient); 58822736c2fSopenharmony_ci auto data = GetValidIme(type); 58922736c2fSopenharmony_ci if (data == nullptr) { 59022736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 59122736c2fSopenharmony_ci } 59222736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::START_INPUT, 59322736c2fSopenharmony_ci [&data, &clientInfo, isBindFromClient]() { return data->core->StartInput(*clientInfo, isBindFromClient); }); 59422736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 59522736c2fSopenharmony_ci IMSA_HILOGE("start input failed, ret: %{public}d!", ret); 59622736c2fSopenharmony_ci return ErrorCode::ERROR_IME_START_INPUT_FAILED; 59722736c2fSopenharmony_ci } 59822736c2fSopenharmony_ci if (type == ImeType::IME) { 59922736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().ReportImeState(ImeState::BIND, data->pid, 60022736c2fSopenharmony_ci ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName); 60122736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID); 60222736c2fSopenharmony_ci } 60322736c2fSopenharmony_ci if (!isBindFromClient && clientInfo->client->OnInputReady(data->agent) != ErrorCode::NO_ERROR) { 60422736c2fSopenharmony_ci IMSA_HILOGE("start client input failed, ret: %{public}d!", ret); 60522736c2fSopenharmony_ci return ErrorCode::ERROR_EX_PARCELABLE; 60622736c2fSopenharmony_ci } 60722736c2fSopenharmony_ci UpdateClientInfo(clientInfo->client->AsObject(), 60822736c2fSopenharmony_ci { { UpdateFlag::BINDIMETYPE, type }, { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard }, 60922736c2fSopenharmony_ci { UpdateFlag::STATE, ClientState::ACTIVE } }); 61022736c2fSopenharmony_ci ReplaceCurrentClient(clientInfo->client); 61122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 61222736c2fSopenharmony_ci} 61322736c2fSopenharmony_ci 61422736c2fSopenharmony_civoid PerUserSession::UnBindClientWithIme(const std::shared_ptr<InputClientInfo> ¤tClientInfo, 61522736c2fSopenharmony_ci bool isUnbindFromClient) 61622736c2fSopenharmony_ci{ 61722736c2fSopenharmony_ci if (currentClientInfo == nullptr) { 61822736c2fSopenharmony_ci return; 61922736c2fSopenharmony_ci } 62022736c2fSopenharmony_ci if (!isUnbindFromClient) { 62122736c2fSopenharmony_ci IMSA_HILOGD("unbind from service."); 62222736c2fSopenharmony_ci StopClientInput(currentClientInfo); 62322736c2fSopenharmony_ci } 62422736c2fSopenharmony_ci StopImeInput(currentClientInfo->bindImeType, currentClientInfo->channel); 62522736c2fSopenharmony_ci} 62622736c2fSopenharmony_ci 62722736c2fSopenharmony_civoid PerUserSession::StopClientInput(const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient) 62822736c2fSopenharmony_ci{ 62922736c2fSopenharmony_ci if (clientInfo == nullptr || clientInfo->client == nullptr) { 63022736c2fSopenharmony_ci return; 63122736c2fSopenharmony_ci } 63222736c2fSopenharmony_ci auto ret = clientInfo->client->OnInputStop(isStopInactiveClient); 63322736c2fSopenharmony_ci IMSA_HILOGI("isStopInactiveClient: %{public}d, client pid: %{public}d, ret: %{public}d.", isStopInactiveClient, 63422736c2fSopenharmony_ci clientInfo->pid, ret); 63522736c2fSopenharmony_ci} 63622736c2fSopenharmony_ci 63722736c2fSopenharmony_civoid PerUserSession::StopImeInput(ImeType currentType, const sptr<IRemoteObject> ¤tChannel) 63822736c2fSopenharmony_ci{ 63922736c2fSopenharmony_ci auto data = GetReadyImeData(currentType); 64022736c2fSopenharmony_ci if (data == nullptr) { 64122736c2fSopenharmony_ci return; 64222736c2fSopenharmony_ci } 64322736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::STOP_INPUT, 64422736c2fSopenharmony_ci [&data, ¤tChannel]() { return data->core->StopInput(currentChannel); }); 64522736c2fSopenharmony_ci IMSA_HILOGI("stop ime input, ret: %{public}d.", ret); 64622736c2fSopenharmony_ci if (ret == ErrorCode::NO_ERROR && currentType == ImeType::IME) { 64722736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().ReportImeState(ImeState::UNBIND, data->pid, 64822736c2fSopenharmony_ci ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName); 64922736c2fSopenharmony_ci Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID); 65022736c2fSopenharmony_ci } 65122736c2fSopenharmony_ci if (currentType == ImeType::IME) { 65222736c2fSopenharmony_ci RestoreCurrentImeSubType(); 65322736c2fSopenharmony_ci } 65422736c2fSopenharmony_ci} 65522736c2fSopenharmony_ci 65622736c2fSopenharmony_civoid PerUserSession::OnSecurityChange(int32_t security) 65722736c2fSopenharmony_ci{ 65822736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::IME); 65922736c2fSopenharmony_ci if (data == nullptr) { 66022736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); 66122736c2fSopenharmony_ci return; 66222736c2fSopenharmony_ci } 66322736c2fSopenharmony_ci auto ret = 66422736c2fSopenharmony_ci RequestIme(data, RequestType::NORMAL, [&data, security] { return data->core->OnSecurityChange(security); }); 66522736c2fSopenharmony_ci IMSA_HILOGD("on security change, ret: %{public}d.", ret); 66622736c2fSopenharmony_ci} 66722736c2fSopenharmony_ci 66822736c2fSopenharmony_ciint32_t PerUserSession::OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent) 66922736c2fSopenharmony_ci{ 67022736c2fSopenharmony_ci IMSA_HILOGI("start."); 67122736c2fSopenharmony_ci auto ret = UpdateImeData(core, agent, IPCSkeleton::GetCallingPid()); 67222736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 67322736c2fSopenharmony_ci return ret; 67422736c2fSopenharmony_ci } 67522736c2fSopenharmony_ci auto action = GetImeAction(ImeEvent::SET_CORE_AND_AGENT); 67622736c2fSopenharmony_ci if (action == ImeAction::DO_NOTHING) { 67722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 67822736c2fSopenharmony_ci } 67922736c2fSopenharmony_ci if (action != ImeAction::DO_SET_CORE_AND_AGENT) { 68022736c2fSopenharmony_ci return ErrorCode::ERROR_IME; 68122736c2fSopenharmony_ci } 68222736c2fSopenharmony_ci ret = InitInputControlChannel(); 68322736c2fSopenharmony_ci IMSA_HILOGI("init input control channel ret: %{public}d.", ret); 68422736c2fSopenharmony_ci auto imeType = ImeType::IME; 68522736c2fSopenharmony_ci auto client = GetCurrentClient(); 68622736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 68722736c2fSopenharmony_ci if (clientInfo != nullptr && IsImeStartInBind(clientInfo->bindImeType, imeType)) { 68822736c2fSopenharmony_ci BindClientWithIme(clientInfo, imeType); 68922736c2fSopenharmony_ci } 69022736c2fSopenharmony_ci bool isStarted = true; 69122736c2fSopenharmony_ci isImeStarted_.SetValue(isStarted); 69222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 69322736c2fSopenharmony_ci} 69422736c2fSopenharmony_ci 69522736c2fSopenharmony_ciint32_t PerUserSession::OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent) 69622736c2fSopenharmony_ci{ 69722736c2fSopenharmony_ci IMSA_HILOGD("start."); 69822736c2fSopenharmony_ci auto imeType = ImeType::PROXY_IME; 69922736c2fSopenharmony_ci auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid()); 70022736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 70122736c2fSopenharmony_ci return ret; 70222736c2fSopenharmony_ci } 70322736c2fSopenharmony_ci auto client = GetCurrentClient(); 70422736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 70522736c2fSopenharmony_ci if (clientInfo != nullptr) { 70622736c2fSopenharmony_ci if (IsProxyImeStartInBind(clientInfo->bindImeType, imeType)) { 70722736c2fSopenharmony_ci BindClientWithIme(clientInfo, imeType); 70822736c2fSopenharmony_ci } 70922736c2fSopenharmony_ci if (IsProxyImeStartInImeBind(clientInfo->bindImeType, imeType)) { 71022736c2fSopenharmony_ci UnBindClientWithIme(clientInfo); 71122736c2fSopenharmony_ci BindClientWithIme(clientInfo, imeType); 71222736c2fSopenharmony_ci } 71322736c2fSopenharmony_ci } 71422736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 71522736c2fSopenharmony_ci} 71622736c2fSopenharmony_ci 71722736c2fSopenharmony_ciint32_t PerUserSession::OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core) 71822736c2fSopenharmony_ci{ 71922736c2fSopenharmony_ci IMSA_HILOGD("proxy unregister type: %{public}d.", type); 72022736c2fSopenharmony_ci // 0: stop proxy 1: switch to ima 72122736c2fSopenharmony_ci if (type == UnRegisteredType::REMOVE_PROXY_IME) { 72222736c2fSopenharmony_ci RemoveIme(core, ImeType::PROXY_IME); 72322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 72422736c2fSopenharmony_ci } 72522736c2fSopenharmony_ci if (type == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) { 72622736c2fSopenharmony_ci auto client = GetCurrentClient(); 72722736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 72822736c2fSopenharmony_ci if (clientInfo == nullptr) { 72922736c2fSopenharmony_ci IMSA_HILOGE("not found current client!"); 73022736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_BOUND; 73122736c2fSopenharmony_ci } 73222736c2fSopenharmony_ci if (clientInfo->bindImeType == ImeType::PROXY_IME) { 73322736c2fSopenharmony_ci UnBindClientWithIme(clientInfo); 73422736c2fSopenharmony_ci } 73522736c2fSopenharmony_ci InputClientInfo infoTemp = { .isShowKeyboard = true, 73622736c2fSopenharmony_ci .client = clientInfo->client, 73722736c2fSopenharmony_ci .channel = clientInfo->channel }; 73822736c2fSopenharmony_ci return BindClientWithIme(std::make_shared<InputClientInfo>(infoTemp), ImeType::IME); 73922736c2fSopenharmony_ci } 74022736c2fSopenharmony_ci return ErrorCode::ERROR_BAD_PARAMETERS; 74122736c2fSopenharmony_ci} 74222736c2fSopenharmony_ci 74322736c2fSopenharmony_ciint32_t PerUserSession::InitInputControlChannel() 74422736c2fSopenharmony_ci{ 74522736c2fSopenharmony_ci IMSA_HILOGD("PerUserSession::InitInputControlChannel start."); 74622736c2fSopenharmony_ci sptr<IInputControlChannel> inputControlChannel = new InputControlChannelStub(userId_); 74722736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::IME); 74822736c2fSopenharmony_ci if (data == nullptr) { 74922736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); 75022736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 75122736c2fSopenharmony_ci } 75222736c2fSopenharmony_ci return RequestIme(data, RequestType::NORMAL, 75322736c2fSopenharmony_ci [&data, &inputControlChannel] { return data->core->InitInputControlChannel(inputControlChannel); }); 75422736c2fSopenharmony_ci} 75522736c2fSopenharmony_ci 75622736c2fSopenharmony_civoid PerUserSession::StartImeInImeDied() 75722736c2fSopenharmony_ci{ 75822736c2fSopenharmony_ci IMSA_HILOGD("StartImeInImeDied."); 75922736c2fSopenharmony_ci { 76022736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(resetLock); 76122736c2fSopenharmony_ci auto now = time(nullptr); 76222736c2fSopenharmony_ci if (difftime(now, manager.last) > IME_RESET_TIME_OUT) { 76322736c2fSopenharmony_ci manager = { 0, now }; 76422736c2fSopenharmony_ci } 76522736c2fSopenharmony_ci ++manager.num; 76622736c2fSopenharmony_ci if (manager.num > MAX_RESTART_NUM) { 76722736c2fSopenharmony_ci return; 76822736c2fSopenharmony_ci } 76922736c2fSopenharmony_ci } 77022736c2fSopenharmony_ci if (!IsWmsReady()) { 77122736c2fSopenharmony_ci IMSA_HILOGW("not ready to start ime."); 77222736c2fSopenharmony_ci return; 77322736c2fSopenharmony_ci } 77422736c2fSopenharmony_ci StartCurrentIme(); 77522736c2fSopenharmony_ci} 77622736c2fSopenharmony_ci 77722736c2fSopenharmony_civoid PerUserSession::SetCurrentClient(sptr<IInputClient> client) 77822736c2fSopenharmony_ci{ 77922736c2fSopenharmony_ci IMSA_HILOGD("set current client."); 78022736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(clientLock_); 78122736c2fSopenharmony_ci currentClient_ = client; 78222736c2fSopenharmony_ci} 78322736c2fSopenharmony_ci 78422736c2fSopenharmony_cisptr<IInputClient> PerUserSession::GetCurrentClient() 78522736c2fSopenharmony_ci{ 78622736c2fSopenharmony_ci IMSA_HILOGD("get current client."); 78722736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(clientLock_); 78822736c2fSopenharmony_ci return currentClient_; 78922736c2fSopenharmony_ci} 79022736c2fSopenharmony_ci 79122736c2fSopenharmony_civoid PerUserSession::ReplaceCurrentClient(const sptr<IInputClient> &client) 79222736c2fSopenharmony_ci{ 79322736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(focusedClientLock_); 79422736c2fSopenharmony_ci if (client == nullptr) { 79522736c2fSopenharmony_ci return; 79622736c2fSopenharmony_ci } 79722736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 79822736c2fSopenharmony_ci if (clientInfo == nullptr) { 79922736c2fSopenharmony_ci return; 80022736c2fSopenharmony_ci } 80122736c2fSopenharmony_ci auto replacedClient = GetCurrentClient(); 80222736c2fSopenharmony_ci SetCurrentClient(client); 80322736c2fSopenharmony_ci if (replacedClient != nullptr) { 80422736c2fSopenharmony_ci auto replacedClientInfo = GetClientInfo(replacedClient->AsObject()); 80522736c2fSopenharmony_ci if (replacedClientInfo != nullptr && replacedClientInfo->pid != clientInfo->pid) { 80622736c2fSopenharmony_ci IMSA_HILOGI("remove replaced client: [%{public}d]", replacedClientInfo->pid); 80722736c2fSopenharmony_ci RemoveClient(replacedClient); 80822736c2fSopenharmony_ci } 80922736c2fSopenharmony_ci } 81022736c2fSopenharmony_ci auto inactiveClient = GetInactiveClient(); 81122736c2fSopenharmony_ci if (inactiveClient != nullptr) { 81222736c2fSopenharmony_ci auto inactiveClientInfo = GetClientInfo(inactiveClient->AsObject()); 81322736c2fSopenharmony_ci if (inactiveClientInfo != nullptr && inactiveClientInfo->pid != clientInfo->pid) { 81422736c2fSopenharmony_ci IMSA_HILOGI("remove inactive client: [%{public}d]", inactiveClientInfo->pid); 81522736c2fSopenharmony_ci RemoveClient(inactiveClient, false); 81622736c2fSopenharmony_ci } 81722736c2fSopenharmony_ci } 81822736c2fSopenharmony_ci} 81922736c2fSopenharmony_ci 82022736c2fSopenharmony_civoid PerUserSession::SetInactiveClient(sptr<IInputClient> client) 82122736c2fSopenharmony_ci{ 82222736c2fSopenharmony_ci IMSA_HILOGD("set inactive client."); 82322736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(inactiveClientLock_); 82422736c2fSopenharmony_ci inactiveClient_ = client; 82522736c2fSopenharmony_ci} 82622736c2fSopenharmony_ci 82722736c2fSopenharmony_cisptr<IInputClient> PerUserSession::GetInactiveClient() 82822736c2fSopenharmony_ci{ 82922736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(inactiveClientLock_); 83022736c2fSopenharmony_ci return inactiveClient_; 83122736c2fSopenharmony_ci} 83222736c2fSopenharmony_ci 83322736c2fSopenharmony_civoid PerUserSession::NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty) 83422736c2fSopenharmony_ci{ 83522736c2fSopenharmony_ci IMSA_HILOGD("start."); 83622736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 83722736c2fSopenharmony_ci for (const auto &client : mapClients_) { 83822736c2fSopenharmony_ci auto clientInfo = client.second; 83922736c2fSopenharmony_ci if (clientInfo == nullptr || !EventStatusManager::IsImeChangeOn(clientInfo->eventFlag)) { 84022736c2fSopenharmony_ci IMSA_HILOGD("client nullptr or no need to notify."); 84122736c2fSopenharmony_ci continue; 84222736c2fSopenharmony_ci } 84322736c2fSopenharmony_ci IMSA_HILOGD("notify client: [%{public}d]", static_cast<int32_t>(clientInfo->pid)); 84422736c2fSopenharmony_ci int32_t ret = clientInfo->client->OnSwitchInput(property, subProperty); 84522736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 84622736c2fSopenharmony_ci IMSA_HILOGE("notify failed, ret: %{public}d, uid: %{public}d!", ret, static_cast<int32_t>(clientInfo->uid)); 84722736c2fSopenharmony_ci continue; 84822736c2fSopenharmony_ci } 84922736c2fSopenharmony_ci } 85022736c2fSopenharmony_ci} 85122736c2fSopenharmony_ci 85222736c2fSopenharmony_ciint32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid) 85322736c2fSopenharmony_ci{ 85422736c2fSopenharmony_ci if (core == nullptr || agent == nullptr) { 85522736c2fSopenharmony_ci IMSA_HILOGE("core or agent is nullptr!"); 85622736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 85722736c2fSopenharmony_ci } 85822736c2fSopenharmony_ci sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient(); 85922736c2fSopenharmony_ci if (deathRecipient == nullptr) { 86022736c2fSopenharmony_ci IMSA_HILOGE("failed to new deathRecipient!"); 86122736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 86222736c2fSopenharmony_ci } 86322736c2fSopenharmony_ci deathRecipient->SetDeathRecipient([this, core, type](const wptr<IRemoteObject> &) { this->OnImeDied(core, type); }); 86422736c2fSopenharmony_ci auto coreObject = core->AsObject(); 86522736c2fSopenharmony_ci if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) { 86622736c2fSopenharmony_ci IMSA_HILOGE("failed to add death recipient!"); 86722736c2fSopenharmony_ci return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; 86822736c2fSopenharmony_ci } 86922736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 87022736c2fSopenharmony_ci auto imeData = std::make_shared<ImeData>(core, agent, deathRecipient, pid); 87122736c2fSopenharmony_ci imeData->imeStatus = ImeStatus::READY; 87222736c2fSopenharmony_ci imeData_.insert_or_assign(type, imeData); 87322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 87422736c2fSopenharmony_ci} 87522736c2fSopenharmony_ci 87622736c2fSopenharmony_cistd::shared_ptr<ImeData> PerUserSession::GetReadyImeData(ImeType type) 87722736c2fSopenharmony_ci{ 87822736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 87922736c2fSopenharmony_ci auto it = imeData_.find(type); 88022736c2fSopenharmony_ci if (it == imeData_.end()) { 88122736c2fSopenharmony_ci return nullptr; 88222736c2fSopenharmony_ci } 88322736c2fSopenharmony_ci if (it->second->imeStatus != ImeStatus::READY) { 88422736c2fSopenharmony_ci return nullptr; 88522736c2fSopenharmony_ci } 88622736c2fSopenharmony_ci return it->second; 88722736c2fSopenharmony_ci} 88822736c2fSopenharmony_ci 88922736c2fSopenharmony_cistd::shared_ptr<ImeData> PerUserSession::GetValidIme(ImeType type) 89022736c2fSopenharmony_ci{ 89122736c2fSopenharmony_ci auto data = GetReadyImeData(type); 89222736c2fSopenharmony_ci if (data != nullptr || type != ImeType::IME) { 89322736c2fSopenharmony_ci return data; 89422736c2fSopenharmony_ci } 89522736c2fSopenharmony_ci IMSA_HILOGI("current ime is empty, try to restart it."); 89622736c2fSopenharmony_ci StartCurrentIme(); 89722736c2fSopenharmony_ci return GetReadyImeData(type); 89822736c2fSopenharmony_ci} 89922736c2fSopenharmony_ci 90022736c2fSopenharmony_civoid PerUserSession::RemoveImeData(ImeType type, bool isImeDied) 90122736c2fSopenharmony_ci{ 90222736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 90322736c2fSopenharmony_ci auto it = imeData_.find(type); 90422736c2fSopenharmony_ci if (it == imeData_.end()) { 90522736c2fSopenharmony_ci IMSA_HILOGD("imeData not found."); 90622736c2fSopenharmony_ci return; 90722736c2fSopenharmony_ci } 90822736c2fSopenharmony_ci auto data = it->second; 90922736c2fSopenharmony_ci if (isImeDied && data->core != nullptr && data->core->AsObject() != nullptr) { 91022736c2fSopenharmony_ci data->core->AsObject()->RemoveDeathRecipient(data->deathRecipient); 91122736c2fSopenharmony_ci } 91222736c2fSopenharmony_ci imeData_.erase(type); 91322736c2fSopenharmony_ci} 91422736c2fSopenharmony_ci 91522736c2fSopenharmony_civoid PerUserSession::OnFocused(int32_t pid, int32_t uid) 91622736c2fSopenharmony_ci{ 91722736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(focusedClientLock_); 91822736c2fSopenharmony_ci auto client = GetCurrentClient(); 91922736c2fSopenharmony_ci if (client == nullptr) { 92022736c2fSopenharmony_ci return; 92122736c2fSopenharmony_ci } 92222736c2fSopenharmony_ci if (IsCurClientFocused(pid, uid)) { 92322736c2fSopenharmony_ci IMSA_HILOGD("current client focused, focusedPid: %{public}d", pid); 92422736c2fSopenharmony_ci return; 92522736c2fSopenharmony_ci } 92622736c2fSopenharmony_ci if (!OHOS::Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) { 92722736c2fSopenharmony_ci IMSA_HILOGI("focus shifts to pid: %{public}d, remove current client.", pid); 92822736c2fSopenharmony_ci RemoveClient(client); 92922736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED); 93022736c2fSopenharmony_ci return; 93122736c2fSopenharmony_ci } 93222736c2fSopenharmony_ci IMSA_HILOGI("focus shifts to pid: %{public}d, deactivate current client.", pid); 93322736c2fSopenharmony_ci DeactivateClient(client); 93422736c2fSopenharmony_ci} 93522736c2fSopenharmony_ci 93622736c2fSopenharmony_civoid PerUserSession::OnUnfocused(int32_t pid, int32_t uid) 93722736c2fSopenharmony_ci{ 93822736c2fSopenharmony_ci if (GetCurrentClient() == nullptr) { 93922736c2fSopenharmony_ci return; 94022736c2fSopenharmony_ci } 94122736c2fSopenharmony_ci if (IsCurClientUnFocused(pid, uid)) { 94222736c2fSopenharmony_ci IMSA_HILOGD("current client Unfocused, unFocusedPid: %{public}d", pid); 94322736c2fSopenharmony_ci return; 94422736c2fSopenharmony_ci } 94522736c2fSopenharmony_ci auto clientInfo = GetClientInfo(pid); 94622736c2fSopenharmony_ci if (clientInfo == nullptr) { 94722736c2fSopenharmony_ci return; 94822736c2fSopenharmony_ci } 94922736c2fSopenharmony_ci RemoveClient(clientInfo->client); 95022736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED); 95122736c2fSopenharmony_ci} 95222736c2fSopenharmony_ci 95322736c2fSopenharmony_cistd::shared_ptr<InputClientInfo> PerUserSession::GetCurClientInfo() 95422736c2fSopenharmony_ci{ 95522736c2fSopenharmony_ci auto client = GetCurrentClient(); 95622736c2fSopenharmony_ci if (client == nullptr) { 95722736c2fSopenharmony_ci IMSA_HILOGD("no client in bound state."); 95822736c2fSopenharmony_ci return nullptr; 95922736c2fSopenharmony_ci } 96022736c2fSopenharmony_ci return GetClientInfo(client->AsObject()); 96122736c2fSopenharmony_ci} 96222736c2fSopenharmony_ci 96322736c2fSopenharmony_cibool PerUserSession::IsCurClientFocused(int32_t pid, int32_t uid) 96422736c2fSopenharmony_ci{ 96522736c2fSopenharmony_ci auto clientInfo = GetCurClientInfo(); 96622736c2fSopenharmony_ci if (clientInfo == nullptr) { 96722736c2fSopenharmony_ci IMSA_HILOGE("failed to get cur client info!"); 96822736c2fSopenharmony_ci return false; 96922736c2fSopenharmony_ci } 97022736c2fSopenharmony_ci auto identityChecker = std::make_shared<IdentityCheckerImpl>(); 97122736c2fSopenharmony_ci if (clientInfo->uiExtensionTokenId != IMF_INVALID_TOKENID && 97222736c2fSopenharmony_ci identityChecker->IsFocusedUIExtension(clientInfo->uiExtensionTokenId)) { 97322736c2fSopenharmony_ci IMSA_HILOGI("UIExtension focused"); 97422736c2fSopenharmony_ci return true; 97522736c2fSopenharmony_ci } 97622736c2fSopenharmony_ci return clientInfo->pid == pid && clientInfo->uid == uid; 97722736c2fSopenharmony_ci} 97822736c2fSopenharmony_ci 97922736c2fSopenharmony_cibool PerUserSession::IsCurClientUnFocused(int32_t pid, int32_t uid) 98022736c2fSopenharmony_ci{ 98122736c2fSopenharmony_ci auto clientInfo = GetCurClientInfo(); 98222736c2fSopenharmony_ci if (clientInfo == nullptr) { 98322736c2fSopenharmony_ci IMSA_HILOGE("failed to get cur client info!"); 98422736c2fSopenharmony_ci return false; 98522736c2fSopenharmony_ci } 98622736c2fSopenharmony_ci auto identityChecker = std::make_shared<IdentityCheckerImpl>(); 98722736c2fSopenharmony_ci if (clientInfo->uiExtensionTokenId != IMF_INVALID_TOKENID && 98822736c2fSopenharmony_ci !identityChecker->IsFocusedUIExtension(clientInfo->uiExtensionTokenId)) { 98922736c2fSopenharmony_ci IMSA_HILOGI("UIExtension UnFocused."); 99022736c2fSopenharmony_ci return true; 99122736c2fSopenharmony_ci } 99222736c2fSopenharmony_ci return clientInfo->pid == pid && clientInfo->uid == uid; 99322736c2fSopenharmony_ci} 99422736c2fSopenharmony_ci 99522736c2fSopenharmony_cibool PerUserSession::IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest) 99622736c2fSopenharmony_ci{ 99722736c2fSopenharmony_ci return source != nullptr && dest != nullptr && source->AsObject() == dest->AsObject(); 99822736c2fSopenharmony_ci} 99922736c2fSopenharmony_ci 100022736c2fSopenharmony_cibool PerUserSession::StartCurrentIme(bool isStopCurrentIme) 100122736c2fSopenharmony_ci{ 100222736c2fSopenharmony_ci auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 100322736c2fSopenharmony_ci auto imeToStart = ImeInfoInquirer::GetInstance().GetImeToStart(userId_); 100422736c2fSopenharmony_ci IMSA_HILOGD("currentIme: %{public}s, imeToStart: %{public}s.", currentIme->imeId.c_str(), 100522736c2fSopenharmony_ci imeToStart->imeId.c_str()); 100622736c2fSopenharmony_ci if (!StartIme(imeToStart, isStopCurrentIme)) { 100722736c2fSopenharmony_ci IMSA_HILOGE("failed to start ime!"); 100822736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ErrorCode::ERROR_IME_START_FAILED, 100922736c2fSopenharmony_ci imeToStart->imeId, "start ime failed!"); 101022736c2fSopenharmony_ci return false; 101122736c2fSopenharmony_ci } 101222736c2fSopenharmony_ci IMSA_HILOGI("current ime changed to %{public}s.", imeToStart->imeId.c_str()); 101322736c2fSopenharmony_ci auto currentImeInfo = 101422736c2fSopenharmony_ci ImeInfoInquirer::GetInstance().GetImeInfo(userId_, imeToStart->bundleName, imeToStart->subName); 101522736c2fSopenharmony_ci if (currentImeInfo != nullptr) { 101622736c2fSopenharmony_ci NotifyImeChangeToClients(currentImeInfo->prop, currentImeInfo->subProp); 101722736c2fSopenharmony_ci SwitchSubtype(currentImeInfo->subProp); 101822736c2fSopenharmony_ci } 101922736c2fSopenharmony_ci return true; 102022736c2fSopenharmony_ci} 102122736c2fSopenharmony_ci 102222736c2fSopenharmony_cibool PerUserSession::GetCurrentUsingImeId(ImeIdentification &imeId) 102322736c2fSopenharmony_ci{ 102422736c2fSopenharmony_ci if (InputTypeManager::GetInstance().IsStarted()) { 102522736c2fSopenharmony_ci IMSA_HILOGI("get right click on state current ime."); 102622736c2fSopenharmony_ci auto currentIme = InputTypeManager::GetInstance().GetCurrentIme(); 102722736c2fSopenharmony_ci imeId = currentIme; 102822736c2fSopenharmony_ci return true; 102922736c2fSopenharmony_ci } 103022736c2fSopenharmony_ci auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 103122736c2fSopenharmony_ci if (currentImeCfg == nullptr) { 103222736c2fSopenharmony_ci IMSA_HILOGE("currentImeCfg is nullptr!"); 103322736c2fSopenharmony_ci return false; 103422736c2fSopenharmony_ci } 103522736c2fSopenharmony_ci imeId.bundleName = currentImeCfg->bundleName; 103622736c2fSopenharmony_ci imeId.subName = currentImeCfg->extName; 103722736c2fSopenharmony_ci return true; 103822736c2fSopenharmony_ci} 103922736c2fSopenharmony_ci 104022736c2fSopenharmony_ciAAFwk::Want PerUserSession::GetWant(const std::shared_ptr<ImeNativeCfg> &ime) 104122736c2fSopenharmony_ci{ 104222736c2fSopenharmony_ci SecurityMode mode; 104322736c2fSopenharmony_ci bool isolatedSandBox = true; 104422736c2fSopenharmony_ci if (SecurityModeParser::GetInstance()->IsDefaultFullMode(ime->bundleName, userId_)) { 104522736c2fSopenharmony_ci mode = SecurityMode::FULL; 104622736c2fSopenharmony_ci isolatedSandBox = false; 104722736c2fSopenharmony_ci } else if (ImeInfoInquirer::GetInstance().IsEnableSecurityMode()) { 104822736c2fSopenharmony_ci mode = SecurityModeParser::GetInstance()->GetSecurityMode(ime->bundleName, userId_); 104922736c2fSopenharmony_ci } else { 105022736c2fSopenharmony_ci mode = SecurityMode::FULL; 105122736c2fSopenharmony_ci } 105222736c2fSopenharmony_ci AAFwk::Want want; 105322736c2fSopenharmony_ci want.SetElementName(ime->bundleName, ime->extName); 105422736c2fSopenharmony_ci want.SetParam(STRICT_MODE, !(mode == SecurityMode::FULL)); 105522736c2fSopenharmony_ci want.SetParam(ISOLATED_SANDBOX, isolatedSandBox); 105622736c2fSopenharmony_ci IMSA_HILOGI("userId: %{public}d, ime: %{public}s, mode: %{public}d, isolatedSandbox: %{public}d", userId_, 105722736c2fSopenharmony_ci ime->imeId.c_str(), static_cast<int32_t>(mode), isolatedSandBox); 105822736c2fSopenharmony_ci return want; 105922736c2fSopenharmony_ci} 106022736c2fSopenharmony_ci 106122736c2fSopenharmony_cibool PerUserSession::StartInputService(const std::shared_ptr<ImeNativeCfg> &ime) 106222736c2fSopenharmony_ci{ 106322736c2fSopenharmony_ci if (ime == nullptr) { 106422736c2fSopenharmony_ci return false; 106522736c2fSopenharmony_ci } 106622736c2fSopenharmony_ci isImeStarted_.Clear(false); 106722736c2fSopenharmony_ci sptr<AAFwk::IAbilityConnection> connection = new (std::nothrow) ImeConnection(); 106822736c2fSopenharmony_ci if (connection == nullptr) { 106922736c2fSopenharmony_ci IMSA_HILOGE("failed to create connection!"); 107022736c2fSopenharmony_ci return false; 107122736c2fSopenharmony_ci } 107222736c2fSopenharmony_ci auto want = GetWant(ime); 107322736c2fSopenharmony_ci auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_); 107422736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 107522736c2fSopenharmony_ci IMSA_HILOGE("connect %{public}s failed, ret: %{public}d!", ime->imeId.c_str(), ret); 107622736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ErrorCode::ERROR_IME_START_FAILED, ime->imeId, 107722736c2fSopenharmony_ci "failed to start ability."); 107822736c2fSopenharmony_ci return false; 107922736c2fSopenharmony_ci } 108022736c2fSopenharmony_ci InitImeData({ ime->bundleName, ime->extName }); 108122736c2fSopenharmony_ci if (!isImeStarted_.GetValue()) { 108222736c2fSopenharmony_ci IMSA_HILOGE("start %{public}s timeout!", ime->imeId.c_str()); 108322736c2fSopenharmony_ci return false; 108422736c2fSopenharmony_ci } 108522736c2fSopenharmony_ci IMSA_HILOGI("%{public}s started successfully.", ime->imeId.c_str()); 108622736c2fSopenharmony_ci InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::START_IME); 108722736c2fSopenharmony_ci return true; 108822736c2fSopenharmony_ci} 108922736c2fSopenharmony_ci 109022736c2fSopenharmony_ciint64_t PerUserSession::GetCurrentClientPid() 109122736c2fSopenharmony_ci{ 109222736c2fSopenharmony_ci auto client = GetCurrentClient(); 109322736c2fSopenharmony_ci if (client == nullptr) { 109422736c2fSopenharmony_ci return INVALID_PID; 109522736c2fSopenharmony_ci } 109622736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 109722736c2fSopenharmony_ci if (clientInfo == nullptr) { 109822736c2fSopenharmony_ci return INVALID_PID; 109922736c2fSopenharmony_ci } 110022736c2fSopenharmony_ci return clientInfo->pid; 110122736c2fSopenharmony_ci} 110222736c2fSopenharmony_ci 110322736c2fSopenharmony_ciint64_t PerUserSession::GetInactiveClientPid() 110422736c2fSopenharmony_ci{ 110522736c2fSopenharmony_ci auto client = GetInactiveClient(); 110622736c2fSopenharmony_ci if (client == nullptr) { 110722736c2fSopenharmony_ci return INVALID_PID; 110822736c2fSopenharmony_ci } 110922736c2fSopenharmony_ci auto clientInfo = GetClientInfo(client->AsObject()); 111022736c2fSopenharmony_ci if (clientInfo == nullptr) { 111122736c2fSopenharmony_ci return INVALID_PID; 111222736c2fSopenharmony_ci } 111322736c2fSopenharmony_ci return clientInfo->pid; 111422736c2fSopenharmony_ci} 111522736c2fSopenharmony_ci 111622736c2fSopenharmony_ciint32_t PerUserSession::OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info) 111722736c2fSopenharmony_ci{ 111822736c2fSopenharmony_ci auto clientMap = GetClientMap(); 111922736c2fSopenharmony_ci for (const auto &client : clientMap) { 112022736c2fSopenharmony_ci auto clientInfo = client.second; 112122736c2fSopenharmony_ci if (clientInfo == nullptr) { 112222736c2fSopenharmony_ci IMSA_HILOGD("client nullptr or no need to notify."); 112322736c2fSopenharmony_ci continue; 112422736c2fSopenharmony_ci } 112522736c2fSopenharmony_ci if (status == InputWindowStatus::SHOW && !EventStatusManager::IsImeShowOn(clientInfo->eventFlag)) { 112622736c2fSopenharmony_ci IMSA_HILOGD("has not imeShow callback"); 112722736c2fSopenharmony_ci continue; 112822736c2fSopenharmony_ci } 112922736c2fSopenharmony_ci if (status == InputWindowStatus::HIDE && !EventStatusManager::IsImeHideOn(clientInfo->eventFlag)) { 113022736c2fSopenharmony_ci IMSA_HILOGD("has not imeHide callback"); 113122736c2fSopenharmony_ci continue; 113222736c2fSopenharmony_ci } 113322736c2fSopenharmony_ci int32_t ret = clientInfo->client->OnPanelStatusChange(status, info); 113422736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 113522736c2fSopenharmony_ci IMSA_HILOGE("failed to OnPanelStatusChange, ret: %{public}d", ret); 113622736c2fSopenharmony_ci continue; 113722736c2fSopenharmony_ci } 113822736c2fSopenharmony_ci } 113922736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 114022736c2fSopenharmony_ci} 114122736c2fSopenharmony_ci 114222736c2fSopenharmony_ciint32_t PerUserSession::OnUpdateListenEventFlag(const InputClientInfo &clientInfo) 114322736c2fSopenharmony_ci{ 114422736c2fSopenharmony_ci auto remoteClient = clientInfo.client->AsObject(); 114522736c2fSopenharmony_ci auto ret = AddClientInfo(remoteClient, clientInfo, START_LISTENING); 114622736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 114722736c2fSopenharmony_ci IMSA_HILOGE("failed to AddClientInfo!"); 114822736c2fSopenharmony_ci return ret; 114922736c2fSopenharmony_ci } 115022736c2fSopenharmony_ci auto info = GetClientInfo(remoteClient); 115122736c2fSopenharmony_ci if (info == nullptr) { 115222736c2fSopenharmony_ci IMSA_HILOGE("info is nullptr!"); 115322736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NOT_FOUND; 115422736c2fSopenharmony_ci } 115522736c2fSopenharmony_ci if (info->eventFlag == NO_EVENT_ON && info->bindImeType == ImeType::NONE) { 115622736c2fSopenharmony_ci RemoveClientInfo(remoteClient, false); 115722736c2fSopenharmony_ci } 115822736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 115922736c2fSopenharmony_ci} 116022736c2fSopenharmony_ci 116122736c2fSopenharmony_cibool PerUserSession::IsImeStartInBind(ImeType bindImeType, ImeType startImeType) 116222736c2fSopenharmony_ci{ 116322736c2fSopenharmony_ci return startImeType == ImeType::IME && bindImeType == ImeType::IME; 116422736c2fSopenharmony_ci} 116522736c2fSopenharmony_ci 116622736c2fSopenharmony_cibool PerUserSession::IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType) 116722736c2fSopenharmony_ci{ 116822736c2fSopenharmony_ci return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::PROXY_IME; 116922736c2fSopenharmony_ci} 117022736c2fSopenharmony_ci 117122736c2fSopenharmony_cibool PerUserSession::IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType) 117222736c2fSopenharmony_ci{ 117322736c2fSopenharmony_ci return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::IME; 117422736c2fSopenharmony_ci} 117522736c2fSopenharmony_ci 117622736c2fSopenharmony_cibool PerUserSession::IsImeBindChanged(ImeType bindImeType) 117722736c2fSopenharmony_ci{ 117822736c2fSopenharmony_ci return (bindImeType == ImeType::IME && IsProxyImeEnable()) || 117922736c2fSopenharmony_ci (bindImeType == ImeType::PROXY_IME && !IsProxyImeEnable()); 118022736c2fSopenharmony_ci} 118122736c2fSopenharmony_ci 118222736c2fSopenharmony_ciint32_t PerUserSession::SwitchSubtype(const SubProperty &subProperty) 118322736c2fSopenharmony_ci{ 118422736c2fSopenharmony_ci auto data = GetValidIme(ImeType::IME); 118522736c2fSopenharmony_ci if (data == nullptr) { 118622736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); 118722736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 118822736c2fSopenharmony_ci } 118922736c2fSopenharmony_ci return RequestIme(data, RequestType::NORMAL, [&data, &subProperty] { return data->core->SetSubtype(subProperty); }); 119022736c2fSopenharmony_ci} 119122736c2fSopenharmony_ci 119222736c2fSopenharmony_ciint32_t PerUserSession::SetInputType() 119322736c2fSopenharmony_ci{ 119422736c2fSopenharmony_ci InputType inputType = InputTypeManager::GetInstance().GetCurrentInputType(); 119522736c2fSopenharmony_ci auto data = GetValidIme(ImeType::IME); 119622736c2fSopenharmony_ci if (data == nullptr) { 119722736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); 119822736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 119922736c2fSopenharmony_ci } 120022736c2fSopenharmony_ci return RequestIme(data, RequestType::NORMAL, [&data, &inputType] { return data->core->OnSetInputType(inputType); }); 120122736c2fSopenharmony_ci} 120222736c2fSopenharmony_ci 120322736c2fSopenharmony_cibool PerUserSession::IsBoundToClient() 120422736c2fSopenharmony_ci{ 120522736c2fSopenharmony_ci if (GetCurrentClient() == nullptr) { 120622736c2fSopenharmony_ci IMSA_HILOGE("not in bound state!"); 120722736c2fSopenharmony_ci return false; 120822736c2fSopenharmony_ci } 120922736c2fSopenharmony_ci return true; 121022736c2fSopenharmony_ci} 121122736c2fSopenharmony_ci 121222736c2fSopenharmony_ciint32_t PerUserSession::RestoreCurrentImeSubType() 121322736c2fSopenharmony_ci{ 121422736c2fSopenharmony_ci if (!InputTypeManager::GetInstance().IsStarted()) { 121522736c2fSopenharmony_ci IMSA_HILOGD("already exit."); 121622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 121722736c2fSopenharmony_ci } 121822736c2fSopenharmony_ci auto typeIme = InputTypeManager::GetInstance().GetCurrentIme(); 121922736c2fSopenharmony_ci auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); 122022736c2fSopenharmony_ci if (cfgIme->bundleName != typeIme.bundleName) { 122122736c2fSopenharmony_ci IMSA_HILOGD("diff ime, not deal, restore ime when attach."); 122222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 122322736c2fSopenharmony_ci } 122422736c2fSopenharmony_ci auto imeData = GetReadyImeData(ImeType::IME); 122522736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 122622736c2fSopenharmony_ci if (imeData == nullptr || imeData->ime.first != cfgIme->bundleName || imeData->ime.second != cfgIme->extName) { 122722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 122822736c2fSopenharmony_ci } 122922736c2fSopenharmony_ci SubProperty subProp = { .name = cfgIme->bundleName, .id = cfgIme->subName }; 123022736c2fSopenharmony_ci auto subPropTemp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(userId_); 123122736c2fSopenharmony_ci if (subPropTemp != nullptr) { 123222736c2fSopenharmony_ci subProp = *subPropTemp; 123322736c2fSopenharmony_ci } 123422736c2fSopenharmony_ci IMSA_HILOGD("same ime, restore subtype: %{public}s.", cfgIme->subName.c_str()); 123522736c2fSopenharmony_ci return SwitchSubtype(subProp); 123622736c2fSopenharmony_ci} 123722736c2fSopenharmony_ci 123822736c2fSopenharmony_cibool PerUserSession::IsCurrentImeByPid(int32_t pid) 123922736c2fSopenharmony_ci{ 124022736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 124122736c2fSopenharmony_ci if (imeData == nullptr) { 124222736c2fSopenharmony_ci IMSA_HILOGE("ime not started!"); 124322736c2fSopenharmony_ci return false; 124422736c2fSopenharmony_ci } 124522736c2fSopenharmony_ci IMSA_HILOGD("userId: %{public}d, pid: %{public}d, current pid: %{public}d.", userId_, pid, imeData->pid); 124622736c2fSopenharmony_ci return imeData->pid == pid; 124722736c2fSopenharmony_ci} 124822736c2fSopenharmony_ci 124922736c2fSopenharmony_ciint32_t PerUserSession::IsPanelShown(const PanelInfo &panelInfo, bool &isShown) 125022736c2fSopenharmony_ci{ 125122736c2fSopenharmony_ci if (GetCurrentClient() == nullptr) { 125222736c2fSopenharmony_ci IMSA_HILOGD("not in bound state."); 125322736c2fSopenharmony_ci isShown = false; 125422736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 125522736c2fSopenharmony_ci } 125622736c2fSopenharmony_ci auto ime = GetReadyImeData(ImeType::IME); 125722736c2fSopenharmony_ci if (ime == nullptr) { 125822736c2fSopenharmony_ci IMSA_HILOGE("ime not started!"); 125922736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 126022736c2fSopenharmony_ci } 126122736c2fSopenharmony_ci return RequestIme(ime, RequestType::NORMAL, 126222736c2fSopenharmony_ci [&ime, &panelInfo, &isShown] { return ime->core->IsPanelShown(panelInfo, isShown); }); 126322736c2fSopenharmony_ci} 126422736c2fSopenharmony_ci 126522736c2fSopenharmony_cibool PerUserSession::CheckSecurityMode() 126622736c2fSopenharmony_ci{ 126722736c2fSopenharmony_ci auto client = GetCurrentClient(); 126822736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 126922736c2fSopenharmony_ci if (clientInfo != nullptr) { 127022736c2fSopenharmony_ci return clientInfo->config.inputAttribute.GetSecurityFlag(); 127122736c2fSopenharmony_ci } 127222736c2fSopenharmony_ci return false; 127322736c2fSopenharmony_ci} 127422736c2fSopenharmony_ci 127522736c2fSopenharmony_cistd::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> PerUserSession::GetClientMap() 127622736c2fSopenharmony_ci{ 127722736c2fSopenharmony_ci std::lock_guard<std::recursive_mutex> lock(mtx); 127822736c2fSopenharmony_ci return mapClients_; 127922736c2fSopenharmony_ci} 128022736c2fSopenharmony_ci 128122736c2fSopenharmony_ciint32_t PerUserSession::RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec) 128222736c2fSopenharmony_ci{ 128322736c2fSopenharmony_ci if (IsProxyImeEnable()) { 128422736c2fSopenharmony_ci IMSA_HILOGD("proxy enable."); 128522736c2fSopenharmony_ci return exec(); 128622736c2fSopenharmony_ci } 128722736c2fSopenharmony_ci if (data == nullptr || data->freezeMgr == nullptr) { 128822736c2fSopenharmony_ci IMSA_HILOGE("data is nullptr!"); 128922736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 129022736c2fSopenharmony_ci } 129122736c2fSopenharmony_ci data->freezeMgr->BeforeIpc(type); 129222736c2fSopenharmony_ci auto ret = exec(); 129322736c2fSopenharmony_ci data->freezeMgr->AfterIpc(type, ret == ErrorCode::NO_ERROR); 129422736c2fSopenharmony_ci return ret; 129522736c2fSopenharmony_ci} 129622736c2fSopenharmony_ci 129722736c2fSopenharmony_ciint32_t PerUserSession::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent) 129822736c2fSopenharmony_ci{ 129922736c2fSopenharmony_ci auto data = GetReadyImeData(ImeType::IME); 130022736c2fSopenharmony_ci if (data == nullptr) { 130122736c2fSopenharmony_ci IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); 130222736c2fSopenharmony_ci return ErrorCode::ERROR_IME_NOT_STARTED; 130322736c2fSopenharmony_ci } 130422736c2fSopenharmony_ci auto ret = RequestIme(data, RequestType::NORMAL, 130522736c2fSopenharmony_ci [&data, &channel, &agent] { return data->core->OnConnectSystemCmd(channel, agent); }); 130622736c2fSopenharmony_ci IMSA_HILOGD("on connect systemCmd, ret: %{public}d.", ret); 130722736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 130822736c2fSopenharmony_ci IMSA_HILOGE("bind failed, ret: %{public}d!", ret); 130922736c2fSopenharmony_ci return ret; 131022736c2fSopenharmony_ci } 131122736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 131222736c2fSopenharmony_ci} 131322736c2fSopenharmony_ci 131422736c2fSopenharmony_cibool PerUserSession::WaitForCurrentImeStop() 131522736c2fSopenharmony_ci{ 131622736c2fSopenharmony_ci IMSA_HILOGI("start."); 131722736c2fSopenharmony_ci std::unique_lock<std::mutex> lock(imeStopMutex_); 131822736c2fSopenharmony_ci isSwitching_.store(true); 131922736c2fSopenharmony_ci return imeStopCv_.wait_for(lock, std::chrono::milliseconds(STOP_IME_TIME), [this]() { return !isSwitching_; }); 132022736c2fSopenharmony_ci} 132122736c2fSopenharmony_ci 132222736c2fSopenharmony_civoid PerUserSession::NotifyImeStopFinished() 132322736c2fSopenharmony_ci{ 132422736c2fSopenharmony_ci IMSA_HILOGI("start."); 132522736c2fSopenharmony_ci std::unique_lock<std::mutex> lock(imeStopMutex_); 132622736c2fSopenharmony_ci isSwitching_.store(false); 132722736c2fSopenharmony_ci imeStopCv_.notify_one(); 132822736c2fSopenharmony_ci} 132922736c2fSopenharmony_ci 133022736c2fSopenharmony_ciint32_t PerUserSession::RemoveCurrentClient() 133122736c2fSopenharmony_ci{ 133222736c2fSopenharmony_ci auto currentClient = GetCurrentClient(); 133322736c2fSopenharmony_ci if (currentClient == nullptr) { 133422736c2fSopenharmony_ci IMSA_HILOGE("currentClient is nullptr!"); 133522736c2fSopenharmony_ci return ErrorCode::ERROR_CLIENT_NULL_POINTER; 133622736c2fSopenharmony_ci } 133722736c2fSopenharmony_ci return RemoveClient(currentClient, false); 133822736c2fSopenharmony_ci} 133922736c2fSopenharmony_ci 134022736c2fSopenharmony_cibool PerUserSession::IsWmsReady() 134122736c2fSopenharmony_ci{ 134222736c2fSopenharmony_ci if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) { 134322736c2fSopenharmony_ci IMSA_HILOGD("scb enable"); 134422736c2fSopenharmony_ci return WmsConnectionObserver::IsWmsConnected(userId_); 134522736c2fSopenharmony_ci } 134622736c2fSopenharmony_ci return IsReady(WINDOW_MANAGER_SERVICE_ID); 134722736c2fSopenharmony_ci} 134822736c2fSopenharmony_ci 134922736c2fSopenharmony_cibool PerUserSession::IsReady(int32_t saId) 135022736c2fSopenharmony_ci{ 135122736c2fSopenharmony_ci auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 135222736c2fSopenharmony_ci if (saMgr == nullptr) { 135322736c2fSopenharmony_ci IMSA_HILOGE("get saMgr failed!"); 135422736c2fSopenharmony_ci return false; 135522736c2fSopenharmony_ci } 135622736c2fSopenharmony_ci if (saMgr->CheckSystemAbility(saId) == nullptr) { 135722736c2fSopenharmony_ci IMSA_HILOGE("sa:%{public}d not ready!", saId); 135822736c2fSopenharmony_ci return false; 135922736c2fSopenharmony_ci } 136022736c2fSopenharmony_ci return true; 136122736c2fSopenharmony_ci} 136222736c2fSopenharmony_ci 136322736c2fSopenharmony_civoid PerUserSession::AddRestartIme() 136422736c2fSopenharmony_ci{ 136522736c2fSopenharmony_ci int32_t tasks = 0; 136622736c2fSopenharmony_ci { 136722736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(restartMutex_); 136822736c2fSopenharmony_ci if (restartTasks_ >= MAX_RESTART_TASKS) { 136922736c2fSopenharmony_ci return; 137022736c2fSopenharmony_ci } 137122736c2fSopenharmony_ci restartTasks_ = std::max(restartTasks_, 0); 137222736c2fSopenharmony_ci tasks = ++restartTasks_; 137322736c2fSopenharmony_ci } 137422736c2fSopenharmony_ci if (tasks == 1 && !RestartIme()) { 137522736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(restartMutex_); 137622736c2fSopenharmony_ci restartTasks_ = 0; 137722736c2fSopenharmony_ci } 137822736c2fSopenharmony_ci} 137922736c2fSopenharmony_ci 138022736c2fSopenharmony_cibool PerUserSession::RestartIme() 138122736c2fSopenharmony_ci{ 138222736c2fSopenharmony_ci auto task = [this]() { 138322736c2fSopenharmony_ci if (IsReady(MEMORY_MANAGER_SA_ID) && IsWmsReady() && runningIme_.empty()) { 138422736c2fSopenharmony_ci auto ret = StartCurrentIme(true); 138522736c2fSopenharmony_ci if (!ret) { 138622736c2fSopenharmony_ci IMSA_HILOGE("start ime failed!"); 138722736c2fSopenharmony_ci } 138822736c2fSopenharmony_ci } 138922736c2fSopenharmony_ci int32_t tasks = 0; 139022736c2fSopenharmony_ci { 139122736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(restartMutex_); 139222736c2fSopenharmony_ci tasks = --restartTasks_; 139322736c2fSopenharmony_ci } 139422736c2fSopenharmony_ci if (tasks > 0 && !RestartIme()) { 139522736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(restartMutex_); 139622736c2fSopenharmony_ci restartTasks_ = 0; 139722736c2fSopenharmony_ci } 139822736c2fSopenharmony_ci }; 139922736c2fSopenharmony_ci if (eventHandler_ == nullptr) { 140022736c2fSopenharmony_ci IMSA_HILOGE("eventHandler_ is nullptr!"); 140122736c2fSopenharmony_ci return false; 140222736c2fSopenharmony_ci } 140322736c2fSopenharmony_ci return eventHandler_->PostTask(task, "RestartCurrentImeTask", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); 140422736c2fSopenharmony_ci} 140522736c2fSopenharmony_ci 140622736c2fSopenharmony_ciBlockQueue<SwitchInfo>& PerUserSession::GetSwitchQueue() 140722736c2fSopenharmony_ci{ 140822736c2fSopenharmony_ci return switchQueue_; 140922736c2fSopenharmony_ci} 141022736c2fSopenharmony_ci 141122736c2fSopenharmony_ciint32_t PerUserSession::InitImeData(const std::pair<std::string, std::string> &ime) 141222736c2fSopenharmony_ci{ 141322736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 141422736c2fSopenharmony_ci auto it = imeData_.find(ImeType::IME); 141522736c2fSopenharmony_ci if (it != imeData_.end()) { 141622736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 141722736c2fSopenharmony_ci } 141822736c2fSopenharmony_ci auto imeData = std::make_shared<ImeData>(nullptr, nullptr, nullptr, -1); 141922736c2fSopenharmony_ci imeData->startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); 142022736c2fSopenharmony_ci imeData->ime = ime; 142122736c2fSopenharmony_ci imeData_.insert({ ImeType::IME, imeData }); 142222736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 142322736c2fSopenharmony_ci} 142422736c2fSopenharmony_ci 142522736c2fSopenharmony_ciint32_t PerUserSession::UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid) 142622736c2fSopenharmony_ci{ 142722736c2fSopenharmony_ci if (core == nullptr || agent == nullptr) { 142822736c2fSopenharmony_ci IMSA_HILOGE("core or agent is nullptr!"); 142922736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 143022736c2fSopenharmony_ci } 143122736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 143222736c2fSopenharmony_ci auto it = imeData_.find(ImeType::IME); 143322736c2fSopenharmony_ci if (it == imeData_.end()) { 143422736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 143522736c2fSopenharmony_ci } 143622736c2fSopenharmony_ci it->second->core = core; 143722736c2fSopenharmony_ci it->second->agent = agent; 143822736c2fSopenharmony_ci it->second->pid = pid; 143922736c2fSopenharmony_ci it->second->freezeMgr = std::make_shared<FreezeManager>(pid); 144022736c2fSopenharmony_ci sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient(); 144122736c2fSopenharmony_ci if (deathRecipient == nullptr) { 144222736c2fSopenharmony_ci IMSA_HILOGE("failed to new deathRecipient!"); 144322736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 144422736c2fSopenharmony_ci } 144522736c2fSopenharmony_ci auto type = ImeType::IME; 144622736c2fSopenharmony_ci deathRecipient->SetDeathRecipient([this, core, type](const wptr<IRemoteObject> &) { this->OnImeDied(core, type); }); 144722736c2fSopenharmony_ci auto coreObject = core->AsObject(); 144822736c2fSopenharmony_ci if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) { 144922736c2fSopenharmony_ci IMSA_HILOGE("failed to add death recipient!"); 145022736c2fSopenharmony_ci return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; 145122736c2fSopenharmony_ci } 145222736c2fSopenharmony_ci it->second->deathRecipient = deathRecipient; 145322736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 145422736c2fSopenharmony_ci} 145522736c2fSopenharmony_ci 145622736c2fSopenharmony_ciint32_t PerUserSession::InitConnect(pid_t pid) 145722736c2fSopenharmony_ci{ 145822736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 145922736c2fSopenharmony_ci auto it = imeData_.find(ImeType::IME); 146022736c2fSopenharmony_ci if (it == imeData_.end()) { 146122736c2fSopenharmony_ci return ErrorCode::ERROR_NULL_POINTER; 146222736c2fSopenharmony_ci } 146322736c2fSopenharmony_ci it->second->pid = pid; 146422736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 146522736c2fSopenharmony_ci} 146622736c2fSopenharmony_ci 146722736c2fSopenharmony_cistd::shared_ptr<ImeData> PerUserSession::GetImeData(ImeType type) 146822736c2fSopenharmony_ci{ 146922736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 147022736c2fSopenharmony_ci auto it = imeData_.find(type); 147122736c2fSopenharmony_ci if (it == imeData_.end()) { 147222736c2fSopenharmony_ci return nullptr; 147322736c2fSopenharmony_ci } 147422736c2fSopenharmony_ci return it->second; 147522736c2fSopenharmony_ci} 147622736c2fSopenharmony_ci 147722736c2fSopenharmony_cibool PerUserSession::StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme) 147822736c2fSopenharmony_ci{ 147922736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeStartLock_); 148022736c2fSopenharmony_ci if (ime == nullptr) { 148122736c2fSopenharmony_ci return false; 148222736c2fSopenharmony_ci } 148322736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 148422736c2fSopenharmony_ci if (imeData == nullptr) { 148522736c2fSopenharmony_ci return HandleFirstStart(ime, isStopCurrentIme); 148622736c2fSopenharmony_ci } 148722736c2fSopenharmony_ci if (imeData->ime.first == ime->bundleName && imeData->ime.second == ime->extName) { 148822736c2fSopenharmony_ci if (isStopCurrentIme) { 148922736c2fSopenharmony_ci return StartNewIme(ime); 149022736c2fSopenharmony_ci } 149122736c2fSopenharmony_ci return StartCurrentIme(ime); 149222736c2fSopenharmony_ci } 149322736c2fSopenharmony_ci return StartNewIme(ime); 149422736c2fSopenharmony_ci} 149522736c2fSopenharmony_ci 149622736c2fSopenharmony_ciImeAction PerUserSession::GetImeAction(ImeEvent action) 149722736c2fSopenharmony_ci{ 149822736c2fSopenharmony_ci std::lock_guard<std::mutex> lock(imeDataLock_); 149922736c2fSopenharmony_ci auto it = imeData_.find(ImeType::IME); 150022736c2fSopenharmony_ci if (it == imeData_.end()) { 150122736c2fSopenharmony_ci return ImeAction::DO_ACTION_IN_NULL_IME_DATA; 150222736c2fSopenharmony_ci } 150322736c2fSopenharmony_ci auto iter = imeEventConverter_.find({ it->second->imeStatus, action }); 150422736c2fSopenharmony_ci if (iter == imeEventConverter_.end()) { 150522736c2fSopenharmony_ci IMSA_HILOGE("abnormal!"); 150622736c2fSopenharmony_ci return ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED; 150722736c2fSopenharmony_ci } 150822736c2fSopenharmony_ci it->second->imeStatus = iter->second.first; 150922736c2fSopenharmony_ci return iter->second.second; 151022736c2fSopenharmony_ci} 151122736c2fSopenharmony_ci 151222736c2fSopenharmony_cibool PerUserSession::StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime) 151322736c2fSopenharmony_ci{ 151422736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 151522736c2fSopenharmony_ci if (imeData == nullptr) { 151622736c2fSopenharmony_ci return StartInputService(ime); 151722736c2fSopenharmony_ci } 151822736c2fSopenharmony_ci auto action = GetImeAction(ImeEvent::START_IME); 151922736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) { 152022736c2fSopenharmony_ci return false; 152122736c2fSopenharmony_ci } 152222736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) { 152322736c2fSopenharmony_ci return StartInputService(ime); 152422736c2fSopenharmony_ci } 152522736c2fSopenharmony_ci if (action == ImeAction::DO_NOTHING) { 152622736c2fSopenharmony_ci return true; 152722736c2fSopenharmony_ci } 152822736c2fSopenharmony_ci if (action == ImeAction::HANDLE_STARTING_IME) { 152922736c2fSopenharmony_ci int64_t time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); 153022736c2fSopenharmony_ci if (time - imeData->startTime > ImeData::START_TIME_OUT) { 153122736c2fSopenharmony_ci IMSA_HILOGE("[%{public}s, %{public}s] start abnormal, more than eight second!", imeData->ime.first.c_str(), 153222736c2fSopenharmony_ci imeData->ime.second.c_str()); 153322736c2fSopenharmony_ci return HandleStartImeTimeout(ime); 153422736c2fSopenharmony_ci } 153522736c2fSopenharmony_ci return StartInputService(ime); 153622736c2fSopenharmony_ci } 153722736c2fSopenharmony_ci if (!StopExitingCurrentIme()) { 153822736c2fSopenharmony_ci return false; 153922736c2fSopenharmony_ci } 154022736c2fSopenharmony_ci return StartInputService(ime); 154122736c2fSopenharmony_ci} 154222736c2fSopenharmony_ci 154322736c2fSopenharmony_cibool PerUserSession::HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime) 154422736c2fSopenharmony_ci{ 154522736c2fSopenharmony_ci auto action = GetImeAction(ImeEvent::START_IME_TIMEOUT); 154622736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) { 154722736c2fSopenharmony_ci return StartInputService(ime); 154822736c2fSopenharmony_ci } 154922736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) { 155022736c2fSopenharmony_ci return false; 155122736c2fSopenharmony_ci } 155222736c2fSopenharmony_ci if (action == ImeAction::DO_NOTHING) { 155322736c2fSopenharmony_ci IMSA_HILOGW("ready when timeout"); 155422736c2fSopenharmony_ci return true; 155522736c2fSopenharmony_ci } 155622736c2fSopenharmony_ci ForceStopCurrentIme(false); 155722736c2fSopenharmony_ci return false; 155822736c2fSopenharmony_ci} 155922736c2fSopenharmony_ci 156022736c2fSopenharmony_cibool PerUserSession::StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime) 156122736c2fSopenharmony_ci{ 156222736c2fSopenharmony_ci if (!StopCurrentIme()) { 156322736c2fSopenharmony_ci return false; 156422736c2fSopenharmony_ci } 156522736c2fSopenharmony_ci return StartInputService(ime); 156622736c2fSopenharmony_ci} 156722736c2fSopenharmony_ci 156822736c2fSopenharmony_cibool PerUserSession::StopCurrentIme() 156922736c2fSopenharmony_ci{ 157022736c2fSopenharmony_ci auto action = GetImeAction(ImeEvent::STOP_IME); 157122736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) { 157222736c2fSopenharmony_ci return true; 157322736c2fSopenharmony_ci } 157422736c2fSopenharmony_ci if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) { 157522736c2fSopenharmony_ci return false; 157622736c2fSopenharmony_ci } 157722736c2fSopenharmony_ci if (action == ImeAction::STOP_READY_IME) { 157822736c2fSopenharmony_ci return StopReadyCurrentIme(); 157922736c2fSopenharmony_ci } 158022736c2fSopenharmony_ci if (action == ImeAction::STOP_STARTING_IME) { 158122736c2fSopenharmony_ci return ForceStopCurrentIme(); 158222736c2fSopenharmony_ci } 158322736c2fSopenharmony_ci return StopExitingCurrentIme(); 158422736c2fSopenharmony_ci} 158522736c2fSopenharmony_ci 158622736c2fSopenharmony_cibool PerUserSession::StopReadyCurrentIme() 158722736c2fSopenharmony_ci{ 158822736c2fSopenharmony_ci auto client = GetCurrentClient(); 158922736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 159022736c2fSopenharmony_ci if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) { 159122736c2fSopenharmony_ci StopClientInput(clientInfo); 159222736c2fSopenharmony_ci } 159322736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 159422736c2fSopenharmony_ci if (imeData == nullptr) { 159522736c2fSopenharmony_ci return true; 159622736c2fSopenharmony_ci } 159722736c2fSopenharmony_ci if (imeData->core == nullptr) { 159822736c2fSopenharmony_ci IMSA_HILOGE("core is nullptr!"); 159922736c2fSopenharmony_ci return ForceStopCurrentIme(); 160022736c2fSopenharmony_ci } 160122736c2fSopenharmony_ci auto ret = RequestIme(imeData, RequestType::NORMAL, [&imeData] { 160222736c2fSopenharmony_ci // failed when register onInputStop after SetCoreAndAgent 160322736c2fSopenharmony_ci return imeData->core->StopInputService(true); 160422736c2fSopenharmony_ci }); 160522736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 160622736c2fSopenharmony_ci IMSA_HILOGE("StopInputService failed."); 160722736c2fSopenharmony_ci return ForceStopCurrentIme(); 160822736c2fSopenharmony_ci } 160922736c2fSopenharmony_ci if (!WaitForCurrentImeStop()) { 161022736c2fSopenharmony_ci IMSA_HILOGI("stop timeout."); 161122736c2fSopenharmony_ci return ForceStopCurrentIme(); 161222736c2fSopenharmony_ci } 161322736c2fSopenharmony_ci return true; 161422736c2fSopenharmony_ci} 161522736c2fSopenharmony_ci 161622736c2fSopenharmony_cibool PerUserSession::StopExitingCurrentIme() 161722736c2fSopenharmony_ci{ 161822736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 161922736c2fSopenharmony_ci if (imeData == nullptr) { 162022736c2fSopenharmony_ci return true; 162122736c2fSopenharmony_ci } 162222736c2fSopenharmony_ci if (!ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) { 162322736c2fSopenharmony_ci IMSA_HILOGD("already stop!"); 162422736c2fSopenharmony_ci RemoveImeData(ImeType::IME, true); 162522736c2fSopenharmony_ci return true; 162622736c2fSopenharmony_ci } 162722736c2fSopenharmony_ci return ForceStopCurrentIme(); 162822736c2fSopenharmony_ci} 162922736c2fSopenharmony_ci 163022736c2fSopenharmony_cibool PerUserSession::ForceStopCurrentIme(bool isNeedWait) 163122736c2fSopenharmony_ci{ 163222736c2fSopenharmony_ci auto client = GetCurrentClient(); 163322736c2fSopenharmony_ci auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr; 163422736c2fSopenharmony_ci if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) { 163522736c2fSopenharmony_ci StopClientInput(clientInfo); 163622736c2fSopenharmony_ci } 163722736c2fSopenharmony_ci auto imeData = GetImeData(ImeType::IME); 163822736c2fSopenharmony_ci if (imeData == nullptr) { 163922736c2fSopenharmony_ci return true; 164022736c2fSopenharmony_ci } 164122736c2fSopenharmony_ci AAFwk::Want want; 164222736c2fSopenharmony_ci want.SetElementName(imeData->ime.first, imeData->ime.second); 164322736c2fSopenharmony_ci auto ret = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility( 164422736c2fSopenharmony_ci want, nullptr, userId_, AppExecFwk::ExtensionAbilityType::INPUTMETHOD); 164522736c2fSopenharmony_ci if (ret != ErrorCode::NO_ERROR) { 164622736c2fSopenharmony_ci IMSA_HILOGE("StopExtensionAbility [%{public}s, %{public}s] failed, ret: %{public}d!", 164722736c2fSopenharmony_ci imeData->ime.first.c_str(), imeData->ime.second.c_str(), ret); 164822736c2fSopenharmony_ci return false; 164922736c2fSopenharmony_ci } 165022736c2fSopenharmony_ci if (!isNeedWait) { 165122736c2fSopenharmony_ci return true; 165222736c2fSopenharmony_ci } 165322736c2fSopenharmony_ci WaitForCurrentImeStop(); 165422736c2fSopenharmony_ci if (ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) { 165522736c2fSopenharmony_ci IMSA_HILOGW("stop [%{public}s, %{public}s] timeout.", imeData->ime.first.c_str(), imeData->ime.second.c_str()); 165622736c2fSopenharmony_ci return false; 165722736c2fSopenharmony_ci } 165822736c2fSopenharmony_ci RemoveImeData(ImeType::IME, true); 165922736c2fSopenharmony_ci return true; 166022736c2fSopenharmony_ci} 166122736c2fSopenharmony_ci 166222736c2fSopenharmony_cibool PerUserSession::HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme) 166322736c2fSopenharmony_ci{ 166422736c2fSopenharmony_ci if (runningIme_.empty()) { 166522736c2fSopenharmony_ci return StartInputService(ime); 166622736c2fSopenharmony_ci } 166722736c2fSopenharmony_ci IMSA_HILOGW("imsa abnormal restore."); 166822736c2fSopenharmony_ci if (isStopCurrentIme) { 166922736c2fSopenharmony_ci return true; 167022736c2fSopenharmony_ci } 167122736c2fSopenharmony_ci if (BlockRetry(CHECK_IME_RUNNING_RETRY_INTERVAL, CHECK_IME_RUNNING_RETRY_TIMES, 167222736c2fSopenharmony_ci [this]() -> bool { return !ImeInfoInquirer::GetInstance().IsRunningIme(userId_, runningIme_); })) { 167322736c2fSopenharmony_ci IMSA_HILOGI("[%{public}d, %{public}s] stop completely", userId_, runningIme_.c_str()); 167422736c2fSopenharmony_ci runningIme_.clear(); 167522736c2fSopenharmony_ci return StartInputService(ime); 167622736c2fSopenharmony_ci } 167722736c2fSopenharmony_ci IMSA_HILOGW("[%{public}d, %{public}s] stop timeout", userId_, runningIme_.c_str()); 167822736c2fSopenharmony_ci return false; 167922736c2fSopenharmony_ci} 168022736c2fSopenharmony_ci 168122736c2fSopenharmony_ciint32_t PerUserSession::RestoreCurrentIme() 168222736c2fSopenharmony_ci{ 168322736c2fSopenharmony_ci InputTypeManager::GetInstance().Set(false); 168422736c2fSopenharmony_ci auto cfgIme = ImeInfoInquirer::GetInstance().GetImeToStart(userId_); 168522736c2fSopenharmony_ci auto imeData = GetReadyImeData(ImeType::IME); 168622736c2fSopenharmony_ci if (imeData != nullptr && imeData->ime.first == cfgIme->bundleName && imeData->ime.second == cfgIme->extName) { 168722736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 168822736c2fSopenharmony_ci } 168922736c2fSopenharmony_ci IMSA_HILOGD("need restore!"); 169022736c2fSopenharmony_ci if (!StartIme(cfgIme)) { 169122736c2fSopenharmony_ci IMSA_HILOGE("start ime failed!"); 169222736c2fSopenharmony_ci return ErrorCode::ERROR_IME_START_FAILED; 169322736c2fSopenharmony_ci } 169422736c2fSopenharmony_ci SubProperty subProp = { .name = cfgIme->bundleName, .id = cfgIme->subName }; 169522736c2fSopenharmony_ci auto subPropTemp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(userId_); 169622736c2fSopenharmony_ci if (subPropTemp != nullptr) { 169722736c2fSopenharmony_ci subProp = *subPropTemp; 169822736c2fSopenharmony_ci } 169922736c2fSopenharmony_ci SwitchSubtype(subProp); 170022736c2fSopenharmony_ci return ErrorCode::NO_ERROR; 170122736c2fSopenharmony_ci} 170222736c2fSopenharmony_ci 170322736c2fSopenharmony_cibool PerUserSession::CheckPwdInputPatternConv(InputClientInfo &newClientInfo) 170422736c2fSopenharmony_ci{ 170522736c2fSopenharmony_ci auto exClient = GetCurrentClient(); 170622736c2fSopenharmony_ci if (exClient == nullptr) { 170722736c2fSopenharmony_ci exClient = GetInactiveClient(); 170822736c2fSopenharmony_ci } 170922736c2fSopenharmony_ci auto exClientInfo = exClient != nullptr ? GetClientInfo(exClient->AsObject()) : nullptr; 171022736c2fSopenharmony_ci if (exClientInfo == nullptr) { 171122736c2fSopenharmony_ci IMSA_HILOGE("exClientInfo is nullptr!"); 171222736c2fSopenharmony_ci return false; 171322736c2fSopenharmony_ci } 171422736c2fSopenharmony_ci // if current input pattern differ from previous in pwd and normal, need hide panel first. 171522736c2fSopenharmony_ci if (newClientInfo.config.inputAttribute.GetSecurityFlag()) { 171622736c2fSopenharmony_ci IMSA_HILOGI("new input pattern is pwd."); 171722736c2fSopenharmony_ci return !exClientInfo->config.inputAttribute.GetSecurityFlag(); 171822736c2fSopenharmony_ci } 171922736c2fSopenharmony_ci IMSA_HILOGI("new input pattern is normal."); 172022736c2fSopenharmony_ci return exClientInfo->config.inputAttribute.GetSecurityFlag(); 172122736c2fSopenharmony_ci} 172222736c2fSopenharmony_ci} // namespace MiscServices 172322736c2fSopenharmony_ci} // namespace OHOS