1 /*
2 * Copyright (C) 2024 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 "ime_event_monitor_manager_impl.h"
17
18 #include <algorithm>
19
20 #include "input_method_controller.h"
21
22 namespace OHOS {
23 namespace MiscServices {
ImeEventMonitorManagerImpl()24 ImeEventMonitorManagerImpl::ImeEventMonitorManagerImpl()
25 {
26 }
27
~ImeEventMonitorManagerImpl()28 ImeEventMonitorManagerImpl::~ImeEventMonitorManagerImpl()
29 {
30 }
31
GetInstance()32 ImeEventMonitorManagerImpl &ImeEventMonitorManagerImpl::GetInstance()
33 {
34 static ImeEventMonitorManagerImpl manager;
35 return manager;
36 }
37
RegisterImeEventListener(uint32_t eventFlag,const std::shared_ptr<ImeEventListener> & listener)38 int32_t ImeEventMonitorManagerImpl::RegisterImeEventListener(
39 uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener)
40 {
41 std::lock_guard<std::mutex> lock(lock_);
42 uint32_t currentEventFlag = 0;
43 for (const auto &listenerTemp : listeners_) {
44 currentEventFlag |= listenerTemp.first;
45 }
46 auto finalEventFlag = currentEventFlag | eventFlag;
47 auto ret = InputMethodController::GetInstance()->UpdateListenEventFlag(finalEventFlag, eventFlag, true);
48 if (ret != ErrorCode::NO_ERROR) {
49 IMSA_HILOGE("failed to UpdateListenEventFlag: %{public}d!", ret);
50 return ret;
51 }
52 for (uint32_t i = 0; i < MAX_EVENT_NUM; i++) {
53 auto eventMask = eventFlag & (1u << i);
54 if (eventMask == 0) {
55 continue;
56 }
57 auto it = listeners_.find(eventMask);
58 if (it == listeners_.end()) {
59 listeners_.insert({ eventMask, { listener } });
60 continue;
61 }
62 it->second.insert(listener);
63 }
64 // Register inputStart callback when imf bound, need inputStart callback when register finish
65 if (EventStatusManager::IsInputStatusChangedOn(eventFlag)) {
66 bool isInputStart = false;
67 uint32_t callingWindowId = 0;
68 int32_t requestKeyboardReason = 0;
69 auto ret = InputMethodController::GetInstance()->GetInputStartInfo(isInputStart,
70 callingWindowId, requestKeyboardReason);
71 if (ret == ErrorCode::NO_ERROR && isInputStart && listener != nullptr) {
72 listener->OnInputStart(callingWindowId, requestKeyboardReason);
73 }
74 }
75 return ErrorCode::NO_ERROR;
76 }
77
UnRegisterImeEventListener(uint32_t eventFlag,const std::shared_ptr<ImeEventListener> & listener)78 int32_t ImeEventMonitorManagerImpl::UnRegisterImeEventListener(
79 uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener)
80 {
81 std::lock_guard<std::mutex> lock(lock_);
82 bool isAbsentParam = false;
83 for (uint32_t i = 0; i < MAX_EVENT_NUM; i++) {
84 auto eventMask = eventFlag & (1u << i);
85 if (eventMask == 0) {
86 continue;
87 }
88 auto it = listeners_.find(eventMask);
89 if (it == listeners_.end()) {
90 isAbsentParam = true;
91 continue;
92 }
93 auto iter = it->second.find(listener);
94 if (iter == it->second.end()) {
95 isAbsentParam = true;
96 continue;
97 }
98 it->second.erase(iter);
99 if (it->second.empty()) {
100 listeners_.erase(it);
101 }
102 }
103 uint32_t finalEventFlag = 0;
104 for (const auto &listenerTemp : listeners_) {
105 finalEventFlag |= listenerTemp.first;
106 }
107 auto ret = InputMethodController::GetInstance()->UpdateListenEventFlag(finalEventFlag, eventFlag, false);
108 if (ret != ErrorCode::NO_ERROR) {
109 IMSA_HILOGE("failed to UpdateListenEventFlag: %{public}d!", ret);
110 return ret;
111 }
112 return isAbsentParam ? ErrorCode::ERROR_BAD_PARAMETERS : ErrorCode::NO_ERROR;
113 }
114
OnImeChange(const Property & property,const SubProperty & subProperty)115 int32_t ImeEventMonitorManagerImpl::OnImeChange(const Property &property, const SubProperty &subProperty)
116 {
117 auto listeners = GetListeners(EVENT_IME_CHANGE_MASK);
118 for (const auto &listener : listeners) {
119 listener->OnImeChange(property, subProperty);
120 }
121 return ErrorCode::NO_ERROR;
122 }
123
OnPanelStatusChange(const InputWindowStatus & status,const ImeWindowInfo & info)124 int32_t ImeEventMonitorManagerImpl::OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info)
125 {
126 if (status == InputWindowStatus::HIDE) {
127 return OnImeHide(info);
128 }
129 if (status == InputWindowStatus::SHOW) {
130 return OnImeShow(info);
131 }
132 return ErrorCode::ERROR_BAD_PARAMETERS;
133 }
134
OnInputStart(uint32_t callingWndId,int32_t requestKeyboardReason)135 int32_t ImeEventMonitorManagerImpl::OnInputStart(uint32_t callingWndId, int32_t requestKeyboardReason)
136 {
137 isInputStart_ = true;
138 callingWindow_ = callingWndId;
139 requestKeyboardReason_ = requestKeyboardReason;
140 auto listeners = GetListeners(EVENT_INPUT_STATUS_CHANGED_MASK);
141 for (const auto &listener : listeners) {
142 if (listener != nullptr) {
143 IMSA_HILOGD("listener start to callback, callingWndId: %{public}u", callingWndId);
144 listener->OnInputStart(callingWndId, requestKeyboardReason);
145 }
146 }
147 return ErrorCode::NO_ERROR;
148 }
149
OnInputStop()150 int32_t ImeEventMonitorManagerImpl::OnInputStop()
151 {
152 isInputStart_ = false;
153 auto listeners = GetListeners(EVENT_INPUT_STATUS_CHANGED_MASK);
154 for (const auto &listener : listeners) {
155 if (listener != nullptr) {
156 listener->OnInputStop();
157 }
158 }
159 return ErrorCode::NO_ERROR;
160 }
161
OnImeShow(const ImeWindowInfo & info)162 int32_t ImeEventMonitorManagerImpl::OnImeShow(const ImeWindowInfo &info)
163 {
164 auto listeners = GetListeners(EVENT_IME_SHOW_MASK);
165 for (const auto &listener : listeners) {
166 listener->OnImeShow(info);
167 }
168 return ErrorCode::NO_ERROR;
169 }
170
OnImeHide(const ImeWindowInfo & info)171 int32_t ImeEventMonitorManagerImpl::OnImeHide(const ImeWindowInfo &info)
172 {
173 auto listeners = GetListeners(EVENT_IME_HIDE_MASK);
174 for (const auto &listener : listeners) {
175 listener->OnImeHide(info);
176 }
177 return ErrorCode::NO_ERROR;
178 }
179
GetListeners(uint32_t eventMask)180 std::set<std::shared_ptr<ImeEventListener>> ImeEventMonitorManagerImpl::GetListeners(uint32_t eventMask)
181 {
182 std::lock_guard<std::mutex> lock(lock_);
183 auto it = listeners_.find(eventMask);
184 if (it == listeners_.end()) {
185 return {};
186 }
187 return it->second;
188 }
189 } // namespace MiscServices
190 } // namespace OHOS