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> ¤tClient, 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> ¤tClient,
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> ¤tClientInfo, 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> ¤tChannel, 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, [¤tChannel, 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