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> &currentClientInfo,
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> &currentChannel);
20722736c2fSopenharmony_ci
20822736c2fSopenharmony_ci    int32_t HideKeyboard(const sptr<IInputClient> &currentClient);
20922736c2fSopenharmony_ci    int32_t ShowKeyboard(const sptr<IInputClient> &currentClient);
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