1 /*
2  * Copyright (c) 2020-2021 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 "input_event_hub.h"
17 #include "gfx_utils/graphic_log.h"
18 
19 namespace OHOS {
20 namespace {
21 const uint32_t TOUCH_DEV_ID = 1;
22 const uint32_t MOUSE_DEV_ID = 2;
23 const uint32_t UNKNOW_DEV_ID = 32;
24 }
25 IInputInterface* InputEventHub::inputInterface_ = nullptr;
26 InputEventCb InputEventHub::callback_ = { 0 };
27 InputEventHub::ReadCallback InputEventHub::readCallback_ = nullptr;
28 
GetInstance()29 InputEventHub* InputEventHub::GetInstance()
30 {
31     static InputEventHub instance;
32     return &instance;
33 }
34 
InputEventHub()35 InputEventHub::InputEventHub()
36 {
37     for (uint8_t i = 0; i < MAX_INPUT_DEVICE_NUM; i++) {
38         mountDevIndex_[i] = UNKNOW_DEV_ID;
39     }
40     openDev_ = 0;
41 
42     data_.deviceId = UNKNOW_DEV_ID;
43     data_.state = 0;
44     data_.timestamp = 0;
45     data_.type = InputDevType::INDEV_TYPE_UNKNOWN;
46     data_.x = 0;
47     data_.y = 0;
48 }
49 
SetUp()50 void InputEventHub::SetUp()
51 {
52     int32_t ret = GetInputInterface(&inputInterface_);
53     if (ret != INPUT_SUCCESS) {
54         GRAPHIC_LOGE("get input driver interface failed!");
55         return;
56     }
57     uint8_t num = ScanInputDevice();
58     if (num == 0) {
59         GRAPHIC_LOGE("There is no device!");
60         return;
61     }
62     for (uint8_t i = 0; i < num; i++) {
63         if (inputInterface_ == nullptr || inputInterface_->iInputManager == nullptr) {
64             GRAPHIC_LOGE("input interface or input manager is nullptr, open device failed!");
65             return;
66         }
67         ret = inputInterface_->iInputManager->OpenInputDevice(mountDevIndex_[i]);
68         if (ret == INPUT_SUCCESS && inputInterface_->iInputReporter != nullptr) {
69             callback_.EventPkgCallback = EventCallback;
70             ret = inputInterface_->iInputReporter->RegisterReportCallback(mountDevIndex_[i], &callback_);
71             if (ret != INPUT_SUCCESS) {
72                 GRAPHIC_LOGE("device dose not exist, can't register callback to it!");
73                 return;
74             }
75             openDev_ = openDev_ | (1 << i);
76         }
77     }
78 }
79 
TearDown()80 void InputEventHub::TearDown()
81 {
82     int32_t ret = 0;
83     for (uint8_t i = 0; i < MAX_INPUT_DEVICE_NUM; i++) {
84         if ((openDev_ & (1 << i)) == 0) {
85             continue;
86         }
87         if (inputInterface_ == nullptr) {
88             GRAPHIC_LOGE("input interface point is nullptr!");
89             return;
90         }
91         if (inputInterface_->iInputReporter == nullptr || inputInterface_->iInputManager == nullptr) {
92             GRAPHIC_LOGE("input interface or input manager is nullptr, open device failed!");
93             return;
94         }
95         ret = inputInterface_->iInputReporter->UnregisterReportCallback(mountDevIndex_[i]);
96         if (ret != INPUT_SUCCESS) {
97             GRAPHIC_LOGE("Unregister callback failed!");
98         }
99         ret  = inputInterface_->iInputManager->CloseInputDevice(mountDevIndex_[i]);
100         if (ret != INPUT_SUCCESS) {
101             GRAPHIC_LOGE("Unmount device failed!");
102         }
103         openDev_ = openDev_ & ~(1 << i);
104     }
105 
106     if (inputInterface_ != nullptr) {
107         if (inputInterface_->iInputManager != nullptr) {
108             free(inputInterface_->iInputManager);
109         }
110         if (inputInterface_->iInputReporter != nullptr) {
111             free(inputInterface_->iInputReporter);
112         }
113         if (inputInterface_->iInputController != nullptr) {
114             free(inputInterface_->iInputController);
115         }
116         free(inputInterface_);
117         inputInterface_ = nullptr;
118     }
119 }
120 
EventCallback(const InputEventPackage ** pkgs,uint32_t count,uint32_t devIndex)121 void InputEventHub::EventCallback(const InputEventPackage **pkgs, uint32_t count, uint32_t devIndex)
122 {
123     if (pkgs == nullptr || readCallback_ == nullptr || count == 0) {
124         return;
125     }
126 
127     RawEvent& data = InputEventHub::GetInstance()->data_;
128     for (uint32_t i = 0; i < count; i++) {
129         if (pkgs[i]->type == EV_REL) {
130             data.type = InputDevType::INDEV_TYPE_MOUSE;
131             if (pkgs[i]->code == REL_X)
132                 data.x += pkgs[i]->value;
133             else if (pkgs[i]->code == REL_Y)
134                 data.y += pkgs[i]->value;
135         } else if (pkgs[i]->type == EV_ABS) {
136             data.type = InputDevType::INDEV_TYPE_TOUCH;
137             if (pkgs[i]->code == ABS_MT_POSITION_X)
138                 data.x = pkgs[i]->value;
139             else if (pkgs[i]->code == ABS_MT_POSITION_Y)
140                 data.y = pkgs[i]->value;
141         } else if (pkgs[i]->type == EV_KEY) {
142             if (pkgs[i]->code == BTN_MOUSE || pkgs[i]->code == BTN_TOUCH) {
143                 if (pkgs[i]->value == 0)
144                     data.state = 0;
145                 else if (pkgs[i]->value == 1)
146                     data.state = 1;
147             }
148         } else if (pkgs[i]->type == EV_SYN) {
149             if (pkgs[i]->code == SYN_REPORT) {
150                 break;
151             }
152         }
153     }
154 
155     readCallback_(&data);
156 }
157 
GetDeviceType(uint32_t devIndex)158 InputDevType InputEventHub::GetDeviceType(uint32_t devIndex)
159 {
160     switch (devIndex) {
161         case TOUCH_DEV_ID: {
162             return InputDevType::INDEV_TYPE_TOUCH;
163         }
164         case MOUSE_DEV_ID: {
165             return InputDevType::INDEV_TYPE_MOUSE;
166         }
167         default: {
168             return InputDevType::INDEV_TYPE_UNKNOWN;
169         }
170     }
171 }
172 
ScanInputDevice()173 uint8_t InputEventHub::ScanInputDevice()
174 {
175     for (uint8_t i = 0; i < MAX_INPUT_DEVICE_NUM; i++) {
176         mountDevIndex_[i] = UNKNOW_DEV_ID;
177     }
178     /* later will be change get device mode */
179     uint32_t deviceNum = 0;
180     mountDevIndex_[0] = TOUCH_DEV_ID;
181     mountDevIndex_[1] = MOUSE_DEV_ID;
182     deviceNum = 2; // 2:Number of current devices
183     return deviceNum;
184 }
185 } // namespace OHOS
186