• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "peruser_session.h"
17 
18 #include <vector>
19 
20 #include "ability_connect_callback_proxy.h"
21 #include "ability_manager_interface.h"
22 #include "element_name.h"
23 #include "ime_cfg_manager.h"
24 #include "input_client_proxy.h"
25 #include "input_control_channel_proxy.h"
26 #include "input_data_channel_proxy.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 "parcel.h"
32 #include "iservice_registry.h"
33 #include "system_ability_definition.h"
34 #include "unistd.h"
35 #include "utils.h"
36 #include "want.h"
37 
38 namespace OHOS {
39 namespace MiscServices {
40     using namespace MessageID;
41 
OnRemoteDied(const wptr<IRemoteObject> & remote)42     void RemoteObjectDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
43     {
44         IMSA_HILOGE("Start");
45         if (handler_ != nullptr) {
46             handler_(remote);
47         }
48     }
49 
SetDeathRecipient(RemoteDiedHandler handler)50     void RemoteObjectDeathRecipient::SetDeathRecipient(RemoteDiedHandler handler)
51     {
52         handler_ = handler;
53     }
54 
PerUserSession(int userId)55     PerUserSession::PerUserSession(int userId) : userId_(userId), imsDeathRecipient(new RemoteObjectDeathRecipient())
56     {
57     }
58 
59     /*! Destructor
60     */
~PerUserSession()61     PerUserSession::~PerUserSession()
62     {
63         imsDeathRecipient = nullptr;
64     }
65 
AddClient(const sptr<IRemoteObject> & inputClient,const ClientInfo & clientInfo)66     int PerUserSession::AddClient(const sptr<IRemoteObject> &inputClient, const ClientInfo &clientInfo)
67     {
68         IMSA_HILOGD("PerUserSession::AddClient");
69         auto cacheClient = GetClientInfo(inputClient);
70         if (cacheClient != nullptr) {
71             IMSA_HILOGI("client is exist, not need add.");
72             return ErrorCode::NO_ERROR;
73         }
74         auto info = std::make_shared<ClientInfo>(clientInfo);
75         if (info == nullptr) {
76             IMSA_HILOGE("info is nullptr");
77             return ErrorCode::ERROR_NULL_POINTER;
78         }
79         info->deathRecipient->SetDeathRecipient(
80             [this, info](const wptr<IRemoteObject> &) { this->OnClientDied(info->client); });
81         sptr<IRemoteObject> obj = info->client->AsObject();
82         if (obj == nullptr) {
83             IMSA_HILOGE("inputClient AsObject is nullptr");
84             return ErrorCode::ERROR_REMOTE_CLIENT_DIED;
85         }
86         if (!obj->AddDeathRecipient(info->deathRecipient)) {
87             IMSA_HILOGE("failed to add death recipient");
88             return ErrorCode::ERROR_ADD_CLIENT_FAILED;
89         }
90         std::lock_guard<std::recursive_mutex> lock(mtx);
91         mapClients.insert({ inputClient, info });
92         return ErrorCode::NO_ERROR;
93     }
94 
UpdateClient(sptr<IRemoteObject> inputClient,bool isShowKeyboard)95     void PerUserSession::UpdateClient(sptr<IRemoteObject> inputClient, bool isShowKeyboard)
96     {
97         IMSA_HILOGD("PerUserSession::start");
98         std::lock_guard<std::recursive_mutex> lock(mtx);
99         auto it = mapClients.find(inputClient);
100         if (it == mapClients.end()) {
101             IMSA_HILOGE("PerUserSession::client not found");
102             return;
103         }
104         it->second->isShowKeyBoard = isShowKeyboard;
105     }
106 
107     /*! Remove an input client
108     \param inputClient remote object handler of the input client
109     \return ErrorCode::NO_ERROR no error
110     \return ErrorCode::ERROR_CLIENT_NOT_FOUND client is not found
111     */
RemoveClient(const sptr<IRemoteObject> & inputClient)112     void PerUserSession::RemoveClient(const sptr<IRemoteObject> &inputClient)
113     {
114         IMSA_HILOGD("PerUserSession::RemoveClient");
115         auto clientInfo = GetClientInfo(inputClient);
116         if (clientInfo == nullptr) {
117             IMSA_HILOGD("client already removed");
118             return;
119         }
120         auto currentClient = GetCurrentClient();
121         if (currentClient != nullptr && currentClient->AsObject() == inputClient) {
122             SetCurrentClient(nullptr);
123         }
124         inputClient->RemoveDeathRecipient(clientInfo->deathRecipient);
125         clientInfo->deathRecipient = nullptr;
126         std::lock_guard<std::recursive_mutex> lock(mtx);
127         mapClients.erase(inputClient);
128     }
129 
130     /*! Show keyboard
131     \param inputClient the remote object handler of the input client.
132     \return ErrorCode::NO_ERROR no error
133     \return ErrorCode::ERROR_IME_NOT_STARTED ime not started
134     \return ErrorCode::ERROR_KBD_IS_OCCUPIED keyboard is showing by other client
135     \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found
136     \return ErrorCode::ERROR_IME_START_FAILED failed to start input method service
137     \return ErrorCode::ERROR_KBD_SHOW_FAILED failed to show keyboard
138     \return other errors returned by binder driver
139     */
ShowKeyboard(const sptr<IInputClient> & inputClient,bool isShowKeyboard)140     int PerUserSession::ShowKeyboard(const sptr<IInputClient>& inputClient, bool isShowKeyboard)
141     {
142         IMSA_HILOGD("PerUserSession::ShowKeyboard");
143         auto clientInfo = GetClientInfo(inputClient->AsObject());
144         int index = GetImeIndex(inputClient);
145         if (index == -1 || clientInfo == nullptr) {
146             IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! index = -1 or clientInfo is nullptr");
147             return ErrorCode::ERROR_CLIENT_NOT_FOUND;
148         }
149         sptr<IInputMethodCore> core = GetImsCore(CURRENT_IME);
150         if (core == nullptr) {
151             IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! imsCore[%{public}d] is nullptr", index);
152             return ErrorCode::ERROR_NULL_POINTER;
153         }
154 
155         auto subProperty = GetCurrentSubProperty();
156         int32_t ret = core->showKeyboard(clientInfo->channel, isShowKeyboard, subProperty);
157         if (ret != ErrorCode::NO_ERROR) {
158             IMSA_HILOGE("PerUserSession::showKeyboard failed ret: %{public}d", ret);
159             return ErrorCode::ERROR_KBD_SHOW_FAILED;
160         }
161         UpdateClient(inputClient->AsObject(), isShowKeyboard);
162         SetCurrentClient(inputClient);
163         return ErrorCode::NO_ERROR;
164     }
165 
166     /*! hide keyboard
167     \param inputClient the remote object handler of the input client.
168     \return ErrorCode::NO_ERROR no error
169     \return ErrorCode::ERROR_IME_NOT_STARTED ime not started
170     \return ErrorCode::ERROR_KBD_IS_NOT_SHOWING keyboard has not been showing
171     \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found
172     \return ErrorCode::ERROR_KBD_HIDE_FAILED failed to hide keyboard
173     \return other errors returned by binder driver
174     */
HideKeyboard(const sptr<IInputClient> & inputClient)175     int PerUserSession::HideKeyboard(const sptr<IInputClient>& inputClient)
176     {
177         IMSA_HILOGD("PerUserSession::HideKeyboard");
178         sptr<IInputMethodCore> core = GetImsCore(CURRENT_IME);
179         if (core == nullptr) {
180             IMSA_HILOGE("PerUserSession::HideKeyboard imsCore is nullptr");
181             return ErrorCode::ERROR_IME_NOT_STARTED;
182         }
183         UpdateClient(inputClient->AsObject(), false);
184         bool ret = core->hideKeyboard(1);
185         if (!ret) {
186             IMSA_HILOGE("PerUserSession::HideKeyboard [imsCore->hideKeyboard] failed");
187             return ErrorCode::ERROR_KBD_HIDE_FAILED;
188         }
189         return ErrorCode::NO_ERROR;
190     }
191 
192     /*! Handle the situation a remote input client died\n
193     It's called when a remote input client died
194     \param the remote object handler of the input client died.
195     */
OnClientDied(sptr<IInputClient> remote)196     void PerUserSession::OnClientDied(sptr<IInputClient> remote)
197     {
198         IMSA_HILOGI("PerUserSession::OnClientDied Start...[%{public}d]\n", userId_);
199         sptr<IInputClient> client = GetCurrentClient();
200         if (client == nullptr) {
201             IMSA_HILOGE("current client is nullptr");
202             RemoveClient(remote->AsObject());
203             return;
204         }
205         if (client->AsObject() == remote->AsObject()) {
206             int ret = HideKeyboard(client);
207             IMSA_HILOGI("hide keyboard ret: %{public}s", ErrorCode::ToString(ret));
208         }
209         RemoveClient(remote->AsObject());
210     }
211 
212     /*! Handle the situation a input method service died\n
213     It's called when an input method service died
214     \param the remote object handler of input method service who died.
215     */
OnImsDied(sptr<IInputMethodCore> remote)216     void PerUserSession::OnImsDied(sptr<IInputMethodCore> remote)
217     {
218         (void)remote;
219         IMSA_HILOGI("Start...[%{public}d]\n", userId_);
220         int index = 0;
221         for (int i = 0; i < MAX_IME; i++) {
222             sptr<IInputMethodCore> core = GetImsCore(i);
223             if (core == remote) {
224                 index = i;
225                 break;
226             }
227         }
228         ClearImeData(index);
229         if (!IsRestartIme(index)) {
230             IMSA_HILOGI("Restart ime over max num");
231             return;
232         }
233         IMSA_HILOGI("IME died. Restart input method...[%{public}d]\n", userId_);
234         auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
235         auto &currentIme = cfg.currentIme;
236         if (currentIme.empty()) {
237             IMSA_HILOGE("currentIme is empty");
238             return;
239         }
240         auto *parcel = new (std::nothrow) MessageParcel();
241         if (parcel == nullptr) {
242             IMSA_HILOGE("parcel is nullptr");
243             return;
244         }
245         parcel->WriteString(currentIme);
246         auto *msg = new (std::nothrow) Message(MSG_ID_START_INPUT_SERVICE, parcel);
247         if (msg == nullptr) {
248             IMSA_HILOGE("msg is nullptr");
249             delete parcel;
250             return;
251         }
252         usleep(MAX_RESET_WAIT_TIME);
253         MessageHandler::Instance()->SendMessage(msg);
254         IMSA_HILOGD("End...[%{public}d]\n", userId_);
255     }
256 
UpdateCurrentUserId(int32_t userId)257     void PerUserSession::UpdateCurrentUserId(int32_t userId)
258     {
259         userId_ = userId;
260     }
261 
262     /*! Hide current keyboard
263     \param flag the flag to hide keyboard.
264     */
OnHideKeyboardSelf()265     int PerUserSession::OnHideKeyboardSelf()
266     {
267         IMSA_HILOGD("PerUserSession::OnHideKeyboardSelf");
268         sptr<IInputClient> client = GetCurrentClient();
269         if (client == nullptr) {
270             IMSA_HILOGE("current client is nullptr");
271             return ErrorCode::ERROR_CLIENT_NOT_FOUND;
272         }
273         return HideKeyboard(client);
274     }
275 
OnShowKeyboardSelf()276     int PerUserSession::OnShowKeyboardSelf()
277     {
278         IMSA_HILOGD("PerUserSession::OnShowKeyboardSelf");
279         sptr<IInputClient> client = GetCurrentClient();
280         if (client == nullptr) {
281             IMSA_HILOGE("current client is nullptr");
282             return ErrorCode::ERROR_CLIENT_NOT_FOUND;
283         }
284         return ShowKeyboard(client, true);
285     }
286 
287     /*! Get ime index for the input client
288     \param inputClient the remote object handler of an input client.
289     \return 0 - default ime
290     \return 1 - security ime
291     \return -1 - input client is not found
292     */
GetImeIndex(const sptr<IInputClient> & inputClient)293     int PerUserSession::GetImeIndex(const sptr<IInputClient>& inputClient)
294     {
295         if (inputClient == nullptr) {
296             IMSA_HILOGW("PerUserSession::GetImeIndex inputClient is nullptr");
297             return -1;
298         }
299 
300         auto clientInfo = GetClientInfo(inputClient->AsObject());
301         if (clientInfo == nullptr) {
302             IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr");
303             return -1;
304         }
305 
306         if (clientInfo->attribute.GetSecurityFlag()) {
307             return SECURITY_IME;
308         }
309         return CURRENT_IME;
310     }
311 
312     /*! Get ClientInfo
313     \param inputClient the IRemoteObject remote handler of given input client
314     \return a pointer of ClientInfo if client is found
315     \n      null if client is not found
316     \note the clientInfo pointer should not be freed by caller
317     */
GetClientInfo(sptr<IRemoteObject> inputClient)318     std::shared_ptr<ClientInfo> PerUserSession::GetClientInfo(sptr<IRemoteObject> inputClient)
319     {
320         std::lock_guard<std::recursive_mutex> lock(mtx);
321         if (inputClient == nullptr) {
322             IMSA_HILOGE("PerUserSession::GetClientInfo inputClient is nullptr");
323             return nullptr;
324         }
325         auto it = mapClients.find(inputClient);
326         if (it == mapClients.end()) {
327             IMSA_HILOGE("PerUserSession::GetClientInfo client not found");
328             return nullptr;
329         }
330         return it->second;
331     }
332 
333     /*! Prepare input. Called by an input client.
334     \n Run in work thread of this user
335     \param the parameters from remote client
336     \return ErrorCode
337     */
OnPrepareInput(const ClientInfo & clientInfo)338     int32_t PerUserSession::OnPrepareInput(const ClientInfo &clientInfo)
339     {
340         IMSA_HILOGD("PerUserSession::OnPrepareInput Start\n");
341         int ret = AddClient(clientInfo.client->AsObject(), clientInfo);
342         if (ret != ErrorCode::NO_ERROR) {
343             IMSA_HILOGE("PerUserSession::OnPrepareInput %{public}s", ErrorCode::ToString(ret));
344             return ErrorCode::ERROR_ADD_CLIENT_FAILED;
345         }
346         SendAgentToSingleClient(clientInfo);
347         return ErrorCode::NO_ERROR;
348     }
349 
SendAgentToSingleClient(const ClientInfo & clientInfo)350     void PerUserSession::SendAgentToSingleClient(const ClientInfo &clientInfo)
351     {
352         IMSA_HILOGD("PerUserSession::SendAgentToSingleClient");
353         if (imsAgent == nullptr) {
354             IMSA_HILOGI("PerUserSession::SendAgentToSingleClient imsAgent is nullptr");
355             CreateComponentFailed(userId_, ErrorCode::ERROR_NULL_POINTER);
356             return;
357         }
358         clientInfo.client->onInputReady(imsAgent);
359     }
360 
361     /*! Release input. Called by an input client.
362     \n Run in work thread of this user
363     \param the parameters from remote client
364     \return ErrorCode
365     */
OnReleaseInput(sptr<IInputClient> client)366     int32_t PerUserSession::OnReleaseInput(sptr<IInputClient> client)
367     {
368         IMSA_HILOGI("PerUserSession::OnReleaseInput Start");
369         RemoveClient(client->AsObject());
370         auto ret = HideKeyboard(client);
371         if (ret != ErrorCode::NO_ERROR) {
372             IMSA_HILOGE("failed to hide keyboard ret %{public}d", ret);
373             return ret;
374         }
375         IMSA_HILOGD("PerUserSession::OnReleaseInput End...[%{public}d]\n", userId_);
376         return ErrorCode::NO_ERROR;
377     }
378 
379     /*! Start input. Called by an input client.
380     \n Run in work thread of this user
381     \param the parameters from remote client
382     \return ErrorCode
383     */
OnStartInput(sptr<IInputClient> client,bool isShowKeyboard)384     int32_t PerUserSession::OnStartInput(sptr<IInputClient> client, bool isShowKeyboard)
385     {
386         IMSA_HILOGI("PerUserSession::OnStartInput");
387         return ShowKeyboard(client, isShowKeyboard);
388     }
389 
OnSetCoreAndAgent(sptr<IInputMethodCore> core,sptr<IInputMethodAgent> agent)390     int32_t PerUserSession::OnSetCoreAndAgent(sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent)
391     {
392         IMSA_HILOGD("PerUserSession::SetCoreAndAgent Start\n");
393         if (core == nullptr || agent == nullptr) {
394             IMSA_HILOGE("PerUserSession::SetCoreAndAgent core or agent nullptr");
395             return ErrorCode::ERROR_EX_NULL_POINTER;
396         }
397         SetImsCore(CURRENT_IME, core);
398         if (imsDeathRecipient != nullptr) {
399             imsDeathRecipient->SetDeathRecipient([this, core](const wptr<IRemoteObject> &) { this->OnImsDied(core); });
400             bool ret = core->AsObject()->AddDeathRecipient(imsDeathRecipient);
401             IMSA_HILOGI("Add death recipient %{public}s", ret ? "success" : "failed");
402         }
403         imsAgent = agent;
404         InitInputControlChannel();
405         SendAgentToAllClients();
406         auto client = GetCurrentClient();
407         if (client != nullptr) {
408             auto it = mapClients.find(client->AsObject());
409             if (it != mapClients.end()) {
410                 IMSA_HILOGI("PerUserSession::Bind IMC to IMA");
411                 OnStartInput(it->second->client, it->second->isShowKeyBoard);
412             }
413         }
414         return ErrorCode::NO_ERROR;
415     }
416 
SendAgentToAllClients()417     void PerUserSession::SendAgentToAllClients()
418     {
419         IMSA_HILOGD("PerUserSession::SendAgentToAllClients");
420         std::lock_guard<std::recursive_mutex> lock(mtx);
421         if (imsAgent == nullptr) {
422             IMSA_HILOGE("PerUserSession::SendAgentToAllClients imsAgent is nullptr");
423             return;
424         }
425 
426         for (auto it = mapClients.begin(); it != mapClients.end(); ++it) {
427             auto clientInfo = it->second;
428             if (clientInfo != nullptr) {
429                 clientInfo->client->onInputReady(imsAgent);
430             }
431         }
432     }
433 
InitInputControlChannel()434     void PerUserSession::InitInputControlChannel()
435     {
436         IMSA_HILOGD("PerUserSession::InitInputControlChannel");
437         sptr<IInputControlChannel> inputControlChannel = new InputControlChannelStub(userId_);
438         sptr<IInputMethodCore> core = GetImsCore(CURRENT_IME);
439         if (core == nullptr) {
440             IMSA_HILOGE("PerUserSession::InitInputControlChannel core is nullptr");
441             return;
442         }
443         auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
444         int ret = core->InitInputControlChannel(inputControlChannel, cfg.currentIme);
445         if (ret != ErrorCode::NO_ERROR) {
446             IMSA_HILOGI("PerUserSession::InitInputControlChannel fail %{public}s", ErrorCode::ToString(ret));
447         }
448     }
449 
450     /*! Stop input. Called by an input client.
451     \n Run in work thread of this user
452     \param the parameters from remote client
453     \return ErrorCode
454     */
OnStopInput(sptr<IInputClient> client)455     int32_t PerUserSession::OnStopInput(sptr<IInputClient> client)
456     {
457         IMSA_HILOGD("PerUserSession::OnStopInput");
458         return HideKeyboard(client);
459     }
460 
StopInputService(std::string imeId)461     void PerUserSession::StopInputService(std::string imeId)
462     {
463         IMSA_HILOGI("PerUserSession::StopInputService");
464         sptr<IInputMethodCore> core = GetImsCore(CURRENT_IME);
465         if (core == nullptr) {
466             IMSA_HILOGE("imsCore[0] is nullptr");
467             return;
468         }
469         IMSA_HILOGI("Remove death recipient");
470         core->AsObject()->RemoveDeathRecipient(imsDeathRecipient);
471         core->StopInputService(imeId);
472     }
473 
IsRestartIme(uint32_t index)474     bool PerUserSession::IsRestartIme(uint32_t index)
475     {
476         IMSA_HILOGD("PerUserSession::IsRestartIme");
477         std::lock_guard<std::mutex> lock(resetLock);
478         auto now = time(nullptr);
479         if (difftime(now, manager[index].last) > IME_RESET_TIME_OUT) {
480             manager[index] = { 0, now };
481         }
482         ++manager[index].num;
483         return manager[index].num <= MAX_RESTART_NUM;
484     }
485 
ClearImeData(uint32_t index)486     void PerUserSession::ClearImeData(uint32_t index)
487     {
488         IMSA_HILOGI("Clear ime...index = %{public}d", index);
489         sptr<IInputMethodCore> core = GetImsCore(index);
490         if (core != nullptr) {
491             core->AsObject()->RemoveDeathRecipient(imsDeathRecipient);
492             SetImsCore(index, nullptr);
493         }
494         inputControlChannel[index] = nullptr;
495     }
496 
SetCurrentClient(sptr<IInputClient> client)497     void PerUserSession::SetCurrentClient(sptr<IInputClient> client)
498     {
499         IMSA_HILOGI("set current client");
500         std::lock_guard<std::mutex> lock(clientLock_);
501         currentClient_ = client;
502     }
503 
GetCurrentClient()504     sptr<IInputClient> PerUserSession::GetCurrentClient()
505     {
506         std::lock_guard<std::mutex> lock(clientLock_);
507         return currentClient_;
508     }
509 
OnInputMethodSwitched(const Property & property,const SubProperty & subProperty)510     void PerUserSession::OnInputMethodSwitched(const Property &property, const SubProperty &subProperty)
511     {
512         IMSA_HILOGD("PerUserSession::OnInputMethodSwitched");
513         std::lock_guard<std::recursive_mutex> lock(mtx);
514         for (const auto &client : mapClients) {
515             auto clientInfo = client.second;
516             if (clientInfo == nullptr) {
517                 IMSA_HILOGD("PerUserSession::clientInfo is nullptr");
518                 continue;
519             }
520             int32_t ret = clientInfo->client->OnSwitchInput(property, subProperty);
521             if (ret != ErrorCode::NO_ERROR) {
522                 IMSA_HILOGE("OnSwitchInput failed, ret: %{public}d, uid: %{public}d", ret,
523                     static_cast<int32_t>(clientInfo->uid));
524                 continue;
525             }
526         }
527         if (subProperty.name != currentSubProperty.name) {
528             SetCurrentSubProperty(subProperty);
529             return;
530         }
531         SetCurrentSubProperty(subProperty);
532         sptr<IInputMethodCore> core = GetImsCore(CURRENT_IME);
533         if (core == nullptr) {
534             IMSA_HILOGE("imsCore is nullptr");
535             return;
536         }
537         int32_t ret = core->SetSubtype(subProperty);
538         if (ret != ErrorCode::NO_ERROR) {
539             IMSA_HILOGE("PerUserSession::SetSubtype failed, ret %{public}d", ret);
540         }
541     }
542 
GetCurrentSubProperty()543     SubProperty PerUserSession::GetCurrentSubProperty()
544     {
545         IMSA_HILOGD("PerUserSession::GetCurrentSubProperty");
546         std::lock_guard<std::mutex> lock(propertyLock_);
547         return currentSubProperty;
548     }
549 
SetCurrentSubProperty(const SubProperty & subProperty)550     void PerUserSession::SetCurrentSubProperty(const SubProperty &subProperty)
551     {
552         IMSA_HILOGD("PerUserSession::SetCurrentSubProperty");
553         std::lock_guard<std::mutex> lock(propertyLock_);
554         currentSubProperty = subProperty;
555     }
556 
GetImsCore(int32_t index)557     sptr<IInputMethodCore> PerUserSession::GetImsCore(int32_t index)
558     {
559         std::lock_guard<std::mutex> lock(imsCoreLock_);
560         if (!IsValid(index)) {
561             return nullptr;
562         }
563         return imsCore[index];
564     }
565 
SetImsCore(int32_t index,sptr<IInputMethodCore> core)566     void PerUserSession::SetImsCore(int32_t index, sptr<IInputMethodCore> core)
567     {
568         std::lock_guard<std::mutex> lock(imsCoreLock_);
569         if (!IsValid(index)) {
570             return;
571         }
572         imsCore[index] = core;
573     }
574 } // namespace MiscServices
575 } // namespace OHOS
576