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 return ErrorCode::NO_ERROR;
65 }
66
UnRegisterImeEventListener(uint32_t eventFlag,const std::shared_ptr<ImeEventListener> & listener)67 int32_t ImeEventMonitorManagerImpl::UnRegisterImeEventListener(
68 uint32_t eventFlag, const std::shared_ptr<ImeEventListener> &listener)
69 {
70 std::lock_guard<std::mutex> lock(lock_);
71 bool isAbsentParam = false;
72 for (uint32_t i = 0; i < MAX_EVENT_NUM; i++) {
73 auto eventMask = eventFlag & (1u << i);
74 if (eventMask == 0) {
75 continue;
76 }
77 auto it = listeners_.find(eventMask);
78 if (it == listeners_.end()) {
79 isAbsentParam = true;
80 continue;
81 }
82 auto iter = it->second.find(listener);
83 if (iter == it->second.end()) {
84 isAbsentParam = true;
85 continue;
86 }
87 it->second.erase(iter);
88 if (it->second.empty()) {
89 listeners_.erase(it);
90 }
91 }
92 uint32_t finalEventFlag = 0;
93 for (const auto &listenerTemp : listeners_) {
94 finalEventFlag |= listenerTemp.first;
95 }
96 auto ret = InputMethodController::GetInstance()->UpdateListenEventFlag(finalEventFlag, eventFlag, false);
97 if (ret != ErrorCode::NO_ERROR) {
98 IMSA_HILOGE("failed to UpdateListenEventFlag: %{public}d!", ret);
99 return ret;
100 }
101 return isAbsentParam ? ErrorCode::ERROR_BAD_PARAMETERS : ErrorCode::NO_ERROR;
102 }
103
OnImeChange(const Property & property,const SubProperty & subProperty)104 int32_t ImeEventMonitorManagerImpl::OnImeChange(const Property &property, const SubProperty &subProperty)
105 {
106 auto listeners = GetListeners(EVENT_IME_CHANGE_MASK);
107 for (const auto &listener : listeners) {
108 listener->OnImeChange(property, subProperty);
109 }
110 return ErrorCode::NO_ERROR;
111 }
112
OnPanelStatusChange(const InputWindowStatus & status,const ImeWindowInfo & info)113 int32_t ImeEventMonitorManagerImpl::OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info)
114 {
115 if (status == InputWindowStatus::HIDE) {
116 return OnImeHide(info);
117 }
118 if (status == InputWindowStatus::SHOW) {
119 return OnImeShow(info);
120 }
121 return ErrorCode::ERROR_BAD_PARAMETERS;
122 }
123
OnImeShow(const ImeWindowInfo & info)124 int32_t ImeEventMonitorManagerImpl::OnImeShow(const ImeWindowInfo &info)
125 {
126 auto listeners = GetListeners(EVENT_IME_SHOW_MASK);
127 for (const auto &listener : listeners) {
128 listener->OnImeShow(info);
129 }
130 return ErrorCode::NO_ERROR;
131 }
132
OnImeHide(const ImeWindowInfo & info)133 int32_t ImeEventMonitorManagerImpl::OnImeHide(const ImeWindowInfo &info)
134 {
135 auto listeners = GetListeners(EVENT_IME_HIDE_MASK);
136 for (const auto &listener : listeners) {
137 listener->OnImeHide(info);
138 }
139 return ErrorCode::NO_ERROR;
140 }
141
GetListeners(uint32_t eventMask)142 std::set<std::shared_ptr<ImeEventListener>> ImeEventMonitorManagerImpl::GetListeners(uint32_t eventMask)
143 {
144 std::lock_guard<std::mutex> lock(lock_);
145 auto it = listeners_.find(eventMask);
146 if (it == listeners_.end()) {
147 return {};
148 }
149 return it->second;
150 }
151 } // namespace MiscServices
152 } // namespace OHOS