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> ¤tClientInfo, bool isUnbindFromClient = false); 212 void StopClientInput(const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient = false); 213 void StopImeInput(ImeType currentType, const sptr<IRemoteObject> ¤tChannel); 214 215 int32_t HideKeyboard(const sptr<IInputClient> ¤tClient); 216 int32_t ShowKeyboard(const sptr<IInputClient> ¤tClient, 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