1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "TouchButtonAccumulator.h"
18 
19 #include "EventHub.h"
20 #include "InputDevice.h"
21 
22 namespace android {
23 
TouchButtonAccumulator()24 TouchButtonAccumulator::TouchButtonAccumulator() : mHaveBtnTouch(false), mHaveStylus(false) {
25     clearButtons();
26 }
27 
configure(InputDevice * device)28 void TouchButtonAccumulator::configure(InputDevice* device) {
29     mHaveBtnTouch = device->hasKey(BTN_TOUCH);
30     mHaveStylus = device->hasKey(BTN_TOOL_PEN) || device->hasKey(BTN_TOOL_RUBBER) ||
31             device->hasKey(BTN_TOOL_BRUSH) || device->hasKey(BTN_TOOL_PENCIL) ||
32             device->hasKey(BTN_TOOL_AIRBRUSH);
33 }
34 
reset(InputDevice * device)35 void TouchButtonAccumulator::reset(InputDevice* device) {
36     mBtnTouch = device->isKeyPressed(BTN_TOUCH);
37     mBtnStylus = device->isKeyPressed(BTN_STYLUS);
38     // BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
39     mBtnStylus2 = device->isKeyPressed(BTN_STYLUS2) || device->isKeyPressed(BTN_0);
40     mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
41     mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
42     mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
43     mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
44     mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
45     mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
46     mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
47     mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
48     mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
49     mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
50     mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
51 }
52 
clearButtons()53 void TouchButtonAccumulator::clearButtons() {
54     mBtnTouch = 0;
55     mBtnStylus = 0;
56     mBtnStylus2 = 0;
57     mBtnToolFinger = 0;
58     mBtnToolPen = 0;
59     mBtnToolRubber = 0;
60     mBtnToolBrush = 0;
61     mBtnToolPencil = 0;
62     mBtnToolAirbrush = 0;
63     mBtnToolMouse = 0;
64     mBtnToolLens = 0;
65     mBtnToolDoubleTap = 0;
66     mBtnToolTripleTap = 0;
67     mBtnToolQuadTap = 0;
68 }
69 
process(const RawEvent * rawEvent)70 void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
71     if (rawEvent->type == EV_KEY) {
72         switch (rawEvent->code) {
73             case BTN_TOUCH:
74                 mBtnTouch = rawEvent->value;
75                 break;
76             case BTN_STYLUS:
77                 mBtnStylus = rawEvent->value;
78                 break;
79             case BTN_STYLUS2:
80             case BTN_0: // BTN_0 is what gets mapped for the HID usage
81                         // Digitizers.SecondaryBarrelSwitch
82                 mBtnStylus2 = rawEvent->value;
83                 break;
84             case BTN_TOOL_FINGER:
85                 mBtnToolFinger = rawEvent->value;
86                 break;
87             case BTN_TOOL_PEN:
88                 mBtnToolPen = rawEvent->value;
89                 break;
90             case BTN_TOOL_RUBBER:
91                 mBtnToolRubber = rawEvent->value;
92                 break;
93             case BTN_TOOL_BRUSH:
94                 mBtnToolBrush = rawEvent->value;
95                 break;
96             case BTN_TOOL_PENCIL:
97                 mBtnToolPencil = rawEvent->value;
98                 break;
99             case BTN_TOOL_AIRBRUSH:
100                 mBtnToolAirbrush = rawEvent->value;
101                 break;
102             case BTN_TOOL_MOUSE:
103                 mBtnToolMouse = rawEvent->value;
104                 break;
105             case BTN_TOOL_LENS:
106                 mBtnToolLens = rawEvent->value;
107                 break;
108             case BTN_TOOL_DOUBLETAP:
109                 mBtnToolDoubleTap = rawEvent->value;
110                 break;
111             case BTN_TOOL_TRIPLETAP:
112                 mBtnToolTripleTap = rawEvent->value;
113                 break;
114             case BTN_TOOL_QUADTAP:
115                 mBtnToolQuadTap = rawEvent->value;
116                 break;
117         }
118     }
119 }
120 
getButtonState() const121 uint32_t TouchButtonAccumulator::getButtonState() const {
122     uint32_t result = 0;
123     if (mBtnStylus) {
124         result |= AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
125     }
126     if (mBtnStylus2) {
127         result |= AMOTION_EVENT_BUTTON_STYLUS_SECONDARY;
128     }
129     return result;
130 }
131 
getToolType() const132 int32_t TouchButtonAccumulator::getToolType() const {
133     if (mBtnToolMouse || mBtnToolLens) {
134         return AMOTION_EVENT_TOOL_TYPE_MOUSE;
135     }
136     if (mBtnToolRubber) {
137         return AMOTION_EVENT_TOOL_TYPE_ERASER;
138     }
139     if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
140         return AMOTION_EVENT_TOOL_TYPE_STYLUS;
141     }
142     if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
143         return AMOTION_EVENT_TOOL_TYPE_FINGER;
144     }
145     return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
146 }
147 
isToolActive() const148 bool TouchButtonAccumulator::isToolActive() const {
149     return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber || mBtnToolBrush ||
150             mBtnToolPencil || mBtnToolAirbrush || mBtnToolMouse || mBtnToolLens ||
151             mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
152 }
153 
isHovering() const154 bool TouchButtonAccumulator::isHovering() const {
155     return mHaveBtnTouch && !mBtnTouch;
156 }
157 
hasStylus() const158 bool TouchButtonAccumulator::hasStylus() const {
159     return mHaveStylus;
160 }
161 
162 } // namespace android
163