/** Report the current selection range. */ public void updateSelection( View view, int selStart, int selEnd, int candidatesStart, int candidatesEnd) { checkFocus(); synchronized (mH) { if ((mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) || mCurrentTextBoxAttribute == null || mCurMethod == null) { return; } if (mCursorSelStart != selStart || mCursorSelEnd != selEnd || mCursorCandStart != candidatesStart || mCursorCandEnd != candidatesEnd) { if (DEBUG) Log.d(TAG, "updateSelection"); try { if (DEBUG) Log.v(TAG, "SELECTION CHANGE: " + mCurMethod); mCurMethod.updateSelection( mCursorSelStart, mCursorSelEnd, selStart, selEnd, candidatesStart, candidatesEnd); mCursorSelStart = selStart; mCursorSelEnd = selEnd; mCursorCandStart = candidatesStart; mCursorCandEnd = candidatesEnd; } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } } } }
/** * When the focused window is dismissed, this method is called to finish the input method started * before. * * @hide */ public void windowDismissed(IBinder appWindowToken) { checkFocus(); synchronized (mH) { if (mServedView != null && mServedView.getWindowToken() == appWindowToken) { finishInputLocked(); } } }
/** Return true if the given view is the currently active view for the input method. */ public boolean isActive(View view) { checkFocus(); synchronized (mH) { return (mServedView == view || (mServedView != null && mServedView.checkInputConnectionProxy(view))) && mCurrentTextBoxAttribute != null; } }
/** * If the input method is currently connected to the given view, restart it with its new contents. * You should call this when the text within your view changes outside of the normal input method * or key input flow, such as when an application calls TextView.setText(). * * @param view The view whose text has changed. */ public void restartInput(View view) { checkFocus(); synchronized (mH) { if (mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) { return; } mServedConnecting = true; } startInputInner(); }
/** * Request to hide the soft input window from the context of the window that is currently * accepting input. This should be called as a result of the user doing some actually than fairly * explicitly requests to have the input window hidden. * * @param windowToken The token of the window that is making the request, as returned by {@link * View#getWindowToken() View.getWindowToken()}. * @param flags Provides additional operating flags. Currently may be 0 or have the {@link * #HIDE_IMPLICIT_ONLY} bit set. * @param resultReceiver If non-null, this will be called by the IME when it has processed your * request to tell you what it has done. The result code you receive may be either {@link * #RESULT_UNCHANGED_SHOWN}, {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or * {@link #RESULT_HIDDEN}. */ public boolean hideSoftInputFromWindow( IBinder windowToken, int flags, ResultReceiver resultReceiver) { checkFocus(); synchronized (mH) { if (mServedView == null || mServedView.getWindowToken() != windowToken) { return false; } try { return mService.hideSoftInput(mClient, flags, resultReceiver); } catch (RemoteException e) { } return false; } }
/** * Explicitly request that the current input method's soft input area be shown to the user, if * needed. Call this if the user interacts with your view in such a way that they have expressed * they would like to start performing input into it. * * @param view The currently focused view, which would like to receive soft keyboard input. * @param flags Provides additional operating flags. Currently may be 0 or have the {@link * #SHOW_IMPLICIT} bit set. * @param resultReceiver If non-null, this will be called by the IME when it has processed your * request to tell you what it has done. The result code you receive may be either {@link * #RESULT_UNCHANGED_SHOWN}, {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or * {@link #RESULT_HIDDEN}. */ public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) { checkFocus(); synchronized (mH) { if (mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) { return false; } try { return mService.showSoftInput(mClient, flags, resultReceiver); } catch (RemoteException e) { } return false; } }
public void updateExtractedText(View view, int token, ExtractedText text) { checkFocus(); synchronized (mH) { if (mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) { return; } if (mCurMethod != null) { try { mCurMethod.updateExtractedText(token, text); } catch (RemoteException e) { } } } }
public void displayCompletions(View view, CompletionInfo[] completions) { checkFocus(); synchronized (mH) { if (mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) { return; } mCompletions = completions; if (mCurMethod != null) { try { mCurMethod.displayCompletions(mCompletions); } catch (RemoteException e) { } } } }
/** * Call {@link InputMethodSession#appPrivateCommand(String, Bundle) * InputMethodSession.appPrivateCommand()} on the current Input Method. * * @param view Optional View that is sending the command, or null if you want to send the command * regardless of the view that is attached to the input method. * @param action Name of the command to be performed. This <em>must</em> be a scoped name, i.e. * prefixed with a package name you own, so that different developers will not create * conflicting commands. * @param data Any data to include with the command. */ public void sendAppPrivateCommand(View view, String action, Bundle data) { checkFocus(); synchronized (mH) { if ((mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) || mCurrentTextBoxAttribute == null || mCurMethod == null) { return; } try { if (DEBUG) Log.v(TAG, "APP PRIVATE COMMAND " + action + ": " + data); mCurMethod.appPrivateCommand(action, data); } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } } }
/** * Called by ViewRoot when its window gets input focus. * * @hide */ public void onWindowFocus( View rootView, View focusedView, int softInputMode, boolean first, int windowFlags) { synchronized (mH) { if (DEBUG) Log.v( TAG, "onWindowFocus: " + focusedView + " softInputMode=" + softInputMode + " first=" + first + " flags=#" + Integer.toHexString(windowFlags)); if (mHasBeenInactive) { if (DEBUG) Log.v(TAG, "Has been inactive! Starting fresh"); mHasBeenInactive = false; mNextServedNeedsStart = true; } focusInLocked(focusedView != null ? focusedView : rootView); } checkFocus(); synchronized (mH) { try { final boolean isTextEditor = focusedView != null && focusedView.onCheckIsTextEditor(); mService.windowGainedFocus( mClient, rootView.getWindowToken(), focusedView != null, isTextEditor, softInputMode, first, windowFlags); } catch (RemoteException e) { } } }
/** Report the current cursor location in its window. */ public void updateCursor(View view, int left, int top, int right, int bottom) { checkFocus(); synchronized (mH) { if ((mServedView != view && (mServedView == null || !mServedView.checkInputConnectionProxy(view))) || mCurrentTextBoxAttribute == null || mCurMethod == null) { return; } mTmpCursorRect.set(left, top, right, bottom); if (!mCursorRect.equals(mTmpCursorRect)) { if (DEBUG) Log.d(TAG, "updateCursor"); try { if (DEBUG) Log.v(TAG, "CURSOR CHANGE: " + mCurMethod); mCurMethod.updateCursor(mTmpCursorRect); mCursorRect.set(mTmpCursorRect); } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } } } }
/** * Return true if the currently served view is accepting full text edits. If false, it has no * input connection, so can only handle raw key events. */ public boolean isAcceptingText() { checkFocus(); return mServedInputConnection != null; }
/** Return true if any view is currently active in the input method. */ public boolean isActive() { checkFocus(); synchronized (mH) { return mServedView != null && mCurrentTextBoxAttribute != null; } }