am b88102f5
: Input dispatcher ANR handling enhancements.
Merge commit 'b88102f5b7e51552a3576cf197b4c8cf96f193d1' into gingerbread-plus-aosp * commit 'b88102f5b7e51552a3576cf197b4c8cf96f193d1': Input dispatcher ANR handling enhancements.
This commit is contained in:
@ -224,8 +224,8 @@ public class MessageQueue {
|
||||
msg.next = prev.next;
|
||||
prev.next = msg;
|
||||
}
|
||||
nativeWake();
|
||||
}
|
||||
nativeWake();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
namespace android {
|
||||
@ -108,15 +109,134 @@ struct InputTarget {
|
||||
// Flags for the input target.
|
||||
int32_t flags;
|
||||
|
||||
// The timeout for event delivery to this target in nanoseconds. Or -1 if none.
|
||||
// The timeout for event delivery to this target in nanoseconds, or -1 to wait indefinitely.
|
||||
nsecs_t timeout;
|
||||
|
||||
// The time already spent waiting for this target in nanoseconds, or 0 if none.
|
||||
nsecs_t timeSpentWaitingForApplication;
|
||||
|
||||
// The x and y offset to add to a MotionEvent as it is delivered.
|
||||
// (ignored for KeyEvents)
|
||||
float xOffset, yOffset;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An input window describes the bounds of a window that can receive input.
|
||||
*/
|
||||
struct InputWindow {
|
||||
// Window flags from WindowManager.LayoutParams
|
||||
enum {
|
||||
FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
|
||||
FLAG_DIM_BEHIND = 0x00000002,
|
||||
FLAG_BLUR_BEHIND = 0x00000004,
|
||||
FLAG_NOT_FOCUSABLE = 0x00000008,
|
||||
FLAG_NOT_TOUCHABLE = 0x00000010,
|
||||
FLAG_NOT_TOUCH_MODAL = 0x00000020,
|
||||
FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
|
||||
FLAG_KEEP_SCREEN_ON = 0x00000080,
|
||||
FLAG_LAYOUT_IN_SCREEN = 0x00000100,
|
||||
FLAG_LAYOUT_NO_LIMITS = 0x00000200,
|
||||
FLAG_FULLSCREEN = 0x00000400,
|
||||
FLAG_FORCE_NOT_FULLSCREEN = 0x00000800,
|
||||
FLAG_DITHER = 0x00001000,
|
||||
FLAG_SECURE = 0x00002000,
|
||||
FLAG_SCALED = 0x00004000,
|
||||
FLAG_IGNORE_CHEEK_PRESSES = 0x00008000,
|
||||
FLAG_LAYOUT_INSET_DECOR = 0x00010000,
|
||||
FLAG_ALT_FOCUSABLE_IM = 0x00020000,
|
||||
FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
|
||||
FLAG_SHOW_WHEN_LOCKED = 0x00080000,
|
||||
FLAG_SHOW_WALLPAPER = 0x00100000,
|
||||
FLAG_TURN_SCREEN_ON = 0x00200000,
|
||||
FLAG_DISMISS_KEYGUARD = 0x00400000,
|
||||
FLAG_IMMERSIVE = 0x00800000,
|
||||
FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000,
|
||||
FLAG_COMPATIBLE_WINDOW = 0x20000000,
|
||||
FLAG_SYSTEM_ERROR = 0x40000000,
|
||||
};
|
||||
|
||||
// Window types from WindowManager.LayoutParams
|
||||
enum {
|
||||
FIRST_APPLICATION_WINDOW = 1,
|
||||
TYPE_BASE_APPLICATION = 1,
|
||||
TYPE_APPLICATION = 2,
|
||||
TYPE_APPLICATION_STARTING = 3,
|
||||
LAST_APPLICATION_WINDOW = 99,
|
||||
FIRST_SUB_WINDOW = 1000,
|
||||
TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW,
|
||||
TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1,
|
||||
TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
|
||||
TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
|
||||
TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4,
|
||||
LAST_SUB_WINDOW = 1999,
|
||||
FIRST_SYSTEM_WINDOW = 2000,
|
||||
TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW,
|
||||
TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1,
|
||||
TYPE_PHONE = FIRST_SYSTEM_WINDOW+2,
|
||||
TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3,
|
||||
TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4,
|
||||
TYPE_TOAST = FIRST_SYSTEM_WINDOW+5,
|
||||
TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6,
|
||||
TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7,
|
||||
TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8,
|
||||
TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9,
|
||||
TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10,
|
||||
TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11,
|
||||
TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
|
||||
TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13,
|
||||
TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14,
|
||||
LAST_SYSTEM_WINDOW = 2999,
|
||||
};
|
||||
|
||||
sp<InputChannel> inputChannel;
|
||||
int32_t layoutParamsFlags;
|
||||
int32_t layoutParamsType;
|
||||
nsecs_t dispatchingTimeout;
|
||||
int32_t frameLeft;
|
||||
int32_t frameTop;
|
||||
int32_t frameRight;
|
||||
int32_t frameBottom;
|
||||
int32_t visibleFrameLeft;
|
||||
int32_t visibleFrameTop;
|
||||
int32_t visibleFrameRight;
|
||||
int32_t visibleFrameBottom;
|
||||
int32_t touchableAreaLeft;
|
||||
int32_t touchableAreaTop;
|
||||
int32_t touchableAreaRight;
|
||||
int32_t touchableAreaBottom;
|
||||
bool visible;
|
||||
bool hasFocus;
|
||||
bool hasWallpaper;
|
||||
bool paused;
|
||||
int32_t ownerPid;
|
||||
int32_t ownerUid;
|
||||
|
||||
bool visibleFrameIntersects(const InputWindow* other) const;
|
||||
bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A private handle type used by the input manager to track the window.
|
||||
*/
|
||||
class InputApplicationHandle : public RefBase {
|
||||
protected:
|
||||
InputApplicationHandle() { }
|
||||
virtual ~InputApplicationHandle() { }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An input application describes properties of an application that can receive input.
|
||||
*/
|
||||
struct InputApplication {
|
||||
String8 name;
|
||||
nsecs_t dispatchingTimeout;
|
||||
sp<InputApplicationHandle> handle;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Input dispatcher policy interface.
|
||||
*
|
||||
@ -135,14 +255,16 @@ public:
|
||||
/* Notifies the system that a configuration change has occurred. */
|
||||
virtual void notifyConfigurationChanged(nsecs_t when) = 0;
|
||||
|
||||
/* Notifies the system that an application is not responding.
|
||||
* Returns a new timeout to continue waiting, or 0 to abort dispatch. */
|
||||
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
|
||||
|
||||
/* Notifies the system that an input channel is unrecoverably broken. */
|
||||
virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
|
||||
|
||||
/* Notifies the system that an input channel is not responding.
|
||||
* Returns true and a new timeout value if the dispatcher should keep waiting.
|
||||
* Otherwise returns false. */
|
||||
virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
|
||||
nsecs_t& outNewTimeout) = 0;
|
||||
* Returns a new timeout to continue waiting, or 0 to abort dispatch. */
|
||||
virtual nsecs_t notifyInputChannelANR(const sp<InputChannel>& inputChannel) = 0;
|
||||
|
||||
/* Notifies the system that an input channel recovered from ANR. */
|
||||
virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
|
||||
@ -153,29 +275,27 @@ public:
|
||||
/* Gets the key repeat inter-key delay. */
|
||||
virtual nsecs_t getKeyRepeatDelay() = 0;
|
||||
|
||||
/* Waits for key event input targets to become available.
|
||||
* If the event is being injected, injectorPid and injectorUid should specify the
|
||||
* process id and used id of the injecting application, otherwise they should both
|
||||
* be -1.
|
||||
* Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
|
||||
virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
|
||||
int32_t injectorPid, int32_t injectorUid,
|
||||
Vector<InputTarget>& outTargets) = 0;
|
||||
|
||||
/* Waits for motion event targets to become available.
|
||||
* If the event is being injected, injectorPid and injectorUid should specify the
|
||||
* process id and used id of the injecting application, otherwise they should both
|
||||
* be -1.
|
||||
* Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
|
||||
virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
|
||||
int32_t injectorPid, int32_t injectorUid,
|
||||
Vector<InputTarget>& outTargets) = 0;
|
||||
|
||||
/* Gets the maximum suggested event delivery rate per second.
|
||||
* This value is used to throttle motion event movement actions on a per-device
|
||||
* basis. It is not intended to be a hard limit.
|
||||
*/
|
||||
virtual int32_t getMaxEventsPerSecond() = 0;
|
||||
|
||||
/* Allows the policy a chance to intercept a key before dispatching. */
|
||||
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
|
||||
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
|
||||
|
||||
/* Poke user activity for an event dispatched to a window. */
|
||||
virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType) = 0;
|
||||
|
||||
/* Checks whether a given application pid/uid has permission to inject input events
|
||||
* into other applications.
|
||||
*
|
||||
* This method is special in that its implementation promises to be non-reentrant and
|
||||
* is safe to call while holding other locks. (Most other methods make no such guarantees!)
|
||||
*/
|
||||
virtual bool checkInjectEventsPermissionNonReentrant(
|
||||
int32_t injectorPid, int32_t injectorUid) = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -187,6 +307,11 @@ protected:
|
||||
virtual ~InputDispatcherInterface() { }
|
||||
|
||||
public:
|
||||
/* Dumps the state of the input dispatcher.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager). */
|
||||
virtual void dump(String8& dump) = 0;
|
||||
|
||||
/* Runs a single iteration of the dispatch loop.
|
||||
* Nominally processes one queued event, a timeout, or a response from an input consumer.
|
||||
*
|
||||
@ -199,7 +324,6 @@ public:
|
||||
* These methods should only be called on the input reader thread.
|
||||
*/
|
||||
virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
|
||||
virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
|
||||
virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
|
||||
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
|
||||
int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
|
||||
@ -219,6 +343,24 @@ public:
|
||||
virtual int32_t injectInputEvent(const InputEvent* event,
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
|
||||
|
||||
/* Sets the list of input windows.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0;
|
||||
|
||||
/* Sets the focused application.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void setFocusedApplication(const InputApplication* inputApplication) = 0;
|
||||
|
||||
/* Sets the input dispatching mode.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
|
||||
|
||||
/* Preempts input dispatch in progress by making pending synchronous
|
||||
* dispatches asynchronous instead. This method is generally called during a focus
|
||||
* transition from one application to the next so as to enable the new application
|
||||
@ -230,10 +372,11 @@ public:
|
||||
virtual void preemptInputDispatch() = 0;
|
||||
|
||||
/* Registers or unregister input channels that may be used as targets for input events.
|
||||
* If monitor is true, the channel will receive a copy of all input events.
|
||||
*
|
||||
* These methods may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) = 0;
|
||||
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
|
||||
};
|
||||
|
||||
@ -261,10 +404,11 @@ protected:
|
||||
public:
|
||||
explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
|
||||
|
||||
virtual void dump(String8& dump);
|
||||
|
||||
virtual void dispatchOnce();
|
||||
|
||||
virtual void notifyConfigurationChanged(nsecs_t eventTime);
|
||||
virtual void notifyAppSwitchComing(nsecs_t eventTime);
|
||||
virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
|
||||
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
|
||||
int32_t scanCode, int32_t metaState, nsecs_t downTime);
|
||||
@ -277,9 +421,12 @@ public:
|
||||
virtual int32_t injectInputEvent(const InputEvent* event,
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
|
||||
|
||||
virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
|
||||
virtual void setFocusedApplication(const InputApplication* inputApplication);
|
||||
virtual void setInputDispatchMode(bool enabled, bool frozen);
|
||||
virtual void preemptInputDispatch();
|
||||
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor);
|
||||
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
|
||||
|
||||
private:
|
||||
@ -310,6 +457,8 @@ private:
|
||||
int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
|
||||
|
||||
inline bool isInjected() { return injectorPid >= 0; }
|
||||
|
||||
void recycle();
|
||||
};
|
||||
|
||||
struct ConfigurationChangedEntry : EventEntry {
|
||||
@ -326,6 +475,17 @@ private:
|
||||
int32_t metaState;
|
||||
int32_t repeatCount;
|
||||
nsecs_t downTime;
|
||||
|
||||
bool syntheticRepeat; // set to true for synthetic key repeats
|
||||
|
||||
enum InterceptKeyResult {
|
||||
INTERCEPT_KEY_RESULT_UNKNOWN,
|
||||
INTERCEPT_KEY_RESULT_SKIP,
|
||||
INTERCEPT_KEY_RESULT_CONTINUE,
|
||||
};
|
||||
InterceptKeyResult interceptKeyResult; // set based on the interception result
|
||||
|
||||
void recycle();
|
||||
};
|
||||
|
||||
struct MotionSample {
|
||||
@ -380,9 +540,13 @@ private:
|
||||
// will be set to NULL.
|
||||
MotionSample* tailMotionSample;
|
||||
|
||||
inline bool isSyncTarget() {
|
||||
inline bool isSyncTarget() const {
|
||||
return targetFlags & InputTarget::FLAG_SYNC;
|
||||
}
|
||||
|
||||
inline void preemptSyncTarget() {
|
||||
targetFlags &= ~ InputTarget::FLAG_SYNC;
|
||||
}
|
||||
};
|
||||
|
||||
// A command entry captures state and behavior for an action to be performed in the
|
||||
@ -413,37 +577,43 @@ private:
|
||||
|
||||
// parameters for the command (usage varies by command)
|
||||
sp<Connection> connection;
|
||||
nsecs_t eventTime;
|
||||
KeyEntry* keyEntry;
|
||||
sp<InputChannel> inputChannel;
|
||||
sp<InputApplicationHandle> inputApplicationHandle;
|
||||
int32_t windowType;
|
||||
int32_t userActivityEventType;
|
||||
};
|
||||
|
||||
// Generic queue implementation.
|
||||
template <typename T>
|
||||
struct Queue {
|
||||
T head;
|
||||
T tail;
|
||||
T headSentinel;
|
||||
T tailSentinel;
|
||||
|
||||
inline Queue() {
|
||||
head.prev = NULL;
|
||||
head.next = & tail;
|
||||
tail.prev = & head;
|
||||
tail.next = NULL;
|
||||
headSentinel.prev = NULL;
|
||||
headSentinel.next = & tailSentinel;
|
||||
tailSentinel.prev = & headSentinel;
|
||||
tailSentinel.next = NULL;
|
||||
}
|
||||
|
||||
inline bool isEmpty() {
|
||||
return head.next == & tail;
|
||||
inline bool isEmpty() const {
|
||||
return headSentinel.next == & tailSentinel;
|
||||
}
|
||||
|
||||
inline void enqueueAtTail(T* entry) {
|
||||
T* last = tail.prev;
|
||||
T* last = tailSentinel.prev;
|
||||
last->next = entry;
|
||||
entry->prev = last;
|
||||
entry->next = & tail;
|
||||
tail.prev = entry;
|
||||
entry->next = & tailSentinel;
|
||||
tailSentinel.prev = entry;
|
||||
}
|
||||
|
||||
inline void enqueueAtHead(T* entry) {
|
||||
T* first = head.next;
|
||||
head.next = entry;
|
||||
entry->prev = & head;
|
||||
T* first = headSentinel.next;
|
||||
headSentinel.next = entry;
|
||||
entry->prev = & headSentinel;
|
||||
entry->next = first;
|
||||
first->prev = entry;
|
||||
}
|
||||
@ -454,7 +624,7 @@ private:
|
||||
}
|
||||
|
||||
inline T* dequeueAtHead() {
|
||||
T* first = head.next;
|
||||
T* first = headSentinel.next;
|
||||
dequeue(first);
|
||||
return first;
|
||||
}
|
||||
@ -476,7 +646,8 @@ private:
|
||||
float xPrecision, float yPrecision,
|
||||
nsecs_t downTime, uint32_t pointerCount,
|
||||
const int32_t* pointerIds, const PointerCoords* pointerCoords);
|
||||
DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
|
||||
DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry,
|
||||
int32_t targetFlags, float xOffset, float yOffset, nsecs_t timeout);
|
||||
CommandEntry* obtainCommandEntry(Command command);
|
||||
|
||||
void releaseEventEntry(EventEntry* entry);
|
||||
@ -500,6 +671,85 @@ private:
|
||||
void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
|
||||
};
|
||||
|
||||
/* Tracks dispatched key and motion event state so that cancelation events can be
|
||||
* synthesized when events are dropped. */
|
||||
class InputState {
|
||||
public:
|
||||
// Specifies whether a given event will violate input state consistency.
|
||||
enum Consistency {
|
||||
// The event is consistent with the current input state.
|
||||
CONSISTENT,
|
||||
// The event is inconsistent with the current input state but applications
|
||||
// will tolerate it. eg. Down followed by another down.
|
||||
TOLERABLE,
|
||||
// The event is inconsistent with the current input state and will probably
|
||||
// cause applications to crash. eg. Up without prior down, move with
|
||||
// unexpected number of pointers.
|
||||
BROKEN
|
||||
};
|
||||
|
||||
InputState();
|
||||
~InputState();
|
||||
|
||||
// Returns true if there is no state to be canceled.
|
||||
bool isNeutral() const;
|
||||
|
||||
// Returns true if the input state believes it is out of sync.
|
||||
bool isOutOfSync() const;
|
||||
|
||||
// Sets the input state to be out of sync if it is not neutral.
|
||||
void setOutOfSync();
|
||||
|
||||
// Resets the input state out of sync flag.
|
||||
void resetOutOfSync();
|
||||
|
||||
// Records tracking information for an event that has just been published.
|
||||
// Returns whether the event is consistent with the current input state.
|
||||
Consistency trackEvent(const EventEntry* entry);
|
||||
|
||||
// Records tracking information for a key event that has just been published.
|
||||
// Returns whether the event is consistent with the current input state.
|
||||
Consistency trackKey(const KeyEntry* entry);
|
||||
|
||||
// Records tracking information for a motion event that has just been published.
|
||||
// Returns whether the event is consistent with the current input state.
|
||||
Consistency trackMotion(const MotionEntry* entry);
|
||||
|
||||
// Synthesizes cancelation events for the current state.
|
||||
void synthesizeCancelationEvents(Allocator* allocator,
|
||||
Vector<EventEntry*>& outEvents) const;
|
||||
|
||||
// Clears the current state.
|
||||
void clear();
|
||||
|
||||
private:
|
||||
bool mIsOutOfSync;
|
||||
|
||||
struct KeyMemento {
|
||||
int32_t deviceId;
|
||||
int32_t source;
|
||||
int32_t keyCode;
|
||||
int32_t scanCode;
|
||||
nsecs_t downTime;
|
||||
};
|
||||
|
||||
struct MotionMemento {
|
||||
int32_t deviceId;
|
||||
int32_t source;
|
||||
float xPrecision;
|
||||
float yPrecision;
|
||||
nsecs_t downTime;
|
||||
uint32_t pointerCount;
|
||||
int32_t pointerIds[MAX_POINTERS];
|
||||
PointerCoords pointerCoords[MAX_POINTERS];
|
||||
|
||||
void setPointers(const MotionEntry* entry);
|
||||
};
|
||||
|
||||
Vector<KeyMemento> mKeyMementos;
|
||||
Vector<MotionMemento> mMotionMementos;
|
||||
};
|
||||
|
||||
/* Manages the dispatch state associated with a single input channel. */
|
||||
class Connection : public RefBase {
|
||||
protected:
|
||||
@ -520,6 +770,7 @@ private:
|
||||
Status status;
|
||||
sp<InputChannel> inputChannel;
|
||||
InputPublisher inputPublisher;
|
||||
InputState inputState;
|
||||
Queue<DispatchEntry> outboundQueue;
|
||||
nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
|
||||
|
||||
@ -540,28 +791,34 @@ private:
|
||||
// Determine whether this connection has a pending synchronous dispatch target.
|
||||
// Since there can only ever be at most one such target at a time, if there is one,
|
||||
// it must be at the tail because nothing else can be enqueued after it.
|
||||
inline bool hasPendingSyncTarget() {
|
||||
return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
|
||||
inline bool hasPendingSyncTarget() const {
|
||||
return ! outboundQueue.isEmpty() && outboundQueue.tailSentinel.prev->isSyncTarget();
|
||||
}
|
||||
|
||||
// Assuming there is a pending sync target, make it async.
|
||||
inline void preemptSyncTarget() {
|
||||
outboundQueue.tailSentinel.prev->preemptSyncTarget();
|
||||
}
|
||||
|
||||
// Gets the time since the current event was originally obtained from the input driver.
|
||||
inline double getEventLatencyMillis(nsecs_t currentTime) {
|
||||
inline double getEventLatencyMillis(nsecs_t currentTime) const {
|
||||
return (currentTime - lastEventTime) / 1000000.0;
|
||||
}
|
||||
|
||||
// Gets the time since the current event entered the outbound dispatch queue.
|
||||
inline double getDispatchLatencyMillis(nsecs_t currentTime) {
|
||||
inline double getDispatchLatencyMillis(nsecs_t currentTime) const {
|
||||
return (currentTime - lastDispatchTime) / 1000000.0;
|
||||
}
|
||||
|
||||
// Gets the time since the current event ANR was declared, if applicable.
|
||||
inline double getANRLatencyMillis(nsecs_t currentTime) {
|
||||
inline double getANRLatencyMillis(nsecs_t currentTime) const {
|
||||
return (currentTime - lastANRTime) / 1000000.0;
|
||||
}
|
||||
|
||||
status_t initialize();
|
||||
|
||||
void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
|
||||
void resetTimeout(nsecs_t currentTime);
|
||||
};
|
||||
|
||||
sp<InputDispatcherPolicyInterface> mPolicy;
|
||||
@ -571,9 +828,26 @@ private:
|
||||
Allocator mAllocator;
|
||||
sp<PollLoop> mPollLoop;
|
||||
|
||||
EventEntry* mPendingEvent;
|
||||
Queue<EventEntry> mInboundQueue;
|
||||
Queue<CommandEntry> mCommandQueue;
|
||||
|
||||
Vector<EventEntry*> mTempCancelationEvents;
|
||||
|
||||
void dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, nsecs_t keyRepeatDelay,
|
||||
nsecs_t* nextWakeupTime);
|
||||
|
||||
// Enqueues an inbound event. Returns true if mPollLoop->wake() should be called.
|
||||
bool enqueueInboundEventLocked(EventEntry* entry);
|
||||
|
||||
// App switch latency optimization.
|
||||
nsecs_t mAppSwitchDueTime;
|
||||
|
||||
static bool isAppSwitchKey(int32_t keyCode);
|
||||
bool isAppSwitchPendingLocked();
|
||||
bool detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry);
|
||||
void resetPendingAppSwitchLocked(bool handled);
|
||||
|
||||
// All registered connections mapped by receive pipe file descriptor.
|
||||
KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
|
||||
|
||||
@ -591,20 +865,15 @@ private:
|
||||
// the duration.
|
||||
Vector<Connection*> mTimedOutConnections;
|
||||
|
||||
// Preallocated key and motion event objects used only to ask the input dispatcher policy
|
||||
// for the targets of an event that is to be dispatched.
|
||||
KeyEvent mReusableKeyEvent;
|
||||
MotionEvent mReusableMotionEvent;
|
||||
// Input channels that will receive a copy of all input events.
|
||||
Vector<sp<InputChannel> > mMonitoringChannels;
|
||||
|
||||
// The input targets that were most recently identified for dispatch.
|
||||
// If there is a synchronous event dispatch in progress, the current input targets will
|
||||
// remain unchanged until the dispatch has completed or been aborted.
|
||||
Vector<InputTarget> mCurrentInputTargets;
|
||||
bool mCurrentInputTargetsValid; // false while targets are being recomputed
|
||||
// Preallocated key event object used for policy inquiries.
|
||||
KeyEvent mReusableKeyEvent;
|
||||
|
||||
// Event injection and synchronization.
|
||||
Condition mInjectionResultAvailableCondition;
|
||||
EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
|
||||
EventEntry* createEntryFromInjectedInputEventLocked(const InputEvent* event);
|
||||
void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
|
||||
|
||||
Condition mInjectionSyncFinishedCondition;
|
||||
@ -622,36 +891,108 @@ private:
|
||||
} mThrottleState;
|
||||
|
||||
// Key repeat tracking.
|
||||
// XXX Move this up to the input reader instead.
|
||||
struct KeyRepeatState {
|
||||
KeyEntry* lastKeyEntry; // or null if no repeat
|
||||
nsecs_t nextRepeatTime;
|
||||
} mKeyRepeatState;
|
||||
|
||||
void resetKeyRepeatLocked();
|
||||
KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime, nsecs_t keyRepeatTimeout);
|
||||
|
||||
// Deferred command processing.
|
||||
bool runCommandsLockedInterruptible();
|
||||
CommandEntry* postCommandLocked(Command command);
|
||||
|
||||
// Process events that have just been dequeued from the head of the input queue.
|
||||
void processConfigurationChangedLockedInterruptible(
|
||||
nsecs_t currentTime, ConfigurationChangedEntry* entry);
|
||||
void processKeyLockedInterruptible(
|
||||
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
|
||||
void processKeyRepeatLockedInterruptible(
|
||||
nsecs_t currentTime, nsecs_t keyRepeatTimeout);
|
||||
void processMotionLockedInterruptible(
|
||||
nsecs_t currentTime, MotionEntry* entry);
|
||||
// Inbound event processing.
|
||||
void drainInboundQueueLocked();
|
||||
void releasePendingEventLocked(bool wasDropped);
|
||||
void releaseInboundEventLocked(EventEntry* entry, bool wasDropped);
|
||||
bool isEventFromReliableSourceLocked(EventEntry* entry);
|
||||
|
||||
// Identify input targets for an event and dispatch to them.
|
||||
void identifyInputTargetsAndDispatchKeyLockedInterruptible(
|
||||
nsecs_t currentTime, KeyEntry* entry);
|
||||
void identifyInputTargetsAndDispatchMotionLockedInterruptible(
|
||||
nsecs_t currentTime, MotionEntry* entry);
|
||||
// Dispatch state.
|
||||
bool mDispatchEnabled;
|
||||
bool mDispatchFrozen;
|
||||
Vector<InputWindow> mWindows;
|
||||
Vector<InputWindow*> mWallpaperWindows;
|
||||
|
||||
// Focus tracking for keys, trackball, etc.
|
||||
InputWindow* mFocusedWindow;
|
||||
|
||||
// Focus tracking for touch.
|
||||
bool mTouchDown;
|
||||
InputWindow* mTouchedWindow; // primary target for current down
|
||||
bool mTouchedWindowIsObscured; // true if other windows may obscure the target
|
||||
Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets
|
||||
struct OutsideTarget {
|
||||
InputWindow* window;
|
||||
bool obscured;
|
||||
};
|
||||
Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets
|
||||
Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets
|
||||
|
||||
// Focused application.
|
||||
InputApplication* mFocusedApplication;
|
||||
InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication
|
||||
void releaseFocusedApplicationLocked();
|
||||
|
||||
// Dispatch inbound events.
|
||||
bool dispatchConfigurationChangedLocked(
|
||||
nsecs_t currentTime, ConfigurationChangedEntry* entry);
|
||||
bool dispatchKeyLocked(
|
||||
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
|
||||
nsecs_t* nextWakeupTime);
|
||||
bool dispatchMotionLocked(
|
||||
nsecs_t currentTime, MotionEntry* entry,
|
||||
nsecs_t* nextWakeupTime);
|
||||
void dispatchEventToCurrentInputTargetsLocked(
|
||||
nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
|
||||
|
||||
void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
|
||||
void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
|
||||
|
||||
// The input targets that were most recently identified for dispatch.
|
||||
// If there is a synchronous event dispatch in progress, the current input targets will
|
||||
// remain unchanged until the dispatch has completed or been aborted.
|
||||
bool mCurrentInputTargetsValid; // false while targets are being recomputed
|
||||
Vector<InputTarget> mCurrentInputTargets;
|
||||
int32_t mCurrentInputWindowType;
|
||||
sp<InputChannel> mCurrentInputChannel;
|
||||
|
||||
enum InputTargetWaitCause {
|
||||
INPUT_TARGET_WAIT_CAUSE_NONE,
|
||||
INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
|
||||
INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
|
||||
};
|
||||
|
||||
InputTargetWaitCause mInputTargetWaitCause;
|
||||
nsecs_t mInputTargetWaitStartTime;
|
||||
nsecs_t mInputTargetWaitTimeoutTime;
|
||||
bool mInputTargetWaitTimeoutExpired;
|
||||
|
||||
// Finding targets for input events.
|
||||
void startFindingTargetsLocked();
|
||||
void finishFindingTargetsLocked(const InputWindow* window);
|
||||
int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
|
||||
const InputApplication* application, const InputWindow* window,
|
||||
nsecs_t* nextWakeupTime);
|
||||
void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout);
|
||||
nsecs_t getTimeSpentWaitingForApplicationWhileFindingTargetsLocked(nsecs_t currentTime);
|
||||
void resetANRTimeoutsLocked();
|
||||
|
||||
int32_t findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry,
|
||||
nsecs_t* nextWakeupTime, InputWindow** outWindow);
|
||||
int32_t findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry,
|
||||
nsecs_t* nextWakeupTime, InputWindow** outWindow);
|
||||
|
||||
void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
|
||||
nsecs_t timeSpentWaitingForApplication);
|
||||
void addMonitoringTargetsLocked();
|
||||
void pokeUserActivityLocked(nsecs_t eventTime, int32_t windowType, int32_t eventType);
|
||||
bool checkInjectionPermission(const InputWindow* window,
|
||||
int32_t injectorPid, int32_t injectorUid);
|
||||
bool isWindowObscuredLocked(const InputWindow* window);
|
||||
void releaseTouchedWindowLocked();
|
||||
|
||||
// Manage the dispatch cycle for a single connection.
|
||||
// These methods are deliberately not Interruptible because doing all of the work
|
||||
// with the mutex held makes it easier to ensure that connection invariants are maintained.
|
||||
@ -659,15 +1000,25 @@ private:
|
||||
void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
|
||||
EventEntry* eventEntry, const InputTarget* inputTarget,
|
||||
bool resumeWithAppendedMotionSample);
|
||||
void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
|
||||
void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
|
||||
nsecs_t timeSpentWaitingForApplication);
|
||||
void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
|
||||
void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
|
||||
void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
|
||||
void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
|
||||
const sp<Connection>& connection, nsecs_t newTimeout);
|
||||
void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
|
||||
bool broken);
|
||||
void drainOutboundQueueLocked(Connection* connection, DispatchEntry* firstDispatchEntryToDrain);
|
||||
static bool handleReceiveCallback(int receiveFd, int events, void* data);
|
||||
|
||||
// Preempting input dispatch.
|
||||
bool preemptInputDispatchInnerLocked();
|
||||
|
||||
// Dump state.
|
||||
void dumpDispatchStateLocked(String8& dump);
|
||||
void logDispatchStateLocked();
|
||||
|
||||
// Add or remove a connection to the mActiveConnections vector.
|
||||
void activateConnectionLocked(Connection* connection);
|
||||
void deactivateConnectionLocked(Connection* connection);
|
||||
@ -683,9 +1034,13 @@ private:
|
||||
nsecs_t currentTime, const sp<Connection>& connection);
|
||||
|
||||
// Outbound policy interactions.
|
||||
void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
|
||||
void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
|
||||
void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
|
||||
void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
|
||||
void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
|
||||
void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
|
||||
void doTargetsNotReadyTimeoutLockedInterruptible(CommandEntry* commandEntry);
|
||||
};
|
||||
|
||||
/* Enqueues and dispatches input events, endlessly. */
|
||||
@ -702,4 +1057,4 @@ private:
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_INPUT_DISPATCHER_PRIV_H
|
||||
#endif // _UI_INPUT_DISPATCHER_H
|
||||
|
@ -72,51 +72,11 @@ public:
|
||||
/* Stops the input manager threads and waits for them to exit. */
|
||||
virtual status_t stop() = 0;
|
||||
|
||||
/* Registers an input channel prior to using it as the target of an event. */
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
|
||||
/* Gets the input reader. */
|
||||
virtual sp<InputReaderInterface> getReader() = 0;
|
||||
|
||||
/* Unregisters an input channel. */
|
||||
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
|
||||
|
||||
/* Injects an input event and optionally waits for sync.
|
||||
* The synchronization mode determines whether the method blocks while waiting for
|
||||
* input injection to proceed.
|
||||
* Returns one of the INPUT_EVENT_INJECTION_XXX constants.
|
||||
*/
|
||||
virtual int32_t injectInputEvent(const InputEvent* event,
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
|
||||
|
||||
/* Preempts input dispatch in progress by making pending synchronous
|
||||
* dispatches asynchronous instead. This method is generally called during a focus
|
||||
* transition from one application to the next so as to enable the new application
|
||||
* to start receiving input as soon as possible without having to wait for the
|
||||
* old application to finish up.
|
||||
*/
|
||||
virtual void preemptInputDispatch() = 0;
|
||||
|
||||
/* Gets input device configuration. */
|
||||
virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
|
||||
|
||||
/* Gets information about the specified input device.
|
||||
* Returns OK if the device information was obtained or NAME_NOT_FOUND if there
|
||||
* was no such device.
|
||||
*/
|
||||
virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
|
||||
|
||||
/* Gets the list of all registered device ids. */
|
||||
virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
|
||||
|
||||
/* Queries current input state. */
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t scanCode) = 0;
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t keyCode) = 0;
|
||||
virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t sw) = 0;
|
||||
|
||||
/* Determines whether physical keys exist for the given framework-domain key codes. */
|
||||
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
|
||||
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
|
||||
/* Gets the input dispatcher. */
|
||||
virtual sp<InputDispatcherInterface> getDispatcher() = 0;
|
||||
};
|
||||
|
||||
class InputManager : public InputManagerInterface {
|
||||
@ -137,25 +97,8 @@ public:
|
||||
virtual status_t start();
|
||||
virtual status_t stop();
|
||||
|
||||
virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
|
||||
virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
|
||||
|
||||
virtual int32_t injectInputEvent(const InputEvent* event,
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
|
||||
|
||||
virtual void preemptInputDispatch();
|
||||
|
||||
virtual void getInputConfiguration(InputConfiguration* outConfiguration);
|
||||
virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
|
||||
virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t scanCode);
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t keyCode);
|
||||
virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t sw);
|
||||
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
|
||||
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
|
||||
virtual sp<InputReaderInterface> getReader();
|
||||
virtual sp<InputDispatcherInterface> getDispatcher();
|
||||
|
||||
private:
|
||||
sp<InputReaderInterface> mReader;
|
||||
|
@ -95,10 +95,6 @@ public:
|
||||
|
||||
// The input dispatcher should dispatch the input to the application.
|
||||
ACTION_DISPATCH = 0x00000001,
|
||||
|
||||
// The input dispatcher should perform special filtering in preparation for
|
||||
// a pending app switch.
|
||||
ACTION_APP_SWITCH_COMING = 0x00000002,
|
||||
};
|
||||
|
||||
/* Gets information about the display with the specified id.
|
||||
@ -168,6 +164,11 @@ protected:
|
||||
virtual ~InputReaderInterface() { }
|
||||
|
||||
public:
|
||||
/* Dumps the state of the input reader.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager). */
|
||||
virtual void dump(String8& dump) = 0;
|
||||
|
||||
/* Runs a single iteration of the processing loop.
|
||||
* Nominally reads and processes one incoming message from the EventHub.
|
||||
*
|
||||
@ -240,6 +241,8 @@ public:
|
||||
const sp<InputDispatcherInterface>& dispatcher);
|
||||
virtual ~InputReader();
|
||||
|
||||
virtual void dump(String8& dump);
|
||||
|
||||
virtual void loopOnce();
|
||||
|
||||
virtual void getInputConfiguration(InputConfiguration* outConfiguration);
|
||||
@ -305,6 +308,9 @@ private:
|
||||
GetStateFunc getStateFunc);
|
||||
bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
// dump state
|
||||
void dumpDeviceInfo(String8& dump);
|
||||
};
|
||||
|
||||
|
||||
@ -759,9 +765,11 @@ protected:
|
||||
} mLocked;
|
||||
|
||||
virtual void configureParameters();
|
||||
virtual void logParameters();
|
||||
virtual void configureRawAxes();
|
||||
virtual void logRawAxes();
|
||||
virtual bool configureSurfaceLocked();
|
||||
virtual void logMotionRangesLocked();
|
||||
virtual void configureVirtualKeysLocked();
|
||||
virtual void parseCalibration();
|
||||
virtual void resolveCalibration();
|
||||
|
37
include/ui/PowerManager.h
Normal file
37
include/ui/PowerManager.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UI_POWER_MANAGER_H
|
||||
#define _UI_POWER_MANAGER_H
|
||||
|
||||
|
||||
namespace android {
|
||||
|
||||
enum {
|
||||
POWER_MANAGER_OTHER_EVENT = 0,
|
||||
POWER_MANAGER_CHEEK_EVENT = 1,
|
||||
POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
|
||||
// up events or LONG_TOUCH events.
|
||||
POWER_MANAGER_LONG_TOUCH_EVENT = 3,
|
||||
POWER_MANAGER_TOUCH_UP_EVENT = 4,
|
||||
POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
|
||||
|
||||
POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code.
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_POWER_MANAGER_H
|
@ -172,22 +172,36 @@ private:
|
||||
void* data;
|
||||
};
|
||||
|
||||
const bool mAllowNonCallbacks;
|
||||
const bool mAllowNonCallbacks; // immutable
|
||||
|
||||
int mWakeReadPipeFd; // immutable
|
||||
int mWakeWritePipeFd; // immutable
|
||||
|
||||
// The lock guards state used to track whether there is a poll() in progress and whether
|
||||
// there are any other threads waiting in wakeAndLock(). The condition variables
|
||||
// are used to transfer control among these threads such that all waiters are
|
||||
// serviced before a new poll can begin.
|
||||
// The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake
|
||||
// until mPolling becomes false, then decrements mWaiters again.
|
||||
// The poll() method blocks on mResume until mWaiters becomes 0, then sets
|
||||
// mPolling to true, blocks until the poll completes, then resets mPolling to false
|
||||
// and signals mResume if there are waiters.
|
||||
Mutex mLock;
|
||||
bool mPolling;
|
||||
uint32_t mWaiters;
|
||||
Condition mAwake;
|
||||
Condition mResume;
|
||||
|
||||
int mWakeReadPipeFd;
|
||||
int mWakeWritePipeFd;
|
||||
bool mPolling; // guarded by mLock
|
||||
uint32_t mWaiters; // guarded by mLock
|
||||
Condition mAwake; // guarded by mLock
|
||||
Condition mResume; // guarded by mLock
|
||||
|
||||
// The next two vectors are only mutated when mPolling is false since they must
|
||||
// not be changed while the poll() system call is in progress. To mutate these
|
||||
// vectors, the poll() must first be awoken then the lock acquired.
|
||||
Vector<struct pollfd> mRequestedFds;
|
||||
Vector<RequestedCallback> mRequestedCallbacks;
|
||||
|
||||
Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
|
||||
Vector<PendingCallback> mPendingFds; // used privately by pollOnce
|
||||
// This state is only used privately by pollOnce and does not require a lock since
|
||||
// it runs on a single thread.
|
||||
Vector<PendingCallback> mPendingCallbacks;
|
||||
Vector<PendingCallback> mPendingFds;
|
||||
size_t mPendingFdsPos;
|
||||
|
||||
void openWakePipe();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -72,52 +72,12 @@ status_t InputManager::stop() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t InputManager::registerInputChannel(const sp<InputChannel>& inputChannel) {
|
||||
return mDispatcher->registerInputChannel(inputChannel);
|
||||
sp<InputReaderInterface> InputManager::getReader() {
|
||||
return mReader;
|
||||
}
|
||||
|
||||
status_t InputManager::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
|
||||
return mDispatcher->unregisterInputChannel(inputChannel);
|
||||
}
|
||||
|
||||
int32_t InputManager::injectInputEvent(const InputEvent* event,
|
||||
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
|
||||
return mDispatcher->injectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
|
||||
}
|
||||
|
||||
void InputManager::preemptInputDispatch() {
|
||||
mDispatcher->preemptInputDispatch();
|
||||
}
|
||||
|
||||
void InputManager::getInputConfiguration(InputConfiguration* outConfiguration) {
|
||||
mReader->getInputConfiguration(outConfiguration);
|
||||
}
|
||||
|
||||
status_t InputManager::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
|
||||
return mReader->getInputDeviceInfo(deviceId, outDeviceInfo);
|
||||
}
|
||||
|
||||
void InputManager::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
|
||||
mReader->getInputDeviceIds(outDeviceIds);
|
||||
}
|
||||
|
||||
int32_t InputManager::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t scanCode) {
|
||||
return mReader->getScanCodeState(deviceId, sourceMask, scanCode);
|
||||
}
|
||||
|
||||
int32_t InputManager::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t keyCode) {
|
||||
return mReader->getKeyCodeState(deviceId, sourceMask, keyCode);
|
||||
}
|
||||
|
||||
int32_t InputManager::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) {
|
||||
return mReader->getSwitchState(deviceId, sourceMask, sw);
|
||||
}
|
||||
|
||||
bool InputManager::hasKeys(int32_t deviceId, uint32_t sourceMask,
|
||||
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
|
||||
return mReader->hasKeys(deviceId, sourceMask, numCodes, keyCodes, outFlags);
|
||||
sp<InputDispatcherInterface> InputManager::getDispatcher() {
|
||||
return mDispatcher;
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
@ -573,6 +573,60 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s
|
||||
} // release device registy reader lock
|
||||
}
|
||||
|
||||
void InputReader::dump(String8& dump) {
|
||||
dumpDeviceInfo(dump);
|
||||
}
|
||||
|
||||
static void dumpMotionRange(String8& dump,
|
||||
const char* name, const InputDeviceInfo::MotionRange* range) {
|
||||
if (range) {
|
||||
dump.appendFormat(" %s = { min: %0.3f, max: %0.3f, flat: %0.3f, fuzz: %0.3f }\n",
|
||||
name, range->min, range->max, range->flat, range->fuzz);
|
||||
}
|
||||
}
|
||||
|
||||
#define DUMP_MOTION_RANGE(range) \
|
||||
dumpMotionRange(dump, #range, deviceInfo.getMotionRange(AINPUT_MOTION_RANGE_##range));
|
||||
|
||||
void InputReader::dumpDeviceInfo(String8& dump) {
|
||||
Vector<int32_t> deviceIds;
|
||||
getInputDeviceIds(deviceIds);
|
||||
|
||||
InputDeviceInfo deviceInfo;
|
||||
for (size_t i = 0; i < deviceIds.size(); i++) {
|
||||
int32_t deviceId = deviceIds[i];
|
||||
|
||||
status_t result = getInputDeviceInfo(deviceId, & deviceInfo);
|
||||
if (result == NAME_NOT_FOUND) {
|
||||
continue;
|
||||
} else if (result != OK) {
|
||||
dump.appendFormat(" ** Unexpected error %d getting information about input devices.\n",
|
||||
result);
|
||||
continue;
|
||||
}
|
||||
|
||||
dump.appendFormat(" Device %d: '%s'\n",
|
||||
deviceInfo.getId(), deviceInfo.getName().string());
|
||||
dump.appendFormat(" sources = 0x%08x\n",
|
||||
deviceInfo.getSources());
|
||||
dump.appendFormat(" keyboardType = %d\n",
|
||||
deviceInfo.getKeyboardType());
|
||||
|
||||
dump.append(" motion ranges:\n");
|
||||
DUMP_MOTION_RANGE(X);
|
||||
DUMP_MOTION_RANGE(Y);
|
||||
DUMP_MOTION_RANGE(PRESSURE);
|
||||
DUMP_MOTION_RANGE(SIZE);
|
||||
DUMP_MOTION_RANGE(TOUCH_MAJOR);
|
||||
DUMP_MOTION_RANGE(TOUCH_MINOR);
|
||||
DUMP_MOTION_RANGE(TOOL_MAJOR);
|
||||
DUMP_MOTION_RANGE(TOOL_MINOR);
|
||||
DUMP_MOTION_RANGE(ORIENTATION);
|
||||
}
|
||||
}
|
||||
|
||||
#undef DUMP_MOTION_RANGE
|
||||
|
||||
|
||||
// --- InputReaderThread ---
|
||||
|
||||
@ -740,10 +794,6 @@ int32_t InputMapper::getMetaState() {
|
||||
}
|
||||
|
||||
bool InputMapper::applyStandardPolicyActions(nsecs_t when, int32_t policyActions) {
|
||||
if (policyActions & InputReaderPolicyInterface::ACTION_APP_SWITCH_COMING) {
|
||||
getDispatcher()->notifyAppSwitchComing(when);
|
||||
}
|
||||
|
||||
return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
|
||||
}
|
||||
|
||||
@ -1249,20 +1299,12 @@ void TouchInputMapper::initializeLocked() {
|
||||
mLocked.orientedRanges.haveOrientation = false;
|
||||
}
|
||||
|
||||
static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
|
||||
if (axis.valid) {
|
||||
LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
|
||||
name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
|
||||
} else {
|
||||
LOGI(INDENT "Raw %s axis: unknown range", name);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputMapper::configure() {
|
||||
InputMapper::configure();
|
||||
|
||||
// Configure basic parameters.
|
||||
configureParameters();
|
||||
logParameters();
|
||||
|
||||
// Configure absolute axis information.
|
||||
configureRawAxes();
|
||||
@ -1287,6 +1329,18 @@ void TouchInputMapper::configureParameters() {
|
||||
mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
|
||||
}
|
||||
|
||||
void TouchInputMapper::logParameters() {
|
||||
if (mParameters.useBadTouchFilter) {
|
||||
LOGI(INDENT "Bad touch filter enabled.");
|
||||
}
|
||||
if (mParameters.useAveragingTouchFilter) {
|
||||
LOGI(INDENT "Averaging touch filter enabled.");
|
||||
}
|
||||
if (mParameters.useJumpyTouchFilter) {
|
||||
LOGI(INDENT "Jumpy touch filter enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputMapper::configureRawAxes() {
|
||||
mRawAxes.x.clear();
|
||||
mRawAxes.y.clear();
|
||||
@ -1298,6 +1352,15 @@ void TouchInputMapper::configureRawAxes() {
|
||||
mRawAxes.orientation.clear();
|
||||
}
|
||||
|
||||
static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
|
||||
if (axis.valid) {
|
||||
LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
|
||||
name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
|
||||
} else {
|
||||
LOGI(INDENT "Raw %s axis: unknown range", name);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputMapper::logRawAxes() {
|
||||
logAxisInfo(mRawAxes.x, "x");
|
||||
logAxisInfo(mRawAxes.y, "y");
|
||||
@ -1331,8 +1394,10 @@ bool TouchInputMapper::configureSurfaceLocked() {
|
||||
|
||||
bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
|
||||
if (sizeChanged) {
|
||||
LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
|
||||
LOGI("Device reconfigured (display size changed): id=0x%x, name=%s",
|
||||
getDeviceId(), getDeviceName().string());
|
||||
LOGI(INDENT "Width: %dpx", width);
|
||||
LOGI(INDENT "Height: %dpx", height);
|
||||
|
||||
mLocked.surfaceWidth = width;
|
||||
mLocked.surfaceHeight = height;
|
||||
@ -1500,9 +1565,41 @@ bool TouchInputMapper::configureSurfaceLocked() {
|
||||
mLocked.orientedRanges.y.fuzz = orientedYScale;
|
||||
}
|
||||
|
||||
if (sizeChanged) {
|
||||
logMotionRangesLocked();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void logMotionRangeInfo(InputDeviceInfo::MotionRange* range, const char* name) {
|
||||
if (range) {
|
||||
LOGI(INDENT "Output %s range: min=%f, max=%f, flat=%f, fuzz=%f",
|
||||
name, range->min, range->max, range->flat, range->fuzz);
|
||||
} else {
|
||||
LOGI(INDENT "Output %s range: unsupported", name);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchInputMapper::logMotionRangesLocked() {
|
||||
logMotionRangeInfo(& mLocked.orientedRanges.x, "x");
|
||||
logMotionRangeInfo(& mLocked.orientedRanges.y, "y");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.havePressure
|
||||
? & mLocked.orientedRanges.pressure : NULL, "pressure");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveSize
|
||||
? & mLocked.orientedRanges.size : NULL, "size");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea
|
||||
? & mLocked.orientedRanges.touchMajor : NULL, "touchMajor");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea
|
||||
? & mLocked.orientedRanges.touchMinor : NULL, "touchMinor");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveToolArea
|
||||
? & mLocked.orientedRanges.toolMajor : NULL, "toolMajor");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveToolArea
|
||||
? & mLocked.orientedRanges.toolMinor : NULL, "toolMinor");
|
||||
logMotionRangeInfo(mLocked.orientedRanges.haveOrientation
|
||||
? & mLocked.orientedRanges.orientation : NULL, "orientation");
|
||||
}
|
||||
|
||||
void TouchInputMapper::configureVirtualKeysLocked() {
|
||||
assert(mRawAxes.x.valid && mRawAxes.y.valid);
|
||||
|
||||
@ -1768,16 +1865,18 @@ void TouchInputMapper::resolveCalibration() {
|
||||
}
|
||||
|
||||
void TouchInputMapper::logCalibration() {
|
||||
LOGI(INDENT "Calibration:");
|
||||
|
||||
// Touch Area
|
||||
switch (mCalibration.touchAreaCalibration) {
|
||||
case Calibration::TOUCH_AREA_CALIBRATION_NONE:
|
||||
LOGI(INDENT " touch.touchArea.calibration: none");
|
||||
LOGI(INDENT INDENT "touch.touchArea.calibration: none");
|
||||
break;
|
||||
case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
|
||||
LOGI(INDENT " touch.touchArea.calibration: geometric");
|
||||
LOGI(INDENT INDENT "touch.touchArea.calibration: geometric");
|
||||
break;
|
||||
case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
|
||||
LOGI(INDENT " touch.touchArea.calibration: pressure");
|
||||
LOGI(INDENT INDENT "touch.touchArea.calibration: pressure");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@ -1786,40 +1885,40 @@ void TouchInputMapper::logCalibration() {
|
||||
// Tool Area
|
||||
switch (mCalibration.toolAreaCalibration) {
|
||||
case Calibration::TOOL_AREA_CALIBRATION_NONE:
|
||||
LOGI(INDENT " touch.toolArea.calibration: none");
|
||||
LOGI(INDENT INDENT "touch.toolArea.calibration: none");
|
||||
break;
|
||||
case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
|
||||
LOGI(INDENT " touch.toolArea.calibration: geometric");
|
||||
LOGI(INDENT INDENT "touch.toolArea.calibration: geometric");
|
||||
break;
|
||||
case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
|
||||
LOGI(INDENT " touch.toolArea.calibration: linear");
|
||||
LOGI(INDENT INDENT "touch.toolArea.calibration: linear");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (mCalibration.haveToolAreaLinearScale) {
|
||||
LOGI(INDENT " touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
|
||||
LOGI(INDENT INDENT "touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
|
||||
}
|
||||
|
||||
if (mCalibration.haveToolAreaLinearBias) {
|
||||
LOGI(INDENT " touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
|
||||
LOGI(INDENT INDENT "touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
|
||||
}
|
||||
|
||||
if (mCalibration.haveToolAreaIsSummed) {
|
||||
LOGI(INDENT " touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
|
||||
LOGI(INDENT INDENT "touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
|
||||
}
|
||||
|
||||
// Pressure
|
||||
switch (mCalibration.pressureCalibration) {
|
||||
case Calibration::PRESSURE_CALIBRATION_NONE:
|
||||
LOGI(INDENT " touch.pressure.calibration: none");
|
||||
LOGI(INDENT INDENT "touch.pressure.calibration: none");
|
||||
break;
|
||||
case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
|
||||
LOGI(INDENT " touch.pressure.calibration: physical");
|
||||
LOGI(INDENT INDENT "touch.pressure.calibration: physical");
|
||||
break;
|
||||
case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
|
||||
LOGI(INDENT " touch.pressure.calibration: amplitude");
|
||||
LOGI(INDENT INDENT "touch.pressure.calibration: amplitude");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@ -1827,10 +1926,10 @@ void TouchInputMapper::logCalibration() {
|
||||
|
||||
switch (mCalibration.pressureSource) {
|
||||
case Calibration::PRESSURE_SOURCE_PRESSURE:
|
||||
LOGI(INDENT " touch.pressure.source: pressure");
|
||||
LOGI(INDENT INDENT "touch.pressure.source: pressure");
|
||||
break;
|
||||
case Calibration::PRESSURE_SOURCE_TOUCH:
|
||||
LOGI(INDENT " touch.pressure.source: touch");
|
||||
LOGI(INDENT INDENT "touch.pressure.source: touch");
|
||||
break;
|
||||
case Calibration::PRESSURE_SOURCE_DEFAULT:
|
||||
break;
|
||||
@ -1839,16 +1938,16 @@ void TouchInputMapper::logCalibration() {
|
||||
}
|
||||
|
||||
if (mCalibration.havePressureScale) {
|
||||
LOGI(INDENT " touch.pressure.scale: %f", mCalibration.pressureScale);
|
||||
LOGI(INDENT INDENT "touch.pressure.scale: %f", mCalibration.pressureScale);
|
||||
}
|
||||
|
||||
// Size
|
||||
switch (mCalibration.sizeCalibration) {
|
||||
case Calibration::SIZE_CALIBRATION_NONE:
|
||||
LOGI(INDENT " touch.size.calibration: none");
|
||||
LOGI(INDENT INDENT "touch.size.calibration: none");
|
||||
break;
|
||||
case Calibration::SIZE_CALIBRATION_NORMALIZED:
|
||||
LOGI(INDENT " touch.size.calibration: normalized");
|
||||
LOGI(INDENT INDENT "touch.size.calibration: normalized");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@ -1857,10 +1956,10 @@ void TouchInputMapper::logCalibration() {
|
||||
// Orientation
|
||||
switch (mCalibration.orientationCalibration) {
|
||||
case Calibration::ORIENTATION_CALIBRATION_NONE:
|
||||
LOGI(INDENT " touch.orientation.calibration: none");
|
||||
LOGI(INDENT INDENT "touch.orientation.calibration: none");
|
||||
break;
|
||||
case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
|
||||
LOGI(INDENT " touch.orientation.calibration: interpolated");
|
||||
LOGI(INDENT INDENT "touch.orientation.calibration: interpolated");
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -120,6 +120,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
|
||||
return pending.ident;
|
||||
}
|
||||
|
||||
// Wait for wakeAndLock() waiters to run then set mPolling to true.
|
||||
mLock.lock();
|
||||
while (mWaiters != 0) {
|
||||
mResume.wait(mLock);
|
||||
@ -127,6 +128,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
|
||||
mPolling = true;
|
||||
mLock.unlock();
|
||||
|
||||
// Poll.
|
||||
int32_t result;
|
||||
size_t requestedCount = mRequestedFds.size();
|
||||
|
||||
@ -168,6 +170,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Process the poll results.
|
||||
mPendingCallbacks.clear();
|
||||
mPendingFds.clear();
|
||||
mPendingFdsPos = 0;
|
||||
@ -218,6 +221,7 @@ int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
|
||||
}
|
||||
|
||||
Done:
|
||||
// Set mPolling to false and wake up the wakeAndLock() waiters.
|
||||
mLock.lock();
|
||||
mPolling = false;
|
||||
if (mWaiters != 0) {
|
||||
@ -357,11 +361,13 @@ ssize_t PollLoop::getRequestIndexLocked(int fd) {
|
||||
|
||||
void PollLoop::wakeAndLock() {
|
||||
mLock.lock();
|
||||
|
||||
mWaiters += 1;
|
||||
while (mPolling) {
|
||||
wake();
|
||||
mAwake.wait(mLock);
|
||||
}
|
||||
|
||||
mWaiters -= 1;
|
||||
if (mWaiters == 0) {
|
||||
mResume.signal();
|
||||
|
@ -432,11 +432,6 @@ public class InputManager {
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void notifyAppSwitchComing() {
|
||||
mWindowManagerService.mInputMonitor.notifyAppSwitchComing();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public boolean filterTouchEvents() {
|
||||
return mContext.getResources().getBoolean(
|
||||
|
@ -1751,24 +1751,28 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
p.println(" mSystemReady=" + mSystemReady + " mScreenOn=" + mScreenOn);
|
||||
}
|
||||
|
||||
if (client != null) {
|
||||
p.println(" ");
|
||||
if (client != null) {
|
||||
pw.flush();
|
||||
try {
|
||||
client.client.asBinder().dump(fd, args);
|
||||
} catch (RemoteException e) {
|
||||
p.println("Input method client dead: " + e);
|
||||
}
|
||||
} else {
|
||||
p.println("No input method client.");
|
||||
}
|
||||
|
||||
if (method != null) {
|
||||
p.println(" ");
|
||||
if (method != null) {
|
||||
pw.flush();
|
||||
try {
|
||||
method.asBinder().dump(fd, args);
|
||||
} catch (RemoteException e) {
|
||||
p.println("Input method service dead: " + e);
|
||||
}
|
||||
} else {
|
||||
p.println("No input method service.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5098,8 +5098,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
/* Notifies the window manager about an input channel that is not responding.
|
||||
* The method can either cause dispatching to be aborted by returning -2 or
|
||||
* return a new timeout in nanoseconds.
|
||||
* Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
|
||||
*
|
||||
* Called by the InputManager.
|
||||
*/
|
||||
@ -5108,7 +5107,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
synchronized (mWindowMap) {
|
||||
WindowState windowState = getWindowStateForInputChannelLocked(inputChannel);
|
||||
if (windowState == null) {
|
||||
return -2; // irrelevant, abort dispatching (-2)
|
||||
return 0; // window is unknown, abort dispatching
|
||||
}
|
||||
|
||||
Slog.i(TAG, "Input event dispatching timed out sending to "
|
||||
@ -5131,8 +5130,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
/* Notifies the window manager about an application that is not responding
|
||||
* in general rather than with respect to a particular input channel.
|
||||
* The method can either cause dispatching to be aborted by returning -2 or
|
||||
* return a new timeout in nanoseconds.
|
||||
* Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
|
||||
*
|
||||
* Called by the InputManager.
|
||||
*/
|
||||
@ -5158,7 +5156,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
return -2; // abort dispatching
|
||||
return 0; // abort dispatching
|
||||
}
|
||||
|
||||
private WindowState getWindowStateForInputChannel(InputChannel inputChannel) {
|
||||
@ -5272,15 +5270,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/* Notifies that an app switch key (BACK / HOME) has just been pressed.
|
||||
* This essentially starts a .5 second timeout for the application to process
|
||||
* subsequent input events while waiting for the app switch to occur. If it takes longer
|
||||
* than this, the pending events will be dropped.
|
||||
*/
|
||||
public void notifyAppSwitchComing() {
|
||||
// TODO Not implemented yet. Should go in the native side.
|
||||
}
|
||||
|
||||
/* Notifies that the lid switch changed state. */
|
||||
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
|
||||
mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,20 +20,10 @@
|
||||
#include "JNIHelp.h"
|
||||
#include "jni.h"
|
||||
|
||||
#include <ui/PowerManager.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
enum {
|
||||
POWER_MANAGER_OTHER_EVENT = 0,
|
||||
POWER_MANAGER_CHEEK_EVENT = 1,
|
||||
POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
|
||||
// up events or LONG_TOUCH events.
|
||||
POWER_MANAGER_LONG_TOUCH_EVENT = 3,
|
||||
POWER_MANAGER_TOUCH_UP_EVENT = 4,
|
||||
POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
|
||||
|
||||
POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code.
|
||||
};
|
||||
|
||||
extern bool android_server_PowerManagerService_isScreenOn();
|
||||
extern bool android_server_PowerManagerService_isScreenBright();
|
||||
extern void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType);
|
||||
|
Reference in New Issue
Block a user