1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/libui/InputTransport.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,443 @@ 1.4 +/* 1.5 + * Copyright (C) 2010 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#ifndef _ANDROIDFW_INPUT_TRANSPORT_H 1.21 +#define _ANDROIDFW_INPUT_TRANSPORT_H 1.22 + 1.23 +/** 1.24 + * Native input transport. 1.25 + * 1.26 + * The InputChannel provides a mechanism for exchanging InputMessage structures across processes. 1.27 + * 1.28 + * The InputPublisher and InputConsumer each handle one end-point of an input channel. 1.29 + * The InputPublisher is used by the input dispatcher to send events to the application. 1.30 + * The InputConsumer is used by the application to receive events from the input dispatcher. 1.31 + */ 1.32 + 1.33 +#include "Input.h" 1.34 +#include <utils/Errors.h> 1.35 +#include <utils/Timers.h> 1.36 +#include <utils/RefBase.h> 1.37 +#include <utils/String8.h> 1.38 +#include <utils/Vector.h> 1.39 +#include <utils/BitSet.h> 1.40 + 1.41 +namespace android { 1.42 + 1.43 +/* 1.44 + * Intermediate representation used to send input events and related signals. 1.45 + */ 1.46 +struct InputMessage { 1.47 + enum { 1.48 + TYPE_KEY = 1, 1.49 + TYPE_MOTION = 2, 1.50 + TYPE_FINISHED = 3, 1.51 + }; 1.52 + 1.53 + struct Header { 1.54 + uint32_t type; 1.55 + uint32_t padding; // 8 byte alignment for the body that follows 1.56 + } header; 1.57 + 1.58 + union Body { 1.59 + struct Key { 1.60 + uint32_t seq; 1.61 + nsecs_t eventTime; 1.62 + int32_t deviceId; 1.63 + int32_t source; 1.64 + int32_t action; 1.65 + int32_t flags; 1.66 + int32_t keyCode; 1.67 + int32_t scanCode; 1.68 + int32_t metaState; 1.69 + int32_t repeatCount; 1.70 + nsecs_t downTime; 1.71 + 1.72 + inline size_t size() const { 1.73 + return sizeof(Key); 1.74 + } 1.75 + } key; 1.76 + 1.77 + struct Motion { 1.78 + uint32_t seq; 1.79 + nsecs_t eventTime; 1.80 + int32_t deviceId; 1.81 + int32_t source; 1.82 + int32_t action; 1.83 + int32_t flags; 1.84 + int32_t metaState; 1.85 + int32_t buttonState; 1.86 + int32_t edgeFlags; 1.87 + nsecs_t downTime; 1.88 + float xOffset; 1.89 + float yOffset; 1.90 + float xPrecision; 1.91 + float yPrecision; 1.92 + size_t pointerCount; 1.93 + struct Pointer { 1.94 + PointerProperties properties; 1.95 + PointerCoords coords; 1.96 + } pointers[MAX_POINTERS]; 1.97 + 1.98 + int32_t getActionId() const { 1.99 + uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) 1.100 + >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 1.101 + return pointers[index].properties.id; 1.102 + } 1.103 + 1.104 + inline size_t size() const { 1.105 + return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS 1.106 + + sizeof(Pointer) * pointerCount; 1.107 + } 1.108 + } motion; 1.109 + 1.110 + struct Finished { 1.111 + uint32_t seq; 1.112 + bool handled; 1.113 + 1.114 + inline size_t size() const { 1.115 + return sizeof(Finished); 1.116 + } 1.117 + } finished; 1.118 + } body; 1.119 + 1.120 + bool isValid(size_t actualSize) const; 1.121 + size_t size() const; 1.122 +}; 1.123 + 1.124 +/* 1.125 + * An input channel consists of a local unix domain socket used to send and receive 1.126 + * input messages across processes. Each channel has a descriptive name for debugging purposes. 1.127 + * 1.128 + * Each endpoint has its own InputChannel object that specifies its file descriptor. 1.129 + * 1.130 + * The input channel is closed when all references to it are released. 1.131 + */ 1.132 +class InputChannel : public RefBase { 1.133 +protected: 1.134 + virtual ~InputChannel(); 1.135 + 1.136 +public: 1.137 + InputChannel(const String8& name, int fd); 1.138 + 1.139 + /* Creates a pair of input channels. 1.140 + * 1.141 + * Returns OK on success. 1.142 + */ 1.143 + static status_t openInputChannelPair(const String8& name, 1.144 + sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel); 1.145 + 1.146 + inline String8 getName() const { return mName; } 1.147 + inline int getFd() const { return mFd; } 1.148 + 1.149 + /* Sends a message to the other endpoint. 1.150 + * 1.151 + * If the channel is full then the message is guaranteed not to have been sent at all. 1.152 + * Try again after the consumer has sent a finished signal indicating that it has 1.153 + * consumed some of the pending messages from the channel. 1.154 + * 1.155 + * Returns OK on success. 1.156 + * Returns WOULD_BLOCK if the channel is full. 1.157 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.158 + * Other errors probably indicate that the channel is broken. 1.159 + */ 1.160 + status_t sendMessage(const InputMessage* msg); 1.161 + 1.162 + /* Receives a message sent by the other endpoint. 1.163 + * 1.164 + * If there is no message present, try again after poll() indicates that the fd 1.165 + * is readable. 1.166 + * 1.167 + * Returns OK on success. 1.168 + * Returns WOULD_BLOCK if there is no message present. 1.169 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.170 + * Other errors probably indicate that the channel is broken. 1.171 + */ 1.172 + status_t receiveMessage(InputMessage* msg); 1.173 + 1.174 + /* Returns a new object that has a duplicate of this channel's fd. */ 1.175 + sp<InputChannel> dup() const; 1.176 + 1.177 +private: 1.178 + String8 mName; 1.179 + int mFd; 1.180 +}; 1.181 + 1.182 +/* 1.183 + * Publishes input events to an input channel. 1.184 + */ 1.185 +class InputPublisher { 1.186 +public: 1.187 + /* Creates a publisher associated with an input channel. */ 1.188 + explicit InputPublisher(const sp<InputChannel>& channel); 1.189 + 1.190 + /* Destroys the publisher and releases its input channel. */ 1.191 + ~InputPublisher(); 1.192 + 1.193 + /* Gets the underlying input channel. */ 1.194 + inline sp<InputChannel> getChannel() { return mChannel; } 1.195 + 1.196 + /* Publishes a key event to the input channel. 1.197 + * 1.198 + * Returns OK on success. 1.199 + * Returns WOULD_BLOCK if the channel is full. 1.200 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.201 + * Returns BAD_VALUE if seq is 0. 1.202 + * Other errors probably indicate that the channel is broken. 1.203 + */ 1.204 + status_t publishKeyEvent( 1.205 + uint32_t seq, 1.206 + int32_t deviceId, 1.207 + int32_t source, 1.208 + int32_t action, 1.209 + int32_t flags, 1.210 + int32_t keyCode, 1.211 + int32_t scanCode, 1.212 + int32_t metaState, 1.213 + int32_t repeatCount, 1.214 + nsecs_t downTime, 1.215 + nsecs_t eventTime); 1.216 + 1.217 + /* Publishes a motion event to the input channel. 1.218 + * 1.219 + * Returns OK on success. 1.220 + * Returns WOULD_BLOCK if the channel is full. 1.221 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.222 + * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS. 1.223 + * Other errors probably indicate that the channel is broken. 1.224 + */ 1.225 + status_t publishMotionEvent( 1.226 + uint32_t seq, 1.227 + int32_t deviceId, 1.228 + int32_t source, 1.229 + int32_t action, 1.230 + int32_t flags, 1.231 + int32_t edgeFlags, 1.232 + int32_t metaState, 1.233 + int32_t buttonState, 1.234 + float xOffset, 1.235 + float yOffset, 1.236 + float xPrecision, 1.237 + float yPrecision, 1.238 + nsecs_t downTime, 1.239 + nsecs_t eventTime, 1.240 + size_t pointerCount, 1.241 + const PointerProperties* pointerProperties, 1.242 + const PointerCoords* pointerCoords); 1.243 + 1.244 + /* Receives the finished signal from the consumer in reply to the original dispatch signal. 1.245 + * If a signal was received, returns the message sequence number, 1.246 + * and whether the consumer handled the message. 1.247 + * 1.248 + * The returned sequence number is never 0 unless the operation failed. 1.249 + * 1.250 + * Returns OK on success. 1.251 + * Returns WOULD_BLOCK if there is no signal present. 1.252 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.253 + * Other errors probably indicate that the channel is broken. 1.254 + */ 1.255 + status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); 1.256 + 1.257 +private: 1.258 + sp<InputChannel> mChannel; 1.259 +}; 1.260 + 1.261 +/* 1.262 + * Consumes input events from an input channel. 1.263 + */ 1.264 +class InputConsumer { 1.265 +public: 1.266 + /* Creates a consumer associated with an input channel. */ 1.267 + explicit InputConsumer(const sp<InputChannel>& channel); 1.268 + 1.269 + /* Destroys the consumer and releases its input channel. */ 1.270 + ~InputConsumer(); 1.271 + 1.272 + /* Gets the underlying input channel. */ 1.273 + inline sp<InputChannel> getChannel() { return mChannel; } 1.274 + 1.275 + /* Consumes an input event from the input channel and copies its contents into 1.276 + * an InputEvent object created using the specified factory. 1.277 + * 1.278 + * Tries to combine a series of move events into larger batches whenever possible. 1.279 + * 1.280 + * If consumeBatches is false, then defers consuming pending batched events if it 1.281 + * is possible for additional samples to be added to them later. Call hasPendingBatch() 1.282 + * to determine whether a pending batch is available to be consumed. 1.283 + * 1.284 + * If consumeBatches is true, then events are still batched but they are consumed 1.285 + * immediately as soon as the input channel is exhausted. 1.286 + * 1.287 + * The frameTime parameter specifies the time when the current display frame started 1.288 + * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown. 1.289 + * 1.290 + * The returned sequence number is never 0 unless the operation failed. 1.291 + * 1.292 + * Returns OK on success. 1.293 + * Returns WOULD_BLOCK if there is no event present. 1.294 + * Returns DEAD_OBJECT if the channel's peer has been closed. 1.295 + * Returns NO_MEMORY if the event could not be created. 1.296 + * Other errors probably indicate that the channel is broken. 1.297 + */ 1.298 + status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, 1.299 + nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); 1.300 + 1.301 + /* Sends a finished signal to the publisher to inform it that the message 1.302 + * with the specified sequence number has finished being process and whether 1.303 + * the message was handled by the consumer. 1.304 + * 1.305 + * Returns OK on success. 1.306 + * Returns BAD_VALUE if seq is 0. 1.307 + * Other errors probably indicate that the channel is broken. 1.308 + */ 1.309 + status_t sendFinishedSignal(uint32_t seq, bool handled); 1.310 + 1.311 + /* Returns true if there is a deferred event waiting. 1.312 + * 1.313 + * Should be called after calling consume() to determine whether the consumer 1.314 + * has a deferred event to be processed. Deferred events are somewhat special in 1.315 + * that they have already been removed from the input channel. If the input channel 1.316 + * becomes empty, the client may need to do extra work to ensure that it processes 1.317 + * the deferred event despite the fact that the input channel's file descriptor 1.318 + * is not readable. 1.319 + * 1.320 + * One option is simply to call consume() in a loop until it returns WOULD_BLOCK. 1.321 + * This guarantees that all deferred events will be processed. 1.322 + * 1.323 + * Alternately, the caller can call hasDeferredEvent() to determine whether there is 1.324 + * a deferred event waiting and then ensure that its event loop wakes up at least 1.325 + * one more time to consume the deferred event. 1.326 + */ 1.327 + bool hasDeferredEvent() const; 1.328 + 1.329 + /* Returns true if there is a pending batch. 1.330 + * 1.331 + * Should be called after calling consume() with consumeBatches == false to determine 1.332 + * whether consume() should be called again later on with consumeBatches == true. 1.333 + */ 1.334 + bool hasPendingBatch() const; 1.335 + 1.336 +private: 1.337 + // True if touch resampling is enabled. 1.338 + const bool mResampleTouch; 1.339 + 1.340 + // The input channel. 1.341 + sp<InputChannel> mChannel; 1.342 + 1.343 + // The current input message. 1.344 + InputMessage mMsg; 1.345 + 1.346 + // True if mMsg contains a valid input message that was deferred from the previous 1.347 + // call to consume and that still needs to be handled. 1.348 + bool mMsgDeferred; 1.349 + 1.350 + // Batched motion events per device and source. 1.351 + struct Batch { 1.352 + Vector<InputMessage> samples; 1.353 + }; 1.354 + Vector<Batch> mBatches; 1.355 + 1.356 + // Touch state per device and source, only for sources of class pointer. 1.357 + struct History { 1.358 + nsecs_t eventTime; 1.359 + BitSet32 idBits; 1.360 + int32_t idToIndex[MAX_POINTER_ID + 1]; 1.361 + PointerCoords pointers[MAX_POINTERS]; 1.362 + 1.363 + void initializeFrom(const InputMessage* msg) { 1.364 + eventTime = msg->body.motion.eventTime; 1.365 + idBits.clear(); 1.366 + for (size_t i = 0; i < msg->body.motion.pointerCount; i++) { 1.367 + uint32_t id = msg->body.motion.pointers[i].properties.id; 1.368 + idBits.markBit(id); 1.369 + idToIndex[id] = i; 1.370 + pointers[i].copyFrom(msg->body.motion.pointers[i].coords); 1.371 + } 1.372 + } 1.373 + 1.374 + const PointerCoords& getPointerById(uint32_t id) const { 1.375 + return pointers[idToIndex[id]]; 1.376 + } 1.377 + }; 1.378 + struct TouchState { 1.379 + int32_t deviceId; 1.380 + int32_t source; 1.381 + size_t historyCurrent; 1.382 + size_t historySize; 1.383 + History history[2]; 1.384 + History lastResample; 1.385 + 1.386 + void initialize(int32_t deviceId, int32_t source) { 1.387 + this->deviceId = deviceId; 1.388 + this->source = source; 1.389 + historyCurrent = 0; 1.390 + historySize = 0; 1.391 + lastResample.eventTime = 0; 1.392 + lastResample.idBits.clear(); 1.393 + } 1.394 + 1.395 + void addHistory(const InputMessage* msg) { 1.396 + historyCurrent ^= 1; 1.397 + if (historySize < 2) { 1.398 + historySize += 1; 1.399 + } 1.400 + history[historyCurrent].initializeFrom(msg); 1.401 + } 1.402 + 1.403 + const History* getHistory(size_t index) const { 1.404 + return &history[(historyCurrent + index) & 1]; 1.405 + } 1.406 + }; 1.407 + Vector<TouchState> mTouchStates; 1.408 + 1.409 + // Chain of batched sequence numbers. When multiple input messages are combined into 1.410 + // a batch, we append a record here that associates the last sequence number in the 1.411 + // batch with the previous one. When the finished signal is sent, we traverse the 1.412 + // chain to individually finish all input messages that were part of the batch. 1.413 + struct SeqChain { 1.414 + uint32_t seq; // sequence number of batched input message 1.415 + uint32_t chain; // sequence number of previous batched input message 1.416 + }; 1.417 + Vector<SeqChain> mSeqChains; 1.418 + 1.419 + status_t consumeBatch(InputEventFactoryInterface* factory, 1.420 + nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); 1.421 + status_t consumeSamples(InputEventFactoryInterface* factory, 1.422 + Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent); 1.423 + 1.424 + void updateTouchState(InputMessage* msg); 1.425 + void rewriteMessage(const TouchState& state, InputMessage* msg); 1.426 + void resampleTouchState(nsecs_t frameTime, MotionEvent* event, 1.427 + const InputMessage *next); 1.428 + 1.429 + ssize_t findBatch(int32_t deviceId, int32_t source) const; 1.430 + ssize_t findTouchState(int32_t deviceId, int32_t source) const; 1.431 + 1.432 + status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled); 1.433 + 1.434 + static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg); 1.435 + static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg); 1.436 + static void addSample(MotionEvent* event, const InputMessage* msg); 1.437 + static bool canAddSample(const Batch& batch, const InputMessage* msg); 1.438 + static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time); 1.439 + static bool shouldResampleTool(int32_t toolType); 1.440 + 1.441 + static bool isTouchResamplingEnabled(); 1.442 +}; 1.443 + 1.444 +} // namespace android 1.445 + 1.446 +#endif // _ANDROIDFW_INPUT_TRANSPORT_H