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#ifndef SERVICES_INCLUDE_PERUSER_SESSION_H 1722736c2fSopenharmony_ci#define SERVICES_INCLUDE_PERUSER_SESSION_H 1822736c2fSopenharmony_ci 1922736c2fSopenharmony_ci#include <functional> 2022736c2fSopenharmony_ci#include <map> 2122736c2fSopenharmony_ci#include <memory> 2222736c2fSopenharmony_ci#include <mutex> 2322736c2fSopenharmony_ci#include <thread> 2422736c2fSopenharmony_ci#include <variant> 2522736c2fSopenharmony_ci 2622736c2fSopenharmony_ci#include "block_data.h" 2722736c2fSopenharmony_ci#include "block_queue.h" 2822736c2fSopenharmony_ci#include "enable_ime_data_parser.h" 2922736c2fSopenharmony_ci#include "event_handler.h" 3022736c2fSopenharmony_ci#include "event_status_manager.h" 3122736c2fSopenharmony_ci#include "freeze_manager.h" 3222736c2fSopenharmony_ci#include "global.h" 3322736c2fSopenharmony_ci#include "i_input_client.h" 3422736c2fSopenharmony_ci#include "i_input_control_channel.h" 3522736c2fSopenharmony_ci#include "i_input_data_channel.h" 3622736c2fSopenharmony_ci#include "i_input_method_agent.h" 3722736c2fSopenharmony_ci#include "i_input_method_core.h" 3822736c2fSopenharmony_ci#include "i_system_cmd_channel.h" 3922736c2fSopenharmony_ci#include "ime_cfg_manager.h" 4022736c2fSopenharmony_ci#include "input_attribute.h" 4122736c2fSopenharmony_ci#include "input_client_info.h" 4222736c2fSopenharmony_ci#include "input_death_recipient.h" 4322736c2fSopenharmony_ci#include "input_method_info.h" 4422736c2fSopenharmony_ci#include "input_method_property.h" 4522736c2fSopenharmony_ci#include "input_type_manager.h" 4622736c2fSopenharmony_ci#include "input_window_info.h" 4722736c2fSopenharmony_ci#include "inputmethod_sysevent.h" 4822736c2fSopenharmony_ci#include "iremote_object.h" 4922736c2fSopenharmony_ci#include "message.h" 5022736c2fSopenharmony_ci#include "message_handler.h" 5122736c2fSopenharmony_ci#include "panel_info.h" 5222736c2fSopenharmony_ci#include "input_method_types.h" 5322736c2fSopenharmony_ci#include "want.h" 5422736c2fSopenharmony_ci 5522736c2fSopenharmony_cinamespace OHOS { 5622736c2fSopenharmony_cinamespace MiscServices { 5722736c2fSopenharmony_cienum class ImeStatus : uint32_t { STARTING, READY, EXITING }; 5822736c2fSopenharmony_cienum class ImeEvent : uint32_t { 5922736c2fSopenharmony_ci START_IME, 6022736c2fSopenharmony_ci START_IME_TIMEOUT, 6122736c2fSopenharmony_ci STOP_IME, 6222736c2fSopenharmony_ci SET_CORE_AND_AGENT, 6322736c2fSopenharmony_ci}; 6422736c2fSopenharmony_cienum class ImeAction : uint32_t { 6522736c2fSopenharmony_ci DO_NOTHING, 6622736c2fSopenharmony_ci HANDLE_STARTING_IME, 6722736c2fSopenharmony_ci STOP_EXITING_IME, 6822736c2fSopenharmony_ci STOP_READY_IME, 6922736c2fSopenharmony_ci STOP_STARTING_IME, 7022736c2fSopenharmony_ci DO_SET_CORE_AND_AGENT, 7122736c2fSopenharmony_ci DO_ACTION_IN_NULL_IME_DATA, 7222736c2fSopenharmony_ci DO_ACTION_IN_IME_EVENT_CONVERT_FAILED, 7322736c2fSopenharmony_ci}; 7422736c2fSopenharmony_cistruct ImeData { 7522736c2fSopenharmony_ci static constexpr int64_t START_TIME_OUT = 8000; 7622736c2fSopenharmony_ci sptr<IInputMethodCore> core{ nullptr }; 7722736c2fSopenharmony_ci sptr<IRemoteObject> agent{ nullptr }; 7822736c2fSopenharmony_ci sptr<InputDeathRecipient> deathRecipient{ nullptr }; 7922736c2fSopenharmony_ci pid_t pid; 8022736c2fSopenharmony_ci std::shared_ptr<FreezeManager> freezeMgr; 8122736c2fSopenharmony_ci ImeStatus imeStatus{ ImeStatus::STARTING }; 8222736c2fSopenharmony_ci std::pair<std::string, std::string> ime; // first: bundleName second:extName 8322736c2fSopenharmony_ci int64_t startTime{ 0 }; 8422736c2fSopenharmony_ci ImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, sptr<InputDeathRecipient> deathRecipient, 8522736c2fSopenharmony_ci pid_t imePid) 8622736c2fSopenharmony_ci : core(std::move(core)), agent(std::move(agent)), deathRecipient(std::move(deathRecipient)), pid(imePid), 8722736c2fSopenharmony_ci freezeMgr(std::make_shared<FreezeManager>(imePid)) 8822736c2fSopenharmony_ci { 8922736c2fSopenharmony_ci } 9022736c2fSopenharmony_ci}; 9122736c2fSopenharmony_ci/**@class PerUserSession 9222736c2fSopenharmony_ci * 9322736c2fSopenharmony_ci * @brief The class provides session management in input method management service 9422736c2fSopenharmony_ci * 9522736c2fSopenharmony_ci * This class manages the sessions between input clients and input method engines for each unlocked user. 9622736c2fSopenharmony_ci */ 9722736c2fSopenharmony_ciclass PerUserSession { 9822736c2fSopenharmony_cipublic: 9922736c2fSopenharmony_ci explicit PerUserSession(int userId); 10022736c2fSopenharmony_ci PerUserSession(int32_t userId, const std::shared_ptr<AppExecFwk::EventHandler> &eventHandler); 10122736c2fSopenharmony_ci ~PerUserSession(); 10222736c2fSopenharmony_ci 10322736c2fSopenharmony_ci int32_t OnPrepareInput(const InputClientInfo &clientInfo); 10422736c2fSopenharmony_ci int32_t OnStartInput(const InputClientInfo &inputClientInfo, sptr<IRemoteObject> &agent); 10522736c2fSopenharmony_ci int32_t OnReleaseInput(const sptr<IInputClient> &client); 10622736c2fSopenharmony_ci int32_t OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent); 10722736c2fSopenharmony_ci int32_t OnHideCurrentInput(); 10822736c2fSopenharmony_ci int32_t OnShowCurrentInput(); 10922736c2fSopenharmony_ci int32_t OnShowInput(sptr<IInputClient> client); 11022736c2fSopenharmony_ci int32_t OnHideInput(sptr<IInputClient> client); 11122736c2fSopenharmony_ci int32_t OnRequestShowInput(); 11222736c2fSopenharmony_ci int32_t OnRequestHideInput(); 11322736c2fSopenharmony_ci void OnSecurityChange(int32_t security); 11422736c2fSopenharmony_ci void OnHideSoftKeyBoardSelf(); 11522736c2fSopenharmony_ci void NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty); 11622736c2fSopenharmony_ci int32_t SwitchSubtype(const SubProperty &subProperty); 11722736c2fSopenharmony_ci void OnFocused(int32_t pid, int32_t uid); 11822736c2fSopenharmony_ci void OnUnfocused(int32_t pid, int32_t uid); 11922736c2fSopenharmony_ci int64_t GetCurrentClientPid(); 12022736c2fSopenharmony_ci int64_t GetInactiveClientPid(); 12122736c2fSopenharmony_ci int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info); 12222736c2fSopenharmony_ci int32_t OnUpdateListenEventFlag(const InputClientInfo &clientInfo); 12322736c2fSopenharmony_ci int32_t OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent); 12422736c2fSopenharmony_ci int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core); 12522736c2fSopenharmony_ci int32_t InitConnect(pid_t pid); 12622736c2fSopenharmony_ci 12722736c2fSopenharmony_ci bool StartCurrentIme(bool isStopCurrentIme = false); 12822736c2fSopenharmony_ci bool StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme = false); 12922736c2fSopenharmony_ci bool StopCurrentIme(); 13022736c2fSopenharmony_ci bool RestartIme(); 13122736c2fSopenharmony_ci void AddRestartIme(); 13222736c2fSopenharmony_ci 13322736c2fSopenharmony_ci bool IsProxyImeEnable(); 13422736c2fSopenharmony_ci bool IsBoundToClient(); 13522736c2fSopenharmony_ci bool IsCurrentImeByPid(int32_t pid); 13622736c2fSopenharmony_ci int32_t RestoreCurrentImeSubType(); 13722736c2fSopenharmony_ci int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown); 13822736c2fSopenharmony_ci bool CheckSecurityMode(); 13922736c2fSopenharmony_ci int32_t OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent); 14022736c2fSopenharmony_ci int32_t RemoveCurrentClient(); 14122736c2fSopenharmony_ci std::shared_ptr<ImeData> GetReadyImeData(ImeType type); 14222736c2fSopenharmony_ci std::shared_ptr<ImeData> GetImeData(ImeType type); 14322736c2fSopenharmony_ci BlockQueue<SwitchInfo>& GetSwitchQueue(); 14422736c2fSopenharmony_ci bool IsWmsReady(); 14522736c2fSopenharmony_ci bool CheckPwdInputPatternConv(InputClientInfo &clientInfo); 14622736c2fSopenharmony_ci int32_t RestoreCurrentIme(); 14722736c2fSopenharmony_ci int32_t SetInputType(); 14822736c2fSopenharmony_ci 14922736c2fSopenharmony_ciprivate: 15022736c2fSopenharmony_ci struct ResetManager { 15122736c2fSopenharmony_ci uint32_t num{ 0 }; 15222736c2fSopenharmony_ci time_t last{}; 15322736c2fSopenharmony_ci }; 15422736c2fSopenharmony_ci enum ClientAddEvent : int32_t { 15522736c2fSopenharmony_ci PREPARE_INPUT = 0, 15622736c2fSopenharmony_ci START_LISTENING, 15722736c2fSopenharmony_ci }; 15822736c2fSopenharmony_ci int32_t userId_; // the id of the user to whom the object is linking 15922736c2fSopenharmony_ci std::recursive_mutex mtx; 16022736c2fSopenharmony_ci std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> mapClients_; 16122736c2fSopenharmony_ci static const int MAX_RESTART_NUM = 3; 16222736c2fSopenharmony_ci static const int IME_RESET_TIME_OUT = 3; 16322736c2fSopenharmony_ci static const int MAX_IME_START_TIME = 1000; 16422736c2fSopenharmony_ci static constexpr int32_t MAX_RESTART_TASKS = 2; 16522736c2fSopenharmony_ci std::mutex clientLock_; 16622736c2fSopenharmony_ci sptr<IInputClient> currentClient_; // the current input client 16722736c2fSopenharmony_ci std::mutex resetLock; 16822736c2fSopenharmony_ci ResetManager manager; 16922736c2fSopenharmony_ci using IpcExec = std::function<int32_t()>; 17022736c2fSopenharmony_ci 17122736c2fSopenharmony_ci PerUserSession(const PerUserSession &); 17222736c2fSopenharmony_ci PerUserSession &operator=(const PerUserSession &); 17322736c2fSopenharmony_ci PerUserSession(const PerUserSession &&); 17422736c2fSopenharmony_ci PerUserSession &operator=(const PerUserSession &&); 17522736c2fSopenharmony_ci 17622736c2fSopenharmony_ci static constexpr int32_t MAX_WAIT_TIME = 5000; 17722736c2fSopenharmony_ci BlockQueue<SwitchInfo> switchQueue_{ MAX_WAIT_TIME }; 17822736c2fSopenharmony_ci 17922736c2fSopenharmony_ci void OnClientDied(sptr<IInputClient> remote); 18022736c2fSopenharmony_ci void OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type); 18122736c2fSopenharmony_ci 18222736c2fSopenharmony_ci int AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo, ClientAddEvent event); 18322736c2fSopenharmony_ci void RemoveClientInfo(const sptr<IRemoteObject> &client, bool isClientDied = false); 18422736c2fSopenharmony_ci int32_t RemoveClient( 18522736c2fSopenharmony_ci const sptr<IInputClient> &client, bool isUnbindFromClient = false, bool isInactiveClient = false); 18622736c2fSopenharmony_ci void DeactivateClient(const sptr<IInputClient> &client); 18722736c2fSopenharmony_ci std::shared_ptr<InputClientInfo> GetClientInfo(sptr<IRemoteObject> inputClient); 18822736c2fSopenharmony_ci std::shared_ptr<InputClientInfo> GetClientInfo(pid_t pid); 18922736c2fSopenharmony_ci std::shared_ptr<InputClientInfo> GetCurClientInfo(); 19022736c2fSopenharmony_ci void UpdateClientInfo(const sptr<IRemoteObject> &client, 19122736c2fSopenharmony_ci const std::unordered_map<UpdateFlag, std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig>> 19222736c2fSopenharmony_ci &updateInfos); 19322736c2fSopenharmony_ci 19422736c2fSopenharmony_ci int32_t InitImeData(const std::pair<std::string, std::string> &ime); 19522736c2fSopenharmony_ci int32_t UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid); 19622736c2fSopenharmony_ci int32_t AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid); 19722736c2fSopenharmony_ci void RemoveImeData(ImeType type, bool isImeDied); 19822736c2fSopenharmony_ci int32_t RemoveIme(const sptr<IInputMethodCore> &core, ImeType type); 19922736c2fSopenharmony_ci std::shared_ptr<ImeData> GetValidIme(ImeType type); 20022736c2fSopenharmony_ci 20122736c2fSopenharmony_ci int32_t BindClientWithIme(const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type, 20222736c2fSopenharmony_ci bool isBindFromClient = false); 20322736c2fSopenharmony_ci void UnBindClientWithIme(const std::shared_ptr<InputClientInfo> ¤tClientInfo, 20422736c2fSopenharmony_ci bool isUnbindFromClient = false); 20522736c2fSopenharmony_ci void StopClientInput(const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient = false); 20622736c2fSopenharmony_ci void StopImeInput(ImeType currentType, const sptr<IRemoteObject> ¤tChannel); 20722736c2fSopenharmony_ci 20822736c2fSopenharmony_ci int32_t HideKeyboard(const sptr<IInputClient> ¤tClient); 20922736c2fSopenharmony_ci int32_t ShowKeyboard(const sptr<IInputClient> ¤tClient); 21022736c2fSopenharmony_ci 21122736c2fSopenharmony_ci int32_t InitInputControlChannel(); 21222736c2fSopenharmony_ci void StartImeInImeDied(); 21322736c2fSopenharmony_ci void SetCurrentClient(sptr<IInputClient> client); 21422736c2fSopenharmony_ci sptr<IInputClient> GetCurrentClient(); 21522736c2fSopenharmony_ci void ReplaceCurrentClient(const sptr<IInputClient> &client); 21622736c2fSopenharmony_ci void SetInactiveClient(sptr<IInputClient> client); 21722736c2fSopenharmony_ci sptr<IInputClient> GetInactiveClient(); 21822736c2fSopenharmony_ci bool IsCurClientFocused(int32_t pid, int32_t uid); 21922736c2fSopenharmony_ci bool IsCurClientUnFocused(int32_t pid, int32_t uid); 22022736c2fSopenharmony_ci bool IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest); 22122736c2fSopenharmony_ci 22222736c2fSopenharmony_ci bool IsImeStartInBind(ImeType bindImeType, ImeType startImeType); 22322736c2fSopenharmony_ci bool IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType); 22422736c2fSopenharmony_ci bool IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType); 22522736c2fSopenharmony_ci bool IsImeBindChanged(ImeType bindImeType); 22622736c2fSopenharmony_ci std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> GetClientMap(); 22722736c2fSopenharmony_ci int32_t RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec); 22822736c2fSopenharmony_ci 22922736c2fSopenharmony_ci bool WaitForCurrentImeStop(); 23022736c2fSopenharmony_ci void NotifyImeStopFinished(); 23122736c2fSopenharmony_ci bool GetCurrentUsingImeId(ImeIdentification &imeId); 23222736c2fSopenharmony_ci bool IsReady(int32_t saId); 23322736c2fSopenharmony_ci AAFwk::Want GetWant(const std::shared_ptr<ImeNativeCfg> &ime); 23422736c2fSopenharmony_ci bool StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime); 23522736c2fSopenharmony_ci bool StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime); 23622736c2fSopenharmony_ci bool StartInputService(const std::shared_ptr<ImeNativeCfg> &ime); 23722736c2fSopenharmony_ci bool ForceStopCurrentIme(bool isNeedWait = true); 23822736c2fSopenharmony_ci bool StopReadyCurrentIme(); 23922736c2fSopenharmony_ci bool StopExitingCurrentIme(); 24022736c2fSopenharmony_ci bool HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme); 24122736c2fSopenharmony_ci bool HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime); 24222736c2fSopenharmony_ci std::mutex imeStartLock_; 24322736c2fSopenharmony_ci 24422736c2fSopenharmony_ci BlockData<bool> isImeStarted_{ MAX_IME_START_TIME, false }; 24522736c2fSopenharmony_ci std::mutex imeDataLock_; 24622736c2fSopenharmony_ci std::unordered_map<ImeType, std::shared_ptr<ImeData>> imeData_; 24722736c2fSopenharmony_ci std::mutex inactiveClientLock_; 24822736c2fSopenharmony_ci sptr<IInputClient> inactiveClient_; // the inactive input client 24922736c2fSopenharmony_ci std::mutex focusedClientLock_; 25022736c2fSopenharmony_ci 25122736c2fSopenharmony_ci std::atomic<bool> isSwitching_ = false; 25222736c2fSopenharmony_ci std::mutex imeStopMutex_; 25322736c2fSopenharmony_ci std::condition_variable imeStopCv_; 25422736c2fSopenharmony_ci 25522736c2fSopenharmony_ci std::mutex restartMutex_; 25622736c2fSopenharmony_ci int32_t restartTasks_ = 0; 25722736c2fSopenharmony_ci std::shared_ptr<AppExecFwk::EventHandler> eventHandler_{ nullptr }; 25822736c2fSopenharmony_ci ImeAction GetImeAction(ImeEvent action); 25922736c2fSopenharmony_ci static inline const std::map<std::pair<ImeStatus, ImeEvent>, std::pair<ImeStatus, ImeAction>> imeEventConverter_ = { 26022736c2fSopenharmony_ci { { ImeStatus::READY, ImeEvent::START_IME }, { ImeStatus::READY, ImeAction::DO_NOTHING } }, 26122736c2fSopenharmony_ci { { ImeStatus::STARTING, ImeEvent::START_IME }, { ImeStatus::STARTING, ImeAction::HANDLE_STARTING_IME } }, 26222736c2fSopenharmony_ci { { ImeStatus::EXITING, ImeEvent::START_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } }, 26322736c2fSopenharmony_ci { { ImeStatus::READY, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::READY, ImeAction::DO_NOTHING } }, 26422736c2fSopenharmony_ci { { ImeStatus::STARTING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } }, 26522736c2fSopenharmony_ci { { ImeStatus::EXITING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } }, 26622736c2fSopenharmony_ci { { ImeStatus::READY, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_READY_IME } }, 26722736c2fSopenharmony_ci { { ImeStatus::STARTING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_STARTING_IME } }, 26822736c2fSopenharmony_ci { { ImeStatus::EXITING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } }, 26922736c2fSopenharmony_ci { { ImeStatus::READY, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::READY, ImeAction::DO_NOTHING } }, 27022736c2fSopenharmony_ci { { ImeStatus::STARTING, ImeEvent::SET_CORE_AND_AGENT }, 27122736c2fSopenharmony_ci { ImeStatus::READY, ImeAction::DO_SET_CORE_AND_AGENT } }, 27222736c2fSopenharmony_ci { { ImeStatus::EXITING, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::EXITING, ImeAction::DO_NOTHING } } 27322736c2fSopenharmony_ci }; 27422736c2fSopenharmony_ci std::string runningIme_; 27522736c2fSopenharmony_ci}; 27622736c2fSopenharmony_ci} // namespace MiscServices 27722736c2fSopenharmony_ci} // namespace OHOS 27822736c2fSopenharmony_ci#endif // SERVICES_INCLUDE_PERUSER_SESSION_H