1 /*
2 * Copyright (C) 2021-2023 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 "input_method_ability.h"
17
18 #include <unistd.h>
19 #include <utility>
20
21 #include "global.h"
22 #include "ima_hisysevent_reporter.h"
23 #include "input_method_agent_stub.h"
24 #include "input_method_core_stub.h"
25 #include "input_method_system_ability_proxy.h"
26 #include "input_method_utils.h"
27 #include "inputmethod_sysevent.h"
28 #include "inputmethod_trace.h"
29 #include "iservice_registry.h"
30 #include "itypes_util.h"
31 #include "message_parcel.h"
32 #include "on_demand_start_stop_sa.h"
33 #include "string_ex.h"
34 #include "sys/prctl.h"
35 #include "system_ability_definition.h"
36 #include "tasks/task.h"
37 #include "tasks/task_imsa.h"
38 #include "task_manager.h"
39
40 namespace OHOS {
41 namespace MiscServices {
42 using namespace MessageID;
43 using namespace std::chrono;
44 sptr<InputMethodAbility> InputMethodAbility::instance_;
45 std::mutex InputMethodAbility::instanceLock_;
46 constexpr double INVALID_CURSOR_VALUE = -1.0;
47 constexpr int32_t INVALID_SELECTION_VALUE = -1;
48 constexpr uint32_t FIND_PANEL_RETRY_INTERVAL = 10;
49 constexpr uint32_t MAX_RETRY_TIMES = 100;
50 constexpr uint32_t START_INPUT_CALLBACK_TIMEOUT_MS = 1000;
51 constexpr uint32_t INVALID_SECURITY_MODE = -1;
52 constexpr uint32_t BASE_TEXT_OPERATION_TIMEOUT = 200;
53
InputMethodAbility()54 InputMethodAbility::InputMethodAbility() { }
55
~InputMethodAbility()56 InputMethodAbility::~InputMethodAbility()
57 {
58 IMSA_HILOGI("InputMethodAbility::~InputMethodAbility.");
59 }
60
GetInstance()61 sptr<InputMethodAbility> InputMethodAbility::GetInstance()
62 {
63 if (instance_ == nullptr) {
64 std::lock_guard<std::mutex> autoLock(instanceLock_);
65 if (instance_ == nullptr) {
66 IMSA_HILOGI("InputMethodAbility need new IMA.");
67 instance_ = new (std::nothrow) InputMethodAbility();
68 if (instance_ == nullptr) {
69 IMSA_HILOGE("instance is nullptr!");
70 return instance_;
71 }
72 instance_->Initialize();
73 }
74 }
75 return instance_;
76 }
77
GetImsaProxy()78 sptr<IInputMethodSystemAbility> InputMethodAbility::GetImsaProxy()
79 {
80 std::lock_guard<std::mutex> lock(abilityLock_);
81 if (abilityManager_ != nullptr) {
82 return abilityManager_;
83 }
84 IMSA_HILOGI("InputMethodAbility get imsa proxy.");
85 auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility();
86 if (systemAbility == nullptr) {
87 IMSA_HILOGE("systemAbility is nullptr!");
88 return nullptr;
89 }
90 if (deathRecipient_ == nullptr) {
91 deathRecipient_ = new (std::nothrow) InputDeathRecipient();
92 if (deathRecipient_ == nullptr) {
93 IMSA_HILOGE("failed to new death recipient!");
94 return nullptr;
95 }
96 }
97 deathRecipient_->SetDeathRecipient([this](const wptr<IRemoteObject> &remote) {
98 OnRemoteSaDied(remote);
99 });
100 if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) {
101 IMSA_HILOGE("failed to add death recipient!");
102 return nullptr;
103 }
104 abilityManager_ = iface_cast<IInputMethodSystemAbility>(systemAbility);
105 return abilityManager_;
106 }
107
SetCoreAndAgent()108 int32_t InputMethodAbility::SetCoreAndAgent()
109 {
110 IMSA_HILOGD("InputMethodAbility, start.");
111 TaskManager::GetInstance().SetInited(true);
112
113 if (isBound_.load()) {
114 IMSA_HILOGD("already bound.");
115 return ErrorCode::NO_ERROR;
116 }
117 auto proxy = GetImsaProxy();
118 if (proxy == nullptr) {
119 IMSA_HILOGE("imsa proxy is nullptr!");
120 return ErrorCode::ERROR_NULL_POINTER;
121 }
122 int32_t ret = proxy->SetCoreAndAgent(coreStub_, agentStub_->AsObject());
123 if (ret != ErrorCode::NO_ERROR) {
124 IMSA_HILOGE("set failed, ret: %{public}d!", ret);
125 return ret;
126 }
127 isBound_.store(true);
128 IMSA_HILOGD("set successfully.");
129 return ErrorCode::NO_ERROR;
130 }
131
InitConnect()132 int32_t InputMethodAbility::InitConnect()
133 {
134 IMSA_HILOGD("InputMethodAbility, init connect.");
135 auto proxy = GetImsaProxy();
136 if (proxy == nullptr) {
137 IMSA_HILOGE("imsa proxy is nullptr!");
138 return ErrorCode::ERROR_NULL_POINTER;
139 }
140 int32_t ret = proxy->InitConnect();
141 if (ret != ErrorCode::NO_ERROR) {
142 IMSA_HILOGE("set failed, ret: %{public}d!", ret);
143 return ret;
144 }
145 return ErrorCode::NO_ERROR;
146 }
147
UnRegisteredProxyIme(UnRegisteredType type)148 int32_t InputMethodAbility::UnRegisteredProxyIme(UnRegisteredType type)
149 {
150 isBound_.store(false);
151 auto proxy = GetImsaProxy();
152 if (proxy == nullptr) {
153 IMSA_HILOGE("imsa proxy is nullptr!");
154 return ErrorCode::ERROR_NULL_POINTER;
155 }
156 return proxy->UnRegisteredProxyIme(type, coreStub_);
157 }
158
Initialize()159 void InputMethodAbility::Initialize()
160 {
161 IMSA_HILOGD("IMA init.");
162 sptr<InputMethodCoreStub> coreStub = new (std::nothrow) InputMethodCoreStub();
163 if (coreStub == nullptr) {
164 IMSA_HILOGE("failed to create core!");
165 return;
166 }
167 sptr<InputMethodAgentStub> agentStub = new (std::nothrow) InputMethodAgentStub();
168 if (agentStub == nullptr) {
169 IMSA_HILOGE("failed to create agent!");
170 return;
171 }
172 agentStub_ = agentStub;
173 coreStub_ = coreStub;
174 }
175
SetImeListener(std::shared_ptr<InputMethodEngineListener> imeListener)176 void InputMethodAbility::SetImeListener(std::shared_ptr<InputMethodEngineListener> imeListener)
177 {
178 IMSA_HILOGD("InputMethodAbility start.");
179 if (imeListener_ == nullptr) {
180 imeListener_ = std::move(imeListener);
181 }
182 }
183
GetImeListener()184 std::shared_ptr<InputMethodEngineListener> InputMethodAbility::GetImeListener()
185 {
186 return imeListener_;
187 }
188
SetKdListener(std::shared_ptr<KeyboardListener> kdListener)189 void InputMethodAbility::SetKdListener(std::shared_ptr<KeyboardListener> kdListener)
190 {
191 IMSA_HILOGD("InputMethodAbility start.");
192 if (kdListener_ == nullptr) {
193 kdListener_ = std::move(kdListener);
194 }
195 }
196
OnInitInputControlChannel(sptr<IRemoteObject> channelObj)197 void InputMethodAbility::OnInitInputControlChannel(sptr<IRemoteObject> channelObj)
198 {
199 IMSA_HILOGD("InputMethodAbility::OnInitInputControlChannel start.");
200 SetInputControlChannel(channelObj);
201 }
202
StartInputInner(const InputClientInfo & clientInfo,bool isBindFromClient)203 int32_t InputMethodAbility::StartInputInner(const InputClientInfo &clientInfo, bool isBindFromClient)
204 {
205 SetBindClientInfo(clientInfo);
206 if (clientInfo.channel == nullptr) {
207 IMSA_HILOGE("channelObject is nullptr!");
208 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
209 }
210 IMSA_HILOGI("IMA showKeyboard:%{public}d,bindFromClient:%{public}d.", clientInfo.isShowKeyboard, isBindFromClient);
211 SetInputDataChannel(clientInfo.channel);
212 if (clientInfo.needHide) {
213 IMSA_HILOGD("pwd or normal input pattern changed, need hide panel first.");
214 auto panel = GetSoftKeyboardPanel();
215 if (panel != nullptr) {
216 panel->HidePanel();
217 }
218 }
219 {
220 std::lock_guard<std::mutex> lock(inputAttrLock_);
221 inputAttribute_.bundleName = clientInfo.config.inputAttribute.bundleName;
222 inputAttribute_.windowId = clientInfo.config.windowId;
223 inputAttribute_.callingDisplayId = clientInfo.config.inputAttribute.callingDisplayId;
224 }
225 int32_t ret = isBindFromClient ? InvokeStartInputCallback(clientInfo.config, clientInfo.isNotifyInputStart) :
226 InvokeStartInputCallback(clientInfo.isNotifyInputStart);
227 if (ret != ErrorCode::NO_ERROR) {
228 IMSA_HILOGE("failed to invoke callback, ret: %{public}d!", ret);
229 return ret;
230 }
231 auto time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
232 auto showPanel = [&, needShow = clientInfo.isShowKeyboard, startTime = time] {
233 auto endTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
234 int32_t ret = ErrorCode::NO_ERROR;
235 if (needShow) {
236 ret = ShowKeyboardImplWithoutLock(cmdId_);
237 }
238 ReportImeStartInput(IInputMethodCore::START_INPUT, ret, needShow, endTime - startTime);
239 isImeTerminating.store(false);
240 };
241 if (!imeListener_) {
242 showPanel();
243 return ErrorCode::NO_ERROR;
244 }
245 uint64_t seqId = Task::GetNextSeqId();
246 imeListener_->PostTaskToEventHandler(
247 [seqId] {
248 TaskManager::GetInstance().Complete(seqId);
249 },
250 "task_manager_complete");
251 TaskManager::GetInstance().WaitExec(seqId, START_INPUT_CALLBACK_TIMEOUT_MS, showPanel);
252 return ErrorCode::NO_ERROR;
253 }
254
OnSetSubtype(SubProperty subProperty)255 void InputMethodAbility::OnSetSubtype(SubProperty subProperty)
256 {
257 if (imeListener_ != nullptr) {
258 imeListener_->OnSetSubtype(subProperty);
259 }
260 }
261
OnSetInputType(InputType inputType)262 void InputMethodAbility::OnSetInputType(InputType inputType)
263 {
264 inputType_ = inputType;
265 IMSA_HILOGD("OnSetInputType, inputType = %{public}d", static_cast<int32_t>(inputType));
266 auto panel = GetSoftKeyboardPanel();
267 if (panel != nullptr) {
268 auto keyboardSize = panel->GetKeyboardSize();
269 SysPanelStatus sysPanelStatus = { inputType_, panel->GetPanelFlag(), keyboardSize.width, keyboardSize.height };
270 NotifyPanelStatus(panel->GetPanelType(), sysPanelStatus);
271 }
272 }
273
ClearDataChannel(const sptr<IRemoteObject> & channel)274 void InputMethodAbility::ClearDataChannel(const sptr<IRemoteObject> &channel)
275 {
276 std::lock_guard<std::mutex> lock(dataChannelLock_);
277 if (dataChannelObject_ == nullptr || channel == nullptr) {
278 IMSA_HILOGD("dataChannelObject_ already nullptr.");
279 return;
280 }
281 if (dataChannelObject_.GetRefPtr() == channel.GetRefPtr()) {
282 dataChannelObject_ = nullptr;
283 dataChannelProxy_ = nullptr;
284 IMSA_HILOGD("end.");
285 }
286 }
287
StopInput(sptr<IRemoteObject> channelObject)288 int32_t InputMethodAbility::StopInput(sptr<IRemoteObject> channelObject)
289 {
290 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
291 int32_t cmdCount = ++cmdId_;
292 IMSA_HILOGI("IMA");
293 HideKeyboardImplWithoutLock(cmdCount);
294 ClearDataChannel(channelObject);
295 ClearInputAttribute();
296 ClearInputType();
297 if (imeListener_ != nullptr) {
298 imeListener_->OnInputFinish();
299 }
300 return ErrorCode::NO_ERROR;
301 }
302
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<KeyEventConsumerProxy> & consumer)303 int32_t InputMethodAbility::DispatchKeyEvent(
304 const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<KeyEventConsumerProxy> &consumer)
305 {
306 if (keyEvent == nullptr) {
307 IMSA_HILOGE("keyEvent is nullptr!");
308 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
309 }
310 if (kdListener_ == nullptr) {
311 IMSA_HILOGE("kdListener_ is nullptr!");
312 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
313 }
314 IMSA_HILOGD("InputMethodAbility, start.");
315
316 if (!kdListener_->OnDealKeyEvent(keyEvent, consumer)) {
317 IMSA_HILOGE("keyEvent not deal!");
318 return ErrorCode::ERROR_DISPATCH_KEY_EVENT;
319 }
320 return ErrorCode::NO_ERROR;
321 }
322
SetCallingWindow(uint32_t windowId)323 void InputMethodAbility::SetCallingWindow(uint32_t windowId)
324 {
325 IMSA_HILOGD("InputMethodAbility windowId: %{public}d.", windowId);
326 {
327 std::lock_guard<std::mutex> lock(inputAttrLock_);
328 inputAttribute_.windowId = windowId;
329 }
330 panels_.ForEach([windowId](const PanelType &panelType, const std::shared_ptr<InputMethodPanel> &panel) {
331 panel->SetCallingWindow(windowId);
332 return false;
333 });
334 if (imeListener_ == nullptr) {
335 IMSA_HILOGD("imeListener_ is nullptr!");
336 return;
337 }
338 imeListener_->OnSetCallingWindow(windowId);
339 }
340
OnCursorUpdate(int32_t positionX,int32_t positionY,int32_t height)341 void InputMethodAbility::OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height)
342 {
343 if (kdListener_ == nullptr) {
344 IMSA_HILOGE("kdListener_ is nullptr!");
345 return;
346 }
347 IMSA_HILOGD("x: %{public}d, y: %{public}d, height: %{public}d.", positionX, positionY, height);
348 kdListener_->OnCursorUpdate(positionX, positionY, height);
349 }
350
OnSelectionChange(std::u16string text,int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)351 void InputMethodAbility::OnSelectionChange(
352 std::u16string text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd)
353 {
354 if (kdListener_ == nullptr) {
355 IMSA_HILOGE("kdListener_ is nullptr!");
356 return;
357 }
358 kdListener_->OnTextChange(Str16ToStr8(text));
359 kdListener_->OnSelectionChange(oldBegin, oldEnd, newBegin, newEnd);
360 }
361
OnAttributeChange(InputAttribute attribute)362 void InputMethodAbility::OnAttributeChange(InputAttribute attribute)
363 {
364 if (kdListener_ == nullptr) {
365 IMSA_HILOGE("kdListener_ is nullptr!");
366 return;
367 }
368 IMSA_HILOGD("enterKeyType: %{public}d, inputPattern: %{public}d.", attribute.enterKeyType, attribute.inputPattern);
369 attribute.bundleName = GetInputAttribute().bundleName;
370 attribute.windowId = GetInputAttribute().windowId;
371 attribute.callingDisplayId = GetInputAttribute().callingDisplayId;
372 SetInputAttribute(attribute);
373 // add for mod inputPattern when panel show
374 auto panel = GetSoftKeyboardPanel();
375 if (panel != nullptr) {
376 auto keyboardSize = panel->GetKeyboardSize();
377 SysPanelStatus sysPanelStatus = { inputType_, panel->GetPanelFlag(), keyboardSize.width, keyboardSize.height };
378 NotifyPanelStatus(panel->GetPanelType(), sysPanelStatus);
379 }
380 kdListener_->OnEditorAttributeChange(attribute);
381 }
382
OnStopInputService(bool isTerminateIme)383 int32_t InputMethodAbility::OnStopInputService(bool isTerminateIme)
384 {
385 IMSA_HILOGI("isTerminateIme: %{public}d.", isTerminateIme);
386 isBound_.store(false);
387 auto imeListener = GetImeListener();
388 if (imeListener == nullptr) {
389 return ErrorCode::ERROR_IME_NOT_STARTED;
390 }
391 if (isTerminateIme) {
392 isImeTerminating.store(true);
393 return imeListener->OnInputStop();
394 }
395 return ErrorCode::NO_ERROR;
396 }
397
HideKeyboard()398 int32_t InputMethodAbility::HideKeyboard()
399 {
400 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
401 int32_t cmdCount = ++cmdId_;
402 return HideKeyboardImplWithoutLock(cmdCount);
403 }
404
HideKeyboardImplWithoutLock(int32_t cmdId)405 int32_t InputMethodAbility::HideKeyboardImplWithoutLock(int32_t cmdId)
406 {
407 if (cmdId != cmdId_) {
408 IMSA_HILOGE("current is not last cmd cur: %{public}d, cmdId_: %{public}d!", cmdId, cmdId_);
409 return ErrorCode::NO_ERROR;
410 }
411 return HideKeyboard(Trigger::IMF);
412 }
413
ShowKeyboard()414 int32_t InputMethodAbility::ShowKeyboard()
415 {
416 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
417 int32_t cmdCount = ++cmdId_;
418 return ShowKeyboardImplWithoutLock(cmdCount);
419 }
420
ShowKeyboardImplWithLock(int32_t cmdId)421 int32_t InputMethodAbility::ShowKeyboardImplWithLock(int32_t cmdId)
422 {
423 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
424 return ShowKeyboardImplWithoutLock(cmdId);
425 }
426
ShowKeyboardImplWithoutLock(int32_t cmdId)427 int32_t InputMethodAbility::ShowKeyboardImplWithoutLock(int32_t cmdId)
428 {
429 if (cmdId != cmdId_) {
430 IMSA_HILOGE("current is not last cmd cur: %{public}d, cmdId_: %{public}d!", cmdId, cmdId_);
431 return ErrorCode::NO_ERROR;
432 }
433 if (imeListener_ == nullptr) {
434 IMSA_HILOGE("imeListener is nullptr!");
435 return ErrorCode::ERROR_IME;
436 }
437 IMSA_HILOGI("IMA start.");
438 if (panels_.Contains(SOFT_KEYBOARD)) {
439 auto panel = GetSoftKeyboardPanel();
440 if (panel == nullptr) {
441 IMSA_HILOGE("panel is nullptr!");
442 return ErrorCode::ERROR_IME;
443 }
444 auto flag = panel->GetPanelFlag();
445 imeListener_->OnKeyboardStatus(true);
446 if (flag == FLG_CANDIDATE_COLUMN) {
447 IMSA_HILOGI("panel flag is candidate, no need to show.");
448 NotifyKeyboardHeight(0, flag);
449 return ErrorCode::NO_ERROR;
450 }
451 return ShowPanel(panel, flag, Trigger::IMF);
452 }
453 isShowAfterCreate_.store(true);
454 IMSA_HILOGI("panel not create.");
455 auto channel = GetInputDataChannelProxy();
456 if (channel != nullptr) {
457 channel->SendKeyboardStatus(KeyboardStatus::SHOW);
458 }
459 imeListener_->OnKeyboardStatus(true);
460 return ErrorCode::NO_ERROR;
461 }
462
NotifyPanelStatusInfo(const PanelStatusInfo & info)463 void InputMethodAbility::NotifyPanelStatusInfo(const PanelStatusInfo &info)
464 {
465 // CANDIDATE_COLUMN not notify
466 auto channel = GetInputDataChannelProxy();
467 NotifyPanelStatusInfo(info, channel);
468 }
469
InvokeStartInputCallback(bool isNotifyInputStart)470 int32_t InputMethodAbility::InvokeStartInputCallback(bool isNotifyInputStart)
471 {
472 TextTotalConfig textConfig = {};
473 int32_t ret = GetTextConfig(textConfig);
474 if (ret == ErrorCode::NO_ERROR) {
475 textConfig.inputAttribute.bundleName = GetInputAttribute().bundleName;
476 return InvokeStartInputCallback(textConfig, isNotifyInputStart);
477 }
478 IMSA_HILOGW("failed to get text config, ret: %{public}d.", ret);
479 if (imeListener_ == nullptr) {
480 IMSA_HILOGE("imeListener_ is nullptr!");
481 return ErrorCode::ERROR_IME;
482 }
483 if (isNotifyInputStart) {
484 imeListener_->OnInputStart();
485 }
486 return ErrorCode::NO_ERROR;
487 }
488
InvokeStartInputCallback(const TextTotalConfig & textConfig,bool isNotifyInputStart)489 int32_t InputMethodAbility::InvokeStartInputCallback(const TextTotalConfig &textConfig, bool isNotifyInputStart)
490 {
491 if (imeListener_ == nullptr) {
492 IMSA_HILOGE("imeListener_ is nullptr!");
493 return ErrorCode::ERROR_IME;
494 }
495 positionY_ = textConfig.positionY;
496 height_ = textConfig.height;
497 auto task = [this, textConfig]() {
498 panels_.ForEach([&textConfig](const PanelType &type, const std::shared_ptr<InputMethodPanel> &panel) {
499 if (panel != nullptr) {
500 panel->SetCallingWindow(textConfig.windowId, true);
501 }
502 return false;
503 });
504 };
505 imeListener_->PostTaskToEventHandler(task, "SetCallingWindow");
506 SetInputAttribute(textConfig.inputAttribute);
507 IMSA_HILOGD("attribute info:%{public}s", textConfig.inputAttribute.ToString().c_str());
508 if (kdListener_ != nullptr) {
509 kdListener_->OnEditorAttributeChange(textConfig.inputAttribute);
510 }
511 if (isNotifyInputStart) {
512 imeListener_->OnInputStart();
513 }
514 if (TextConfig::IsPrivateCommandValid(textConfig.privateCommand) && IsDefaultIme()) {
515 IMSA_HILOGI("notify privateCommand.");
516 imeListener_->ReceivePrivateCommand(textConfig.privateCommand);
517 }
518 if (kdListener_ != nullptr) {
519 if (textConfig.cursorInfo.left != INVALID_CURSOR_VALUE) {
520 kdListener_->OnCursorUpdate(
521 textConfig.cursorInfo.left, textConfig.cursorInfo.top, textConfig.cursorInfo.height);
522 }
523 if (textConfig.textSelection.newBegin == INVALID_SELECTION_VALUE ||
524 (textConfig.textSelection.newBegin == textConfig.textSelection.oldBegin &&
525 textConfig.textSelection.newEnd == textConfig.textSelection.oldEnd)) {
526 IMSA_HILOGD("invalid selection or no selection change");
527 } else {
528 kdListener_->OnSelectionChange(textConfig.textSelection.oldBegin, textConfig.textSelection.oldEnd,
529 textConfig.textSelection.newBegin, textConfig.textSelection.newEnd);
530 }
531 }
532 if (textConfig.windowId != INVALID_WINDOW_ID) {
533 imeListener_->OnSetCallingWindow(textConfig.windowId);
534 }
535 return ErrorCode::NO_ERROR;
536 }
537
InsertTextInner(const std::string & text)538 int32_t InputMethodAbility::InsertTextInner(const std::string &text)
539 {
540 InputMethodSyncTrace tracer("IMA_InsertText");
541 IMSA_HILOGD("InputMethodAbility start.");
542 auto channel = GetInputDataChannelProxy();
543 if (channel == nullptr) {
544 IMSA_HILOGE("channel is nullptr!");
545 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
546 }
547 return channel->InsertText(Str8ToStr16(text));
548 }
549
DeleteForwardInner(int32_t length)550 int32_t InputMethodAbility::DeleteForwardInner(int32_t length)
551 {
552 InputMethodSyncTrace tracer("IMA_DeleteForward");
553 IMSA_HILOGD("InputMethodAbility start, length: %{public}d.", length);
554 auto channel = GetInputDataChannelProxy();
555 if (channel == nullptr) {
556 IMSA_HILOGE("channel is nullptr!");
557 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
558 }
559 return channel->DeleteForward(length);
560 }
561
DeleteBackwardInner(int32_t length)562 int32_t InputMethodAbility::DeleteBackwardInner(int32_t length)
563 {
564 IMSA_HILOGD("InputMethodAbility start, length: %{public}d.", length);
565 auto channel = GetInputDataChannelProxy();
566 if (channel == nullptr) {
567 IMSA_HILOGE("channel is nullptr!");
568 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
569 }
570 return channel->DeleteBackward(length);
571 }
572
SendFunctionKey(int32_t funcKey)573 int32_t InputMethodAbility::SendFunctionKey(int32_t funcKey)
574 {
575 auto channel = GetInputDataChannelProxy();
576 if (channel == nullptr) {
577 IMSA_HILOGE("channel is nullptr!");
578 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
579 }
580 return channel->SendFunctionKey(funcKey);
581 }
582
HideKeyboardSelf()583 int32_t InputMethodAbility::HideKeyboardSelf()
584 {
585 // Current Ime is exiting, hide softkeyboard will cause the TextFiled to lose focus.
586 if (isImeTerminating.load()) {
587 IMSA_HILOGI("Current Ime is terminating, no need to hide keyboard.");
588 return ErrorCode::NO_ERROR;
589 }
590 InputMethodSyncTrace tracer("IMA_HideKeyboardSelf start.");
591 auto ret = HideKeyboard(Trigger::IME_APP);
592 if (ret == ErrorCode::NO_ERROR) {
593 InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_HIDE_SELF);
594 }
595 return ret == ErrorCode::ERROR_CLIENT_NULL_POINTER ? ret : ErrorCode::NO_ERROR;
596 }
597
SendExtendAction(int32_t action)598 int32_t InputMethodAbility::SendExtendAction(int32_t action)
599 {
600 IMSA_HILOGD("InputMethodAbility, action: %{public}d.", action);
601 auto channel = GetInputDataChannelProxy();
602 if (channel == nullptr) {
603 IMSA_HILOGE("channel is nullptr!");
604 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
605 }
606 return channel->HandleExtendAction(action);
607 }
608
GetTextBeforeCursorInner(int32_t number,std::u16string & text)609 int32_t InputMethodAbility::GetTextBeforeCursorInner(int32_t number, std::u16string &text)
610 {
611 InputMethodSyncTrace tracer("IMA_GetForward");
612 IMSA_HILOGD("InputMethodAbility, number: %{public}d.", number);
613 auto channel = GetInputDataChannelProxy();
614 if (channel == nullptr) {
615 IMSA_HILOGE("channel is nullptr!");
616 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
617 }
618 return channel->GetTextBeforeCursor(number, text);
619 }
620
GetTextAfterCursorInner(int32_t number,std::u16string & text)621 int32_t InputMethodAbility::GetTextAfterCursorInner(int32_t number, std::u16string &text)
622 {
623 InputMethodSyncTrace tracer("IMA_GetTextAfterCursor");
624 IMSA_HILOGD("InputMethodAbility, number: %{public}d.", number);
625 auto channel = GetInputDataChannelProxy();
626 if (channel == nullptr) {
627 IMSA_HILOGE("channel is nullptr!");
628 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
629 }
630 return channel->GetTextAfterCursor(number, text);
631 }
632
MoveCursor(int32_t keyCode)633 int32_t InputMethodAbility::MoveCursor(int32_t keyCode)
634 {
635 IMSA_HILOGD("InputMethodAbility, keyCode: %{public}d.", keyCode);
636 auto channel = GetInputDataChannelProxy();
637 if (channel == nullptr) {
638 IMSA_HILOGE("channel is nullptr!");
639 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
640 }
641 return channel->MoveCursor(keyCode);
642 }
643
SelectByRange(int32_t start,int32_t end)644 int32_t InputMethodAbility::SelectByRange(int32_t start, int32_t end)
645 {
646 IMSA_HILOGD("InputMethodAbility, start: %{public}d, end: %{public}d", start, end);
647 if (start < 0 || end < 0) {
648 IMSA_HILOGE("check parameter failed, start: %{public}d, end: %{public}d!", start, end);
649 return ErrorCode::ERROR_PARAMETER_CHECK_FAILED;
650 }
651 auto dataChannel = GetInputDataChannelProxy();
652 if (dataChannel == nullptr) {
653 IMSA_HILOGE("datachannel is nullptr!");
654 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
655 }
656 return dataChannel->SelectByRange(start, end);
657 }
658
SelectByMovement(int32_t direction)659 int32_t InputMethodAbility::SelectByMovement(int32_t direction)
660 {
661 IMSA_HILOGD("InputMethodAbility, direction: %{public}d.", direction);
662 auto dataChannel = GetInputDataChannelProxy();
663 if (dataChannel == nullptr) {
664 IMSA_HILOGE("datachannel is nullptr!");
665 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
666 }
667 return dataChannel->SelectByMovement(direction, 0);
668 }
669
GetEnterKeyType(int32_t & keyType)670 int32_t InputMethodAbility::GetEnterKeyType(int32_t &keyType)
671 {
672 IMSA_HILOGD("InputMethodAbility start.");
673 auto channel = GetInputDataChannelProxy();
674 if (channel == nullptr) {
675 IMSA_HILOGE("channel is nullptr!");
676 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
677 }
678 return channel->GetEnterKeyType(keyType);
679 }
680
GetInputPattern(int32_t & inputPattern)681 int32_t InputMethodAbility::GetInputPattern(int32_t &inputPattern)
682 {
683 IMSA_HILOGD("InputMethodAbility start.");
684 auto channel = GetInputDataChannelProxy();
685 if (channel == nullptr) {
686 IMSA_HILOGE("channel is nullptr!");
687 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
688 }
689 return channel->GetInputPattern(inputPattern);
690 }
691
GetTextIndexAtCursorInner(int32_t & index)692 int32_t InputMethodAbility::GetTextIndexAtCursorInner(int32_t &index)
693 {
694 IMSA_HILOGD("InputMethodAbility start.");
695 auto channel = GetInputDataChannelProxy();
696 if (channel == nullptr) {
697 IMSA_HILOGE("channel is nullptr!");
698 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
699 }
700 return channel->GetTextIndexAtCursor(index);
701 }
702
GetTextConfig(TextTotalConfig & textConfig)703 int32_t InputMethodAbility::GetTextConfig(TextTotalConfig &textConfig)
704 {
705 IMSA_HILOGD("InputMethodAbility start.");
706 auto channel = GetInputDataChannelProxy();
707 if (channel == nullptr) {
708 IMSA_HILOGE("channel is nullptr!");
709 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
710 }
711 auto ret = channel->GetTextConfig(textConfig);
712 if (ret == ErrorCode::NO_ERROR) {
713 textConfig.inputAttribute.bundleName = GetInputAttribute().bundleName;
714 textConfig.inputAttribute.callingDisplayId = GetInputAttribute().callingDisplayId;
715 textConfig.inputAttribute.windowId = textConfig.windowId;
716 }
717 return ret;
718 }
719
SetInputDataChannel(const sptr<IRemoteObject> & object)720 void InputMethodAbility::SetInputDataChannel(const sptr<IRemoteObject> &object)
721 {
722 IMSA_HILOGD("SetInputDataChannel start.");
723 std::lock_guard<std::mutex> lock(dataChannelLock_);
724 auto channelProxy = std::make_shared<InputDataChannelProxy>(object);
725 if (channelProxy == nullptr) {
726 IMSA_HILOGE("failed to create channel proxy!");
727 return;
728 }
729 dataChannelObject_ = object;
730 dataChannelProxy_ = channelProxy;
731 }
732
GetInputDataChannelProxy()733 std::shared_ptr<InputDataChannelProxy> InputMethodAbility::GetInputDataChannelProxy()
734 {
735 std::lock_guard<std::mutex> lock(dataChannelLock_);
736 return dataChannelProxy_;
737 }
738
SetInputControlChannel(sptr<IRemoteObject> & object)739 void InputMethodAbility::SetInputControlChannel(sptr<IRemoteObject> &object)
740 {
741 IMSA_HILOGD("SetInputControlChannel start.");
742 std::lock_guard<std::mutex> lock(controlChannelLock_);
743 std::shared_ptr<InputControlChannelProxy> channelProxy = std::make_shared<InputControlChannelProxy>(object);
744 if (channelProxy == nullptr) {
745 IMSA_HILOGD("channelProxy is nullptr!");
746 return;
747 }
748 controlChannel_ = channelProxy;
749 }
750
ClearInputControlChannel()751 void InputMethodAbility::ClearInputControlChannel()
752 {
753 std::lock_guard<std::mutex> lock(controlChannelLock_);
754 controlChannel_ = nullptr;
755 }
756
GetInputControlChannel()757 std::shared_ptr<InputControlChannelProxy> InputMethodAbility::GetInputControlChannel()
758 {
759 std::lock_guard<std::mutex> lock(controlChannelLock_);
760 return controlChannel_;
761 }
762
OnRemoteSaDied(const wptr<IRemoteObject> & object)763 void InputMethodAbility::OnRemoteSaDied(const wptr<IRemoteObject> &object)
764 {
765 IMSA_HILOGI("input method service died.");
766 isBound_.store(false);
767 ClearInputControlChannel();
768 ClearSystemCmdChannel();
769 {
770 std::lock_guard<std::mutex> lock(abilityLock_);
771 abilityManager_ = nullptr;
772 }
773 if (imeListener_ != nullptr) {
774 imeListener_->OnInputStop();
775 }
776 }
777
GetSecurityMode(int32_t & security)778 int32_t InputMethodAbility::GetSecurityMode(int32_t &security)
779 {
780 IMSA_HILOGI("InputMethodAbility start.");
781 int32_t securityMode = securityMode_.load();
782 if (securityMode != static_cast<int32_t>(INVALID_SECURITY_MODE)) {
783 IMSA_HILOGD("Get cache security mode: %{public}d.", securityMode);
784 security = securityMode;
785 return ErrorCode::NO_ERROR;
786 }
787 auto proxy = GetImsaProxy();
788 if (proxy == nullptr) {
789 IMSA_HILOGE("Imsa proxy is nullptr!");
790 return ErrorCode::ERROR_NULL_POINTER;
791 }
792 auto ret = proxy->GetSecurityMode(security);
793 if (ret == ErrorCode::NO_ERROR) {
794 securityMode_.store(security);
795 }
796 return ret;
797 }
798
ClearSystemCmdChannel()799 void InputMethodAbility::ClearSystemCmdChannel()
800 {
801 std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
802 if (systemCmdChannelProxy_ == nullptr) {
803 IMSA_HILOGD("systemCmdChannelProxy_ already nullptr.");
804 return;
805 }
806 systemCmdChannelProxy_ = nullptr;
807 IMSA_HILOGD("end.");
808 }
809
GetSystemCmdChannelProxy()810 sptr<SystemCmdChannelProxy> InputMethodAbility::GetSystemCmdChannelProxy()
811 {
812 std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
813 return systemCmdChannelProxy_;
814 }
815
OnConnectSystemCmd(const sptr<IRemoteObject> & channel,sptr<IRemoteObject> & agent)816 int32_t InputMethodAbility::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent)
817 {
818 IMSA_HILOGD("InputMethodAbility start.");
819 {
820 std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
821 systemCmdChannelProxy_ = new (std::nothrow) SystemCmdChannelProxy(channel);
822 if (systemCmdChannelProxy_ == nullptr) {
823 IMSA_HILOGE("failed to create channel proxy!");
824 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
825 }
826 }
827 systemAgentStub_ = new (std::nothrow) InputMethodAgentStub();
828 if (systemAgentStub_ == nullptr) {
829 IMSA_HILOGE("failed to create agent!");
830 systemCmdChannelProxy_ = nullptr;
831 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
832 }
833 agent = systemAgentStub_->AsObject();
834 auto panel = GetSoftKeyboardPanel();
835 if (panel != nullptr) {
836 auto flag = panel->GetPanelFlag();
837 if (panel->IsShowing() && flag != FLG_CANDIDATE_COLUMN) {
838 auto keyboardSize = panel->GetKeyboardSize();
839 SysPanelStatus sysPanelStatus = { inputType_, flag, keyboardSize.width, keyboardSize.height };
840 NotifyPanelStatus(panel->GetPanelType(), sysPanelStatus);
841 }
842 }
843 return ErrorCode::NO_ERROR;
844 }
845
OnSecurityChange(int32_t security)846 int32_t InputMethodAbility::OnSecurityChange(int32_t security)
847 {
848 IMSA_HILOGI("InputMethodAbility start.");
849 securityMode_.store(security);
850 if (imeListener_ == nullptr) {
851 IMSA_HILOGE("imeListener_ is nullptr!");
852 return ErrorCode::ERROR_BAD_PARAMETERS;
853 }
854 imeListener_->OnSecurityChange(security);
855 return ErrorCode::NO_ERROR;
856 }
857
AdjustKeyboard()858 int32_t InputMethodAbility::AdjustKeyboard()
859 {
860 if (panels_.Contains(SOFT_KEYBOARD)) {
861 auto panel = GetSoftKeyboardPanel();
862 if (panel == nullptr) {
863 IMSA_HILOGE("panel is nullptr!");
864 return ErrorCode::ERROR_IME;
865 }
866 auto flag = panel->GetPanelFlag();
867 if (flag != FLG_FIXED) {
868 IMSA_HILOGI("panel flag is not fix, no need to adjust.");
869 return ErrorCode::NO_ERROR;
870 }
871 return panel->AdjustKeyboard();
872 }
873 return ErrorCode::NO_ERROR;
874 }
875
CreatePanel(const std::shared_ptr<AbilityRuntime::Context> & context,const PanelInfo & panelInfo,std::shared_ptr<InputMethodPanel> & inputMethodPanel)876 int32_t InputMethodAbility::CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context,
877 const PanelInfo &panelInfo, std::shared_ptr<InputMethodPanel> &inputMethodPanel)
878 {
879 IMSA_HILOGI("InputMethodAbility start.");
880 auto panelHeightCallback = [this](uint32_t panelHeight, PanelFlag panelFlag) {
881 NotifyKeyboardHeight(panelHeight, panelFlag);
882 };
883 auto flag = panels_.ComputeIfAbsent(panelInfo.panelType,
884 [panelHeightCallback, &panelInfo, &context, &inputMethodPanel](
885 const PanelType &panelType, std::shared_ptr<InputMethodPanel> &panel) {
886 inputMethodPanel = std::make_shared<InputMethodPanel>();
887 inputMethodPanel->SetPanelHeightCallback(panelHeightCallback);
888 auto ret = inputMethodPanel->CreatePanel(context, panelInfo);
889 if (ret == ErrorCode::NO_ERROR) {
890 panel = inputMethodPanel;
891 return true;
892 }
893 inputMethodPanel = nullptr;
894 return false;
895 });
896 if (flag && isShowAfterCreate_.load() && panelInfo.panelType == SOFT_KEYBOARD
897 && panelInfo.panelFlag != FLG_CANDIDATE_COLUMN) {
898 isShowAfterCreate_.store(false);
899 auto task = std::make_shared<TaskImsaShowKeyboard>();
900 TaskManager::GetInstance().PostTask(task);
901 }
902 return flag ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
903 }
904
DestroyPanel(const std::shared_ptr<InputMethodPanel> & inputMethodPanel)905 int32_t InputMethodAbility::DestroyPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel)
906 {
907 IMSA_HILOGI("InputMethodAbility start.");
908 if (inputMethodPanel == nullptr) {
909 IMSA_HILOGE("panel is nullptr!");
910 return ErrorCode::ERROR_BAD_PARAMETERS;
911 }
912 auto ret = inputMethodPanel->DestroyPanel();
913 if (ret == ErrorCode::NO_ERROR) {
914 PanelType panelType = inputMethodPanel->GetPanelType();
915 panels_.Erase(panelType);
916 }
917 return ret;
918 }
919
ShowPanel(const std::shared_ptr<InputMethodPanel> & inputMethodPanel)920 int32_t InputMethodAbility::ShowPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel)
921 {
922 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
923 if (inputMethodPanel == nullptr) {
924 return ErrorCode::ERROR_BAD_PARAMETERS;
925 }
926 return ShowPanel(inputMethodPanel, inputMethodPanel->GetPanelFlag(), Trigger::IME_APP);
927 }
928
HidePanel(const std::shared_ptr<InputMethodPanel> & inputMethodPanel)929 int32_t InputMethodAbility::HidePanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel)
930 {
931 if (inputMethodPanel == nullptr) {
932 return ErrorCode::ERROR_BAD_PARAMETERS;
933 }
934 // Current Ime is exiting, hide softkeyboard will cause the TextFiled to lose focus.
935 if (isImeTerminating.load() && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD) {
936 IMSA_HILOGI("Current Ime is terminating, no need to hide keyboard.");
937 return ErrorCode::NO_ERROR;
938 }
939 if (isShowAfterCreate_.load() && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD
940 && inputMethodPanel->GetPanelFlag() != PanelFlag::FLG_CANDIDATE_COLUMN) {
941 isShowAfterCreate_.store(false);
942 }
943 std::lock_guard<std::recursive_mutex> lock(keyboardCmdLock_);
944 return HidePanel(inputMethodPanel, inputMethodPanel->GetPanelFlag(), Trigger::IME_APP);
945 }
946
ShowPanel(const std::shared_ptr<InputMethodPanel> & inputMethodPanel,PanelFlag flag,Trigger trigger)947 int32_t InputMethodAbility::ShowPanel(
948 const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger)
949 {
950 if (inputMethodPanel == nullptr) {
951 return ErrorCode::ERROR_IMA_NULLPTR;
952 }
953 if (trigger == Trigger::IME_APP && GetInputDataChannelProxy() == nullptr) {
954 IMSA_HILOGE("channel is nullptr!");
955 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
956 }
957 if (flag == FLG_FIXED && inputMethodPanel->GetPanelType() == SOFT_KEYBOARD) {
958 auto ret = inputMethodPanel->SetTextFieldAvoidInfo(positionY_, height_);
959 if (ret != ErrorCode::NO_ERROR) {
960 IMSA_HILOGE("failed to set keyBoard, ret: %{public}d!", ret);
961 }
962 }
963 auto keyboardSize = inputMethodPanel->GetKeyboardSize();
964 SysPanelStatus sysPanelStatus = { inputType_, flag, keyboardSize.width, keyboardSize.height };
965 NotifyPanelStatus(inputMethodPanel->GetPanelType(), sysPanelStatus);
966 auto ret = inputMethodPanel->ShowPanel();
967 if (ret == ErrorCode::NO_ERROR) {
968 NotifyPanelStatusInfo({
969 {inputMethodPanel->GetPanelType(), flag},
970 true, trigger
971 });
972 }
973 return ret;
974 }
975
HidePanel(const std::shared_ptr<InputMethodPanel> & inputMethodPanel,PanelFlag flag,Trigger trigger)976 int32_t InputMethodAbility::HidePanel(
977 const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger)
978 {
979 if (inputMethodPanel == nullptr) {
980 return ErrorCode::ERROR_BAD_PARAMETERS;
981 }
982 auto ret = inputMethodPanel->HidePanel();
983 if (ret != ErrorCode::NO_ERROR) {
984 IMSA_HILOGD("failed, ret: %{public}d", ret);
985 return ret;
986 }
987 NotifyPanelStatusInfo({
988 {inputMethodPanel->GetPanelType(), flag},
989 false, trigger
990 });
991 if (trigger == Trigger::IMF && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD) {
992 FinishTextPreview(true);
993 }
994 return ErrorCode::NO_ERROR;
995 }
996
NotifyPanelStatus(PanelType panelType,SysPanelStatus & sysPanelStatus)997 int32_t InputMethodAbility::NotifyPanelStatus(PanelType panelType, SysPanelStatus &sysPanelStatus)
998 {
999 if (panelType != PanelType::SOFT_KEYBOARD) {
1000 return ErrorCode::NO_ERROR;
1001 }
1002 // If it is not binding, do not need to notify the panel
1003 auto channel = GetInputDataChannelProxy();
1004 if (channel == nullptr) {
1005 return ErrorCode::NO_ERROR;
1006 }
1007 sysPanelStatus.inputType = inputType_;
1008 auto systemChannel = GetSystemCmdChannelProxy();
1009 if (systemChannel == nullptr) {
1010 IMSA_HILOGE("channel is nullptr!");
1011 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1012 }
1013 auto panel = GetSoftKeyboardPanel();
1014 if (panel != nullptr) {
1015 sysPanelStatus.isMainDisplay = panel->IsInMainDisplay();
1016 }
1017 return systemChannel->NotifyPanelStatus(sysPanelStatus);
1018 }
1019
SetInputAttribute(const InputAttribute & inputAttribute)1020 void InputMethodAbility::SetInputAttribute(const InputAttribute &inputAttribute)
1021 {
1022 std::lock_guard<std::mutex> lock(inputAttrLock_);
1023 inputAttribute_ = inputAttribute;
1024 }
1025
ClearInputAttribute()1026 void InputMethodAbility::ClearInputAttribute()
1027 {
1028 std::lock_guard<std::mutex> lock(inputAttrLock_);
1029 inputAttribute_ = {};
1030 }
1031
GetInputAttribute()1032 InputAttribute InputMethodAbility::GetInputAttribute()
1033 {
1034 std::lock_guard<std::mutex> lock(inputAttrLock_);
1035 return inputAttribute_;
1036 }
1037
HideKeyboard(Trigger trigger)1038 int32_t InputMethodAbility::HideKeyboard(Trigger trigger)
1039 {
1040 isShowAfterCreate_.store(false);
1041 InputMethodSyncTrace tracer("IMA_HideKeyboard");
1042 if (imeListener_ == nullptr) {
1043 IMSA_HILOGE("imeListener_ is nullptr!");
1044 return ErrorCode::ERROR_IME;
1045 }
1046 IMSA_HILOGD("IMA, trigger: %{public}d.", static_cast<int32_t>(trigger));
1047 if (panels_.Contains(SOFT_KEYBOARD)) {
1048 auto panel = GetSoftKeyboardPanel();
1049 if (panel == nullptr) {
1050 IMSA_HILOGE("panel is nullptr!");
1051 return ErrorCode::ERROR_IME;
1052 }
1053 auto flag = panel->GetPanelFlag();
1054 imeListener_->OnKeyboardStatus(false);
1055 if (flag == FLG_CANDIDATE_COLUMN) {
1056 IMSA_HILOGI("panel flag is candidate, no need to hide.");
1057 return ErrorCode::NO_ERROR;
1058 }
1059 return HidePanel(panel, flag, trigger);
1060 }
1061 IMSA_HILOGI("panel is not created.");
1062 imeListener_->OnKeyboardStatus(false);
1063 auto channel = GetInputDataChannelProxy();
1064 if (channel != nullptr) {
1065 channel->SendKeyboardStatus(KeyboardStatus::HIDE);
1066 }
1067 auto controlChannel = GetInputControlChannel();
1068 if (controlChannel != nullptr && trigger == Trigger::IME_APP) {
1069 controlChannel->HideKeyboardSelf();
1070 }
1071 return ErrorCode::NO_ERROR;
1072 }
1073
GetSoftKeyboardPanel()1074 std::shared_ptr<InputMethodPanel> InputMethodAbility::GetSoftKeyboardPanel()
1075 {
1076 auto result = panels_.Find(SOFT_KEYBOARD);
1077 if (!result.first) {
1078 return nullptr;
1079 }
1080 auto panel = result.second;
1081 if (!BlockRetry(FIND_PANEL_RETRY_INTERVAL, MAX_RETRY_TIMES, [panel]() -> bool {
1082 return panel != nullptr && panel->windowId_ != InputMethodPanel::INVALID_WINDOW_ID;
1083 })) {
1084 return nullptr;
1085 }
1086 return panel;
1087 }
1088
IsCurrentIme()1089 bool InputMethodAbility::IsCurrentIme()
1090 {
1091 IMSA_HILOGD("InputMethodAbility start.");
1092 if (isCurrentIme_) {
1093 return true;
1094 }
1095 std::lock_guard<std::mutex> lock(imeCheckMutex_);
1096 if (isCurrentIme_) {
1097 return true;
1098 }
1099 auto proxy = GetImsaProxy();
1100 if (proxy == nullptr) {
1101 IMSA_HILOGE("failed to get imsa proxy!");
1102 return false;
1103 }
1104 if (proxy->IsCurrentIme()) {
1105 isCurrentIme_ = true;
1106 return true;
1107 }
1108 return false;
1109 }
1110
IsDefaultIme()1111 bool InputMethodAbility::IsDefaultIme()
1112 {
1113 IMSA_HILOGD("InputMethodAbility start");
1114 if (isDefaultIme_) {
1115 return true;
1116 }
1117 std::lock_guard<std::mutex> lock(defaultImeCheckMutex_);
1118 if (isDefaultIme_) {
1119 return true;
1120 }
1121 auto proxy = GetImsaProxy();
1122 if (proxy == nullptr) {
1123 IMSA_HILOGE("failed to get imsa proxy!");
1124 return false;
1125 }
1126 auto ret = proxy->IsDefaultIme();
1127 if (ret == ErrorCode::NO_ERROR) {
1128 isDefaultIme_ = true;
1129 return true;
1130 }
1131 IMSA_HILOGE("call IsDefaultIme failed, ret: %{public}d!", ret);
1132 return false;
1133 }
1134
IsEnable()1135 bool InputMethodAbility::IsEnable()
1136 {
1137 if (imeListener_ == nullptr) {
1138 return false;
1139 }
1140 return imeListener_->IsEnable();
1141 }
1142
IsSystemApp()1143 bool InputMethodAbility::IsSystemApp()
1144 {
1145 IMSA_HILOGD("InputMethodAbility start");
1146 if (isSystemApp_) {
1147 return true;
1148 }
1149 std::lock_guard<std::mutex> lock(systemAppCheckMutex_);
1150 if (isSystemApp_) {
1151 return true;
1152 }
1153 auto proxy = GetImsaProxy();
1154 if (proxy == nullptr) {
1155 IMSA_HILOGE("failed to get imsa proxy!");
1156 return false;
1157 }
1158 if (proxy->IsSystemApp()) {
1159 isSystemApp_ = true;
1160 return true;
1161 }
1162 return false;
1163 }
1164
ExitCurrentInputType()1165 int32_t InputMethodAbility::ExitCurrentInputType()
1166 {
1167 IMSA_HILOGD("InputMethodAbility start.");
1168 ClearInputType();
1169 auto panel = GetSoftKeyboardPanel();
1170 if (panel != nullptr) {
1171 auto keyboardSize = panel->GetKeyboardSize();
1172 SysPanelStatus sysPanelStatus = { inputType_, panel->GetPanelFlag(), keyboardSize.width, keyboardSize.height };
1173 NotifyPanelStatus(panel->GetPanelType(), sysPanelStatus);
1174 }
1175 auto proxy = GetImsaProxy();
1176 if (proxy == nullptr) {
1177 IMSA_HILOGE("failed to get imsa proxy!");
1178 return false;
1179 }
1180 return proxy->ExitCurrentInputType();
1181 }
1182
ClearInputType()1183 void InputMethodAbility::ClearInputType()
1184 {
1185 std::lock_guard<std::mutex> lock(inputTypeLock_);
1186 if (inputType_ != InputType::SECURITY_INPUT) {
1187 inputType_ = InputType::NONE;
1188 }
1189 }
1190
IsPanelShown(const PanelInfo & panelInfo,bool & isShown)1191 int32_t InputMethodAbility::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
1192 {
1193 isShown = false;
1194 auto result = panels_.Find(panelInfo.panelType);
1195 if (!result.first) {
1196 IMSA_HILOGI("panel type: %{public}d not found.", static_cast<int32_t>(panelInfo.panelType));
1197 return ErrorCode::NO_ERROR;
1198 }
1199 auto panel = result.second;
1200 if (panel->GetPanelType() == PanelType::SOFT_KEYBOARD && panel->GetPanelFlag() != panelInfo.panelFlag) {
1201 IMSA_HILOGI("queried flag: %{public}d, current flag: %{public}d, panel not found.",
1202 static_cast<int32_t>(panelInfo.panelFlag), static_cast<int32_t>(panel->GetPanelFlag()));
1203 return ErrorCode::NO_ERROR;
1204 }
1205 isShown = panel->IsShowing();
1206 IMSA_HILOGI("type: %{public}d, flag: %{public}d, result: %{public}d.", static_cast<int32_t>(panelInfo.panelType),
1207 static_cast<int32_t>(panelInfo.panelFlag), isShown);
1208 return ErrorCode::NO_ERROR;
1209 }
1210
OnClientInactive(const sptr<IRemoteObject> & channel)1211 void InputMethodAbility::OnClientInactive(const sptr<IRemoteObject> &channel)
1212 {
1213 IMSA_HILOGI("client inactive.");
1214 if (imeListener_ != nullptr) {
1215 imeListener_->OnInputFinish();
1216 }
1217 auto channelProxy = std::make_shared<InputDataChannelProxy>(channel);
1218 if (channelProxy == nullptr) {
1219 IMSA_HILOGE("failed to create channel proxy!");
1220 return;
1221 }
1222 auto panel = GetSoftKeyboardPanel();
1223 if (imeListener_ != nullptr && panel != nullptr && panel->GetPanelFlag() != PanelFlag::FLG_FIXED) {
1224 imeListener_->OnKeyboardStatus(false);
1225 }
1226 panels_.ForEach([this, &channelProxy](const PanelType &panelType, const std::shared_ptr<InputMethodPanel> &panel) {
1227 if (panelType != PanelType::SOFT_KEYBOARD || panel->GetPanelFlag() != PanelFlag::FLG_FIXED) {
1228 auto ret = panel->HidePanel();
1229 if (ret != ErrorCode::NO_ERROR) {
1230 IMSA_HILOGE("failed, ret: %{public}d", ret);
1231 return false;
1232 }
1233 NotifyPanelStatusInfo({ { panel->GetPanelType(), panel->GetPanelFlag() }, false, Trigger::IME_APP },
1234 channelProxy);
1235 // finish previewing text when soft keyboard hides
1236 if (panel->GetPanelType() == PanelType::SOFT_KEYBOARD) {
1237 FinishTextPreview(true);
1238 }
1239 }
1240 return false;
1241 });
1242 ClearDataChannel(channel);
1243 }
1244
NotifyKeyboardHeight(uint32_t panelHeight,PanelFlag panelFlag)1245 void InputMethodAbility::NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag)
1246 {
1247 auto channel = GetInputDataChannelProxy();
1248 if (channel == nullptr) {
1249 IMSA_HILOGE("channel is nullptr!");
1250 return;
1251 }
1252 IMSA_HILOGD("notify panel height: %{public}u, flag: %{public}d.", panelHeight, static_cast<int32_t>(panelFlag));
1253 if (panelFlag != PanelFlag::FLG_FIXED) {
1254 channel->NotifyKeyboardHeight(0);
1255 return;
1256 }
1257 channel->NotifyKeyboardHeight(panelHeight);
1258 }
1259
SendPrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)1260 int32_t InputMethodAbility::SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
1261 {
1262 if (!IsDefaultIme()) {
1263 IMSA_HILOGE("current is not default ime!");
1264 return ErrorCode::ERROR_NOT_DEFAULT_IME;
1265 }
1266 if (!TextConfig::IsPrivateCommandValid(privateCommand)) {
1267 IMSA_HILOGE("privateCommand is limit 32KB, count limit 5!");
1268 return ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE;
1269 }
1270 if (TextConfig::IsSystemPrivateCommand(privateCommand)) {
1271 auto systemChannel = GetSystemCmdChannelProxy();
1272 if (systemChannel == nullptr) {
1273 IMSA_HILOGE("channel is nullptr!");
1274 return ErrorCode::ERROR_SYSTEM_CMD_CHANNEL_ERROR;
1275 }
1276 return systemChannel->SendPrivateCommand(privateCommand);
1277 } else {
1278 auto channel = GetInputDataChannelProxy();
1279 if (channel == nullptr) {
1280 IMSA_HILOGE("channel is nullptr!");
1281 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1282 }
1283 return channel->SendPrivateCommand(privateCommand);
1284 }
1285 }
1286
ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)1287 int32_t InputMethodAbility::ReceivePrivateCommand(
1288 const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
1289 {
1290 if (imeListener_ == nullptr) {
1291 IMSA_HILOGE("imeListener is nullptr!");
1292 return ErrorCode::ERROR_IME;
1293 }
1294 imeListener_->ReceivePrivateCommand(privateCommand);
1295 return ErrorCode::NO_ERROR;
1296 }
1297
SetPreviewTextInner(const std::string & text,const Range & range)1298 int32_t InputMethodAbility::SetPreviewTextInner(const std::string &text, const Range &range)
1299 {
1300 InputMethodSyncTrace tracer("IMA_SetPreviewText");
1301 auto dataChannel = GetInputDataChannelProxy();
1302 if (dataChannel == nullptr) {
1303 IMSA_HILOGE("dataChannel is nullptr!");
1304 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
1305 }
1306 return dataChannel->SetPreviewText(text, range);
1307 }
1308
FinishTextPreviewInner(bool isAsync)1309 int32_t InputMethodAbility::FinishTextPreviewInner(bool isAsync)
1310 {
1311 InputMethodSyncTrace tracer("IMA_FinishTextPreview");
1312 auto dataChannel = GetInputDataChannelProxy();
1313 if (dataChannel == nullptr) {
1314 IMSA_HILOGE("dataChannel is nullptr!");
1315 return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR;
1316 }
1317 return dataChannel->FinishTextPreview(isAsync);
1318 }
1319
GetCallingWindowInfo(CallingWindowInfo & windowInfo)1320 int32_t InputMethodAbility::GetCallingWindowInfo(CallingWindowInfo &windowInfo)
1321 {
1322 IMSA_HILOGD("IMA start.");
1323 auto channel = GetInputDataChannelProxy();
1324 if (channel == nullptr) {
1325 IMSA_HILOGE("channel is nullptr!");
1326 return ErrorCode::ERROR_CLIENT_NOT_FOUND;
1327 }
1328 auto panel = GetSoftKeyboardPanel();
1329 if (panel == nullptr) {
1330 IMSA_HILOGE("panel not found!");
1331 return ErrorCode::ERROR_PANEL_NOT_FOUND;
1332 }
1333 TextTotalConfig textConfig;
1334 int32_t ret = GetTextConfig(textConfig);
1335 if (ret != ErrorCode::NO_ERROR) {
1336 IMSA_HILOGE("failed to get window id, ret: %{public}d!", ret);
1337 return ErrorCode::ERROR_GET_TEXT_CONFIG;
1338 }
1339 ret = panel->SetCallingWindow(textConfig.windowId);
1340 if (ret != ErrorCode::NO_ERROR) {
1341 IMSA_HILOGE("failed to set calling window, ret: %{public}d!", ret);
1342 return ret;
1343 }
1344 ret = panel->GetCallingWindowInfo(windowInfo);
1345 if (ret != ErrorCode::NO_ERROR) {
1346 IMSA_HILOGE("failed to get calling window, ret: %{public}d", ret);
1347 }
1348 return ret;
1349 }
1350
NotifyPanelStatusInfo(const PanelStatusInfo & info,std::shared_ptr<InputDataChannelProxy> & channelProxy)1351 void InputMethodAbility::NotifyPanelStatusInfo(
1352 const PanelStatusInfo &info, std::shared_ptr<InputDataChannelProxy> &channelProxy)
1353 {
1354 // CANDIDATE_COLUMN not notify
1355 if (info.panelInfo.panelFlag == PanelFlag::FLG_CANDIDATE_COLUMN) {
1356 return;
1357 }
1358 if (channelProxy != nullptr) {
1359 channelProxy->NotifyPanelStatusInfo(info);
1360 }
1361
1362 auto controlChannel = GetInputControlChannel();
1363 if (controlChannel != nullptr && info.trigger == Trigger::IME_APP && !info.visible) {
1364 controlChannel->HideKeyboardSelf();
1365 }
1366 }
1367
SendMessage(const ArrayBuffer & arrayBuffer)1368 int32_t InputMethodAbility::SendMessage(const ArrayBuffer &arrayBuffer)
1369 {
1370 int32_t securityMode = INVALID_SECURITY_MODE;
1371 auto ret = GetSecurityMode(securityMode);
1372 if (ret != ErrorCode::NO_ERROR) {
1373 IMSA_HILOGE("Get security mode failed!");
1374 return ret;
1375 }
1376 if (!ArrayBuffer::IsSizeValid(arrayBuffer)) {
1377 IMSA_HILOGE("arrayBuffer size is invalid!");
1378 return ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE;
1379 }
1380 if (securityMode != static_cast<int32_t>(SecurityMode::FULL)) {
1381 IMSA_HILOGE("Security mode must be FULL!.");
1382 return ErrorCode::ERROR_SECURITY_MODE_OFF;
1383 }
1384 auto dataChannel = GetInputDataChannelProxy();
1385 if (dataChannel == nullptr) {
1386 IMSA_HILOGE("datachannel is nullptr.");
1387 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
1388 }
1389 return dataChannel->SendMessage(arrayBuffer);
1390 }
1391
RecvMessage(const ArrayBuffer & arrayBuffer)1392 int32_t InputMethodAbility::RecvMessage(const ArrayBuffer &arrayBuffer)
1393 {
1394 int32_t securityMode = -1;
1395 auto ret = GetSecurityMode(securityMode);
1396 if (ret != ErrorCode::NO_ERROR) {
1397 IMSA_HILOGE("Get security mode failed!");
1398 return ret;
1399 }
1400 if (securityMode != static_cast<int32_t>(SecurityMode::FULL)) {
1401 IMSA_HILOGE("Security mode must be FULL!.");
1402 return ErrorCode::ERROR_SECURITY_MODE_OFF;
1403 }
1404 auto msgHandlerCallback = GetMsgHandlerCallback();
1405 if (msgHandlerCallback == nullptr) {
1406 IMSA_HILOGW("Message handler was not regist!");
1407 return ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST;
1408 }
1409 return msgHandlerCallback->OnMessage(arrayBuffer);
1410 }
1411
RegisterMsgHandler(const std::shared_ptr<MsgHandlerCallbackInterface> & msgHandler)1412 int32_t InputMethodAbility::RegisterMsgHandler(const std::shared_ptr<MsgHandlerCallbackInterface> &msgHandler)
1413 {
1414 IMSA_HILOGI("isRegist: %{public}d", msgHandler != nullptr);
1415 std::shared_ptr<MsgHandlerCallbackInterface> exMsgHandler = nullptr;
1416 {
1417 std::lock_guard<decltype(msgHandlerMutex_)> lock(msgHandlerMutex_);
1418 exMsgHandler = msgHandler_;
1419 msgHandler_ = msgHandler;
1420 }
1421 if (exMsgHandler != nullptr) {
1422 IMSA_HILOGI("Trigger exMessageHandler OnTerminated.");
1423 exMsgHandler->OnTerminated();
1424 }
1425 return ErrorCode::NO_ERROR;
1426 }
1427
GetMsgHandlerCallback()1428 std::shared_ptr<MsgHandlerCallbackInterface> InputMethodAbility::GetMsgHandlerCallback()
1429 {
1430 std::lock_guard<decltype(msgHandlerMutex_)> lock(msgHandlerMutex_);
1431 return msgHandler_;
1432 }
1433
StartInput(const InputClientInfo & clientInfo,bool isBindFromClient)1434 int32_t InputMethodAbility::StartInput(const InputClientInfo &clientInfo, bool isBindFromClient)
1435 {
1436 auto ret = StartInputInner(clientInfo, isBindFromClient);
1437 if (ret == ErrorCode::NO_ERROR) {
1438 return ret;
1439 }
1440 ReportImeStartInput(IInputMethodCore::START_INPUT, ret, clientInfo.isShowKeyboard);
1441 return ret;
1442 }
1443
InsertText(const std::string text)1444 int32_t InputMethodAbility::InsertText(const std::string text)
1445 {
1446 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1447 auto ret = InsertTextInner(text);
1448 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1449 ReportBaseTextOperation(IInputDataChannel::INSERT_TEXT, ret, end - start);
1450 return ret;
1451 }
1452
DeleteForward(int32_t length)1453 int32_t InputMethodAbility::DeleteForward(int32_t length)
1454 {
1455 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1456 auto ret = DeleteForwardInner(length);
1457 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1458 ReportBaseTextOperation(IInputDataChannel::DELETE_FORWARD, ret, end - start);
1459 return ret;
1460 }
1461
DeleteBackward(int32_t length)1462 int32_t InputMethodAbility::DeleteBackward(int32_t length)
1463 {
1464 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1465 auto ret = DeleteBackwardInner(length);
1466 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1467 ReportBaseTextOperation(IInputDataChannel::DELETE_BACKWARD, ret, end - start);
1468 return ret;
1469 }
1470
SetPreviewText(const std::string & text,const Range & range)1471 int32_t InputMethodAbility::SetPreviewText(const std::string &text, const Range &range)
1472 {
1473 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1474 auto ret = SetPreviewTextInner(text, range);
1475 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1476 ReportBaseTextOperation(IInputDataChannel::SET_PREVIEW_TEXT, ret, end - start);
1477 return ret;
1478 }
1479
FinishTextPreview(bool isSync)1480 int32_t InputMethodAbility::FinishTextPreview(bool isSync)
1481 {
1482 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1483 auto ret = FinishTextPreviewInner(isSync);
1484 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1485 ReportBaseTextOperation(IInputDataChannel::FINISH_TEXT_PREVIEW, ret, end - start);
1486 return ret;
1487 }
1488
GetTextBeforeCursor(int32_t number,std::u16string & text)1489 int32_t InputMethodAbility::GetTextBeforeCursor(int32_t number, std::u16string &text)
1490 {
1491 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1492 auto ret = GetTextBeforeCursorInner(number, text);
1493 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1494 ReportBaseTextOperation(IInputDataChannel::GET_TEXT_BEFORE_CURSOR, ret, end - start);
1495 return ret;
1496 }
GetTextAfterCursor(int32_t number,std::u16string & text)1497 int32_t InputMethodAbility::GetTextAfterCursor(int32_t number, std::u16string &text)
1498 {
1499 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1500 auto ret = GetTextAfterCursorInner(number, text);
1501 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1502 ReportBaseTextOperation(IInputDataChannel::GET_TEXT_AFTER_CURSOR, ret, end - start);
1503 return ret;
1504 }
GetTextIndexAtCursor(int32_t & index)1505 int32_t InputMethodAbility::GetTextIndexAtCursor(int32_t &index)
1506 {
1507 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1508 auto ret = GetTextIndexAtCursorInner(index);
1509 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1510 ReportBaseTextOperation(IInputDataChannel::GET_TEXT_INDEX_AT_CURSOR, ret, end - start);
1511 return ret;
1512 }
1513
SetBindClientInfo(const InputClientInfo & clientInfo)1514 void InputMethodAbility::SetBindClientInfo(const InputClientInfo &clientInfo)
1515 {
1516 std::lock_guard<std::mutex> lock(bindClientInfoLock_);
1517 bindClientInfo_ = { clientInfo.pid, clientInfo.type, clientInfo.name };
1518 }
1519
GetBindClientInfo()1520 HiSysEventClientInfo InputMethodAbility::GetBindClientInfo()
1521 {
1522 std::lock_guard<std::mutex> lock(bindClientInfoLock_);
1523 return bindClientInfo_;
1524 }
1525
ReportImeStartInput(int32_t eventCode,int32_t errCode,bool isShowKeyboard,int64_t consumeTime)1526 void InputMethodAbility::ReportImeStartInput(
1527 int32_t eventCode, int32_t errCode, bool isShowKeyboard, int64_t consumeTime)
1528 {
1529 IMSA_HILOGD("HiSysEvent report start:[%{public}d, %{public}d]!", eventCode, errCode);
1530 auto clientInfo = GetBindClientInfo();
1531 auto evenInfo = HiSysOriginalInfo::Builder()
1532 .SetPeerName(clientInfo.name)
1533 .SetPeerPid(clientInfo.pid)
1534 .SetIsShowKeyboard(isShowKeyboard)
1535 .SetEventCode(eventCode)
1536 .SetErrCode(errCode)
1537 .SetImeCbTime(consumeTime)
1538 .Build();
1539 ImaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::IME_START_INPUT, *evenInfo);
1540 IMSA_HILOGD("HiSysEvent report end:[%{public}d, %{public}d]!", eventCode, errCode);
1541 }
1542
ReportBaseTextOperation(int32_t eventCode,int32_t errCode,int64_t consumeTime)1543 void InputMethodAbility::ReportBaseTextOperation(int32_t eventCode, int32_t errCode, int64_t consumeTime)
1544 {
1545 IMSA_HILOGD("HiSysEvent report start:[%{public}d, %{public}d]!", eventCode, errCode);
1546 auto clientInfo = GetBindClientInfo();
1547 if (errCode == ErrorCode::NO_ERROR && consumeTime > BASE_TEXT_OPERATION_TIMEOUT) {
1548 errCode = ErrorCode::ERROR_DEAL_TIMEOUT;
1549 }
1550 auto evenInfo = HiSysOriginalInfo::Builder()
1551 .SetPeerName(clientInfo.name)
1552 .SetPeerPid(clientInfo.pid)
1553 .SetClientType(clientInfo.type)
1554 .SetEventCode(eventCode)
1555 .SetErrCode(errCode)
1556 .SetBaseTextOperatorTime(consumeTime)
1557 .Build();
1558 ImaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::BASE_TEXT_OPERATOR, *evenInfo);
1559 IMSA_HILOGD("HiSysEvent report end:[%{public}d, %{public}d]!", eventCode, errCode);
1560 }
1561
OnCallingDisplayIdChanged(uint64_t displayId)1562 int32_t InputMethodAbility::OnCallingDisplayIdChanged(uint64_t displayId)
1563 {
1564 IMSA_HILOGD("InputMethodAbility calling display: %{public}" PRIu64".", displayId);
1565 if (imeListener_ == nullptr) {
1566 IMSA_HILOGD("imeListener_ is nullptr!");
1567 return ErrorCode::NO_ERROR;
1568 }
1569 auto windowId = GetInputAttribute().windowId;
1570 auto task = [this, windowId]() {
1571 panels_.ForEach([windowId](const PanelType &panelType, const std::shared_ptr<InputMethodPanel> &panel) {
1572 if (panel != nullptr) {
1573 panel->SetCallingWindow(windowId, true);
1574 }
1575 return false;
1576 });
1577 };
1578 imeListener_->PostTaskToEventHandler(task, "SetCallingWindow");
1579 {
1580 std::lock_guard<std::mutex> lock(inputAttrLock_);
1581 inputAttribute_.callingDisplayId = displayId;
1582 }
1583 imeListener_->OnCallingDisplayIdChanged(displayId);
1584 return ErrorCode::NO_ERROR;
1585 }
1586
GetCallingWindowDisplayId()1587 uint64_t InputMethodAbility::GetCallingWindowDisplayId()
1588 {
1589 return GetInputAttribute().callingDisplayId;
1590 }
1591 } // namespace MiscServices
1592 } // namespace OHOS