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 #include "peruser_session.h"
17 #include "ability_manager_client.h"
18 #include "identity_checker_impl.h"
19 #include "ime_connection.h"
20 #include "ime_info_inquirer.h"
21 #include "input_control_channel_stub.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "mem_mgr_client.h"
25 #include "on_demand_start_stop_sa.h"
26 #include "os_account_adapter.h"
27 #include "scene_board_judgement.h"
28 #include "security_mode_parser.h"
29 #include "system_ability_definition.h"
30 #include "wms_connection_observer.h"
31 #include "window_adapter.h"
32 #include <cinttypes>
33
34 namespace OHOS {
35 namespace MiscServices {
36 using namespace std::chrono;
37 using namespace MessageID;
38 using namespace OHOS::AppExecFwk;
39 using namespace OHOS::Rosen;
40 constexpr int64_t INVALID_PID = -1;
41 constexpr uint32_t STOP_IME_TIME = 600;
42 constexpr const char *STRICT_MODE = "strictMode";
43 constexpr const char *ISOLATED_SANDBOX = "isolatedSandbox";
44 constexpr uint32_t CHECK_IME_RUNNING_RETRY_INTERVAL = 60;
45 constexpr uint32_t CHECK_IME_RUNNING_RETRY_TIMES = 10;
46 constexpr int32_t MAX_RESTART_NUM = 3;
47 constexpr int32_t IME_RESET_TIME_OUT = 3;
48 constexpr int32_t MAX_RESTART_TASKS = 2;
PerUserSession(int userId)49 PerUserSession::PerUserSession(int userId) : userId_(userId) { }
50
PerUserSession(int32_t userId,const std::shared_ptr<AppExecFwk::EventHandler> & eventHandler)51 PerUserSession::PerUserSession(int32_t userId, const std::shared_ptr<AppExecFwk::EventHandler> &eventHandler)
52 : userId_(userId), eventHandler_(eventHandler)
53 {
54 // if bms not start, AppMgrClient::GetProcessRunningInfosByUserId will blocked
55 if (IsSaReady(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID)) {
56 auto bundleNames = ImeInfoInquirer::GetInstance().GetRunningIme(userId_);
57 if (!bundleNames.empty()) {
58 runningIme_ = bundleNames[0]; // one user only has one ime at present
59 }
60 }
61 }
62
~PerUserSession()63 PerUserSession::~PerUserSession() { }
64
AddClientInfo(sptr<IRemoteObject> inputClient,const InputClientInfo & clientInfo,ClientAddEvent event)65 int PerUserSession::AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo,
66 ClientAddEvent event)
67 {
68 IMSA_HILOGD("PerUserSession start.");
69 auto cacheInfo = GetClientInfo(inputClient);
70 if (cacheInfo != nullptr) {
71 IMSA_HILOGD("info is existed.");
72 if (event == PREPARE_INPUT) {
73 if (cacheInfo->uiExtensionTokenId == IMF_INVALID_TOKENID &&
74 clientInfo.uiExtensionTokenId != IMF_INVALID_TOKENID) {
75 UpdateClientInfo(inputClient, { { UpdateFlag::UIEXTENSION_TOKENID, clientInfo.uiExtensionTokenId } });
76 }
77 UpdateClientInfo(inputClient,
78 { { UpdateFlag::TEXT_CONFIG, clientInfo.config }, { UpdateFlag::CLIENT_TYPE, clientInfo.type } });
79 }
80 if (event == START_LISTENING) {
81 UpdateClientInfo(inputClient, { { UpdateFlag::EVENTFLAG, clientInfo.eventFlag } });
82 }
83 return ErrorCode::NO_ERROR;
84 }
85 auto info = std::make_shared<InputClientInfo>(clientInfo);
86 std::weak_ptr<InputClientInfo> weakClientInfo = info;
87 info->deathRecipient->SetDeathRecipient([this, weakClientInfo](const wptr<IRemoteObject> &) {
88 auto clientInfo = weakClientInfo.lock();
89 if (clientInfo == nullptr) {
90 IMSA_HILOGD("clientInfo is nullptr.");
91 return;
92 }
93 this->OnClientDied(clientInfo->client);
94 });
95 auto obj = info->client->AsObject();
96 if (obj == nullptr) {
97 IMSA_HILOGE("client obj is nullptr!");
98 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
99 }
100 if (obj->IsProxyObject() && !obj->AddDeathRecipient(info->deathRecipient)) {
101 IMSA_HILOGE("failed to add client death recipient!");
102 return ErrorCode::ERROR_CLIENT_ADD_FAILED;
103 }
104 std::lock_guard<std::recursive_mutex> lock(mtx);
105 mapClients_.insert({ inputClient, info });
106 IMSA_HILOGI("add client end.");
107 return ErrorCode::NO_ERROR;
108 }
109
RemoveClientInfo(const sptr<IRemoteObject> & client,bool isClientDied)110 void PerUserSession::RemoveClientInfo(const sptr<IRemoteObject> &client, bool isClientDied)
111 {
112 std::lock_guard<std::recursive_mutex> lock(mtx);
113 auto clientInfo = GetClientInfo(client);
114 if (clientInfo == nullptr) {
115 IMSA_HILOGD("client already removed.");
116 return;
117 }
118 // if client is subscriber and the release is not because of the client died, do not remove
119 if (clientInfo->eventFlag != NO_EVENT_ON && !isClientDied) {
120 IMSA_HILOGD("is subscriber, do not remove.");
121 auto isShowKeyboard = false;
122 auto bindImeType = ImeType::NONE;
123 UpdateClientInfo(client,
124 { { UpdateFlag::BINDIMETYPE, bindImeType }, { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } });
125 return;
126 }
127 if (clientInfo->deathRecipient != nullptr) {
128 IMSA_HILOGD("deathRecipient remove.");
129 client->RemoveDeathRecipient(clientInfo->deathRecipient);
130 }
131 mapClients_.erase(client);
132 IMSA_HILOGI("client[%{public}d] is removed.", clientInfo->pid);
133 }
134
UpdateClientInfo(const sptr<IRemoteObject> & client,const std::unordered_map<UpdateFlag,std::variant<bool,uint32_t,ImeType,ClientState,TextTotalConfig,ClientType>> & updateInfos)135 void PerUserSession::UpdateClientInfo(const sptr<IRemoteObject> &client, const std::unordered_map<UpdateFlag,
136 std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig, ClientType>> &updateInfos)
137 {
138 if (client == nullptr) {
139 IMSA_HILOGE("client is nullptr!");
140 return;
141 }
142 auto info = GetClientInfo(client);
143 if (info == nullptr) {
144 IMSA_HILOGE("client info is not exist!");
145 return;
146 }
147 for (const auto &updateInfo : updateInfos) {
148 switch (updateInfo.first) {
149 case UpdateFlag::EVENTFLAG: {
150 info->eventFlag = std::get<uint32_t>(updateInfo.second);
151 break;
152 }
153 case UpdateFlag::ISSHOWKEYBOARD: {
154 info->isShowKeyboard = std::get<bool>(updateInfo.second);
155 break;
156 }
157 case UpdateFlag::BINDIMETYPE: {
158 info->bindImeType = std::get<ImeType>(updateInfo.second);
159 break;
160 }
161 case UpdateFlag::STATE: {
162 info->state = std::get<ClientState>(updateInfo.second);
163 break;
164 }
165 case UpdateFlag::TEXT_CONFIG: {
166 info->config = std::get<TextTotalConfig>(updateInfo.second);
167 break;
168 }
169 case UpdateFlag::UIEXTENSION_TOKENID: {
170 info->uiExtensionTokenId = std::get<uint32_t>(updateInfo.second);
171 break;
172 }
173 case UpdateFlag::CLIENT_TYPE: {
174 info->type = std::get<ClientType>(updateInfo.second);
175 break;
176 }
177 default:
178 break;
179 }
180 }
181 }
182
HideKeyboard(const sptr<IInputClient> & currentClient)183 int32_t PerUserSession::HideKeyboard(const sptr<IInputClient> ¤tClient)
184 {
185 IMSA_HILOGD("PerUserSession::HideKeyboard start.");
186 if (currentClient == nullptr) {
187 IMSA_HILOGE("current client is nullptr!");
188 return ErrorCode::ERROR_NULL_POINTER;
189 }
190 auto clientInfo = GetClientInfo(currentClient->AsObject());
191 if (clientInfo == nullptr) {
192 IMSA_HILOGE("client info is nullptr!");
193 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
194 }
195 auto data = GetReadyImeData(clientInfo->bindImeType);
196 if (data == nullptr) {
197 IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType);
198 return ErrorCode::ERROR_IME_NOT_STARTED;
199 }
200 auto ret = RequestIme(data, RequestType::NORMAL, [&data] { return data->core->HideKeyboard(); });
201 if (ret != ErrorCode::NO_ERROR) {
202 IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret);
203 return ErrorCode::ERROR_KBD_HIDE_FAILED;
204 }
205 bool isShowKeyboard = false;
206 UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } });
207 RestoreCurrentImeSubType();
208 return ErrorCode::NO_ERROR;
209 }
210
ShowKeyboard(const sptr<IInputClient> & currentClient,int32_t requestKeyboardReason)211 int32_t PerUserSession::ShowKeyboard(const sptr<IInputClient> ¤tClient, int32_t requestKeyboardReason)
212 {
213 IMSA_HILOGD("PerUserSession::ShowKeyboard start.");
214 if (currentClient == nullptr) {
215 IMSA_HILOGE("current client is nullptr!");
216 return ErrorCode::ERROR_IMSA_NULLPTR;
217 }
218 auto clientInfo = GetClientInfo(currentClient->AsObject());
219 if (clientInfo == nullptr) {
220 IMSA_HILOGE("client info is nullptr!");
221 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
222 }
223 auto data = GetReadyImeData(clientInfo->bindImeType);
224 if (data == nullptr) {
225 IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType);
226 return ErrorCode::ERROR_IME_NOT_STARTED;
227 }
228 auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); });
229 if (ret != ErrorCode::NO_ERROR) {
230 IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret);
231 return ErrorCode::ERROR_KBD_SHOW_FAILED;
232 }
233 bool isShowKeyboard = true;
234 UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } });
235 NotifyInputStartToClients(clientInfo->config.windowId, requestKeyboardReason);
236 return ErrorCode::NO_ERROR;
237 }
238
239 /** Handle the situation a remote input client died.
240 * It's called when a remote input client died
241 * @param the remote object handler of the input client died.
242 */
OnClientDied(sptr<IInputClient> remote)243 void PerUserSession::OnClientDied(sptr<IInputClient> remote)
244 {
245 if (IsNotifyInputStop(remote)) {
246 NotifyInputStopToClients();
247 }
248 if (remote == nullptr) {
249 return;
250 }
251 auto clientInfo = GetClientInfo(remote->AsObject());
252 IMSA_HILOGI("userId: %{public}d.", userId_);
253 if (IsSameClient(remote, GetCurrentClient())) {
254 if (clientInfo != nullptr) {
255 StopImeInput(clientInfo->bindImeType, clientInfo->channel);
256 }
257 SetCurrentClient(nullptr);
258 RestoreCurrentImeSubType();
259 }
260 if (IsSameClient(remote, GetInactiveClient())) {
261 if (clientInfo != nullptr) {
262 StopImeInput(clientInfo->bindImeType, clientInfo->channel);
263 }
264 SetInactiveClient(nullptr);
265 RestoreCurrentImeSubType();
266 }
267 RemoveClientInfo(remote->AsObject(), true);
268 }
269
270 /** Handle the situation that an ime died
271 * It's called when an ime died
272 * @param the remote object handler of the ime who died.
273 */
OnImeDied(const sptr<IInputMethodCore> & remote,ImeType type)274 void PerUserSession::OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type)
275 {
276 if (remote == nullptr) {
277 return;
278 }
279 IMSA_HILOGI("type: %{public}d.", type);
280 auto imeData = GetImeData(type);
281 if (imeData != nullptr && imeData->imeStatus == ImeStatus::EXITING) {
282 RemoveImeData(type, true);
283 InputTypeManager::GetInstance().Set(false);
284 NotifyImeStopFinished();
285 IMSA_HILOGI("%{public}d not current imeData.", type);
286 return;
287 }
288 RemoveImeData(type, true);
289 if (!OsAccountAdapter::IsOsAccountForeground(userId_)) {
290 IMSA_HILOGW("userId:%{public}d in background, no need to restart ime.", userId_);
291 return;
292 }
293 auto client = GetCurrentClient();
294 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
295 if (clientInfo != nullptr && clientInfo->bindImeType == type) {
296 NotifyInputStopToClients();
297 StopClientInput(clientInfo);
298 if (type == ImeType::IME) {
299 StartImeInImeDied();
300 }
301 return;
302 }
303 auto currentImeInfo = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
304 if (currentImeInfo == nullptr) {
305 IMSA_HILOGE("currentImeInfo is nullptr!");
306 return;
307 }
308 auto defaultImeInfo = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp();
309 if (defaultImeInfo == nullptr) {
310 IMSA_HILOGE("defaultImeInfo is nullptr!");
311 return;
312 }
313 if (type == ImeType::IME && currentImeInfo->bundleName == defaultImeInfo->name) {
314 StartImeInImeDied();
315 }
316 }
317
RemoveIme(const sptr<IInputMethodCore> & core,ImeType type)318 int32_t PerUserSession::RemoveIme(const sptr<IInputMethodCore> &core, ImeType type)
319 {
320 if (core == nullptr) {
321 return ErrorCode::ERROR_NULL_POINTER;
322 }
323 auto data = GetReadyImeData(type);
324 if (data == nullptr || data->core->AsObject() != core->AsObject()) {
325 return ErrorCode::ERROR_IME_NOT_STARTED;
326 }
327
328 auto client = GetCurrentClient();
329 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
330 if (clientInfo != nullptr && clientInfo->bindImeType == type) {
331 UnBindClientWithIme(clientInfo);
332 }
333 RemoveImeData(type, true);
334 return ErrorCode::NO_ERROR;
335 }
336
OnHideCurrentInput()337 int32_t PerUserSession::OnHideCurrentInput()
338 {
339 sptr<IInputClient> client = GetCurrentClient();
340 if (client == nullptr) {
341 IMSA_HILOGE("current client is nullptr!");
342 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
343 }
344 return HideKeyboard(client);
345 }
346
OnShowCurrentInput()347 int32_t PerUserSession::OnShowCurrentInput()
348 {
349 IMSA_HILOGD("PerUserSession::OnShowCurrentInput start.");
350 sptr<IInputClient> client = GetCurrentClient();
351 if (client == nullptr) {
352 IMSA_HILOGE("current client is nullptr!");
353 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
354 }
355 return ShowKeyboard(client);
356 }
357
OnHideInput(sptr<IInputClient> client)358 int32_t PerUserSession::OnHideInput(sptr<IInputClient> client)
359 {
360 IMSA_HILOGD("PerUserSession::OnHideInput start.");
361 if (!IsSameClient(client, GetCurrentClient())) {
362 IMSA_HILOGE("client is not current client!");
363 return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
364 }
365 return HideKeyboard(client);
366 }
367
OnShowInput(sptr<IInputClient> client,int32_t requestKeyboardReason)368 int32_t PerUserSession::OnShowInput(sptr<IInputClient> client, int32_t requestKeyboardReason)
369 {
370 IMSA_HILOGD("PerUserSession::OnShowInput start.");
371 if (!IsSameClient(client, GetCurrentClient())) {
372 IMSA_HILOGE("client is not current client!");
373 return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
374 }
375 return ShowKeyboard(client, requestKeyboardReason);
376 }
377
OnHideSoftKeyBoardSelf()378 void PerUserSession::OnHideSoftKeyBoardSelf()
379 {
380 IMSA_HILOGD("PerUserSession::OnHideSoftKeyBoardSel start.");
381 sptr<IInputClient> client = GetCurrentClient();
382 if (client == nullptr) {
383 IMSA_HILOGE("current client is nullptr!");
384 return;
385 }
386 UpdateClientInfo(client->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } });
387 RestoreCurrentImeSubType();
388 }
389
OnRequestShowInput()390 int32_t PerUserSession::OnRequestShowInput()
391 {
392 IMSA_HILOGD("PerUserSession::OnRequestShowInput start.");
393 auto data = GetReadyImeData(ImeType::IME);
394 if (data == nullptr) {
395 IMSA_HILOGE("ime: %{public}d doesn't exist!", ImeType::IME);
396 return ErrorCode::ERROR_IME_NOT_STARTED;
397 }
398 auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] { return data->core->ShowKeyboard(); });
399 if (ret != ErrorCode::NO_ERROR) {
400 IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret);
401 return ErrorCode::ERROR_KBD_SHOW_FAILED;
402 }
403 InputMethodSysEvent::GetInstance().ReportImeState(ImeState::BIND, data->pid,
404 ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
405 Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID);
406 auto currentClient = GetCurrentClient();
407 if (currentClient != nullptr) {
408 UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, true } });
409 }
410 return ErrorCode::NO_ERROR;
411 }
412
OnRequestHideInput(int32_t callingPid)413 int32_t PerUserSession::OnRequestHideInput(int32_t callingPid)
414 {
415 IMSA_HILOGD("PerUserSession::OnRequestHideInput start.");
416 auto data = GetReadyImeData(ImeType::IME);
417 if (data != nullptr) {
418 auto ret = RequestIme(data, RequestType::REQUEST_HIDE, [&data] { return data->core->HideKeyboard(); });
419 if (ret != ErrorCode::NO_ERROR) {
420 IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret);
421 return ErrorCode::ERROR_KBD_HIDE_FAILED;
422 }
423 }
424
425 auto currentClient = GetCurrentClient();
426 auto currentClientInfo = currentClient != nullptr ? GetClientInfo(currentClient->AsObject()) : nullptr;
427 if (currentClientInfo != nullptr) {
428 UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } });
429 }
430 auto inactiveClient = GetInactiveClient();
431 if (inactiveClient != nullptr) {
432 RemoveClient(inactiveClient, false, true);
433 }
434 RestoreCurrentImeSubType();
435 NotifyInputStopToClients();
436 return ErrorCode::NO_ERROR;
437 }
438
439 /** Get ClientInfo
440 * @param inputClient the IRemoteObject remote handler of given input client
441 * @return a pointer of ClientInfo if client is found
442 * null if client is not found
443 * @note the clientInfo pointer should not be freed by caller
444 */
GetClientInfo(sptr<IRemoteObject> inputClient)445 std::shared_ptr<InputClientInfo> PerUserSession::GetClientInfo(sptr<IRemoteObject> inputClient)
446 {
447 if (inputClient == nullptr) {
448 IMSA_HILOGE("inputClient is nullptr!");
449 return nullptr;
450 }
451 std::lock_guard<std::recursive_mutex> lock(mtx);
452 auto it = mapClients_.find(inputClient);
453 if (it == mapClients_.end()) {
454 IMSA_HILOGD("client not found.");
455 return nullptr;
456 }
457 return it->second;
458 }
459
GetClientInfo(pid_t pid)460 std::shared_ptr<InputClientInfo> PerUserSession::GetClientInfo(pid_t pid)
461 {
462 std::lock_guard<std::recursive_mutex> lock(mtx);
463 auto iter = std::find_if(mapClients_.begin(), mapClients_.end(),
464 [pid](const auto &mapClient) { return mapClient.second->pid == pid; });
465 if (iter == mapClients_.end()) {
466 IMSA_HILOGD("not found.");
467 return nullptr;
468 }
469 return iter->second;
470 }
471
OnPrepareInput(const InputClientInfo & clientInfo)472 int32_t PerUserSession::OnPrepareInput(const InputClientInfo &clientInfo)
473 {
474 IMSA_HILOGD("PerUserSession::OnPrepareInput start");
475 return AddClientInfo(clientInfo.client->AsObject(), clientInfo, PREPARE_INPUT);
476 }
477
478 /** Release input. Called by an input client.Run in work thread of this user
479 * @param the parameters from remote client
480 * @return ErrorCode
481 */
OnReleaseInput(const sptr<IInputClient> & client)482 int32_t PerUserSession::OnReleaseInput(const sptr<IInputClient> &client)
483 {
484 IMSA_HILOGD("PerUserSession::OnReleaseInput start");
485 bool isReady = IsNotifyInputStop(client);
486 int32_t ret = RemoveClient(client, true);
487 if (ret != ErrorCode::NO_ERROR) {
488 IMSA_HILOGE("remove client failed");
489 return ret;
490 }
491 if (isReady) {
492 NotifyInputStopToClients();
493 }
494 return ErrorCode::NO_ERROR;
495 }
496
RemoveClient(const sptr<IInputClient> & client,bool isUnbindFromClient,bool isInactiveClient,bool isNotifyClientAsync)497 int32_t PerUserSession::RemoveClient(
498 const sptr<IInputClient> &client, bool isUnbindFromClient, bool isInactiveClient, bool isNotifyClientAsync)
499 {
500 if (client == nullptr) {
501 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
502 }
503 // if client is current client, unbind firstly
504 auto clientInfo = GetClientInfo(client->AsObject());
505 if (IsSameClient(client, GetCurrentClient())) {
506 UnBindClientWithIme(clientInfo, isUnbindFromClient, isNotifyClientAsync);
507 SetCurrentClient(nullptr);
508 RestoreCurrentImeSubType();
509 StopClientInput(clientInfo, false, isNotifyClientAsync);
510 }
511 if (IsSameClient(client, GetInactiveClient())) {
512 SetInactiveClient(nullptr);
513 StopClientInput(clientInfo, isInactiveClient);
514 }
515 RemoveClientInfo(client->AsObject());
516 return ErrorCode::NO_ERROR;
517 }
518
DeactivateClient(const sptr<IInputClient> & client)519 void PerUserSession::DeactivateClient(const sptr<IInputClient> &client)
520 {
521 if (client == nullptr) {
522 IMSA_HILOGD("client is nullptr.");
523 return;
524 }
525 auto clientInfo = GetClientInfo(client->AsObject());
526 if (clientInfo == nullptr) {
527 return;
528 }
529 IMSA_HILOGI("deactivate client[%{public}d].", clientInfo->pid);
530 UpdateClientInfo(client->AsObject(), { { UpdateFlag::STATE, ClientState::INACTIVE } });
531 if (IsSameClient(client, GetCurrentClient())) {
532 SetCurrentClient(nullptr);
533 }
534 SetInactiveClient(client);
535 client->DeactivateClient();
536 auto data = GetReadyImeData(clientInfo->bindImeType);
537 if (data == nullptr) {
538 IMSA_HILOGE("ime %{public}d doesn't exist!", clientInfo->bindImeType);
539 return;
540 }
541 RequestIme(data, RequestType::NORMAL, [&data, &clientInfo] {
542 data->core->OnClientInactive(clientInfo->channel);
543 return ErrorCode::NO_ERROR;
544 });
545 InputMethodSysEvent::GetInstance().ReportImeState(ImeState::UNBIND, data->pid,
546 ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
547 Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID);
548 }
549
IsProxyImeEnable()550 bool PerUserSession::IsProxyImeEnable()
551 {
552 auto data = GetReadyImeData(ImeType::PROXY_IME);
553 return data != nullptr && data->core != nullptr && data->core->IsEnable();
554 }
555
OnStartInput(const InputClientInfo & inputClientInfo,sptr<IRemoteObject> & agent,std::pair<int64_t,std::string> & imeInfo)556 int32_t PerUserSession::OnStartInput(
557 const InputClientInfo &inputClientInfo, sptr<IRemoteObject> &agent, std::pair<int64_t, std::string> &imeInfo)
558 {
559 const sptr<IInputClient> &client = inputClientInfo.client;
560 if (client == nullptr) {
561 IMSA_HILOGE("client is nullptr!");
562 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
563 }
564 auto clientInfo = GetClientInfo(client->AsObject());
565 if (clientInfo == nullptr) {
566 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
567 }
568 IMSA_HILOGD("start input with keyboard[%{public}d].", inputClientInfo.isShowKeyboard);
569 InputClientInfo infoTemp = *clientInfo;
570 infoTemp.isNotifyInputStart = inputClientInfo.isNotifyInputStart;
571 HandleImeBindTypeChanged(infoTemp);
572 infoTemp.isShowKeyboard = inputClientInfo.isShowKeyboard;
573 infoTemp.needHide = inputClientInfo.needHide;
574 infoTemp.requestKeyboardReason = inputClientInfo.requestKeyboardReason;
575 auto imeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME;
576 int32_t ret = BindClientWithIme(std::make_shared<InputClientInfo>(infoTemp), imeType, true);
577 if (ret != ErrorCode::NO_ERROR) {
578 IMSA_HILOGE("bind failed, ret: %{public}d!", ret);
579 return ret;
580 }
581 auto data = GetReadyImeData(imeType);
582 if (data == nullptr || data->agent == nullptr) {
583 IMSA_HILOGE("data or agent is nullptr!");
584 return ErrorCode::ERROR_IME_NOT_STARTED;
585 }
586 agent = data->agent;
587 imeInfo = { data->pid, data->ime.first };
588 return ErrorCode::NO_ERROR;
589 }
590
BindClientWithIme(const std::shared_ptr<InputClientInfo> & clientInfo,ImeType type,bool isBindFromClient)591 int32_t PerUserSession::BindClientWithIme(const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type,
592 bool isBindFromClient)
593 {
594 if (clientInfo == nullptr) {
595 IMSA_HILOGE("clientInfo is nullptr!");
596 return ErrorCode::ERROR_IMSA_NULLPTR;
597 }
598 IMSA_HILOGD("imeType: %{public}d, isShowKeyboard: %{public}d, isBindFromClient: %{public}d.", type,
599 clientInfo->isShowKeyboard, isBindFromClient);
600 auto data = GetValidIme(type);
601 if (data == nullptr) {
602 return ErrorCode::ERROR_IME_NOT_STARTED;
603 }
604 auto ret = RequestIme(data, RequestType::START_INPUT,
605 [&data, &clientInfo, isBindFromClient]() { return data->core->StartInput(*clientInfo, isBindFromClient); });
606 if (ret != ErrorCode::NO_ERROR) {
607 IMSA_HILOGE("start input failed, ret: %{public}d!", ret);
608 return ErrorCode::ERROR_IME_START_INPUT_FAILED;
609 }
610 if (type == ImeType::IME) {
611 InputMethodSysEvent::GetInstance().ReportImeState(ImeState::BIND, data->pid,
612 ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
613 Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID);
614 }
615 if (!isBindFromClient) {
616 ret = clientInfo->client->OnInputReady(data->agent, { data->pid, data->ime.first });
617 if (ret != ErrorCode::NO_ERROR) {
618 IMSA_HILOGE("start client input failed, ret: %{public}d!", ret);
619 return ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED;
620 }
621 }
622 UpdateClientInfo(clientInfo->client->AsObject(),
623 { { UpdateFlag::BINDIMETYPE, type }, { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard },
624 { UpdateFlag::STATE, ClientState::ACTIVE } });
625 ReplaceCurrentClient(clientInfo->client);
626 if (clientInfo->isShowKeyboard) {
627 NotifyInputStartToClients(clientInfo->config.windowId, static_cast<int32_t>(clientInfo->requestKeyboardReason));
628 }
629 return ErrorCode::NO_ERROR;
630 }
631
UnBindClientWithIme(const std::shared_ptr<InputClientInfo> & currentClientInfo,bool isUnbindFromClient,bool isNotifyClientAsync)632 void PerUserSession::UnBindClientWithIme(
633 const std::shared_ptr<InputClientInfo> ¤tClientInfo, bool isUnbindFromClient, bool isNotifyClientAsync)
634 {
635 if (currentClientInfo == nullptr) {
636 return;
637 }
638 if (!isUnbindFromClient) {
639 IMSA_HILOGD("unbind from service.");
640 StopClientInput(currentClientInfo, isNotifyClientAsync);
641 }
642 StopImeInput(currentClientInfo->bindImeType, currentClientInfo->channel);
643 }
644
StopClientInput(const std::shared_ptr<InputClientInfo> & clientInfo,bool isStopInactiveClient,bool isAsync)645 void PerUserSession::StopClientInput(
646 const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient, bool isAsync)
647 {
648 if (clientInfo == nullptr || clientInfo->client == nullptr) {
649 return;
650 }
651 auto ret = clientInfo->client->OnInputStop(isStopInactiveClient, isAsync);
652 IMSA_HILOGI("isStopInactiveClient: %{public}d, client pid: %{public}d, ret: %{public}d.", isStopInactiveClient,
653 clientInfo->pid, ret);
654 }
655
StopImeInput(ImeType currentType,const sptr<IRemoteObject> & currentChannel)656 void PerUserSession::StopImeInput(ImeType currentType, const sptr<IRemoteObject> ¤tChannel)
657 {
658 auto data = GetReadyImeData(currentType);
659 if (data == nullptr) {
660 return;
661 }
662 auto ret = RequestIme(data, RequestType::STOP_INPUT,
663 [&data, ¤tChannel]() { return data->core->StopInput(currentChannel); });
664 IMSA_HILOGI("stop ime input, ret: %{public}d.", ret);
665 if (ret == ErrorCode::NO_ERROR && currentType == ImeType::IME) {
666 InputMethodSysEvent::GetInstance().ReportImeState(ImeState::UNBIND, data->pid,
667 ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
668 Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID);
669 }
670 if (currentType == ImeType::IME) {
671 RestoreCurrentImeSubType();
672 }
673 }
674
OnSecurityChange(int32_t security)675 void PerUserSession::OnSecurityChange(int32_t security)
676 {
677 auto data = GetReadyImeData(ImeType::IME);
678 if (data == nullptr) {
679 IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
680 return;
681 }
682 auto ret =
683 RequestIme(data, RequestType::NORMAL, [&data, security] { return data->core->OnSecurityChange(security); });
684 IMSA_HILOGD("on security change, ret: %{public}d.", ret);
685 }
686
OnSetCoreAndAgent(const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent)687 int32_t PerUserSession::OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent)
688 {
689 IMSA_HILOGI("start.");
690 auto ret = UpdateImeData(core, agent, IPCSkeleton::GetCallingPid());
691 if (ret != ErrorCode::NO_ERROR) {
692 return ret;
693 }
694 auto action = GetImeAction(ImeEvent::SET_CORE_AND_AGENT);
695 if (action == ImeAction::DO_NOTHING) {
696 return ErrorCode::NO_ERROR;
697 }
698 if (action != ImeAction::DO_SET_CORE_AND_AGENT) {
699 return ErrorCode::ERROR_IME;
700 }
701 ret = InitInputControlChannel();
702 IMSA_HILOGI("init input control channel ret: %{public}d.", ret);
703 auto imeType = ImeType::IME;
704 auto client = GetCurrentClient();
705 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
706 if (clientInfo != nullptr && IsImeStartInBind(clientInfo->bindImeType, imeType)) {
707 BindClientWithIme(clientInfo, imeType);
708 SetInputType();
709 }
710 bool isStarted = true;
711 isImeStarted_.SetValue(isStarted);
712 return ErrorCode::NO_ERROR;
713 }
714
OnRegisterProxyIme(const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent)715 int32_t PerUserSession::OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent)
716 {
717 IMSA_HILOGD("start.");
718 auto imeType = ImeType::PROXY_IME;
719 auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid());
720 if (ret != ErrorCode::NO_ERROR) {
721 return ret;
722 }
723 auto client = GetCurrentClient();
724 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
725 if (clientInfo != nullptr) {
726 if (IsProxyImeStartInBind(clientInfo->bindImeType, imeType)) {
727 BindClientWithIme(clientInfo, imeType);
728 }
729 if (IsProxyImeStartInImeBind(clientInfo->bindImeType, imeType)) {
730 UnBindClientWithIme(clientInfo);
731 BindClientWithIme(clientInfo, imeType);
732 }
733 }
734 return ErrorCode::NO_ERROR;
735 }
736
OnUnRegisteredProxyIme(UnRegisteredType type,const sptr<IInputMethodCore> & core)737 int32_t PerUserSession::OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core)
738 {
739 IMSA_HILOGD("proxy unregister type: %{public}d.", type);
740 // 0: stop proxy 1: switch to ima
741 if (type == UnRegisteredType::REMOVE_PROXY_IME) {
742 RemoveIme(core, ImeType::PROXY_IME);
743 return ErrorCode::NO_ERROR;
744 }
745 if (type == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) {
746 auto client = GetCurrentClient();
747 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
748 if (clientInfo == nullptr) {
749 IMSA_HILOGE("not found current client!");
750 return ErrorCode::ERROR_CLIENT_NOT_BOUND;
751 }
752 if (clientInfo->bindImeType == ImeType::PROXY_IME) {
753 UnBindClientWithIme(clientInfo);
754 }
755 InputClientInfo infoTemp = { .isShowKeyboard = true,
756 .client = clientInfo->client,
757 .channel = clientInfo->channel };
758 return BindClientWithIme(std::make_shared<InputClientInfo>(infoTemp), ImeType::IME);
759 }
760 return ErrorCode::ERROR_BAD_PARAMETERS;
761 }
762
InitInputControlChannel()763 int32_t PerUserSession::InitInputControlChannel()
764 {
765 IMSA_HILOGD("PerUserSession::InitInputControlChannel start.");
766 sptr<IInputControlChannel> inputControlChannel = new InputControlChannelStub(userId_);
767 auto data = GetReadyImeData(ImeType::IME);
768 if (data == nullptr) {
769 IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
770 return ErrorCode::ERROR_IME_NOT_STARTED;
771 }
772 return RequestIme(data, RequestType::NORMAL,
773 [&data, &inputControlChannel] { return data->core->InitInputControlChannel(inputControlChannel); });
774 }
775
StartImeInImeDied()776 void PerUserSession::StartImeInImeDied()
777 {
778 IMSA_HILOGD("StartImeInImeDied.");
779 {
780 std::lock_guard<std::mutex> lock(resetLock);
781 auto now = time(nullptr);
782 if (difftime(now, manager.last) > IME_RESET_TIME_OUT) {
783 manager = { 0, now };
784 }
785 ++manager.num;
786 if (manager.num > MAX_RESTART_NUM) {
787 return;
788 }
789 }
790 if (!IsWmsReady()) {
791 IMSA_HILOGW("not ready to start ime.");
792 return;
793 }
794 StartImeIfInstalled();
795 }
796
StartImeIfInstalled()797 void PerUserSession::StartImeIfInstalled()
798 {
799 std::shared_ptr<ImeNativeCfg> imeToStart = nullptr;
800 if (!GetInputTypeToStart(imeToStart)) {
801 imeToStart = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
802 }
803 if (imeToStart == nullptr || imeToStart->imeId.empty()) {
804 IMSA_HILOGE("imeToStart is nullptr!");
805 return;
806 }
807 if (!ImeInfoInquirer::GetInstance().IsImeInstalled(userId_, imeToStart->bundleName, imeToStart->extName)) {
808 IMSA_HILOGE("imeToStart is not installed, imeId = %{public}s!", imeToStart->imeId.c_str());
809 return;
810 }
811 StartCurrentIme();
812 }
813
SetCurrentClient(sptr<IInputClient> client)814 void PerUserSession::SetCurrentClient(sptr<IInputClient> client)
815 {
816 IMSA_HILOGD("set current client.");
817 std::lock_guard<std::mutex> lock(clientLock_);
818 currentClient_ = client;
819 }
820
GetCurrentClient()821 sptr<IInputClient> PerUserSession::GetCurrentClient()
822 {
823 IMSA_HILOGD("get current client.");
824 std::lock_guard<std::mutex> lock(clientLock_);
825 return currentClient_;
826 }
827
ReplaceCurrentClient(const sptr<IInputClient> & client)828 void PerUserSession::ReplaceCurrentClient(const sptr<IInputClient> &client)
829 {
830 std::lock_guard<std::mutex> lock(focusedClientLock_);
831 if (client == nullptr) {
832 return;
833 }
834 auto clientInfo = GetClientInfo(client->AsObject());
835 if (clientInfo == nullptr) {
836 return;
837 }
838 auto replacedClient = GetCurrentClient();
839 SetCurrentClient(client);
840 if (replacedClient != nullptr) {
841 auto replacedClientInfo = GetClientInfo(replacedClient->AsObject());
842 if (replacedClientInfo != nullptr && replacedClientInfo->pid != clientInfo->pid) {
843 IMSA_HILOGI("remove replaced client: [%{public}d]", replacedClientInfo->pid);
844 RemoveClient(replacedClient);
845 }
846 }
847 auto inactiveClient = GetInactiveClient();
848 if (inactiveClient != nullptr) {
849 auto inactiveClientInfo = GetClientInfo(inactiveClient->AsObject());
850 if (inactiveClientInfo != nullptr && inactiveClientInfo->pid != clientInfo->pid) {
851 IMSA_HILOGI("remove inactive client: [%{public}d]", inactiveClientInfo->pid);
852 RemoveClient(inactiveClient, false);
853 }
854 }
855 }
856
SetInactiveClient(sptr<IInputClient> client)857 void PerUserSession::SetInactiveClient(sptr<IInputClient> client)
858 {
859 IMSA_HILOGD("set inactive client.");
860 std::lock_guard<std::mutex> lock(inactiveClientLock_);
861 inactiveClient_ = client;
862 }
863
GetInactiveClient()864 sptr<IInputClient> PerUserSession::GetInactiveClient()
865 {
866 std::lock_guard<std::mutex> lock(inactiveClientLock_);
867 return inactiveClient_;
868 }
869
NotifyImeChangeToClients(const Property & property,const SubProperty & subProperty)870 void PerUserSession::NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty)
871 {
872 IMSA_HILOGD("start.");
873 auto clientMap = GetClientMap();
874 for (const auto &client : clientMap) {
875 auto clientInfo = client.second;
876 if (clientInfo == nullptr || !EventStatusManager::IsImeChangeOn(clientInfo->eventFlag)) {
877 IMSA_HILOGD("client nullptr or no need to notify.");
878 continue;
879 }
880 IMSA_HILOGD("notify client: [%{public}d]", static_cast<int32_t>(clientInfo->pid));
881 int32_t ret = clientInfo->client->OnSwitchInput(property, subProperty);
882 if (ret != ErrorCode::NO_ERROR) {
883 IMSA_HILOGE("notify failed, ret: %{public}d, uid: %{public}d!", ret, static_cast<int32_t>(clientInfo->uid));
884 continue;
885 }
886 }
887 }
888
AddImeData(ImeType type,sptr<IInputMethodCore> core,sptr<IRemoteObject> agent,pid_t pid)889 int32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid)
890 {
891 if (core == nullptr || agent == nullptr) {
892 IMSA_HILOGE("core or agent is nullptr!");
893 return ErrorCode::ERROR_NULL_POINTER;
894 }
895 sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient();
896 if (deathRecipient == nullptr) {
897 IMSA_HILOGE("failed to new deathRecipient!");
898 return ErrorCode::ERROR_NULL_POINTER;
899 }
900 deathRecipient->SetDeathRecipient([this, core, type](const wptr<IRemoteObject> &) { this->OnImeDied(core, type); });
901 auto coreObject = core->AsObject();
902 if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) {
903 IMSA_HILOGE("failed to add death recipient!");
904 return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED;
905 }
906 std::lock_guard<std::mutex> lock(imeDataLock_);
907 auto imeData = std::make_shared<ImeData>(core, agent, deathRecipient, pid);
908 imeData->imeStatus = ImeStatus::READY;
909 imeData->ime.first = "proxyIme";
910 imeData_.insert_or_assign(type, imeData);
911 return ErrorCode::NO_ERROR;
912 }
913
GetReadyImeData(ImeType type)914 std::shared_ptr<ImeData> PerUserSession::GetReadyImeData(ImeType type)
915 {
916 std::lock_guard<std::mutex> lock(imeDataLock_);
917 auto it = imeData_.find(type);
918 if (it == imeData_.end()) {
919 return nullptr;
920 }
921 if (it->second->imeStatus != ImeStatus::READY) {
922 return nullptr;
923 }
924 return it->second;
925 }
926
GetValidIme(ImeType type)927 std::shared_ptr<ImeData> PerUserSession::GetValidIme(ImeType type)
928 {
929 auto data = GetReadyImeData(type);
930 if (data != nullptr || type != ImeType::IME) {
931 return data;
932 }
933 IMSA_HILOGI("current ime is empty, try to restart it.");
934 StartCurrentIme();
935 return GetReadyImeData(type);
936 }
937
RemoveImeData(ImeType type,bool isImeDied)938 void PerUserSession::RemoveImeData(ImeType type, bool isImeDied)
939 {
940 std::lock_guard<std::mutex> lock(imeDataLock_);
941 auto it = imeData_.find(type);
942 if (it == imeData_.end()) {
943 IMSA_HILOGD("imeData not found.");
944 return;
945 }
946 auto data = it->second;
947 if (isImeDied && data->core != nullptr && data->core->AsObject() != nullptr) {
948 data->core->AsObject()->RemoveDeathRecipient(data->deathRecipient);
949 }
950 imeData_.erase(type);
951 }
952
OnFocused(int32_t pid,int32_t uid)953 void PerUserSession::OnFocused(int32_t pid, int32_t uid)
954 {
955 std::lock_guard<std::mutex> lock(focusedClientLock_);
956 auto client = GetCurrentClient();
957 if (client == nullptr) {
958 return;
959 }
960 if (IsCurClientFocused(pid, uid)) {
961 IMSA_HILOGD("current client focused, focusedPid: %{public}d", pid);
962 return;
963 }
964 if (!OHOS::Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
965 IMSA_HILOGI("focus shifts to pid: %{public}d, remove current client.", pid);
966 RemoveClient(client);
967 InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED);
968 return;
969 }
970 IMSA_HILOGI("focus shifts to pid: %{public}d, deactivate current client.", pid);
971 DeactivateClient(client);
972 }
973
OnUnfocused(int32_t pid,int32_t uid)974 void PerUserSession::OnUnfocused(int32_t pid, int32_t uid)
975 {
976 if (GetCurrentClient() == nullptr) {
977 return;
978 }
979 if (IsCurClientUnFocused(pid, uid)) {
980 IMSA_HILOGD("current client Unfocused, unFocusedPid: %{public}d", pid);
981 return;
982 }
983 auto clientInfo = GetClientInfo(pid);
984 if (clientInfo == nullptr) {
985 return;
986 }
987 RemoveClient(clientInfo->client);
988 InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED);
989 }
990
OnUserUnlocked()991 void PerUserSession::OnUserUnlocked()
992 {
993 isUserUnlocked_.store(true);
994 ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, "");
995 auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
996 if (currentIme == nullptr) {
997 IMSA_HILOGE("currentIme nullptr");
998 return;
999 }
1000 auto imeData = GetImeData(ImeType::IME);
1001 if (imeData != nullptr && imeData->ime.first == currentIme->bundleName) {
1002 IMSA_HILOGD("no need to switch");
1003 return;
1004 }
1005 IMSA_HILOGI("user %{public}d unlocked, start current ime", userId_);
1006 #ifndef IMF_ON_DEMAND_START_STOP_SA_ENABLE
1007 AddRestartIme();
1008 #endif
1009 }
1010
UpdateUserLockState()1011 void PerUserSession::UpdateUserLockState()
1012 {
1013 bool isUnlocked = false;
1014 if (OsAccountAdapter::IsOsAccountVerified(userId_, isUnlocked) != ErrorCode::NO_ERROR) {
1015 return;
1016 }
1017 IMSA_HILOGI("isUnlocked: %{public}d", isUnlocked);
1018 isUserUnlocked_.store(isUnlocked);
1019 if (isUnlocked) {
1020 OnUserUnlocked();
1021 }
1022 }
1023
GetCurClientInfo()1024 std::shared_ptr<InputClientInfo> PerUserSession::GetCurClientInfo()
1025 {
1026 auto client = GetCurrentClient();
1027 if (client == nullptr) {
1028 IMSA_HILOGD("no client in bound state.");
1029 return nullptr;
1030 }
1031 return GetClientInfo(client->AsObject());
1032 }
1033
IsCurClientFocused(int32_t pid,int32_t uid)1034 bool PerUserSession::IsCurClientFocused(int32_t pid, int32_t uid)
1035 {
1036 auto clientInfo = GetCurClientInfo();
1037 if (clientInfo == nullptr) {
1038 IMSA_HILOGE("failed to get cur client info!");
1039 return false;
1040 }
1041 auto identityChecker = std::make_shared<IdentityCheckerImpl>();
1042 if (clientInfo->uiExtensionTokenId != IMF_INVALID_TOKENID &&
1043 identityChecker->IsFocusedUIExtension(clientInfo->uiExtensionTokenId)) {
1044 IMSA_HILOGI("UIExtension focused");
1045 return true;
1046 }
1047 return clientInfo->pid == pid && clientInfo->uid == uid;
1048 }
1049
IsCurClientUnFocused(int32_t pid,int32_t uid)1050 bool PerUserSession::IsCurClientUnFocused(int32_t pid, int32_t uid)
1051 {
1052 auto clientInfo = GetCurClientInfo();
1053 if (clientInfo == nullptr) {
1054 IMSA_HILOGE("failed to get cur client info!");
1055 return false;
1056 }
1057 auto identityChecker = std::make_shared<IdentityCheckerImpl>();
1058 if (clientInfo->uiExtensionTokenId != IMF_INVALID_TOKENID &&
1059 !identityChecker->IsFocusedUIExtension(clientInfo->uiExtensionTokenId)) {
1060 IMSA_HILOGI("UIExtension UnFocused.");
1061 return true;
1062 }
1063 return clientInfo->pid == pid && clientInfo->uid == uid;
1064 }
1065
IsSameClient(sptr<IInputClient> source,sptr<IInputClient> dest)1066 bool PerUserSession::IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest)
1067 {
1068 return source != nullptr && dest != nullptr && source->AsObject() == dest->AsObject();
1069 }
1070
StartCurrentIme(bool isStopCurrentIme)1071 int32_t PerUserSession::StartCurrentIme(bool isStopCurrentIme)
1072 {
1073 std::shared_ptr<ImeNativeCfg> imeToStart = nullptr;
1074 if (!GetInputTypeToStart(imeToStart)) {
1075 imeToStart = ImeInfoInquirer::GetInstance().GetImeToStart(userId_);
1076 }
1077 if (imeToStart == nullptr) {
1078 IMSA_HILOGE("imeToStart is nullptr!");
1079 return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1080 }
1081 auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1082 IMSA_HILOGD("currentIme: %{public}s, imeToStart: %{public}s.", currentIme->imeId.c_str(),
1083 imeToStart->imeId.c_str());
1084 auto ret = StartIme(imeToStart, isStopCurrentIme);
1085 if (ret != ErrorCode::NO_ERROR) {
1086 IMSA_HILOGE("failed to start ime!");
1087 InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ret,
1088 imeToStart->imeId, "start ime failed!");
1089 return ret;
1090 }
1091 currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1092 IMSA_HILOGI("current ime changed to %{public}s.", currentIme->imeId.c_str());
1093 auto currentImeInfo =
1094 ImeInfoInquirer::GetInstance().GetImeInfo(userId_, currentIme->bundleName, currentIme->subName);
1095 if (currentImeInfo == nullptr) {
1096 IMSA_HILOGD("currentImeInfo is nullptr!");
1097 return ErrorCode::NO_ERROR;
1098 }
1099
1100 NotifyImeChangeToClients(currentImeInfo->prop, currentImeInfo->subProp);
1101 ret = SwitchSubtypeWithoutStartIme(currentImeInfo->subProp);
1102 if (ret != ErrorCode::NO_ERROR) {
1103 IMSA_HILOGE("SwitchSubtype failed!");
1104 }
1105 return ErrorCode::NO_ERROR;
1106 }
1107
GetCurrentUsingImeId(ImeIdentification & imeId)1108 bool PerUserSession::GetCurrentUsingImeId(ImeIdentification &imeId)
1109 {
1110 if (InputTypeManager::GetInstance().IsStarted()) {
1111 IMSA_HILOGI("get right click on state current ime.");
1112 auto currentIme = InputTypeManager::GetInstance().GetCurrentIme();
1113 imeId = currentIme;
1114 return true;
1115 }
1116 auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1117 if (currentImeCfg == nullptr) {
1118 IMSA_HILOGE("currentImeCfg is nullptr!");
1119 return false;
1120 }
1121 imeId.bundleName = currentImeCfg->bundleName;
1122 imeId.subName = currentImeCfg->extName;
1123 return true;
1124 }
1125
CanStartIme()1126 bool PerUserSession::CanStartIme()
1127 {
1128 return IsSaReady(MEMORY_MANAGER_SA_ID) && IsWmsReady() && runningIme_.empty();
1129 }
1130
ChangeToDefaultImeIfNeed(const std::shared_ptr<ImeNativeCfg> & targetIme,std::shared_ptr<ImeNativeCfg> & imeToStart)1131 int32_t PerUserSession::ChangeToDefaultImeIfNeed(
1132 const std::shared_ptr<ImeNativeCfg> &targetIme, std::shared_ptr<ImeNativeCfg> &imeToStart)
1133 {
1134 if (isUserUnlocked_.load()) {
1135 IMSA_HILOGD("no need");
1136 imeToStart = targetIme;
1137 return ErrorCode::NO_ERROR;
1138 }
1139 IMSA_HILOGI("Screen is locked, start default ime");
1140 auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg();
1141 if (defaultIme == nullptr) {
1142 IMSA_HILOGE("failed to get default ime");
1143 return ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND;
1144 }
1145 if (defaultIme->bundleName == targetIme->bundleName) {
1146 IMSA_HILOGD("no need");
1147 imeToStart = targetIme;
1148 return ErrorCode::NO_ERROR;
1149 }
1150 imeToStart = defaultIme;
1151 ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, imeToStart->imeId);
1152 return ErrorCode::NO_ERROR;
1153 }
1154
GetWant(const std::shared_ptr<ImeNativeCfg> & ime)1155 AAFwk::Want PerUserSession::GetWant(const std::shared_ptr<ImeNativeCfg> &ime)
1156 {
1157 SecurityMode mode;
1158 bool isolatedSandBox = true;
1159 if (SecurityModeParser::GetInstance()->IsDefaultFullMode(ime->bundleName, userId_)) {
1160 mode = SecurityMode::FULL;
1161 isolatedSandBox = false;
1162 } else if (ImeInfoInquirer::GetInstance().IsEnableSecurityMode()) {
1163 mode = SecurityModeParser::GetInstance()->GetSecurityMode(ime->bundleName, userId_);
1164 } else {
1165 mode = SecurityMode::FULL;
1166 }
1167 AAFwk::Want want;
1168 want.SetElementName(ime->bundleName, ime->extName);
1169 want.SetParam(STRICT_MODE, !(mode == SecurityMode::FULL));
1170 want.SetParam(ISOLATED_SANDBOX, isolatedSandBox);
1171 IMSA_HILOGI("StartInputService userId: %{public}d, ime: %{public}s, mode: %{public}d, isolatedSandbox: %{public}d",
1172 userId_, ime->imeId.c_str(), static_cast<int32_t>(mode), isolatedSandBox);
1173 return want;
1174 }
1175
StartInputService(const std::shared_ptr<ImeNativeCfg> & ime)1176 int32_t PerUserSession::StartInputService(const std::shared_ptr<ImeNativeCfg> &ime)
1177 {
1178 if (ime == nullptr) {
1179 return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1180 }
1181 auto imeToStart = std::make_shared<ImeNativeCfg>();
1182 auto ret = ChangeToDefaultImeIfNeed(ime, imeToStart);
1183 if (ret != ErrorCode::NO_ERROR) {
1184 return ret;
1185 }
1186 InitImeData({ imeToStart->bundleName, imeToStart->extName });
1187 isImeStarted_.Clear(false);
1188 sptr<AAFwk::IAbilityConnection> connection = new (std::nothrow) ImeConnection();
1189 if (connection == nullptr) {
1190 IMSA_HILOGE("failed to create connection!");
1191 return ErrorCode::ERROR_IMSA_MALLOC_FAILED;
1192 }
1193 auto want = GetWant(imeToStart);
1194 ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_);
1195 if (ret != ErrorCode::NO_ERROR) {
1196 IMSA_HILOGE("connect %{public}s failed, ret: %{public}d!", imeToStart->imeId.c_str(), ret);
1197 InputMethodSysEvent::GetInstance().InputmethodFaultReporter(
1198 ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, imeToStart->imeId, "failed to start ability.");
1199 return ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED;
1200 }
1201 if (!isImeStarted_.GetValue()) {
1202 IMSA_HILOGE("start %{public}s timeout!", imeToStart->imeId.c_str());
1203 return ErrorCode::ERROR_IMSA_IME_START_TIMEOUT;
1204 }
1205 IMSA_HILOGI("%{public}s started successfully.", imeToStart->imeId.c_str());
1206 InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::START_IME);
1207 return ErrorCode::NO_ERROR;
1208 }
1209
GetCurrentClientPid()1210 int64_t PerUserSession::GetCurrentClientPid()
1211 {
1212 auto client = GetCurrentClient();
1213 if (client == nullptr) {
1214 return INVALID_PID;
1215 }
1216 auto clientInfo = GetClientInfo(client->AsObject());
1217 if (clientInfo == nullptr) {
1218 return INVALID_PID;
1219 }
1220 return clientInfo->pid;
1221 }
1222
GetInactiveClientPid()1223 int64_t PerUserSession::GetInactiveClientPid()
1224 {
1225 auto client = GetInactiveClient();
1226 if (client == nullptr) {
1227 return INVALID_PID;
1228 }
1229 auto clientInfo = GetClientInfo(client->AsObject());
1230 if (clientInfo == nullptr) {
1231 return INVALID_PID;
1232 }
1233 return clientInfo->pid;
1234 }
1235
OnPanelStatusChange(const InputWindowStatus & status,const ImeWindowInfo & info)1236 int32_t PerUserSession::OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info)
1237 {
1238 auto clientMap = GetClientMap();
1239 for (const auto &client : clientMap) {
1240 auto clientInfo = client.second;
1241 if (clientInfo == nullptr) {
1242 IMSA_HILOGD("client nullptr or no need to notify.");
1243 continue;
1244 }
1245 if (status == InputWindowStatus::SHOW && !EventStatusManager::IsImeShowOn(clientInfo->eventFlag)) {
1246 IMSA_HILOGD("has not imeShow callback");
1247 continue;
1248 }
1249 if (status == InputWindowStatus::HIDE && !EventStatusManager::IsImeHideOn(clientInfo->eventFlag)) {
1250 IMSA_HILOGD("has not imeHide callback");
1251 continue;
1252 }
1253 int32_t ret = clientInfo->client->OnPanelStatusChange(status, info);
1254 if (ret != ErrorCode::NO_ERROR) {
1255 IMSA_HILOGE("failed to OnPanelStatusChange, ret: %{public}d", ret);
1256 continue;
1257 }
1258 }
1259 return ErrorCode::NO_ERROR;
1260 }
1261
OnUpdateListenEventFlag(const InputClientInfo & clientInfo)1262 int32_t PerUserSession::OnUpdateListenEventFlag(const InputClientInfo &clientInfo)
1263 {
1264 auto remoteClient = clientInfo.client->AsObject();
1265 auto ret = AddClientInfo(remoteClient, clientInfo, START_LISTENING);
1266 if (ret != ErrorCode::NO_ERROR) {
1267 IMSA_HILOGE("failed to AddClientInfo!");
1268 return ret;
1269 }
1270 auto info = GetClientInfo(remoteClient);
1271 if (info == nullptr) {
1272 IMSA_HILOGE("info is nullptr!");
1273 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
1274 }
1275 if (info->eventFlag == NO_EVENT_ON && info->bindImeType == ImeType::NONE) {
1276 RemoveClientInfo(remoteClient, false);
1277 }
1278 return ErrorCode::NO_ERROR;
1279 }
1280
OnSetCallingWindow(uint32_t callingWindowId,sptr<IInputClient> client)1281 int32_t PerUserSession::OnSetCallingWindow(uint32_t callingWindowId, sptr<IInputClient> client)
1282 {
1283 IMSA_HILOGD("OnSetCallingWindow enter");
1284 if (!IsSameClient(client, GetCurrentClient())) {
1285 IMSA_HILOGE("client is not current client!");
1286 return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
1287 }
1288 if (client == nullptr) {
1289 IMSA_HILOGE("nullptr client!");
1290 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1291 }
1292 auto clientInfo = GetClientInfo(client->AsObject());
1293 if (clientInfo == nullptr) {
1294 IMSA_HILOGE("nullptr clientInfo!");
1295 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1296 }
1297 if (clientInfo->config.windowId == callingWindowId) {
1298 return ErrorCode::NO_ERROR;
1299 }
1300 InputClientInfo clientInfoTmp = *clientInfo;
1301 clientInfoTmp.config.windowId = callingWindowId;
1302 auto callingWindowInfo = GetCallingWindowInfo(clientInfoTmp);
1303 if (callingWindowInfo.windowId == clientInfo->config.windowId) {
1304 return ErrorCode::NO_ERROR;
1305 }
1306 clientInfo->config.windowId = callingWindowInfo.windowId;
1307 clientInfo->config.inputAttribute.windowId = callingWindowInfo.windowId;
1308 bool isNotifyDisplayChanged = clientInfo->config.inputAttribute.callingDisplayId != callingWindowInfo.displayId
1309 && SceneBoardJudgement::IsSceneBoardEnabled();
1310 clientInfo->config.inputAttribute.callingDisplayId = callingWindowInfo.displayId;
1311 IMSA_HILOGD("windowId changed, refresh windowId info and notify clients input start.");
1312 NotifyInputStartToClients(callingWindowInfo.windowId, static_cast<int32_t>(clientInfo->requestKeyboardReason));
1313 if (isNotifyDisplayChanged) {
1314 NotifyCallingDisplayChanged(callingWindowInfo.displayId);
1315 }
1316 return ErrorCode::NO_ERROR;
1317 }
1318
GetInputStartInfo(bool & isInputStart,uint32_t & callingWndId,int32_t & requestKeyboardReason)1319 int32_t PerUserSession::GetInputStartInfo(bool& isInputStart, uint32_t& callingWndId, int32_t& requestKeyboardReason)
1320 {
1321 auto client = GetCurrentClient();
1322 if (client == nullptr) {
1323 IMSA_HILOGE("nullptr client!");
1324 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1325 }
1326 auto clientInfo = GetClientInfo(client->AsObject());
1327 if (clientInfo == nullptr) {
1328 IMSA_HILOGE("nullptr clientInfo!");
1329 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1330 }
1331 isInputStart = true;
1332 callingWndId = clientInfo->config.windowId;
1333 requestKeyboardReason = static_cast<int32_t>(clientInfo->requestKeyboardReason);
1334 return ErrorCode::NO_ERROR;
1335 }
1336
NotifyInputStartToClients(uint32_t callingWndId,int32_t requestKeyboardReason)1337 int32_t PerUserSession::NotifyInputStartToClients(uint32_t callingWndId, int32_t requestKeyboardReason)
1338 {
1339 IMSA_HILOGD("NotifyInputStartToClients enter");
1340 auto clientMap = GetClientMap();
1341 for (const auto &client : clientMap) {
1342 auto clientInfo = client.second;
1343 if (clientInfo == nullptr || clientInfo->client == nullptr ||
1344 !EventStatusManager::IsInputStatusChangedOn(clientInfo->eventFlag)) {
1345 IMSA_HILOGE("nullptr clientInfo or no need to notify");
1346 continue;
1347 }
1348 int32_t ret = clientInfo->client->NotifyInputStart(callingWndId, requestKeyboardReason);
1349 if (ret != ErrorCode::NO_ERROR) {
1350 IMSA_HILOGE("failed to notify OnInputStart, errorCode: %{public}d", ret);
1351 continue;
1352 }
1353 }
1354 return ErrorCode::NO_ERROR;
1355 }
1356
NotifyInputStopToClients()1357 int32_t PerUserSession::NotifyInputStopToClients()
1358 {
1359 IMSA_HILOGD("NotifyInputStopToClients enter");
1360 auto clientMap = GetClientMap();
1361 for (const auto &client : clientMap) {
1362 auto clientInfo = client.second;
1363 if (clientInfo == nullptr || clientInfo->client == nullptr ||
1364 !EventStatusManager::IsInputStatusChangedOn(clientInfo->eventFlag)) {
1365 IMSA_HILOGE("nullptr clientInfo or no need to notify");
1366 continue;
1367 }
1368 int32_t ret = clientInfo->client->NotifyInputStop();
1369 if (ret != ErrorCode::NO_ERROR) {
1370 IMSA_HILOGE("failed to notify OnInputStop, errorCode: %{public}d", ret);
1371 continue;
1372 }
1373 }
1374 return ErrorCode::NO_ERROR;
1375 }
1376
IsNotifyInputStop(const sptr<IInputClient> & client)1377 bool PerUserSession::IsNotifyInputStop(const sptr<IInputClient> &client)
1378 {
1379 if (IsSameClient(client, GetCurrentClient())) {
1380 return true;
1381 }
1382 if (IsSameClient(client, GetInactiveClient()) && GetCurrentClient() == nullptr) {
1383 return true;
1384 }
1385 return false;
1386 }
1387
IsImeStartInBind(ImeType bindImeType,ImeType startImeType)1388 bool PerUserSession::IsImeStartInBind(ImeType bindImeType, ImeType startImeType)
1389 {
1390 return startImeType == ImeType::IME && bindImeType == ImeType::IME;
1391 }
1392
IsProxyImeStartInBind(ImeType bindImeType,ImeType startImeType)1393 bool PerUserSession::IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType)
1394 {
1395 return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::PROXY_IME;
1396 }
1397
IsProxyImeStartInImeBind(ImeType bindImeType,ImeType startImeType)1398 bool PerUserSession::IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType)
1399 {
1400 return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::IME;
1401 }
1402
IsImeBindTypeChanged(ImeType bindImeType)1403 bool PerUserSession::IsImeBindTypeChanged(ImeType bindImeType)
1404 {
1405 return (bindImeType == ImeType::IME && IsProxyImeEnable()) ||
1406 (bindImeType == ImeType::PROXY_IME && !IsProxyImeEnable());
1407 }
1408
SwitchSubtype(const SubProperty & subProperty)1409 int32_t PerUserSession::SwitchSubtype(const SubProperty &subProperty)
1410 {
1411 auto data = GetValidIme(ImeType::IME);
1412 if (data == nullptr) {
1413 IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1414 return ErrorCode::ERROR_IME_NOT_STARTED;
1415 }
1416 return RequestIme(data, RequestType::NORMAL, [&data, &subProperty] { return data->core->SetSubtype(subProperty); });
1417 }
1418
SwitchSubtypeWithoutStartIme(const SubProperty & subProperty)1419 int32_t PerUserSession::SwitchSubtypeWithoutStartIme(const SubProperty &subProperty)
1420 {
1421 auto data = GetReadyImeData(ImeType::IME);
1422 if (data == nullptr || data->core == nullptr) {
1423 IMSA_HILOGE("ime: %{public}d is not exist, or core is nullptr.", ImeType::IME);
1424 return ErrorCode::ERROR_IME_NOT_STARTED;
1425 }
1426 return RequestIme(data, RequestType::NORMAL,
1427 [&data, &subProperty] { return data->core->SetSubtype(subProperty); });
1428 }
1429
SetInputType()1430 int32_t PerUserSession::SetInputType()
1431 {
1432 InputType inputType = InputTypeManager::GetInstance().GetCurrentInputType();
1433 auto data = GetValidIme(ImeType::IME);
1434 if (data == nullptr) {
1435 IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1436 return ErrorCode::ERROR_IME_NOT_STARTED;
1437 }
1438 return RequestIme(data, RequestType::NORMAL, [&data, &inputType] { return data->core->OnSetInputType(inputType); });
1439 }
1440
IsBoundToClient()1441 bool PerUserSession::IsBoundToClient()
1442 {
1443 if (GetCurrentClient() == nullptr) {
1444 IMSA_HILOGE("not in bound state!");
1445 return false;
1446 }
1447 return true;
1448 }
1449
RestoreCurrentImeSubType()1450 int32_t PerUserSession::RestoreCurrentImeSubType()
1451 {
1452 if (!InputTypeManager::GetInstance().IsStarted()) {
1453 IMSA_HILOGD("already exit.");
1454 return ErrorCode::NO_ERROR;
1455 }
1456 auto typeIme = InputTypeManager::GetInstance().GetCurrentIme();
1457 auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1458 if (cfgIme->bundleName != typeIme.bundleName) {
1459 IMSA_HILOGD("diff ime, not deal, restore ime when attach.");
1460 return ErrorCode::NO_ERROR;
1461 }
1462 auto imeData = GetReadyImeData(ImeType::IME);
1463 InputTypeManager::GetInstance().Set(false);
1464 if (imeData == nullptr || imeData->ime.first != cfgIme->bundleName || imeData->ime.second != cfgIme->extName) {
1465 return ErrorCode::NO_ERROR;
1466 }
1467 SubProperty subProp = { .name = cfgIme->bundleName, .id = cfgIme->subName };
1468 auto subPropTemp = ImeInfoInquirer::GetInstance().GetCurrentSubtype(userId_);
1469 if (subPropTemp != nullptr) {
1470 subProp = *subPropTemp;
1471 }
1472 IMSA_HILOGD("same ime, restore subtype: %{public}s.", cfgIme->subName.c_str());
1473 return SwitchSubtype(subProp);
1474 }
1475
IsCurrentImeByPid(int32_t pid)1476 bool PerUserSession::IsCurrentImeByPid(int32_t pid)
1477 {
1478 auto imeData = GetImeData(ImeType::IME);
1479 if (imeData == nullptr) {
1480 IMSA_HILOGE("ime not started!");
1481 return false;
1482 }
1483 IMSA_HILOGD("userId: %{public}d, pid: %{public}d, current pid: %{public}d.", userId_, pid, imeData->pid);
1484 return imeData->pid == pid;
1485 }
1486
IsPanelShown(const PanelInfo & panelInfo,bool & isShown)1487 int32_t PerUserSession::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
1488 {
1489 if (GetCurrentClient() == nullptr) {
1490 IMSA_HILOGI("not in bound state.");
1491 isShown = false;
1492 return ErrorCode::NO_ERROR;
1493 }
1494 auto ime = GetReadyImeData(ImeType::IME);
1495 if (ime == nullptr) {
1496 IMSA_HILOGE("ime not started!");
1497 return ErrorCode::ERROR_IME_NOT_STARTED;
1498 }
1499 return RequestIme(ime, RequestType::NORMAL,
1500 [&ime, &panelInfo, &isShown] { return ime->core->IsPanelShown(panelInfo, isShown); });
1501 }
1502
CheckSecurityMode()1503 bool PerUserSession::CheckSecurityMode()
1504 {
1505 auto client = GetCurrentClient();
1506 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
1507 if (clientInfo != nullptr) {
1508 return clientInfo->config.inputAttribute.GetSecurityFlag();
1509 }
1510 return false;
1511 }
1512
GetClientMap()1513 std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> PerUserSession::GetClientMap()
1514 {
1515 std::lock_guard<std::recursive_mutex> lock(mtx);
1516 return mapClients_;
1517 }
1518
RequestIme(const std::shared_ptr<ImeData> & data,RequestType type,const IpcExec & exec)1519 int32_t PerUserSession::RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec)
1520 {
1521 if (IsProxyImeEnable()) {
1522 IMSA_HILOGD("proxy enable.");
1523 return exec();
1524 }
1525 if (data == nullptr || data->freezeMgr == nullptr) {
1526 IMSA_HILOGE("data is nullptr!");
1527 return ErrorCode::NO_ERROR;
1528 }
1529 if (!data->freezeMgr->IsIpcNeeded(type)) {
1530 IMSA_HILOGD("no need to request, type: %{public}d.", type);
1531 return ErrorCode::NO_ERROR;
1532 }
1533 data->freezeMgr->BeforeIpc(type);
1534 auto ret = exec();
1535 data->freezeMgr->AfterIpc(type, ret == ErrorCode::NO_ERROR);
1536 return ret;
1537 }
1538
OnConnectSystemCmd(const sptr<IRemoteObject> & channel,sptr<IRemoteObject> & agent)1539 int32_t PerUserSession::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent)
1540 {
1541 auto data = GetReadyImeData(ImeType::IME);
1542 if (data == nullptr) {
1543 IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1544 return ErrorCode::ERROR_IME_NOT_STARTED;
1545 }
1546 auto ret = RequestIme(data, RequestType::NORMAL,
1547 [&data, &channel, &agent] { return data->core->OnConnectSystemCmd(channel, agent); });
1548 IMSA_HILOGD("on connect systemCmd, ret: %{public}d.", ret);
1549 if (ret != ErrorCode::NO_ERROR) {
1550 IMSA_HILOGE("bind failed, ret: %{public}d!", ret);
1551 return ret;
1552 }
1553 return ErrorCode::NO_ERROR;
1554 }
1555
WaitForCurrentImeStop()1556 bool PerUserSession::WaitForCurrentImeStop()
1557 {
1558 IMSA_HILOGI("start.");
1559 std::unique_lock<std::mutex> lock(imeStopMutex_);
1560 isSwitching_.store(true);
1561 return imeStopCv_.wait_for(lock, std::chrono::milliseconds(STOP_IME_TIME), [this]() { return !isSwitching_; });
1562 }
1563
NotifyImeStopFinished()1564 void PerUserSession::NotifyImeStopFinished()
1565 {
1566 IMSA_HILOGI("start.");
1567 std::unique_lock<std::mutex> lock(imeStopMutex_);
1568 isSwitching_.store(false);
1569 imeStopCv_.notify_one();
1570 }
1571
RemoveCurrentClient()1572 int32_t PerUserSession::RemoveCurrentClient()
1573 {
1574 auto currentClient = GetCurrentClient();
1575 if (currentClient == nullptr) {
1576 IMSA_HILOGE("currentClient is nullptr!");
1577 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1578 }
1579 NotifyInputStopToClients();
1580 return RemoveClient(currentClient, false);
1581 }
1582
IsWmsReady()1583 bool PerUserSession::IsWmsReady()
1584 {
1585 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
1586 IMSA_HILOGD("scb enable");
1587 return WmsConnectionObserver::IsWmsConnected(userId_);
1588 }
1589 return IsSaReady(WINDOW_MANAGER_SERVICE_ID);
1590 }
1591
IsSaReady(int32_t saId)1592 bool PerUserSession::IsSaReady(int32_t saId)
1593 {
1594 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1595 if (saMgr == nullptr) {
1596 IMSA_HILOGE("get saMgr failed!");
1597 return false;
1598 }
1599 if (saMgr->CheckSystemAbility(saId) == nullptr) {
1600 IMSA_HILOGE("sa:%{public}d not ready!", saId);
1601 return false;
1602 }
1603 return true;
1604 }
1605
AddRestartIme()1606 void PerUserSession::AddRestartIme()
1607 {
1608 int32_t tasks = 0;
1609 {
1610 std::lock_guard<std::mutex> lock(restartMutex_);
1611 if (restartTasks_ >= MAX_RESTART_TASKS) {
1612 return;
1613 }
1614 restartTasks_ = std::max(restartTasks_, 0);
1615 tasks = ++restartTasks_;
1616 }
1617 if (tasks == 1 && !RestartIme()) {
1618 std::lock_guard<std::mutex> lock(restartMutex_);
1619 restartTasks_ = 0;
1620 }
1621 }
1622
RestartIme()1623 bool PerUserSession::RestartIme()
1624 {
1625 auto task = [this]() {
1626 if (CanStartIme()) {
1627 auto ret = StartCurrentIme(true);
1628 if (ret != ErrorCode::NO_ERROR) {
1629 IMSA_HILOGE("start ime failed!");
1630 }
1631 }
1632 int32_t tasks = 0;
1633 {
1634 std::lock_guard<std::mutex> lock(restartMutex_);
1635 tasks = --restartTasks_;
1636 }
1637 if (tasks > 0 && !RestartIme()) {
1638 std::lock_guard<std::mutex> lock(restartMutex_);
1639 restartTasks_ = 0;
1640 }
1641 };
1642 if (eventHandler_ == nullptr) {
1643 IMSA_HILOGE("eventHandler_ is nullptr!");
1644 return false;
1645 }
1646 return eventHandler_->PostTask(task, "RestartCurrentImeTask", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1647 }
1648
GetSwitchQueue()1649 BlockQueue<SwitchInfo>& PerUserSession::GetSwitchQueue()
1650 {
1651 return switchQueue_;
1652 }
1653
InitImeData(const std::pair<std::string,std::string> & ime)1654 int32_t PerUserSession::InitImeData(const std::pair<std::string, std::string> &ime)
1655 {
1656 std::lock_guard<std::mutex> lock(imeDataLock_);
1657 auto it = imeData_.find(ImeType::IME);
1658 if (it != imeData_.end()) {
1659 return ErrorCode::NO_ERROR;
1660 }
1661 auto imeData = std::make_shared<ImeData>(nullptr, nullptr, nullptr, -1);
1662 imeData->startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1663 imeData->ime = ime;
1664 imeData_.insert({ ImeType::IME, imeData });
1665 return ErrorCode::NO_ERROR;
1666 }
1667
UpdateImeData(sptr<IInputMethodCore> core,sptr<IRemoteObject> agent,pid_t pid)1668 int32_t PerUserSession::UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid)
1669 {
1670 if (core == nullptr || agent == nullptr) {
1671 IMSA_HILOGE("core or agent is nullptr!");
1672 return ErrorCode::ERROR_NULL_POINTER;
1673 }
1674 std::lock_guard<std::mutex> lock(imeDataLock_);
1675 auto it = imeData_.find(ImeType::IME);
1676 if (it == imeData_.end()) {
1677 return ErrorCode::ERROR_NULL_POINTER;
1678 }
1679 it->second->core = core;
1680 it->second->agent = agent;
1681 it->second->pid = pid;
1682 it->second->freezeMgr = std::make_shared<FreezeManager>(pid);
1683 sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient();
1684 if (deathRecipient == nullptr) {
1685 IMSA_HILOGE("failed to new deathRecipient!");
1686 return ErrorCode::ERROR_NULL_POINTER;
1687 }
1688 auto type = ImeType::IME;
1689 deathRecipient->SetDeathRecipient([this, core, type](const wptr<IRemoteObject> &) { this->OnImeDied(core, type); });
1690 auto coreObject = core->AsObject();
1691 if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) {
1692 IMSA_HILOGE("failed to add death recipient!");
1693 return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED;
1694 }
1695 it->second->deathRecipient = deathRecipient;
1696 return ErrorCode::NO_ERROR;
1697 }
1698
InitConnect(pid_t pid)1699 int32_t PerUserSession::InitConnect(pid_t pid)
1700 {
1701 std::lock_guard<std::mutex> lock(imeDataLock_);
1702 auto it = imeData_.find(ImeType::IME);
1703 if (it == imeData_.end()) {
1704 return ErrorCode::ERROR_NULL_POINTER;
1705 }
1706 it->second->pid = pid;
1707 return ErrorCode::NO_ERROR;
1708 }
1709
GetImeData(ImeType type)1710 std::shared_ptr<ImeData> PerUserSession::GetImeData(ImeType type)
1711 {
1712 std::lock_guard<std::mutex> lock(imeDataLock_);
1713 auto it = imeData_.find(type);
1714 if (it == imeData_.end()) {
1715 return nullptr;
1716 }
1717 return it->second;
1718 }
1719
StartIme(const std::shared_ptr<ImeNativeCfg> & ime,bool isStopCurrentIme)1720 int32_t PerUserSession::StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme)
1721 {
1722 std::lock_guard<std::mutex> lock(imeStartLock_);
1723 if (ime == nullptr) {
1724 return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1725 }
1726 auto imeData = GetImeData(ImeType::IME);
1727 if (imeData == nullptr) {
1728 return HandleFirstStart(ime, isStopCurrentIme);
1729 }
1730 if (imeData->ime.first == ime->bundleName && imeData->ime.second == ime->extName) {
1731 if (isStopCurrentIme) {
1732 return StartNewIme(ime);
1733 }
1734 return StartCurrentIme(ime);
1735 }
1736 return StartNewIme(ime);
1737 }
1738
GetImeAction(ImeEvent action)1739 ImeAction PerUserSession::GetImeAction(ImeEvent action)
1740 {
1741 std::lock_guard<std::mutex> lock(imeDataLock_);
1742 auto it = imeData_.find(ImeType::IME);
1743 if (it == imeData_.end()) {
1744 return ImeAction::DO_ACTION_IN_NULL_IME_DATA;
1745 }
1746 auto iter = imeEventConverter_.find({ it->second->imeStatus, action });
1747 if (iter == imeEventConverter_.end()) {
1748 IMSA_HILOGE("abnormal!");
1749 return ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED;
1750 }
1751 it->second->imeStatus = iter->second.first;
1752 return iter->second.second;
1753 }
1754
StartCurrentIme(const std::shared_ptr<ImeNativeCfg> & ime)1755 int32_t PerUserSession::StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime)
1756 {
1757 auto imeData = GetImeData(ImeType::IME);
1758 if (imeData == nullptr) {
1759 return StartInputService(ime);
1760 }
1761 auto action = GetImeAction(ImeEvent::START_IME);
1762 if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
1763 return ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
1764 }
1765 if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
1766 return StartInputService(ime);
1767 }
1768 if (action == ImeAction::DO_NOTHING) {
1769 return ErrorCode::NO_ERROR;
1770 }
1771 if (action == ImeAction::HANDLE_STARTING_IME) {
1772 int64_t time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1773 if (time - imeData->startTime > ImeData::START_TIME_OUT) {
1774 IMSA_HILOGE("[%{public}s, %{public}s] start abnormal, more than eight second!", imeData->ime.first.c_str(),
1775 imeData->ime.second.c_str());
1776 return HandleStartImeTimeout(ime);
1777 }
1778 return StartInputService(ime);
1779 }
1780 auto ret = ForceStopCurrentIme();
1781 if (ret != ErrorCode::NO_ERROR) {
1782 return ret;
1783 }
1784 return StartInputService(ime);
1785 }
1786
HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> & ime)1787 int32_t PerUserSession::HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime)
1788 {
1789 auto action = GetImeAction(ImeEvent::START_IME_TIMEOUT);
1790 if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
1791 return StartInputService(ime);
1792 }
1793 if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
1794 return ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
1795 }
1796 if (action == ImeAction::DO_NOTHING) {
1797 IMSA_HILOGW("ready when timeout");
1798 return ErrorCode::NO_ERROR;
1799 }
1800 auto ret = ForceStopCurrentIme(false);
1801 if (ret != ErrorCode::NO_ERROR) {
1802 return ret;
1803 }
1804 return StartInputService(ime);
1805 }
1806
StartNewIme(const std::shared_ptr<ImeNativeCfg> & ime)1807 int32_t PerUserSession::StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime)
1808 {
1809 auto ret = StopCurrentIme();
1810 if (ret != ErrorCode::NO_ERROR) {
1811 return ret;
1812 }
1813 return StartInputService(ime);
1814 }
1815
StopCurrentIme()1816 int32_t PerUserSession::StopCurrentIme()
1817 {
1818 auto action = GetImeAction(ImeEvent::STOP_IME);
1819 if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
1820 return ErrorCode::NO_ERROR;
1821 }
1822 if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
1823 return ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
1824 }
1825 if (action == ImeAction::STOP_READY_IME) {
1826 return StopReadyCurrentIme();
1827 }
1828 return ForceStopCurrentIme();
1829 }
1830
StopReadyCurrentIme()1831 int32_t PerUserSession::StopReadyCurrentIme()
1832 {
1833 auto client = GetCurrentClient();
1834 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
1835 if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
1836 StopClientInput(clientInfo);
1837 }
1838 auto imeData = GetImeData(ImeType::IME);
1839 if (imeData == nullptr) {
1840 return ErrorCode::NO_ERROR;
1841 }
1842 if (imeData->core == nullptr) {
1843 IMSA_HILOGE("core is nullptr!");
1844 return ForceStopCurrentIme();
1845 }
1846 auto ret = RequestIme(imeData, RequestType::NORMAL, [&imeData] {
1847 // failed when register onInputStop after SetCoreAndAgent
1848 return imeData->core->StopInputService(true);
1849 });
1850 if (ret != ErrorCode::NO_ERROR) {
1851 IMSA_HILOGE("StopInputService failed.");
1852 return ForceStopCurrentIme();
1853 }
1854 if (!WaitForCurrentImeStop()) {
1855 IMSA_HILOGI("stop timeout.");
1856 return ForceStopCurrentIme();
1857 }
1858 return ErrorCode::NO_ERROR;
1859 }
1860
ForceStopCurrentIme(bool isNeedWait)1861 int32_t PerUserSession::ForceStopCurrentIme(bool isNeedWait)
1862 {
1863 auto imeData = GetImeData(ImeType::IME);
1864 if (imeData == nullptr) {
1865 return ErrorCode::NO_ERROR;
1866 }
1867 if (!ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) {
1868 IMSA_HILOGW("[%{public}s, %{public}s] already stop.", imeData->ime.first.c_str(), imeData->ime.second.c_str());
1869 RemoveImeData(ImeType::IME, true);
1870 return ErrorCode::NO_ERROR;
1871 }
1872 auto client = GetCurrentClient();
1873 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
1874 if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
1875 StopClientInput(clientInfo);
1876 }
1877
1878 AAFwk::Want want;
1879 want.SetElementName(imeData->ime.first, imeData->ime.second);
1880 auto ret = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(
1881 want, nullptr, userId_, AppExecFwk::ExtensionAbilityType::INPUTMETHOD);
1882 if (ret != ErrorCode::NO_ERROR) {
1883 IMSA_HILOGE("StopExtensionAbility [%{public}s, %{public}s] failed, ret: %{public}d!",
1884 imeData->ime.first.c_str(), imeData->ime.second.c_str(), ret);
1885 return ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED;
1886 }
1887 if (!isNeedWait) {
1888 return ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND;
1889 }
1890 WaitForCurrentImeStop();
1891 if (ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) {
1892 IMSA_HILOGW("stop [%{public}s, %{public}s] timeout.", imeData->ime.first.c_str(), imeData->ime.second.c_str());
1893 return ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT;
1894 }
1895 RemoveImeData(ImeType::IME, true);
1896 return ErrorCode::NO_ERROR;
1897 }
1898
HandleFirstStart(const std::shared_ptr<ImeNativeCfg> & ime,bool isStopCurrentIme)1899 int32_t PerUserSession::HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme)
1900 {
1901 if (runningIme_.empty()) {
1902 return StartInputService(ime);
1903 }
1904 IMSA_HILOGW("imsa abnormal restore.");
1905 if (isStopCurrentIme) {
1906 return ErrorCode::NO_ERROR;
1907 }
1908 if (BlockRetry(CHECK_IME_RUNNING_RETRY_INTERVAL, CHECK_IME_RUNNING_RETRY_TIMES,
1909 [this]() -> bool { return !ImeInfoInquirer::GetInstance().IsRunningIme(userId_, runningIme_); })) {
1910 IMSA_HILOGI("[%{public}d, %{public}s] stop completely", userId_, runningIme_.c_str());
1911 runningIme_.clear();
1912 return StartInputService(ime);
1913 }
1914 IMSA_HILOGW("[%{public}d, %{public}s] stop timeout", userId_, runningIme_.c_str());
1915 return ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP;
1916 }
1917
RestoreCurrentIme()1918 int32_t PerUserSession::RestoreCurrentIme()
1919 {
1920 InputTypeManager::GetInstance().Set(false);
1921 auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1922 auto imeData = GetReadyImeData(ImeType::IME);
1923 if (imeData != nullptr && cfgIme != nullptr && imeData->ime.first == cfgIme->bundleName
1924 && imeData->ime.second == cfgIme->extName) {
1925 return ErrorCode::NO_ERROR;
1926 }
1927 IMSA_HILOGD("need restore!");
1928 auto ret = StartCurrentIme();
1929 if (ret != ErrorCode::NO_ERROR) {
1930 IMSA_HILOGE("start ime failed!");
1931 return ret; // ERROR_IME_START_FAILED
1932 }
1933 return ErrorCode::NO_ERROR;
1934 }
1935
CheckPwdInputPatternConv(InputClientInfo & newClientInfo)1936 bool PerUserSession::CheckPwdInputPatternConv(InputClientInfo &newClientInfo)
1937 {
1938 auto exClient = GetCurrentClient();
1939 if (exClient == nullptr) {
1940 exClient = GetInactiveClient();
1941 }
1942 auto exClientInfo = exClient != nullptr ? GetClientInfo(exClient->AsObject()) : nullptr;
1943 if (exClientInfo == nullptr) {
1944 IMSA_HILOGE("exClientInfo is nullptr!");
1945 return false;
1946 }
1947 // if current input pattern differ from previous in pwd and normal, need hide panel first.
1948 if (newClientInfo.config.inputAttribute.GetSecurityFlag()) {
1949 IMSA_HILOGI("new input pattern is pwd.");
1950 return !exClientInfo->config.inputAttribute.GetSecurityFlag();
1951 }
1952 IMSA_HILOGI("new input pattern is normal.");
1953 return exClientInfo->config.inputAttribute.GetSecurityFlag();
1954 }
1955
GetImeNativeCfg(int32_t userId,const std::string & bundleName,const std::string & subName)1956 std::shared_ptr<ImeNativeCfg> PerUserSession::GetImeNativeCfg(int32_t userId, const std::string &bundleName,
1957 const std::string &subName)
1958 {
1959 auto targetImeProperty = ImeInfoInquirer::GetInstance().GetImeProperty(userId, bundleName);
1960 if (targetImeProperty == nullptr) {
1961 IMSA_HILOGE("GetImeProperty [%{public}d, %{public}s] failed!", userId, bundleName.c_str());
1962 return nullptr;
1963 }
1964 std::string targetName = bundleName + "/" + targetImeProperty->id;
1965 ImeNativeCfg targetIme = { targetName, bundleName, subName, targetImeProperty->id };
1966 return std::make_shared<ImeNativeCfg>(targetIme);
1967 }
1968
GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> & imeToStart)1969 bool PerUserSession::GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> &imeToStart)
1970 {
1971 if (!InputTypeManager::GetInstance().IsStarted()) {
1972 return false;
1973 }
1974 auto currentInputTypeIme = InputTypeManager::GetInstance().GetCurrentIme();
1975 if (currentInputTypeIme.bundleName.empty()) {
1976 auto currentInputType = InputTypeManager::GetInstance().GetCurrentInputType();
1977 InputTypeManager::GetInstance().GetImeByInputType(currentInputType, currentInputTypeIme);
1978 }
1979 imeToStart = GetImeNativeCfg(userId_, currentInputTypeIme.bundleName, currentInputTypeIme.subName);
1980 return true;
1981 }
1982
HandleImeBindTypeChanged(InputClientInfo & newClientInfo)1983 void PerUserSession::HandleImeBindTypeChanged(InputClientInfo &newClientInfo)
1984 {
1985 /* isClientInactive: true: represent the oldClientInfo is inactiveClient's
1986 false: represent the oldClientInfo is currentClient's */
1987 std::shared_ptr<InputClientInfo> oldClientInfo = nullptr;
1988 bool isClientInactive = false;
1989 {
1990 std::lock_guard<std::mutex> lock(focusedClientLock_);
1991 auto currentClient = GetCurrentClient();
1992 oldClientInfo = currentClient != nullptr ? GetClientInfo(currentClient->AsObject()) : nullptr;
1993 if (oldClientInfo == nullptr) {
1994 auto inactiveClient = GetInactiveClient();
1995 oldClientInfo = inactiveClient != nullptr ? GetClientInfo(inactiveClient->AsObject()) : nullptr;
1996 isClientInactive = true;
1997 }
1998 if (oldClientInfo == nullptr) {
1999 return;
2000 }
2001 if (!IsImeBindTypeChanged(oldClientInfo->bindImeType)) {
2002 return;
2003 }
2004 // has current client, but new client is not current client
2005 if (!isClientInactive && !IsSameClient(newClientInfo.client, oldClientInfo->client)) {
2006 SetCurrentClient(nullptr);
2007 if (oldClientInfo->client != nullptr) {
2008 RemoveClientInfo(oldClientInfo->client->AsObject());
2009 }
2010 }
2011 }
2012 IMSA_HILOGD("isClientInactive: %{public}d!", isClientInactive);
2013 if (IsSameClient(newClientInfo.client, oldClientInfo->client)) {
2014 newClientInfo.isNotifyInputStart = true;
2015 }
2016 if (isClientInactive) {
2017 StopImeInput(oldClientInfo->bindImeType, oldClientInfo->channel);
2018 return;
2019 }
2020 UnBindClientWithIme(oldClientInfo);
2021 }
2022
TryUnloadSystemAbility()2023 void PerUserSession::TryUnloadSystemAbility()
2024 {
2025 auto data = GetReadyImeData(ImeType::IME);
2026 if (data != nullptr && data->freezeMgr != nullptr) {
2027 if (data->freezeMgr->IsImeInUse()) {
2028 return;
2029 }
2030 }
2031
2032 auto onDemandStartStopSa = std::make_shared<OnDemandStartStopSa>();
2033 onDemandStartStopSa->UnloadInputMethodSystemAbility();
2034 }
2035
OnCallingDisplayIdChanged(const int32_t windowId,const int32_t callingPid,const uint64_t displayId)2036 void PerUserSession::OnCallingDisplayIdChanged(
2037 const int32_t windowId, const int32_t callingPid, const uint64_t displayId)
2038 {
2039 IMSA_HILOGD("enter!windowId:%{public}d,callingPid:%{public}d,displayId:%{public}" PRIu64 "", windowId,
2040 callingPid, displayId);
2041 auto client = GetCurrentClient();
2042 auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
2043 if (clientInfo == nullptr) {
2044 IMSA_HILOGD("clientInfo is null");
2045 return;
2046 }
2047 IMSA_HILOGD("userId:%{public}d, windowId:%{public}d", userId_, clientInfo->config.windowId);
2048 if (clientInfo->config.windowId != static_cast<uint32_t>(windowId)) {
2049 return;
2050 }
2051 uint64_t curDisplay = clientInfo->config.inputAttribute.callingDisplayId;
2052 if (curDisplay == displayId) {
2053 return;
2054 }
2055 clientInfo->config.inputAttribute.callingDisplayId = displayId;
2056 NotifyCallingDisplayChanged(displayId);
2057 }
2058
NotifyCallingDisplayChanged(uint64_t displayId)2059 int32_t PerUserSession::NotifyCallingDisplayChanged(uint64_t displayId)
2060 {
2061 IMSA_HILOGD("enter displayId:%{public}" PRIu64 "", displayId);
2062 auto data = GetValidIme(ImeType::IME);
2063 if (data == nullptr) {
2064 IMSA_HILOGE("ime is nullptr!");
2065 return ErrorCode::ERROR_IME_NOT_STARTED;
2066 }
2067 auto callBack = [&data, displayId]() -> int32_t {
2068 data->core->OnCallingDisplayIdChanged(displayId);
2069 return ErrorCode::NO_ERROR;
2070 };
2071 auto ret = RequestIme(data, RequestType::NORMAL, callBack);
2072 if (ret != ErrorCode::NO_ERROR) {
2073 IMSA_HILOGE("notify calling window display changed failed, ret: %{public}d!", ret);
2074 }
2075 return ret;
2076 }
2077
GetCallingWindowInfo(const InputClientInfo & clientInfo)2078 ImfCallingWindowInfo PerUserSession::GetCallingWindowInfo(const InputClientInfo &clientInfo)
2079 {
2080 ImfCallingWindowInfo finalWindowInfo{ clientInfo.config.windowId, 0 };
2081 if (!SceneBoardJudgement::IsSceneBoardEnabled()) {
2082 return finalWindowInfo;
2083 }
2084 CallingWindowInfo callingWindowInfo;
2085 if (GetCallingWindowInfo(clientInfo, callingWindowInfo)) {
2086 finalWindowInfo.displayId = callingWindowInfo.displayId_;
2087 return finalWindowInfo;
2088 }
2089 FocusChangeInfo focusInfo;
2090 WindowAdapter::GetFocusInfo(focusInfo);
2091 if (!WindowAdapter::GetCallingWindowInfo(focusInfo.windowId_, userId_, callingWindowInfo)) {
2092 IMSA_HILOGE("GetCallingWindowInfo error!");
2093 return finalWindowInfo;
2094 }
2095 // The value set from the IMC is used and does not need to be modified on the service side
2096 return { clientInfo.config.windowId, callingWindowInfo.displayId_ };
2097 }
2098
GetCallingWindowInfo(const InputClientInfo & clientInfo,CallingWindowInfo & callingWindowInfo)2099 bool PerUserSession::GetCallingWindowInfo(const InputClientInfo &clientInfo, CallingWindowInfo &callingWindowInfo)
2100 {
2101 auto windowId = clientInfo.config.windowId;
2102 if (windowId == INVALID_WINDOW_ID) {
2103 return false;
2104 }
2105 if (!WindowAdapter::GetCallingWindowInfo(windowId, userId_, callingWindowInfo)) {
2106 return false;
2107 }
2108 return !(callingWindowInfo.callingPid_ != clientInfo.pid && clientInfo.uiExtensionTokenId == IMF_INVALID_TOKENID);
2109 }
2110 } // namespace MiscServices
2111 } // namespace OHOS