1 /* 2 * Copyright (C) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "peruser_session.h" 17 18 #include <vector> 19 20 #include "ability_connect_callback_proxy.h" 21 #include "ability_manager_interface.h" 22 #include "element_name.h" 23 #include "input_client_proxy.h" 24 #include "input_control_channel_proxy.h" 25 #include "input_data_channel_proxy.h" 26 #include "input_method_ability_connection_stub.h" 27 #include "input_method_agent_proxy.h" 28 #include "input_method_core_proxy.h" 29 #include "ipc_skeleton.h" 30 #include "message_parcel.h" 31 #include "para_handle.h" 32 #include "parcel.h" 33 #include "platform.h" 34 #include "sa_mgr_client.h" 35 #include "system_ability_definition.h" 36 #include "unistd.h" 37 #include "utils.h" 38 #include "want.h" 39 40 namespace OHOS { 41 namespace MiscServices { 42 using namespace MessageID; 43 /*! Constructor 44 \param userId the id of the given user 45 \param msgId the msg id can be MessageID::MSG_ID_CLIENT_DIED (to monitor input client) 46 \n or MessageID::MSG_ID_IMS_DIED (to monitor input method service) 47 */ RemoteObjectDeathRecipient(int userId,int msgId)48 RemoteObjectDeathRecipient::RemoteObjectDeathRecipient(int userId, int msgId) 49 { 50 userId_ = userId; 51 msgId_ = msgId; 52 } 53 ~RemoteObjectDeathRecipient()54 RemoteObjectDeathRecipient::~RemoteObjectDeathRecipient() 55 { 56 } 57 58 /*! Notify that a remote object died. 59 \n It's called when the linked remote object died. 60 \param who the IRemoteObject handler of the remote object died. 61 */ OnRemoteDied(const wptr<IRemoteObject> & who)62 void RemoteObjectDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &who) 63 { 64 auto parcel = new (std::nothrow) MessageParcel(); 65 if (parcel == nullptr) { 66 IMSA_HILOGE("parcel is nullptr"); 67 return; 68 } 69 parcel->WriteInt32(userId_); 70 parcel->WritePointer(reinterpret_cast<uintptr_t>(who.GetRefPtr())); 71 auto msg = new (std::nothrow) Message(msgId_, parcel); 72 if (msg == nullptr) { 73 IMSA_HILOGE("msg is nullptr"); 74 delete parcel; 75 return; 76 } 77 MessageHandler::Instance()->SendMessage(msg); 78 } 79 80 /*! Constructor 81 \param userId the user id of this user whose session are managed by this instance of PerUserSession. 82 */ PerUserSession(int userId)83 PerUserSession::PerUserSession(int userId) 84 { 85 userState = UserState::USER_STATE_STARTED; 86 userId_ = userId; 87 currentIme[0] = nullptr; 88 currentIme[1] = nullptr; 89 90 needReshowClient = nullptr; 91 92 imsDeathRecipient = new RemoteObjectDeathRecipient(userId, MSG_ID_IMS_DIED); 93 } 94 95 /*! Destructor 96 */ ~PerUserSession()97 PerUserSession::~PerUserSession() 98 { 99 if (userState == UserState::USER_STATE_UNLOCKED) { 100 OnUserLocked(); 101 } 102 imsDeathRecipient = nullptr; 103 if (workThreadHandler.joinable()) { 104 workThreadHandler.join(); 105 } 106 } 107 108 109 /*! Create work thread for this user 110 \param handle message handle to receive the message 111 */ CreateWorkThread(MessageHandler & handler)112 void PerUserSession::CreateWorkThread(MessageHandler& handler) 113 { 114 msgHandler = &handler; 115 workThreadHandler = std::thread([this] {WorkThread();}); 116 } 117 118 /*! Wait till work thread exits 119 */ JoinWorkThread()120 void PerUserSession::JoinWorkThread() 121 { 122 if (workThreadHandler.joinable()) { 123 workThreadHandler.join(); 124 } 125 } 126 127 /*! Work thread for this user 128 */ WorkThread()129 void PerUserSession::WorkThread() 130 { 131 if (msgHandler == nullptr) { 132 return; 133 } 134 while (1) { 135 Message *msg = msgHandler->GetMessage(); 136 std::unique_lock<std::mutex> lock(mtx); 137 switch (msg->msgId_) { 138 case MSG_ID_USER_LOCK: 139 case MSG_ID_EXIT_SERVICE: { 140 OnUserLocked(); 141 delete msg; 142 msg = nullptr; 143 return; 144 } 145 case MSG_ID_PREPARE_INPUT: { 146 OnPrepareInput(msg); 147 break; 148 } 149 case MSG_ID_RELEASE_INPUT: { 150 OnReleaseInput(msg); 151 break; 152 } 153 case MSG_ID_START_INPUT: { 154 OnStartInput(msg); 155 break; 156 } 157 case MSG_ID_STOP_INPUT: { 158 OnStopInput(msg); 159 break; 160 } 161 case MSG_ID_SET_CORE_AND_AGENT: { 162 SetCoreAndAgent(msg); 163 break; 164 } 165 case MSG_ID_CLIENT_DIED: { 166 auto *remoteObject = reinterpret_cast<IRemoteObject *>(msg->msgContent_->ReadPointer()); 167 if (remoteObject == nullptr) { 168 IMSA_HILOGE("MSG_ID_CLIENT_DIED remoteObject is nullptr"); 169 break; 170 } 171 OnClientDied(remoteObject); 172 break; 173 } 174 case MSG_ID_IMS_DIED: { 175 auto *remoteObject = reinterpret_cast<IRemoteObject *>(msg->msgContent_->ReadPointer()); 176 if (remoteObject == nullptr) { 177 IMSA_HILOGE("MSG_ID_IMS_DIED remoteObject is nullptr"); 178 break; 179 } 180 OnImsDied(remoteObject); 181 break; 182 } 183 case MSG_ID_HIDE_KEYBOARD_SELF: { 184 int flag = msg->msgContent_->ReadInt32(); 185 OnHideKeyboardSelf(flag); 186 break; 187 } 188 case MSG_ID_ADVANCE_TO_NEXT: { 189 OnAdvanceToNext(); 190 break; 191 } 192 case MSG_ID_SET_DISPLAY_MODE: { 193 int mode = msg->msgContent_->ReadInt32(); 194 OnSetDisplayMode(mode); 195 break; 196 } 197 case MSG_ID_RESTART_IMS: { 198 int index = msg->msgContent_->ReadInt32(); 199 std::u16string imeId = msg->msgContent_->ReadString16(); 200 OnRestartIms(index, imeId); 201 break; 202 } 203 case MSG_HIDE_CURRENT_INPUT: { 204 OnHideKeyboardSelf(0); 205 } 206 default: { 207 break; 208 } 209 } 210 delete msg; 211 msg = nullptr; 212 } 213 } 214 215 /*! Set display Id 216 \param displayId the Id of display screen on which the input method keyboard show. 217 */ SetDisplayId(int displayId)218 void PerUserSession::SetDisplayId(int displayId) 219 { 220 this->displayId = displayId; 221 } 222 223 /*! Set the current input method engine 224 \param ime the current (default) IME pointer referred to the instance in PerUserSetting. 225 */ SetCurrentIme(InputMethodProperty * ime)226 void PerUserSession::SetCurrentIme(InputMethodProperty *ime) 227 { 228 currentIme[DEFAULT_IME] = ime; 229 userState = UserState::USER_STATE_UNLOCKED; 230 } 231 232 /*! Set the system security input method engine 233 \param ime system security IME pointer referred to the instance in PerUserSetting. 234 */ SetSecurityIme(InputMethodProperty * ime)235 void PerUserSession::SetSecurityIme(InputMethodProperty *ime) 236 { 237 currentIme[SECURITY_IME] = ime; 238 } 239 240 /*! Set the input method setting data 241 \param setting InputMethodSetting pointer referred to the instance in PerUserSetting. 242 */ SetInputMethodSetting(InputMethodSetting * setting)243 void PerUserSession::SetInputMethodSetting(InputMethodSetting *setting) 244 { 245 inputMethodSetting = setting; 246 } 247 248 /*! Reset input method engine 249 \param defaultIme default ime pointer referred to the instance in PerUserSetting 250 \param security security ime pointer referred to the instance in PerUserSetting 251 \n Two input method engines can be running at the same time for one user. 252 \n One is the default ime, another is security ime 253 */ ResetIme(InputMethodProperty * defaultIme,InputMethodProperty * securityIme)254 void PerUserSession::ResetIme(InputMethodProperty *defaultIme, InputMethodProperty *securityIme) 255 { 256 IMSA_HILOGI("PerUserSession::ResetIme"); 257 std::unique_lock<std::mutex> lock(mtx); 258 InputMethodProperty *ime[] = {defaultIme, securityIme}; 259 for (int i = 0; i < MIN_IME; i++) { 260 if (currentIme[i] == ime[i] && ime[i] != nullptr) { 261 continue; 262 } 263 if (imsCore[i]) { 264 StopInputMethod(i); 265 } 266 ResetImeError(i); 267 currentIme[i] = ime[i]; 268 if (currentIme[i] == nullptr) { 269 if (needReshowClient && GetImeIndex(needReshowClient) == i) { 270 needReshowClient = nullptr; 271 } 272 continue; 273 } 274 275 bool flag = false; 276 for (auto mapClient : mapClients) { 277 if ((i == DEFAULT_IME && !mapClient.second->attribute.GetSecurityFlag()) 278 || (i == SECURITY_IME && mapClient.second->attribute.GetSecurityFlag())) { 279 flag = true; 280 break; 281 } 282 } 283 if (flag) { 284 int ret = StartInputMethod(i); 285 if (ret != ErrorCode::NO_ERROR) { 286 needReshowClient = nullptr; 287 break; 288 } 289 if (needReshowClient && GetImeIndex(needReshowClient) == i) { 290 ShowKeyboard(needReshowClient); 291 needReshowClient = nullptr; 292 } 293 } 294 } 295 } 296 297 /*! Called when a package is removed 298 \param packageName the name of package removed 299 */ OnPackageRemoved(const std::u16string & packageName)300 void PerUserSession::OnPackageRemoved(const std::u16string& packageName) 301 { 302 IMSA_HILOGI("PerUserSession::OnPackageRemoved"); 303 InputMethodSetting tmpSetting; 304 bool flag = false; 305 std::unique_lock<std::mutex> lock(mtx); 306 for (int i = 0; i < MAX_IME; i++) { 307 sptr<IInputClient> client = GetCurrentClient(); 308 if (currentIme[i] && currentIme[i]->mPackageName == packageName) { 309 if (client != nullptr && GetImeIndex(client) == i) { 310 needReshowClient = client; 311 HideKeyboard(client); 312 } 313 StopInputMethod(i); 314 currentIme[i] = nullptr; 315 if (i == DEFAULT_IME) { 316 tmpSetting.SetCurrentKeyboardType(-1); 317 inputMethodSetting->SetCurrentKeyboardType(-1); 318 } else if (i == SECURITY_IME) { 319 tmpSetting.SetCurrentSysKeyboardType(-1); 320 inputMethodSetting->SetCurrentSysKeyboardType(-1); 321 } 322 currentKbdIndex[i] = 0; 323 flag = true; 324 } 325 } 326 if (flag) { 327 Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); 328 } 329 } 330 331 /*! Add an input client 332 \param pid the process pid of the input client 333 \param uid the uid of the the input client 334 \param displayId the display id of the input client 335 \param inputClient the remote object handler of the input client 336 \param channel the remote InputDataChannel object handler for the input client. 337 \n It will be transferred to input method service 338 \param attribute the input attribute of the input client. 339 \return \li ErrorCode::NO_ERROR no error 340 \return \li ErrorCode::ERROR_CLIENT_DUPLICATED client is duplicated 341 */ AddClient(const ClientInfo & clientInfo)342 int PerUserSession::AddClient(const ClientInfo &clientInfo) 343 { 344 IMSA_HILOGI("PerUserSession::AddClient"); 345 ClientInfo *info = GetClientInfo(clientInfo.client); 346 if (info != nullptr) { 347 IMSA_HILOGE("info is exist, not need add."); 348 return ErrorCode::NO_ERROR; 349 } 350 sptr<IRemoteObject> obj = clientInfo.client->AsObject(); 351 if (obj == nullptr) { 352 IMSA_HILOGE("inputClient AsObject is nullptr"); 353 return ErrorCode::ERROR_REMOTE_CLIENT_DIED; 354 } 355 bool ret = obj->AddDeathRecipient(clientInfo.deathRecipient); 356 IMSA_HILOGI("Add death recipient %{public}s", ret ? "success" : "failed"); 357 358 info = new (std::nothrow) ClientInfo(clientInfo); 359 if (info == nullptr) { 360 IMSA_HILOGE("failed to create ClientInfo"); 361 return ErrorCode::ERROR_NULL_POINTER; 362 } 363 mapClients.insert({ obj, info }); 364 return ErrorCode::NO_ERROR; 365 } 366 367 /*! Remove an input client 368 \param inputClient remote object handler of the input client 369 \param[out] remainClientNum remained count of the same kinds of clients for this user 370 \n (i.e. if inputClient is an normal client, remainClientNum is the count of remained normal clients. 371 \n if inputClient is a security client, remainClientNum is the count of remained security clients.) 372 \return ErrorCode::NO_ERROR no error 373 \return ErrorCode::ERROR_CLIENT_NOT_FOUND client is not found 374 */ RemoveClient(IRemoteObject * inputClient)375 void PerUserSession::RemoveClient(IRemoteObject *inputClient) 376 { 377 IMSA_HILOGI("PerUserSession::RemoveClient"); 378 auto it = mapClients.find(inputClient); 379 if (it == mapClients.end()) { 380 IMSA_HILOGE("PerUserSession::RemoveClient client not found"); 381 return; 382 } 383 ClientInfo *clientInfo = it->second; 384 inputClient->RemoveDeathRecipient(clientInfo->deathRecipient); 385 delete clientInfo; 386 clientInfo = nullptr; 387 mapClients.erase(it); 388 } 389 390 /*! Start input method service 391 \param index it can be 0 or 1. 0 - default ime, 1 - security ime 392 \return ErrorCode::NO_ERROR no error 393 \return ErrorCode::ERROR_IME_BIND_FAILED failed to bind ime 394 \return ErrorCode::ERROR_IME_NOT_AVAILABLE no ime is available 395 \return ErrorCode::ERROR_SECURITY_IME_NOT_AVAILABLE no security ime is available 396 \return ErrorCode::ERROR_TOKEN_CREATE_FAILED failed to create window token 397 \return other errors returned by binder driver 398 */ StartInputMethod(int index)399 int PerUserSession::StartInputMethod(int index) 400 { 401 IMSA_HILOGI("PerUserSession::StartInputMethod index = %{public}d [%{public}d]\n", index, userId_); 402 403 if (imsCore[index] == nullptr) { 404 IMSA_HILOGI("PerUserSession::StartInputMethod imscore is null"); 405 return ErrorCode::ERROR_IME_BIND_FAILED; 406 } 407 408 sptr<IRemoteObject> b = imsCore[index]->AsObject(); 409 inputMethodToken[index] = IPCSkeleton::GetInstance().GetContextObject(); 410 localControlChannel[index] = new InputControlChannelStub(userId_); 411 inputControlChannel[index] = localControlChannel[index]; 412 int ret_init = imsCore[index]->initializeInput(inputMethodToken[index], displayId, inputControlChannel[index]); 413 if (ret_init != ErrorCode::NO_ERROR) { 414 IMSA_HILOGE("PerUserSession::StartInputMethod initializeInput fail %{public}s", ErrorCode::ToString(ret_init)); 415 localControlChannel[index] = nullptr; 416 inputControlChannel[index] = nullptr; 417 return ret_init; 418 } 419 return ErrorCode::NO_ERROR; 420 } 421 422 /*! Stop input method service 423 \param index it can be 0 or 1. 0 - default ime, 1 - security ime 424 \return ErrorCode::NO_ERROR no error 425 \return ErrorCode::ERROR_IME_NOT_STARTED ime not started 426 \return ErrorCode::ERROR_IME_UNBIND_FAILED failed to unbind ime 427 \return ErrorCode::ERROR_TOKEN_DESTROY_FAILED failed to destroy window token 428 \return other errors returned by binder driver 429 */ StopInputMethod(int index)430 int PerUserSession::StopInputMethod(int index) 431 { 432 IMSA_HILOGI("Start... index = %{public}d [%{public}d]\n", index, userId_); 433 if (index >= MAX_IME || index < 0) { 434 IMSA_HILOGE("Aborted! %{public}s", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS)); 435 return ErrorCode::ERROR_BAD_PARAMETERS; 436 } 437 if (imsCore[index] == nullptr || currentIme[index] == nullptr) { 438 IMSA_HILOGE("Aborted! %{public}s", ErrorCode::ToString(ErrorCode::ERROR_IME_NOT_STARTED)); 439 return ErrorCode::ERROR_IME_NOT_STARTED; 440 } 441 if (currentIme[index] == currentIme[1 - index] && imsCore[1 - index] != nullptr) { 442 imsCore[index] = nullptr; 443 inputControlChannel[index] = nullptr; 444 localControlChannel[index] = nullptr; 445 IMSA_HILOGI("End...[%{public}d]\n", userId_); 446 return ErrorCode::NO_ERROR; 447 } 448 449 IMSA_HILOGD("unbindInputMethodService...\n"); 450 451 IMSA_HILOGD("destroyWindowToken...\n"); 452 int errorCode = ErrorCode::NO_ERROR; 453 int ret = Platform::Instance()->DestroyWindowToken(userId_, currentIme[index]->mPackageName); 454 inputMethodToken[index] = nullptr; 455 if (ret != ErrorCode::NO_ERROR) { 456 IMSA_HILOGE("destroyWindowToken return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); 457 errorCode = ErrorCode::ERROR_TOKEN_DESTROY_FAILED; 458 } 459 sptr<IRemoteObject> b = imsCore[index]->AsObject(); 460 ret = b->RemoveDeathRecipient(imsDeathRecipient); 461 if (ret != ErrorCode::NO_ERROR) { 462 IMSA_HILOGE("RemoveDeathRecipient return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); 463 } 464 imsCore[index] = nullptr; 465 inputControlChannel[index] = nullptr; 466 localControlChannel[index] = nullptr; 467 IMSA_HILOGI("End...[%{public}d]\n", userId_); 468 return errorCode; 469 } 470 471 /*! Show keyboard 472 \param inputClient the remote object handler of the input client. 473 \return ErrorCode::NO_ERROR no error 474 \return ErrorCode::ERROR_IME_NOT_STARTED ime not started 475 \return ErrorCode::ERROR_KBD_IS_OCCUPIED keyboard is showing by other client 476 \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found 477 \return ErrorCode::ERROR_IME_START_FAILED failed to start input method service 478 \return ErrorCode::ERROR_KBD_SHOW_FAILED failed to show keyboard 479 \return other errors returned by binder driver 480 */ ShowKeyboard(const sptr<IInputClient> & inputClient)481 int PerUserSession::ShowKeyboard(const sptr<IInputClient>& inputClient) 482 { 483 IMSA_HILOGI("PerUserSession::ShowKeyboard"); 484 ClientInfo *clientInfo = GetClientInfo(inputClient); 485 int index = GetImeIndex(inputClient); 486 if (index == -1 || clientInfo == nullptr) { 487 IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! index = -1 or clientInfo is nullptr"); 488 return ErrorCode::ERROR_CLIENT_NOT_FOUND; 489 } 490 491 if (imsCore[0] == nullptr) { 492 IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! imsCore[%{public}d] is nullptr", index); 493 return ErrorCode::ERROR_NULL_POINTER; 494 } 495 496 imsCore[0]->showKeyboard(clientInfo->channel); 497 498 SetCurrentClient(inputClient); 499 return ErrorCode::NO_ERROR; 500 } 501 502 /*! hide keyboard 503 \param inputClient the remote object handler of the input client. 504 \return ErrorCode::NO_ERROR no error 505 \return ErrorCode::ERROR_IME_NOT_STARTED ime not started 506 \return ErrorCode::ERROR_KBD_IS_NOT_SHOWING keyboard has not been showing 507 \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found 508 \return ErrorCode::ERROR_KBD_HIDE_FAILED failed to hide keyboard 509 \return other errors returned by binder driver 510 */ HideKeyboard(const sptr<IInputClient> & inputClient)511 int PerUserSession::HideKeyboard(const sptr<IInputClient>& inputClient) 512 { 513 IMSA_HILOGI("PerUserSession::HideKeyboard"); 514 int index = GetImeIndex(inputClient); 515 if (index == -1) { 516 IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! ErrorCode::ERROR_CLIENT_NOT_FOUND"); 517 return ErrorCode::ERROR_CLIENT_NOT_FOUND; 518 } 519 ClientInfo *clientInfo = GetClientInfo(inputClient); 520 if (clientInfo == nullptr) { 521 IMSA_HILOGE("PerUserSession::HideKeyboard GetClientInfo pointer nullptr"); 522 } 523 if (imsCore[0] == nullptr) { 524 IMSA_HILOGE("PerUserSession::HideKeyboard imsCore[index] is nullptr"); 525 return ErrorCode::ERROR_IME_NOT_STARTED; 526 } 527 528 bool ret = imsCore[0]->hideKeyboard(1); 529 if (!ret) { 530 IMSA_HILOGE("PerUserSession::HideKeyboard [imsCore->hideKeyboard] failed"); 531 ret = ErrorCode::ERROR_KBD_HIDE_FAILED; 532 } 533 534 return ErrorCode::NO_ERROR; 535 } 536 537 /*! Get the display mode of the current keyboard showing 538 \return return display mode. 539 \n 0 - part sceen mode, 1 - full sceen mode 540 */ GetDisplayMode()541 int PerUserSession::GetDisplayMode() 542 { 543 return currentDisplayMode; 544 } 545 546 /*! Get the keyboard window height 547 \param[out] retHeight the height of keyboard window showing or showed returned to caller 548 \return ErrorCode 549 */ GetKeyboardWindowHeight(int retHeight)550 int PerUserSession::GetKeyboardWindowHeight(int retHeight) 551 { 552 if (imsCore[lastImeIndex] != nullptr) { 553 int ret = imsCore[lastImeIndex]->getKeyboardWindowHeight(retHeight); 554 if (ret != ErrorCode::NO_ERROR) { 555 IMSA_HILOGE("getKeyboardWindowHeight return : %{public}s", ErrorCode::ToString(ret)); 556 } 557 return ret; 558 } 559 IMSA_HILOGW("No IME is started [%{public}d]\n", userId_); 560 return ErrorCode::ERROR_IME_NOT_STARTED; 561 } 562 563 /*! Get the current keyboard type 564 \return return the pointer of the object of current keyboard type. 565 \n null if no keyboard type supported by the current ime. 566 \note The returned pointer should NOT be freed by the caller. 567 */ GetCurrentKeyboardType()568 KeyboardType *PerUserSession::GetCurrentKeyboardType() 569 { 570 if (inputMethodSetting == nullptr || currentIme[DEFAULT_IME] == nullptr) { 571 IMSA_HILOGI("Ime has not started ! [%{public}d]\n", userId_); 572 return nullptr; 573 } 574 if (currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { 575 return nullptr; 576 } 577 int hashCode = inputMethodSetting->GetCurrentKeyboardType(); // To be checked. 578 if (hashCode == -1) { 579 std::vector<int> hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[DEFAULT_IME]->mImeId); 580 if (hashCodeList.size() == 0) { 581 IMSA_HILOGE("Cannot find any keyboard types for the current ime [%{public}d]\n", userId_); 582 return nullptr; 583 } 584 hashCode = hashCodeList[0]; 585 } 586 587 for (int i = 0; i < (int)currentIme[DEFAULT_IME]->mTypes.size(); i++) { 588 if (currentIme[DEFAULT_IME]->mTypes[i]->getHashCode() == hashCode) { 589 return currentIme[DEFAULT_IME]->mTypes[i]; 590 } 591 } 592 return nullptr; 593 } 594 595 /*! Handle the situation a remote input client died\n 596 It's called when a remote input client died 597 \param remoteObject the remote object handler of the input client died. 598 */ OnClientDied(IRemoteObject * remoteObject)599 void PerUserSession::OnClientDied(IRemoteObject *remoteObject) 600 { 601 IMSA_HILOGI("PerUserSession::OnClientDied Start...[%{public}d]\n", userId_); 602 auto it = mapClients.find(remoteObject); 603 if (it == mapClients.end()) { 604 IMSA_HILOGE("PerUserSession::RemoveClient client not found"); 605 return; 606 } 607 sptr<IInputClient> client = GetCurrentClient(); 608 if (client == nullptr) { 609 IMSA_HILOGE("current client is nullptr"); 610 RemoveClient(it->first); 611 return; 612 } 613 if (client->AsObject().GetRefPtr() == remoteObject) { 614 int ret = HideKeyboard(client); 615 IMSA_HILOGI("hide keyboard ret: %{public}s", ErrorCode::ToString(ret)); 616 } 617 RemoveClient(it->first); 618 } 619 620 /*! Handle the situation a input method service died\n 621 It's called when an input method service died 622 \param remoteObject the remote object handler of input method service remoteObject died. 623 */ OnImsDied(IRemoteObject * remoteObject)624 void PerUserSession::OnImsDied(IRemoteObject *remoteObject) 625 { 626 (void)remoteObject; 627 IMSA_HILOGI("Start...[%{public}d]\n", userId_); 628 int index = 0; 629 for (int i = 0; i < MAX_IME; i++) { 630 if (imsCore[i] == nullptr) { 631 continue; 632 } 633 auto b = imsCore[i]->AsObject(); 634 if (b.GetRefPtr() == remoteObject) { 635 index = i; 636 break; 637 } 638 } 639 ClearImeData(index); 640 if (!IsRestartIme(index)) { 641 IMSA_HILOGI("Restart ime over max num"); 642 return; 643 } 644 IMSA_HILOGI("IME died. Restart input method...[%{public}d]\n", userId_); 645 const auto &ime = ParaHandle::GetDefaultIme(userId_); 646 auto *parcel = new (std::nothrow) MessageParcel(); 647 if (parcel == nullptr) { 648 IMSA_HILOGE("parcel is nullptr"); 649 return; 650 } 651 parcel->WriteString(ime); 652 auto *msg = new (std::nothrow) Message(MSG_ID_START_INPUT_SERVICE, parcel); 653 if (msg == nullptr) { 654 IMSA_HILOGE("msg is nullptr"); 655 delete parcel; 656 return; 657 } 658 usleep(MAX_RESET_WAIT_TIME); 659 MessageHandler::Instance()->SendMessage(msg); 660 IMSA_HILOGI("End...[%{public}d]\n", userId_); 661 } 662 663 /*! It's called when input method setting data in the system is changed 664 \param key the name of setting item changed. 665 \param value the value of setting item changed. 666 \return ErrorCode::NO_ERROR no error 667 \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. 668 */ OnSettingChanged(const std::u16string & key,const std::u16string & value)669 int PerUserSession::OnSettingChanged(const std::u16string& key, const std::u16string& value) 670 { 671 IMSA_HILOGI("Start...[%{public}d]\n", userId_); 672 std::unique_lock<std::mutex> lock(mtx); 673 if (inputMethodSetting == nullptr) { 674 return ErrorCode::ERROR_NULL_POINTER; 675 } 676 std::u16string currentValue = inputMethodSetting->GetValue(key); 677 678 IMSA_HILOGD("PerUserSession::OnSettingChanged key = %{public}s", Utils::to_utf8(key).c_str()); 679 IMSA_HILOGD("PerUserSession::OnSettingChanged value = %{public}s", Utils::to_utf8(value).c_str()); 680 IMSA_HILOGD("PerUserSession::OnSettingChanged currentValue = %{public}s", Utils::to_utf8(currentValue).c_str()); 681 682 if (currentValue == value) { 683 IMSA_HILOGI("End...[%{public}d]\n", userId_); 684 return ErrorCode::ERROR_SETTING_SAME_VALUE; 685 } 686 sptr<IInputClient> client = GetCurrentClient(); 687 if (key == InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG) { 688 return OnCurrentKeyboardTypeChanged(DEFAULT_IME, value); 689 } else if (key == InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG) { 690 return OnCurrentKeyboardTypeChanged(SECURITY_IME, value); 691 } else if (key == InputMethodSetting::CURRENT_INPUT_METHOD_TAG) { 692 if (currentIme[DEFAULT_IME] == nullptr || value == currentIme[DEFAULT_IME]->mImeId) { 693 return ErrorCode::NO_ERROR; 694 } 695 if (client != nullptr && GetImeIndex(client) == DEFAULT_IME) { 696 needReshowClient = client; 697 HideKeyboard(client); 698 } 699 StopInputMethod(DEFAULT_IME); 700 currentIme[DEFAULT_IME] = nullptr; 701 currentKbdIndex[DEFAULT_IME] = 0; 702 inputMethodSetting->SetCurrentKeyboardType(-1); 703 } else if (key == InputMethodSetting::ENABLED_INPUT_METHODS_TAG) { 704 if (currentIme[DEFAULT_IME] != nullptr && currentIme[DEFAULT_IME] != currentIme[SECURITY_IME] 705 && value.find(currentIme[DEFAULT_IME]->mImeId) == std::string::npos) { 706 if (client != nullptr && GetImeIndex(client) == DEFAULT_IME) { 707 needReshowClient = client; 708 HideKeyboard(client); 709 } 710 StopInputMethod(DEFAULT_IME); 711 currentIme[DEFAULT_IME] = nullptr; 712 currentKbdIndex[DEFAULT_IME] = 0; 713 inputMethodSetting->SetCurrentKeyboardType(-1); 714 } 715 } 716 IMSA_HILOGI("End...[%{public}d]\n", userId_); 717 return ErrorCode::NO_ERROR; 718 } 719 720 /*! Change current keyboard type. 721 \param index it can be 0 or 1. 0 - default ime, 1 - security ime. 722 \param value the hash code of keyboard type 723 \return ErrorCode::NO_ERROR no error 724 \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. 725 */ OnCurrentKeyboardTypeChanged(int index,const std::u16string & value)726 int PerUserSession::OnCurrentKeyboardTypeChanged(int index, const std::u16string& value) 727 { 728 std::string str = Utils::to_utf8(value); 729 int hashCode = std::atoi(str.c_str()); 730 if (hashCode == -1) { 731 return ErrorCode::ERROR_SETTING_SAME_VALUE;; 732 } 733 // switch within the current ime. 734 if (index == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { 735 int num = currentKbdIndex[index]; 736 if (currentIme[index]->mTypes[num]->getHashCode() == hashCode) { 737 return ErrorCode::ERROR_SETTING_SAME_VALUE; 738 } 739 for (int i = 0; i < (int)currentIme[index]->mTypes.size(); i++) { 740 if (currentIme[index]->mTypes[i]->getHashCode() == hashCode) { 741 currentKbdIndex[index] = i; 742 break; 743 } 744 } 745 } else { 746 std::u16string imeId = currentIme[index]->mImeId; 747 std::vector<int> currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); 748 int num = currentKbdIndex[index]; 749 if (currentKbdTypes[num] == hashCode) { 750 return ErrorCode::ERROR_SETTING_SAME_VALUE; 751 } 752 for (int i = 0; i < (int)currentKbdTypes.size(); i++) { 753 if (currentKbdTypes[i] == hashCode) { 754 currentKbdIndex[index] = i; 755 break; 756 } 757 } 758 } 759 KeyboardType *type = GetKeyboardType(index, currentKbdIndex[index]); 760 if (type != nullptr) { 761 if (GetCurrentClient() != nullptr) { 762 int ret = imsCore[index]->setKeyboardType(*type); 763 if (ret != ErrorCode::NO_ERROR) { 764 IMSA_HILOGE("setKeyboardType return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); 765 } 766 } 767 if (imsCore[index] == imsCore[1 - index]) { 768 inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); 769 inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); 770 currentKbdIndex[1 - index] = currentKbdIndex[index]; 771 } else if (index == DEFAULT_IME) { 772 inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); 773 } else { 774 inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); 775 } 776 } 777 return ErrorCode::NO_ERROR; 778 } 779 780 /*! Hide current keyboard 781 \param flag the flag to hide keyboard. 782 */ OnHideKeyboardSelf(int flags)783 void PerUserSession::OnHideKeyboardSelf(int flags) 784 { 785 IMSA_HILOGW("PerUserSession::OnHideKeyboardSelf"); 786 (void) flags; 787 sptr<IInputClient> client = GetCurrentClient(); 788 if (client == nullptr) { 789 IMSA_HILOGE("current client is nullptr"); 790 return; 791 } 792 HideKeyboard(client); 793 } 794 795 /*! Switch to next keyboard type 796 */ OnAdvanceToNext()797 void PerUserSession::OnAdvanceToNext() 798 { 799 sptr<IInputClient> client = GetCurrentClient(); 800 if (client == nullptr) { 801 IMSA_HILOGE("current client is nullptr"); 802 return; 803 } 804 int index = GetImeIndex(client); 805 if (index == -1) { 806 IMSA_HILOGW("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); 807 return; 808 } 809 int size = 0; 810 if (index == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { 811 size = currentIme[index]->mTypes.size(); 812 } else { 813 std::u16string imeId = currentIme[index]->mImeId; 814 std::vector<int> currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); 815 size = currentKbdTypes.size(); 816 } 817 if (size < MIN_IME) { 818 IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); 819 return; 820 } 821 822 int num = currentKbdIndex[index]+1; 823 if (size != 0) { 824 num %= size; 825 } 826 KeyboardType *type = GetKeyboardType(index, num); 827 if (type == nullptr) { 828 IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); 829 return; 830 } 831 InputMethodSetting tmpSetting; 832 if (imsCore[index] == imsCore[1 - index]) { 833 tmpSetting.SetCurrentKeyboardType(type->getHashCode()); 834 tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); 835 } 836 else if (index == DEFAULT_IME) { 837 tmpSetting.SetCurrentKeyboardType(type->getHashCode()); 838 } else { 839 tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); 840 } 841 Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); 842 } 843 844 /*! Set display mode 845 \param mode the display mode of soft keyboard UI. 846 \n 0 - part sceen mode, 1 - full sceen mode 847 */ OnSetDisplayMode(int mode)848 void PerUserSession::OnSetDisplayMode(int mode) 849 { 850 currentDisplayMode = mode; 851 sptr<IInputClient> client = GetCurrentClient(); 852 if (client == nullptr) { 853 IMSA_HILOGE("current client is nullptr"); 854 return; 855 } 856 ClientInfo *clientInfo = GetClientInfo(client); 857 if (clientInfo == nullptr) { 858 IMSA_HILOGE("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); 859 return; 860 } 861 int ret = clientInfo->client->setDisplayMode(mode); 862 if (ret != ErrorCode::NO_ERROR) { 863 IMSA_HILOGE("setDisplayMode return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); 864 } 865 } 866 867 /*! Restart input method service 868 \param index it can be DEFAULT_IME or SECURITY_IME 869 \param imeId the id of the input method service going to restart 870 */ OnRestartIms(int index,const std::u16string & imeId)871 void PerUserSession::OnRestartIms(int index, const std::u16string& imeId) 872 { 873 if (index < 0 || index >= MAX_IME) { 874 return; 875 } 876 IMSA_HILOGI("Start...[%{public}d]\n", userId_); 877 if (currentIme[index] && currentIme[index]->mImeId == imeId) { 878 int ret = StartInputMethod(index); 879 if (needReshowClient && GetImeIndex(needReshowClient) == index) { 880 if (ret == ErrorCode::NO_ERROR) { 881 ShowKeyboard(needReshowClient); 882 } 883 needReshowClient = nullptr; 884 } 885 } 886 IMSA_HILOGI("End...[%{public}d]\n", userId_); 887 } 888 889 /*! It's called when this user is locked 890 */ OnUserLocked()891 void PerUserSession::OnUserLocked() 892 { 893 IMSA_HILOGI("PerUserSession::OnUserLocked"); 894 if (userState == UserState::USER_STATE_STARTED) { 895 IMSA_HILOGI("End...[%{public}d]\n", userId_); 896 return; 897 } 898 userState = UserState::USER_STATE_STARTED; 899 // hide current keyboard 900 sptr<IInputClient> client = GetCurrentClient(); 901 if (client != nullptr) { 902 HideKeyboard(client); 903 } 904 for (int i = 0; i < MIN_IME; i++) { 905 StopInputMethod(i); 906 currentIme[i] = nullptr; 907 } 908 // disconnect all clients. 909 for (auto it = mapClients.begin(); it != mapClients.end();) { 910 auto object = it->first; 911 ClientInfo *clientInfo = it->second; 912 if (clientInfo != nullptr) { 913 object->RemoveDeathRecipient(clientInfo->deathRecipient); 914 int ret = clientInfo->client->onInputReleased(0); 915 if (ret != ErrorCode::NO_ERROR) { 916 IMSA_HILOGE("2-onInputReleased return : %{public}s", ErrorCode::ToString(ret)); 917 } 918 delete clientInfo; 919 clientInfo = nullptr; 920 } 921 IMSA_HILOGD("erase client..\n"); 922 it = mapClients.erase(it); 923 } 924 mapClients.clear(); 925 926 // reset values 927 inputMethodSetting = nullptr; 928 SetCurrentClient(nullptr); 929 needReshowClient = nullptr; 930 } 931 932 /*! Get keyboard type 933 \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime 934 \param typeIndex the index of keyboard type. 935 \return a KeyboardType pointer when it's found. 936 \return null when it's not found. 937 \note The returned pointer should not be freed by caller. 938 */ GetKeyboardType(int imeIndex,int typeIndex)939 KeyboardType *PerUserSession::GetKeyboardType(int imeIndex, int typeIndex) 940 { 941 if (typeIndex < 0) { 942 return nullptr; 943 } 944 if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { 945 if (typeIndex >= (int)currentIme[imeIndex]->mTypes.size()) { 946 return nullptr; 947 } 948 return currentIme[imeIndex]->mTypes[typeIndex]; 949 } else { 950 std::u16string imeId = currentIme[imeIndex]->mImeId; 951 std::vector<int> currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); 952 int size = currentKbdTypes.size(); 953 if (typeIndex >= size) { 954 return nullptr; 955 } 956 int hashCode = currentKbdTypes[typeIndex]; 957 for (int i = 0; i < (int)currentIme[imeIndex]->mTypes.size(); i++) { 958 if (currentIme[imeIndex]->mTypes[i]->getHashCode() == hashCode) { 959 return currentIme[imeIndex]->mTypes[i]; 960 } 961 } 962 } 963 return nullptr; 964 } 965 966 /*! Reset current keyboard type 967 \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime 968 */ ResetCurrentKeyboardType(int imeIndex)969 void PerUserSession::ResetCurrentKeyboardType(int imeIndex) 970 { 971 if (imeIndex < 0 || imeIndex > 1) { 972 return; 973 } 974 currentKbdIndex[imeIndex] = 0; 975 int hashCode = 0; 976 if (imeIndex == DEFAULT_IME) { 977 hashCode = inputMethodSetting->GetCurrentKeyboardType(); 978 } else { 979 hashCode = inputMethodSetting->GetCurrentSysKeyboardType(); 980 } 981 KeyboardType *type = nullptr; 982 if (hashCode == -1) { 983 type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); 984 } else { 985 bool flag = false; 986 if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { 987 for (int i = 0; i < (int)currentIme[imeIndex]->mTypes.size(); i++) { 988 if (currentIme[imeIndex]->mTypes[i]->getHashCode() == hashCode) { 989 currentKbdIndex[imeIndex] = i; 990 flag = true; 991 break; 992 } 993 } 994 } else { 995 std::vector<int> hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[imeIndex]->mImeId); 996 for (int i = 0; i < (int)hashCodeList.size(); i++) { 997 if (hashCode == hashCodeList[i]) { 998 currentKbdIndex[imeIndex] = i; 999 flag = true; 1000 break; 1001 } 1002 } 1003 } 1004 if (flag == false) { 1005 IMSA_HILOGW("The current keyboard type is not found in the current IME. Reset it!"); 1006 type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); 1007 } else if (imsCore[imeIndex] == imsCore[1 - imeIndex]) { 1008 currentKbdIndex[1 - imeIndex] = currentKbdIndex[imeIndex]; 1009 } 1010 } 1011 if (type != nullptr) { 1012 InputMethodSetting tmpSetting; 1013 if (imsCore[imeIndex] == imsCore[1 - imeIndex]) { 1014 inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); 1015 inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); 1016 currentKbdIndex[1 - imeIndex] = currentKbdIndex[imeIndex]; 1017 tmpSetting.SetCurrentKeyboardType(type->getHashCode()); 1018 tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); 1019 } else if (imeIndex == DEFAULT_IME) { 1020 tmpSetting.SetCurrentKeyboardType(type->getHashCode()); 1021 inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); 1022 } else { 1023 tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); 1024 inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); 1025 } 1026 Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); 1027 } 1028 } 1029 1030 /*! Get ime index for the input client 1031 \param inputClient the remote object handler of an input client. 1032 \return 0 - default ime 1033 \return 1 - security ime 1034 \return -1 - input client is not found 1035 */ GetImeIndex(const sptr<IInputClient> & inputClient)1036 int PerUserSession::GetImeIndex(const sptr<IInputClient>& inputClient) 1037 { 1038 if (inputClient == nullptr) { 1039 IMSA_HILOGW("PerUserSession::GetImeIndex inputClient is nullptr"); 1040 return -1; 1041 } 1042 1043 ClientInfo *clientInfo = GetClientInfo(inputClient); 1044 if (clientInfo == nullptr) { 1045 IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr"); 1046 return -1; 1047 } 1048 1049 if (clientInfo->attribute.GetSecurityFlag() == true) { 1050 return SECURITY_IME; 1051 } 1052 return DEFAULT_IME; 1053 } 1054 1055 /*! Copy session data from one IME to another IME 1056 \param imeIndex it can be 0 or 1. 1057 \n 0 - default ime, 1 - security ime 1058 */ CopyInputMethodService(int imeIndex)1059 void PerUserSession::CopyInputMethodService(int imeIndex) 1060 { 1061 imsCore[imeIndex] = imsCore[1 - imeIndex]; 1062 localControlChannel[imeIndex] = localControlChannel[1 - imeIndex]; 1063 inputControlChannel[imeIndex] = inputControlChannel[1 - imeIndex]; 1064 inputMethodToken[imeIndex] = inputMethodToken[1 - imeIndex]; 1065 currentKbdIndex[imeIndex] = currentKbdIndex[1 - imeIndex]; 1066 int hashCode[2]; 1067 hashCode[0] = inputMethodSetting->GetCurrentKeyboardType(); 1068 hashCode[1] = inputMethodSetting->GetCurrentSysKeyboardType(); 1069 if (hashCode[imeIndex] != hashCode[1 - imeIndex]) { 1070 hashCode[imeIndex] = hashCode[1 - imeIndex]; 1071 inputMethodSetting->SetCurrentKeyboardType(hashCode[0]); 1072 inputMethodSetting->SetCurrentSysKeyboardType(hashCode[1]); 1073 1074 InputMethodSetting tmpSetting; 1075 tmpSetting.ClearData(); 1076 tmpSetting.SetCurrentKeyboardType(hashCode[0]); 1077 tmpSetting.SetCurrentSysKeyboardType(hashCode[1]); 1078 Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); 1079 } 1080 } 1081 1082 /*! Get ClientInfo 1083 \param inputClient the IInputClient remote handler of given input client 1084 \return a pointer of ClientInfo if client is found 1085 \n null if client is not found 1086 \note the clientInfo pointer should not be freed by caller 1087 */ GetClientInfo(const sptr<IInputClient> & inputClient)1088 ClientInfo *PerUserSession::GetClientInfo(const sptr<IInputClient> &inputClient) 1089 { 1090 if (inputClient == nullptr) { 1091 IMSA_HILOGE("PerUserSession::GetClientInfo inputClient is nullptr"); 1092 return nullptr; 1093 } 1094 sptr<IRemoteObject> object = Platform::RemoteBrokerToObject(inputClient); 1095 auto it = mapClients.find(object); 1096 if (it == mapClients.end()) { 1097 IMSA_HILOGE("client not found"); 1098 return nullptr; 1099 } 1100 return it->second; 1101 } 1102 StartInputService()1103 bool PerUserSession::StartInputService() 1104 { 1105 IMSA_HILOGE("PerUserSession::StartInputService"); 1106 sptr<AAFwk::IAbilityManager> ams = GetAbilityManagerService(); 1107 if (ams == nullptr) { 1108 return false; 1109 } 1110 AAFwk::Want want; 1111 want.SetAction("action.system.inputmethod"); 1112 want.SetElementName("com.example.kikakeyboard", "com.example.kikakeyboard.ServiceExtAbility"); 1113 int32_t result = ams->StartAbility(want); 1114 if (result != 0) { 1115 IMSA_HILOGE("PerUserSession::StartInputService fail. result = %{public}d", result); 1116 return false; 1117 } 1118 return true; 1119 } 1120 GetAbilityManagerService()1121 sptr<AAFwk::IAbilityManager> PerUserSession::GetAbilityManagerService() 1122 { 1123 IMSA_HILOGE("GetAbilityManagerService start"); 1124 sptr<IRemoteObject> abilityMsObj = 1125 OHOS::DelayedSingleton<AAFwk::SaMgrClient>::GetInstance()->GetSystemAbility(ABILITY_MGR_SERVICE_ID); 1126 if (abilityMsObj == nullptr) { 1127 IMSA_HILOGE("failed to get ability manager service"); 1128 return nullptr; 1129 } 1130 return iface_cast<AAFwk::IAbilityManager>(abilityMsObj); 1131 } 1132 1133 /*! Prepare input. Called by an input client. 1134 \n Run in work thread of this user 1135 \param msg the parameters from remote client are saved in msg->msgContent_ 1136 \return ErrorCode 1137 */ OnPrepareInput(Message * msg)1138 void PerUserSession::OnPrepareInput(Message *msg) 1139 { 1140 IMSA_HILOGI("PerUserSession::OnPrepareInput Start...[%{public}d]\n", userId_); 1141 MessageParcel *data = msg->msgContent_; 1142 int pid = data->ReadInt32(); 1143 int uid = data->ReadInt32(); 1144 int displayId = data->ReadInt32(); 1145 1146 sptr<IRemoteObject> clientObject = data->ReadRemoteObject(); 1147 if (clientObject == nullptr) { 1148 IMSA_HILOGI("PerUserSession::OnPrepareInput clientObject is null"); 1149 return; 1150 } 1151 1152 sptr<InputClientProxy> client = new InputClientProxy(clientObject); 1153 sptr<IRemoteObject> channelObject = data->ReadRemoteObject(); 1154 if (channelObject == nullptr) { 1155 IMSA_HILOGI("PerUserSession::OnPrepareInput channelObject is null"); 1156 return; 1157 } 1158 1159 sptr<InputDataChannelProxy> channel = new InputDataChannelProxy(channelObject); 1160 InputAttribute *attribute = data->ReadParcelable<InputAttribute>(); 1161 if (attribute == nullptr) { 1162 IMSA_HILOGI("PerUserSession::OnPrepareInput attribute is nullptr"); 1163 return; 1164 } 1165 1166 sptr<RemoteObjectDeathRecipient> clientDeathRecipient = new (std::nothrow) 1167 RemoteObjectDeathRecipient(Utils::GetUserId(), MSG_ID_CLIENT_DIED); 1168 if (clientDeathRecipient == nullptr) { 1169 IMSA_HILOGE("failed to create clientDeathRecipient"); 1170 } 1171 1172 int ret = AddClient({ pid, uid, userId_, displayId, client, channel, *attribute, clientDeathRecipient }); 1173 delete attribute; 1174 if (ret != ErrorCode::NO_ERROR) { 1175 IMSA_HILOGE("PerUserSession::OnPrepareInput Aborted! %{public}s", ErrorCode::ToString(ret)); 1176 return; 1177 } 1178 SendAgentToSingleClient(client); 1179 } 1180 SendAgentToSingleClient(const sptr<IInputClient> & inputClient)1181 void PerUserSession::SendAgentToSingleClient(const sptr<IInputClient>& inputClient) 1182 { 1183 IMSA_HILOGI("PerUserSession::SendAgentToSingleClient"); 1184 if (imsAgent == nullptr) { 1185 IMSA_HILOGI("PerUserSession::SendAgentToSingleClient imsAgent is nullptr"); 1186 return; 1187 } 1188 ClientInfo *clientInfo = GetClientInfo(inputClient); 1189 if (clientInfo == nullptr) { 1190 IMSA_HILOGE("PerUserSession::SendAgentToSingleClient clientInfo is nullptr"); 1191 return; 1192 } 1193 clientInfo->client->onInputReady(imsAgent); 1194 } 1195 1196 /*! Release input. Called by an input client. 1197 \n Run in work thread of this user 1198 \param msg the parameters from remote client are saved in msg->msgContent_ 1199 \return ErrorCode 1200 */ OnReleaseInput(Message * msg)1201 void PerUserSession::OnReleaseInput(Message *msg) 1202 { 1203 IMSA_HILOGI("PerUserSession::OnReleaseInput Start...[%{public}d]\n", userId_); 1204 MessageParcel *data = msg->msgContent_; 1205 1206 sptr<IRemoteObject> clientObject = data->ReadRemoteObject(); 1207 sptr<InputClientProxy> client = new InputClientProxy(clientObject); 1208 sptr<IInputClient> interface = client; 1209 if (imsCore[0] != nullptr) { 1210 imsCore[0]->SetClientState(false); 1211 } 1212 HideKeyboard(client); 1213 RemoveClient(clientObject.GetRefPtr()); 1214 IMSA_HILOGI("PerUserSession::OnReleaseInput End...[%{public}d]\n", userId_); 1215 } 1216 1217 /*! Start input. Called by an input client. 1218 \n Run in work thread of this user 1219 \param msg the parameters from remote client are saved in msg->msgContent_ 1220 \return ErrorCode 1221 */ OnStartInput(Message * msg)1222 void PerUserSession::OnStartInput(Message *msg) 1223 { 1224 IMSA_HILOGI("PerUserSession::OnStartInput"); 1225 MessageParcel *data = msg->msgContent_; 1226 sptr<IRemoteObject> clientObject = data->ReadRemoteObject(); 1227 sptr<InputClientProxy> client = new InputClientProxy(clientObject); 1228 if (imsCore[0] != nullptr) { 1229 imsCore[0]->SetClientState(true); 1230 } 1231 ShowKeyboard(client); 1232 } 1233 SetCoreAndAgent(Message * msg)1234 void PerUserSession::SetCoreAndAgent(Message *msg) 1235 { 1236 IMSA_HILOGI("PerUserSession::SetCoreAndAgent Start...[%{public}d]\n", userId_); 1237 auto data = msg->msgContent_; 1238 1239 auto coreObject = data->ReadRemoteObject(); 1240 if (coreObject == nullptr) { 1241 IMSA_HILOGE("coreObject is nullptr"); 1242 return; 1243 } 1244 auto core = new (std::nothrow) InputMethodCoreProxy(coreObject); 1245 if (core == nullptr) { 1246 IMSA_HILOGE("core is nullptr"); 1247 return; 1248 } 1249 if (imsCore[0] != nullptr) { 1250 IMSA_HILOGI("PerUserSession::SetCoreAndAgent Input Method Service has already been started ! "); 1251 } 1252 imsCore[0] = core; 1253 1254 bool ret = coreObject->AddDeathRecipient(imsDeathRecipient); 1255 IMSA_HILOGI("Add death recipient %{public}s", ret ? "success" : "failed"); 1256 1257 auto agentObject = data->ReadRemoteObject(); 1258 auto proxy = new (std::nothrow) InputMethodAgentProxy(agentObject); 1259 if (proxy == nullptr) { 1260 IMSA_HILOGE("proxy is nullptr"); 1261 return; 1262 } 1263 imsAgent = proxy; 1264 1265 InitInputControlChannel(); 1266 1267 SendAgentToAllClients(); 1268 } 1269 SendAgentToAllClients()1270 void PerUserSession::SendAgentToAllClients() 1271 { 1272 IMSA_HILOGI("PerUserSession::SendAgentToAllClients"); 1273 if (imsAgent == nullptr) { 1274 IMSA_HILOGI("PerUserSession::SendAgentToAllClients imsAgent is nullptr"); 1275 return; 1276 } 1277 1278 for (auto & mapClient : mapClients) { 1279 auto clientInfo = mapClient.second; 1280 if (clientInfo != nullptr) { 1281 clientInfo->client->onInputReady(imsAgent); 1282 } 1283 } 1284 } 1285 InitInputControlChannel()1286 void PerUserSession::InitInputControlChannel() 1287 { 1288 IMSA_HILOGI("PerUserSession::InitInputControlChannel"); 1289 sptr<IInputControlChannel> inputControlChannel = new InputControlChannelStub(userId_); 1290 int ret = imsCore[0]->InitInputControlChannel(inputControlChannel); 1291 if (ret != ErrorCode::NO_ERROR) { 1292 IMSA_HILOGI("PerUserSession::InitInputControlChannel fail %{public}s", ErrorCode::ToString(ret)); 1293 } 1294 } 1295 1296 /*! Stop input. Called by an input client. 1297 \n Run in work thread of this user 1298 \param msg the parameters from remote client are saved in msg->msgContent_ 1299 \return ErrorCode 1300 */ OnStopInput(Message * msg)1301 void PerUserSession::OnStopInput(Message *msg) 1302 { 1303 IMSA_HILOGI("PerUserSession::OnStopInput"); 1304 MessageParcel *data = msg->msgContent_; 1305 1306 sptr<IRemoteObject> clientObject = data->ReadRemoteObject(); 1307 sptr<InputClientProxy> client = new InputClientProxy(clientObject); 1308 HideKeyboard(client); 1309 } 1310 StopInputService(std::string imeId)1311 void PerUserSession::StopInputService(std::string imeId) 1312 { 1313 IMSA_HILOGI("PerUserSession::StopInputService"); 1314 if (imsCore[0] == nullptr) { 1315 IMSA_HILOGE("imsCore[0] is nullptr"); 1316 return; 1317 } 1318 IMSA_HILOGI("Remove death recipient"); 1319 imsCore[0]->AsObject()->RemoveDeathRecipient(imsDeathRecipient); 1320 imsCore[0]->StopInputService(imeId); 1321 } 1322 IsRestartIme(uint32_t index)1323 bool PerUserSession::IsRestartIme(uint32_t index) 1324 { 1325 IMSA_HILOGI("PerUserSession::IsRestartIme"); 1326 std::lock_guard<std::mutex> lock(resetLock); 1327 auto now = time(nullptr); 1328 if (difftime(now, manager[index].last) > IME_RESET_TIME_OUT) { 1329 manager[index] = { 0, now }; 1330 } 1331 ++manager[index].num; 1332 return manager[index].num <= MAX_RESTART_NUM; 1333 } 1334 ResetImeError(uint32_t index)1335 void PerUserSession::ResetImeError(uint32_t index) 1336 { 1337 IMSA_HILOGI("PerUserSession::ResetImeError index = %{public}d", index); 1338 std::lock_guard<std::mutex> lock(resetLock); 1339 manager[index] = { 0, 0 }; 1340 } 1341 ClearImeData(uint32_t index)1342 void PerUserSession::ClearImeData(uint32_t index) 1343 { 1344 IMSA_HILOGI("Clear ime...index = %{public}d", index); 1345 if (imsCore[index] != nullptr) { 1346 imsCore[index]->AsObject()->RemoveDeathRecipient(imsDeathRecipient); 1347 imsCore[index] = nullptr; 1348 } 1349 inputControlChannel[index] = nullptr; 1350 localControlChannel[index] = nullptr; 1351 inputMethodToken[index] = nullptr; 1352 } 1353 SetCurrentClient(sptr<IInputClient> client)1354 void PerUserSession::SetCurrentClient(sptr<IInputClient> client) 1355 { 1356 IMSA_HILOGI("set current client"); 1357 std::lock_guard<std::mutex> lock(clientLock_); 1358 currentClient = client; 1359 } 1360 GetCurrentClient()1361 sptr<IInputClient> PerUserSession::GetCurrentClient() 1362 { 1363 std::lock_guard<std::mutex> lock(clientLock_); 1364 return currentClient; 1365 } 1366 } // namespace MiscServices 1367 } // namespace OHOS 1368