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 "delegate_interface.h"
17
18#include <algorithm>
19
20#include "display_event_monitor.h"
21#include "error_multimodal.h"
22#include "input_event_handler.h"
23#include "i_pointer_drawing_manager.h"
24#include "mmi_log.h"
25#include "touch_drawing_manager.h"
26
27#undef MMI_LOG_DOMAIN
28#define MMI_LOG_DOMAIN MMI_LOG_SERVER
29#undef MMI_LOG_TAG
30#define MMI_LOG_TAG "DelegateInterface"
31
32namespace OHOS {
33namespace MMI {
34void DelegateInterface::Init()
35{
36    TOUCH_DRAWING_MGR->SetDelegateProxy(shared_from_this());
37#ifdef OHOS_BUILD_ENABLE_KEYBOARD
38    DISPLAY_MONITOR->SetDelegateProxy(shared_from_this());
39#endif // #ifdef OHOS_BUILD_ENABLE_KEYBOARD
40#ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
41    IPointerDrawingManager::GetInstance()->SetDelegateProxy(shared_from_this());
42#endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
43}
44
45int32_t DelegateInterface::OnPostSyncTask(DTaskCallback cb) const
46{
47    CHKPR(delegateTasks_, ERROR_NULL_POINTER);
48    int32_t ret = delegateTasks_(cb);
49    if (ret != RET_OK) {
50        MMI_HILOGE("Failed to execute the task, ret: %{public}d", ret);
51    }
52    return ret;
53}
54
55void DelegateInterface::OnInputEvent(
56    InputHandlerType type, std::shared_ptr<PointerEvent> event) const
57{
58#if defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR)
59    OnInputEventHandler(type, event);
60#endif // OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
61}
62
63#if defined(OHOS_BUILD_ENABLE_INTERCEPTOR) || defined(OHOS_BUILD_ENABLE_MONITOR)
64void DelegateInterface::OnInputEventHandler(
65    InputHandlerType type, std::shared_ptr<PointerEvent> event) const
66{
67    CHKPV(event);
68    for (const auto &handler : handlers) {
69        auto summary = handler.second;
70        if (handler.first != type) {
71            continue;
72        }
73#ifdef OHOS_BUILD_ENABLE_MONITOR
74        if (type == InputHandlerType::MONITOR &&
75            (summary.eventType & HANDLE_EVENT_TYPE_POINTER) != HANDLE_EVENT_TYPE_POINTER) {
76            continue;
77        }
78#endif // OHOS_BUILD_ENABLE_MONITOR
79#ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
80        uint32_t deviceTags = 0;
81        if (type == InputHandlerType::INTERCEPTOR &&
82            ((deviceTags & summary.deviceTags) == summary.deviceTags) &&
83            !EventInterceptorHandler::CheckInputDeviceSource(event, summary.deviceTags)) {
84            continue;
85        }
86#endif // OHOS_BUILD_ENABLE_INTERCEPTOR
87        CHKPV(summary.cb);
88        if (summary.mode == HandlerMode::SYNC) {
89            summary.cb(event);
90        } else {
91            if (OnPostSyncTask(std::bind(summary.cb, event)) != RET_OK) {
92                MMI_HILOGE("Failed to execute the task(%{public}s)", summary.handlerName.c_str());
93            }
94        }
95    }
96}
97
98int32_t DelegateInterface::AddHandler(InputHandlerType type, const HandlerSummary &summary)
99{
100    CHKPR(summary.cb, ERROR_NULL_POINTER);
101    int32_t ret = RET_OK;
102    if (HasHandler(summary.handlerName)) {
103        MMI_HILOGW("The current handler(%{public}s) already exists", summary.handlerName.c_str());
104        return ret;
105    }
106    const HandleEventType currentType = GetEventType(type);
107    uint32_t currentTags = GetDeviceTags(type);
108    handlers.emplace(type, summary);
109    const HandleEventType newType = GetEventType(type);
110    if (currentType != newType || ((currentTags & summary.deviceTags) != summary.deviceTags)) {
111        uint32_t allDeviceTags = GetDeviceTags(type);
112        if (type == InputHandlerType::INTERCEPTOR) {
113#ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
114            auto interceptorHandler = InputHandler->GetInterceptorHandler();
115            CHKPR(interceptorHandler, ERROR_NULL_POINTER);
116            ret = interceptorHandler->AddInputHandler(type,
117                newType, summary.priority, allDeviceTags, nullptr);
118#endif // OHOS_BUILD_ENABLE_INTERCEPTOR
119        } else if (type == InputHandlerType::MONITOR) {
120#ifdef OHOS_BUILD_ENABLE_MONITOR
121            auto monitorHandler = InputHandler->GetMonitorHandler();
122            CHKPR(monitorHandler, ERROR_NULL_POINTER);
123            ret = monitorHandler->AddInputHandler(type,
124                newType, shared_from_this());
125#endif // OHOS_BUILD_ENABLE_MONITOR
126        }
127    }
128    if (ret != RET_OK) {
129        RemoveLocal(type, summary.handlerName, currentTags);
130    } else {
131        MMI_HILOGI("Service Add Monitor Success, size:%{public}zu", handlers.size());
132    }
133    return ret;
134}
135
136HandleEventType DelegateInterface::GetEventType(InputHandlerType type) const
137{
138    uint32_t eventType {HANDLE_EVENT_TYPE_NONE};
139    if (handlers.empty()) {
140        MMI_HILOGW("handlers is empty");
141        return HANDLE_EVENT_TYPE_NONE;
142    }
143    for (const auto &handler : handlers) {
144        if (handler.first == type) {
145            eventType |= handler.second.eventType;
146        }
147    }
148    return eventType;
149}
150
151uint32_t DelegateInterface::GetDeviceTags(InputHandlerType type) const
152{
153    uint32_t deviceTags = 0;
154    if (type == InputHandlerType::MONITOR) {
155        return deviceTags;
156    }
157    if (handlers.empty()) {
158        MMI_HILOGW("handlers is empty");
159        return deviceTags;
160    }
161    for (const auto &handler : handlers) {
162        if (handler.first == type) {
163            deviceTags |= handler.second.deviceTags;
164        }
165    }
166    return deviceTags;
167}
168
169void DelegateInterface::RemoveLocal(InputHandlerType type, const std::string &name, uint32_t &deviceTags)
170{
171    for (auto it = handlers.cbegin(); it != handlers.cend(); ++it) {
172        if (type != it->first) {
173            continue;
174        }
175        if (it->second.handlerName != name) {
176            continue;
177        }
178        handlers.erase(it);
179        if (type == InputHandlerType::INTERCEPTOR) {
180            deviceTags = it->second.deviceTags;
181        }
182        break;
183    }
184}
185
186int32_t DelegateInterface::GetPriority(InputHandlerType type) const
187{
188    for (auto it = handlers.cbegin(); it != handlers.cend(); ++it) {
189        if (type == it->first) {
190            return it->second.priority;
191        }
192    }
193    return DEFUALT_INTERCEPTOR_PRIORITY;
194}
195
196void DelegateInterface::RemoveHandler(InputHandlerType type, const std::string &name)
197{
198    const HandleEventType currentType = GetEventType(type);
199    uint32_t currentTags = GetDeviceTags(type);
200    uint32_t deviceTags = 0;
201    RemoveLocal(type, name, deviceTags);
202    const HandleEventType newType = GetEventType(type);
203    const int32_t newLevel = GetPriority(type);
204    const uint64_t newTags = GetDeviceTags(type);
205    if (currentType != newType || ((currentTags & deviceTags) != 0)) {
206        if (type == InputHandlerType::INTERCEPTOR) {
207#ifdef OHOS_BUILD_ENABLE_INTERCEPTOR
208            auto interceptorHandler = InputHandler->GetInterceptorHandler();
209            CHKPV(interceptorHandler);
210            interceptorHandler->RemoveInputHandler(type,
211                newType, newLevel, newTags, nullptr);
212#endif // OHOS_BUILD_ENABLE_INTERCEPTOR
213        }
214        if (type == InputHandlerType::MONITOR) {
215#ifdef OHOS_BUILD_ENABLE_MONITOR
216            auto monitorHandler = InputHandler->GetMonitorHandler();
217            CHKPV(monitorHandler);
218            monitorHandler->RemoveInputHandler(type,
219                newType, shared_from_this());
220#endif // OHOS_BUILD_ENABLE_MONITOR
221        }
222    }
223    MMI_HILOGI("Remove Handler:%{public}d:%{public}s-%{public}d:%{public}d, size:%{public}zu", type,
224               name.c_str(), currentType, currentTags, handlers.size());
225}
226
227bool DelegateInterface::HasHandler(const std::string &name) const
228{
229    return std::find_if(handlers.cbegin(), handlers.cend(),
230        [name](const auto &item) {
231            return item.second.handlerName == name;
232        }) != handlers.cend();
233}
234#endif // OHOS_BUILD_ENABLE_INTERCEPTOR || OHOS_BUILD_ENABLE_MONITOR
235} // namespace MMI
236} // namespace OHOS