• 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 "unordered_map"
17 #include "variant"
18 #include "peruser_session.h"
19 
20 #include <cinttypes>
21 #include <algorithm>
22 
23 #include "ability_manager_client.h"
24 #include "full_ime_info_manager.h"
25 #include "identity_checker_impl.h"
26 #include "im_common_event_manager.h"
27 #include "ime_enabled_info_manager.h"
28 #include "ime_info_inquirer.h"
29 #include "input_control_channel_service_impl.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "mem_mgr_client.h"
33 #include "numkey_apps_manager.h"
34 #include "on_demand_start_stop_sa.h"
35 #include "os_account_adapter.h"
36 #include "scene_board_judgement.h"
37 #include "system_ability_definition.h"
38 #include "system_param_adapter.h"
39 #include "wms_connection_observer.h"
40 #ifdef IMF_SCREENLOCK_MGR_ENABLE
41 #include "screenlock_manager.h"
42 #endif
43 #include "window_adapter.h"
44 #include "variant_util.h"
45 #include "input_method_tools.h"
46 #include "ime_state_manager_factory.h"
47 #include "inputmethod_trace.h"
48 #include "notify_service_impl.h"
49 
50 
51 namespace OHOS {
52 namespace MiscServices {
53 using namespace std::chrono;
54 using namespace MessageID;
55 using namespace OHOS::AppExecFwk;
56 using namespace OHOS::Rosen;
57 constexpr uint32_t STOP_IME_TIME = 600;
58 constexpr const char *STRICT_MODE = "strictMode";
59 constexpr const char *ISOLATED_SANDBOX = "isolatedSandbox";
60 constexpr uint32_t CHECK_IME_RUNNING_RETRY_INTERVAL = 60;
61 constexpr uint32_t CHECK_IME_RUNNING_RETRY_TIMES = 10;
62 constexpr int32_t MAX_RESTART_NUM = 3;
63 constexpr int32_t IME_RESET_TIME_OUT = 3;
64 constexpr int32_t MAX_RESTART_TASKS = 2;
65 constexpr uint32_t MAX_ATTACH_COUNT = 100000;
66 constexpr const char *UNDEFINED = "undefined";
67 constexpr int32_t WAIT_ATTACH_FINISH_DELAY = 50;
68 constexpr int32_t WAIT_ATTACH_FINISH_MAX_TIMES = 20;
69 constexpr uint32_t MAX_SCB_START_COUNT = 2;
70 constexpr uint32_t PROXY_REGISTERATION_TIME_INTERVAL = 1; // 1s
71 constexpr uint32_t MAX_REGISTRATIONS_NUM = 3;
PerUserSession(int userId)72 PerUserSession::PerUserSession(int userId) : userId_(userId) { }
73 
PerUserSession(int32_t userId,const std::shared_ptr<AppExecFwk::EventHandler> & eventHandler)74 PerUserSession::PerUserSession(int32_t userId, const std::shared_ptr<AppExecFwk::EventHandler> &eventHandler)
75     : userId_(userId), eventHandler_(eventHandler)
76 {
77     // if bms not start, AppMgrClient::GetProcessRunningInfosByUserId will blocked
78     if (IsSaReady(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID)) {
79         auto bundleNames = ImeInfoInquirer::GetInstance().GetRunningIme(userId_);
80         if (!bundleNames.empty()) {
81             runningIme_ = bundleNames[0]; // one user only has one ime at present
82         }
83     }
84 }
85 
~PerUserSession()86 PerUserSession::~PerUserSession() { }
87 
AddClientInfo(sptr<IRemoteObject> inputClient,const InputClientInfo & clientInfo,ClientAddEvent event)88 int PerUserSession::AddClientInfo(sptr<IRemoteObject> inputClient, const InputClientInfo &clientInfo,
89     ClientAddEvent event)
90 {
91     IMSA_HILOGD("PerUserSession start.");
92     auto clientGroup = GetClientGroup(clientInfo.displayId);
93     if (clientGroup != nullptr) {
94         return clientGroup->AddClientInfo(inputClient, clientInfo, event);
95     }
96     clientGroup = std::make_shared<ClientGroup>(
97         clientInfo.displayId, [this](const sptr<IInputClient> &remote) { this->OnClientDied(remote); });
98     auto ret = clientGroup->AddClientInfo(inputClient, clientInfo, event);
99     if (ret != ErrorCode::NO_ERROR) {
100         IMSA_HILOGE("failed to AddClientInfo: %{public}d", ret);
101         return ret;
102     }
103     uint64_t displayGroupId = GetDisplayGroupId(clientInfo.displayId);
104     std::lock_guard<std::mutex> lock(clientGroupLock_);
105     clientGroupMap_.insert(std::make_pair(displayGroupId, clientGroup));
106     IMSA_HILOGI("add client group: %{public}" PRIu64 " end.", displayGroupId);
107     return ErrorCode::NO_ERROR;
108 }
109 
HideKeyboard(const sptr<IInputClient> & currentClient,const std::shared_ptr<ClientGroup> & clientGroup)110 int32_t PerUserSession::HideKeyboard(
111     const sptr<IInputClient> &currentClient, const std::shared_ptr<ClientGroup> &clientGroup)
112 {
113     IMSA_HILOGD("PerUserSession::HideKeyboard start.");
114     if (currentClient == nullptr) {
115         IMSA_HILOGE("current client is nullptr!");
116         return ErrorCode::ERROR_NULL_POINTER;
117     }
118     auto clientInfo = clientGroup->GetClientInfo(currentClient->AsObject());
119     if (clientInfo == nullptr) {
120         IMSA_HILOGE("client info is nullptr!");
121         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
122     }
123     auto data = GetReadyImeData(clientInfo->bindImeType);
124     if (data == nullptr) {
125         IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType);
126         return ErrorCode::ERROR_IME_NOT_STARTED;
127     }
128     auto ret = RequestIme(data, RequestType::NORMAL, [&data] {
129         return data->core->HideKeyboard();
130     });
131     if (ret != ErrorCode::NO_ERROR) {
132         IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret);
133         return ErrorCode::ERROR_KBD_HIDE_FAILED;
134     }
135     bool isShowKeyboard = false;
136     clientGroup->UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } });
137     RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId());
138     return ErrorCode::NO_ERROR;
139 }
140 
ShowKeyboard(const sptr<IInputClient> & currentClient,const std::shared_ptr<ClientGroup> & clientGroup,int32_t requestKeyboardReason)141 int32_t PerUserSession::ShowKeyboard(const sptr<IInputClient> &currentClient,
142     const std::shared_ptr<ClientGroup> &clientGroup, int32_t requestKeyboardReason)
143 {
144     if (currentClient == nullptr || clientGroup == nullptr) {
145         IMSA_HILOGE("client is nullptr");
146         return ErrorCode::ERROR_IMSA_NULLPTR;
147     }
148     auto clientInfo = clientGroup->GetClientInfo(currentClient->AsObject());
149     if (clientInfo == nullptr) {
150         IMSA_HILOGE("client info is nullptr!");
151         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
152     }
153     auto data = GetReadyImeData(clientInfo->bindImeType);
154     if (data == nullptr) {
155         IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType);
156         return ErrorCode::ERROR_IME_NOT_STARTED;
157     }
158     auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data, requestKeyboardReason] {
159         return data->core->ShowKeyboard(requestKeyboardReason);
160     });
161     if (ret != ErrorCode::NO_ERROR) {
162         IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret);
163         return ErrorCode::ERROR_KBD_SHOW_FAILED;
164     }
165     bool isShowKeyboard = true;
166     clientGroup->UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } });
167     clientGroup->NotifyInputStartToClients(clientInfo->config.windowId, requestKeyboardReason);
168     return ErrorCode::NO_ERROR;
169 }
170 
171 /** Handle the situation a remote input client died.
172  * It's called when a remote input client died
173  * @param the remote object handler of the input client died.
174  */
OnClientDied(sptr<IInputClient> remote)175 void PerUserSession::OnClientDied(sptr<IInputClient> remote)
176 {
177     if (remote == nullptr) {
178         return;
179     }
180     auto clientGroup = GetClientGroup(remote->AsObject());
181     if (clientGroup == nullptr) {
182         return;
183     }
184     if (clientGroup->IsNotifyInputStop(remote)) {
185         clientGroup->NotifyInputStopToClients();
186     }
187     auto clientInfo = clientGroup->GetClientInfo(remote->AsObject());
188     IMSA_HILOGI("userId: %{public}d.", userId_);
189     if (IsSameClient(remote, clientGroup->GetCurrentClient())) {
190         if (clientInfo != nullptr) {
191             StopImeInput(clientInfo->bindImeType, clientInfo->channel, 0);
192         }
193         clientGroup->SetCurrentClient(nullptr);
194         RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId());
195     }
196     if (IsSameClient(remote, clientGroup->GetInactiveClient())) {
197         if (clientInfo != nullptr) {
198             StopImeInput(clientInfo->bindImeType, clientInfo->channel, 0);
199         }
200         clientGroup->SetInactiveClient(nullptr);
201         RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId());
202     }
203     clientGroup->RemoveClientInfo(remote->AsObject(), true);
204 }
205 
206 /** Handle the situation that an ime died
207  * It's called when an ime died
208  * @param the remote object handler of the ime who died.
209  */
OnImeDied(const sptr<IInputMethodCore> & remote,ImeType type,pid_t pid)210 void PerUserSession::OnImeDied(const sptr<IInputMethodCore> &remote, ImeType type, pid_t pid)
211 {
212     if (remote == nullptr) {
213         return;
214     }
215     IMSA_HILOGI("type: %{public}d.", type);
216     auto imeData = GetImeData(pid);
217     if (imeData != nullptr && imeData->imeStatus == ImeStatus::EXITING) {
218         RemoveImeData(pid);
219         InputTypeManager::GetInstance().Set(false);
220         NotifyImeStopFinished();
221         IMSA_HILOGI("%{public}d not current imeData.", type);
222         return;
223     }
224     RemoveImeData(pid);
225     if (!OsAccountAdapter::IsOsAccountForeground(userId_)) {
226         IMSA_HILOGW("userId:%{public}d in background, no need to restart ime.", userId_);
227         return;
228     }
229     auto clientGroup = GetClientGroup(type);
230     auto clientInfo = clientGroup != nullptr ? clientGroup->GetCurrentClientInfo() : nullptr;
231     if (clientInfo != nullptr && clientInfo->bindImeType == type && clientInfo->bindImePid == pid) {
232         clientGroup->NotifyInputStopToClients();
233         StopClientInput(clientInfo);
234         if (type == ImeType::IME) {
235             StartImeInImeDied();
236         }
237         return;
238     }
239     auto currentImeInfo = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
240     if (currentImeInfo == nullptr) {
241         IMSA_HILOGE("currentImeInfo is nullptr!");
242         return;
243     }
244     auto defaultImeInfo = ImeInfoInquirer::GetInstance().GetDefaultImeCfgProp();
245     if (defaultImeInfo == nullptr) {
246         IMSA_HILOGE("defaultImeInfo is nullptr!");
247         return;
248     }
249     if (type == ImeType::IME && currentImeInfo->bundleName == defaultImeInfo->name) {
250         if (!SystemParamAdapter::GetInstance().GetBoolParam(SystemParamAdapter::MEMORY_WATERMARK_KEY)) {
251             StartImeInImeDied();
252         } else {
253             isBlockStartedByLowMem_.store(true);
254         }
255     }
256 }
257 
RemoveIme(ImeType type,pid_t pid)258 int32_t PerUserSession::RemoveIme(ImeType type, pid_t pid)
259 {
260     auto clientGroup = GetClientGroup(type);
261     auto clientInfo = clientGroup != nullptr ? clientGroup->GetCurrentClientInfo() : nullptr;
262     if (clientInfo != nullptr && clientInfo->bindImeType == type && clientInfo->bindImePid == pid) {
263         UnBindClientWithIme(clientInfo, { .sessionId = 0 });
264     }
265     RemoveImeData(pid);
266     return ErrorCode::NO_ERROR;
267 }
268 
OnHideCurrentInput(uint64_t displayId)269 int32_t PerUserSession::OnHideCurrentInput(uint64_t displayId)
270 {
271     auto clientGroup = GetClientGroup(displayId);
272     if (clientGroup == nullptr) {
273         IMSA_HILOGE("client group not found");
274         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
275     }
276     sptr<IInputClient> client = clientGroup->GetCurrentClient();
277     if (client == nullptr) {
278         IMSA_HILOGE("current client is nullptr!");
279         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
280     }
281     return HideKeyboard(client, clientGroup);
282 }
283 
OnShowCurrentInput(uint64_t displayId)284 int32_t PerUserSession::OnShowCurrentInput(uint64_t displayId)
285 {
286     IMSA_HILOGD("PerUserSession::OnShowCurrentInput start.");
287     auto clientGroup = GetClientGroup(displayId);
288     if (clientGroup == nullptr) {
289         IMSA_HILOGE("client group not found");
290         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
291     }
292     sptr<IInputClient> client = clientGroup->GetCurrentClient();
293     if (client == nullptr) {
294         IMSA_HILOGE("current client is nullptr!");
295         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
296     }
297     return ShowKeyboard(client, clientGroup);
298 }
299 
OnHideInput(sptr<IInputClient> client)300 int32_t PerUserSession::OnHideInput(sptr<IInputClient> client)
301 {
302     IMSA_HILOGD("PerUserSession::OnHideInput start.");
303     if (client == nullptr) {
304         IMSA_HILOGE("client is nullptr");
305         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
306     }
307     auto clientGroup = GetClientGroup(client->AsObject());
308     if (clientGroup == nullptr) {
309         IMSA_HILOGE("client group not found");
310         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
311     }
312     if (!IsSameClient(client, clientGroup->GetCurrentClient())) {
313         IMSA_HILOGE("client is not current client!");
314         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
315     }
316     return HideKeyboard(client, clientGroup);
317 }
318 
OnShowInput(sptr<IInputClient> client,int32_t requestKeyboardReason)319 int32_t PerUserSession::OnShowInput(sptr<IInputClient> client, int32_t requestKeyboardReason)
320 {
321     IMSA_HILOGD("PerUserSession::OnShowInput start.");
322     if (client == nullptr) {
323         IMSA_HILOGE("client is nullptr");
324         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
325     }
326     auto clientGroup = GetClientGroup(client->AsObject());
327     if (clientGroup == nullptr) {
328         IMSA_HILOGE("client group not found");
329         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
330     }
331     if (!IsSameClient(client, clientGroup->GetCurrentClient())) {
332         IMSA_HILOGE("client is not current client!");
333         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
334     }
335     return ShowKeyboard(client, clientGroup, requestKeyboardReason);
336 }
337 
OnHideSoftKeyBoardSelf()338 void PerUserSession::OnHideSoftKeyBoardSelf()
339 {
340     IMSA_HILOGD("PerUserSession::OnHideSoftKeyBoardSel start.");
341     auto clientGroup = GetClientGroup(DEFAULT_DISPLAY_ID);
342     if (clientGroup == nullptr) {
343         IMSA_HILOGE("current client is nullptr!");
344         return;
345     }
346     sptr<IInputClient> client = clientGroup->GetCurrentClient();
347     if (client == nullptr) {
348         IMSA_HILOGE("current client is nullptr!");
349         return;
350     }
351     clientGroup->UpdateClientInfo(client->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } });
352     RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID);
353 }
354 
OnRequestShowInput(uint64_t displayId)355 int32_t PerUserSession::OnRequestShowInput(uint64_t displayId)
356 {
357     IMSA_HILOGD("PerUserSession::OnRequestShowInput start.");
358     auto clientGroup = GetClientGroup(displayId);
359     if (clientGroup == nullptr) {
360         IMSA_HILOGE("no current client");
361         return ErrorCode::ERROR_IME_NOT_STARTED;
362     }
363     ImeType type = GetImeType(displayId);
364     auto data = GetReadyImeData(type);
365     if (data == nullptr) {
366         IMSA_HILOGE("ime: %{public}d doesn't exist!", type);
367         return ErrorCode::ERROR_IME_NOT_STARTED;
368     }
369     auto ret = RequestIme(data, RequestType::REQUEST_SHOW, [&data] {
370         return data->core->ShowKeyboard(static_cast<int32_t>(RequestKeyboardReason::NONE));
371     });
372     if (ret != ErrorCode::NO_ERROR) {
373         IMSA_HILOGE("failed to show keyboard, ret: %{public}d!", ret);
374         return ErrorCode::ERROR_KBD_SHOW_FAILED;
375     }
376     InputMethodSysEvent::GetInstance().ReportImeState(
377         ImeState::BIND, data->pid, ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
378     Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID);
379     auto currentClient = clientGroup->GetCurrentClient();
380     if (currentClient != nullptr) {
381         clientGroup->UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, true } });
382     }
383     return ErrorCode::NO_ERROR;
384 }
385 
OnRequestHideInput(int32_t callingPid,uint64_t displayId)386 int32_t PerUserSession::OnRequestHideInput(int32_t callingPid, uint64_t displayId)
387 {
388     IMSA_HILOGD("PerUserSession::OnRequestHideInput start.");
389     auto data = GetReadyImeData(GetImeType(displayId));
390     if (data != nullptr) {
391         auto ret = RequestIme(data, RequestType::REQUEST_HIDE, [&data] {
392             return data->core->HideKeyboard();
393         });
394         if (ret != ErrorCode::NO_ERROR) {
395             IMSA_HILOGE("failed to hide keyboard, ret: %{public}d!", ret);
396             return ErrorCode::ERROR_KBD_HIDE_FAILED;
397         }
398     }
399 
400     auto clientGroup = GetClientGroup(displayId);
401     if (clientGroup == nullptr) {
402         RestoreCurrentImeSubType(displayId);
403         return ErrorCode::NO_ERROR;
404     }
405     auto currentClient = clientGroup->GetCurrentClient();
406     auto currentClientInfo = clientGroup->GetCurrentClientInfo();
407     if (currentClient != nullptr && currentClientInfo != nullptr) {
408         clientGroup->UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } });
409     }
410     auto inactiveClient = clientGroup->GetInactiveClient();
411     if (inactiveClient != nullptr) {
412         DetachOptions options = { .sessionId = 0, .isUnbindFromClient = false, .isInactiveClient = true };
413         RemoveClient(inactiveClient, clientGroup, options);
414     }
415     RestoreCurrentImeSubType(displayId);
416     clientGroup->NotifyInputStopToClients();
417     return ErrorCode::NO_ERROR;
418 }
419 
OnPrepareInput(const InputClientInfo & clientInfo)420 int32_t PerUserSession::OnPrepareInput(const InputClientInfo &clientInfo)
421 {
422     IMSA_HILOGD("PerUserSession::OnPrepareInput start");
423     if (clientInfo.client == nullptr) {
424         IMSA_HILOGE("client is nullptr");
425         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
426     }
427     return AddClientInfo(clientInfo.client->AsObject(), clientInfo, PREPARE_INPUT);
428 }
429 
430 /** Release input. Called by an input client.Run in work thread of this user
431  * @param the parameters from remote client
432  * @return ErrorCode
433  */
OnReleaseInput(const sptr<IInputClient> & client,uint32_t sessionId)434 int32_t PerUserSession::OnReleaseInput(const sptr<IInputClient> &client, uint32_t sessionId)
435 {
436     IMSA_HILOGD("PerUserSession::OnReleaseInput start");
437     if (client == nullptr) {
438         IMSA_HILOGE("client nullptr");
439         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
440     }
441     auto clientGroup = GetClientGroup(client->AsObject());
442     if (clientGroup == nullptr) {
443         IMSA_HILOGD("client not found");
444         return ErrorCode::NO_ERROR;
445     }
446     bool isReady = clientGroup->IsNotifyInputStop(client);
447     DetachOptions options = { .sessionId = sessionId, .isUnbindFromClient = true };
448     int32_t ret = RemoveClient(client, clientGroup, options);
449     if (ret != ErrorCode::NO_ERROR) {
450         IMSA_HILOGE("remove client failed");
451         return ret;
452     }
453     if (isReady) {
454         clientGroup->NotifyInputStopToClients();
455     }
456     return ErrorCode::NO_ERROR;
457 }
458 
RemoveClient(const sptr<IInputClient> & client,const std::shared_ptr<ClientGroup> & clientGroup,const DetachOptions & options)459 int32_t PerUserSession::RemoveClient(
460     const sptr<IInputClient> &client, const std::shared_ptr<ClientGroup> &clientGroup, const DetachOptions &options)
461 {
462     if (client == nullptr || clientGroup == nullptr) {
463         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
464     }
465     // if client is current client, unbind firstly
466     auto clientInfo = clientGroup->GetClientInfo(client->AsObject());
467     if (IsSameClient(client, clientGroup->GetCurrentClient())) {
468         UnBindClientWithIme(clientInfo, options);
469         clientGroup->SetCurrentClient(nullptr);
470         RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId());
471         StopClientInput(clientInfo, false, options.isNotifyClientAsync);
472     }
473     if (IsSameClient(client, clientGroup->GetInactiveClient())) {
474         clientGroup->SetInactiveClient(nullptr);
475         StopClientInput(clientInfo, options.isInactiveClient);
476     }
477     clientGroup->RemoveClientInfo(client->AsObject());
478     return ErrorCode::NO_ERROR;
479 }
480 
DeactivateClient(const sptr<IInputClient> & client)481 void PerUserSession::DeactivateClient(const sptr<IInputClient> &client)
482 {
483     if (client == nullptr) {
484         IMSA_HILOGD("client is nullptr.");
485         return;
486     }
487     auto clientGroup = GetClientGroup(client->AsObject());
488     if (clientGroup == nullptr) {
489         IMSA_HILOGD("client group not found");
490         return;
491     }
492     auto clientInfo = clientGroup->GetClientInfo(client->AsObject());
493     if (clientInfo == nullptr) {
494         return;
495     }
496     IMSA_HILOGI("deactivate client[%{public}d].", clientInfo->pid);
497     clientGroup->UpdateClientInfo(client->AsObject(), { { UpdateFlag::STATE, ClientState::INACTIVE } });
498     if (IsSameClient(client, clientGroup->GetCurrentClient())) {
499         clientGroup->SetCurrentClient(nullptr);
500     }
501     clientGroup->SetInactiveClient(client);
502     client->DeactivateClient();
503     auto data = GetReadyImeData(clientInfo->bindImeType);
504     if (data == nullptr) {
505         IMSA_HILOGE("ime %{public}d doesn't exist!", clientInfo->bindImeType);
506         return;
507     }
508     RequestAllIme(data, RequestType::NORMAL, [&clientInfo](const sptr<IInputMethodCore> &core) {
509         core->OnClientInactive(clientInfo->channel);
510         return ErrorCode::NO_ERROR;
511     });
512     InputMethodSysEvent::GetInstance().ReportImeState(
513         ImeState::UNBIND, data->pid, ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
514     Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID);
515 }
516 
IsProxyImeEnable()517 bool PerUserSession::IsProxyImeEnable()
518 {
519     auto data = GetReadyImeData(ImeType::PROXY_IME);
520     return IsEnable(data);
521 }
522 
FillBindImeInfo(ImeType imeType,std::vector<sptr<IRemoteObject>> & agents,std::vector<BindImeInfo> & imeInfos)523 int32_t PerUserSession::FillBindImeInfo(ImeType imeType, std::vector<sptr<IRemoteObject>> &agents,
524     std::vector<BindImeInfo> &imeInfos)
525 {
526     auto allData = GetAllReadyImeData(imeType);
527     if (allData.empty()) {
528         IMSA_HILOGE("allData is empty!");
529         return ErrorCode::ERROR_IME_NOT_STARTED;
530     }
531 
532     for (auto &data : allData) {
533         if (data->agent == nullptr) {
534             IMSA_HILOGE("agent is nullptr!");
535             return ErrorCode::ERROR_IME_NOT_STARTED;
536         }
537         agents.emplace_back(data->agent);
538         BindImeInfo imeInfo = { data->pid, data->ime.first };
539         imeInfos.emplace_back(imeInfo);
540     }
541 
542     return ErrorCode::NO_ERROR;
543 }
544 
OnStartInput(const InputClientInfo & inputClientInfo,std::vector<sptr<IRemoteObject>> & agents,std::vector<BindImeInfo> & imeInfos)545 int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, std::vector<sptr<IRemoteObject>> &agents,
546     std::vector<BindImeInfo> &imeInfos)
547 {
548     const sptr<IInputClient> &client = inputClientInfo.client;
549     if (client == nullptr) {
550         IMSA_HILOGE("client is nullptr!");
551         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
552     }
553     auto clientGroup = GetClientGroup(inputClientInfo.displayId);
554     if (clientGroup == nullptr) {
555         IMSA_HILOGE("client group not found");
556         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
557     }
558     auto clientInfo = clientGroup->GetClientInfo(client->AsObject());
559     if (clientInfo == nullptr) {
560         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
561     }
562     IMSA_HILOGD("start input with keyboard[%{public}d].", inputClientInfo.isShowKeyboard);
563     InputClientInfo infoTemp = *clientInfo;
564     infoTemp.isNotifyInputStart = inputClientInfo.isNotifyInputStart;
565     ImeType imeType = GetImeType(inputClientInfo.displayId);
566     if (GetDisplayGroupId(inputClientInfo.displayId) == DEFAULT_DISPLAY_ID) {
567         imeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME;
568     }
569     auto data = GetReadyImeData(imeType);
570     if (data == nullptr || data->agent == nullptr) {
571         IMSA_HILOGE("data or agent is nullptr!");
572         return ErrorCode::ERROR_IME_NOT_STARTED;
573     }
574     infoTemp.bindImePid = data->pid;
575     infoTemp.bindImeType = imeType;
576     HandleBindImeChanged(infoTemp, clientGroup);
577     infoTemp.isShowKeyboard = inputClientInfo.isShowKeyboard;
578     infoTemp.needHide = inputClientInfo.needHide;
579     infoTemp.requestKeyboardReason = inputClientInfo.requestKeyboardReason;
580     infoTemp.config.requestKeyboardReason = inputClientInfo.requestKeyboardReason;
581     int32_t ret =
582         BindClientWithIme(std::make_shared<InputClientInfo>(infoTemp), imeType, true, inputClientInfo.displayId);
583     if (ret != ErrorCode::NO_ERROR) {
584         IMSA_HILOGE("bind failed, ret: %{public}d!", ret);
585         return ret;
586     }
587 
588     return FillBindImeInfo(imeType, agents, imeInfos);
589 }
590 
SendAllReadyImeToClient(std::shared_ptr<ImeData> data,const std::shared_ptr<InputClientInfo> & clientInfo)591 int32_t PerUserSession::SendAllReadyImeToClient(
592     std::shared_ptr<ImeData> data, const std::shared_ptr<InputClientInfo> &clientInfo)
593 {
594     if (data == nullptr) {
595         IMSA_HILOGW("no need to send");
596         return ErrorCode::NO_ERROR;
597     }
598 
599     std::vector<std::shared_ptr<ImeData>> imeDatas = { data };
600     if (!data->IsImeMirror()) {
601         auto imeMirrorData = GetReadyImeData(ImeType::IME_MIRROR);
602         if (imeMirrorData != nullptr) {
603             imeDatas.push_back(imeMirrorData);
604         }
605     }
606 
607     int32_t finalResult = ErrorCode::NO_ERROR;
608     int32_t ret;
609     for (const auto &dataItem : imeDatas) {
610         BindImeInfo imeInfo;
611         imeInfo.pid = dataItem->pid;
612         imeInfo.bundleName = dataItem->ime.first;
613         ret = clientInfo->client->OnInputReady(dataItem->agent, imeInfo);
614         if (ret != ErrorCode::NO_ERROR) {
615             IMSA_HILOGE("OnInputReady failed, ret = %{public}d", ret);
616         }
617         if (!dataItem->IsImeMirror()) {
618             finalResult = ret;
619         }
620     }
621     return finalResult;
622 }
623 
BindClientWithIme(const std::shared_ptr<InputClientInfo> & clientInfo,ImeType type,bool isBindFromClient,uint64_t displayId)624 int32_t PerUserSession::BindClientWithIme(
625     const std::shared_ptr<InputClientInfo> &clientInfo, ImeType type, bool isBindFromClient, uint64_t displayId)
626 {
627     if (clientInfo == nullptr) {
628         IMSA_HILOGE("clientInfo is nullptr!");
629         return ErrorCode::ERROR_IMSA_NULLPTR;
630     }
631     auto clientGroup = GetClientGroup(displayId);
632     if (clientGroup == nullptr) {
633         IMSA_HILOGE("not found group");
634         return ErrorCode::ERROR_IMSA_NULLPTR;
635     }
636     IMSA_HILOGD("imeType: %{public}d, isShowKeyboard: %{public}d, isBindFromClient: %{public}d.", type,
637         clientInfo->isShowKeyboard, isBindFromClient);
638     auto data = GetReadyImeData(type);
639     if (data == nullptr) {
640         return ErrorCode::ERROR_IME_NOT_STARTED;
641     }
642 
643     if (!data->imeExtendInfo.privateCommand.empty()) {
644         auto ret = SendPrivateData(data->imeExtendInfo.privateCommand);
645         if (ret != ErrorCode::NO_ERROR) {
646             IMSA_HILOGE("before start input notify send private data failed, ret: %{public}d!", ret);
647             return ret;
648         }
649     }
650 
651     InputClientInfoInner inputClientInfoInner =
652         InputMethodTools::GetInstance().InputClientInfoToInner(*clientInfo);
653     auto ret = RequestAllIme(
654         data, RequestType::START_INPUT, [&inputClientInfoInner, isBindFromClient](const sptr<IInputMethodCore> &core) {
655             return core->StartInput(inputClientInfoInner, isBindFromClient);
656         });
657     if (ret != ErrorCode::NO_ERROR) {
658         IMSA_HILOGE("start input failed, ret: %{public}d!", ret);
659         return ErrorCode::ERROR_IME_START_INPUT_FAILED;
660     }
661     if (type == ImeType::IME) {
662         InputMethodSysEvent::GetInstance().ReportImeState(
663             ImeState::BIND, data->pid, ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
664         Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, INPUT_METHOD_SYSTEM_ABILITY_ID);
665     }
666     if (!isBindFromClient) {
667         ret = SendAllReadyImeToClient(data, clientInfo);
668         if (ret != ErrorCode::NO_ERROR) {
669             IMSA_HILOGE("start client input failed, ret: %{public}d!", ret);
670             return ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED;
671         }
672     }
673 
674     if (type == ImeType::IME_MIRROR) {
675         return ErrorCode::NO_ERROR;
676     }
677 
678     clientGroup->UpdateClientInfo(clientInfo->client->AsObject(), { { UpdateFlag::BINDIMETYPE, type },
679         { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard }, { UpdateFlag::STATE, ClientState::ACTIVE },
680         { UpdateFlag::BIND_IME_PID, data->pid} });
681     ReplaceCurrentClient(clientInfo->client, clientGroup);
682     if (clientInfo->isShowKeyboard) {
683         clientGroup->NotifyInputStartToClients(
684             clientInfo->config.windowId, static_cast<int32_t>(clientInfo->requestKeyboardReason));
685     }
686     return ErrorCode::NO_ERROR;
687 }
688 
UnBindClientWithIme(const std::shared_ptr<InputClientInfo> & currentClientInfo,const DetachOptions & options)689 void PerUserSession::UnBindClientWithIme(
690     const std::shared_ptr<InputClientInfo> &currentClientInfo, const DetachOptions &options)
691 {
692     if (currentClientInfo == nullptr) {
693         return;
694     }
695     if (!options.isUnbindFromClient) {
696         IMSA_HILOGD("unbind from service.");
697         StopClientInput(currentClientInfo, options.isNotifyClientAsync);
698     }
699     StopImeInput(currentClientInfo->bindImeType, currentClientInfo->channel, options.sessionId);
700 }
701 
StopClientInput(const std::shared_ptr<InputClientInfo> & clientInfo,bool isStopInactiveClient,bool isAsync)702 void PerUserSession::StopClientInput(
703     const std::shared_ptr<InputClientInfo> &clientInfo, bool isStopInactiveClient, bool isAsync)
704 {
705     if (clientInfo == nullptr || clientInfo->client == nullptr) {
706         return;
707     }
708     int32_t ret;
709     if (isAsync == true) {
710         ret = clientInfo->client->OnInputStopAsync(isStopInactiveClient);
711     } else {
712         auto onInputStopObject = new (std::nothrow) OnInputStopNotifyServiceImpl(clientInfo->pid);
713         if (onInputStopObject == nullptr) {
714             IMSA_HILOGE("Failed to create onInputStopObject.");
715             return;
716         }
717         std::lock_guard<std::mutex> lock(isNotifyFinishedLock_);
718         sptr<IRemoteObject> sptrObj(onInputStopObject);
719         isNotifyFinished_.Clear(false);
720         ret = clientInfo->client->OnInputStop(isStopInactiveClient, sptrObj);
721         if (!isNotifyFinished_.GetValue()) {
722             IMSA_HILOGE("OnInputStop is not finished!");
723         }
724     }
725     IMSA_HILOGI("isStopInactiveClient: %{public}d, client pid: %{public}d, ret: %{public}d.", isStopInactiveClient,
726         clientInfo->pid, ret);
727 }
728 
StopImeInput(ImeType currentType,const sptr<IRemoteObject> & currentChannel,uint32_t sessionId)729 void PerUserSession::StopImeInput(ImeType currentType, const sptr<IRemoteObject> &currentChannel, uint32_t sessionId)
730 {
731     auto data = GetReadyImeData(currentType);
732     if (data == nullptr) {
733         return;
734     }
735     auto ret =
736         RequestAllIme(data, RequestType::STOP_INPUT, [&currentChannel, sessionId](const sptr<IInputMethodCore> &core) {
737             return core->StopInput(currentChannel, sessionId);
738         });
739     IMSA_HILOGI("stop ime input, ret: %{public}d.", ret);
740     if (ret == ErrorCode::NO_ERROR && currentType == ImeType::IME) {
741         InputMethodSysEvent::GetInstance().ReportImeState(
742             ImeState::UNBIND, data->pid, ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName);
743         Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID);
744     }
745     if (currentType == ImeType::IME) {
746         RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID);
747     }
748 }
749 
OnSecurityChange(int32_t security)750 void PerUserSession::OnSecurityChange(int32_t security)
751 {
752     auto data = GetReadyImeData(ImeType::IME);
753     if (data == nullptr) {
754         IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
755         return;
756     }
757     auto ret = RequestIme(data, RequestType::NORMAL, [&data, security] {
758         return data->core->OnSecurityChange(security);
759     });
760     IMSA_HILOGD("on security change, ret: %{public}d.", ret);
761 }
762 
OnSetCoreAndAgent(const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent)763 int32_t PerUserSession::OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent)
764 {
765     IMSA_HILOGI("start.");
766     auto ret = UpdateImeData(core, agent, IPCSkeleton::GetCallingPid());
767     if (ret != ErrorCode::NO_ERROR) {
768         return ret;
769     }
770     auto action = GetImeAction(ImeEvent::SET_CORE_AND_AGENT);
771     if (action == ImeAction::DO_NOTHING) {
772         return ErrorCode::NO_ERROR;
773     }
774     if (action != ImeAction::DO_SET_CORE_AND_AGENT) {
775         return ErrorCode::ERROR_IME;
776     }
777     ret = InitInputControlChannel();
778     IMSA_HILOGI("init input control channel ret: %{public}d.", ret);
779     auto imeType = ImeType::IME;
780     auto clientInfo = GetCurrentClientInfo();
781     if (clientInfo != nullptr && IsImeStartInBind(clientInfo->bindImeType, imeType)) {
782         ClearRequestKeyboardReason(clientInfo);
783         BindClientWithIme(clientInfo, imeType);
784         SetInputType();
785     }
786     bool isStarted = true;
787     isImeStarted_.SetValue(isStarted);
788     return ErrorCode::NO_ERROR;
789 }
790 
OnRegisterProxyIme(const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent,pid_t pid)791 int32_t PerUserSession::OnRegisterProxyIme(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent,
792     pid_t pid)
793 {
794     IMSA_HILOGD("start.");
795     auto result = IsRequestOverLimit(TimeLimitType::PROXY_IME_LIMIT, PROXY_REGISTERATION_TIME_INTERVAL,
796         MAX_REGISTRATIONS_NUM);
797     if (result != ErrorCode::NO_ERROR) {
798         IMSA_HILOGI("frequent calls, service is busy.");
799         return result;
800     }
801     auto imeType = ImeType::PROXY_IME;
802     auto lastImeData = GetImeData(imeType);
803     if (lastImeData != nullptr && lastImeData->core != nullptr && lastImeData->core->AsObject() != core->AsObject()) {
804         lastImeData->core->NotifyPreemption();
805     }
806     auto ret = AddImeData(imeType, core, agent, pid);
807     if (ret != ErrorCode::NO_ERROR) {
808         return ret;
809     }
810     auto clientInfo = GetCurrentClientInfo();
811     if (clientInfo != nullptr) {
812         if (IsProxyImeStartInBind(clientInfo->bindImeType, imeType)) {
813             BindClientWithIme(clientInfo, imeType);
814         }
815         if (IsProxyImeStartInImeBind(clientInfo->bindImeType, imeType)) {
816             UnBindClientWithIme(clientInfo, { .sessionId = 0 });
817             BindClientWithIme(clientInfo, imeType);
818         }
819     }
820     return ErrorCode::NO_ERROR;
821 }
822 
CompareExchange(const int32_t value)823 bool PerUserSession::CompareExchange(const int32_t value)
824 {
825     std::lock_guard<std::mutex> lock(largeMemoryStateMutex_);
826     if (largeMemoryState_ == value) {
827         IMSA_HILOGD("Duplicate message.");
828         return true;
829     }
830     largeMemoryState_ = value;
831     return false;
832 }
833 
UpdateLargeMemorySceneState(const int32_t memoryState)834 int32_t PerUserSession::UpdateLargeMemorySceneState(const int32_t memoryState)
835 {
836     if (CompareExchange(memoryState)) {
837         return ErrorCode::NO_ERROR;
838     }
839     IMSA_HILOGI("large memory state: %{public}d.", memoryState);
840     if (memoryState == LargeMemoryState::LARGE_MEMORY_NOT_NEED) {
841         StartCurrentIme();
842     }
843     return ErrorCode::NO_ERROR;
844 }
845 
OnRegisterProxyIme(uint64_t displayId,const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent)846 int32_t PerUserSession::OnRegisterProxyIme(
847     uint64_t displayId, const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent)
848 {
849     IMSA_HILOGI("start. displayId: %{public}" PRIu64 "", displayId);
850     auto imeType = ImeType::PROXY_AGENT_IME;
851     auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid());
852     if (ret != ErrorCode::NO_ERROR) {
853         return ret;
854     }
855     {
856         std::lock_guard<std::mutex> lock(virtualDisplayLock_);
857         virtualScreenDisplayId_.emplace(displayId);
858     }
859     agentDisplayId_.store(displayId);
860     auto clientInfo = GetCurrentClientInfo(displayId);
861     if (clientInfo != nullptr) {
862         BindClientWithIme(clientInfo, imeType);
863     }
864     return ErrorCode::NO_ERROR;
865 }
866 
OnUnregisterProxyIme(uint64_t displayId)867 int32_t PerUserSession::OnUnregisterProxyIme(uint64_t displayId)
868 {
869     IMSA_HILOGD("start. displayId: %{public}" PRIu64 "", displayId);
870     if (displayId != agentDisplayId_.load()) {
871         return false;
872     }
873     RemoveImeData(ImeType::PROXY_AGENT_IME);
874     {
875         std::lock_guard<std::mutex> lock(virtualDisplayLock_);
876         virtualScreenDisplayId_.erase(displayId);
877     }
878     auto clientInfo = GetCurrentClientInfo(displayId);
879     if (clientInfo == nullptr) {
880         IMSA_HILOGD("no current client");
881         return ErrorCode::NO_ERROR;
882     }
883     UnBindClientWithIme(clientInfo, { .sessionId = 0 });
884     return ErrorCode::NO_ERROR;
885 }
886 
OnUnRegisteredProxyIme(UnRegisteredType type,const sptr<IInputMethodCore> & core,pid_t pid)887 int32_t PerUserSession::OnUnRegisteredProxyIme(UnRegisteredType type, const sptr<IInputMethodCore> &core, pid_t pid)
888 {
889     IMSA_HILOGD("proxy unregister type: %{public}d.", type);
890     // 0: stop proxy  1: switch to ima
891     if (type == UnRegisteredType::REMOVE_PROXY_IME) {
892         RemoveIme(ImeType::PROXY_IME, pid);
893         return ErrorCode::NO_ERROR;
894     }
895     return ErrorCode::ERROR_BAD_PARAMETERS;
896 }
897 
OnBindImeMirror(const sptr<IInputMethodCore> & core,const sptr<IRemoteObject> & agent)898 int32_t PerUserSession::OnBindImeMirror(const sptr<IInputMethodCore> &core, const sptr<IRemoteObject> &agent)
899 {
900     IMSA_HILOGI("[ImeMirrorTag]star");
901     auto imeType = ImeType::IME_MIRROR;
902     auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid());
903     if (ret != ErrorCode::NO_ERROR) {
904         return ret;
905     }
906 
907     auto clientInfo = GetCurrentClientInfo();
908     if (clientInfo != nullptr) {
909         BindClientWithIme(clientInfo, imeType);
910     }
911     return ErrorCode::NO_ERROR;
912 }
OnUnbindImeMirror()913 int32_t PerUserSession::OnUnbindImeMirror()
914 {
915     IMSA_HILOGD("[ImeMirrorTag]start");
916     auto clientInfo = GetCurrentClientInfo();
917     if (clientInfo == nullptr) {
918         RemoveImeData(ImeType::IME_MIRROR);
919         IMSA_HILOGD("[ImeMirrorTag]no current client");
920         return ErrorCode::NO_ERROR;
921     }
922 
923     auto data = GetReadyImeData(ImeType::IME_MIRROR);
924     if (data == nullptr) {
925         IMSA_HILOGD("[ImeMirrorTag]no ime mirror");
926         return ErrorCode::NO_ERROR;
927     }
928 
929     clientInfo->client->OnImeMirrorStop(data->agent);
930     StopImeInput(ImeType::IME_MIRROR, clientInfo->channel, 0);
931     RemoveImeData(ImeType::IME_MIRROR);
932     return ErrorCode::NO_ERROR;
933 }
934 
InitInputControlChannel()935 int32_t PerUserSession::InitInputControlChannel()
936 {
937     IMSA_HILOGD("PerUserSession::InitInputControlChannel start.");
938     sptr<IInputControlChannel> inputControlChannel = new (std::nothrow) InputControlChannelServiceImpl(userId_);
939     if (inputControlChannel == nullptr) {
940         IMSA_HILOGE("new inputControlChannel failed!");
941         return ErrorCode::ERROR_NULL_POINTER;
942     }
943     auto data = GetReadyImeData(ImeType::IME);
944     if (data == nullptr) {
945         IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
946         return ErrorCode::ERROR_IME_NOT_STARTED;
947     }
948     return RequestIme(data, RequestType::NORMAL, [&data, &inputControlChannel] {
949         return data->core->InitInputControlChannel(inputControlChannel);
950     });
951 }
952 
IsLargeMemoryStateNeed()953 bool PerUserSession::IsLargeMemoryStateNeed()
954 {
955     IMSA_HILOGI(" IsLargeMemoryStateNeed called.");
956     std::lock_guard<std::mutex> lock(largeMemoryStateMutex_);
957     if (largeMemoryState_ == LargeMemoryState::LARGE_MEMORY_NEED) {
958         IMSA_HILOGI("large memory state is True");
959         return true;
960     }
961     return false;
962 }
963 
StartImeInImeDied()964 void PerUserSession::StartImeInImeDied()
965 {
966     IMSA_HILOGD("StartImeInImeDied.");
967     {
968         auto result = IsRequestOverLimit(TimeLimitType::IME_LIMIT, IME_RESET_TIME_OUT, MAX_RESTART_NUM);
969         if (result != ErrorCode::NO_ERROR) {
970             return;
971         }
972     }
973     if (!IsWmsReady()) {
974         IMSA_HILOGW("not ready to start ime.");
975         return;
976     }
977     if (IsLargeMemoryStateNeed()) {
978         return;
979     }
980     StartImeIfInstalled();
981 }
982 
StartImeIfInstalled()983 void PerUserSession::StartImeIfInstalled()
984 {
985     auto imeToStart = GetRealCurrentIme(false);
986     if (imeToStart == nullptr || imeToStart->imeId.empty()) {
987         IMSA_HILOGE("imeToStart is nullptr!");
988         return;
989     }
990     if (!ImeInfoInquirer::GetInstance().IsImeInstalled(userId_, imeToStart->bundleName, imeToStart->extName)) {
991         IMSA_HILOGE("imeToStart is not installed, imeId = %{public}s!", imeToStart->imeId.c_str());
992         return;
993     }
994     StartCurrentIme();
995 }
996 
ReplaceCurrentClient(const sptr<IInputClient> & client,const std::shared_ptr<ClientGroup> & clientGroup)997 void PerUserSession::ReplaceCurrentClient(
998     const sptr<IInputClient> &client, const std::shared_ptr<ClientGroup> &clientGroup)
999 {
1000     std::lock_guard<std::mutex> lock(focusedClientLock_);
1001     if (client == nullptr || clientGroup == nullptr) {
1002         return;
1003     }
1004     auto clientInfo = clientGroup->GetClientInfo(client->AsObject());
1005     if (clientInfo == nullptr) {
1006         return;
1007     }
1008     auto replacedClient = clientGroup->GetCurrentClient();
1009     clientGroup->SetCurrentClient(client);
1010     if (replacedClient != nullptr) {
1011         auto replacedClientInfo = clientGroup->GetClientInfo(replacedClient->AsObject());
1012         if (replacedClientInfo != nullptr && replacedClientInfo->pid != clientInfo->pid) {
1013             IMSA_HILOGI("remove replaced client: [%{public}d]", replacedClientInfo->pid);
1014             RemoveClient(replacedClient, clientGroup, { .sessionId = 0 });
1015         }
1016     }
1017     auto inactiveClient = clientGroup->GetInactiveClient();
1018     if (inactiveClient != nullptr) {
1019         auto inactiveClientInfo = clientGroup->GetClientInfo(inactiveClient->AsObject());
1020         if (inactiveClientInfo != nullptr && inactiveClientInfo->pid != clientInfo->pid) {
1021             IMSA_HILOGI("remove inactive client: [%{public}d]", inactiveClientInfo->pid);
1022             DetachOptions options = { .sessionId = 0, .isUnbindFromClient = false };
1023             RemoveClient(inactiveClient, clientGroup, options);
1024         }
1025     }
1026 }
1027 
NotifyImeChangeToClients(const Property & property,const SubProperty & subProperty)1028 void PerUserSession::NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty)
1029 {
1030     IMSA_HILOGD("start.");
1031     auto clientGroup = GetClientGroup(DEFAULT_DISPLAY_ID);
1032     if (clientGroup == nullptr) {
1033         IMSA_HILOGD("no client need to notify");
1034         return;
1035     }
1036     clientGroup->NotifyImeChangeToClients(property, subProperty);
1037 }
1038 
AddImeData(ImeType type,sptr<IInputMethodCore> core,sptr<IRemoteObject> agent,pid_t pid)1039 int32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid)
1040 {
1041     if (core == nullptr || agent == nullptr) {
1042         IMSA_HILOGE("core or agent is nullptr!");
1043         return ErrorCode::ERROR_NULL_POINTER;
1044     }
1045     std::lock_guard<std::mutex> lock(imeDataLock_);
1046     auto &imeDataList = imeData_[type];
1047     auto iter = std::find_if(
1048         imeDataList.begin(), imeDataList.end(), [&core, this](const std::shared_ptr<ImeData> &existingImeData) {
1049             return existingImeData != nullptr && core->AsObject() == existingImeData->core->AsObject();
1050         });
1051     if (iter != imeDataList.end()) {
1052         auto imeData = *iter;
1053         imeDataList.erase(iter);
1054         IMSA_HILOGI("%{public}s preempt again!", imeData->ime.first.c_str());
1055         imeDataList.push_back(imeData);
1056         return ErrorCode::NO_ERROR;
1057     }
1058     sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient();
1059     if (deathRecipient == nullptr) {
1060         IMSA_HILOGE("failed to new deathRecipient!");
1061         return ErrorCode::ERROR_NULL_POINTER;
1062     }
1063     deathRecipient->SetDeathRecipient(
1064         [this, core, type, pid](const wptr<IRemoteObject> &) { this->OnImeDied(core, type, pid); });
1065     auto coreObject = core->AsObject();
1066     if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) {
1067         IMSA_HILOGE("failed to add death recipient!");
1068         return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED;
1069     }
1070     auto imeData = std::make_shared<ImeData>(core, agent, deathRecipient, pid);
1071     imeData->imeStatus = ImeStatus::READY;
1072     imeData->ime.first = "proxyIme";
1073     imeData->imeStateManager = ImeStateManagerFactory::GetInstance().CreateImeStateManager(pid, [this] {
1074         StopCurrentIme();
1075     });
1076     if (type == ImeType::PROXY_IME) {
1077         imeData->ime.first.append(GET_NAME(_PROXY_IME));
1078     } else if (type == ImeType::PROXY_AGENT_IME) {
1079         imeData->ime.first.append(GET_NAME(_PROXY_AGENT_IME));
1080     } else if (type == ImeType::IME_MIRROR) {
1081         imeData->ime.first.append(GET_NAME(_IME_MIRROR));
1082     }
1083     AddImeData(imeDataList, imeData);
1084     IMSA_HILOGI("add imeData with type: %{public}d name: %{public}s end", type, imeData->ime.first.c_str());
1085     return ErrorCode::NO_ERROR;
1086 }
1087 
AddImeData(std::vector<std::shared_ptr<ImeData>> & imeDataList,const std::shared_ptr<ImeData> & imeData)1088 void PerUserSession::AddImeData(std::vector<std::shared_ptr<ImeData>> &imeDataList,
1089     const std::shared_ptr<ImeData> &imeData)
1090 {
1091     if (imeDataList.empty()) {
1092         imeDataList.push_back(imeData);
1093         return;
1094     }
1095     if (!isFirstPreemption_) {
1096         isFirstPreemption_ = true;
1097         const auto &lastImeData = imeDataList.back();
1098         if (IsEnable(lastImeData) && !IsEnable(imeData)) {
1099             imeDataList.insert(imeDataList.begin(), imeData);
1100             return;
1101         }
1102     }
1103     imeDataList.push_back(imeData);
1104     return;
1105 }
1106 
GetReadyImeData(ImeType type)1107 std::shared_ptr<ImeData> PerUserSession::GetReadyImeData(ImeType type)
1108 {
1109     auto data = GetImeData(type);
1110     if (data == nullptr || data->imeStatus != ImeStatus::READY) {
1111         return nullptr;
1112     }
1113     return data;
1114 }
1115 
GetAllReadyImeData(ImeType type)1116 std::vector<std::shared_ptr<ImeData>> PerUserSession::GetAllReadyImeData(ImeType type)
1117 {
1118     auto typeData = GetReadyImeData(type);
1119     if (typeData == nullptr) {
1120         return {};
1121     }
1122 
1123     if (type == ImeType::IME_MIRROR) {
1124         return { typeData };
1125     }
1126 
1127     auto imeMirrorData = GetReadyImeData(ImeType::IME_MIRROR);
1128     if (imeMirrorData == nullptr) {
1129         return { typeData };
1130     }
1131 
1132     return { typeData, imeMirrorData };
1133 }
1134 
RemoveImeData(pid_t pid)1135 void PerUserSession::RemoveImeData(pid_t pid)
1136 {
1137     std::lock_guard<std::mutex> lock(imeDataLock_);
1138     for (auto itType = imeData_.begin(); itType != imeData_.end(); ++itType) {
1139         auto &imeDataList = itType->second;
1140         auto iter =
1141             std::find_if(imeDataList.begin(), imeDataList.end(), [pid](const std::shared_ptr<ImeData> &imeDataTmp) {
1142                 return imeDataTmp != nullptr && imeDataTmp->pid == pid;
1143             });
1144         if (iter != imeDataList.end()) {
1145             auto imeData = *iter;
1146             if (imeData != nullptr && imeData->core != nullptr && imeData->core->AsObject() != nullptr) {
1147                     imeData->core->AsObject()->RemoveDeathRecipient(imeData->deathRecipient);
1148             }
1149             imeDataList.erase(iter);
1150             if (imeDataList.empty()) {
1151                 imeData_.erase(itType);
1152             }
1153             break;
1154         }
1155     }
1156 }
1157 
RemoveImeData(ImeType type)1158 void PerUserSession::RemoveImeData(ImeType type)
1159 {
1160     std::lock_guard<std::mutex> lock(imeDataLock_);
1161     auto it = imeData_.find(type);
1162     if (it == imeData_.end()) {
1163         IMSA_HILOGD("imeData not found.");
1164         return;
1165     }
1166     for (auto &imeData : it->second) {
1167         if (imeData != nullptr && imeData->core != nullptr && imeData->core->AsObject() != nullptr) {
1168             imeData->core->AsObject()->RemoveDeathRecipient(imeData->deathRecipient);
1169         }
1170     }
1171     imeData_.erase(type);
1172 }
1173 
OnFocused(uint64_t displayId,int32_t pid,int32_t uid)1174 void PerUserSession::OnFocused(uint64_t displayId, int32_t pid, int32_t uid)
1175 {
1176     std::lock_guard<std::mutex> lock(focusedClientLock_);
1177     auto clientGroup = GetClientGroup(displayId);
1178     if (clientGroup == nullptr) {
1179         return;
1180     }
1181     auto client = clientGroup->GetCurrentClient();
1182     if (client == nullptr) {
1183         return;
1184     }
1185     if (clientGroup->IsCurClientFocused(pid, uid)) {
1186         IMSA_HILOGD("current client focused, focusedPid: %{public}d", pid);
1187         return;
1188     }
1189     if (!OHOS::Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
1190         IMSA_HILOGI("focus shifts to pid: %{public}d, remove current client.", pid);
1191         RemoveClient(client, clientGroup, { .sessionId = 0 });
1192         InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED);
1193         return;
1194     }
1195     IMSA_HILOGI("focus shifts to pid: %{public}d, deactivate current client.", pid);
1196     DeactivateClient(client);
1197 }
1198 
OnUnfocused(uint64_t displayId,int32_t pid,int32_t uid)1199 void PerUserSession::OnUnfocused(uint64_t displayId, int32_t pid, int32_t uid)
1200 {
1201     auto clientGroup = GetClientGroup(displayId);
1202     if (clientGroup == nullptr) {
1203         return;
1204     }
1205     if (clientGroup->GetCurrentClient() == nullptr) {
1206         return;
1207     }
1208     if (clientGroup->IsCurClientUnFocused(pid, uid)) {
1209         IMSA_HILOGD("current client Unfocused, unFocusedPid: %{public}d", pid);
1210         return;
1211     }
1212     auto clientInfo = clientGroup->GetClientInfo(pid);
1213     if (clientInfo == nullptr) {
1214         return;
1215     }
1216     RemoveClient(clientInfo->client, clientGroup, { .sessionId = 0 });
1217     InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_UNFOCUSED);
1218 }
1219 
OnScreenUnlock()1220 void PerUserSession::OnScreenUnlock()
1221 {
1222     ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, "");
1223     auto imeData = GetImeData(ImeType::IME);
1224     if (imeData != nullptr && imeData->ime == GetImeUsedBeforeScreenLocked()) {
1225         IMSA_HILOGD("no need to switch");
1226         return;
1227     }
1228     IMSA_HILOGI("user %{public}d unlocked, start current ime", userId_);
1229 #ifndef IMF_ON_DEMAND_START_STOP_SA_ENABLE
1230     if (!ImeStateManagerFactory::GetInstance().GetDynamicStartIme()) {
1231         AddRestartIme();
1232     }
1233 #endif
1234 }
1235 
OnScreenLock()1236 void PerUserSession::OnScreenLock()
1237 {
1238     auto imeData = GetImeData(ImeType::IME);
1239     if (imeData == nullptr) {
1240         IMSA_HILOGD("imeData is nullptr");
1241         std::pair<std::string, std::string> ime{ "", "" };
1242         SetImeUsedBeforeScreenLocked(ime);
1243         return;
1244     }
1245     SetImeUsedBeforeScreenLocked(imeData->ime);
1246 }
1247 
GetCurrentClientInfo(uint64_t displayId)1248 std::shared_ptr<InputClientInfo> PerUserSession::GetCurrentClientInfo(uint64_t displayId)
1249 {
1250     auto clientGroup = GetClientGroup(displayId);
1251     if (clientGroup == nullptr) {
1252         IMSA_HILOGD("client group: %{public}" PRIu64 "", displayId);
1253         return nullptr;
1254     }
1255     return clientGroup->GetCurrentClientInfo();
1256 }
1257 
IsSameClient(sptr<IInputClient> source,sptr<IInputClient> dest)1258 bool PerUserSession::IsSameClient(sptr<IInputClient> source, sptr<IInputClient> dest)
1259 {
1260     return source != nullptr && dest != nullptr && source->AsObject() == dest->AsObject();
1261 }
1262 
GetRealCurrentIme(bool needMinGuarantee)1263 std::shared_ptr<ImeNativeCfg> PerUserSession::GetRealCurrentIme(bool needMinGuarantee)
1264 {
1265     std::shared_ptr<ImeNativeCfg> currentIme = nullptr;
1266     if (GetInputTypeToStart(currentIme)) {
1267         return currentIme;
1268     }
1269     auto clientGroup = GetClientGroup(ImeType::IME);
1270     auto clientInfo = clientGroup != nullptr ? clientGroup->GetCurrentClientInfo() : nullptr;
1271     if (clientInfo != nullptr) {
1272         InputType type = InputType::NONE;
1273         if (clientInfo->config.inputAttribute.GetSecurityFlag()) {
1274             type = InputType::SECURITY_INPUT;
1275         }
1276         if (type != InputType::NONE) {
1277             ImeIdentification inputTypeIme;
1278             InputTypeManager::GetInstance().GetImeByInputType(type, inputTypeIme);
1279             currentIme = GetImeNativeCfg(userId_, inputTypeIme.bundleName, inputTypeIme.subName);
1280             if (currentIme != nullptr) {
1281                 IMSA_HILOGD("get inputType ime:%{public}d!", type);
1282                 return currentIme;
1283             }
1284         }
1285         if (IsPreconfiguredDefaultImeSpecified(*clientInfo)) {
1286             IMSA_HILOGD("get preconfigured default ime:%{public}d/%{public}d!",
1287                 clientInfo->config.isSimpleKeyboardEnabled, clientInfo->config.inputAttribute.IsOneTimeCodeFlag());
1288             auto preconfiguredIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg();
1289             auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1290             if (preconfiguredIme != nullptr && defaultIme != nullptr && defaultIme->imeId == preconfiguredIme->imeId) {
1291                 return defaultIme;
1292             }
1293             if (preconfiguredIme != nullptr) {
1294                 return preconfiguredIme;
1295             }
1296         }
1297     }
1298 #ifdef IMF_SCREENLOCK_MGR_ENABLE
1299     auto screenLockMgr = ScreenLock::ScreenLockManager::GetInstance();
1300     if (screenLockMgr != nullptr && screenLockMgr->IsScreenLocked()) {
1301         IMSA_HILOGD("get screen locked ime!");
1302         auto preconfiguredIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg();
1303         auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1304         if (preconfiguredIme != nullptr && (defaultIme == nullptr || defaultIme->imeId != preconfiguredIme->imeId)) {
1305             ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, preconfiguredIme->imeId);
1306         }
1307     }
1308 #endif
1309     IMSA_HILOGD("get user set ime:%{public}d!", needMinGuarantee);
1310     return needMinGuarantee ? ImeInfoInquirer::GetInstance().GetImeToStart(userId_)
1311                                 : ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1312 }
1313 
NotifyImeChangedToClients()1314 int32_t PerUserSession::NotifyImeChangedToClients()
1315 {
1316     auto userSpecifiedIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1317     if (userSpecifiedIme == nullptr) {
1318         IMSA_HILOGW("userSpecifiedIme not find.");
1319         return ErrorCode::ERROR_IMSA_NULLPTR;
1320     }
1321     auto userSpecifiedImeInfo =
1322         ImeInfoInquirer::GetInstance().GetImeInfo(userId_, userSpecifiedIme->bundleName, userSpecifiedIme->subName);
1323     if (userSpecifiedImeInfo == nullptr) {
1324         IMSA_HILOGE("userSpecifiedIme:%{public}s not find.", userSpecifiedIme->bundleName.c_str());
1325         return ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED;
1326     }
1327     NotifyImeChangeToClients(userSpecifiedImeInfo->prop, userSpecifiedImeInfo->subProp);
1328     return ErrorCode::NO_ERROR;
1329 }
1330 
NotifySubTypeChangedToIme(const std::string & bundleName,const std::string & subName)1331 int32_t PerUserSession::NotifySubTypeChangedToIme(const std::string &bundleName, const std::string &subName)
1332 {
1333     SubProperty subProp;
1334     subProp.name = UNDEFINED;
1335     subProp.id = UNDEFINED;
1336     if (subName.empty()) {
1337         IMSA_HILOGW("undefined subtype");
1338     } else if (InputTypeManager::GetInstance().IsInputType({ bundleName, subName })) {
1339         IMSA_HILOGD("inputType: %{public}s", subName.c_str());
1340         InputTypeManager::GetInstance().Set(true, { bundleName, subName });
1341         subProp.name = bundleName;
1342         subProp.id = subName;
1343     } else {
1344         auto currentImeInfo = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName);
1345         if (currentImeInfo != nullptr) {
1346             subProp = currentImeInfo->subProp;
1347         }
1348     }
1349     auto ret = SwitchSubtypeWithoutStartIme(subProp);
1350     if (ret != ErrorCode::NO_ERROR) {
1351         IMSA_HILOGE("SwitchSubtype failed!");
1352     }
1353     return ret;
1354 }
1355 
StartCurrentIme(bool isStopCurrentIme)1356 int32_t PerUserSession::StartCurrentIme(bool isStopCurrentIme)
1357 {
1358     IMSA_HILOGD("enter");
1359     auto imeToStart = GetRealCurrentIme(true);
1360     if (imeToStart == nullptr) {
1361         IMSA_HILOGE("imeToStart is nullptr!");
1362         return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1363     }
1364     IMSA_HILOGI("ime info:%{public}s/%{public}s.", imeToStart->bundleName.c_str(), imeToStart->subName.c_str());
1365     auto ret = StartIme(imeToStart, isStopCurrentIme);
1366     if (ret != ErrorCode::NO_ERROR) {
1367         IMSA_HILOGE("failed to start ime!");
1368         InputMethodSysEvent::GetInstance().InputmethodFaultReporter(ret, imeToStart->imeId, "start ime failed!");
1369         return ret;
1370     }
1371     auto readyIme = GetReadyImeData(ImeType::IME);
1372     if (readyIme == nullptr) {
1373         IMSA_HILOGE("ime abnormal.");
1374         return ErrorCode::ERROR_IME_NOT_STARTED;
1375     }
1376     NotifyImeChangedToClients();
1377     auto subName = readyIme->ime.first != imeToStart->bundleName ? "" : imeToStart->subName;
1378     NotifySubTypeChangedToIme(readyIme->ime.first, subName);
1379     return ErrorCode::NO_ERROR;
1380 }
1381 
CanStartIme()1382 bool PerUserSession::CanStartIme()
1383 {
1384     return (IsSaReady(MEMORY_MANAGER_SA_ID) && IsWmsReady() &&
1385 #ifdef IMF_SCREENLOCK_MGR_ENABLE
1386     IsSaReady(SCREENLOCK_SERVICE_ID) &&
1387 #endif
1388     runningIme_.empty());
1389 }
1390 
ChangeToDefaultImeIfNeed(const std::shared_ptr<ImeNativeCfg> & targetIme,std::shared_ptr<ImeNativeCfg> & imeToStart)1391 int32_t PerUserSession::ChangeToDefaultImeIfNeed(
1392     const std::shared_ptr<ImeNativeCfg> &targetIme, std::shared_ptr<ImeNativeCfg> &imeToStart)
1393 {
1394 #ifndef IMF_SCREENLOCK_MGR_ENABLE
1395     IMSA_HILOGD("no need");
1396     return ErrorCode::NO_ERROR;
1397 #endif
1398     auto screenLockMgr = ScreenLock::ScreenLockManager::GetInstance();
1399     if (screenLockMgr != nullptr && !screenLockMgr->IsScreenLocked()) {
1400         IMSA_HILOGD("no need");
1401         imeToStart = targetIme;
1402         return ErrorCode::NO_ERROR;
1403     }
1404     IMSA_HILOGI("Screen is locked, start default ime");
1405     auto defaultIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg();
1406     if (defaultIme == nullptr) {
1407         IMSA_HILOGE("failed to get default ime");
1408         return ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND;
1409     }
1410     if (defaultIme->bundleName == targetIme->bundleName) {
1411         IMSA_HILOGD("no need");
1412         imeToStart = targetIme;
1413         return ErrorCode::NO_ERROR;
1414     }
1415     imeToStart = defaultIme;
1416     ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, imeToStart->imeId);
1417     return ErrorCode::NO_ERROR;
1418 }
1419 
GetWant(const std::shared_ptr<ImeNativeCfg> & ime)1420 AAFwk::Want PerUserSession::GetWant(const std::shared_ptr<ImeNativeCfg> &ime)
1421 {
1422     bool isolatedSandBox = true;
1423     EnabledStatus status = EnabledStatus::BASIC_MODE;
1424     AAFwk::Want want;
1425     if (ime == nullptr) {
1426         IMSA_HILOGE("ime is null");
1427         return want;
1428     }
1429     if (ImeEnabledInfoManager::GetInstance().IsDefaultFullMode(userId_, ime->bundleName)) {
1430         status = EnabledStatus::FULL_EXPERIENCE_MODE;
1431         isolatedSandBox = false;
1432     } else {
1433         auto ret = ImeEnabledInfoManager::GetInstance().GetEnabledState(userId_, ime->bundleName, status);
1434         if (ret != ErrorCode::NO_ERROR) {
1435             IMSA_HILOGE("%{public}d/%{public}s GetEnabledState failed.", userId_, ime->imeId.c_str());
1436         }
1437     }
1438     want.SetElementName(ime->bundleName, ime->extName);
1439     want.SetParam(STRICT_MODE, !(status == EnabledStatus::FULL_EXPERIENCE_MODE));
1440     want.SetParam(ISOLATED_SANDBOX, isolatedSandBox);
1441     IMSA_HILOGI("StartInputService userId: %{public}d, ime: %{public}s, mode: %{public}d, isolatedSandbox: %{public}d",
1442         userId_, ime->imeId.c_str(), static_cast<int32_t>(status), isolatedSandBox);
1443     return want;
1444 }
1445 
StartInputService(const std::shared_ptr<ImeNativeCfg> & ime)1446 int32_t PerUserSession::StartInputService(const std::shared_ptr<ImeNativeCfg> &ime)
1447 {
1448     InputMethodSyncTrace tracer("StartInputService trace.");
1449     if (ime == nullptr) {
1450         return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1451     }
1452     IMSA_HILOGI("run in %{public}s", ime->imeId.c_str());
1453     auto imeToStart = std::make_shared<ImeNativeCfg>();
1454     auto ret = ChangeToDefaultImeIfNeed(ime, imeToStart);
1455     if (imeToStart == nullptr) {
1456         return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
1457     }
1458     if (ret != ErrorCode::NO_ERROR) {
1459         return ret;
1460     }
1461     InitImeData({ imeToStart->bundleName, imeToStart->extName }, ime);
1462     isImeStarted_.Clear(false);
1463     sptr<AAFwk::IAbilityConnection> connection = new (std::nothrow) ImeConnection();
1464     if (connection == nullptr) {
1465         IMSA_HILOGE("failed to create connection!");
1466         return ErrorCode::ERROR_IMSA_MALLOC_FAILED;
1467     }
1468     SetImeConnection(connection);
1469     auto want = GetWant(imeToStart);
1470     IMSA_HILOGI("connect %{public}s start!", imeToStart->imeId.c_str());
1471     ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_);
1472     if (ret != ErrorCode::NO_ERROR) {
1473         IMSA_HILOGE("connect %{public}s failed, ret: %{public}d!", imeToStart->imeId.c_str(), ret);
1474         InputMethodSysEvent::GetInstance().InputmethodFaultReporter(
1475             ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, imeToStart->imeId, "failed to start ability.");
1476         SetImeConnection(nullptr);
1477         return ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED;
1478     }
1479     if (!isImeStarted_.GetValue()) {
1480         IMSA_HILOGE("start %{public}s timeout!", imeToStart->imeId.c_str());
1481         return ErrorCode::ERROR_IMSA_IME_START_TIMEOUT;
1482     }
1483     IMSA_HILOGI("%{public}s started successfully.", imeToStart->imeId.c_str());
1484     InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::START_IME);
1485     return ErrorCode::NO_ERROR;
1486 }
1487 
GetCurrentClientPid(uint64_t displayId)1488 int64_t PerUserSession::GetCurrentClientPid(uint64_t displayId)
1489 {
1490     auto clientGroup = GetClientGroup(displayId);
1491     if (clientGroup == nullptr) {
1492         return INVALID_PID;
1493     }
1494     return clientGroup->GetCurrentClientPid();
1495 }
1496 
GetInactiveClientPid(uint64_t displayId)1497 int64_t PerUserSession::GetInactiveClientPid(uint64_t displayId)
1498 {
1499     auto clientGroup = GetClientGroup(displayId);
1500     if (clientGroup == nullptr) {
1501         return INVALID_PID;
1502     }
1503     return clientGroup->GetInactiveClientPid();
1504 }
1505 
OnPanelStatusChange(const InputWindowStatus & status,const ImeWindowInfo & info,uint64_t displayId)1506 int32_t PerUserSession::OnPanelStatusChange(
1507     const InputWindowStatus &status, const ImeWindowInfo &info, uint64_t displayId)
1508 {
1509     auto clientGroup = GetClientGroup(displayId);
1510     if (clientGroup == nullptr) {
1511         IMSA_HILOGD("client nullptr");
1512         return ErrorCode::NO_ERROR;
1513     }
1514     return clientGroup->NotifyPanelStatusChange(status, info);
1515 }
1516 
OnUpdateListenEventFlag(const InputClientInfo & clientInfo)1517 int32_t PerUserSession::OnUpdateListenEventFlag(const InputClientInfo &clientInfo)
1518 {
1519     if (clientInfo.client == nullptr) {
1520         IMSA_HILOGE("clientInfo is nullptr!");
1521         return ErrorCode::ERROR_NULL_POINTER;
1522     }
1523     auto remoteClient = clientInfo.client->AsObject();
1524     auto ret = AddClientInfo(remoteClient, clientInfo, START_LISTENING);
1525     if (ret != ErrorCode::NO_ERROR) {
1526         IMSA_HILOGE("failed to AddClientInfo!");
1527         return ret;
1528     }
1529     auto clientGroup = GetClientGroup(remoteClient);
1530     if (clientGroup == nullptr) {
1531         IMSA_HILOGE("group is nullptr");
1532         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
1533     }
1534     auto info = clientGroup->GetClientInfo(remoteClient);
1535     if (info == nullptr) {
1536         IMSA_HILOGE("info is nullptr!");
1537         return ErrorCode::ERROR_CLIENT_NOT_FOUND;
1538     }
1539     if (info->eventFlag == NO_EVENT_ON && info->bindImeType == ImeType::NONE) {
1540         clientGroup->RemoveClientInfo(remoteClient, false);
1541     }
1542     return ErrorCode::NO_ERROR;
1543 }
1544 
OnSetCallingWindow(uint32_t callingWindowId,uint64_t callingDisplayId,sptr<IInputClient> client)1545 int32_t PerUserSession::OnSetCallingWindow(uint32_t callingWindowId,
1546     uint64_t callingDisplayId, sptr<IInputClient> client)
1547 {
1548     IMSA_HILOGD("OnSetCallingWindow enter");
1549     if (client == nullptr) {
1550         IMSA_HILOGE("nullptr client!");
1551         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
1552     }
1553     auto clientGroup = GetClientGroup(client->AsObject());
1554     if (clientGroup == nullptr) {
1555         IMSA_HILOGE("clientGroup nullptr");
1556         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
1557     }
1558     if (!IsSameClient(client, clientGroup->GetCurrentClient())) {
1559         IMSA_HILOGE("client is not current client!");
1560         return ErrorCode::ERROR_CLIENT_NOT_FOCUSED;
1561     }
1562     auto clientInfo = clientGroup->GetClientInfo(client->AsObject());
1563     if (clientInfo == nullptr) {
1564         IMSA_HILOGE("nullptr clientInfo!");
1565         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1566     }
1567     if (clientInfo->config.windowId == callingWindowId) {
1568         return ErrorCode::NO_ERROR;
1569     }
1570     IMSA_HILOGD("windowId changed, refresh windowId info and notify clients input start.");
1571     clientInfo->config.windowId = callingWindowId;
1572     clientInfo->config.privateCommand.insert_or_assign(
1573         "displayId", PrivateDataValue(static_cast<int32_t>(callingDisplayId)));
1574     clientGroup->NotifyInputStartToClients(callingWindowId, static_cast<int32_t>(clientInfo->requestKeyboardReason));
1575 
1576     if (callingWindowId != INVALID_WINDOW_ID) {
1577         auto callingWindowInfo = GetCallingWindowInfo(*clientInfo);
1578         clientInfo->config.inputAttribute.windowId = callingWindowInfo.windowId;
1579         bool isNotifyDisplayChanged =
1580             clientInfo->config.inputAttribute.callingDisplayId != callingWindowInfo.displayId &&
1581             SceneBoardJudgement::IsSceneBoardEnabled();
1582         clientInfo->config.inputAttribute.callingDisplayId = callingWindowInfo.displayId;
1583         if (isNotifyDisplayChanged) {
1584             NotifyCallingDisplayChanged(callingWindowInfo.displayId);
1585         }
1586     }
1587     return ErrorCode::NO_ERROR;
1588 }
1589 
GetInputStartInfo(uint64_t displayId,bool & isInputStart,uint32_t & callingWndId,int32_t & requestKeyboardReason)1590 int32_t PerUserSession::GetInputStartInfo(
1591     uint64_t displayId, bool &isInputStart, uint32_t &callingWndId, int32_t &requestKeyboardReason)
1592 {
1593     auto clientInfo = GetCurrentClientInfo(displayId);
1594     if (clientInfo == nullptr) {
1595         IMSA_HILOGE("nullptr clientInfo!");
1596         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1597     }
1598     isInputStart = true;
1599     callingWndId = clientInfo->config.windowId;
1600     requestKeyboardReason = static_cast<int32_t>(clientInfo->requestKeyboardReason);
1601     return ErrorCode::NO_ERROR;
1602 }
1603 
IsImeStartInBind(ImeType bindImeType,ImeType startImeType)1604 bool PerUserSession::IsImeStartInBind(ImeType bindImeType, ImeType startImeType)
1605 {
1606     return startImeType == ImeType::IME && bindImeType == ImeType::IME;
1607 }
1608 
IsProxyImeStartInBind(ImeType bindImeType,ImeType startImeType)1609 bool PerUserSession::IsProxyImeStartInBind(ImeType bindImeType, ImeType startImeType)
1610 {
1611     return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::PROXY_IME;
1612 }
1613 
IsProxyImeStartInImeBind(ImeType bindImeType,ImeType startImeType)1614 bool PerUserSession::IsProxyImeStartInImeBind(ImeType bindImeType, ImeType startImeType)
1615 {
1616     return startImeType == ImeType::PROXY_IME && bindImeType == ImeType::IME;
1617 }
1618 
IsImeBindTypeChanged(ImeType bindImeType)1619 bool PerUserSession::IsImeBindTypeChanged(ImeType bindImeType)
1620 {
1621     return (bindImeType == ImeType::IME && IsProxyImeEnable()) ||
1622            (bindImeType == ImeType::PROXY_IME && !IsProxyImeEnable());
1623 }
1624 
SwitchSubtype(const SubProperty & subProperty)1625 int32_t PerUserSession::SwitchSubtype(const SubProperty &subProperty)
1626 {
1627     auto data = GetReadyImeData(ImeType::IME);
1628     if (data == nullptr || data->core == nullptr) {
1629         IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1630         return ErrorCode::ERROR_IME_NOT_STARTED;
1631     }
1632     return RequestIme(data, RequestType::NORMAL, [&data, &subProperty] {
1633         return data->core->SetSubtype(subProperty);
1634     });
1635 }
1636 
SwitchSubtypeWithoutStartIme(const SubProperty & subProperty)1637 int32_t PerUserSession::SwitchSubtypeWithoutStartIme(const SubProperty &subProperty)
1638 {
1639     auto data = GetReadyImeData(ImeType::IME);
1640     if (data == nullptr || data->core == nullptr) {
1641         IMSA_HILOGE("ime: %{public}d is not exist, or core is nullptr.", ImeType::IME);
1642         return ErrorCode::ERROR_IME_NOT_STARTED;
1643     }
1644     return RequestIme(data, RequestType::NORMAL, [&data, &subProperty] {
1645         return data->core->SetSubtype(subProperty);
1646     });
1647 }
1648 
SetInputType()1649 int32_t PerUserSession::SetInputType()
1650 {
1651     InputType inputType = InputTypeManager::GetInstance().GetCurrentInputType();
1652     auto data = GetReadyImeData(ImeType::IME);
1653     if (data == nullptr) {
1654         IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1655         return ErrorCode::ERROR_IME_NOT_STARTED;
1656     }
1657     return RequestIme(data, RequestType::NORMAL, [&data, &inputType] {
1658         return data->core->OnSetInputType(static_cast<int32_t>(inputType));
1659     });
1660 }
1661 
IsBoundToClient(uint64_t displayId)1662 bool PerUserSession::IsBoundToClient(uint64_t displayId)
1663 {
1664     auto clientGroup = GetClientGroup(displayId);
1665     if (clientGroup == nullptr) {
1666         IMSA_HILOGE("not in bound state!");
1667         return false;
1668     }
1669     if (clientGroup->GetCurrentClient() == nullptr) {
1670         IMSA_HILOGE("not in bound state!");
1671         return false;
1672     }
1673     return true;
1674 }
1675 
RestoreCurrentImeSubType(uint64_t callingDisplayId)1676 int32_t PerUserSession::RestoreCurrentImeSubType(uint64_t callingDisplayId)
1677 {
1678     if (!IsDefaultDisplayGroup(callingDisplayId)) {
1679         IMSA_HILOGI("only need restore in default display, calling display: %{public}" PRIu64 "", callingDisplayId);
1680         return ErrorCode::NO_ERROR;
1681     }
1682     if (!InputTypeManager::GetInstance().IsStarted()) {
1683         IMSA_HILOGD("already exit.");
1684         return ErrorCode::NO_ERROR;
1685     }
1686     auto typeIme = InputTypeManager::GetInstance().GetCurrentIme();
1687     InputTypeManager::GetInstance().Set(false);
1688     auto imeData = GetReadyImeData(ImeType::IME);
1689     if (imeData == nullptr) {
1690         IMSA_HILOGD("has no ready ime, not deal.");
1691         return ErrorCode::NO_ERROR;
1692     }
1693     if (imeData->ime.first != typeIme.bundleName) {
1694         IMSA_HILOGD("ready ime:%{public}s is not input type ime:%{public}s, not deal.", imeData->ime.first.c_str(),
1695             typeIme.bundleName.c_str());
1696         return ErrorCode::NO_ERROR;
1697     }
1698     auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
1699     std::string subName;
1700     if (defaultIme != nullptr && imeData->ime.first == defaultIme->bundleName) {
1701         IMSA_HILOGD("readyIme is input type ime, same to default ime:%{public}s.", typeIme.bundleName.c_str());
1702         subName = defaultIme->subName;
1703     }
1704     IMSA_HILOGD("restore subtype: %{public}s/%{public}s.", imeData->ime.first.c_str(), subName.c_str());
1705     return NotifySubTypeChangedToIme(imeData->ime.first, subName);
1706 }
1707 
IsCurrentImeByPid(int32_t pid)1708 bool PerUserSession::IsCurrentImeByPid(int32_t pid)
1709 {
1710     auto imeData = GetImeData(ImeType::IME);
1711     if (imeData == nullptr) {
1712         IMSA_HILOGE("ime not started!");
1713         return false;
1714     }
1715     IMSA_HILOGD("userId: %{public}d, pid: %{public}d, current pid: %{public}d.", userId_, pid, imeData->pid);
1716     return imeData->pid == pid;
1717 }
1718 
IsPanelShown(const PanelInfo & panelInfo,bool & isShown)1719 int32_t PerUserSession::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
1720 {
1721     auto clientGroup = GetClientGroup(DEFAULT_DISPLAY_ID);
1722     if (clientGroup == nullptr || clientGroup->GetCurrentClient() == nullptr) {
1723         IMSA_HILOGD("not in bound state.");
1724         isShown = false;
1725         return ErrorCode::NO_ERROR;
1726     }
1727     auto ime = GetReadyImeData(ImeType::IME);
1728     if (ime == nullptr) {
1729         IMSA_HILOGE("ime not started!");
1730         return ErrorCode::ERROR_IME_NOT_STARTED;
1731     }
1732     return RequestIme(ime, RequestType::NORMAL, [&ime, &panelInfo, &isShown] {
1733         return ime->core->IsPanelShown(panelInfo, isShown);
1734     });
1735 }
1736 
CheckSecurityMode()1737 bool PerUserSession::CheckSecurityMode()
1738 {
1739     auto clientInfo = GetCurrentClientInfo();
1740     if (clientInfo != nullptr) {
1741         return clientInfo->config.inputAttribute.GetSecurityFlag();
1742     }
1743     return false;
1744 }
1745 
RequestIme(const std::shared_ptr<ImeData> & data,RequestType type,const IpcExec & exec)1746 int32_t PerUserSession::RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IpcExec &exec)
1747 {
1748     if (IsProxyImeEnable() || data->IsImeMirror()) {
1749         IMSA_HILOGD("proxy enable.");
1750         return exec();
1751     }
1752     if (data == nullptr || data->core == nullptr || data->imeStateManager == nullptr) {
1753         IMSA_HILOGE("data is nullptr!");
1754         return ErrorCode::NO_ERROR;
1755     }
1756     if (!data->imeStateManager->IsIpcNeeded(type)) {
1757         IMSA_HILOGD("no need to request, type: %{public}d.", type);
1758         return ErrorCode::NO_ERROR;
1759     }
1760 
1761     data->imeStateManager->BeforeIpc(type);
1762     auto ret = exec();
1763     data->imeStateManager->AfterIpc(type, ret == ErrorCode::NO_ERROR);
1764     return ret;
1765 }
1766 
RequestAllIme(const std::shared_ptr<ImeData> data,RequestType reqType,const CoreMethod & method)1767 int32_t PerUserSession::RequestAllIme(
1768     const std::shared_ptr<ImeData> data, RequestType reqType, const CoreMethod &method)
1769 {
1770     if (data == nullptr) {
1771         IMSA_HILOGW("no need to request, type:%{public}d}", reqType);
1772         return ErrorCode::NO_ERROR;
1773     }
1774 
1775     std::vector<std::shared_ptr<ImeData>> dataArray = { data };
1776 
1777     if (!data->IsImeMirror()) {
1778         auto imeMirrorData = GetReadyImeData(ImeType::IME_MIRROR);
1779         if (imeMirrorData != nullptr) {
1780             dataArray.push_back(imeMirrorData);
1781         }
1782     }
1783 
1784     int32_t finalResult = ErrorCode::NO_ERROR;
1785     for (const auto &dataItem : dataArray) {
1786         int32_t ret = RequestIme(dataItem, reqType, [&dataItem, &method]() {
1787             return method(dataItem->core); // Execute the specified core method
1788         });
1789         if (ret != ErrorCode::NO_ERROR) {
1790             IMSA_HILOGE(
1791                 "request ime failed, ret: %{public}d, IsImeMirror:%{public}d", ret, dataItem->IsImeMirror());
1792         }
1793         // IME_MIRROR not effect overall result
1794         if (!dataItem->IsImeMirror()) {
1795             finalResult = ret;
1796         }
1797     }
1798     return finalResult;
1799 }
1800 
OnConnectSystemCmd(const sptr<IRemoteObject> & channel,sptr<IRemoteObject> & agent)1801 int32_t PerUserSession::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent)
1802 {
1803     auto data = GetReadyImeData(ImeType::IME);
1804     if (data == nullptr) {
1805         IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME);
1806         return ErrorCode::ERROR_IME_NOT_STARTED;
1807     }
1808     auto ret = RequestIme(data, RequestType::NORMAL, [&data, &channel, &agent] {
1809         return data->core->OnConnectSystemCmd(channel, agent);
1810     });
1811     IMSA_HILOGD("on connect systemCmd, ret: %{public}d.", ret);
1812     if (ret != ErrorCode::NO_ERROR) {
1813         IMSA_HILOGE("bind failed, ret: %{public}d!", ret);
1814         return ret;
1815     }
1816     return ErrorCode::NO_ERROR;
1817 }
1818 
WaitForCurrentImeStop()1819 bool PerUserSession::WaitForCurrentImeStop()
1820 {
1821     IMSA_HILOGI("start.");
1822     std::unique_lock<std::mutex> lock(imeStopMutex_);
1823     isSwitching_.store(true);
1824     return imeStopCv_.wait_for(lock, std::chrono::milliseconds(STOP_IME_TIME), [this]() { return !isSwitching_; });
1825 }
1826 
NotifyImeStopFinished()1827 void PerUserSession::NotifyImeStopFinished()
1828 {
1829     IMSA_HILOGI("start.");
1830     std::unique_lock<std::mutex> lock(imeStopMutex_);
1831     isSwitching_.store(false);
1832     imeStopCv_.notify_one();
1833 }
1834 
RemoveAllCurrentClient()1835 int32_t PerUserSession::RemoveAllCurrentClient()
1836 {
1837     std::lock_guard<std::mutex> lock(clientGroupLock_);
1838     if (clientGroupMap_.empty()) {
1839         IMSA_HILOGI("no current client");
1840         return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1841     }
1842     for (const auto &clientGroup : clientGroupMap_) {
1843         auto clientGroupObject = clientGroup.second;
1844         if (clientGroupObject == nullptr) {
1845             continue;
1846         }
1847         clientGroupObject->NotifyInputStopToClients();
1848         DetachOptions options = { .sessionId = 0, .isUnbindFromClient = false };
1849         RemoveClient(clientGroupObject->GetCurrentClient(), clientGroupObject, options);
1850     }
1851     return ErrorCode::NO_ERROR;
1852 }
1853 
IsWmsReady()1854 bool PerUserSession::IsWmsReady()
1855 {
1856     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
1857         IMSA_HILOGD("scb enable");
1858         return WmsConnectionObserver::IsWmsConnected(userId_);
1859     }
1860     return IsSaReady(WINDOW_MANAGER_SERVICE_ID);
1861 }
1862 
IsSaReady(int32_t saId)1863 bool PerUserSession::IsSaReady(int32_t saId)
1864 {
1865     auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1866     if (saMgr == nullptr) {
1867         IMSA_HILOGE("get saMgr failed!");
1868         return false;
1869     }
1870     if (saMgr->CheckSystemAbility(saId) == nullptr) {
1871         IMSA_HILOGE("sa:%{public}d not ready!", saId);
1872         return false;
1873     }
1874     return true;
1875 }
1876 
AddRestartIme()1877 void PerUserSession::AddRestartIme()
1878 {
1879     int32_t tasks = 0;
1880     {
1881         std::lock_guard<std::mutex> lock(restartMutex_);
1882         if (restartTasks_ >= MAX_RESTART_TASKS) {
1883             return;
1884         }
1885         restartTasks_ = std::max(restartTasks_, 0);
1886         tasks = ++restartTasks_;
1887     }
1888     if (tasks == 1 && !RestartIme()) {
1889         std::lock_guard<std::mutex> lock(restartMutex_);
1890         restartTasks_ = 0;
1891     }
1892 }
1893 
IsAttachFinished()1894 bool PerUserSession::IsAttachFinished()
1895 {
1896     static uint32_t waitAttachTimes = 0;
1897     if (GetAttachCount() != 0 && waitAttachTimes < WAIT_ATTACH_FINISH_MAX_TIMES) {
1898         IMSA_HILOGI("wait for attach finish");
1899         waitAttachTimes++;
1900         return false;
1901     }
1902     waitAttachTimes = 0;
1903     return true;
1904 }
1905 
IncreaseScbStartCount()1906 void PerUserSession::IncreaseScbStartCount()
1907 {
1908     std::lock_guard<std::mutex> lock(scbStartCountMtx_);
1909     scbStartCount_ = std::min(scbStartCount_ + 1, MAX_SCB_START_COUNT);
1910     IMSA_HILOGI("scb start count: %{public}u", scbStartCount_);
1911 }
1912 
GetScbStartCount()1913 uint32_t PerUserSession::GetScbStartCount()
1914 {
1915     std::lock_guard<std::mutex> lock(scbStartCountMtx_);
1916     return scbStartCount_;
1917 }
1918 
ResetRestartTasks()1919 void PerUserSession::ResetRestartTasks()
1920 {
1921     std::lock_guard<std::mutex> lock(restartMutex_);
1922     restartTasks_ = 0;
1923 }
1924 
RestartIme()1925 bool PerUserSession::RestartIme()
1926 {
1927     static int32_t delayTime = 0;
1928     IMSA_HILOGD("enter");
1929     auto task = [this]() {
1930         // When the attach conflict with the first scb startup event, discard the first scb startup event.
1931         if (GetAttachCount() != 0 && GetScbStartCount() <= 1) {
1932             IMSA_HILOGI("attach conflict with the first scb startup event, discard the first scb startup event");
1933             ResetRestartTasks();
1934             return;
1935         }
1936         if (!IsAttachFinished()) {
1937             delayTime = WAIT_ATTACH_FINISH_DELAY;
1938             RestartIme();
1939             return;
1940         }
1941         delayTime = 0;
1942         if (CanStartIme()) {
1943             IMSA_HILOGI("start ime");
1944             ResetRestartTasks();
1945             auto ret = StartCurrentIme(true);
1946             if (ret != ErrorCode::NO_ERROR) {
1947                 IMSA_HILOGE("start ime failed:%{public}d", ret);
1948             }
1949         }
1950         IMSA_HILOGD("restart again");
1951         int32_t tasks = 0;
1952         {
1953             std::lock_guard<std::mutex> lock(restartMutex_);
1954             tasks = --restartTasks_;
1955         }
1956         if (tasks > 0 && !RestartIme()) {
1957             ResetRestartTasks();
1958         }
1959     };
1960     if (eventHandler_ == nullptr) {
1961         IMSA_HILOGE("eventHandler_ is nullptr!");
1962         return false;
1963     }
1964     return eventHandler_->PostTask(
1965         task, "RestartCurrentImeTask", delayTime, AppExecFwk::EventQueue::Priority::IMMEDIATE);
1966 }
1967 
GetSwitchQueue()1968 BlockQueue<SwitchInfo>& PerUserSession::GetSwitchQueue()
1969 {
1970     return switchQueue_;
1971 }
1972 
InitImeData(const std::pair<std::string,std::string> & ime,const std::shared_ptr<ImeNativeCfg> & imeNativeCfg)1973 int32_t PerUserSession::InitImeData(
1974     const std::pair<std::string, std::string> &ime, const std::shared_ptr<ImeNativeCfg> &imeNativeCfg)
1975 {
1976     std::lock_guard<std::mutex> lock(imeDataLock_);
1977     auto it = imeData_.find(ImeType::IME);
1978     if (it != imeData_.end()) {
1979         return ErrorCode::NO_ERROR;
1980     }
1981     auto imeData = std::make_shared<ImeData>(nullptr, nullptr, nullptr, -1);
1982     imeData->startTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1983     imeData->ime = ime;
1984     imeData->imeStateManager = ImeStateManagerFactory::GetInstance().CreateImeStateManager(-1, [this] {
1985         StopCurrentIme();
1986     });
1987     if (imeNativeCfg != nullptr && !imeNativeCfg->imeExtendInfo.privateCommand.empty()) {
1988         imeData->imeExtendInfo.privateCommand = imeNativeCfg->imeExtendInfo.privateCommand;
1989     }
1990     imeData_.insert_or_assign(ImeType::IME, std::vector<std::shared_ptr<ImeData>>{imeData});
1991     return ErrorCode::NO_ERROR;
1992 }
1993 
UpdateImeData(sptr<IInputMethodCore> core,sptr<IRemoteObject> agent,pid_t pid)1994 int32_t PerUserSession::UpdateImeData(sptr<IInputMethodCore> core, sptr<IRemoteObject> agent, pid_t pid)
1995 {
1996     if (core == nullptr || agent == nullptr) {
1997         IMSA_HILOGE("core or agent is nullptr!");
1998         return ErrorCode::ERROR_NULL_POINTER;
1999     }
2000     std::lock_guard<std::mutex> lock(imeDataLock_);
2001     auto it = imeData_.find(ImeType::IME);
2002     if (it == imeData_.end()) {
2003         return ErrorCode::ERROR_NULL_POINTER;
2004     }
2005     auto &dataList = it->second;
2006     if (dataList.empty() || dataList.back() == nullptr) {
2007         return ErrorCode::ERROR_NULL_POINTER;
2008     }
2009     dataList.back()->core = core;
2010     dataList.back()->agent = agent;
2011     dataList.back()->pid = pid;
2012     dataList.back()->imeStateManager = ImeStateManagerFactory::GetInstance().CreateImeStateManager(pid, [this] {
2013         StopCurrentIme();
2014     });
2015     sptr<InputDeathRecipient> deathRecipient = new (std::nothrow) InputDeathRecipient();
2016     if (deathRecipient == nullptr) {
2017         IMSA_HILOGE("failed to new deathRecipient!");
2018         return ErrorCode::ERROR_NULL_POINTER;
2019     }
2020     auto type = ImeType::IME;
2021     deathRecipient->SetDeathRecipient(
2022         [this, core, type, pid](const wptr<IRemoteObject> &) { this->OnImeDied(core, type, pid); });
2023     auto coreObject = core->AsObject();
2024     if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) {
2025         IMSA_HILOGE("failed to add death recipient!");
2026         return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED;
2027     }
2028     dataList.back()->deathRecipient = deathRecipient;
2029     return ErrorCode::NO_ERROR;
2030 }
2031 
InitConnect(pid_t pid)2032 int32_t PerUserSession::InitConnect(pid_t pid)
2033 {
2034     std::lock_guard<std::mutex> lock(imeDataLock_);
2035     auto it = imeData_.find(ImeType::IME);
2036     if (it == imeData_.end()) {
2037         return ErrorCode::ERROR_NULL_POINTER;
2038     }
2039     auto &dataList = it->second;
2040     if (dataList.empty() || dataList.back() == nullptr) {
2041         return ErrorCode::ERROR_NULL_POINTER;
2042     }
2043     dataList.back()->pid = pid;
2044     return ErrorCode::NO_ERROR;
2045 }
2046 
GetImeData(ImeType type)2047 std::shared_ptr<ImeData> PerUserSession::GetImeData(ImeType type)
2048 {
2049     std::lock_guard<std::mutex> lock(imeDataLock_);
2050     auto it = imeData_.find(type);
2051     if (it == imeData_.end()) {
2052         return nullptr;
2053     }
2054     auto &dataList = it->second;
2055     if (dataList.empty() || dataList.back() == nullptr) {
2056         return nullptr;
2057     }
2058     return dataList.back();
2059 }
2060 
GetImeData(pid_t pid)2061 std::shared_ptr<ImeData> PerUserSession::GetImeData(pid_t pid)
2062 {
2063     std::lock_guard<std::mutex> lock(imeDataLock_);
2064     for (const auto &[imeType, imeDataList] : imeData_) {
2065         auto iter =
2066             std::find_if(imeDataList.begin(), imeDataList.end(), [pid](const std::shared_ptr<ImeData> &imeDataTmp) {
2067                 return imeDataTmp != nullptr && imeDataTmp->pid == pid;
2068             });
2069         if (iter != imeDataList.end()) {
2070             return *iter;
2071         }
2072     }
2073     return nullptr;
2074 }
2075 
StartIme(const std::shared_ptr<ImeNativeCfg> & ime,bool isStopCurrentIme)2076 int32_t PerUserSession::StartIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme)
2077 {
2078     std::unique_lock<std::mutex> lock(imeStartLock_, std::defer_lock);
2079     if (!lock.try_lock()) {
2080         IMSA_HILOGW("try failed");
2081         return ErrorCode::ERROR_IME_START_INPUT_FAILED;
2082     }
2083     if (ime == nullptr) {
2084         return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR;
2085     }
2086     auto imeData = GetImeData(ImeType::IME);
2087     if (imeData == nullptr) {
2088         return HandleFirstStart(ime, isStopCurrentIme);
2089     }
2090     if (imeData->ime.first == ime->bundleName && imeData->ime.second == ime->extName) {
2091         if (isStopCurrentIme) {
2092             return StartNewIme(ime);
2093         }
2094         return StartCurrentIme(ime);
2095     }
2096     IMSA_HILOGD("%{public}s switch to %{public}s!", imeData->ime.first.c_str(), ime->bundleName.c_str());
2097     return StartNewIme(ime);
2098 }
2099 
GetImeAction(ImeEvent action)2100 ImeAction PerUserSession::GetImeAction(ImeEvent action)
2101 {
2102     std::lock_guard<std::mutex> lock(imeDataLock_);
2103     auto it = imeData_.find(ImeType::IME);
2104     if (it == imeData_.end()) {
2105         return ImeAction::DO_ACTION_IN_NULL_IME_DATA;
2106     }
2107     auto &dataList = it->second;
2108     if (dataList.empty() || dataList.back() == nullptr) {
2109         return ImeAction::DO_ACTION_IN_NULL_IME_DATA;
2110     }
2111     auto iter = imeEventConverter_.find({ dataList.back()->imeStatus, action });
2112     if (iter == imeEventConverter_.end()) {
2113         IMSA_HILOGE("abnormal!");
2114         return ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED;
2115     }
2116     dataList.back()->imeStatus = iter->second.first;
2117     return iter->second.second;
2118 }
2119 
StartCurrentIme(const std::shared_ptr<ImeNativeCfg> & ime)2120 int32_t PerUserSession::StartCurrentIme(const std::shared_ptr<ImeNativeCfg> &ime)
2121 {
2122     auto imeData = GetImeData(ImeType::IME);
2123     if (imeData == nullptr) {
2124         return StartInputService(ime);
2125     }
2126     auto action = GetImeAction(ImeEvent::START_IME);
2127     if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
2128         return ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
2129     }
2130     if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
2131         return StartInputService(ime);
2132     }
2133     if (action == ImeAction::DO_NOTHING) {
2134         return ErrorCode::NO_ERROR;
2135     }
2136     if (action == ImeAction::HANDLE_STARTING_IME) {
2137         int64_t time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
2138         if (time - imeData->startTime > ImeData::START_TIME_OUT) {
2139             IMSA_HILOGE("[%{public}s, %{public}s] start abnormal, more than eight second!", imeData->ime.first.c_str(),
2140                 imeData->ime.second.c_str());
2141             return HandleStartImeTimeout(ime);
2142         }
2143         IMSA_HILOGW("%{public}s/%{public}s start retry!", imeData->ime.first.c_str(), imeData->ime.second.c_str());
2144         return StartInputService(ime);
2145     }
2146     IMSA_HILOGW("%{public}s/%{public}s start in exiting, force stop firstly!", imeData->ime.first.c_str(),
2147         imeData->ime.second.c_str());
2148     auto ret = ForceStopCurrentIme();
2149     if (ret != ErrorCode::NO_ERROR) {
2150         return ret;
2151     }
2152     return StartInputService(ime);
2153 }
2154 
HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> & ime)2155 int32_t PerUserSession::HandleStartImeTimeout(const std::shared_ptr<ImeNativeCfg> &ime)
2156 {
2157     auto action = GetImeAction(ImeEvent::START_IME_TIMEOUT);
2158     if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
2159         return StartInputService(ime);
2160     }
2161     if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
2162         return ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
2163     }
2164     if (action == ImeAction::DO_NOTHING) {
2165         IMSA_HILOGW("ready when timeout");
2166         return ErrorCode::NO_ERROR;
2167     }
2168     auto ret = ForceStopCurrentIme(false);
2169     if (ret != ErrorCode::NO_ERROR) {
2170         return ret;
2171     }
2172     return StartInputService(ime);
2173 }
2174 
StartNewIme(const std::shared_ptr<ImeNativeCfg> & ime)2175 int32_t PerUserSession::StartNewIme(const std::shared_ptr<ImeNativeCfg> &ime)
2176 {
2177     auto ret = StopCurrentIme();
2178     if (ret != ErrorCode::NO_ERROR) {
2179         return ret;
2180     }
2181     return StartInputService(ime);
2182 }
2183 
StopCurrentIme()2184 int32_t PerUserSession::StopCurrentIme()
2185 {
2186     IMSA_HILOGD("enter");
2187     auto action = GetImeAction(ImeEvent::STOP_IME);
2188     if (action == ImeAction::DO_ACTION_IN_NULL_IME_DATA) {
2189         return ErrorCode::NO_ERROR;
2190     }
2191     if (action == ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED) {
2192         return  ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED;
2193     }
2194     if (action == ImeAction::STOP_READY_IME) {
2195         return StopReadyCurrentIme();
2196     }
2197     return ForceStopCurrentIme();
2198 }
2199 
StopReadyCurrentIme()2200 int32_t PerUserSession::StopReadyCurrentIme()
2201 {
2202     auto clientInfo = GetCurrentClientInfo();
2203     if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
2204         StopClientInput(clientInfo);
2205     }
2206     auto imeData = GetImeData(ImeType::IME);
2207     if (imeData == nullptr) {
2208         return ErrorCode::NO_ERROR;
2209     }
2210     if (imeData->core == nullptr) {
2211         IMSA_HILOGE("core is nullptr!");
2212         return ForceStopCurrentIme();
2213     }
2214     auto ret = RequestAllIme(imeData, RequestType::NORMAL, [](const sptr<IInputMethodCore> &core) {
2215         // failed when register onInputStop after SetCoreAndAgent
2216         return core->StopInputService(true);
2217     });
2218     if (ret != ErrorCode::NO_ERROR) {
2219         IMSA_HILOGE("StopInputService failed.");
2220         return ForceStopCurrentIme();
2221     }
2222     if (!WaitForCurrentImeStop()) {
2223         IMSA_HILOGI("stop timeout.");
2224         return ForceStopCurrentIme();
2225     }
2226     return ErrorCode::NO_ERROR;
2227 }
2228 
ForceStopCurrentIme(bool isNeedWait)2229 int32_t PerUserSession::ForceStopCurrentIme(bool isNeedWait)
2230 {
2231     auto imeData = GetImeData(ImeType::IME);
2232     if (imeData == nullptr) {
2233         return ErrorCode::NO_ERROR;
2234     }
2235     if (!ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) {
2236         IMSA_HILOGW("[%{public}s, %{public}s] already stop.", imeData->ime.first.c_str(), imeData->ime.second.c_str());
2237         RemoveImeData(ImeType::IME);
2238         return ErrorCode::NO_ERROR;
2239     }
2240     auto clientInfo = GetCurrentClientInfo();
2241     if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
2242         StopClientInput(clientInfo);
2243     }
2244 
2245     AAFwk::Want want;
2246     want.SetElementName(imeData->ime.first, imeData->ime.second);
2247     auto ret = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(
2248         want, nullptr, userId_, AppExecFwk::ExtensionAbilityType::INPUTMETHOD);
2249     if (ret != ErrorCode::NO_ERROR) {
2250         IMSA_HILOGE("StopExtensionAbility [%{public}s, %{public}s] failed, ret: %{public}d!",
2251             imeData->ime.first.c_str(), imeData->ime.second.c_str(), ret);
2252         return ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED;
2253     }
2254     if (!isNeedWait) {
2255         return ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND;
2256     }
2257     WaitForCurrentImeStop();
2258     if (ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) {
2259         IMSA_HILOGW("stop [%{public}s, %{public}s] timeout.", imeData->ime.first.c_str(), imeData->ime.second.c_str());
2260         return ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT;
2261     }
2262     RemoveImeData(ImeType::IME);
2263     return ErrorCode::NO_ERROR;
2264 }
2265 
HandleFirstStart(const std::shared_ptr<ImeNativeCfg> & ime,bool isStopCurrentIme)2266 int32_t PerUserSession::HandleFirstStart(const std::shared_ptr<ImeNativeCfg> &ime, bool isStopCurrentIme)
2267 {
2268     if (runningIme_.empty()) {
2269         return StartInputService(ime);
2270     }
2271     IMSA_HILOGW("imsa abnormal restore.");
2272     if (isStopCurrentIme) {
2273         return ErrorCode::NO_ERROR;
2274     }
2275     if (BlockRetry(CHECK_IME_RUNNING_RETRY_INTERVAL, CHECK_IME_RUNNING_RETRY_TIMES,
2276                    [this]() -> bool { return !ImeInfoInquirer::GetInstance().IsRunningIme(userId_, runningIme_); })) {
2277         IMSA_HILOGI("[%{public}d, %{public}s] stop completely", userId_, runningIme_.c_str());
2278         runningIme_.clear();
2279         return StartInputService(ime);
2280     }
2281     IMSA_HILOGW("[%{public}d, %{public}s] stop timeout", userId_, runningIme_.c_str());
2282     return ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP;
2283 }
2284 
StartUserSpecifiedIme(uint64_t callingDisplayId)2285 int32_t PerUserSession::StartUserSpecifiedIme(uint64_t callingDisplayId)
2286 {
2287     InputMethodSyncTrace tracer("StartUserSpecifiedIme trace.");
2288     if (!IsDefaultDisplayGroup(callingDisplayId)) {
2289         IMSA_HILOGI("only need restore in default display, calling display: %{public}" PRIu64 "", callingDisplayId);
2290         return ErrorCode::NO_ERROR;
2291     }
2292     InputTypeManager::GetInstance().Set(false);
2293     auto cfgIme = ImeInfoInquirer::GetInstance().GetImeToStart(userId_);
2294     auto imeData = GetReadyImeData(ImeType::IME);
2295     if (imeData != nullptr && cfgIme != nullptr && imeData->ime.first == cfgIme->bundleName
2296         && imeData->ime.second == cfgIme->extName) {
2297         return ErrorCode::NO_ERROR;
2298     }
2299     IMSA_HILOGD("need restore!");
2300     auto ret = StartIme(cfgIme);
2301     if (ret != ErrorCode::NO_ERROR) {
2302         IMSA_HILOGE("start ime failed!");
2303         return ret;
2304     }
2305     NotifyImeChangedToClients();
2306     cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
2307     if (cfgIme != nullptr) {
2308         NotifySubTypeChangedToIme(cfgIme->bundleName, cfgIme->subName);
2309     }
2310     return ErrorCode::NO_ERROR;
2311 }
2312 
CheckPwdInputPatternConv(InputClientInfo & clientInfo,uint64_t displayId)2313 bool PerUserSession::CheckPwdInputPatternConv(InputClientInfo &clientInfo, uint64_t displayId)
2314 {
2315     auto clientGroup = GetClientGroup(displayId);
2316     if (clientGroup == nullptr) {
2317         IMSA_HILOGD("clientGroup not found");
2318         return false;
2319     }
2320     auto exClient = clientGroup->GetCurrentClient();
2321     if (exClient == nullptr) {
2322         exClient = clientGroup->GetInactiveClient();
2323     }
2324     auto exClientInfo = exClient != nullptr ? clientGroup->GetClientInfo(exClient->AsObject()) : nullptr;
2325     if (exClientInfo == nullptr) {
2326         IMSA_HILOGE("exClientInfo is nullptr!");
2327         return false;
2328     }
2329     // if current input pattern differ from previous in pwd and normal, need hide panel first.
2330     if (clientInfo.config.inputAttribute.GetSecurityFlag()) {
2331         IMSA_HILOGI("new input pattern is pwd.");
2332         return !exClientInfo->config.inputAttribute.GetSecurityFlag();
2333     }
2334     IMSA_HILOGI("new input pattern is normal.");
2335     return exClientInfo->config.inputAttribute.GetSecurityFlag();
2336 }
2337 
GetImeNativeCfg(int32_t userId,const std::string & bundleName,const std::string & subName)2338 std::shared_ptr<ImeNativeCfg> PerUserSession::GetImeNativeCfg(int32_t userId, const std::string &bundleName,
2339     const std::string &subName)
2340 {
2341     auto targetImeProperty = ImeInfoInquirer::GetInstance().GetImeProperty(userId, bundleName);
2342     if (targetImeProperty == nullptr) {
2343         IMSA_HILOGE("GetImeProperty [%{public}d, %{public}s] failed!", userId, bundleName.c_str());
2344         return nullptr;
2345     }
2346     std::string targetName = bundleName + "/" + targetImeProperty->id;
2347     ImeNativeCfg targetIme = { targetName, bundleName, subName, targetImeProperty->id };
2348     return std::make_shared<ImeNativeCfg>(targetIme);
2349 }
2350 
GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> & imeToStart)2351 bool PerUserSession::GetInputTypeToStart(std::shared_ptr<ImeNativeCfg> &imeToStart)
2352 {
2353     if (!InputTypeManager::GetInstance().IsStarted()) {
2354         return false;
2355     }
2356     auto currentInputTypeIme = InputTypeManager::GetInstance().GetCurrentIme();
2357     if (currentInputTypeIme.bundleName.empty()) {
2358         auto currentInputType = InputTypeManager::GetInstance().GetCurrentInputType();
2359         InputTypeManager::GetInstance().GetImeByInputType(currentInputType, currentInputTypeIme);
2360     }
2361     imeToStart = GetImeNativeCfg(userId_, currentInputTypeIme.bundleName, currentInputTypeIme.subName);
2362     return true;
2363 }
2364 
HandleBindImeChanged(InputClientInfo & newClientInfo,const std::shared_ptr<ClientGroup> & clientGroup)2365 void PerUserSession::HandleBindImeChanged(
2366     InputClientInfo &newClientInfo, const std::shared_ptr<ClientGroup> &clientGroup)
2367 {
2368     /* isClientInactive: true: represent the oldClientInfo is inactiveClient's
2369                          false: represent the oldClientInfo is currentClient's */
2370     std::shared_ptr<InputClientInfo> oldClientInfo = nullptr;
2371     if (clientGroup == nullptr) {
2372         IMSA_HILOGE("clientGroup is nullptr!");
2373         return;
2374     }
2375     bool isClientInactive = false;
2376     {
2377         std::lock_guard<std::mutex> lock(focusedClientLock_);
2378         oldClientInfo = clientGroup->GetCurrentClientInfo();
2379         if (oldClientInfo == nullptr) {
2380             auto inactiveClient = clientGroup->GetInactiveClient();
2381             if (inactiveClient != nullptr) {
2382                 oldClientInfo = clientGroup->GetClientInfo(inactiveClient->AsObject());
2383                 isClientInactive = true;
2384             }
2385         }
2386         if (oldClientInfo == nullptr) {
2387             return;
2388         }
2389         if (IsSameClient(newClientInfo.client, oldClientInfo->client) &&
2390             newClientInfo.bindImePid != oldClientInfo->bindImePid) {
2391             newClientInfo.isNotifyInputStart = true;
2392         }
2393         if (!IsImeBindTypeChanged(oldClientInfo->bindImeType)) {
2394             return;
2395         }
2396         // has current client, but new client is not current client
2397         if (!isClientInactive && !IsSameClient(newClientInfo.client, oldClientInfo->client)) {
2398             clientGroup->SetCurrentClient(nullptr);
2399             if (oldClientInfo->client != nullptr) {
2400                 clientGroup->RemoveClientInfo(oldClientInfo->client->AsObject());
2401             }
2402         }
2403     }
2404     IMSA_HILOGD("isClientInactive: %{public}d!", isClientInactive);
2405     if (isClientInactive) {
2406         StopImeInput(oldClientInfo->bindImeType, oldClientInfo->channel, 0);
2407         return;
2408     }
2409     UnBindClientWithIme(oldClientInfo, { .sessionId = 0 });
2410 }
2411 
TryUnloadSystemAbility()2412 void PerUserSession::TryUnloadSystemAbility()
2413 {
2414     auto data = GetReadyImeData(ImeType::IME);
2415     if (data != nullptr && data->imeStateManager != nullptr) {
2416         if (data->imeStateManager->IsImeInUse()) {
2417             return;
2418         }
2419     }
2420 
2421     auto onDemandStartStopSa = std::make_shared<OnDemandStartStopSa>();
2422     onDemandStartStopSa->UnloadInputMethodSystemAbility();
2423 }
2424 
GetDisplayGroupId(uint64_t displayId)2425 uint64_t PerUserSession::GetDisplayGroupId(uint64_t displayId)
2426 {
2427     std::lock_guard<std::mutex> lock(virtualDisplayLock_);
2428     IMSA_HILOGD("displayId: %{public}" PRIu64 "", displayId);
2429     if (displayId == DEFAULT_DISPLAY_ID || virtualScreenDisplayId_.empty()) {
2430         return DEFAULT_DISPLAY_ID;
2431     }
2432     if (virtualScreenDisplayId_.find(displayId) != virtualScreenDisplayId_.end()) {
2433         return displayId;
2434     }
2435     return DEFAULT_DISPLAY_ID;
2436 }
2437 
GetClientGroup(uint64_t displayId)2438 std::shared_ptr<ClientGroup> PerUserSession::GetClientGroup(uint64_t displayId)
2439 {
2440     uint64_t displayGroupId = GetDisplayGroupId(displayId);
2441     std::lock_guard<std::mutex> lock(clientGroupLock_);
2442     auto iter = clientGroupMap_.find(displayGroupId);
2443     if (iter == clientGroupMap_.end()) {
2444         IMSA_HILOGD("not found client group with displayId: %{public}" PRIu64 "", displayId);
2445         return nullptr;
2446     }
2447     return iter->second;
2448 }
2449 
GetClientGroup(sptr<IRemoteObject> client)2450 std::shared_ptr<ClientGroup> PerUserSession::GetClientGroup(sptr<IRemoteObject> client)
2451 {
2452     if (client == nullptr) {
2453         IMSA_HILOGE("client is nullptr");
2454         return nullptr;
2455     }
2456     std::lock_guard<std::mutex> lock(clientGroupLock_);
2457     auto iter = std::find_if(clientGroupMap_.begin(), clientGroupMap_.end(), [client](const auto &clientGroup) {
2458         if (clientGroup.second == nullptr) {
2459             return false;
2460         }
2461         return clientGroup.second->IsClientExist(client);
2462     });
2463     if (iter == clientGroupMap_.end()) {
2464         IMSA_HILOGD("not found");
2465         return nullptr;
2466     }
2467     return iter->second;
2468 }
2469 
GetClientGroup(ImeType type)2470 std::shared_ptr<ClientGroup> PerUserSession::GetClientGroup(ImeType type)
2471 {
2472     if (type == ImeType::IME || type == ImeType::PROXY_IME || type == ImeType::IME_MIRROR) {
2473         return GetClientGroup(DEFAULT_DISPLAY_ID);
2474     }
2475     auto agentDisplayId = agentDisplayId_.load();
2476     if (type == ImeType::PROXY_AGENT_IME && agentDisplayId != DEFAULT_DISPLAY_ID) {
2477         return GetClientGroup(agentDisplayId);
2478     }
2479     IMSA_HILOGE("invalid ime type: %{public}d", static_cast<int32_t>(type));
2480     return nullptr;
2481 }
2482 
GetImeType(uint64_t displayId)2483 ImeType PerUserSession::GetImeType(uint64_t displayId)
2484 {
2485     displayId = GetDisplayGroupId(displayId);
2486     if (displayId == DEFAULT_DISPLAY_ID) {
2487         return ImeType::IME;
2488     }
2489     if (displayId == agentDisplayId_.load()) {
2490         return ImeType::PROXY_AGENT_IME;
2491     }
2492     return ImeType::NONE;
2493 }
2494 
OnCallingDisplayIdChanged(const int32_t windowId,const int32_t callingPid,const uint64_t displayId)2495 void PerUserSession::OnCallingDisplayIdChanged(
2496     const int32_t windowId, const int32_t callingPid, const uint64_t displayId)
2497 {
2498     IMSA_HILOGD("enter!windowId:%{public}d,callingPid:%{public}d,displayId:%{public}" PRIu64 "", windowId,
2499         callingPid, displayId);
2500     auto clientGroup = GetClientGroup(displayId);
2501     if (clientGroup == nullptr) {
2502         IMSA_HILOGD("client group not found");
2503         return;
2504     }
2505     auto clientInfo = clientGroup->GetCurrentClientInfo();
2506     if (clientInfo == nullptr) {
2507         IMSA_HILOGD("clientInfo is null");
2508         return;
2509     }
2510     IMSA_HILOGD("userId:%{public}d, windowId:%{public}d", userId_, clientInfo->config.windowId);
2511     if (clientInfo->config.windowId != static_cast<uint32_t>(windowId)) {
2512         return;
2513     }
2514     uint64_t curDisplay = clientInfo->config.inputAttribute.callingDisplayId;
2515     if (curDisplay == displayId) {
2516         return;
2517     }
2518     clientInfo->config.inputAttribute.callingDisplayId = displayId;
2519     NotifyCallingDisplayChanged(displayId);
2520 }
2521 
NotifyCallingDisplayChanged(uint64_t displayId)2522 int32_t PerUserSession::NotifyCallingDisplayChanged(uint64_t displayId)
2523 {
2524     IMSA_HILOGD("enter displayId:%{public}" PRIu64 "", displayId);
2525     if (GetImeType(displayId) != ImeType::IME) {
2526         IMSA_HILOGD("not default display");
2527         return ErrorCode::NO_ERROR;
2528     }
2529     auto data = GetReadyImeData(ImeType::IME);
2530     if (data == nullptr) {
2531         IMSA_HILOGE("ime is nullptr!");
2532         return ErrorCode::ERROR_IME_NOT_STARTED;
2533     }
2534     auto callBack = [&data, displayId]() -> int32_t {
2535         data->core->OnCallingDisplayIdChanged(displayId);
2536         return ErrorCode::NO_ERROR;
2537     };
2538     auto ret = RequestIme(data, RequestType::NORMAL, callBack);
2539     if (ret != ErrorCode::NO_ERROR) {
2540         IMSA_HILOGE("notify calling window display changed failed, ret: %{public}d!", ret);
2541     }
2542     return ret;
2543 }
2544 
GetCallingWindowInfo(const InputClientInfo & clientInfo)2545 ImfCallingWindowInfo PerUserSession::GetCallingWindowInfo(const InputClientInfo &clientInfo)
2546 {
2547     InputMethodSyncTrace tracer("GetCallingWindowInfo trace");
2548     auto finalWindowId = clientInfo.config.windowId;
2549     ImfCallingWindowInfo finalWindowInfo{ finalWindowId, 0 };
2550     if (!SceneBoardJudgement::IsSceneBoardEnabled()) {
2551         return finalWindowInfo;
2552     }
2553     CallingWindowInfo callingWindowInfo;
2554     if (GetCallingWindowInfo(clientInfo, callingWindowInfo)) {
2555         finalWindowInfo.displayId = callingWindowInfo.displayId_;
2556         return finalWindowInfo;
2557     }
2558     FocusChangeInfo focusInfo;
2559     WindowAdapter::GetFocusInfo(focusInfo);
2560     if (!WindowAdapter::GetCallingWindowInfo(focusInfo.windowId_, userId_, callingWindowInfo)) {
2561         IMSA_HILOGE("GetCallingWindowInfo error!");
2562         return finalWindowInfo;
2563     }
2564     if (finalWindowId == INVALID_WINDOW_ID) {
2565         finalWindowId = static_cast<uint32_t>(focusInfo.windowId_);
2566     }
2567     return { finalWindowId, callingWindowInfo.displayId_ };
2568 }
2569 
GetCallingWindowInfo(const InputClientInfo & clientInfo,CallingWindowInfo & callingWindowInfo)2570 bool PerUserSession::GetCallingWindowInfo(const InputClientInfo &clientInfo, CallingWindowInfo &callingWindowInfo)
2571 {
2572     auto windowId = clientInfo.config.windowId;
2573     if (windowId == INVALID_WINDOW_ID) {
2574         return false;
2575     }
2576     return WindowAdapter::GetCallingWindowInfo(windowId, userId_, callingWindowInfo);
2577 }
2578 
IsDefaultDisplayGroup(uint64_t displayId)2579 bool PerUserSession::IsDefaultDisplayGroup(uint64_t displayId)
2580 {
2581     return GetDisplayGroupId(displayId) == DEFAULT_DISPLAY_ID;
2582 }
2583 
SpecialScenarioCheck()2584 bool PerUserSession::SpecialScenarioCheck()
2585 {
2586     auto clientInfo = GetCurrentClientInfo();
2587     if (clientInfo == nullptr) {
2588         IMSA_HILOGE("send failed, not input Status!");
2589         return false;
2590     }
2591     if (clientInfo->config.isSimpleKeyboardEnabled) {
2592         IMSA_HILOGE("send failed, is simple keyboard!");
2593         return false;
2594     }
2595     if (clientInfo->config.inputAttribute.IsSecurityImeFlag() ||
2596         clientInfo->config.inputAttribute.IsOneTimeCodeFlag()) {
2597         IMSA_HILOGE("send failed, is special input box!");
2598         return false;
2599     }
2600     if (clientInfo->bindImeType == ImeType::PROXY_IME) {
2601         IMSA_HILOGE("send failed, is collaborative input!");
2602         return false;
2603     }
2604     if (ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked()) {
2605         IMSA_HILOGE("send failed, is screen locked");
2606         return false;
2607     }
2608     return true;
2609 }
2610 
GetCurrentInputPattern()2611 std::pair<int32_t, int32_t> PerUserSession::GetCurrentInputPattern()
2612 {
2613     auto clientInfo = GetCurrentClientInfo();
2614     if (clientInfo == nullptr) {
2615         IMSA_HILOGE("clientInfo is nullptr!");
2616         return { ErrorCode::ERROR_NULL_POINTER, static_cast<int32_t>(InputType::NONE) };
2617     }
2618     return { ErrorCode::NO_ERROR, clientInfo->config.inputAttribute.inputPattern };
2619 }
2620 
SpecialSendPrivateData(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)2621 int32_t PerUserSession::SpecialSendPrivateData(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
2622 {
2623     ImeExtendInfo imeExtendInfo;
2624     imeExtendInfo.privateCommand = privateCommand;
2625     auto [ret, status] = StartPreconfiguredDefaultIme(DEFAULT_DISPLAY_ID, imeExtendInfo, true);
2626     if (ret != ErrorCode::NO_ERROR) {
2627         IMSA_HILOGE("start pre default ime failed, ret: %{public}d!", ret);
2628         return ret;
2629     }
2630     if (status == StartPreDefaultImeStatus::NO_NEED || status == StartPreDefaultImeStatus::TO_START) {
2631         return ret;
2632     }
2633     ret = SendPrivateData(privateCommand);
2634     if (ret != ErrorCode::NO_ERROR) {
2635         IMSA_HILOGE("Notify send private data failed, ret: %{public}d!", ret);
2636     }
2637     return ret;
2638 }
2639 
SendPrivateData(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)2640 int32_t PerUserSession::SendPrivateData(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
2641 {
2642     auto data = GetReadyImeData(ImeType::IME);
2643     if (data == nullptr) {
2644         IMSA_HILOGE("data is nullptr");
2645         return ErrorCode::ERROR_IME_NOT_STARTED;
2646     }
2647     auto ret = RequestIme(data, RequestType::NORMAL, [&data, &privateCommand] {
2648         Value value(privateCommand);
2649         return data->core->OnSendPrivateData(value);
2650     });
2651     if (!data->imeExtendInfo.privateCommand.empty()) {
2652         data->imeExtendInfo.privateCommand.clear();
2653     }
2654     if (ret != ErrorCode::NO_ERROR) {
2655         IMSA_HILOGE("notify send private data failed, ret: %{public}d!", ret);
2656         return ret;
2657     }
2658     IMSA_HILOGI("notify send private data success.");
2659     return ret;
2660 }
2661 
ClearRequestKeyboardReason(std::shared_ptr<InputClientInfo> & clientInfo)2662 void PerUserSession::ClearRequestKeyboardReason(std::shared_ptr<InputClientInfo> &clientInfo)
2663 {
2664     if (clientInfo == nullptr) {
2665         IMSA_HILOGE("clientGroup is nullptr!");
2666         return;
2667     }
2668     clientInfo->requestKeyboardReason = RequestKeyboardReason::NONE;
2669 }
2670 
IsNumkeyAutoInputApp(const std::string & bundleName)2671 bool PerUserSession::IsNumkeyAutoInputApp(const std::string &bundleName)
2672 {
2673     return NumkeyAppsManager::GetInstance().NeedAutoNumKeyInput(userId_, bundleName);
2674 }
2675 
NotifyOnInputStopFinished()2676 void PerUserSession::NotifyOnInputStopFinished()
2677 {
2678     isNotifyFinished_.SetValue(true);
2679 }
2680 
IsPreconfiguredDefaultImeSpecified(const InputClientInfo & inputClientInfo)2681 bool PerUserSession::IsPreconfiguredDefaultImeSpecified(const InputClientInfo &inputClientInfo)
2682 {
2683     auto callingWindowInfo = GetCallingWindowInfo(inputClientInfo);
2684     return ImeInfoInquirer::GetInstance().IsRestrictedDefaultImeByDisplay(callingWindowInfo.displayId) ||
2685         inputClientInfo.config.isSimpleKeyboardEnabled || inputClientInfo.config.inputAttribute.IsOneTimeCodeFlag();
2686 }
2687 
GetImeUsedBeforeScreenLocked()2688 std::pair<std::string, std::string> PerUserSession::GetImeUsedBeforeScreenLocked()
2689 {
2690     std::lock_guard<std::mutex> lock(imeUsedLock_);
2691     return imeUsedBeforeScreenLocked_;
2692 }
2693 
SetImeUsedBeforeScreenLocked(const std::pair<std::string,std::string> & ime)2694 void PerUserSession::SetImeUsedBeforeScreenLocked(const std::pair<std::string, std::string> &ime)
2695 {
2696     std::lock_guard<std::mutex> lock(imeUsedLock_);
2697     imeUsedBeforeScreenLocked_ = ime;
2698 }
2699 
IsImeSwitchForbidden()2700 bool PerUserSession::IsImeSwitchForbidden()
2701 {
2702 #ifdef IMF_SCREENLOCK_MGR_ENABLE
2703     auto screenLockMgr = ScreenLock::ScreenLockManager::GetInstance();
2704     if (screenLockMgr != nullptr && screenLockMgr->IsScreenLocked()) {
2705         return true;
2706     }
2707 #endif
2708     auto clientInfo = GetCurrentClientInfo();
2709     if (clientInfo == nullptr) {
2710         return false;
2711     }
2712 
2713     bool isSimpleKeyboard = (clientInfo->config.inputAttribute.IsSecurityImeFlag() ||
2714                                 clientInfo->config.inputAttribute.IsOneTimeCodeFlag()) ?
2715         false :
2716         clientInfo->config.isSimpleKeyboardEnabled;
2717 
2718     auto callingWindowInfo = GetCallingWindowInfo(*clientInfo);
2719     return ImeInfoInquirer::GetInstance().IsRestrictedDefaultImeByDisplay(callingWindowInfo.displayId) ||
2720         clientInfo->config.inputAttribute.IsSecurityImeFlag() || isSimpleKeyboard;
2721 }
2722 
StartPreconfiguredDefaultIme(uint64_t callingDisplayId,const ImeExtendInfo & imeExtendInfo,bool isStopCurrentIme)2723 std::pair<int32_t, StartPreDefaultImeStatus> PerUserSession::StartPreconfiguredDefaultIme(
2724     uint64_t callingDisplayId, const ImeExtendInfo &imeExtendInfo, bool isStopCurrentIme)
2725 {
2726     if (!IsDefaultDisplayGroup(callingDisplayId)) {
2727         IMSA_HILOGI("only start in default display, calling display: %{public}" PRIu64 "", callingDisplayId);
2728         return std::make_pair(ErrorCode::NO_ERROR, StartPreDefaultImeStatus::NO_NEED);
2729     }
2730     InputTypeManager::GetInstance().Set(false);
2731     auto preDefaultIme = ImeInfoInquirer::GetInstance().GetDefaultIme();
2732     auto ime = GetReadyImeData(ImeType::IME);
2733     if (ime != nullptr && (ime->ime.first == preDefaultIme.bundleName && ime->ime.second == preDefaultIme.extName)) {
2734         return std::make_pair(ErrorCode::NO_ERROR, StartPreDefaultImeStatus::HAS_STARTED);
2735     }
2736     preDefaultIme.imeExtendInfo = imeExtendInfo;
2737     auto ret = StartIme(std::make_shared<ImeNativeCfg>(preDefaultIme), isStopCurrentIme);
2738     if (ret != ErrorCode::NO_ERROR) {
2739         IMSA_HILOGE("start ime failed, ret: %{public}d!", ret);
2740         return std::make_pair(ret, StartPreDefaultImeStatus::TO_START);
2741     }
2742     std::string subName;
2743     auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
2744     if (defaultIme != nullptr && defaultIme->imeId == preDefaultIme.imeId) {
2745         NotifyImeChangedToClients();
2746         subName = defaultIme->subName;
2747     }
2748     NotifySubTypeChangedToIme(preDefaultIme.bundleName, subName);
2749     return std::make_pair(ErrorCode::NO_ERROR, StartPreDefaultImeStatus::TO_START);
2750 }
2751 
IncreaseAttachCount()2752 void PerUserSession::IncreaseAttachCount()
2753 {
2754     std::lock_guard<std::mutex> lock(attachCountMtx_);
2755     if (attachingCount_ >= MAX_ATTACH_COUNT) {
2756         IMSA_HILOGE("attach count over:%{public}u", MAX_ATTACH_COUNT);
2757         return;
2758     }
2759     attachingCount_++;
2760 }
2761 
DecreaseAttachCount()2762 void PerUserSession::DecreaseAttachCount()
2763 {
2764     std::lock_guard<std::mutex> lock(attachCountMtx_);
2765     if (attachingCount_ == 0) {
2766         IMSA_HILOGE("attachingCount_ is 0");
2767         return;
2768     }
2769     attachingCount_--;
2770 }
2771 
GetAttachCount()2772 uint32_t PerUserSession::GetAttachCount()
2773 {
2774     std::lock_guard<std::mutex> lock(attachCountMtx_);
2775     return attachingCount_;
2776 }
2777 
TryStartIme()2778 int32_t PerUserSession::TryStartIme()
2779 {
2780     if (!isBlockStartedByLowMem_.load()) {
2781         IMSA_HILOGI("ime is not blocked in starting by low mem, no need to deal.");
2782         return ErrorCode::ERROR_OPERATION_NOT_ALLOWED;
2783     }
2784     isBlockStartedByLowMem_.store(false);
2785     auto imeData = GetImeData(ImeType::IME);
2786     if (imeData != nullptr) {
2787         IMSA_HILOGI("has running ime:%{public}s, no need to deal.", imeData->ime.first.c_str());
2788         return ErrorCode::ERROR_IME_HAS_STARTED;
2789     }
2790     auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_);
2791     if (cfgIme == nullptr || ImeInfoInquirer::GetInstance().GetDefaultIme().bundleName != cfgIme->bundleName) {
2792         IMSA_HILOGI("has no cfgIme or cfg ime is not sys preconfigured ime, can not start.");
2793         return ErrorCode::ERROR_OPERATION_NOT_ALLOWED;
2794     }
2795 #ifndef IMF_ON_DEMAND_START_STOP_SA_ENABLE
2796     if (!ImeStateManagerFactory::GetInstance().GetDynamicStartIme()) {
2797         StartImeIfInstalled();
2798     }
2799 #endif
2800     return ErrorCode::NO_ERROR;
2801 }
2802 
TryDisconnectIme()2803 int32_t PerUserSession::TryDisconnectIme()
2804 {
2805     auto imeData = GetImeData(ImeType::IME);
2806     if (imeData == nullptr) {
2807         return ErrorCode::ERROR_IME_NOT_STARTED;
2808     }
2809     if (GetAttachCount() != 0) {
2810         IMSA_HILOGI("attaching, can not disconnect.");
2811         return ErrorCode::ERROR_OPERATION_NOT_ALLOWED;
2812     }
2813     auto clientInfo = GetCurrentClientInfo();
2814     if (clientInfo != nullptr) {
2815         IMSA_HILOGI("has current client, can not disconnect.");
2816         return ErrorCode::ERROR_OPERATION_NOT_ALLOWED;
2817     }
2818     auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance();
2819     if (abilityMgr == nullptr) {
2820         return ErrorCode::ERROR_IMSA_NULLPTR;
2821     }
2822     auto imeConnection = GetImeConnection();
2823     if (imeConnection == nullptr) {
2824         return ErrorCode::ERROR_IME_NOT_STARTED;
2825     }
2826     auto ret = abilityMgr->DisconnectAbility(imeConnection);
2827     if (ret != ErrorCode::NO_ERROR) {
2828         IMSA_HILOGE("disConnect %{public}s/%{public}s failed, ret:%{public}d.", imeData->ime.first.c_str(),
2829             imeData->ime.second.c_str(), ret);
2830         return ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED;
2831     }
2832     ClearImeConnection(imeConnection);
2833     return ErrorCode::NO_ERROR;
2834 }
2835 
SetImeConnection(const sptr<AAFwk::IAbilityConnection> & connection)2836 void PerUserSession::SetImeConnection(const sptr<AAFwk::IAbilityConnection> &connection)
2837 {
2838     std::lock_guard<std::mutex> lock(connectionLock_);
2839     connection_ = connection;
2840 }
2841 
GetImeConnection()2842 sptr<AAFwk::IAbilityConnection> PerUserSession::GetImeConnection()
2843 {
2844     std::lock_guard<std::mutex> lock(connectionLock_);
2845     return connection_;
2846 }
2847 
ClearImeConnection(const sptr<AAFwk::IAbilityConnection> & connection)2848 void PerUserSession::ClearImeConnection(const sptr<AAFwk::IAbilityConnection> &connection)
2849 {
2850     std::lock_guard<std::mutex> lock(connectionLock_);
2851     if (connection == nullptr || connection_ == nullptr || connection->AsObject() != connection_->AsObject()) {
2852         return;
2853     }
2854     IMSA_HILOGI("clear imeConnection.");
2855     connection_ = nullptr;
2856 }
2857 
IsRequestOverLimit(TimeLimitType timeLimitType,int32_t resetTimeOut,int32_t restartNum)2858 int32_t PerUserSession::IsRequestOverLimit(TimeLimitType timeLimitType, int32_t resetTimeOut, int32_t restartNum)
2859 {
2860     std::lock_guard<std::mutex> lock(resetLock);
2861     auto now = time(nullptr);
2862     auto& manager = managers_[timeLimitType];
2863     if (difftime(now, manager.last) > resetTimeOut) {
2864         manager = {0, now};
2865     }
2866     ++manager.num;
2867     if (manager.num > restartNum) {
2868         return ErrorCode::ERROR_REQUEST_RATE_EXCEEDED;
2869     }
2870     return ErrorCode::NO_ERROR;
2871 }
2872 
IsEnable(const std::shared_ptr<ImeData> & data)2873 bool PerUserSession::IsEnable(const std::shared_ptr<ImeData> &data)
2874 {
2875     bool ret = false;
2876     if (data == nullptr || data->core == nullptr) {
2877         return false;
2878     }
2879     data->core->IsEnable(ret);
2880     return ret;
2881 }
2882 } // namespace MiscServices
2883 } // namespace OHOS