1/*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef SERVICES_INCLUDE_PERUSER_SESSION_H
17#define SERVICES_INCLUDE_PERUSER_SESSION_H
18
19#include <functional>
20#include <map>
21#include <memory>
22#include <mutex>
23#include <thread>
24#include <variant>
25
26#include "block_data.h"
27#include "block_queue.h"
28#include "enable_ime_data_parser.h"
29#include "event_handler.h"
30#include "event_status_manager.h"
31#include "freeze_manager.h"
32#include "global.h"
33#include "i_input_client.h"
34#include "i_input_control_channel.h"
35#include "i_input_data_channel.h"
36#include "i_input_method_agent.h"
37#include "i_input_method_core.h"
38#include "i_system_cmd_channel.h"
39#include "ime_cfg_manager.h"
40#include "input_attribute.h"
41#include "input_client_info.h"
42#include "input_death_recipient.h"
43#include "input_method_info.h"
44#include "input_method_property.h"
45#include "input_type_manager.h"
46#include "input_window_info.h"
47#include "inputmethod_sysevent.h"
48#include "iremote_object.h"
49#include "message.h"
50#include "message_handler.h"
51#include "panel_info.h"
52#include "input_method_types.h"
53#include "want.h"
54
55namespace OHOS {
56namespace MiscServices {
57enum class ImeStatus : uint32_t { STARTING, READY, EXITING };
58enum class ImeEvent : uint32_t {
59    START_IME,
60    START_IME_TIMEOUT,
61    STOP_IME,
62    SET_CORE_AND_AGENT,
63};
64enum class ImeAction : uint32_t {
65    DO_NOTHING,
66    HANDLE_STARTING_IME,
67    STOP_EXITING_IME,
68    STOP_READY_IME,
69    STOP_STARTING_IME,
70    DO_SET_CORE_AND_AGENT,
71    DO_ACTION_IN_NULL_IME_DATA,
72    DO_ACTION_IN_IME_EVENT_CONVERT_FAILED,
73};
74struct ImeData {
75    static constexpr int64_t START_TIME_OUT = 8000;
76    sptr<IInputMethodCore> core{ nullptr };
77    sptr<IRemoteObject> agent{ nullptr };
78    sptr<InputDeathRecipient> deathRecipient{ nullptr };
79    pid_t pid;
80    std::shared_ptr<FreezeManager> freezeMgr;
81    ImeStatus imeStatus{ ImeStatus::STARTING };
82    std::pair<std::string, std::string> ime; // first: bundleName  second:extName
83    int64_t startTime{ 0 };
84    ImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, sptr<InputDeathRecipient> deathRecipient,
85        pid_t imePid)
86        : core(std::move(core)), agent(std::move(agent)), deathRecipient(std::move(deathRecipient)), pid(imePid),
87          freezeMgr(std::make_shared<FreezeManager>(imePid))
88    {
89    }
90};
91/**@class PerUserSession
92 *
93 * @brief The class provides session management in input method management service
94 *
95 * This class manages the sessions between input clients and input method engines for each unlocked user.
96 */
97class PerUserSession {
98public:
99    explicit PerUserSession(int userId);
100    PerUserSession(int32_t userId, const std::shared_ptr<AppExecFwk::EventHandler> &eventHandler);
101    ~PerUserSession();
102
103    int32_t OnPrepareInput(const InputClientInfo &clientInfo);
104    int32_t OnStartInput(const InputClientInfo &inputClientInfo, sptr<IRemoteObject> &agent);
105    int32_t OnReleaseInput(const sptr<IInputClient> &client);
106    int32_t OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent);
107    int32_t OnHideCurrentInput();
108    int32_t OnShowCurrentInput();
109    int32_t OnShowInput(sptr<IInputClient> client);
110    int32_t OnHideInput(sptr<IInputClient> client);
111    int32_t OnRequestShowInput();
112    int32_t OnRequestHideInput();
113    void OnSecurityChange(int32_t security);
114    void OnHideSoftKeyBoardSelf();
115    void NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty);
116    int32_t SwitchSubtype(const SubProperty &subProperty);
117    void OnFocused(int32_t pid, int32_t uid);
118    void OnUnfocused(int32_t pid, int32_t uid);
119    int64_t GetCurrentClientPid();
120    int64_t GetInactiveClientPid();
121    int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info);
122    int32_t OnUpdateListenEventFlag(const InputClientInfo &clientInfo);
123    int32_t OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent);
124    int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core);
125    int32_t InitConnect(pid_t pid);
126
127    bool StartCurrentIme(bool isStopCurrentIme = false);
128    bool StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme = false);
129    bool StopCurrentIme();
130    bool RestartIme();
131    void AddRestartIme();
132
133    bool IsProxyImeEnable();
134    bool IsBoundToClient();
135    bool IsCurrentImeByPid(int32_t pid);
136    int32_t RestoreCurrentImeSubType();
137    int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown);
138    bool CheckSecurityMode();
139    int32_t OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent);
140    int32_t RemoveCurrentClient();
141    std::shared_ptr<ImeData> GetReadyImeData(ImeType type);
142    std::shared_ptr<ImeData> GetImeData(ImeType type);
143    BlockQueue<SwitchInfo>& GetSwitchQueue();
144    bool IsWmsReady();
145    bool CheckPwdInputPatternConv(InputClientInfo &clientInfo);
146    int32_t RestoreCurrentIme();
147    int32_t SetInputType();
148
149private:
150    struct ResetManager {
151        uint32_t num{ 0 };
152        time_t last{};
153    };
154    enum ClientAddEvent : int32_t {
155        PREPARE_INPUT = 0,
156        START_LISTENING,
157    };
158    int32_t userId_; // the id of the user to whom the object is linking
159    std::recursive_mutex mtx;
160    std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> mapClients_;
161    static const int MAX_RESTART_NUM = 3;
162    static const int IME_RESET_TIME_OUT = 3;
163    static const int MAX_IME_START_TIME = 1000;
164    static constexpr int32_t MAX_RESTART_TASKS = 2;
165    std::mutex clientLock_;
166    sptr<IInputClient> currentClient_; // the current input client
167    std::mutex resetLock;
168    ResetManager manager;
169    using IpcExec = std::function<int32_t()>;
170
171    PerUserSession(const PerUserSession &);
172    PerUserSession &operator=(const PerUserSession &);
173    PerUserSession(const PerUserSession &&);
174    PerUserSession &operator=(const PerUserSession &&);
175
176    static constexpr int32_t MAX_WAIT_TIME = 5000;
177    BlockQueue<SwitchInfo> switchQueue_{ MAX_WAIT_TIME };
178
179    void OnClientDied(sptr<IInputClient> remote);
180    void OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type);
181
182    int AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo, ClientAddEvent event);
183    void RemoveClientInfo(const sptr<IRemoteObject> &client, bool isClientDied = false);
184    int32_t RemoveClient(
185        const sptr<IInputClient> &client, bool isUnbindFromClient = false, bool isInactiveClient = false);
186    void DeactivateClient(const sptr<IInputClient> &client);
187    std::shared_ptr<InputClientInfo> GetClientInfo(sptr<IRemoteObject> inputClient);
188    std::shared_ptr<InputClientInfo> GetClientInfo(pid_t pid);
189    std::shared_ptr<InputClientInfo> GetCurClientInfo();
190    void UpdateClientInfo(const sptr<IRemoteObject> &client,
191        const std::unordered_map<UpdateFlag, std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig>>
192            &updateInfos);
193
194    int32_t InitImeData(const std::pair<std::string, std::string> &ime);
195    int32_t UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid);
196    int32_t AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid);
197    void RemoveImeData(ImeType type, bool isImeDied);
198    int32_t RemoveIme(const sptr<IInputMethodCore> &core, ImeType type);
199    std::shared_ptr<ImeData> GetValidIme(ImeType type);
200
201    int32_t BindClientWithIme(const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type,
202        bool isBindFromClient = false);
203    void UnBindClientWithIme(const std::shared_ptr<InputClientInfo> &currentClientInfo,
204        bool isUnbindFromClient = false);
205    void StopClientInput(const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient = false);
206    void StopImeInput(ImeType currentType, const sptr<IRemoteObject> &currentChannel);
207
208    int32_t HideKeyboard(const sptr<IInputClient> &currentClient);
209    int32_t ShowKeyboard(const sptr<IInputClient> &currentClient);
210
211    int32_t InitInputControlChannel();
212    void StartImeInImeDied();
213    void SetCurrentClient(sptr<IInputClient> client);
214    sptr<IInputClient> GetCurrentClient();
215    void ReplaceCurrentClient(const sptr<IInputClient> &client);
216    void SetInactiveClient(sptr<IInputClient> client);
217    sptr<IInputClient> GetInactiveClient();
218    bool IsCurClientFocused(int32_t pid, int32_t uid);
219    bool IsCurClientUnFocused(int32_t pid, int32_t uid);
220    bool IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest);
221
222    bool IsImeStartInBind(ImeType bindImeType, ImeType startImeType);
223    bool IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType);
224    bool IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType);
225    bool IsImeBindChanged(ImeType bindImeType);
226    std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> GetClientMap();
227    int32_t RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec);
228
229    bool WaitForCurrentImeStop();
230    void NotifyImeStopFinished();
231    bool GetCurrentUsingImeId(ImeIdentification &imeId);
232    bool IsReady(int32_t saId);
233    AAFwk::Want GetWant(const std::shared_ptr<ImeNativeCfg> &ime);
234    bool StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime);
235    bool StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime);
236    bool StartInputService(const std::shared_ptr<ImeNativeCfg> &ime);
237    bool ForceStopCurrentIme(bool isNeedWait = true);
238    bool StopReadyCurrentIme();
239    bool StopExitingCurrentIme();
240    bool HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme);
241    bool HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime);
242    std::mutex imeStartLock_;
243
244    BlockData<bool> isImeStarted_{ MAX_IME_START_TIME, false };
245    std::mutex imeDataLock_;
246    std::unordered_map<ImeType, std::shared_ptr<ImeData>> imeData_;
247    std::mutex inactiveClientLock_;
248    sptr<IInputClient> inactiveClient_; // the inactive input client
249    std::mutex focusedClientLock_;
250
251    std::atomic<bool> isSwitching_ = false;
252    std::mutex imeStopMutex_;
253    std::condition_variable imeStopCv_;
254
255    std::mutex restartMutex_;
256    int32_t restartTasks_ = 0;
257    std::shared_ptr<AppExecFwk::EventHandler> eventHandler_{ nullptr };
258    ImeAction GetImeAction(ImeEvent action);
259    static inline const std::map<std::pair<ImeStatus, ImeEvent>, std::pair<ImeStatus, ImeAction>> imeEventConverter_ = {
260        { { ImeStatus::READY, ImeEvent::START_IME }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
261        { { ImeStatus::STARTING, ImeEvent::START_IME }, { ImeStatus::STARTING, ImeAction::HANDLE_STARTING_IME } },
262        { { ImeStatus::EXITING, ImeEvent::START_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
263        { { ImeStatus::READY, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
264        { { ImeStatus::STARTING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
265        { { ImeStatus::EXITING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
266        { { ImeStatus::READY, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_READY_IME } },
267        { { ImeStatus::STARTING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_STARTING_IME } },
268        { { ImeStatus::EXITING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
269        { { ImeStatus::READY, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
270        { { ImeStatus::STARTING, ImeEvent::SET_CORE_AND_AGENT },
271            { ImeStatus::READY, ImeAction::DO_SET_CORE_AND_AGENT } },
272        { { ImeStatus::EXITING, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::EXITING, ImeAction::DO_NOTHING } }
273    };
274    std::string runningIme_;
275};
276} // namespace MiscServices
277} // namespace OHOS
278#endif // SERVICES_INCLUDE_PERUSER_SESSION_H