Merge "Introduce a sequence number to avoid redundant IPCs"

This commit is contained in:
Yohei Yukawa
2014-06-09 12:02:29 +00:00
committed by Android (Google) Code Review
6 changed files with 127 additions and 14 deletions

View File

@@ -319,6 +319,25 @@ public final class InputMethodManager {
int mCursorCandStart;
int mCursorCandEnd;
/**
* Represents an invalid action notification sequence number. {@link InputMethodManagerService}
* always issues a positive integer for action notification sequence numbers. Thus -1 is
* guaranteed to be different from any valid sequence number.
*/
private static final int NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1;
/**
* The next sequence number that is to be sent to {@link InputMethodManagerService} via
* {@link IInputMethodManager#notifyUserAction(int)} at once when a user action is observed.
*/
private int mNextUserActionNotificationSequenceNumber =
NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER;
/**
* The last sequence number that is already sent to {@link InputMethodManagerService}.
*/
private int mLastSentUserActionNotificationSequenceNumber =
NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER;
/**
* The instance that has previously been sent to the input method.
*/
@@ -364,6 +383,7 @@ public final class InputMethodManager {
static final int MSG_TIMEOUT_INPUT_EVENT = 6;
static final int MSG_FLUSH_INPUT_EVENT = 7;
static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8;
static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9;
class H extends Handler {
H(Looper looper) {
@@ -503,6 +523,11 @@ public final class InputMethodManager {
}
return;
}
case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: {
synchronized (mH) {
mNextUserActionNotificationSequenceNumber = msg.arg1;
}
}
}
}
}
@@ -572,6 +597,12 @@ public final class InputMethodManager {
public void setCursorAnchorMonitorMode(int monitorMode) {
mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0));
}
@Override
public void setUserActionNotificationSequenceNumber(int sequenceNumber) {
mH.sendMessage(mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER,
sequenceNumber, 0));
}
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this, false);
@@ -1214,6 +1245,8 @@ public final class InputMethodManager {
mBindSequence = res.sequence;
mCurMethod = res.method;
mCurId = res.id;
mNextUserActionNotificationSequenceNumber =
res.userActionNotificationSequenceNumber;
} else {
if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
@@ -1918,8 +1951,28 @@ public final class InputMethodManager {
*/
public void notifyUserAction() {
synchronized (mH) {
if (mLastSentUserActionNotificationSequenceNumber ==
mNextUserActionNotificationSequenceNumber) {
if (DEBUG) {
Log.w(TAG, "Ignoring notifyUserAction as it has already been sent."
+ " mLastSentUserActionNotificationSequenceNumber: "
+ mLastSentUserActionNotificationSequenceNumber
+ " mNextUserActionNotificationSequenceNumber: "
+ mNextUserActionNotificationSequenceNumber);
}
return;
}
try {
mService.notifyUserAction();
if (DEBUG) {
Log.w(TAG, "notifyUserAction: "
+ " mLastSentUserActionNotificationSequenceNumber: "
+ mLastSentUserActionNotificationSequenceNumber
+ " mNextUserActionNotificationSequenceNumber: "
+ mNextUserActionNotificationSequenceNumber);
}
mService.notifyUserAction(mNextUserActionNotificationSequenceNumber);
mLastSentUserActionNotificationSequenceNumber =
mNextUserActionNotificationSequenceNumber;
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
@@ -2103,6 +2156,10 @@ public final class InputMethodManager {
+ " mCursorSelEnd=" + mCursorSelEnd
+ " mCursorCandStart=" + mCursorCandStart
+ " mCursorCandEnd=" + mCursorCandEnd);
p.println(" mNextUserActionNotificationSequenceNumber="
+ mNextUserActionNotificationSequenceNumber
+ " mLastSentUserActionNotificationSequenceNumber="
+ mLastSentUserActionNotificationSequenceNumber);
}
/**

View File

@@ -28,4 +28,5 @@ oneway interface IInputMethodClient {
void onUnbindMethod(int sequence);
void setActive(boolean active);
void setCursorAnchorMonitorMode(int monitorMode);
void setUserActionNotificationSequenceNumber(int sequenceNumber);
}

View File

@@ -77,6 +77,6 @@ interface IInputMethodManager {
boolean setInputMethodEnabled(String id, boolean enabled);
void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
int getInputMethodWindowVisibleHeight();
oneway void notifyUserAction();
oneway void notifyUserAction(int sequenceNumber);
void setCursorAnchorMonitorMode(in IBinder token, int monitorMode);
}

View File

@@ -47,13 +47,19 @@ public final class InputBindResult implements Parcelable {
* Sequence number of this binding.
*/
public final int sequence;
/**
* Sequence number of user action notification.
*/
public final int userActionNotificationSequenceNumber;
public InputBindResult(IInputMethodSession _method, InputChannel _channel,
String _id, int _sequence) {
String _id, int _sequence, int _userActionNotificationSequenceNumber) {
method = _method;
channel = _channel;
id = _id;
sequence = _sequence;
userActionNotificationSequenceNumber = _userActionNotificationSequenceNumber;
}
InputBindResult(Parcel source) {
@@ -65,12 +71,15 @@ public final class InputBindResult implements Parcelable {
}
id = source.readString();
sequence = source.readInt();
userActionNotificationSequenceNumber = source.readInt();
}
@Override
public String toString() {
return "InputBindResult{" + method + " " + id
+ " #" + sequence + "}";
+ " sequence:" + sequence
+ " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber
+ "}";
}
/**
@@ -90,6 +99,7 @@ public final class InputBindResult implements Parcelable {
}
dest.writeString(id);
dest.writeInt(sequence);
dest.writeInt(userActionNotificationSequenceNumber);
}
/**

View File

@@ -149,6 +149,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
static final int MSG_BIND_METHOD = 3010;
static final int MSG_SET_ACTIVE = 3020;
static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 3030;
static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 3040;
static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
@@ -172,7 +173,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final HardKeyboardListener mHardKeyboardListener;
private final WindowManagerService mWindowManagerService;
final InputBindResult mNoBinding = new InputBindResult(null, null, null, -1);
final InputBindResult mNoBinding = new InputBindResult(null, null, null, -1, -1);
// All known input methods. mMethodMap also serves as the global
// lock for this class.
@@ -379,6 +380,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
boolean mScreenOn = true;
int mCurUserActionNotificationSequenceNumber = 0;
int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
int mImeWindowVis;
@@ -1129,7 +1132,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
showCurrentInputLocked(getAppShowFlags(), null);
}
return new InputBindResult(session.session,
session.channel != null ? session.channel.dup() : null, mCurId, mCurSeq);
(session.channel != null ? session.channel.dup() : null),
mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber);
}
InputBindResult startInputLocked(IInputMethodClient client,
@@ -1205,7 +1209,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Return to client, and we will get back with it when
// we have had a session made for it.
requestClientSessionLocked(cs);
return new InputBindResult(null, null, mCurId, mCurSeq);
return new InputBindResult(null, null, mCurId, mCurSeq,
mCurUserActionNotificationSequenceNumber);
} else if (SystemClock.uptimeMillis()
< (mLastBindTime+TIME_TO_RECONNECT)) {
// In this case we have connected to the service, but
@@ -1215,7 +1220,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// we can report back. If it has been too long, we want
// to fall through so we can try a disconnect/reconnect
// to see if we can get back in touch with the service.
return new InputBindResult(null, null, mCurId, mCurSeq);
return new InputBindResult(null, null, mCurId, mCurSeq,
mCurUserActionNotificationSequenceNumber);
} else {
EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0);
@@ -1234,7 +1240,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!mSystemReady) {
// If the system is not yet ready, we shouldn't be running third
// party code.
return new InputBindResult(null, null, mCurMethodId, mCurSeq);
return new InputBindResult(null, null, mCurMethodId, mCurSeq,
mCurUserActionNotificationSequenceNumber);
}
InputMethodInfo info = mMethodMap.get(mCurMethodId);
@@ -1263,7 +1270,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
WindowManager.LayoutParams.TYPE_INPUT_METHOD);
} catch (RemoteException e) {
}
return new InputBindResult(null, null, mCurId, mCurSeq);
return new InputBindResult(null, null, mCurId, mCurSeq,
mCurUserActionNotificationSequenceNumber);
} else {
mCurIntent = null;
Slog.w(TAG, "Failure connecting to input method service: "
@@ -2310,11 +2318,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
public void notifyUserAction() {
public void notifyUserAction(int sequenceNumber) {
if (DEBUG) {
Slog.d(TAG, "Got the notification of a user action");
Slog.d(TAG, "Got the notification of a user action. sequenceNumber:" + sequenceNumber);
}
synchronized (mMethodMap) {
if (mCurUserActionNotificationSequenceNumber != sequenceNumber) {
if (DEBUG) {
Slog.d(TAG, "Ignoring the user action notification due to the sequence number "
+ "mismatch. expected:" + mCurUserActionNotificationSequenceNumber
+ " actual: " + sequenceNumber);
}
return;
}
final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
if (imi != null) {
mSwitchingController.onUserActionLocked(imi, mCurrentSubtype);
@@ -2588,6 +2604,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ " uid " + ((ClientState)msg.obj).uid);
}
return true;
case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: {
final int sequenceNumber = msg.arg1;
final IInputMethodClient client = (IInputMethodClient)msg.obj;
try {
client.setUserActionNotificationSequenceNumber(sequenceNumber);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending "
+ "setUserActionNotificationSequenceNumber("
+ sequenceNumber + ") notification to pid "
+ ((ClientState)msg.obj).pid + " uid "
+ ((ClientState)msg.obj).uid);
}
return true;
}
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
@@ -2999,6 +3029,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Update the history of InputMethod and Subtype
mSettings.saveCurrentInputMethodAndSubtypeToHistory(mCurMethodId, mCurrentSubtype);
mCurUserActionNotificationSequenceNumber =
Math.max(mCurUserActionNotificationSequenceNumber + 1, 1);
if (DEBUG) {
Slog.d(TAG, "Bump mCurUserActionNotificationSequenceNumber:"
+ mCurUserActionNotificationSequenceNumber);
}
if (mCurClient != null && mCurClient.client != null) {
executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER,
mCurUserActionNotificationSequenceNumber, mCurClient.client));
}
// Set Subtype here
if (imi == null || subtypeId < 0) {
mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
@@ -3490,6 +3533,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
+ " mShowExplicitlyRequested=" + mShowExplicitlyRequested
+ " mShowForced=" + mShowForced
+ " mInputShown=" + mInputShown);
p.println(" mCurUserActionNotificationSequenceNumber="
+ mCurUserActionNotificationSequenceNumber);
p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn);
}

View File

@@ -214,7 +214,7 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
}
@Override
public void notifyUserAction() throws RemoteException {
public void notifyUserAction(int sequenceNumber) throws RemoteException {
// TODO Auto-generated method stub
}