Merge "Introduce a sequence number to avoid redundant IPCs"
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,4 +28,5 @@ oneway interface IInputMethodClient {
|
||||
void onUnbindMethod(int sequence);
|
||||
void setActive(boolean active);
|
||||
void setCursorAnchorMonitorMode(int monitorMode);
|
||||
void setUserActionNotificationSequenceNumber(int sequenceNumber);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user