• 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 #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