2 * Copyright (C) 2013 Canonical Ltd
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
20 #include <hybris/input/input_stack_compatibility_layer.h>
22 #include "InputListener.h"
23 #include "InputReader.h"
24 #include "PointerController.h"
25 #include "SpriteController.h"
26 #include <gui/ISurfaceComposer.h>
27 #include <gui/SurfaceComposerClient.h>
30 #define LOG_TAG "InputStackCompatibilityLayer"
31 #include <utils/Log.h>
35 static bool enable_verbose_function_reporting
= false;
38 #define REPORT_FUNCTION() ALOGV("%s\n", __PRETTY_FUNCTION__);
43 class DefaultPointerControllerPolicy
: public android::PointerControllerPolicyInterface
46 static const size_t bitmap_width
= 64;
47 static const size_t bitmap_height
= 64;
49 DefaultPointerControllerPolicy()
52 SkBitmap::kARGB_8888_Config
,
57 // Icon for spot touches
58 bitmap
.eraseARGB(125, 0, 255, 0);
59 spotTouchIcon
= android::SpriteIcon(
64 // Icon for anchor touches
65 bitmap
.eraseARGB(125, 0, 0, 255);
66 spotAnchorIcon
= android::SpriteIcon(
71 // Icon for hovering touches
72 bitmap
.eraseARGB(125, 255, 0, 0);
73 spotHoverIcon
= android::SpriteIcon(
79 void loadPointerResources(android::PointerResources
* outResources
)
81 outResources
->spotHover
= spotHoverIcon
.copy();
82 outResources
->spotTouch
= spotTouchIcon
.copy();
83 outResources
->spotAnchor
= spotAnchorIcon
.copy();
86 android::SpriteIcon spotHoverIcon
;
87 android::SpriteIcon spotTouchIcon
;
88 android::SpriteIcon spotAnchorIcon
;
92 class DefaultInputReaderPolicyInterface
: public android::InputReaderPolicyInterface
95 static const int32_t internal_display_id
= android::ISurfaceComposer::eDisplayIdMain
;
96 static const int32_t external_display_id
= android::ISurfaceComposer::eDisplayIdHdmi
;
98 DefaultInputReaderPolicyInterface(
99 InputStackConfiguration
* configuration
,
100 const android::sp
<android::Looper
>& looper
)
102 default_layer_for_touch_point_visualization(configuration
->default_layer_for_touch_point_visualization
),
103 input_area_width(configuration
->input_area_width
),
104 input_area_height(configuration
->input_area_height
)
106 default_configuration
.showTouches
= configuration
->enable_touch_point_visualization
;
108 android::DisplayViewport viewport
;
109 viewport
.setNonDisplayViewport(input_area_width
, input_area_height
);
110 viewport
.displayId
= android::ISurfaceComposer::eDisplayIdMain
;
111 default_configuration
.setDisplayInfo(
112 false, /* external */
116 void getReaderConfiguration(android::InputReaderConfiguration
* outConfig
)
118 *outConfig
= default_configuration
;
121 android::sp
<android::PointerControllerInterface
> obtainPointerController(int32_t deviceId
)
125 android::sp
<android::SpriteController
> sprite_controller(
126 new android::SpriteController(
128 default_layer_for_touch_point_visualization
));
129 android::sp
<android::PointerController
> pointer_controller(
130 new android::PointerController(
131 android::sp
<DefaultPointerControllerPolicy
>(new DefaultPointerControllerPolicy()),
134 pointer_controller
->setPresentation(
135 android::PointerControllerInterface::PRESENTATION_SPOT
);
137 pointer_controller
->setDisplayViewport(input_area_width
, input_area_height
, 0);
138 return pointer_controller
;
141 virtual void notifyInputDevicesChanged(const android::Vector
<android::InputDeviceInfo
>& inputDevices
) {
142 mInputDevices
= inputDevices
;
145 virtual android::sp
<android::KeyCharacterMap
> getKeyboardLayoutOverlay(const android::String8
& inputDeviceDescriptor
) {
149 virtual android::String8
getDeviceAlias(const android::InputDeviceIdentifier
& identifier
) {
150 return android::String8::empty();
154 android::sp
<android::Looper
> looper
;
155 int default_layer_for_touch_point_visualization
;
156 android::InputReaderConfiguration default_configuration
;
157 android::Vector
<android::InputDeviceInfo
> mInputDevices
;
158 int input_area_width
;
159 int input_area_height
;
162 class ExportedInputListener
: public android::InputListenerInterface
165 ExportedInputListener(AndroidEventListener
* external_listener
) : external_listener(external_listener
)
169 void notifyConfigurationChanged(const android::NotifyConfigurationChangedArgs
* args
)
175 void notifyKey(const android::NotifyKeyArgs
* args
)
179 current_event
.type
= KEY_EVENT_TYPE
;
180 current_event
.device_id
= args
->deviceId
;
181 current_event
.source_id
= args
->source
;
182 current_event
.action
= args
->action
;
183 current_event
.flags
= args
->flags
;
184 current_event
.meta_state
= args
->metaState
;
186 current_event
.details
.key
.key_code
= args
->keyCode
;
187 current_event
.details
.key
.scan_code
= args
->scanCode
;
188 current_event
.details
.key
.down_time
= args
->downTime
;
189 current_event
.details
.key
.event_time
= args
->eventTime
;
191 current_event
.details
.key
.is_system_key
= false;
193 external_listener
->on_new_event(¤t_event
, external_listener
->context
);
196 void notifyMotion(const android::NotifyMotionArgs
* args
)
200 current_event
.type
= MOTION_EVENT_TYPE
;
201 current_event
.device_id
= args
->deviceId
;
202 current_event
.source_id
= args
->source
;
203 current_event
.action
= args
->action
;
204 current_event
.flags
= args
->flags
;
205 current_event
.meta_state
= args
->metaState
;
207 current_event
.details
.motion
.button_state
= args
->buttonState
;
208 current_event
.details
.motion
.down_time
= args
->downTime
;
209 current_event
.details
.motion
.event_time
= args
->eventTime
;
210 current_event
.details
.motion
.edge_flags
= args
->edgeFlags
;
211 current_event
.details
.motion
.x_precision
= args
->xPrecision
;
212 current_event
.details
.motion
.y_precision
= args
->yPrecision
;
213 current_event
.details
.motion
.pointer_count
= args
->pointerCount
;
215 for (unsigned int i
= 0; i
< current_event
.details
.motion
.pointer_count
; i
++) {
216 current_event
.details
.motion
.pointer_coordinates
[i
].id
= args
->pointerProperties
[i
].id
;
217 current_event
.details
.motion
.pointer_coordinates
[i
].x
218 = current_event
.details
.motion
.pointer_coordinates
[i
].raw_x
219 = args
->pointerCoords
[i
].getX();
220 current_event
.details
.motion
.pointer_coordinates
[i
].y
221 = current_event
.details
.motion
.pointer_coordinates
[i
].raw_y
222 = args
->pointerCoords
[i
].getY();
223 current_event
.details
.motion
.pointer_coordinates
[i
].touch_major
224 = args
->pointerCoords
[i
].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR
);
225 current_event
.details
.motion
.pointer_coordinates
[i
].touch_minor
226 = args
->pointerCoords
[i
].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR
);
227 current_event
.details
.motion
.pointer_coordinates
[i
].pressure
228 = args
->pointerCoords
[i
].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE
);
229 current_event
.details
.motion
.pointer_coordinates
[i
].size
230 = args
->pointerCoords
[i
].getAxisValue(AMOTION_EVENT_AXIS_SIZE
);
231 current_event
.details
.motion
.pointer_coordinates
[i
].orientation
232 = args
->pointerCoords
[i
].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION
);
236 external_listener
->on_new_event(¤t_event
, external_listener
->context
);
239 void notifySwitch(const android::NotifySwitchArgs
* args
)
242 current_event
.type
= HW_SWITCH_EVENT_TYPE
;
244 current_event
.details
.hw_switch
.event_time
= args
->eventTime
;
245 current_event
.details
.hw_switch
.policy_flags
= args
->policyFlags
;
246 current_event
.details
.hw_switch
.switch_values
= args
->switchValues
;
247 current_event
.details
.hw_switch
.switch_mask
= args
->switchMask
;
249 external_listener
->on_new_event(¤t_event
, external_listener
->context
);
252 void notifyDeviceReset(const android::NotifyDeviceResetArgs
* args
)
259 AndroidEventListener
* external_listener
;
263 class LooperThread
: public android::Thread
266 static const int default_poll_timeout_ms
= -1;
268 LooperThread(const android::sp
<android::Looper
>& looper
) : looper(looper
)
275 if (ALOOPER_POLL_ERROR
== looper
->pollAll(default_poll_timeout_ms
))
280 android::sp
<android::Looper
> looper
;
283 struct State
: public android::RefBase
285 State(AndroidEventListener
* listener
,
286 InputStackConfiguration
* configuration
)
287 : looper(new android::Looper(false)),
288 looper_thread(new LooperThread(looper
)),
289 event_hub(new android::EventHub()),
290 input_reader_policy(new DefaultInputReaderPolicyInterface(configuration
, looper
)),
291 input_listener(new ExportedInputListener(listener
)),
292 input_reader(new android::InputReader(
296 input_reader_thread(new android::InputReaderThread(input_reader
))
302 input_reader_thread
->requestExit();
305 android::sp
<android::Looper
> looper
;
306 android::sp
<LooperThread
> looper_thread
;
308 android::sp
<android::EventHubInterface
> event_hub
;
309 android::sp
<android::InputReaderPolicyInterface
> input_reader_policy
;
310 android::sp
<android::InputListenerInterface
> input_listener
;
311 android::sp
<android::InputReaderInterface
> input_reader
;
312 android::sp
<android::InputReaderThread
> input_reader_thread
;
314 android::Condition wait_condition
;
315 android::Mutex wait_guard
;
318 android::sp
<State
> global_state
;
322 void android_input_stack_initialize(AndroidEventListener
* listener
, InputStackConfiguration
* config
)
324 global_state
= new State(listener
, config
);
327 void android_input_stack_loop_once()
329 global_state
->input_reader
->loopOnce();
332 void android_input_stack_start()
334 global_state
->input_reader_thread
->run();
335 global_state
->looper_thread
->run();
338 void android_input_stack_start_waiting_for_flag(bool* flag
)
340 global_state
->input_reader_thread
->run();
341 global_state
->looper_thread
->run();
344 global_state
->wait_condition
.waitRelative(
345 global_state
->wait_guard
,
350 void android_input_stack_stop()
352 global_state
->input_reader_thread
->requestExit();
355 void android_input_stack_shutdown()