Loading core/java/android/view/inputmethod/InputMethodManager.java +31 −49 Original line number Original line Diff line number Diff line Loading @@ -281,10 +281,10 @@ public final class InputMethodManager { boolean mActive = false; boolean mActive = false; /** /** * Set whenever this client becomes inactive, to know we need to reset * {@code true} if next {@link #onPostWindowFocus(View, View, int, boolean, int)} needs to * state with the IME the next time we receive focus. * restart input. */ */ boolean mHasBeenInactive = true; boolean mRestartOnNextWindowFocus = true; /** /** * As reported by IME through InputConnection. * As reported by IME through InputConnection. Loading Loading @@ -489,7 +489,7 @@ public final class InputMethodManager { // Some other client has starting using the IME, so note // Some other client has starting using the IME, so note // that this happened and make sure our own editor's // that this happened and make sure our own editor's // state is reset. // state is reset. mHasBeenInactive = true; mRestartOnNextWindowFocus = true; try { try { // Note that finishComposingText() is allowed to run // Note that finishComposingText() is allowed to run // even when we are not active. // even when we are not active. Loading @@ -500,7 +500,7 @@ public final class InputMethodManager { // Check focus again in case that "onWindowFocus" is called before // Check focus again in case that "onWindowFocus" is called before // handling this message. // handling this message. if (mServedView != null && mServedView.hasWindowFocus()) { if (mServedView != null && mServedView.hasWindowFocus()) { if (checkFocusNoStartInput(mHasBeenInactive)) { if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) { final int reason = active ? final int reason = active ? InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS : InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS : InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS; InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS; Loading Loading @@ -1336,7 +1336,14 @@ public final class InputMethodManager { windowFlags, tba, servedContext, missingMethodFlags, windowFlags, tba, servedContext, missingMethodFlags, view.getContext().getApplicationInfo().targetSdkVersion); view.getContext().getApplicationInfo().targetSdkVersion); if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (res != null) { if (res == null) { Log.wtf(TAG, "startInputOrWindowGainedFocus must not return" + " null. startInputReason=" + InputMethodClient.getStartInputReason(startInputReason) + " editorInfo=" + tba + " controlFlags=#" + Integer.toHexString(controlFlags)); return false; } if (res.id != null) { if (res.id != null) { setInputChannelLocked(res.channel); setInputChannelLocked(res.channel); mBindSequence = res.sequence; mBindSequence = res.sequence; Loading @@ -1344,38 +1351,13 @@ public final class InputMethodManager { mCurId = res.id; mCurId = res.id; mNextUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; res.userActionNotificationSequenceNumber; } else { } else if (res.channel != null && res.channel != mCurChannel) { if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); res.channel.dispose(); } } if (mCurMethod == null) { switch (res.result) { // This means there is no input method available. case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW: if (DEBUG) Log.v(TAG, "ABORT input: no input method!"); mRestartOnNextWindowFocus = true; return true; break; } } } else { if (startInputReason == InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN) { // We are here probably because of an obsolete window-focus-in message sent // to windowGainingFocus. Since IMMS determines whether a Window can have // IME focus or not by using the latest window focus state maintained in the // WMS, this kind of race condition cannot be avoided. One obvious example // would be that we have already received a window-focus-out message but the // UI thread is still handling previous window-focus-in message here. // TODO: InputBindResult should have the error code. if (DEBUG) Log.w(TAG, "startInputOrWindowGainedFocus failed. " + "Window focus may have already been lost. " + "win=" + windowGainingFocus + " view=" + dumpViewInfo(view)); if (!mActive) { // mHasBeenInactive is a latch switch to forcefully refresh IME focus // state when an inactive (mActive == false) client is gaining window // focus. In case we have unnecessary disable the latch due to this // spurious wakeup, we re-enable the latch here. // TODO: Come up with more robust solution. mHasBeenInactive = true; } } } } if (mCurMethod != null && mCompletions != null) { if (mCurMethod != null && mCompletions != null) { try { try { Loading Loading @@ -1551,9 +1533,9 @@ public final class InputMethodManager { + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " first=" + first + " flags=#" + " first=" + first + " flags=#" + Integer.toHexString(windowFlags)); + Integer.toHexString(windowFlags)); if (mHasBeenInactive) { if (mRestartOnNextWindowFocus) { if (DEBUG) Log.v(TAG, "Has been inactive! Starting fresh"); if (DEBUG) Log.v(TAG, "Restarting due to mRestartOnNextWindowFocus"); mHasBeenInactive = false; mRestartOnNextWindowFocus = false; forceNewFocus = true; forceNewFocus = true; } } focusInLocked(focusedView != null ? focusedView : rootView); focusInLocked(focusedView != null ? focusedView : rootView); Loading Loading @@ -2485,7 +2467,7 @@ public final class InputMethodManager { p.println(" mMainLooper=" + mMainLooper); p.println(" mMainLooper=" + mMainLooper); p.println(" mIInputContext=" + mIInputContext); p.println(" mIInputContext=" + mIInputContext); p.println(" mActive=" + mActive p.println(" mActive=" + mActive + " mHasBeenInactive=" + mHasBeenInactive + " mRestartOnNextWindowFocus=" + mRestartOnNextWindowFocus + " mBindSequence=" + mBindSequence + " mBindSequence=" + mBindSequence + " mCurId=" + mCurId); + " mCurId=" + mCurId); p.println(" mFullscreenMode=" + mFullscreenMode); p.println(" mFullscreenMode=" + mFullscreenMode); Loading core/java/com/android/internal/view/IInputMethodManager.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,7 @@ interface IInputMethodManager { in ResultReceiver resultReceiver); in ResultReceiver resultReceiver); // If windowToken is null, this just does startInput(). Otherwise this reports that a window // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'attribute' is non-null then also does startInput. // has gained focus, and if 'attribute' is non-null then also does startInput. // @NonNull InputBindResult startInputOrWindowGainedFocus( InputBindResult startInputOrWindowGainedFocus( /* @InputMethodClient.StartInputReason */ int startInputReason, /* @InputMethodClient.StartInputReason */ int startInputReason, in IInputMethodClient client, in IBinder windowToken, int controlFlags, in IInputMethodClient client, in IBinder windowToken, int controlFlags, Loading core/java/com/android/internal/view/InputBindResult.java +196 −7 Original line number Original line Diff line number Diff line Loading @@ -16,16 +16,133 @@ package com.android.internal.view; package com.android.internal.view; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.view.InputChannel; import android.view.InputChannel; import java.lang.annotation.Retention; /** /** * Bundle of information returned by input method manager about a successful * Bundle of information returned by input method manager about a successful * binding to an input method. * binding to an input method. */ */ public final class InputBindResult implements Parcelable { public final class InputBindResult implements Parcelable { static final String TAG = "InputBindResult"; @Retention(SOURCE) @IntDef({ ResultCode.SUCCESS_WITH_IME_SESSION, ResultCode.SUCCESS_WAITING_IME_SESSION, ResultCode.SUCCESS_WAITING_IME_BINDING, ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, ResultCode.ERROR_NULL, ResultCode.ERROR_NO_IME, ResultCode.ERROR_INVALID_PACKAGE_NAME, ResultCode.ERROR_SYSTEM_NOT_READY, ResultCode.ERROR_IME_NOT_CONNECTED, ResultCode.ERROR_INVALID_USER, ResultCode.ERROR_NULL_EDITOR_INFO, ResultCode.ERROR_NOT_IME_TARGET_WINDOW, }) public @interface ResultCode { /** * Indicates that everything in this result object including {@link #method} is valid. */ int SUCCESS_WITH_IME_SESSION = 0; /** * Indicates that this is a temporary binding until the * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session * to {@link com.android.server.InputMethodManagerService} (IMMS). * * <p>Note that in this state the IMS is already bound to IMMS but the logical session * is not yet established on top of the IPC channel.</p> * * <p>Some of fields such as {@link #channel} is not yet available.</p> * * @see android.inputmethodservice.InputMethodService##onCreateInputMethodSessionInterface() **/ int SUCCESS_WAITING_IME_SESSION = 1; /** * Indicates that this is a temporary binding until the * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session * to {@link com.android.server.InputMethodManagerService} (IMMS). * * <p>Note that in this state the IMMS has already initiated a connection to the IMS but * the binding process is not completed yet.</p> * * <p>Some of fields such as {@link #channel} is not yet available.</p> * @see android.content.ServiceConnection#onServiceConnected(ComponentName, IBinder) */ int SUCCESS_WAITING_IME_BINDING = 2; /** * Indicates that this is not intended for starting input but just for reporting window * focus change from the application process. * * <p>All other fields do not have meaningful value.</p> */ int SUCCESS_REPORT_WINDOW_FOCUS_ONLY = 3; /** * Indicates somehow * {@link com.android.server.InputMethodManagerService#startInputOrWindowGainedFocus} is * trying to return null {@link InputBindResult}, which must never happen. */ int ERROR_NULL = 4; /** * Indicates that {@link com.android.server.InputMethodManagerService} recognizes no IME. */ int ERROR_NO_IME = 5; /** * Indicates that {@link android.view.inputmethod.EditorInfo#packageName} does not match * the caller UID. * * @see android.view.inputmethod.EditorInfo#packageName */ int ERROR_INVALID_PACKAGE_NAME = 6; /** * Indicates that the system is still in an early stage of the boot process and any 3rd * party application is not allowed to run. * * @see com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START */ int ERROR_SYSTEM_NOT_READY = 7; /** * Indicates that {@link com.android.server.InputMethodManagerService} tried to connect to * an {@link android.inputmethodservice.InputMethodService} but failed. * * @see android.content.Context#bindServiceAsUser(Intent, ServiceConnection, int, UserHandle) */ int ERROR_IME_NOT_CONNECTED = 8; /** * Indicates that the caller is not the foreground user (or does not have * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission). */ int ERROR_INVALID_USER = 9; /** * Indicates that the caller should have specified non-null * {@link android.view.inputmethod.EditorInfo}. */ int ERROR_NULL_EDITOR_INFO = 10; /** * Indicates that the target window the client specified cannot be the IME target right now. * * <p>Due to the asynchronous nature of Android OS, we cannot completely avoid this error. * The client should try to restart input when its {@link android.view.Window} is focused * again.</p> * * @see com.android.server.wm.WindowManagerService#inputMethodClientHasFocus(IInputMethodClient) */ int ERROR_NOT_IME_TARGET_WINDOW = 11; } @ResultCode public final int result; /** /** * The input method service. * The input method service. Loading Loading @@ -53,8 +170,10 @@ public final class InputBindResult implements Parcelable { */ */ public final int userActionNotificationSequenceNumber; public final int userActionNotificationSequenceNumber; public InputBindResult(IInputMethodSession _method, InputChannel _channel, public InputBindResult(@ResultCode int _result, IInputMethodSession _method, InputChannel _channel, String _id, int _sequence, int _userActionNotificationSequenceNumber) { String _id, int _sequence, int _userActionNotificationSequenceNumber) { result = _result; method = _method; method = _method; channel = _channel; channel = _channel; id = _id; id = _id; Loading @@ -63,6 +182,7 @@ public final class InputBindResult implements Parcelable { } } InputBindResult(Parcel source) { InputBindResult(Parcel source) { result = source.readInt(); method = IInputMethodSession.Stub.asInterface(source.readStrongBinder()); method = IInputMethodSession.Stub.asInterface(source.readStrongBinder()); if (source.readInt() != 0) { if (source.readInt() != 0) { channel = InputChannel.CREATOR.createFromParcel(source); channel = InputChannel.CREATOR.createFromParcel(source); Loading @@ -76,9 +196,9 @@ public final class InputBindResult implements Parcelable { @Override @Override public String toString() { public String toString() { return "InputBindResult{" + method + " " + id return "InputBindResult{result=" + getResultString() + " method="+ method + " id=" + id + " sequence:" + sequence + " sequence=" + sequence + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber + " userActionNotificationSequenceNumber=" + userActionNotificationSequenceNumber + "}"; + "}"; } } Loading @@ -90,6 +210,7 @@ public final class InputBindResult implements Parcelable { */ */ @Override @Override public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(result); dest.writeStrongInterface(method); dest.writeStrongInterface(method); if (channel != null) { if (channel != null) { dest.writeInt(1); dest.writeInt(1); Loading Loading @@ -122,4 +243,72 @@ public final class InputBindResult implements Parcelable { public int describeContents() { public int describeContents() { return channel != null ? channel.describeContents() : 0; return channel != null ? channel.describeContents() : 0; } } public String getResultString() { switch (result) { case ResultCode.SUCCESS_WITH_IME_SESSION: return "SUCCESS_WITH_IME_SESSION"; case ResultCode.SUCCESS_WAITING_IME_SESSION: return "SUCCESS_WAITING_IME_SESSION"; case ResultCode.SUCCESS_WAITING_IME_BINDING: return "SUCCESS_WAITING_IME_BINDING"; case ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY: return "SUCCESS_REPORT_WINDOW_FOCUS_ONLY"; case ResultCode.ERROR_NULL: return "ERROR_NULL"; case ResultCode.ERROR_NO_IME: return "ERROR_NO_IME"; case ResultCode.ERROR_INVALID_PACKAGE_NAME: return "ERROR_INVALID_PACKAGE_NAME"; case ResultCode.ERROR_SYSTEM_NOT_READY: return "ERROR_SYSTEM_NOT_READY"; case ResultCode.ERROR_IME_NOT_CONNECTED: return "ERROR_IME_NOT_CONNECTED"; case ResultCode.ERROR_INVALID_USER: return "ERROR_INVALID_USER"; case ResultCode.ERROR_NULL_EDITOR_INFO: return "ERROR_NULL_EDITOR_INFO"; case ResultCode.ERROR_NOT_IME_TARGET_WINDOW: return "ERROR_NOT_IME_TARGET_WINDOW"; default: return "Unknown(" + result + ")"; } } private static InputBindResult error(@ResultCode int result) { return new InputBindResult(result, null, null, null, -1, -1); } /** * Predefined error object for {@link ResultCode#ERROR_NULL}. */ public static final InputBindResult NULL = error(ResultCode.ERROR_NULL); /** * Predefined error object for {@link ResultCode#NO_IME}. */ public static final InputBindResult NO_IME = error(ResultCode.ERROR_NO_IME); /** * Predefined error object for {@link ResultCode#ERROR_INVALID_PACKAGE_NAME}. */ public static final InputBindResult INVALID_PACKAGE_NAME = error(ResultCode.ERROR_INVALID_PACKAGE_NAME); /** * Predefined error object for {@link ResultCode#ERROR_NULL_EDITOR_INFO}. */ public static final InputBindResult NULL_EDITOR_INFO = error(ResultCode.ERROR_NULL_EDITOR_INFO); /** * Predefined error object for {@link ResultCode#ERROR_NOT_IME_TARGET_WINDOW}. */ public static final InputBindResult NOT_IME_TARGET_WINDOW = error(ResultCode.ERROR_NOT_IME_TARGET_WINDOW); /** * Predefined error object for {@link ResultCode#ERROR_IME_NOT_CONNECTED}. */ public static final InputBindResult IME_NOT_CONNECTED = error(ResultCode.ERROR_IME_NOT_CONNECTED); /** * Predefined error object for {@link ResultCode#ERROR_INVALID_USER}. */ public static final InputBindResult INVALID_USER = error(ResultCode.ERROR_INVALID_USER); } } services/core/java/com/android/server/InputMethodManagerService.java +47 −26 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/view/inputmethod/InputMethodManager.java +31 −49 Original line number Original line Diff line number Diff line Loading @@ -281,10 +281,10 @@ public final class InputMethodManager { boolean mActive = false; boolean mActive = false; /** /** * Set whenever this client becomes inactive, to know we need to reset * {@code true} if next {@link #onPostWindowFocus(View, View, int, boolean, int)} needs to * state with the IME the next time we receive focus. * restart input. */ */ boolean mHasBeenInactive = true; boolean mRestartOnNextWindowFocus = true; /** /** * As reported by IME through InputConnection. * As reported by IME through InputConnection. Loading Loading @@ -489,7 +489,7 @@ public final class InputMethodManager { // Some other client has starting using the IME, so note // Some other client has starting using the IME, so note // that this happened and make sure our own editor's // that this happened and make sure our own editor's // state is reset. // state is reset. mHasBeenInactive = true; mRestartOnNextWindowFocus = true; try { try { // Note that finishComposingText() is allowed to run // Note that finishComposingText() is allowed to run // even when we are not active. // even when we are not active. Loading @@ -500,7 +500,7 @@ public final class InputMethodManager { // Check focus again in case that "onWindowFocus" is called before // Check focus again in case that "onWindowFocus" is called before // handling this message. // handling this message. if (mServedView != null && mServedView.hasWindowFocus()) { if (mServedView != null && mServedView.hasWindowFocus()) { if (checkFocusNoStartInput(mHasBeenInactive)) { if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) { final int reason = active ? final int reason = active ? InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS : InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS : InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS; InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS; Loading Loading @@ -1336,7 +1336,14 @@ public final class InputMethodManager { windowFlags, tba, servedContext, missingMethodFlags, windowFlags, tba, servedContext, missingMethodFlags, view.getContext().getApplicationInfo().targetSdkVersion); view.getContext().getApplicationInfo().targetSdkVersion); if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); if (res != null) { if (res == null) { Log.wtf(TAG, "startInputOrWindowGainedFocus must not return" + " null. startInputReason=" + InputMethodClient.getStartInputReason(startInputReason) + " editorInfo=" + tba + " controlFlags=#" + Integer.toHexString(controlFlags)); return false; } if (res.id != null) { if (res.id != null) { setInputChannelLocked(res.channel); setInputChannelLocked(res.channel); mBindSequence = res.sequence; mBindSequence = res.sequence; Loading @@ -1344,38 +1351,13 @@ public final class InputMethodManager { mCurId = res.id; mCurId = res.id; mNextUserActionNotificationSequenceNumber = mNextUserActionNotificationSequenceNumber = res.userActionNotificationSequenceNumber; res.userActionNotificationSequenceNumber; } else { } else if (res.channel != null && res.channel != mCurChannel) { if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); res.channel.dispose(); } } if (mCurMethod == null) { switch (res.result) { // This means there is no input method available. case InputBindResult.ResultCode.ERROR_NOT_IME_TARGET_WINDOW: if (DEBUG) Log.v(TAG, "ABORT input: no input method!"); mRestartOnNextWindowFocus = true; return true; break; } } } else { if (startInputReason == InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN) { // We are here probably because of an obsolete window-focus-in message sent // to windowGainingFocus. Since IMMS determines whether a Window can have // IME focus or not by using the latest window focus state maintained in the // WMS, this kind of race condition cannot be avoided. One obvious example // would be that we have already received a window-focus-out message but the // UI thread is still handling previous window-focus-in message here. // TODO: InputBindResult should have the error code. if (DEBUG) Log.w(TAG, "startInputOrWindowGainedFocus failed. " + "Window focus may have already been lost. " + "win=" + windowGainingFocus + " view=" + dumpViewInfo(view)); if (!mActive) { // mHasBeenInactive is a latch switch to forcefully refresh IME focus // state when an inactive (mActive == false) client is gaining window // focus. In case we have unnecessary disable the latch due to this // spurious wakeup, we re-enable the latch here. // TODO: Come up with more robust solution. mHasBeenInactive = true; } } } } if (mCurMethod != null && mCompletions != null) { if (mCurMethod != null && mCompletions != null) { try { try { Loading Loading @@ -1551,9 +1533,9 @@ public final class InputMethodManager { + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode) + " first=" + first + " flags=#" + " first=" + first + " flags=#" + Integer.toHexString(windowFlags)); + Integer.toHexString(windowFlags)); if (mHasBeenInactive) { if (mRestartOnNextWindowFocus) { if (DEBUG) Log.v(TAG, "Has been inactive! Starting fresh"); if (DEBUG) Log.v(TAG, "Restarting due to mRestartOnNextWindowFocus"); mHasBeenInactive = false; mRestartOnNextWindowFocus = false; forceNewFocus = true; forceNewFocus = true; } } focusInLocked(focusedView != null ? focusedView : rootView); focusInLocked(focusedView != null ? focusedView : rootView); Loading Loading @@ -2485,7 +2467,7 @@ public final class InputMethodManager { p.println(" mMainLooper=" + mMainLooper); p.println(" mMainLooper=" + mMainLooper); p.println(" mIInputContext=" + mIInputContext); p.println(" mIInputContext=" + mIInputContext); p.println(" mActive=" + mActive p.println(" mActive=" + mActive + " mHasBeenInactive=" + mHasBeenInactive + " mRestartOnNextWindowFocus=" + mRestartOnNextWindowFocus + " mBindSequence=" + mBindSequence + " mBindSequence=" + mBindSequence + " mCurId=" + mCurId); + " mCurId=" + mCurId); p.println(" mFullscreenMode=" + mFullscreenMode); p.println(" mFullscreenMode=" + mFullscreenMode); Loading
core/java/com/android/internal/view/IInputMethodManager.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -56,6 +56,7 @@ interface IInputMethodManager { in ResultReceiver resultReceiver); in ResultReceiver resultReceiver); // If windowToken is null, this just does startInput(). Otherwise this reports that a window // If windowToken is null, this just does startInput(). Otherwise this reports that a window // has gained focus, and if 'attribute' is non-null then also does startInput. // has gained focus, and if 'attribute' is non-null then also does startInput. // @NonNull InputBindResult startInputOrWindowGainedFocus( InputBindResult startInputOrWindowGainedFocus( /* @InputMethodClient.StartInputReason */ int startInputReason, /* @InputMethodClient.StartInputReason */ int startInputReason, in IInputMethodClient client, in IBinder windowToken, int controlFlags, in IInputMethodClient client, in IBinder windowToken, int controlFlags, Loading
core/java/com/android/internal/view/InputBindResult.java +196 −7 Original line number Original line Diff line number Diff line Loading @@ -16,16 +16,133 @@ package com.android.internal.view; package com.android.internal.view; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.view.InputChannel; import android.view.InputChannel; import java.lang.annotation.Retention; /** /** * Bundle of information returned by input method manager about a successful * Bundle of information returned by input method manager about a successful * binding to an input method. * binding to an input method. */ */ public final class InputBindResult implements Parcelable { public final class InputBindResult implements Parcelable { static final String TAG = "InputBindResult"; @Retention(SOURCE) @IntDef({ ResultCode.SUCCESS_WITH_IME_SESSION, ResultCode.SUCCESS_WAITING_IME_SESSION, ResultCode.SUCCESS_WAITING_IME_BINDING, ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY, ResultCode.ERROR_NULL, ResultCode.ERROR_NO_IME, ResultCode.ERROR_INVALID_PACKAGE_NAME, ResultCode.ERROR_SYSTEM_NOT_READY, ResultCode.ERROR_IME_NOT_CONNECTED, ResultCode.ERROR_INVALID_USER, ResultCode.ERROR_NULL_EDITOR_INFO, ResultCode.ERROR_NOT_IME_TARGET_WINDOW, }) public @interface ResultCode { /** * Indicates that everything in this result object including {@link #method} is valid. */ int SUCCESS_WITH_IME_SESSION = 0; /** * Indicates that this is a temporary binding until the * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session * to {@link com.android.server.InputMethodManagerService} (IMMS). * * <p>Note that in this state the IMS is already bound to IMMS but the logical session * is not yet established on top of the IPC channel.</p> * * <p>Some of fields such as {@link #channel} is not yet available.</p> * * @see android.inputmethodservice.InputMethodService##onCreateInputMethodSessionInterface() **/ int SUCCESS_WAITING_IME_SESSION = 1; /** * Indicates that this is a temporary binding until the * {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session * to {@link com.android.server.InputMethodManagerService} (IMMS). * * <p>Note that in this state the IMMS has already initiated a connection to the IMS but * the binding process is not completed yet.</p> * * <p>Some of fields such as {@link #channel} is not yet available.</p> * @see android.content.ServiceConnection#onServiceConnected(ComponentName, IBinder) */ int SUCCESS_WAITING_IME_BINDING = 2; /** * Indicates that this is not intended for starting input but just for reporting window * focus change from the application process. * * <p>All other fields do not have meaningful value.</p> */ int SUCCESS_REPORT_WINDOW_FOCUS_ONLY = 3; /** * Indicates somehow * {@link com.android.server.InputMethodManagerService#startInputOrWindowGainedFocus} is * trying to return null {@link InputBindResult}, which must never happen. */ int ERROR_NULL = 4; /** * Indicates that {@link com.android.server.InputMethodManagerService} recognizes no IME. */ int ERROR_NO_IME = 5; /** * Indicates that {@link android.view.inputmethod.EditorInfo#packageName} does not match * the caller UID. * * @see android.view.inputmethod.EditorInfo#packageName */ int ERROR_INVALID_PACKAGE_NAME = 6; /** * Indicates that the system is still in an early stage of the boot process and any 3rd * party application is not allowed to run. * * @see com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START */ int ERROR_SYSTEM_NOT_READY = 7; /** * Indicates that {@link com.android.server.InputMethodManagerService} tried to connect to * an {@link android.inputmethodservice.InputMethodService} but failed. * * @see android.content.Context#bindServiceAsUser(Intent, ServiceConnection, int, UserHandle) */ int ERROR_IME_NOT_CONNECTED = 8; /** * Indicates that the caller is not the foreground user (or does not have * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission). */ int ERROR_INVALID_USER = 9; /** * Indicates that the caller should have specified non-null * {@link android.view.inputmethod.EditorInfo}. */ int ERROR_NULL_EDITOR_INFO = 10; /** * Indicates that the target window the client specified cannot be the IME target right now. * * <p>Due to the asynchronous nature of Android OS, we cannot completely avoid this error. * The client should try to restart input when its {@link android.view.Window} is focused * again.</p> * * @see com.android.server.wm.WindowManagerService#inputMethodClientHasFocus(IInputMethodClient) */ int ERROR_NOT_IME_TARGET_WINDOW = 11; } @ResultCode public final int result; /** /** * The input method service. * The input method service. Loading Loading @@ -53,8 +170,10 @@ public final class InputBindResult implements Parcelable { */ */ public final int userActionNotificationSequenceNumber; public final int userActionNotificationSequenceNumber; public InputBindResult(IInputMethodSession _method, InputChannel _channel, public InputBindResult(@ResultCode int _result, IInputMethodSession _method, InputChannel _channel, String _id, int _sequence, int _userActionNotificationSequenceNumber) { String _id, int _sequence, int _userActionNotificationSequenceNumber) { result = _result; method = _method; method = _method; channel = _channel; channel = _channel; id = _id; id = _id; Loading @@ -63,6 +182,7 @@ public final class InputBindResult implements Parcelable { } } InputBindResult(Parcel source) { InputBindResult(Parcel source) { result = source.readInt(); method = IInputMethodSession.Stub.asInterface(source.readStrongBinder()); method = IInputMethodSession.Stub.asInterface(source.readStrongBinder()); if (source.readInt() != 0) { if (source.readInt() != 0) { channel = InputChannel.CREATOR.createFromParcel(source); channel = InputChannel.CREATOR.createFromParcel(source); Loading @@ -76,9 +196,9 @@ public final class InputBindResult implements Parcelable { @Override @Override public String toString() { public String toString() { return "InputBindResult{" + method + " " + id return "InputBindResult{result=" + getResultString() + " method="+ method + " id=" + id + " sequence:" + sequence + " sequence=" + sequence + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber + " userActionNotificationSequenceNumber=" + userActionNotificationSequenceNumber + "}"; + "}"; } } Loading @@ -90,6 +210,7 @@ public final class InputBindResult implements Parcelable { */ */ @Override @Override public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(result); dest.writeStrongInterface(method); dest.writeStrongInterface(method); if (channel != null) { if (channel != null) { dest.writeInt(1); dest.writeInt(1); Loading Loading @@ -122,4 +243,72 @@ public final class InputBindResult implements Parcelable { public int describeContents() { public int describeContents() { return channel != null ? channel.describeContents() : 0; return channel != null ? channel.describeContents() : 0; } } public String getResultString() { switch (result) { case ResultCode.SUCCESS_WITH_IME_SESSION: return "SUCCESS_WITH_IME_SESSION"; case ResultCode.SUCCESS_WAITING_IME_SESSION: return "SUCCESS_WAITING_IME_SESSION"; case ResultCode.SUCCESS_WAITING_IME_BINDING: return "SUCCESS_WAITING_IME_BINDING"; case ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY: return "SUCCESS_REPORT_WINDOW_FOCUS_ONLY"; case ResultCode.ERROR_NULL: return "ERROR_NULL"; case ResultCode.ERROR_NO_IME: return "ERROR_NO_IME"; case ResultCode.ERROR_INVALID_PACKAGE_NAME: return "ERROR_INVALID_PACKAGE_NAME"; case ResultCode.ERROR_SYSTEM_NOT_READY: return "ERROR_SYSTEM_NOT_READY"; case ResultCode.ERROR_IME_NOT_CONNECTED: return "ERROR_IME_NOT_CONNECTED"; case ResultCode.ERROR_INVALID_USER: return "ERROR_INVALID_USER"; case ResultCode.ERROR_NULL_EDITOR_INFO: return "ERROR_NULL_EDITOR_INFO"; case ResultCode.ERROR_NOT_IME_TARGET_WINDOW: return "ERROR_NOT_IME_TARGET_WINDOW"; default: return "Unknown(" + result + ")"; } } private static InputBindResult error(@ResultCode int result) { return new InputBindResult(result, null, null, null, -1, -1); } /** * Predefined error object for {@link ResultCode#ERROR_NULL}. */ public static final InputBindResult NULL = error(ResultCode.ERROR_NULL); /** * Predefined error object for {@link ResultCode#NO_IME}. */ public static final InputBindResult NO_IME = error(ResultCode.ERROR_NO_IME); /** * Predefined error object for {@link ResultCode#ERROR_INVALID_PACKAGE_NAME}. */ public static final InputBindResult INVALID_PACKAGE_NAME = error(ResultCode.ERROR_INVALID_PACKAGE_NAME); /** * Predefined error object for {@link ResultCode#ERROR_NULL_EDITOR_INFO}. */ public static final InputBindResult NULL_EDITOR_INFO = error(ResultCode.ERROR_NULL_EDITOR_INFO); /** * Predefined error object for {@link ResultCode#ERROR_NOT_IME_TARGET_WINDOW}. */ public static final InputBindResult NOT_IME_TARGET_WINDOW = error(ResultCode.ERROR_NOT_IME_TARGET_WINDOW); /** * Predefined error object for {@link ResultCode#ERROR_IME_NOT_CONNECTED}. */ public static final InputBindResult IME_NOT_CONNECTED = error(ResultCode.ERROR_IME_NOT_CONNECTED); /** * Predefined error object for {@link ResultCode#ERROR_INVALID_USER}. */ public static final InputBindResult INVALID_USER = error(ResultCode.ERROR_INVALID_USER); } }
services/core/java/com/android/server/InputMethodManagerService.java +47 −26 File changed.Preview size limit exceeded, changes collapsed. Show changes