Merge "Use asynchronous messages for input method events." into jb-mr1-aah-dev

This commit is contained in:
Mita Yun
2012-12-10 14:37:26 -08:00
committed by Android (Google) Code Review
7 changed files with 55 additions and 50 deletions

View File

@ -556,7 +556,7 @@ public abstract class AccessibilityService extends Service {
public IAccessibilityServiceClientWrapper(Context context, Looper looper, public IAccessibilityServiceClientWrapper(Context context, Looper looper,
Callbacks callback) { Callbacks callback) {
mCallback = callback; mCallback = callback;
mCaller = new HandlerCaller(context, looper, this); mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/);
} }
public void setConnection(IAccessibilityServiceConnection connection, int connectionId) { public void setConnection(IAccessibilityServiceConnection connection, int connectionId) {

View File

@ -70,7 +70,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
public IInputMethodSessionWrapper(Context context, public IInputMethodSessionWrapper(Context context,
InputMethodSession inputMethodSession) { InputMethodSession inputMethodSession) {
mCaller = new HandlerCaller(context, this); mCaller = new HandlerCaller(context, null,
this, true /*asyncHandler*/);
mInputMethodSession = inputMethodSession; mInputMethodSession = inputMethodSession;
} }

View File

@ -102,7 +102,8 @@ class IInputMethodWrapper extends IInputMethod.Stub
public IInputMethodWrapper(AbstractInputMethodService context, public IInputMethodWrapper(AbstractInputMethodService context,
InputMethod inputMethod) { InputMethod inputMethod) {
mTarget = new WeakReference<AbstractInputMethodService>(context); mTarget = new WeakReference<AbstractInputMethodService>(context);
mCaller = new HandlerCaller(context.getApplicationContext(), this); mCaller = new HandlerCaller(context.getApplicationContext(), null,
this, true /*asyncHandler*/);
mInputMethod = new WeakReference<InputMethod>(inputMethod); mInputMethod = new WeakReference<InputMethod>(inputMethod);
mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
} }

View File

@ -967,7 +967,7 @@ public abstract class WallpaperService extends Service {
mCaller = new HandlerCaller(context, mCaller = new HandlerCaller(context,
mCallbackLooper != null mCallbackLooper != null
? mCallbackLooper : context.getMainLooper(), ? mCallbackLooper : context.getMainLooper(),
this); this, true /*asyncHandler*/);
mConnection = conn; mConnection = conn;
mWindowToken = windowToken; mWindowToken = windowToken;
mWindowType = windowType; mWindowType = windowType;

View File

@ -40,7 +40,7 @@ class SimulatedTrackball {
private static final int MAX_TAP_TIME = 250; private static final int MAX_TAP_TIME = 250;
// Where the cutoff is for determining an edge swipe // Where the cutoff is for determining an edge swipe
private static final float EDGE_SWIPE_THRESHOLD = 0.9f; private static final float EDGE_SWIPE_THRESHOLD = 0.9f;
private static final int FLICK_MSG_ID = 313; private static final int MSG_FLICK = 313;
// TODO: Pass touch slop from the input device // TODO: Pass touch slop from the input device
private static final int TOUCH_SLOP = 30; private static final int TOUCH_SLOP = 30;
@ -75,8 +75,11 @@ class SimulatedTrackball {
// Has the TouchSlop constraint been invalidated // Has the TouchSlop constraint been invalidated
private boolean mAlwaysInTapRegion = true; private boolean mAlwaysInTapRegion = true;
// Most recent event. Used to determine what device sent the event. // Information from the most recent event.
private MotionEvent mRecentEvent; // Used to determine what device sent the event during a fling.
private int mLastSource;
private int mLastMetaState;
private int mLastDeviceId;
// TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to // TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to
// read this from a config file instead // read this from a config file instead
@ -101,33 +104,34 @@ class SimulatedTrackball {
mTouchSlopSquared = mTouchSlop * mTouchSlop; mTouchSlopSquared = mTouchSlop * mTouchSlop;
} }
private final Handler mHandler = new Handler(new Callback() { private final Handler mHandler = new Handler(true /*async*/) {
@Override @Override
public boolean handleMessage(Message msg) { public void handleMessage(Message msg) {
if (msg.what != FLICK_MSG_ID) switch (msg.what) {
return false; case MSG_FLICK: {
final long time = SystemClock.uptimeMillis(); final long time = SystemClock.uptimeMillis();
ViewRootImpl viewroot = (ViewRootImpl) msg.obj; ViewRootImpl viewroot = (ViewRootImpl) msg.obj;
// Send the key // Send the key
viewroot.enqueueInputEvent(new KeyEvent(time, time, viewroot.enqueueInputEvent(new KeyEvent(time, time,
KeyEvent.ACTION_DOWN, msg.arg2, 0, mRecentEvent.getMetaState(), KeyEvent.ACTION_DOWN, msg.arg2, 0, mLastMetaState,
mRecentEvent.getDeviceId(), 0, mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
viewroot.enqueueInputEvent(new KeyEvent(time, time, viewroot.enqueueInputEvent(new KeyEvent(time, time,
KeyEvent.ACTION_UP, msg.arg2, 0, mRecentEvent.getMetaState(), KeyEvent.ACTION_UP, msg.arg2, 0, mLastMetaState,
mRecentEvent.getDeviceId(), 0, mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource()));
// Increase the delay by the decay factor and resend
final int delay = (int) Math.ceil(mFlickDecay * msg.arg1);
if (delay <= mMaxRepeatDelay) {
Message msgCopy = Message.obtain(msg); Message msgCopy = Message.obtain(msg);
// Increase the delay by the decay factor msgCopy.arg1 = delay;
msgCopy.arg1 = (int) Math.ceil(mFlickDecay * msgCopy.arg1); msgCopy.setAsynchronous(true);
if (msgCopy.arg1 <= mMaxRepeatDelay) { mHandler.sendMessageDelayed(msgCopy, delay);
// Send the key again in arg1 milliseconds
mHandler.sendMessageDelayed(msgCopy, msgCopy.arg1);
} }
return false; break;
} }
}); }
}
};
public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) { public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) {
// Store what time the touchpad event occurred // Store what time the touchpad event occurred
@ -148,7 +152,7 @@ class SimulatedTrackball {
mEdgeSwipePossible = true; mEdgeSwipePossible = true;
} }
// Clear any flings // Clear any flings
mHandler.removeMessages(FLICK_MSG_ID); mHandler.removeMessages(MSG_FLICK);
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
@ -245,15 +249,20 @@ class SimulatedTrackball {
if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared && if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared &&
time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME && time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME &&
mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) { mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) {
Message message = Message.obtain(mHandler, FLICK_MSG_ID, mLastDeviceId = event.getDeviceId();
mLastSource = event.getSource();
mLastMetaState = event.getMetaState();
Message message = Message.obtain(mHandler, MSG_FLICK,
mKeySendRateMs, mLastKeySent, viewroot); mKeySendRateMs, mLastKeySent, viewroot);
mRecentEvent = event; message.setAsynchronous(true);
mHandler.sendMessageDelayed(message, mKeySendRateMs); mHandler.sendMessageDelayed(message, mKeySendRateMs);
} }
} }
mEdgeSwipePossible = false; mEdgeSwipePossible = false;
break; break;
} }
// Store touch event position and time // Store touch event position and time
mLastTouchPadEventTimeMs = time; mLastTouchPadEventTimeMs = time;
mLastTouchpadXPosition = event.getX(); mLastTouchpadXPosition = event.getX();

View File

@ -31,8 +31,8 @@ public class HandlerCaller {
final Callback mCallback; final Callback mCallback;
class MyHandler extends Handler { class MyHandler extends Handler {
MyHandler(Looper looper) { MyHandler(Looper looper, boolean async) {
super(looper); super(looper, null, async);
} }
@Override @Override
@ -45,17 +45,11 @@ public class HandlerCaller {
public void executeMessage(Message msg); public void executeMessage(Message msg);
} }
public HandlerCaller(Context context, Callback callback) { public HandlerCaller(Context context, Looper looper, Callback callback,
boolean asyncHandler) {
mContext = context; mContext = context;
mMainLooper = context.getMainLooper(); mMainLooper = looper != null ? looper : context.getMainLooper();
mH = new MyHandler(mMainLooper); mH = new MyHandler(mMainLooper, asyncHandler);
mCallback = callback;
}
public HandlerCaller(Context context, Looper looper, Callback callback) {
mContext = context;
mMainLooper = looper;
mH = new MyHandler(mMainLooper);
mCallback = callback; mCallback = callback;
} }

View File

@ -602,12 +602,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mHandler = new Handler(this); mHandler = new Handler(this);
mIWindowManager = IWindowManager.Stub.asInterface( mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE)); ServiceManager.getService(Context.WINDOW_SERVICE));
mCaller = new HandlerCaller(context, new HandlerCaller.Callback() { mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
@Override @Override
public void executeMessage(Message msg) { public void executeMessage(Message msg) {
handleMessage(msg); handleMessage(msg);
} }
}); }, true /*asyncHandler*/);
mWindowManagerService = windowManager; mWindowManagerService = windowManager;
mHardKeyboardListener = new HardKeyboardListener(); mHardKeyboardListener = new HardKeyboardListener();