Merge "Add IC#closeConnection()." into nyc-dev

This commit is contained in:
Yohei Yukawa
2016-03-30 21:55:30 +00:00
committed by Android (Google) Code Review
12 changed files with 84 additions and 25 deletions

View File

@@ -44648,6 +44648,7 @@ package android.view.inputmethod {
ctor public BaseInputConnection(android.view.View, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
@@ -44815,6 +44816,7 @@ package android.view.inputmethod {
public abstract interface InputConnection {
method public abstract boolean beginBatchEdit();
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
@@ -44847,6 +44849,7 @@ package android.view.inputmethod {
ctor public InputConnectionWrapper(android.view.inputmethod.InputConnection, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);

View File

@@ -47379,6 +47379,7 @@ package android.view.inputmethod {
ctor public BaseInputConnection(android.view.View, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
@@ -47546,6 +47547,7 @@ package android.view.inputmethod {
public abstract interface InputConnection {
method public abstract boolean beginBatchEdit();
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
@@ -47578,6 +47580,7 @@ package android.view.inputmethod {
ctor public InputConnectionWrapper(android.view.inputmethod.InputConnection, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);

View File

@@ -44722,6 +44722,7 @@ package android.view.inputmethod {
ctor public BaseInputConnection(android.view.View, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);
@@ -44889,6 +44890,7 @@ package android.view.inputmethod {
public abstract interface InputConnection {
method public abstract boolean beginBatchEdit();
method public abstract boolean clearMetaKeyStates(int);
method public abstract void closeConnection();
method public abstract boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public abstract boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public abstract boolean commitText(java.lang.CharSequence, int);
@@ -44921,6 +44923,7 @@ package android.view.inputmethod {
ctor public InputConnectionWrapper(android.view.inputmethod.InputConnection, boolean);
method public boolean beginBatchEdit();
method public boolean clearMetaKeyStates(int);
method public void closeConnection();
method public boolean commitCompletion(android.view.inputmethod.CompletionInfo);
method public boolean commitCorrection(android.view.inputmethod.CorrectionInfo);
method public boolean commitText(java.lang.CharSequence, int);

View File

@@ -16,6 +16,7 @@
package android.view.inputmethod;
import android.annotation.CallSuper;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
@@ -154,12 +155,11 @@ public class BaseInputConnection implements InputConnection {
}
/**
* Called when this InputConnection is no longer used by the InputMethodManager.
*
* @hide
* Default implementation calls {@link #finishComposingText()}.
*/
public void reportFinish() {
// Intentionally empty
@CallSuper
public void closeConnection() {
finishComposingText();
}
/**

View File

@@ -45,6 +45,8 @@ import android.view.KeyEvent;
* was introduced in {@link android.os.Build.VERSION_CODES#N}.</li>
* <li>{@link #getHandler()}}, which was introduced in
* {@link android.os.Build.VERSION_CODES#N}.</li>
* <li>{@link #closeConnection()}}, which was introduced in
* {@link android.os.Build.VERSION_CODES#N}.</li>
* </ul>
*
* <h3>Implementing an IME or an editor</h3>
@@ -820,4 +822,18 @@ public interface InputConnection {
* @return {@code null} to use the default {@link Handler}.
*/
public Handler getHandler();
/**
* Called by the system up to only once to notify that the system is about to invalidate
* connection between the input method and the application.
*
* <p><strong>Editor authors</strong>: You can clear all the nested batch edit right now and
* you no longer need to handle subsequent callbacks on this connection, including
* {@link #beginBatchEdit()}}. Note that although the system tries to call this method whenever
* possible, there may be a chance that this method is not called in some exceptional
* situations.</p>
*
* <p>Note: This does nothing when called from input methods.</p>
*/
public void closeConnection();
}

View File

@@ -73,6 +73,11 @@ public final class InputConnectionInspector {
* {@link android.os.Build.VERSION_CODES#N} and later.
*/
int GET_HANDLER = 1 << 5;
/**
* {@link InputConnection#closeConnection()}} is available in
* {@link android.os.Build.VERSION_CODES#N} and later.
*/
int CLOSE_CONNECTION = 1 << 6;
}
private static final Map<Class, Integer> sMissingMethodsMap = Collections.synchronizedMap(
@@ -119,6 +124,9 @@ public final class InputConnectionInspector {
if (!hasGetHandler(clazz)) {
flags |= MissingMethodFlags.GET_HANDLER;
}
if (!hasCloseConnection(clazz)) {
flags |= MissingMethodFlags.CLOSE_CONNECTION;
}
sMissingMethodsMap.put(clazz, flags);
return flags;
}
@@ -178,6 +186,15 @@ public final class InputConnectionInspector {
}
}
private static boolean hasCloseConnection(@NonNull final Class clazz) {
try {
final Method method = clazz.getMethod("closeConnection");
return !Modifier.isAbstract(method.getModifiers());
} catch (NoSuchMethodException e) {
return false;
}
}
public static String getMissingMethodFlagsAsString(@MissingMethodFlags final int flags) {
final StringBuilder sb = new StringBuilder();
boolean isEmpty = true;
@@ -219,6 +236,12 @@ public final class InputConnectionInspector {
}
sb.append("getHandler()");
}
if ((flags & MissingMethodFlags.CLOSE_CONNECTION) != 0) {
if (!isEmpty) {
sb.append(",");
}
sb.append("closeConnection()");
}
return sb.toString();
}
}

View File

@@ -261,4 +261,12 @@ public class InputConnectionWrapper implements InputConnection {
public Handler getHandler() {
return mTarget.getHandler();
}
/**
* {@inheritDoc}
* @throws NullPointerException if the target is {@code null}.
*/
public void closeConnection() {
mTarget.closeConnection();
}
}

View File

@@ -544,7 +544,7 @@ public final class InputMethodManager {
// reportFinish() will take effect.
return;
}
reportFinish();
closeConnection();
}
@Override

View File

@@ -5937,6 +5937,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
public Handler getHandler() {
return getTarget().getHandler();
}
@Override
public void closeConnection() {
getTarget().closeConnection();
}
}
/**

View File

@@ -27,13 +27,12 @@ import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.lang.ref.WeakReference;
import android.view.inputmethod.InputConnectionInspector;
import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
public abstract class IInputConnectionWrapper extends IInputContext.Stub {
static final String TAG = "IInputConnectionWrapper";
@@ -61,7 +60,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
private static final int DO_CLEAR_META_KEY_STATES = 130;
private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
private static final int DO_REPORT_FINISH = 150;
private static final int DO_CLOSE_CONNECTION = 150;
@GuardedBy("mLock")
@Nullable
@@ -222,8 +221,8 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
seq, callback));
}
public void reportFinish() {
dispatchMessage(obtainMessage(DO_REPORT_FINISH));
public void closeConnection() {
dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
}
void dispatchMessage(Message msg) {
@@ -501,10 +500,10 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
}
return;
}
case DO_REPORT_FINISH: {
case DO_CLOSE_CONNECTION: {
// Note that we do not need to worry about race condition here, because 1) mFinished
// is updated only inside this block, and 2) the code here is running on a Handler
// hence we assume multiple DO_REPORT_FINISH messages will not be handled at the
// hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
// same time.
if (isFinished()) {
return;
@@ -518,11 +517,10 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
if (ic == null) {
return;
}
ic.finishComposingText();
// TODO: Make reportFinish() public method of InputConnection to remove this
// check.
if (ic instanceof BaseInputConnection) {
((BaseInputConnection) ic).reportFinish();
@MissingMethodFlags
final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
ic.closeConnection();
}
} finally {
synchronized (mLock) {

View File

@@ -487,6 +487,10 @@ public class InputConnectionWrapper implements InputConnection {
return null;
}
public void closeConnection() {
// Nothing should happen when called from input method.
}
private boolean isMethodMissing(@MissingMethodFlags final int methodFlag) {
return (mMissingMethods & methodFlag) == methodFlag;
}

View File

@@ -83,13 +83,9 @@ public class EditableInputConnection extends BaseInputConnection {
return false;
}
/**
* @hide
*/
@Override
public void reportFinish() {
super.reportFinish();
public void closeConnection() {
super.closeConnection();
synchronized(this) {
while (mBatchEditNesting > 0) {
endBatchEdit();