• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_system_cmd_channel.h"
36 #include "i_input_data_channel.h"
37 #include "i_input_method_agent.h"
38 #include "i_input_method_core.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 
55 namespace OHOS {
56 namespace MiscServices {
57 enum class ImeStatus : uint32_t { STARTING, READY, EXITING };
58 enum class ImeEvent : uint32_t {
59     START_IME,
60     START_IME_TIMEOUT,
61     STOP_IME,
62     SET_CORE_AND_AGENT,
63 };
64 enum 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 };
74 struct 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 };
ImeDataImeData84     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  */
97 class PerUserSession {
98 public:
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, int32_t requestKeyboardReason = 0);
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     int32_t SwitchSubtypeWithoutStartIme(const SubProperty &subProperty);
118     void OnFocused(int32_t pid, int32_t uid);
119     void OnUnfocused(int32_t pid, int32_t uid);
120     void OnUserUnlocked();
121     int64_t GetCurrentClientPid();
122     int64_t GetInactiveClientPid();
123     int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info);
124     int32_t OnUpdateListenEventFlag(const InputClientInfo &clientInfo);
125     int32_t OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent);
126     int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core);
127     int32_t InitConnect(pid_t pid);
128 
129     bool StartCurrentIme(bool isStopCurrentIme = false);
130     bool StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme = false);
131     bool StopCurrentIme();
132     bool RestartIme();
133     void AddRestartIme();
134 
135     bool IsProxyImeEnable();
136     bool IsBoundToClient();
137     bool IsCurrentImeByPid(int32_t pid);
138     int32_t RestoreCurrentImeSubType();
139     int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown);
140     bool CheckSecurityMode();
141     int32_t OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent);
142     int32_t RemoveCurrentClient();
143     std::shared_ptr<ImeData> GetReadyImeData(ImeType type);
144     std::shared_ptr<ImeData> GetImeData(ImeType type);
145     BlockQueue<SwitchInfo>& GetSwitchQueue();
146     bool IsWmsReady();
147     bool CheckPwdInputPatternConv(InputClientInfo &clientInfo);
148     int32_t RestoreCurrentIme();
149     std::shared_ptr<ImeNativeCfg> GetImeNativeCfg(int32_t userId, const std::string &bundleName,
150         const std::string &subName);
151     void UpdateUserLockState();
152     int32_t OnSetCallingWindow(uint32_t callingWindowId, sptr<IInputClient> client);
153     int32_t GetInputStartInfo(bool& isInputStart, uint32_t& callingWndId, int32_t& requestKeyboardReason);
154     bool IsSaReady(int32_t saId);
155 
156 private:
157     struct ResetManager {
158         uint32_t num{ 0 };
159         time_t last{};
160     };
161     enum ClientAddEvent : int32_t {
162         PREPARE_INPUT = 0,
163         START_LISTENING,
164     };
165     int32_t userId_; // the id of the user to whom the object is linking
166     std::recursive_mutex mtx;
167     std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> mapClients_;
168     static const int MAX_RESTART_NUM = 3;
169     static const int IME_RESET_TIME_OUT = 3;
170     static const int MAX_IME_START_TIME = 1000;
171     static constexpr int32_t MAX_RESTART_TASKS = 2;
172     std::mutex clientLock_;
173     sptr<IInputClient> currentClient_; // the current input client
174     std::mutex resetLock;
175     ResetManager manager;
176     using IpcExec = std::function<int32_t()>;
177 
178     PerUserSession(const PerUserSession &);
179     PerUserSession &operator=(const PerUserSession &);
180     PerUserSession(const PerUserSession &&);
181     PerUserSession &operator=(const PerUserSession &&);
182 
183     static constexpr int32_t MAX_WAIT_TIME = 5000;
184     BlockQueue<SwitchInfo> switchQueue_{ MAX_WAIT_TIME };
185 
186     void OnClientDied(sptr<IInputClient> remote);
187     void OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type);
188 
189     int AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo, ClientAddEvent event);
190     void RemoveClientInfo(const sptr<IRemoteObject> &client, bool isClientDied = false);
191     int32_t RemoveClient(
192         const sptr<IInputClient> &client, bool isUnbindFromClient = false, bool isInactiveClient = false);
193     void DeactivateClient(const sptr<IInputClient> &client);
194     std::shared_ptr<InputClientInfo> GetClientInfo(sptr<IRemoteObject> inputClient);
195     std::shared_ptr<InputClientInfo> GetClientInfo(pid_t pid);
196     std::shared_ptr<InputClientInfo> GetCurClientInfo();
197     void UpdateClientInfo(const sptr<IRemoteObject> &client,
198         const std::unordered_map<UpdateFlag, std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig>>
199             &updateInfos);
200 
201     int32_t InitImeData(const std::pair<std::string, std::string> &ime);
202     int32_t UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid);
203     int32_t AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid);
204     void RemoveImeData(ImeType type, bool isImeDied);
205     int32_t RemoveIme(const sptr<IInputMethodCore> &core, ImeType type);
206     std::shared_ptr<ImeData> GetValidIme(ImeType type);
207 
208     int32_t BindClientWithIme(
209         const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type, bool isBindFromClient = false);
210     void UnBindClientWithIme(
211         const std::shared_ptr<InputClientInfo> &currentClientInfo, bool isUnbindFromClient = false);
212     void StopClientInput(const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient = false);
213     void StopImeInput(ImeType currentType, const sptr<IRemoteObject> &currentChannel);
214 
215     int32_t HideKeyboard(const sptr<IInputClient> &currentClient);
216     int32_t ShowKeyboard(const sptr<IInputClient> &currentClient, int32_t requestKeyboardReason = 0);
217 
218     int32_t InitInputControlChannel();
219     void StartImeInImeDied();
220     void SetCurrentClient(sptr<IInputClient> client);
221     sptr<IInputClient> GetCurrentClient();
222     void ReplaceCurrentClient(const sptr<IInputClient> &client);
223     void SetInactiveClient(sptr<IInputClient> client);
224     sptr<IInputClient> GetInactiveClient();
225     bool IsCurClientFocused(int32_t pid, int32_t uid);
226     bool IsCurClientUnFocused(int32_t pid, int32_t uid);
227     bool IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest);
228 
229     bool IsImeStartInBind(ImeType bindImeType, ImeType startImeType);
230     bool IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType);
231     bool IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType);
232     bool IsImeBindChanged(ImeType bindImeType);
233     std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> GetClientMap();
234     int32_t RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec);
235 
236     bool WaitForCurrentImeStop();
237     void NotifyImeStopFinished();
238     bool GetCurrentUsingImeId(ImeIdentification &imeId);
239     bool CanStartIme();
240     int32_t ChangeToDefaultImeIfNeed(
241         const std::shared_ptr<ImeNativeCfg> &ime, std::shared_ptr<ImeNativeCfg> &imeToStart);
242     bool IsReady(int32_t saId);
243     AAFwk::Want GetWant(const std::shared_ptr<ImeNativeCfg> &ime);
244     bool StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime);
245     bool StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime);
246     bool StartInputService(const std::shared_ptr<ImeNativeCfg> &ime);
247     bool ForceStopCurrentIme(bool isNeedWait = true);
248     bool StopReadyCurrentIme();
249     bool StopExitingCurrentIme();
250     bool HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme);
251     bool HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime);
252     bool GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> &imeToStart);
253     // from service notify clients input start and stop
254     int32_t NotifyInputStartToClients(uint32_t callingWndId, int32_t requestKeyboardReason = 0);
255     int32_t NotifyInputStopToClients();
256     bool IsNotifyInputStop(const sptr<IInputClient> &client);
257     std::mutex imeStartLock_;
258 
259     BlockData<bool> isImeStarted_{ MAX_IME_START_TIME, false };
260     std::mutex imeDataLock_;
261     std::unordered_map<ImeType, std::shared_ptr<ImeData>> imeData_;
262     std::mutex inactiveClientLock_;
263     sptr<IInputClient> inactiveClient_; // the inactive input client
264     std::mutex focusedClientLock_;
265 
266     std::atomic<bool> isSwitching_ = false;
267     std::mutex imeStopMutex_;
268     std::condition_variable imeStopCv_;
269 
270     std::mutex restartMutex_;
271     int32_t restartTasks_ = 0;
272     std::shared_ptr<AppExecFwk::EventHandler> eventHandler_{ nullptr };
273     ImeAction GetImeAction(ImeEvent action);
274     static inline const std::map<std::pair<ImeStatus, ImeEvent>, std::pair<ImeStatus, ImeAction>> imeEventConverter_ = {
275         { { ImeStatus::READY, ImeEvent::START_IME }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
276         { { ImeStatus::STARTING, ImeEvent::START_IME }, { ImeStatus::STARTING, ImeAction::HANDLE_STARTING_IME } },
277         { { ImeStatus::EXITING, ImeEvent::START_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
278         { { ImeStatus::READY, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
279         { { ImeStatus::STARTING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
280         { { ImeStatus::EXITING, ImeEvent::START_IME_TIMEOUT }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
281         { { ImeStatus::READY, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_READY_IME } },
282         { { ImeStatus::STARTING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_STARTING_IME } },
283         { { ImeStatus::EXITING, ImeEvent::STOP_IME }, { ImeStatus::EXITING, ImeAction::STOP_EXITING_IME } },
284         { { ImeStatus::READY, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::READY, ImeAction::DO_NOTHING } },
285         { { ImeStatus::STARTING, ImeEvent::SET_CORE_AND_AGENT },
286             { ImeStatus::READY, ImeAction::DO_SET_CORE_AND_AGENT } },
287         { { ImeStatus::EXITING, ImeEvent::SET_CORE_AND_AGENT }, { ImeStatus::EXITING, ImeAction::DO_NOTHING } }
288     };
289     std::string runningIme_;
290     std::atomic<bool> isUserUnlocked_{ false };
291 };
292 } // namespace MiscServices
293 } // namespace OHOS
294 #endif // SERVICES_INCLUDE_PERUSER_SESSION_H
295