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