diff options
author | Jeff Brown <jeffbrown@google.com> | 2013-03-26 19:48:23 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-03-26 19:48:23 -0700 |
commit | c5ebd80c43e388977e4ef978f18fa5fc36bd8650 (patch) | |
tree | d9d593a8d719a6aeb6ef562874ae05077d6d13e6 /services/java/com/android/server/InputMethodManagerService.java | |
parent | 96f2fef2460adcf815baa1c2a74e417451fe1237 (diff) | |
parent | 901b77c63bc707c5785a149975e2113a43e38ad6 (diff) |
am 901b77c6: am ca3d655d: Merge "Use input transport for communications between app and IME." into jb-mr2-dev
* commit '901b77c63bc707c5785a149975e2113a43e38ad6':
Use input transport for communications between app and IME.
Diffstat (limited to 'services/java/com/android/server/InputMethodManagerService.java')
-rw-r--r-- | services/java/com/android/server/InputMethodManagerService.java | 127 |
1 files changed, 81 insertions, 46 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index c300c447fa87..658bb5c88c4e 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -88,6 +88,7 @@ import android.util.Printer; import android.util.Slog; import android.util.Xml; import android.view.IWindowManager; +import android.view.InputChannel; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -170,7 +171,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final HardKeyboardListener mHardKeyboardListener; private final WindowManagerService mWindowManagerService; - final InputBindResult mNoBinding = new InputBindResult(null, null, -1); + final InputBindResult mNoBinding = new InputBindResult(null, null, null, -1); // All known input methods. mMethodMap also serves as the global // lock for this class. @@ -202,7 +203,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub class SessionState { final ClientState client; final IInputMethod method; - final IInputMethodSession session; + + IInputMethodSession session; + InputChannel channel; @Override public String toString() { @@ -211,18 +214,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub System.identityHashCode(method)) + " session " + Integer.toHexString( System.identityHashCode(session)) + + " channel " + channel + "}"; } SessionState(ClientState _client, IInputMethod _method, - IInputMethodSession _session) { + IInputMethodSession _session, InputChannel _channel) { client = _client; method = _method; session = _session; + channel = _channel; } } - class ClientState { + static final class ClientState { final IInputMethodClient client; final IInputContext inputContext; final int uid; @@ -555,18 +560,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - private static class MethodCallback extends IInputSessionCallback.Stub { - private final IInputMethod mMethod; + private static final class MethodCallback extends IInputSessionCallback.Stub { private final InputMethodManagerService mParentIMMS; + private final IInputMethod mMethod; + private final InputChannel mChannel; - MethodCallback(final IInputMethod method, final InputMethodManagerService imms) { - mMethod = method; + MethodCallback(InputMethodManagerService imms, IInputMethod method, + InputChannel channel) { mParentIMMS = imms; + mMethod = method; + mChannel = channel; } @Override - public void sessionCreated(IInputMethodSession session) throws RemoteException { - mParentIMMS.onSessionCreated(mMethod, session); + public void sessionCreated(IInputMethodSession session) { + mParentIMMS.onSessionCreated(mMethod, session, mChannel); } } @@ -989,7 +997,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return; } synchronized (mMethodMap) { - mClients.remove(client.asBinder()); + ClientState cs = mClients.remove(client.asBinder()); + if (cs != null) { + clearClientSessionLocked(cs); + } } } @@ -1064,7 +1075,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Attach new input asks to show input"); showCurrentInputLocked(getAppShowFlags(), null); } - return new InputBindResult(session.session, mCurId, mCurSeq); + return new InputBindResult(session.session, session.channel, mCurId, mCurSeq); } InputBindResult startInputLocked(IInputMethodClient client, @@ -1142,16 +1153,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } if (mHaveConnection) { if (mCurMethod != null) { - if (!cs.sessionRequested) { - cs.sessionRequested = true; - if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs); - executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( - MSG_CREATE_SESSION, mCurMethod, - new MethodCallback(mCurMethod, this))); - } // Return to client, and we will get back with it when // we have had a session made for it. - return new InputBindResult(null, mCurId, mCurSeq); + requestClientSessionLocked(cs); + return new InputBindResult(null, null, mCurId, mCurSeq); } else if (SystemClock.uptimeMillis() < (mLastBindTime+TIME_TO_RECONNECT)) { // In this case we have connected to the service, but @@ -1161,7 +1166,7 @@ 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, mCurId, mCurSeq); + return new InputBindResult(null, null, mCurId, mCurSeq); } else { EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); @@ -1180,7 +1185,7 @@ 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, mCurMethodId, mCurSeq); + return new InputBindResult(null, null, mCurMethodId, mCurSeq); } InputMethodInfo info = mMethodMap.get(mCurMethodId); @@ -1208,7 +1213,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub WindowManager.LayoutParams.TYPE_INPUT_METHOD); } catch (RemoteException e) { } - return new InputBindResult(null, mCurId, mCurSeq); + return new InputBindResult(null, null, mCurId, mCurSeq); } else { mCurIntent = null; Slog.w(TAG, "Failure connecting to input method service: " @@ -1251,32 +1256,34 @@ public class InputMethodManagerService extends IInputMethodManager.Stub executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( MSG_ATTACH_TOKEN, mCurMethod, mCurToken)); if (mCurClient != null) { - if (DEBUG) Slog.v(TAG, "Creating first session while with client " - + mCurClient); - executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( - MSG_CREATE_SESSION, mCurMethod, - new MethodCallback(mCurMethod, this))); + clearClientSessionLocked(mCurClient); + requestClientSessionLocked(mCurClient); } } } } - void onSessionCreated(IInputMethod method, IInputMethodSession session) { + void onSessionCreated(IInputMethod method, IInputMethodSession session, + InputChannel channel) { synchronized (mMethodMap) { if (mCurMethod != null && method != null && mCurMethod.asBinder() == method.asBinder()) { if (mCurClient != null) { + clearClientSessionLocked(mCurClient); mCurClient.curSession = new SessionState(mCurClient, - method, session); - mCurClient.sessionRequested = false; + method, session, channel); InputBindResult res = attachNewInputLocked(true); if (res.method != null) { executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO( MSG_BIND_METHOD, mCurClient.client, res)); } + return; } } } + + // Session abandoned. Close its associated input channel. + channel.dispose(); } void unbindCurrentMethodLocked(boolean reportToClient, boolean savePosition) { @@ -1311,14 +1318,38 @@ public class InputMethodManagerService extends IInputMethodManager.Stub MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); } } - - private void finishSession(SessionState sessionState) { - if (sessionState != null && sessionState.session != null) { - try { - sessionState.session.finishSession(); - } catch (RemoteException e) { - Slog.w(TAG, "Session failed to close due to remote exception", e); - setImeWindowVisibilityStatusHiddenLocked(); + + void requestClientSessionLocked(ClientState cs) { + if (!cs.sessionRequested) { + if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs); + InputChannel[] channels = InputChannel.openInputChannelPair(cs.toString()); + cs.sessionRequested = true; + executeOrSendMessage(mCurMethod, mCaller.obtainMessageOOO( + MSG_CREATE_SESSION, mCurMethod, channels[1], + new MethodCallback(this, mCurMethod, channels[0]))); + } + } + + void clearClientSessionLocked(ClientState cs) { + finishSessionLocked(cs.curSession); + cs.curSession = null; + cs.sessionRequested = false; + } + + private void finishSessionLocked(SessionState sessionState) { + if (sessionState != null) { + if (sessionState.session != null) { + try { + sessionState.session.finishSession(); + } catch (RemoteException e) { + Slog.w(TAG, "Session failed to close due to remote exception", e); + setImeWindowVisibilityStatusHiddenLocked(); + } + sessionState.session = null; + } + if (sessionState.channel != null) { + sessionState.channel.dispose(); + sessionState.channel = null; } } } @@ -1326,12 +1357,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub void clearCurMethodLocked() { if (mCurMethod != null) { for (ClientState cs : mClients.values()) { - cs.sessionRequested = false; - finishSession(cs.curSession); - cs.curSession = null; + clearClientSessionLocked(cs); } - finishSession(mEnabledSession); + finishSessionLocked(mEnabledSession); mEnabledSession = null; mCurMethod = null; } @@ -2330,15 +2359,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } args.recycle(); return true; - case MSG_CREATE_SESSION: + case MSG_CREATE_SESSION: { args = (SomeArgs)msg.obj; + InputChannel channel = (InputChannel)args.arg2; try { - ((IInputMethod)args.arg1).createSession( - (IInputSessionCallback)args.arg2); + ((IInputMethod)args.arg1).createSession(channel, + (IInputSessionCallback)args.arg3); } catch (RemoteException e) { + } finally { + if (channel != null) { + channel.dispose(); + } } args.recycle(); return true; + } // --------------------------------------------------------- case MSG_START_INPUT: |