• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #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> &currentClient)
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> &currentClient, 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> &currentClientInfo, 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> &currentChannel)
657 {
658     auto data = GetReadyImeData(currentType);
659     if (data == nullptr) {
660         return;
661     }
662     auto ret = RequestIme(data, RequestType::STOP_INPUT,
663         [&data, &currentChannel]() { 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