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