widget/gonk/libui/InputDispatcher.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright (C) 2010 The Android Open Source Project
michael@0 3 *
michael@0 4 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 5 * you may not use this file except in compliance with the License.
michael@0 6 * You may obtain a copy of the License at
michael@0 7 *
michael@0 8 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 9 *
michael@0 10 * Unless required by applicable law or agreed to in writing, software
michael@0 11 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 13 * See the License for the specific language governing permissions and
michael@0 14 * limitations under the License.
michael@0 15 */
michael@0 16
michael@0 17 #ifndef _UI_INPUT_DISPATCHER_H
michael@0 18 #define _UI_INPUT_DISPATCHER_H
michael@0 19
michael@0 20 #include "Input.h"
michael@0 21 #include "InputTransport.h"
michael@0 22 #include <utils/KeyedVector.h>
michael@0 23 #include <utils/Vector.h>
michael@0 24 #include <utils/threads.h>
michael@0 25 #include <utils/Timers.h>
michael@0 26 #include <utils/RefBase.h>
michael@0 27 #include <utils/String8.h>
michael@0 28 #include <utils/Looper.h>
michael@0 29 #include <utils/BitSet.h>
michael@0 30 #include <cutils/atomic.h>
michael@0 31
michael@0 32 #include <stddef.h>
michael@0 33 #include <unistd.h>
michael@0 34 #include <limits.h>
michael@0 35
michael@0 36 #include "InputWindow.h"
michael@0 37 #include "InputApplication.h"
michael@0 38 #include "InputListener.h"
michael@0 39
michael@0 40
michael@0 41 namespace android {
michael@0 42
michael@0 43 /*
michael@0 44 * Constants used to report the outcome of input event injection.
michael@0 45 */
michael@0 46 enum {
michael@0 47 /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
michael@0 48 INPUT_EVENT_INJECTION_PENDING = -1,
michael@0 49
michael@0 50 /* Injection succeeded. */
michael@0 51 INPUT_EVENT_INJECTION_SUCCEEDED = 0,
michael@0 52
michael@0 53 /* Injection failed because the injector did not have permission to inject
michael@0 54 * into the application with input focus. */
michael@0 55 INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
michael@0 56
michael@0 57 /* Injection failed because there were no available input targets. */
michael@0 58 INPUT_EVENT_INJECTION_FAILED = 2,
michael@0 59
michael@0 60 /* Injection failed due to a timeout. */
michael@0 61 INPUT_EVENT_INJECTION_TIMED_OUT = 3
michael@0 62 };
michael@0 63
michael@0 64 /*
michael@0 65 * Constants used to determine the input event injection synchronization mode.
michael@0 66 */
michael@0 67 enum {
michael@0 68 /* Injection is asynchronous and is assumed always to be successful. */
michael@0 69 INPUT_EVENT_INJECTION_SYNC_NONE = 0,
michael@0 70
michael@0 71 /* Waits for previous events to be dispatched so that the input dispatcher can determine
michael@0 72 * whether input event injection willbe permitted based on the current input focus.
michael@0 73 * Does not wait for the input event to finish processing. */
michael@0 74 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
michael@0 75
michael@0 76 /* Waits for the input event to be completely processed. */
michael@0 77 INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
michael@0 78 };
michael@0 79
michael@0 80
michael@0 81 /*
michael@0 82 * An input target specifies how an input event is to be dispatched to a particular window
michael@0 83 * including the window's input channel, control flags, a timeout, and an X / Y offset to
michael@0 84 * be added to input event coordinates to compensate for the absolute position of the
michael@0 85 * window area.
michael@0 86 */
michael@0 87 struct InputTarget {
michael@0 88 enum {
michael@0 89 /* This flag indicates that the event is being delivered to a foreground application. */
michael@0 90 FLAG_FOREGROUND = 1 << 0,
michael@0 91
michael@0 92 /* This flag indicates that the target of a MotionEvent is partly or wholly
michael@0 93 * obscured by another visible window above it. The motion event should be
michael@0 94 * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
michael@0 95 FLAG_WINDOW_IS_OBSCURED = 1 << 1,
michael@0 96
michael@0 97 /* This flag indicates that a motion event is being split across multiple windows. */
michael@0 98 FLAG_SPLIT = 1 << 2,
michael@0 99
michael@0 100 /* This flag indicates that the pointer coordinates dispatched to the application
michael@0 101 * will be zeroed out to avoid revealing information to an application. This is
michael@0 102 * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
michael@0 103 * the same UID from watching all touches. */
michael@0 104 FLAG_ZERO_COORDS = 1 << 3,
michael@0 105
michael@0 106 /* This flag indicates that the event should be sent as is.
michael@0 107 * Should always be set unless the event is to be transmuted. */
michael@0 108 FLAG_DISPATCH_AS_IS = 1 << 8,
michael@0 109
michael@0 110 /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
michael@0 111 * of the area of this target and so should instead be delivered as an
michael@0 112 * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
michael@0 113 FLAG_DISPATCH_AS_OUTSIDE = 1 << 9,
michael@0 114
michael@0 115 /* This flag indicates that a hover sequence is starting in the given window.
michael@0 116 * The event is transmuted into ACTION_HOVER_ENTER. */
michael@0 117 FLAG_DISPATCH_AS_HOVER_ENTER = 1 << 10,
michael@0 118
michael@0 119 /* This flag indicates that a hover event happened outside of a window which handled
michael@0 120 * previous hover events, signifying the end of the current hover sequence for that
michael@0 121 * window.
michael@0 122 * The event is transmuted into ACTION_HOVER_ENTER. */
michael@0 123 FLAG_DISPATCH_AS_HOVER_EXIT = 1 << 11,
michael@0 124
michael@0 125 /* This flag indicates that the event should be canceled.
michael@0 126 * It is used to transmute ACTION_MOVE into ACTION_CANCEL when a touch slips
michael@0 127 * outside of a window. */
michael@0 128 FLAG_DISPATCH_AS_SLIPPERY_EXIT = 1 << 12,
michael@0 129
michael@0 130 /* This flag indicates that the event should be dispatched as an initial down.
michael@0 131 * It is used to transmute ACTION_MOVE into ACTION_DOWN when a touch slips
michael@0 132 * into a new window. */
michael@0 133 FLAG_DISPATCH_AS_SLIPPERY_ENTER = 1 << 13,
michael@0 134
michael@0 135 /* Mask for all dispatch modes. */
michael@0 136 FLAG_DISPATCH_MASK = FLAG_DISPATCH_AS_IS
michael@0 137 | FLAG_DISPATCH_AS_OUTSIDE
michael@0 138 | FLAG_DISPATCH_AS_HOVER_ENTER
michael@0 139 | FLAG_DISPATCH_AS_HOVER_EXIT
michael@0 140 | FLAG_DISPATCH_AS_SLIPPERY_EXIT
michael@0 141 | FLAG_DISPATCH_AS_SLIPPERY_ENTER,
michael@0 142 };
michael@0 143
michael@0 144 // The input channel to be targeted.
michael@0 145 sp<InputChannel> inputChannel;
michael@0 146
michael@0 147 // Flags for the input target.
michael@0 148 int32_t flags;
michael@0 149
michael@0 150 // The x and y offset to add to a MotionEvent as it is delivered.
michael@0 151 // (ignored for KeyEvents)
michael@0 152 float xOffset, yOffset;
michael@0 153
michael@0 154 // Scaling factor to apply to MotionEvent as it is delivered.
michael@0 155 // (ignored for KeyEvents)
michael@0 156 float scaleFactor;
michael@0 157
michael@0 158 // The subset of pointer ids to include in motion events dispatched to this input target
michael@0 159 // if FLAG_SPLIT is set.
michael@0 160 BitSet32 pointerIds;
michael@0 161 };
michael@0 162
michael@0 163
michael@0 164 /*
michael@0 165 * Input dispatcher configuration.
michael@0 166 *
michael@0 167 * Specifies various options that modify the behavior of the input dispatcher.
michael@0 168 * The values provided here are merely defaults. The actual values will come from ViewConfiguration
michael@0 169 * and are passed into the dispatcher during initialization.
michael@0 170 */
michael@0 171 struct InputDispatcherConfiguration {
michael@0 172 // The key repeat initial timeout.
michael@0 173 nsecs_t keyRepeatTimeout;
michael@0 174
michael@0 175 // The key repeat inter-key delay.
michael@0 176 nsecs_t keyRepeatDelay;
michael@0 177
michael@0 178 InputDispatcherConfiguration() :
michael@0 179 keyRepeatTimeout(500 * 1000000LL),
michael@0 180 keyRepeatDelay(50 * 1000000LL) { }
michael@0 181 };
michael@0 182
michael@0 183
michael@0 184 /*
michael@0 185 * Input dispatcher policy interface.
michael@0 186 *
michael@0 187 * The input reader policy is used by the input reader to interact with the Window Manager
michael@0 188 * and other system components.
michael@0 189 *
michael@0 190 * The actual implementation is partially supported by callbacks into the DVM
michael@0 191 * via JNI. This interface is also mocked in the unit tests.
michael@0 192 */
michael@0 193 class InputDispatcherPolicyInterface : public virtual RefBase {
michael@0 194 protected:
michael@0 195 InputDispatcherPolicyInterface() { }
michael@0 196 virtual ~InputDispatcherPolicyInterface() { }
michael@0 197
michael@0 198 public:
michael@0 199 /* Notifies the system that a configuration change has occurred. */
michael@0 200 virtual void notifyConfigurationChanged(nsecs_t when) = 0;
michael@0 201
michael@0 202 /* Notifies the system that an application is not responding.
michael@0 203 * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
michael@0 204 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
michael@0 205 const sp<InputWindowHandle>& inputWindowHandle) = 0;
michael@0 206
michael@0 207 /* Notifies the system that an input channel is unrecoverably broken. */
michael@0 208 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
michael@0 209
michael@0 210 /* Gets the input dispatcher configuration. */
michael@0 211 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
michael@0 212
michael@0 213 /* Returns true if automatic key repeating is enabled. */
michael@0 214 virtual bool isKeyRepeatEnabled() = 0;
michael@0 215
michael@0 216 /* Filters an input event.
michael@0 217 * Return true to dispatch the event unmodified, false to consume the event.
michael@0 218 * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
michael@0 219 * to injectInputEvent.
michael@0 220 */
michael@0 221 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0;
michael@0 222
michael@0 223 /* Intercepts a key event immediately before queueing it.
michael@0 224 * The policy can use this method as an opportunity to perform power management functions
michael@0 225 * and early event preprocessing such as updating policy flags.
michael@0 226 *
michael@0 227 * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
michael@0 228 * should be dispatched to applications.
michael@0 229 */
michael@0 230 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) = 0;
michael@0 231
michael@0 232 /* Intercepts a touch, trackball or other motion event before queueing it.
michael@0 233 * The policy can use this method as an opportunity to perform power management functions
michael@0 234 * and early event preprocessing such as updating policy flags.
michael@0 235 *
michael@0 236 * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
michael@0 237 * should be dispatched to applications.
michael@0 238 */
michael@0 239 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
michael@0 240
michael@0 241 /* Allows the policy a chance to intercept a key before dispatching. */
michael@0 242 virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
michael@0 243 const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
michael@0 244
michael@0 245 /* Allows the policy a chance to perform default processing for an unhandled key.
michael@0 246 * Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
michael@0 247 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
michael@0 248 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
michael@0 249
michael@0 250 /* Notifies the policy about switch events.
michael@0 251 */
michael@0 252 virtual void notifySwitch(nsecs_t when,
michael@0 253 uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) = 0;
michael@0 254
michael@0 255 /* Poke user activity for an event dispatched to a window. */
michael@0 256 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
michael@0 257
michael@0 258 /* Checks whether a given application pid/uid has permission to inject input events
michael@0 259 * into other applications.
michael@0 260 *
michael@0 261 * This method is special in that its implementation promises to be non-reentrant and
michael@0 262 * is safe to call while holding other locks. (Most other methods make no such guarantees!)
michael@0 263 */
michael@0 264 virtual bool checkInjectEventsPermissionNonReentrant(
michael@0 265 int32_t injectorPid, int32_t injectorUid) = 0;
michael@0 266 };
michael@0 267
michael@0 268
michael@0 269 /* Notifies the system about input events generated by the input reader.
michael@0 270 * The dispatcher is expected to be mostly asynchronous. */
michael@0 271 class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
michael@0 272 protected:
michael@0 273 InputDispatcherInterface() { }
michael@0 274 virtual ~InputDispatcherInterface() { }
michael@0 275
michael@0 276 public:
michael@0 277 /* Dumps the state of the input dispatcher.
michael@0 278 *
michael@0 279 * This method may be called on any thread (usually by the input manager). */
michael@0 280 virtual void dump(String8& dump) = 0;
michael@0 281
michael@0 282 /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */
michael@0 283 virtual void monitor() = 0;
michael@0 284
michael@0 285 /* Runs a single iteration of the dispatch loop.
michael@0 286 * Nominally processes one queued event, a timeout, or a response from an input consumer.
michael@0 287 *
michael@0 288 * This method should only be called on the input dispatcher thread.
michael@0 289 */
michael@0 290 virtual void dispatchOnce() = 0;
michael@0 291
michael@0 292 /* Injects an input event and optionally waits for sync.
michael@0 293 * The synchronization mode determines whether the method blocks while waiting for
michael@0 294 * input injection to proceed.
michael@0 295 * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
michael@0 296 *
michael@0 297 * This method may be called on any thread (usually by the input manager).
michael@0 298 */
michael@0 299 virtual int32_t injectInputEvent(const InputEvent* event,
michael@0 300 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
michael@0 301 uint32_t policyFlags) = 0;
michael@0 302
michael@0 303 /* Sets the list of input windows.
michael@0 304 *
michael@0 305 * This method may be called on any thread (usually by the input manager).
michael@0 306 */
michael@0 307 virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
michael@0 308
michael@0 309 /* Sets the focused application.
michael@0 310 *
michael@0 311 * This method may be called on any thread (usually by the input manager).
michael@0 312 */
michael@0 313 virtual void setFocusedApplication(
michael@0 314 const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
michael@0 315
michael@0 316 /* Sets the input dispatching mode.
michael@0 317 *
michael@0 318 * This method may be called on any thread (usually by the input manager).
michael@0 319 */
michael@0 320 virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
michael@0 321
michael@0 322 /* Sets whether input event filtering is enabled.
michael@0 323 * When enabled, incoming input events are sent to the policy's filterInputEvent
michael@0 324 * method instead of being dispatched. The filter is expected to use
michael@0 325 * injectInputEvent to inject the events it would like to have dispatched.
michael@0 326 * It should include POLICY_FLAG_FILTERED in the policy flags during injection.
michael@0 327 */
michael@0 328 virtual void setInputFilterEnabled(bool enabled) = 0;
michael@0 329
michael@0 330 /* Transfers touch focus from the window associated with one channel to the
michael@0 331 * window associated with the other channel.
michael@0 332 *
michael@0 333 * Returns true on success. False if the window did not actually have touch focus.
michael@0 334 */
michael@0 335 virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
michael@0 336 const sp<InputChannel>& toChannel) = 0;
michael@0 337
michael@0 338 /* Registers or unregister input channels that may be used as targets for input events.
michael@0 339 * If monitor is true, the channel will receive a copy of all input events.
michael@0 340 *
michael@0 341 * These methods may be called on any thread (usually by the input manager).
michael@0 342 */
michael@0 343 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
michael@0 344 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) = 0;
michael@0 345 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
michael@0 346 };
michael@0 347
michael@0 348 /* Dispatches events to input targets. Some functions of the input dispatcher, such as
michael@0 349 * identifying input targets, are controlled by a separate policy object.
michael@0 350 *
michael@0 351 * IMPORTANT INVARIANT:
michael@0 352 * Because the policy can potentially block or cause re-entrance into the input dispatcher,
michael@0 353 * the input dispatcher never calls into the policy while holding its internal locks.
michael@0 354 * The implementation is also carefully designed to recover from scenarios such as an
michael@0 355 * input channel becoming unregistered while identifying input targets or processing timeouts.
michael@0 356 *
michael@0 357 * Methods marked 'Locked' must be called with the lock acquired.
michael@0 358 *
michael@0 359 * Methods marked 'LockedInterruptible' must be called with the lock acquired but
michael@0 360 * may during the course of their execution release the lock, call into the policy, and
michael@0 361 * then reacquire the lock. The caller is responsible for recovering gracefully.
michael@0 362 *
michael@0 363 * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
michael@0 364 */
michael@0 365 class InputDispatcher : public InputDispatcherInterface {
michael@0 366 protected:
michael@0 367 virtual ~InputDispatcher();
michael@0 368
michael@0 369 public:
michael@0 370 explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
michael@0 371
michael@0 372 virtual void dump(String8& dump);
michael@0 373 virtual void monitor();
michael@0 374
michael@0 375 virtual void dispatchOnce();
michael@0 376
michael@0 377 virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
michael@0 378 virtual void notifyKey(const NotifyKeyArgs* args);
michael@0 379 virtual void notifyMotion(const NotifyMotionArgs* args);
michael@0 380 virtual void notifySwitch(const NotifySwitchArgs* args);
michael@0 381 virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
michael@0 382
michael@0 383 virtual int32_t injectInputEvent(const InputEvent* event,
michael@0 384 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
michael@0 385 uint32_t policyFlags);
michael@0 386
michael@0 387 virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
michael@0 388 virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
michael@0 389 virtual void setInputDispatchMode(bool enabled, bool frozen);
michael@0 390 virtual void setInputFilterEnabled(bool enabled);
michael@0 391
michael@0 392 virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
michael@0 393 const sp<InputChannel>& toChannel);
michael@0 394
michael@0 395 virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
michael@0 396 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
michael@0 397 virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
michael@0 398
michael@0 399 private:
michael@0 400 template <typename T>
michael@0 401 struct Link {
michael@0 402 T* next;
michael@0 403 T* prev;
michael@0 404
michael@0 405 protected:
michael@0 406 inline Link() : next(NULL), prev(NULL) { }
michael@0 407 };
michael@0 408
michael@0 409 struct InjectionState {
michael@0 410 mutable int32_t refCount;
michael@0 411
michael@0 412 int32_t injectorPid;
michael@0 413 int32_t injectorUid;
michael@0 414 int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
michael@0 415 bool injectionIsAsync; // set to true if injection is not waiting for the result
michael@0 416 int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
michael@0 417
michael@0 418 InjectionState(int32_t injectorPid, int32_t injectorUid);
michael@0 419 void release();
michael@0 420
michael@0 421 private:
michael@0 422 ~InjectionState();
michael@0 423 };
michael@0 424
michael@0 425 struct EventEntry : Link<EventEntry> {
michael@0 426 enum {
michael@0 427 TYPE_CONFIGURATION_CHANGED,
michael@0 428 TYPE_DEVICE_RESET,
michael@0 429 TYPE_KEY,
michael@0 430 TYPE_MOTION
michael@0 431 };
michael@0 432
michael@0 433 mutable int32_t refCount;
michael@0 434 int32_t type;
michael@0 435 nsecs_t eventTime;
michael@0 436 uint32_t policyFlags;
michael@0 437 InjectionState* injectionState;
michael@0 438
michael@0 439 bool dispatchInProgress; // initially false, set to true while dispatching
michael@0 440
michael@0 441 inline bool isInjected() const { return injectionState != NULL; }
michael@0 442
michael@0 443 void release();
michael@0 444
michael@0 445 virtual void appendDescription(String8& msg) const = 0;
michael@0 446
michael@0 447 protected:
michael@0 448 EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
michael@0 449 virtual ~EventEntry();
michael@0 450 void releaseInjectionState();
michael@0 451 };
michael@0 452
michael@0 453 struct ConfigurationChangedEntry : EventEntry {
michael@0 454 ConfigurationChangedEntry(nsecs_t eventTime);
michael@0 455 virtual void appendDescription(String8& msg) const;
michael@0 456
michael@0 457 protected:
michael@0 458 virtual ~ConfigurationChangedEntry();
michael@0 459 };
michael@0 460
michael@0 461 struct DeviceResetEntry : EventEntry {
michael@0 462 int32_t deviceId;
michael@0 463
michael@0 464 DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
michael@0 465 virtual void appendDescription(String8& msg) const;
michael@0 466
michael@0 467 protected:
michael@0 468 virtual ~DeviceResetEntry();
michael@0 469 };
michael@0 470
michael@0 471 struct KeyEntry : EventEntry {
michael@0 472 int32_t deviceId;
michael@0 473 uint32_t source;
michael@0 474 int32_t action;
michael@0 475 int32_t flags;
michael@0 476 int32_t keyCode;
michael@0 477 int32_t scanCode;
michael@0 478 int32_t metaState;
michael@0 479 int32_t repeatCount;
michael@0 480 nsecs_t downTime;
michael@0 481
michael@0 482 bool syntheticRepeat; // set to true for synthetic key repeats
michael@0 483
michael@0 484 enum InterceptKeyResult {
michael@0 485 INTERCEPT_KEY_RESULT_UNKNOWN,
michael@0 486 INTERCEPT_KEY_RESULT_SKIP,
michael@0 487 INTERCEPT_KEY_RESULT_CONTINUE,
michael@0 488 INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
michael@0 489 };
michael@0 490 InterceptKeyResult interceptKeyResult; // set based on the interception result
michael@0 491 nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
michael@0 492
michael@0 493 KeyEntry(nsecs_t eventTime,
michael@0 494 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
michael@0 495 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
michael@0 496 int32_t repeatCount, nsecs_t downTime);
michael@0 497 virtual void appendDescription(String8& msg) const;
michael@0 498 void recycle();
michael@0 499
michael@0 500 protected:
michael@0 501 virtual ~KeyEntry();
michael@0 502 };
michael@0 503
michael@0 504 struct MotionEntry : EventEntry {
michael@0 505 nsecs_t eventTime;
michael@0 506 int32_t deviceId;
michael@0 507 uint32_t source;
michael@0 508 int32_t action;
michael@0 509 int32_t flags;
michael@0 510 int32_t metaState;
michael@0 511 int32_t buttonState;
michael@0 512 int32_t edgeFlags;
michael@0 513 float xPrecision;
michael@0 514 float yPrecision;
michael@0 515 nsecs_t downTime;
michael@0 516 int32_t displayId;
michael@0 517 uint32_t pointerCount;
michael@0 518 PointerProperties pointerProperties[MAX_POINTERS];
michael@0 519 PointerCoords pointerCoords[MAX_POINTERS];
michael@0 520
michael@0 521 MotionEntry(nsecs_t eventTime,
michael@0 522 int32_t deviceId, uint32_t source, uint32_t policyFlags,
michael@0 523 int32_t action, int32_t flags,
michael@0 524 int32_t metaState, int32_t buttonState, int32_t edgeFlags,
michael@0 525 float xPrecision, float yPrecision,
michael@0 526 nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
michael@0 527 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
michael@0 528 virtual void appendDescription(String8& msg) const;
michael@0 529
michael@0 530 protected:
michael@0 531 virtual ~MotionEntry();
michael@0 532 };
michael@0 533
michael@0 534 // Tracks the progress of dispatching a particular event to a particular connection.
michael@0 535 struct DispatchEntry : Link<DispatchEntry> {
michael@0 536 const uint32_t seq; // unique sequence number, never 0
michael@0 537
michael@0 538 EventEntry* eventEntry; // the event to dispatch
michael@0 539 int32_t targetFlags;
michael@0 540 float xOffset;
michael@0 541 float yOffset;
michael@0 542 float scaleFactor;
michael@0 543 nsecs_t deliveryTime; // time when the event was actually delivered
michael@0 544
michael@0 545 // Set to the resolved action and flags when the event is enqueued.
michael@0 546 int32_t resolvedAction;
michael@0 547 int32_t resolvedFlags;
michael@0 548
michael@0 549 DispatchEntry(EventEntry* eventEntry,
michael@0 550 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
michael@0 551 ~DispatchEntry();
michael@0 552
michael@0 553 inline bool hasForegroundTarget() const {
michael@0 554 return targetFlags & InputTarget::FLAG_FOREGROUND;
michael@0 555 }
michael@0 556
michael@0 557 inline bool isSplit() const {
michael@0 558 return targetFlags & InputTarget::FLAG_SPLIT;
michael@0 559 }
michael@0 560
michael@0 561 private:
michael@0 562 static volatile int32_t sNextSeqAtomic;
michael@0 563
michael@0 564 static uint32_t nextSeq();
michael@0 565 };
michael@0 566
michael@0 567 // A command entry captures state and behavior for an action to be performed in the
michael@0 568 // dispatch loop after the initial processing has taken place. It is essentially
michael@0 569 // a kind of continuation used to postpone sensitive policy interactions to a point
michael@0 570 // in the dispatch loop where it is safe to release the lock (generally after finishing
michael@0 571 // the critical parts of the dispatch cycle).
michael@0 572 //
michael@0 573 // The special thing about commands is that they can voluntarily release and reacquire
michael@0 574 // the dispatcher lock at will. Initially when the command starts running, the
michael@0 575 // dispatcher lock is held. However, if the command needs to call into the policy to
michael@0 576 // do some work, it can release the lock, do the work, then reacquire the lock again
michael@0 577 // before returning.
michael@0 578 //
michael@0 579 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
michael@0 580 // never calls into the policy while holding its lock.
michael@0 581 //
michael@0 582 // Commands are implicitly 'LockedInterruptible'.
michael@0 583 struct CommandEntry;
michael@0 584 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
michael@0 585
michael@0 586 class Connection;
michael@0 587 struct CommandEntry : Link<CommandEntry> {
michael@0 588 CommandEntry(Command command);
michael@0 589 ~CommandEntry();
michael@0 590
michael@0 591 Command command;
michael@0 592
michael@0 593 // parameters for the command (usage varies by command)
michael@0 594 sp<Connection> connection;
michael@0 595 nsecs_t eventTime;
michael@0 596 KeyEntry* keyEntry;
michael@0 597 sp<InputApplicationHandle> inputApplicationHandle;
michael@0 598 sp<InputWindowHandle> inputWindowHandle;
michael@0 599 int32_t userActivityEventType;
michael@0 600 uint32_t seq;
michael@0 601 bool handled;
michael@0 602 };
michael@0 603
michael@0 604 // Generic queue implementation.
michael@0 605 template <typename T>
michael@0 606 struct Queue {
michael@0 607 T* head;
michael@0 608 T* tail;
michael@0 609
michael@0 610 inline Queue() : head(NULL), tail(NULL) {
michael@0 611 }
michael@0 612
michael@0 613 inline bool isEmpty() const {
michael@0 614 return !head;
michael@0 615 }
michael@0 616
michael@0 617 inline void enqueueAtTail(T* entry) {
michael@0 618 entry->prev = tail;
michael@0 619 if (tail) {
michael@0 620 tail->next = entry;
michael@0 621 } else {
michael@0 622 head = entry;
michael@0 623 }
michael@0 624 entry->next = NULL;
michael@0 625 tail = entry;
michael@0 626 }
michael@0 627
michael@0 628 inline void enqueueAtHead(T* entry) {
michael@0 629 entry->next = head;
michael@0 630 if (head) {
michael@0 631 head->prev = entry;
michael@0 632 } else {
michael@0 633 tail = entry;
michael@0 634 }
michael@0 635 entry->prev = NULL;
michael@0 636 head = entry;
michael@0 637 }
michael@0 638
michael@0 639 inline void dequeue(T* entry) {
michael@0 640 if (entry->prev) {
michael@0 641 entry->prev->next = entry->next;
michael@0 642 } else {
michael@0 643 head = entry->next;
michael@0 644 }
michael@0 645 if (entry->next) {
michael@0 646 entry->next->prev = entry->prev;
michael@0 647 } else {
michael@0 648 tail = entry->prev;
michael@0 649 }
michael@0 650 }
michael@0 651
michael@0 652 inline T* dequeueAtHead() {
michael@0 653 T* entry = head;
michael@0 654 head = entry->next;
michael@0 655 if (head) {
michael@0 656 head->prev = NULL;
michael@0 657 } else {
michael@0 658 tail = NULL;
michael@0 659 }
michael@0 660 return entry;
michael@0 661 }
michael@0 662
michael@0 663 uint32_t count() const;
michael@0 664 };
michael@0 665
michael@0 666 /* Specifies which events are to be canceled and why. */
michael@0 667 struct CancelationOptions {
michael@0 668 enum Mode {
michael@0 669 CANCEL_ALL_EVENTS = 0,
michael@0 670 CANCEL_POINTER_EVENTS = 1,
michael@0 671 CANCEL_NON_POINTER_EVENTS = 2,
michael@0 672 CANCEL_FALLBACK_EVENTS = 3,
michael@0 673 };
michael@0 674
michael@0 675 // The criterion to use to determine which events should be canceled.
michael@0 676 Mode mode;
michael@0 677
michael@0 678 // Descriptive reason for the cancelation.
michael@0 679 const char* reason;
michael@0 680
michael@0 681 // The specific keycode of the key event to cancel, or -1 to cancel any key event.
michael@0 682 int32_t keyCode;
michael@0 683
michael@0 684 // The specific device id of events to cancel, or -1 to cancel events from any device.
michael@0 685 int32_t deviceId;
michael@0 686
michael@0 687 CancelationOptions(Mode mode, const char* reason) :
michael@0 688 mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
michael@0 689 };
michael@0 690
michael@0 691 /* Tracks dispatched key and motion event state so that cancelation events can be
michael@0 692 * synthesized when events are dropped. */
michael@0 693 class InputState {
michael@0 694 public:
michael@0 695 InputState();
michael@0 696 ~InputState();
michael@0 697
michael@0 698 // Returns true if there is no state to be canceled.
michael@0 699 bool isNeutral() const;
michael@0 700
michael@0 701 // Returns true if the specified source is known to have received a hover enter
michael@0 702 // motion event.
michael@0 703 bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
michael@0 704
michael@0 705 // Records tracking information for a key event that has just been published.
michael@0 706 // Returns true if the event should be delivered, false if it is inconsistent
michael@0 707 // and should be skipped.
michael@0 708 bool trackKey(const KeyEntry* entry, int32_t action, int32_t flags);
michael@0 709
michael@0 710 // Records tracking information for a motion event that has just been published.
michael@0 711 // Returns true if the event should be delivered, false if it is inconsistent
michael@0 712 // and should be skipped.
michael@0 713 bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
michael@0 714
michael@0 715 // Synthesizes cancelation events for the current state and resets the tracked state.
michael@0 716 void synthesizeCancelationEvents(nsecs_t currentTime,
michael@0 717 Vector<EventEntry*>& outEvents, const CancelationOptions& options);
michael@0 718
michael@0 719 // Clears the current state.
michael@0 720 void clear();
michael@0 721
michael@0 722 // Copies pointer-related parts of the input state to another instance.
michael@0 723 void copyPointerStateTo(InputState& other) const;
michael@0 724
michael@0 725 // Gets the fallback key associated with a keycode.
michael@0 726 // Returns -1 if none.
michael@0 727 // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy.
michael@0 728 int32_t getFallbackKey(int32_t originalKeyCode);
michael@0 729
michael@0 730 // Sets the fallback key for a particular keycode.
michael@0 731 void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode);
michael@0 732
michael@0 733 // Removes the fallback key for a particular keycode.
michael@0 734 void removeFallbackKey(int32_t originalKeyCode);
michael@0 735
michael@0 736 inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const {
michael@0 737 return mFallbackKeys;
michael@0 738 }
michael@0 739
michael@0 740 private:
michael@0 741 struct KeyMemento {
michael@0 742 int32_t deviceId;
michael@0 743 uint32_t source;
michael@0 744 int32_t keyCode;
michael@0 745 int32_t scanCode;
michael@0 746 int32_t metaState;
michael@0 747 int32_t flags;
michael@0 748 nsecs_t downTime;
michael@0 749 uint32_t policyFlags;
michael@0 750 };
michael@0 751
michael@0 752 struct MotionMemento {
michael@0 753 int32_t deviceId;
michael@0 754 uint32_t source;
michael@0 755 int32_t flags;
michael@0 756 float xPrecision;
michael@0 757 float yPrecision;
michael@0 758 nsecs_t downTime;
michael@0 759 int32_t displayId;
michael@0 760 uint32_t pointerCount;
michael@0 761 PointerProperties pointerProperties[MAX_POINTERS];
michael@0 762 PointerCoords pointerCoords[MAX_POINTERS];
michael@0 763 bool hovering;
michael@0 764 uint32_t policyFlags;
michael@0 765
michael@0 766 void setPointers(const MotionEntry* entry);
michael@0 767 };
michael@0 768
michael@0 769 Vector<KeyMemento> mKeyMementos;
michael@0 770 Vector<MotionMemento> mMotionMementos;
michael@0 771 KeyedVector<int32_t, int32_t> mFallbackKeys;
michael@0 772
michael@0 773 ssize_t findKeyMemento(const KeyEntry* entry) const;
michael@0 774 ssize_t findMotionMemento(const MotionEntry* entry, bool hovering) const;
michael@0 775
michael@0 776 void addKeyMemento(const KeyEntry* entry, int32_t flags);
michael@0 777 void addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering);
michael@0 778
michael@0 779 static bool shouldCancelKey(const KeyMemento& memento,
michael@0 780 const CancelationOptions& options);
michael@0 781 static bool shouldCancelMotion(const MotionMemento& memento,
michael@0 782 const CancelationOptions& options);
michael@0 783 };
michael@0 784
michael@0 785 /* Manages the dispatch state associated with a single input channel. */
michael@0 786 class Connection : public RefBase {
michael@0 787 protected:
michael@0 788 virtual ~Connection();
michael@0 789
michael@0 790 public:
michael@0 791 enum Status {
michael@0 792 // Everything is peachy.
michael@0 793 STATUS_NORMAL,
michael@0 794 // An unrecoverable communication error has occurred.
michael@0 795 STATUS_BROKEN,
michael@0 796 // The input channel has been unregistered.
michael@0 797 STATUS_ZOMBIE
michael@0 798 };
michael@0 799
michael@0 800 Status status;
michael@0 801 sp<InputChannel> inputChannel; // never null
michael@0 802 sp<InputWindowHandle> inputWindowHandle; // may be null
michael@0 803 bool monitor;
michael@0 804 InputPublisher inputPublisher;
michael@0 805 InputState inputState;
michael@0 806
michael@0 807 // True if the socket is full and no further events can be published until
michael@0 808 // the application consumes some of the input.
michael@0 809 bool inputPublisherBlocked;
michael@0 810
michael@0 811 // Queue of events that need to be published to the connection.
michael@0 812 Queue<DispatchEntry> outboundQueue;
michael@0 813
michael@0 814 // Queue of events that have been published to the connection but that have not
michael@0 815 // yet received a "finished" response from the application.
michael@0 816 Queue<DispatchEntry> waitQueue;
michael@0 817
michael@0 818 explicit Connection(const sp<InputChannel>& inputChannel,
michael@0 819 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
michael@0 820
michael@0 821 inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
michael@0 822
michael@0 823 const char* getWindowName() const;
michael@0 824 const char* getStatusLabel() const;
michael@0 825
michael@0 826 DispatchEntry* findWaitQueueEntry(uint32_t seq);
michael@0 827 };
michael@0 828
michael@0 829 enum DropReason {
michael@0 830 DROP_REASON_NOT_DROPPED = 0,
michael@0 831 DROP_REASON_POLICY = 1,
michael@0 832 DROP_REASON_APP_SWITCH = 2,
michael@0 833 DROP_REASON_DISABLED = 3,
michael@0 834 DROP_REASON_BLOCKED = 4,
michael@0 835 DROP_REASON_STALE = 5,
michael@0 836 };
michael@0 837
michael@0 838 sp<InputDispatcherPolicyInterface> mPolicy;
michael@0 839 InputDispatcherConfiguration mConfig;
michael@0 840
michael@0 841 Mutex mLock;
michael@0 842
michael@0 843 Condition mDispatcherIsAliveCondition;
michael@0 844
michael@0 845 sp<Looper> mLooper;
michael@0 846
michael@0 847 EventEntry* mPendingEvent;
michael@0 848 Queue<EventEntry> mInboundQueue;
michael@0 849 Queue<CommandEntry> mCommandQueue;
michael@0 850
michael@0 851 void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
michael@0 852
michael@0 853 // Enqueues an inbound event. Returns true if mLooper->wake() should be called.
michael@0 854 bool enqueueInboundEventLocked(EventEntry* entry);
michael@0 855
michael@0 856 // Cleans up input state when dropping an inbound event.
michael@0 857 void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
michael@0 858
michael@0 859 // App switch latency optimization.
michael@0 860 bool mAppSwitchSawKeyDown;
michael@0 861 nsecs_t mAppSwitchDueTime;
michael@0 862
michael@0 863 static bool isAppSwitchKeyCode(int32_t keyCode);
michael@0 864 bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
michael@0 865 bool isAppSwitchPendingLocked();
michael@0 866 void resetPendingAppSwitchLocked(bool handled);
michael@0 867
michael@0 868 // Stale event latency optimization.
michael@0 869 static bool isStaleEventLocked(nsecs_t currentTime, EventEntry* entry);
michael@0 870
michael@0 871 // Blocked event latency optimization. Drops old events when the user intends
michael@0 872 // to transfer focus to a new application.
michael@0 873 EventEntry* mNextUnblockedEvent;
michael@0 874
michael@0 875 sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
michael@0 876
michael@0 877 // All registered connections mapped by channel file descriptor.
michael@0 878 KeyedVector<int, sp<Connection> > mConnectionsByFd;
michael@0 879
michael@0 880 ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel);
michael@0 881
michael@0 882 // Input channels that will receive a copy of all input events.
michael@0 883 Vector<sp<InputChannel> > mMonitoringChannels;
michael@0 884
michael@0 885 // Event injection and synchronization.
michael@0 886 Condition mInjectionResultAvailableCondition;
michael@0 887 bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
michael@0 888 void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
michael@0 889
michael@0 890 Condition mInjectionSyncFinishedCondition;
michael@0 891 void incrementPendingForegroundDispatchesLocked(EventEntry* entry);
michael@0 892 void decrementPendingForegroundDispatchesLocked(EventEntry* entry);
michael@0 893
michael@0 894 // Key repeat tracking.
michael@0 895 struct KeyRepeatState {
michael@0 896 KeyEntry* lastKeyEntry; // or null if no repeat
michael@0 897 nsecs_t nextRepeatTime;
michael@0 898 } mKeyRepeatState;
michael@0 899
michael@0 900 void resetKeyRepeatLocked();
michael@0 901 KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
michael@0 902
michael@0 903 // Deferred command processing.
michael@0 904 bool haveCommandsLocked() const;
michael@0 905 bool runCommandsLockedInterruptible();
michael@0 906 CommandEntry* postCommandLocked(Command command);
michael@0 907
michael@0 908 // Input filter processing.
michael@0 909 bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
michael@0 910 bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
michael@0 911
michael@0 912 // Inbound event processing.
michael@0 913 void drainInboundQueueLocked();
michael@0 914 void releasePendingEventLocked();
michael@0 915 void releaseInboundEventLocked(EventEntry* entry);
michael@0 916
michael@0 917 // Dispatch state.
michael@0 918 bool mDispatchEnabled;
michael@0 919 bool mDispatchFrozen;
michael@0 920 bool mInputFilterEnabled;
michael@0 921
michael@0 922 Vector<sp<InputWindowHandle> > mWindowHandles;
michael@0 923
michael@0 924 sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
michael@0 925 bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
michael@0 926
michael@0 927 // Focus tracking for keys, trackball, etc.
michael@0 928 sp<InputWindowHandle> mFocusedWindowHandle;
michael@0 929
michael@0 930 // Focus tracking for touch.
michael@0 931 struct TouchedWindow {
michael@0 932 sp<InputWindowHandle> windowHandle;
michael@0 933 int32_t targetFlags;
michael@0 934 BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
michael@0 935 };
michael@0 936 struct TouchState {
michael@0 937 bool down;
michael@0 938 bool split;
michael@0 939 int32_t deviceId; // id of the device that is currently down, others are rejected
michael@0 940 uint32_t source; // source of the device that is current down, others are rejected
michael@0 941 int32_t displayId; // id to the display that currently has a touch, others are rejected
michael@0 942 Vector<TouchedWindow> windows;
michael@0 943
michael@0 944 TouchState();
michael@0 945 ~TouchState();
michael@0 946 void reset();
michael@0 947 void copyFrom(const TouchState& other);
michael@0 948 void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
michael@0 949 int32_t targetFlags, BitSet32 pointerIds);
michael@0 950 void removeWindow(const sp<InputWindowHandle>& windowHandle);
michael@0 951 void filterNonAsIsTouchWindows();
michael@0 952 sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
michael@0 953 bool isSlippery() const;
michael@0 954 };
michael@0 955
michael@0 956 TouchState mTouchState;
michael@0 957 TouchState mTempTouchState;
michael@0 958
michael@0 959 // Focused application.
michael@0 960 sp<InputApplicationHandle> mFocusedApplicationHandle;
michael@0 961
michael@0 962 // Dispatcher state at time of last ANR.
michael@0 963 String8 mLastANRState;
michael@0 964
michael@0 965 // Dispatch inbound events.
michael@0 966 bool dispatchConfigurationChangedLocked(
michael@0 967 nsecs_t currentTime, ConfigurationChangedEntry* entry);
michael@0 968 bool dispatchDeviceResetLocked(
michael@0 969 nsecs_t currentTime, DeviceResetEntry* entry);
michael@0 970 bool dispatchKeyLocked(
michael@0 971 nsecs_t currentTime, KeyEntry* entry,
michael@0 972 DropReason* dropReason, nsecs_t* nextWakeupTime);
michael@0 973 bool dispatchMotionLocked(
michael@0 974 nsecs_t currentTime, MotionEntry* entry,
michael@0 975 DropReason* dropReason, nsecs_t* nextWakeupTime);
michael@0 976 void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
michael@0 977 const Vector<InputTarget>& inputTargets);
michael@0 978
michael@0 979 void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
michael@0 980 void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
michael@0 981
michael@0 982 // Keeping track of ANR timeouts.
michael@0 983 enum InputTargetWaitCause {
michael@0 984 INPUT_TARGET_WAIT_CAUSE_NONE,
michael@0 985 INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
michael@0 986 INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
michael@0 987 };
michael@0 988
michael@0 989 InputTargetWaitCause mInputTargetWaitCause;
michael@0 990 nsecs_t mInputTargetWaitStartTime;
michael@0 991 nsecs_t mInputTargetWaitTimeoutTime;
michael@0 992 bool mInputTargetWaitTimeoutExpired;
michael@0 993 sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
michael@0 994
michael@0 995 // Contains the last window which received a hover event.
michael@0 996 sp<InputWindowHandle> mLastHoverWindowHandle;
michael@0 997
michael@0 998 // Finding targets for input events.
michael@0 999 int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
michael@0 1000 const sp<InputApplicationHandle>& applicationHandle,
michael@0 1001 const sp<InputWindowHandle>& windowHandle,
michael@0 1002 nsecs_t* nextWakeupTime, const char* reason);
michael@0 1003 void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
michael@0 1004 const sp<InputChannel>& inputChannel);
michael@0 1005 nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
michael@0 1006 void resetANRTimeoutsLocked();
michael@0 1007
michael@0 1008 int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
michael@0 1009 Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
michael@0 1010 int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
michael@0 1011 Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
michael@0 1012 bool* outConflictingPointerActions);
michael@0 1013
michael@0 1014 void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
michael@0 1015 int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
michael@0 1016 void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
michael@0 1017
michael@0 1018 void pokeUserActivityLocked(const EventEntry* eventEntry);
michael@0 1019 bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
michael@0 1020 const InjectionState* injectionState);
michael@0 1021 bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
michael@0 1022 int32_t x, int32_t y) const;
michael@0 1023 bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
michael@0 1024 const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
michael@0 1025 String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
michael@0 1026 const sp<InputWindowHandle>& windowHandle);
michael@0 1027
michael@0 1028 // Manage the dispatch cycle for a single connection.
michael@0 1029 // These methods are deliberately not Interruptible because doing all of the work
michael@0 1030 // with the mutex held makes it easier to ensure that connection invariants are maintained.
michael@0 1031 // If needed, the methods post commands to run later once the critical bits are done.
michael@0 1032 void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
michael@0 1033 EventEntry* eventEntry, const InputTarget* inputTarget);
michael@0 1034 void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
michael@0 1035 EventEntry* eventEntry, const InputTarget* inputTarget);
michael@0 1036 void enqueueDispatchEntryLocked(const sp<Connection>& connection,
michael@0 1037 EventEntry* eventEntry, const InputTarget* inputTarget, int32_t dispatchMode);
michael@0 1038 void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
michael@0 1039 void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
michael@0 1040 uint32_t seq, bool handled);
michael@0 1041 void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
michael@0 1042 bool notify);
michael@0 1043 void drainDispatchQueueLocked(Queue<DispatchEntry>* queue);
michael@0 1044 void releaseDispatchEntryLocked(DispatchEntry* dispatchEntry);
michael@0 1045 static int handleReceiveCallback(int fd, int events, void* data);
michael@0 1046
michael@0 1047 void synthesizeCancelationEventsForAllConnectionsLocked(
michael@0 1048 const CancelationOptions& options);
michael@0 1049 void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
michael@0 1050 const CancelationOptions& options);
michael@0 1051 void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
michael@0 1052 const CancelationOptions& options);
michael@0 1053
michael@0 1054 // Splitting motion events across windows.
michael@0 1055 MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
michael@0 1056
michael@0 1057 // Reset and drop everything the dispatcher is doing.
michael@0 1058 void resetAndDropEverythingLocked(const char* reason);
michael@0 1059
michael@0 1060 // Dump state.
michael@0 1061 void dumpDispatchStateLocked(String8& dump);
michael@0 1062 void logDispatchStateLocked();
michael@0 1063
michael@0 1064 // Registration.
michael@0 1065 void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel);
michael@0 1066 status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify);
michael@0 1067
michael@0 1068 // Add or remove a connection to the mActiveConnections vector.
michael@0 1069 void activateConnectionLocked(Connection* connection);
michael@0 1070 void deactivateConnectionLocked(Connection* connection);
michael@0 1071
michael@0 1072 // Interesting events that we might like to log or tell the framework about.
michael@0 1073 void onDispatchCycleFinishedLocked(
michael@0 1074 nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled);
michael@0 1075 void onDispatchCycleBrokenLocked(
michael@0 1076 nsecs_t currentTime, const sp<Connection>& connection);
michael@0 1077 void onANRLocked(
michael@0 1078 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
michael@0 1079 const sp<InputWindowHandle>& windowHandle,
michael@0 1080 nsecs_t eventTime, nsecs_t waitStartTime, const char* reason);
michael@0 1081
michael@0 1082 // Outbound policy interactions.
michael@0 1083 void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
michael@0 1084 void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
michael@0 1085 void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
michael@0 1086 void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
michael@0 1087 void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry);
michael@0 1088 bool afterKeyEventLockedInterruptible(const sp<Connection>& connection,
michael@0 1089 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled);
michael@0 1090 bool afterMotionEventLockedInterruptible(const sp<Connection>& connection,
michael@0 1091 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled);
michael@0 1092 void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
michael@0 1093 void initializeKeyEvent(KeyEvent* event, const KeyEntry* entry);
michael@0 1094
michael@0 1095 // Statistics gathering.
michael@0 1096 void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
michael@0 1097 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
michael@0 1098 void traceInboundQueueLengthLocked();
michael@0 1099 void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
michael@0 1100 void traceWaitQueueLengthLocked(const sp<Connection>& connection);
michael@0 1101 };
michael@0 1102
michael@0 1103 /* Enqueues and dispatches input events, endlessly. */
michael@0 1104 class InputDispatcherThread : public Thread {
michael@0 1105 public:
michael@0 1106 explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
michael@0 1107 ~InputDispatcherThread();
michael@0 1108
michael@0 1109 private:
michael@0 1110 virtual bool threadLoop();
michael@0 1111
michael@0 1112 sp<InputDispatcherInterface> mDispatcher;
michael@0 1113 };
michael@0 1114
michael@0 1115 } // namespace android
michael@0 1116
michael@0 1117 #endif // _UI_INPUT_DISPATCHER_H

mercurial