未验证 提交 f9e53c72 编写于 作者: J Jason Simmons 提交者: GitHub

Unregister the TextInputChannel method handler when the TextInputPlugin is destroyed (#17646)

Fixes https://github.com/flutter/flutter/issues/54275
上级 88e454bf
......@@ -710,7 +710,7 @@ public class FlutterView extends FrameLayout {
textInputPlugin =
new TextInputPlugin(
this,
this.flutterEngine.getDartExecutor(),
this.flutterEngine.getTextInputChannel(),
this.flutterEngine.getPlatformViewsController());
androidKeyProcessor =
new AndroidKeyProcessor(this.flutterEngine.getKeyEventChannel(), textInputPlugin);
......
......@@ -26,7 +26,6 @@ import android.view.inputmethod.InputMethodSubtype;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.platform.PlatformViewsController;
import java.util.HashMap;
......@@ -55,7 +54,7 @@ public class TextInputPlugin {
public TextInputPlugin(
View view,
@NonNull DartExecutor dartExecutor,
@NonNull TextInputChannel textInputChannel,
@NonNull PlatformViewsController platformViewsController) {
mView = view;
mImm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
......@@ -65,7 +64,7 @@ public class TextInputPlugin {
afm = null;
}
textInputChannel = new TextInputChannel(dartExecutor);
this.textInputChannel = textInputChannel;
textInputChannel.setTextInputMethodHandler(
new TextInputChannel.TextInputMethodHandler() {
@Override
......@@ -162,6 +161,7 @@ public class TextInputPlugin {
*/
public void destroy() {
platformViewsController.detachTextInputPlugin();
textInputChannel.setTextInputMethodHandler(null);
}
private static int inputTypeFromTextInputType(
......
......@@ -52,6 +52,7 @@ import io.flutter.embedding.engine.systemchannels.NavigationChannel;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
import io.flutter.embedding.engine.systemchannels.SystemChannel;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.common.ActivityLifecycleListener;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.editing.TextInputPlugin;
......@@ -216,7 +217,8 @@ public class FlutterView extends SurfaceView implements BinaryMessenger, Texture
mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
PlatformViewsController platformViewsController =
mNativeView.getPluginRegistry().getPlatformViewsController();
mTextInputPlugin = new TextInputPlugin(this, dartExecutor, platformViewsController);
mTextInputPlugin =
new TextInputPlugin(this, new TextInputChannel(dartExecutor), platformViewsController);
androidKeyProcessor = new AndroidKeyProcessor(keyEventChannel, mTextInputPlugin);
androidTouchProcessor = new AndroidTouchProcessor(flutterRenderer);
mNativeView
......
......@@ -30,6 +30,7 @@ import io.flutter.embedding.engine.systemchannels.LocalizationChannel;
import io.flutter.embedding.engine.systemchannels.NavigationChannel;
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
import io.flutter.embedding.engine.systemchannels.SystemChannel;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.platform.PlatformViewsController;
import org.junit.Before;
import org.junit.Test;
......@@ -613,6 +614,7 @@ public class FlutterActivityAndFragmentDelegateTest {
when(engine.getLifecycleChannel()).thenReturn(mock(LifecycleChannel.class));
when(engine.getNavigationChannel()).thenReturn(mock(NavigationChannel.class));
when(engine.getSystemChannel()).thenReturn(mock(SystemChannel.class));
when(engine.getTextInputChannel()).thenReturn(mock(TextInputChannel.class));
when(engine.getActivityControlSurface()).thenReturn(mock(ActivityControlSurface.class));
return engine;
......
......@@ -3,10 +3,12 @@ package io.flutter.plugin.editing;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.notNull;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
......@@ -79,8 +81,9 @@ public class TextInputPluginTest {
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
TextInputPlugin textInputPlugin =
new TextInputPlugin(testView, dartExecutor, mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
ArgumentCaptor<String> channelCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<ByteBuffer> bufferCaptor = ArgumentCaptor.forClass(ByteBuffer.class);
......@@ -103,9 +106,9 @@ public class TextInputPluginTest {
RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE));
testImm.setCurrentInputMethodSubtype(inputMethodSubtype);
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -140,9 +143,9 @@ public class TextInputPluginTest {
RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE));
testImm.setCurrentInputMethodSubtype(inputMethodSubtype);
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -189,9 +192,9 @@ public class TextInputPluginTest {
RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE));
testImm.setCurrentInputMethodSubtype(inputMethodSubtype);
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -232,9 +235,9 @@ public class TextInputPluginTest {
RuntimeEnvironment.application.getSystemService(Context.INPUT_METHOD_SERVICE));
testImm.setCurrentInputMethodSubtype(inputMethodSubtype);
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -268,9 +271,9 @@ public class TextInputPluginTest {
testImm.setCurrentInputMethodSubtype(null);
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -289,6 +292,19 @@ public class TextInputPluginTest {
assertEquals(1, testImm.getRestartCount(testView));
}
@Test
public void destroy_clearTextInputMethodHandler() {
View testView = new View(RuntimeEnvironment.application);
TextInputChannel textInputChannel = spy(new TextInputChannel(mock(DartExecutor.class)));
TextInputPlugin textInputPlugin =
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
verify(textInputChannel, times(1))
.setTextInputMethodHandler(notNull(TextInputChannel.TextInputMethodHandler.class));
textInputPlugin.destroy();
verify(textInputChannel, times(1))
.setTextInputMethodHandler(isNull(TextInputChannel.TextInputMethodHandler.class));
}
@Test
public void inputConnection_createsActionFromEnter() throws JSONException {
TestImm testImm =
......@@ -297,8 +313,9 @@ public class TextInputPluginTest {
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
View testView = new View(RuntimeEnvironment.application);
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
TextInputPlugin textInputPlugin =
new TextInputPlugin(testView, dartExecutor, mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -368,8 +385,9 @@ public class TextInputPluginTest {
FlutterJNI mockFlutterJni = mock(FlutterJNI.class);
View testView = new View(RuntimeEnvironment.application);
DartExecutor dartExecutor = spy(new DartExecutor(mockFlutterJni, mock(AssetManager.class)));
TextInputChannel textInputChannel = new TextInputChannel(dartExecutor);
TextInputPlugin textInputPlugin =
new TextInputPlugin(testView, dartExecutor, mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
textInputPlugin.setTextInputClient(
0,
new TextInputChannel.Configuration(
......@@ -402,9 +420,9 @@ public class TextInputPluginTest {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return;
FlutterView testView = new FlutterView(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
final TextInputChannel.Configuration.Autofill autofill1 =
new TextInputChannel.Configuration.Autofill(
"1", new String[] {"HINT1"}, new TextInputChannel.TextEditState("", 0, 0));
......@@ -472,9 +490,9 @@ public class TextInputPluginTest {
}
FlutterView testView = new FlutterView(RuntimeEnvironment.application);
TextInputChannel textInputChannel = new TextInputChannel(mock(DartExecutor.class));
TextInputPlugin textInputPlugin =
new TextInputPlugin(
testView, mock(DartExecutor.class), mock(PlatformViewsController.class));
new TextInputPlugin(testView, textInputChannel, mock(PlatformViewsController.class));
final TextInputChannel.Configuration.Autofill autofill =
new TextInputChannel.Configuration.Autofill(
"1", new String[] {"HINT1"}, new TextInputChannel.TextEditState("", 0, 0));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册