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