1/*
2 * Copyright (c) 2021-2023 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#include "input_event.h"
16#include <unistd.h>
17#include "log/log.h"
18#include "keys_input_device.h"
19
20namespace Updater {
21constexpr const int MAX_INPUT_DEVICES = 32;
22extern "C" __attribute__((constructor)) void RegisterAddInputDeviceHelper(void)
23{
24    InputEvent::GetInstance().RegisterAddInputDeviceHelper(AddInputDevice);
25}
26
27void InputEvent::RegisterAddInputDeviceHelper(AddInputDeviceFunc ptr)
28{
29    addInputDeviceHelper_ = std::move(ptr);
30}
31
32extern "C" __attribute__((constructor)) void RegisterHandleEventHelper(void)
33{
34    InputEvent::GetInstance().RegisterHandleEventHelper(HandlePointersEvent);
35}
36
37void InputEvent::RegisterHandleEventHelper(HandlePointersEventFunc ptr)
38{
39    handlePointersEventHelper_ = std::move(ptr);
40}
41
42InputEvent &InputEvent::GetInstance()
43{
44    static InputEvent instance;
45    return instance;
46}
47
48int InputEvent::HandleInputEvent(const struct input_event *iev, uint32_t type)
49{
50    struct input_event ev {};
51    ev.type = iev->type;
52    ev.code = iev->code;
53    ev.value = iev->value;
54
55    KeysInputDevice::GetInstance().HandleKeyEvent(ev, type);
56    handlePointersEventHelper_(ev, type);
57    return 0;
58}
59
60void InputEvent::GetInputDeviceType(uint32_t devIndex, uint32_t &type)
61{
62    auto it = devTypeMap_.find(devIndex);
63    if (it == devTypeMap_.end()) {
64        LOG(ERROR) << "devTypeMap_ devIndex: " << devIndex << "not valid";
65        return;
66    }
67    type = it->second;
68}
69
70void InputEvent::ReportEventPkgCallback(const InputEventPackage **pkgs, const uint32_t count, uint32_t devIndex)
71{
72    if (pkgs == nullptr || *pkgs == nullptr) {
73        return;
74    }
75    for (uint32_t i = 0; i < count; i++) {
76        struct input_event ev = {
77            .type = static_cast<__u16>(pkgs[i]->type),
78            .code = static_cast<__u16>(pkgs[i]->code),
79            .value = pkgs[i]->value,
80        };
81        uint32_t type = 0;
82        InputEvent::GetInstance().GetInputDeviceType(devIndex, type);
83        InputEvent::GetInstance().HandleInputEvent(&ev, type);
84    }
85    return;
86}
87
88int InputEvent::HdfInit()
89{
90    int ret = GetInputInterface(&inputInterface_);
91    if (ret != INPUT_SUCCESS) {
92        LOG(ERROR) << "get input driver interface failed";
93        return ret;
94    }
95
96    sleep(1); // need wait thread running
97
98    InputDevDesc sta[MAX_INPUT_DEVICES] = {{0}};
99    ret = inputInterface_->iInputManager->ScanInputDevice(sta, MAX_INPUT_DEVICES);
100    if (ret != INPUT_SUCCESS) {
101        LOG(ERROR) << "scan device failed";
102        return ret;
103    }
104
105    for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
106        uint32_t idx = sta[i].devIndex;
107        uint32_t dev = sta[i].devType;
108        if ((idx == 0) || (inputInterface_->iInputManager->OpenInputDevice(idx) == INPUT_FAILURE)) {
109            continue;
110        }
111        devTypeMap_.insert(std::pair<uint32_t, uint32_t>(idx, dev));
112
113        LOG(INFO) << "hdf devType:" << dev << ", devIndex:" << idx;
114    }
115
116    /* first param not necessary, pass default 1 */
117    callback_.EventPkgCallback = ReportEventPkgCallback;
118    ret = inputInterface_->iInputReporter->RegisterReportCallback(1, &callback_);
119    if (ret != INPUT_SUCCESS) {
120        LOG(ERROR) << "register callback failed for device 1";
121        return ret;
122    }
123
124    OHOS::InputDeviceManager::GetInstance()->Add(&KeysInputDevice::GetInstance());
125    OHOS::InputDeviceManager::GetInstance()->SetPeriod(0);
126    addInputDeviceHelper_();
127    LOG(INFO) << "add InputDevice done";
128
129    return 0;
130}
131} // namespace Updater
132