Loading core/java/android/view/inputmethod/InputMethodManager.java +58 −1 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,25 @@ public final class InputMethodManager { int mCursorCandStart; int mCursorCandStart; int mCursorCandEnd; 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. * The instance that has previously been sent to the input method. */ */ Loading Loading @@ -364,6 +383,7 @@ public final class InputMethodManager { static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8; 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 { class H extends Handler { H(Looper looper) { H(Looper looper) { Loading Loading @@ -503,6 +523,11 @@ public final class InputMethodManager { } } return; return; } } case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { synchronized (mH) { mNextUserActionNotificationSequenceNumber = msg.arg1; } } } } } } } } Loading Loading @@ -572,6 +597,12 @@ public final class InputMethodManager { public void setCursorAnchorMonitorMode(int monitorMode) { public void setCursorAnchorMonitorMode(int monitorMode) { mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0)); 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); final InputConnection mDummyInputConnection = new BaseInputConnection(this, false); Loading Loading @@ -1214,6 +1245,8 @@ public final class InputMethodManager { mBindSequence = res.sequence; mBindSequence = res.sequence; mCurMethod = res.method; mCurMethod = res.method; mCurId = res.id; mCurId = res.id; mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; } else { } else { if (res.channel != null && res.channel != mCurChannel) { if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); res.channel.dispose(); Loading Loading @@ -1918,8 +1951,28 @@ public final class InputMethodManager { */ */ public void notifyUserAction() { public void notifyUserAction() { synchronized (mH) { synchronized (mH) { if (mLastSentUserActionNotificationSequenceNumber == mNextUserActionNotificationSequenceNumber) { if (DEBUG) { Log.w(TAG, "Ignoring notifyUserAction as it has already been sent." + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } return; } try { try { mService.notifyUserAction(); if (DEBUG) { Log.w(TAG, "notifyUserAction: " + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } mService.notifyUserAction(mNextUserActionNotificationSequenceNumber); mLastSentUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); Log.w(TAG, "IME died: " + mCurId, e); } } Loading Loading @@ -2103,6 +2156,10 @@ public final class InputMethodManager { + " mCursorSelEnd=" + mCursorSelEnd + " mCursorSelEnd=" + mCursorSelEnd + " mCursorCandStart=" + mCursorCandStart + " mCursorCandStart=" + mCursorCandStart + " mCursorCandEnd=" + mCursorCandEnd); + " mCursorCandEnd=" + mCursorCandEnd); p.println(" mNextUserActionNotificationSequenceNumber=" + mNextUserActionNotificationSequenceNumber + " mLastSentUserActionNotificationSequenceNumber=" + mLastSentUserActionNotificationSequenceNumber); } } /** /** Loading core/java/com/android/internal/view/IInputMethodClient.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -28,4 +28,5 @@ oneway interface IInputMethodClient { void onUnbindMethod(int sequence); void onUnbindMethod(int sequence); void setActive(boolean active); void setActive(boolean active); void setCursorAnchorMonitorMode(int monitorMode); void setCursorAnchorMonitorMode(int monitorMode); void setUserActionNotificationSequenceNumber(int sequenceNumber); } } core/java/com/android/internal/view/IInputMethodManager.aidl +1 −1 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,6 @@ interface IInputMethodManager { boolean setInputMethodEnabled(String id, boolean enabled); boolean setInputMethodEnabled(String id, boolean enabled); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); int getInputMethodWindowVisibleHeight(); int getInputMethodWindowVisibleHeight(); oneway void notifyUserAction(); oneway void notifyUserAction(int sequenceNumber); void setCursorAnchorMonitorMode(in IBinder token, int monitorMode); void setCursorAnchorMonitorMode(in IBinder token, int monitorMode); } } core/java/com/android/internal/view/InputBindResult.java +13 −3 Original line number Original line Diff line number Diff line Loading @@ -48,12 +48,18 @@ public final class InputBindResult implements Parcelable { */ */ public final int sequence; public final int sequence; /** * Sequence number of user action notification. */ public final int userActionNotificationSequenceNumber; public InputBindResult(IInputMethodSession _method, InputChannel _channel, public InputBindResult(IInputMethodSession _method, InputChannel _channel, String _id, int _sequence) { String _id, int _sequence, int _userActionNotificationSequenceNumber) { method = _method; method = _method; channel = _channel; channel = _channel; id = _id; id = _id; sequence = _sequence; sequence = _sequence; userActionNotificationSequenceNumber = _userActionNotificationSequenceNumber; } } InputBindResult(Parcel source) { InputBindResult(Parcel source) { Loading @@ -65,12 +71,15 @@ public final class InputBindResult implements Parcelable { } } id = source.readString(); id = source.readString(); sequence = source.readInt(); sequence = source.readInt(); userActionNotificationSequenceNumber = source.readInt(); } } @Override @Override public String toString() { public String toString() { return "InputBindResult{" + method + " " + id return "InputBindResult{" + method + " " + id + " #" + sequence + "}"; + " sequence:" + sequence + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber + "}"; } } /** /** Loading @@ -90,6 +99,7 @@ public final class InputBindResult implements Parcelable { } } dest.writeString(id); dest.writeString(id); dest.writeInt(sequence); dest.writeInt(sequence); dest.writeInt(userActionNotificationSequenceNumber); } } /** /** Loading services/core/java/com/android/server/InputMethodManagerService.java +53 −8 Original line number Original line Diff line number Diff line Loading @@ -149,6 +149,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_BIND_METHOD = 3010; static final int MSG_BIND_METHOD = 3010; static final int MSG_SET_ACTIVE = 3020; static final int MSG_SET_ACTIVE = 3020; static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 3030; 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; static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000; Loading @@ -172,7 +173,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final HardKeyboardListener mHardKeyboardListener; private final HardKeyboardListener mHardKeyboardListener; private final WindowManagerService mWindowManagerService; 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 // All known input methods. mMethodMap also serves as the global // lock for this class. // lock for this class. Loading Loading @@ -379,6 +380,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ */ boolean mScreenOn = true; boolean mScreenOn = true; int mCurUserActionNotificationSequenceNumber = 0; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; int mImeWindowVis; int mImeWindowVis; Loading Loading @@ -1129,7 +1132,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub showCurrentInputLocked(getAppShowFlags(), null); showCurrentInputLocked(getAppShowFlags(), null); } } return new InputBindResult(session.session, 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, InputBindResult startInputLocked(IInputMethodClient client, Loading Loading @@ -1205,7 +1209,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Return to client, and we will get back with it when // Return to client, and we will get back with it when // we have had a session made for it. // we have had a session made for it. requestClientSessionLocked(cs); requestClientSessionLocked(cs); return new InputBindResult(null, null, mCurId, mCurSeq); return new InputBindResult(null, null, mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber); } else if (SystemClock.uptimeMillis() } else if (SystemClock.uptimeMillis() < (mLastBindTime+TIME_TO_RECONNECT)) { < (mLastBindTime+TIME_TO_RECONNECT)) { // In this case we have connected to the service, but // In this case we have connected to the service, but Loading @@ -1215,7 +1220,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // we can report back. If it has been too long, we want // we can report back. If it has been too long, we want // to fall through so we can try a disconnect/reconnect // to fall through so we can try a disconnect/reconnect // to see if we can get back in touch with the service. // 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 { } else { EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); Loading @@ -1234,7 +1240,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!mSystemReady) { if (!mSystemReady) { // If the system is not yet ready, we shouldn't be running third // If the system is not yet ready, we shouldn't be running third // party code. // party code. return new InputBindResult(null, null, mCurMethodId, mCurSeq); return new InputBindResult(null, null, mCurMethodId, mCurSeq, mCurUserActionNotificationSequenceNumber); } } InputMethodInfo info = mMethodMap.get(mCurMethodId); InputMethodInfo info = mMethodMap.get(mCurMethodId); Loading Loading @@ -1263,7 +1270,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub WindowManager.LayoutParams.TYPE_INPUT_METHOD); WindowManager.LayoutParams.TYPE_INPUT_METHOD); } catch (RemoteException e) { } catch (RemoteException e) { } } return new InputBindResult(null, null, mCurId, mCurSeq); return new InputBindResult(null, null, mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber); } else { } else { mCurIntent = null; mCurIntent = null; Slog.w(TAG, "Failure connecting to input method service: " Slog.w(TAG, "Failure connecting to input method service: " Loading Loading @@ -2310,11 +2318,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } @Override @Override public void notifyUserAction() { public void notifyUserAction(int sequenceNumber) { if (DEBUG) { 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) { 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); final InputMethodInfo imi = mMethodMap.get(mCurMethodId); if (imi != null) { if (imi != null) { mSwitchingController.onUserActionLocked(imi, mCurrentSubtype); mSwitchingController.onUserActionLocked(imi, mCurrentSubtype); Loading Loading @@ -2588,6 +2604,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " uid " + ((ClientState)msg.obj).uid); + " uid " + ((ClientState)msg.obj).uid); } } return true; 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: case MSG_HARD_KEYBOARD_SWITCH_CHANGED: Loading Loading @@ -2999,6 +3029,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Update the history of InputMethod and Subtype // Update the history of InputMethod and Subtype mSettings.saveCurrentInputMethodAndSubtypeToHistory(mCurMethodId, mCurrentSubtype); 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 // Set Subtype here if (imi == null || subtypeId < 0) { if (imi == null || subtypeId < 0) { mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); Loading Loading @@ -3490,6 +3533,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " mShowExplicitlyRequested=" + mShowExplicitlyRequested + " mShowExplicitlyRequested=" + mShowExplicitlyRequested + " mShowForced=" + mShowForced + " mShowForced=" + mShowForced + " mInputShown=" + mInputShown); + " mInputShown=" + mInputShown); p.println(" mCurUserActionNotificationSequenceNumber=" + mCurUserActionNotificationSequenceNumber); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); } } Loading Loading
core/java/android/view/inputmethod/InputMethodManager.java +58 −1 Original line number Original line Diff line number Diff line Loading @@ -319,6 +319,25 @@ public final class InputMethodManager { int mCursorCandStart; int mCursorCandStart; int mCursorCandEnd; 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. * The instance that has previously been sent to the input method. */ */ Loading Loading @@ -364,6 +383,7 @@ public final class InputMethodManager { static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8; 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 { class H extends Handler { H(Looper looper) { H(Looper looper) { Loading Loading @@ -503,6 +523,11 @@ public final class InputMethodManager { } } return; return; } } case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { synchronized (mH) { mNextUserActionNotificationSequenceNumber = msg.arg1; } } } } } } } } Loading Loading @@ -572,6 +597,12 @@ public final class InputMethodManager { public void setCursorAnchorMonitorMode(int monitorMode) { public void setCursorAnchorMonitorMode(int monitorMode) { mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0)); 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); final InputConnection mDummyInputConnection = new BaseInputConnection(this, false); Loading Loading @@ -1214,6 +1245,8 @@ public final class InputMethodManager { mBindSequence = res.sequence; mBindSequence = res.sequence; mCurMethod = res.method; mCurMethod = res.method; mCurId = res.id; mCurId = res.id; mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; } else { } else { if (res.channel != null && res.channel != mCurChannel) { if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); res.channel.dispose(); Loading Loading @@ -1918,8 +1951,28 @@ public final class InputMethodManager { */ */ public void notifyUserAction() { public void notifyUserAction() { synchronized (mH) { synchronized (mH) { if (mLastSentUserActionNotificationSequenceNumber == mNextUserActionNotificationSequenceNumber) { if (DEBUG) { Log.w(TAG, "Ignoring notifyUserAction as it has already been sent." + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } return; } try { try { mService.notifyUserAction(); if (DEBUG) { Log.w(TAG, "notifyUserAction: " + " mLastSentUserActionNotificationSequenceNumber: " + mLastSentUserActionNotificationSequenceNumber + " mNextUserActionNotificationSequenceNumber: " + mNextUserActionNotificationSequenceNumber); } mService.notifyUserAction(mNextUserActionNotificationSequenceNumber); mLastSentUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); Log.w(TAG, "IME died: " + mCurId, e); } } Loading Loading @@ -2103,6 +2156,10 @@ public final class InputMethodManager { + " mCursorSelEnd=" + mCursorSelEnd + " mCursorSelEnd=" + mCursorSelEnd + " mCursorCandStart=" + mCursorCandStart + " mCursorCandStart=" + mCursorCandStart + " mCursorCandEnd=" + mCursorCandEnd); + " mCursorCandEnd=" + mCursorCandEnd); p.println(" mNextUserActionNotificationSequenceNumber=" + mNextUserActionNotificationSequenceNumber + " mLastSentUserActionNotificationSequenceNumber=" + mLastSentUserActionNotificationSequenceNumber); } } /** /** Loading
core/java/com/android/internal/view/IInputMethodClient.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -28,4 +28,5 @@ oneway interface IInputMethodClient { void onUnbindMethod(int sequence); void onUnbindMethod(int sequence); void setActive(boolean active); void setActive(boolean active); void setCursorAnchorMonitorMode(int monitorMode); void setCursorAnchorMonitorMode(int monitorMode); void setUserActionNotificationSequenceNumber(int sequenceNumber); } }
core/java/com/android/internal/view/IInputMethodManager.aidl +1 −1 Original line number Original line Diff line number Diff line Loading @@ -77,6 +77,6 @@ interface IInputMethodManager { boolean setInputMethodEnabled(String id, boolean enabled); boolean setInputMethodEnabled(String id, boolean enabled); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); int getInputMethodWindowVisibleHeight(); int getInputMethodWindowVisibleHeight(); oneway void notifyUserAction(); oneway void notifyUserAction(int sequenceNumber); void setCursorAnchorMonitorMode(in IBinder token, int monitorMode); void setCursorAnchorMonitorMode(in IBinder token, int monitorMode); } }
core/java/com/android/internal/view/InputBindResult.java +13 −3 Original line number Original line Diff line number Diff line Loading @@ -48,12 +48,18 @@ public final class InputBindResult implements Parcelable { */ */ public final int sequence; public final int sequence; /** * Sequence number of user action notification. */ public final int userActionNotificationSequenceNumber; public InputBindResult(IInputMethodSession _method, InputChannel _channel, public InputBindResult(IInputMethodSession _method, InputChannel _channel, String _id, int _sequence) { String _id, int _sequence, int _userActionNotificationSequenceNumber) { method = _method; method = _method; channel = _channel; channel = _channel; id = _id; id = _id; sequence = _sequence; sequence = _sequence; userActionNotificationSequenceNumber = _userActionNotificationSequenceNumber; } } InputBindResult(Parcel source) { InputBindResult(Parcel source) { Loading @@ -65,12 +71,15 @@ public final class InputBindResult implements Parcelable { } } id = source.readString(); id = source.readString(); sequence = source.readInt(); sequence = source.readInt(); userActionNotificationSequenceNumber = source.readInt(); } } @Override @Override public String toString() { public String toString() { return "InputBindResult{" + method + " " + id return "InputBindResult{" + method + " " + id + " #" + sequence + "}"; + " sequence:" + sequence + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber + "}"; } } /** /** Loading @@ -90,6 +99,7 @@ public final class InputBindResult implements Parcelable { } } dest.writeString(id); dest.writeString(id); dest.writeInt(sequence); dest.writeInt(sequence); dest.writeInt(userActionNotificationSequenceNumber); } } /** /** Loading
services/core/java/com/android/server/InputMethodManagerService.java +53 −8 Original line number Original line Diff line number Diff line Loading @@ -149,6 +149,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub static final int MSG_BIND_METHOD = 3010; static final int MSG_BIND_METHOD = 3010; static final int MSG_SET_ACTIVE = 3020; static final int MSG_SET_ACTIVE = 3020; static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 3030; 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; static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000; Loading @@ -172,7 +173,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final HardKeyboardListener mHardKeyboardListener; private final HardKeyboardListener mHardKeyboardListener; private final WindowManagerService mWindowManagerService; 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 // All known input methods. mMethodMap also serves as the global // lock for this class. // lock for this class. Loading Loading @@ -379,6 +380,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ */ boolean mScreenOn = true; boolean mScreenOn = true; int mCurUserActionNotificationSequenceNumber = 0; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; int mImeWindowVis; int mImeWindowVis; Loading Loading @@ -1129,7 +1132,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub showCurrentInputLocked(getAppShowFlags(), null); showCurrentInputLocked(getAppShowFlags(), null); } } return new InputBindResult(session.session, 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, InputBindResult startInputLocked(IInputMethodClient client, Loading Loading @@ -1205,7 +1209,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Return to client, and we will get back with it when // Return to client, and we will get back with it when // we have had a session made for it. // we have had a session made for it. requestClientSessionLocked(cs); requestClientSessionLocked(cs); return new InputBindResult(null, null, mCurId, mCurSeq); return new InputBindResult(null, null, mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber); } else if (SystemClock.uptimeMillis() } else if (SystemClock.uptimeMillis() < (mLastBindTime+TIME_TO_RECONNECT)) { < (mLastBindTime+TIME_TO_RECONNECT)) { // In this case we have connected to the service, but // In this case we have connected to the service, but Loading @@ -1215,7 +1220,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // we can report back. If it has been too long, we want // we can report back. If it has been too long, we want // to fall through so we can try a disconnect/reconnect // to fall through so we can try a disconnect/reconnect // to see if we can get back in touch with the service. // 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 { } else { EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); Loading @@ -1234,7 +1240,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!mSystemReady) { if (!mSystemReady) { // If the system is not yet ready, we shouldn't be running third // If the system is not yet ready, we shouldn't be running third // party code. // party code. return new InputBindResult(null, null, mCurMethodId, mCurSeq); return new InputBindResult(null, null, mCurMethodId, mCurSeq, mCurUserActionNotificationSequenceNumber); } } InputMethodInfo info = mMethodMap.get(mCurMethodId); InputMethodInfo info = mMethodMap.get(mCurMethodId); Loading Loading @@ -1263,7 +1270,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub WindowManager.LayoutParams.TYPE_INPUT_METHOD); WindowManager.LayoutParams.TYPE_INPUT_METHOD); } catch (RemoteException e) { } catch (RemoteException e) { } } return new InputBindResult(null, null, mCurId, mCurSeq); return new InputBindResult(null, null, mCurId, mCurSeq, mCurUserActionNotificationSequenceNumber); } else { } else { mCurIntent = null; mCurIntent = null; Slog.w(TAG, "Failure connecting to input method service: " Slog.w(TAG, "Failure connecting to input method service: " Loading Loading @@ -2310,11 +2318,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } @Override @Override public void notifyUserAction() { public void notifyUserAction(int sequenceNumber) { if (DEBUG) { 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) { 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); final InputMethodInfo imi = mMethodMap.get(mCurMethodId); if (imi != null) { if (imi != null) { mSwitchingController.onUserActionLocked(imi, mCurrentSubtype); mSwitchingController.onUserActionLocked(imi, mCurrentSubtype); Loading Loading @@ -2588,6 +2604,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " uid " + ((ClientState)msg.obj).uid); + " uid " + ((ClientState)msg.obj).uid); } } return true; 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: case MSG_HARD_KEYBOARD_SWITCH_CHANGED: Loading Loading @@ -2999,6 +3029,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Update the history of InputMethod and Subtype // Update the history of InputMethod and Subtype mSettings.saveCurrentInputMethodAndSubtypeToHistory(mCurMethodId, mCurrentSubtype); 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 // Set Subtype here if (imi == null || subtypeId < 0) { if (imi == null || subtypeId < 0) { mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); Loading Loading @@ -3490,6 +3533,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub + " mShowExplicitlyRequested=" + mShowExplicitlyRequested + " mShowExplicitlyRequested=" + mShowExplicitlyRequested + " mShowForced=" + mShowForced + " mShowForced=" + mShowForced + " mInputShown=" + mInputShown); + " mInputShown=" + mInputShown); p.println(" mCurUserActionNotificationSequenceNumber=" + mCurUserActionNotificationSequenceNumber); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); } } Loading