1 /*
2  * Copyright (c) 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 "text_listener.h"
17 
18 #include "input_method_utils.h"
19 
20 namespace OHOS {
21 namespace MiscServices {
22 constexpr uint32_t KEYBOARD_STATUS_WAIT_TIME_OUT = 2;
23 std::mutex TextListener::textListenerCallbackLock_;
24 std::condition_variable TextListener::textListenerCv_;
25 int32_t TextListener::direction_ = -1;
26 int32_t TextListener::deleteForwardLength_ = -1;
27 int32_t TextListener::deleteBackwardLength_ = -1;
28 std::u16string TextListener::insertText_;
29 int32_t TextListener::key_ = -1;
30 bool TextListener::status_ = false;
31 int32_t TextListener::selectionStart_ = -1;
32 int32_t TextListener::selectionEnd_ = -1;
33 int32_t TextListener::selectionDirection_ = -1;
34 int32_t TextListener::selectionSkip_ = -1;
35 int32_t TextListener::action_ = -1;
36 uint32_t TextListener::height_ = 0;
37 KeyboardStatus TextListener::keyboardStatus_ = { KeyboardStatus::NONE };
38 PanelStatusInfo TextListener::info_{};
39 std::unordered_map<std::string, PrivateDataValue> TextListener::privateCommand_{};
40 std::string TextListener::previewText_;
41 Range TextListener::previewRange_{};
42 bool TextListener::isFinishTextPreviewCalled_{ false };
TextListener()43 TextListener::TextListener()
44 {
45     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("TextListenerNotifier");
46     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
47 }
48 
~TextListener()49 TextListener::~TextListener()
50 {
51 }
52 
InsertText(const std::u16string & text)53 void TextListener::InsertText(const std::u16string &text)
54 {
55     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
56     insertText_ = text;
57     textListenerCv_.notify_one();
58     IMSA_HILOGI("TextListener text: %{public}s", Str16ToStr8(text).c_str());
59 }
60 
DeleteForward(int32_t length)61 void TextListener::DeleteForward(int32_t length)
62 {
63     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
64     deleteForwardLength_ = length;
65     textListenerCv_.notify_one();
66     IMSA_HILOGI("TextListener: DeleteForward, length is: %{public}d", length);
67 }
68 
DeleteBackward(int32_t length)69 void TextListener::DeleteBackward(int32_t length)
70 {
71     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
72     deleteBackwardLength_ = length;
73     textListenerCv_.notify_one();
74     IMSA_HILOGI("TextListener: DeleteBackward, direction is: %{public}d", length);
75 }
76 
SendKeyEventFromInputMethod(const KeyEvent & event)77 void TextListener::SendKeyEventFromInputMethod(const KeyEvent &event)
78 {
79 }
80 
SendKeyboardStatus(const KeyboardStatus & keyboardStatus)81 void TextListener::SendKeyboardStatus(const KeyboardStatus &keyboardStatus)
82 {
83     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
84     IMSA_HILOGI("TextListener::SendKeyboardStatus %{public}d", static_cast<int>(keyboardStatus));
85     keyboardStatus_ = keyboardStatus;
86     textListenerCv_.notify_one();
87 }
88 
SendFunctionKey(const FunctionKey & functionKey)89 void TextListener::SendFunctionKey(const FunctionKey &functionKey)
90 {
91     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
92     EnterKeyType enterKeyType = functionKey.GetEnterKeyType();
93     key_ = static_cast<int32_t>(enterKeyType);
94     IMSA_HILOGI("TextListener functionKey: %{public}d", key_);
95     textListenerCv_.notify_one();
96 }
97 
SetKeyboardStatus(bool status)98 void TextListener::SetKeyboardStatus(bool status)
99 {
100     status_ = status;
101     IMSA_HILOGI("TextListener status: %{public}d", status);
102 }
103 
MoveCursor(const Direction direction)104 void TextListener::MoveCursor(const Direction direction)
105 {
106     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
107     direction_ = static_cast<int32_t>(direction);
108     textListenerCv_.notify_one();
109     IMSA_HILOGI("TextListener: MoveCursor, direction is: %{public}d", direction);
110 }
111 
HandleSetSelection(int32_t start,int32_t end)112 void TextListener::HandleSetSelection(int32_t start, int32_t end)
113 {
114     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
115     selectionStart_ = start;
116     selectionEnd_ = end;
117     textListenerCv_.notify_one();
118     IMSA_HILOGI("TextListener, selectionStart_: %{public}d, selectionEnd_: %{public}d", selectionStart_, selectionEnd_);
119 }
120 
HandleExtendAction(int32_t action)121 void TextListener::HandleExtendAction(int32_t action)
122 {
123     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
124     action_ = action;
125     textListenerCv_.notify_one();
126     IMSA_HILOGI("HandleExtendAction, action_: %{public}d", action_);
127 }
128 
HandleSelect(int32_t keyCode,int32_t cursorMoveSkip)129 void TextListener::HandleSelect(int32_t keyCode, int32_t cursorMoveSkip)
130 {
131     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
132     selectionDirection_ = keyCode;
133     selectionSkip_ = cursorMoveSkip;
134     textListenerCv_.notify_one();
135     IMSA_HILOGI("TextListener, selectionDirection_: %{public}d", selectionDirection_);
136 }
137 
GetLeftTextOfCursor(int32_t number)138 std::u16string TextListener::GetLeftTextOfCursor(int32_t number)
139 {
140     IMSA_HILOGI("TextListener number: %{public}d", number);
141     return Str8ToStr16(TEXT_BEFORE_CURSOR);
142 }
143 
GetRightTextOfCursor(int32_t number)144 std::u16string TextListener::GetRightTextOfCursor(int32_t number)
145 {
146     IMSA_HILOGI("TextListener number: %{public}d", number);
147     return Str8ToStr16(TEXT_AFTER_CURSOR);
148 }
149 
GetTextIndexAtCursor()150 int32_t TextListener::GetTextIndexAtCursor()
151 {
152     return TEXT_INDEX;
153 }
154 
ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)155 int32_t TextListener::ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
156 {
157     privateCommand_ = privateCommand;
158     return 0;
159 }
160 
NotifyPanelStatusInfo(const PanelStatusInfo & info)161 void TextListener::NotifyPanelStatusInfo(const PanelStatusInfo &info)
162 {
163     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
164     IMSA_HILOGI("TextListener::type: %{public}d, flag: %{public}d, visible: %{public}d, trigger: %{public}d.",
165         static_cast<PanelType>(info.panelInfo.panelType), static_cast<PanelFlag>(info.panelInfo.panelFlag),
166         info.visible, static_cast<Trigger>(info.trigger));
167     info_ = info;
168     textListenerCv_.notify_one();
169 }
170 
NotifyKeyboardHeight(uint32_t height)171 void TextListener::NotifyKeyboardHeight(uint32_t height)
172 {
173     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
174     IMSA_HILOGI("keyboard height: %{public}u", height);
175     height_ = height;
176     textListenerCv_.notify_one();
177 }
178 
SetPreviewText(const std::u16string & text,const Range & range)179 int32_t TextListener::SetPreviewText(const std::u16string &text, const Range &range)
180 {
181     IMSA_HILOGI("TextListener, text: %{public}s, range[start, end]: [%{public}d, %{public}d]",
182         Str16ToStr8(text).c_str(), range.start, range.end);
183     previewText_ = Str16ToStr8(text);
184     previewRange_ = range;
185     return ErrorCode::NO_ERROR;
186 }
187 
FinishTextPreview()188 void TextListener::FinishTextPreview()
189 {
190     IMSA_HILOGI("TextListener in");
191     isFinishTextPreviewCalled_ = true;
192 }
193 
ResetParam()194 void TextListener::ResetParam()
195 {
196     direction_ = -1;
197     deleteForwardLength_ = -1;
198     deleteBackwardLength_ = -1;
199     insertText_ = u"";
200     key_ = -1;
201     status_ = false;
202     selectionStart_ = -1;
203     selectionEnd_ = -1;
204     selectionDirection_ = -1;
205     selectionSkip_ = -1;
206     action_ = -1;
207     keyboardStatus_ = KeyboardStatus::NONE;
208     info_ = {};
209     height_ = 0;
210     previewText_ = "";
211     previewRange_ = {};
212     isFinishTextPreviewCalled_ = false;
213 }
214 
WaitSendKeyboardStatusCallback(const KeyboardStatus & keyboardStatus)215 bool TextListener::WaitSendKeyboardStatusCallback(const KeyboardStatus &keyboardStatus)
216 {
217     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
218     textListenerCv_.wait_for(lock, std::chrono::seconds(KEYBOARD_STATUS_WAIT_TIME_OUT),
219         [&keyboardStatus]() { return keyboardStatus == keyboardStatus_; });
220     return keyboardStatus == keyboardStatus_;
221 }
222 
WaitNotifyPanelStatusInfoCallback(const PanelStatusInfo & info)223 bool TextListener::WaitNotifyPanelStatusInfoCallback(const PanelStatusInfo &info)
224 {
225     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
226     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [info]() { return info == info_; });
227     return info == info_;
228 }
229 
WaitNotifyKeyboardHeightCallback(uint32_t height)230 bool TextListener::WaitNotifyKeyboardHeightCallback(uint32_t height)
231 {
232     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
233     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [height]() { return height_ == height; });
234     return height_ == height;
235 }
236 
WaitSendPrivateCommandCallback(std::unordered_map<std::string,PrivateDataValue> & privateCommand)237 bool TextListener::WaitSendPrivateCommandCallback(std::unordered_map<std::string, PrivateDataValue> &privateCommand)
238 {
239     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
240     textListenerCv_.wait_for(
241         lock, std::chrono::seconds(1), [privateCommand]() { return privateCommand_ == privateCommand; });
242     return privateCommand_ == privateCommand;
243 }
WaitInsertText(const std::u16string & insertText)244 bool TextListener::WaitInsertText(const std::u16string &insertText)
245 {
246     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
247     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [insertText]() { return insertText_ == insertText; });
248     return insertText_ == insertText;
249 }
WaitMoveCursor(int32_t direction)250 bool TextListener::WaitMoveCursor(int32_t direction)
251 {
252     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
253     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [direction]() { return direction_ == direction; });
254     return direction_ == direction;
255 }
WaitDeleteForward(int32_t length)256 bool TextListener::WaitDeleteForward(int32_t length)
257 {
258     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
259     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [length]() { return deleteForwardLength_ == length; });
260     return deleteForwardLength_ == length;
261 }
WaitDeleteBackward(int32_t length)262 bool TextListener::WaitDeleteBackward(int32_t length)
263 {
264     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
265     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [length]() { return deleteBackwardLength_ == length; });
266     return deleteBackwardLength_ == length;
267 }
WaitSendFunctionKey(int32_t functionKey)268 bool TextListener::WaitSendFunctionKey(int32_t functionKey)
269 {
270     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
271     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [functionKey]() { return key_ == functionKey; });
272     return key_ == functionKey;
273 }
WaitHandleExtendAction(int32_t action)274 bool TextListener::WaitHandleExtendAction(int32_t action)
275 {
276     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
277     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [action]() { return action_ == action; });
278     return action_ == action;
279 }
WaitHandleSetSelection(int32_t start,int32_t end)280 bool TextListener::WaitHandleSetSelection(int32_t start, int32_t end)
281 {
282     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
283     textListenerCv_.wait_for(
284         lock, std::chrono::seconds(1), [start, end]() { return selectionStart_ == start && selectionEnd_ == end; });
285     return selectionStart_ == start && selectionEnd_ == end;
286 }
WaitHandleSelect(int32_t keyCode,int32_t cursorMoveSkip)287 bool TextListener::WaitHandleSelect(int32_t keyCode, int32_t cursorMoveSkip)
288 {
289     std::unique_lock<std::mutex> lock(textListenerCallbackLock_);
290     textListenerCv_.wait_for(lock, std::chrono::seconds(1), [keyCode]() { return selectionDirection_ == keyCode; });
291     return selectionDirection_ == keyCode;
292 }
293 } // namespace MiscServices
294 } // namespace OHOS