Let IME#onFinishInput called without dup onStartInput when screen-off
Also called IME#onStartInput without dup onFinishInput when screen-on,
to fix the long-standing IME input connection lifecycle issue when
device screen state changes.
Bug: 156215187
Bug: 26851566
Test: atest InputMethodStartInputLifecycleTest
Test: manual as below steps
0) Enable InputMethodService debug flag.
0-1) In Settings -> Develop options -> AppCompatibility Changes,
Select Gboard and then toggle
"FINISH_INPUT_NO_FALLBACK_CONNECTION" change.
1) Launch a app with focused a editor and show soft-input
2) When device screen turned-off, will see InputMethodService only
callbacks below logs:
CALL: doFinishInput
CALL: onFinishInputView
CALL: onFinishInput
3) When device screen turned-on, will see InputMethodService only
callbacks below logs:
CALL: onStartInput
CALL: onStartInputView
Change-Id: I8a657e75e274d842fb46b60375f6aeafeab96a59
This commit is contained in:
@@ -54,6 +54,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
|
||||
private static final int DO_VIEW_CLICKED = 115;
|
||||
private static final int DO_NOTIFY_IME_HIDDEN = 120;
|
||||
private static final int DO_REMOVE_IME_SURFACE = 130;
|
||||
private static final int DO_FINISH_INPUT = 140;
|
||||
|
||||
|
||||
@UnsupportedAppUsage
|
||||
HandlerCaller mCaller;
|
||||
@@ -141,6 +143,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
|
||||
mInputMethodSession.removeImeSurface();
|
||||
return;
|
||||
}
|
||||
case DO_FINISH_INPUT: {
|
||||
mInputMethodSession.finishInput();
|
||||
return;
|
||||
}
|
||||
}
|
||||
Log.w(TAG, "Unhandled message code: " + msg.what);
|
||||
}
|
||||
@@ -222,6 +228,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_SESSION));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishInput() {
|
||||
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_INPUT));
|
||||
}
|
||||
private final class ImeInputEventReceiver extends InputEventReceiver
|
||||
implements InputMethodSession.EventCallback {
|
||||
private final SparseArray<InputEvent> mPendingEvents = new SparseArray<InputEvent>();
|
||||
|
||||
@@ -61,9 +61,12 @@ import android.annotation.IntDef;
|
||||
import android.annotation.MainThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.TestApi;
|
||||
import android.annotation.UiContext;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Dialog;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -411,7 +414,29 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
int mTheme = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Finish the {@link InputConnection} when the device becomes
|
||||
* {@link android.os.PowerManager#isInteractive non-interactive}.
|
||||
*
|
||||
* <p>
|
||||
* If enabled by the current {@link InputMethodService input method}, the current input
|
||||
* connection will be {@link InputMethodService#onFinishInput finished} whenever the devices
|
||||
* becomes non-interactive.
|
||||
*
|
||||
* <p>
|
||||
* If not enabled, the current input connection will instead be silently deactivated when the
|
||||
* devices becomes non-interactive, and an {@link InputMethodService#onFinishInput
|
||||
* onFinishInput()} {@link InputMethodService#onStartInput onStartInput()} pair is dispatched
|
||||
* when the device becomes interactive again.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
|
||||
public static final long FINISH_INPUT_NO_FALLBACK_CONNECTION = 156215187L; // This is a bug id.
|
||||
|
||||
LayoutInflater mInflater;
|
||||
TypedArray mThemeAttrs;
|
||||
@UnsupportedAppUsage
|
||||
@@ -2325,7 +2350,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
}
|
||||
|
||||
void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
|
||||
if (!restarting) {
|
||||
if (!restarting && mInputStarted) {
|
||||
doFinishInput();
|
||||
}
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this);
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.util.Log;
|
||||
import android.view.InputChannel;
|
||||
@@ -38,8 +39,8 @@ import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.inputmethod.IMultiClientInputMethodSession;
|
||||
import com.android.internal.inputmethod.CancellationGroup;
|
||||
import com.android.internal.inputmethod.IMultiClientInputMethodSession;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.util.function.pooled.PooledLambda;
|
||||
import com.android.internal.view.IInputContext;
|
||||
@@ -303,6 +304,12 @@ final class MultiClientInputMethodClientCallbackAdaptor {
|
||||
// no-op for multi-session
|
||||
reportNotSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishInput() throws RemoteException {
|
||||
// no-op for multi-session
|
||||
reportNotSupported();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MultiClientInputMethodSessionImpl
|
||||
|
||||
Reference in New Issue
Block a user