Add support for new input sources.

Added several new coordinate values to MotionEvents to capture
touch major/minor area, tool major/minor area and orientation.

Renamed NDK input constants per convention.

Added InputDevice class in Java which will eventually provide
useful information about available input devices.

Added APIs for manufacturing new MotionEvent objects with multiple
pointers and all necessary coordinate data.

Fixed a bug in the input dispatcher where it could get stuck with
a pointer down forever.

Fixed a bug in the WindowManager where the input window list could
end up containing stale removed windows.

Fixed a bug in the WindowManager where the input channel was being
removed only after the final animation transition had taken place
which caused spurious WINDOW DIED log messages to be printed.

Change-Id: Ie55084da319b20aad29b28a0499b8dd98bb5da68
This commit is contained in:
Jeff Brown
2010-07-14 18:48:53 -07:00
parent d9452ecd0c
commit c5ed5910c9
36 changed files with 2439 additions and 617 deletions

View File

@ -102,6 +102,7 @@ import android.view.IWindow;
import android.view.IWindowManager;
import android.view.IWindowSession;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputQueue;
import android.view.KeyEvent;
import android.view.MotionEvent;
@ -2017,6 +2018,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ ", surface=" + win.mSurface);
final long origId = Binder.clearCallingIdentity();
win.disposeInputChannel();
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Remove " + win + ": mSurface=" + win.mSurface
@ -2077,8 +2080,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
private void removeWindowInnerLocked(Session session, WindowState win) {
mInputMonitor.windowIsBeingRemovedLw(win);
win.mRemoved = true;
if (mInputMethodTarget == win) {
@ -2157,6 +2158,8 @@ public class WindowManagerService extends IWindowManager.Stub
win.mAppToken.updateReportedVisibilityLocked();
}
}
mInputMonitor.updateInputWindowsLw();
}
private static void logSurface(WindowState w, String msg, RuntimeException where) {
@ -2907,7 +2910,6 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.isVisibleNow()) {
applyAnimationLocked(win,
WindowManagerPolicy.TRANSIT_EXIT, false);
mInputMonitor.windowIsBeingRemovedLw(win);
changed = true;
}
}
@ -2925,6 +2927,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
mInputMonitor.updateInputWindowsLw();
} else {
Slog.w(TAG, "Attempted to remove non-existing token: " + token);
}
@ -5111,7 +5114,7 @@ public class WindowManagerService extends IWindowManager.Stub
final int N = windows.size();
for (int i = N - 1; i >= 0; i--) {
final WindowState child = (WindowState) windows.get(i);
if (child.mInputChannel == null) {
if (child.mInputChannel == null || child.mRemoved) {
// Skip this window because it cannot possibly receive input.
continue;
}
@ -5288,11 +5291,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
public void windowIsBeingRemovedLw(WindowState window) {
// Window is being removed.
updateInputWindowsLw();
}
public void pauseDispatchingLw(WindowToken window) {
if (! window.paused) {
if (DEBUG_INPUT) {
@ -5410,19 +5408,24 @@ public class WindowManagerService extends IWindowManager.Stub
int metaState = ev.getMetaState();
int deviceId = ev.getDeviceId();
int scancode = ev.getScanCode();
int source = ev.getSource();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
if (downTime == 0) downTime = eventTime;
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source);
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final int result = mInputManager.injectKeyEvent(newEvent,
InputQueue.INPUT_EVENT_NATURE_KEY, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
return reportInjectionResult(result);
@ -5442,8 +5445,13 @@ public class WindowManagerService extends IWindowManager.Stub
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final int result = mInputManager.injectMotionEvent(ev,
InputQueue.INPUT_EVENT_NATURE_TOUCH, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
MotionEvent newEvent = MotionEvent.obtain(ev);
if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
final int result = mInputManager.injectMotionEvent(newEvent,
pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
return reportInjectionResult(result);
@ -5463,8 +5471,13 @@ public class WindowManagerService extends IWindowManager.Stub
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
final int result = mInputManager.injectMotionEvent(ev,
InputQueue.INPUT_EVENT_NATURE_TRACKBALL, pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
MotionEvent newEvent = MotionEvent.obtain(ev);
if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
}
final int result = mInputManager.injectMotionEvent(newEvent,
pid, uid, sync, INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
return reportInjectionResult(result);
@ -6960,6 +6973,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
void removeLocked() {
disposeInputChannel();
if (mAttachedWindow != null) {
mAttachedWindow.mChildWindows.remove(this);
}
@ -6971,7 +6986,9 @@ public class WindowManagerService extends IWindowManager.Stub
// Ignore if it has already been removed (usually because
// we are doing this as part of processing a death note.)
}
}
void disposeInputChannel() {
if (mInputChannel != null) {
mInputManager.unregisterInputChannel(mInputChannel);