• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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