Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_34031325
engine
提交
4003fbc3
E
engine
项目概览
qq_34031325
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4003fbc3
编写于
8月 19, 2019
作者:
M
Matt Carroll
提交者:
GitHub
8月 19, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Notify framework to clear input connection when app is backgrounded (#35054) (#9498)
上级
74ac6d25
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
134 addition
and
8 deletion
+134
-8
shell/platform/android/BUILD.gn
shell/platform/android/BUILD.gn
+1
-0
shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java
...ter/embedding/engine/systemchannels/TextInputChannel.java
+12
-0
shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java
...oid/io/flutter/plugin/editing/InputConnectionAdaptor.java
+20
-6
shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java
...rm/android/io/flutter/plugin/editing/TextInputPlugin.java
+9
-1
shell/platform/android/test/io/flutter/FlutterTestSuite.java
shell/platform/android/test/io/flutter/FlutterTestSuite.java
+3
-1
shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java
...embedding/engine/systemchannels/TextInputChannelTest.java
+89
-0
未找到文件。
shell/platform/android/BUILD.gn
浏览文件 @
4003fbc3
...
...
@@ -407,6 +407,7 @@ action("robolectric_tests") {
"test/io/flutter/embedding/android/FlutterActivityTest.java",
"test/io/flutter/embedding/android/FlutterFragmentTest.java",
"test/io/flutter/embedding/engine/FlutterEngineCacheTest.java",
"test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java",
"test/io/flutter/util/PreconditionsTest.java",
]
...
...
shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java
浏览文件 @
4003fbc3
...
...
@@ -9,6 +9,7 @@ import org.json.JSONException;
import
org.json.JSONObject
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
io.flutter.Log
;
...
...
@@ -222,6 +223,17 @@ public class TextInputChannel {
);
}
/**
* Instructs Flutter to clear the current input client, which ends the text
* input interaction with the given input control.
*/
public
void
onConnectionClosed
(
int
inputClientId
)
{
channel
.
invokeMethod
(
"TextInputClient.onConnectionClosed"
,
Collections
.
singletonList
(
inputClientId
)
);
}
/**
* Sets the {@link TextInputMethodHandler} which receives all events and requests
* that are parsed from the underlying platform channel.
...
...
shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java
浏览文件 @
4003fbc3
...
...
@@ -5,10 +5,10 @@
package
io.flutter.plugin.editing
;
import
android.content.Context
;
import
android.support.annotation.NonNull
;
import
android.text.DynamicLayout
;
import
android.text.Editable
;
import
android.text.Layout
;
import
android.text.Layout.Directions
;
import
android.text.Selection
;
import
android.text.TextPaint
;
import
android.view.KeyEvent
;
...
...
@@ -19,30 +19,37 @@ import android.view.inputmethod.InputMethodManager;
import
io.flutter.embedding.engine.systemchannels.TextInputChannel
;
import
io.flutter.Log
;
import
io.flutter.plugin.common.ErrorLogResult
;
import
io.flutter.plugin.common.MethodChannel
;
class
InputConnectionAdaptor
extends
BaseInputConnection
{
@NonNull
private
final
View
mFlutterView
;
private
final
int
mClient
;
@NonNull
private
final
TextInputChannel
textInputChannel
;
@NonNull
private
final
Editable
mEditable
;
@NonNull
private
final
Runnable
onConnectionClosed
;
private
int
mBatchCount
;
@NonNull
private
InputMethodManager
mImm
;
@NonNull
private
final
Layout
mLayout
;
@SuppressWarnings
(
"deprecation"
)
public
InputConnectionAdaptor
(
View
view
,
@NonNull
View
view
,
int
client
,
TextInputChannel
textInputChannel
,
Editable
editable
@NonNull
TextInputChannel
textInputChannel
,
@NonNull
Editable
editable
,
@NonNull
Runnable
onConnectionClosed
)
{
super
(
view
,
true
);
mFlutterView
=
view
;
mClient
=
client
;
this
.
textInputChannel
=
textInputChannel
;
mEditable
=
editable
;
this
.
onConnectionClosed
=
onConnectionClosed
;
mBatchCount
=
0
;
// We create a dummy Layout with max width so that the selection
// shifting acts as if all text were in one line.
...
...
@@ -50,6 +57,13 @@ class InputConnectionAdaptor extends BaseInputConnection {
mImm
=
(
InputMethodManager
)
view
.
getContext
().
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
}
@Override
public
void
closeConnection
()
{
super
.
closeConnection
();
textInputChannel
.
onConnectionClosed
(
mClient
);
onConnectionClosed
.
run
();
}
// Send the current state of the editable to Flutter.
private
void
updateEditingState
()
{
// If the IME is in the middle of a batch edit, then wait until it completes.
...
...
shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java
浏览文件 @
4003fbc3
...
...
@@ -46,6 +46,13 @@ public class TextInputPlugin {
// target is a platform view. See the comments on lockPlatformViewInputConnection for more details.
private
boolean
isInputConnectionLocked
;
private
final
Runnable
onInputConnectionClosed
=
new
Runnable
()
{
@Override
public
void
run
()
{
clearTextInputClient
();
}
};
public
TextInputPlugin
(
View
view
,
@NonNull
DartExecutor
dartExecutor
,
@NonNull
PlatformViewsController
platformViewsController
)
{
mView
=
view
;
mImm
=
(
InputMethodManager
)
view
.
getContext
().
getSystemService
(
...
...
@@ -219,7 +226,8 @@ public class TextInputPlugin {
view
,
inputTarget
.
id
,
textInputChannel
,
mEditable
mEditable
,
onInputConnectionClosed
);
outAttrs
.
initialSelStart
=
Selection
.
getSelectionStart
(
mEditable
);
outAttrs
.
initialSelEnd
=
Selection
.
getSelectionEnd
(
mEditable
);
...
...
shell/platform/android/test/io/flutter/FlutterTestSuite.java
浏览文件 @
4003fbc3
...
...
@@ -12,6 +12,7 @@ import io.flutter.embedding.android.FlutterActivityAndFragmentDelegateTest;
import
io.flutter.embedding.android.FlutterActivityTest
;
import
io.flutter.embedding.android.FlutterFragmentTest
;
import
io.flutter.embedding.engine.FlutterEngineCacheTest
;
import
io.flutter.embedding.engine.systemchannels.TextInputChannelTest
;
import
io.flutter.util.PreconditionsTest
;
@RunWith
(
Suite
.
class
)
...
...
@@ -21,7 +22,8 @@ import io.flutter.util.PreconditionsTest;
FlutterActivityTest
.
class
,
FlutterFragmentTest
.
class
,
// FlutterActivityAndFragmentDelegateTest.class, TODO(mklim): Fix and re-enable this
FlutterEngineCacheTest
.
class
FlutterEngineCacheTest
.
class
,
TextInputChannelTest
.
class
})
/** Runs all of the unit tests listed in the {@code @SuiteClasses} annotation. */
public
class
FlutterTestSuite
{}
shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java
0 → 100644
浏览文件 @
4003fbc3
package
io.flutter.embedding.engine.systemchannels
;
import
org.hamcrest.Description
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.mockito.ArgumentMatcher
;
import
org.robolectric.RobolectricTestRunner
;
import
org.robolectric.annotation.Config
;
import
java.nio.ByteBuffer
;
import
java.util.Collections
;
import
io.flutter.embedding.engine.dart.DartExecutor
;
import
io.flutter.plugin.common.JSONMethodCodec
;
import
io.flutter.plugin.common.MethodCall
;
import
static
org
.
mockito
.
Matchers
.
argThat
;
import
static
org
.
mockito
.
Matchers
.
eq
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
@Config
(
manifest
=
Config
.
NONE
)
@RunWith
(
RobolectricTestRunner
.
class
)
public
class
TextInputChannelTest
{
@Test
public
void
itNotifiesFrameworkWhenPlatformClosesInputConnection
()
{
// Setup test.
final
int
INPUT_CLIENT_ID
=
9
;
// Arbitrary integer.
DartExecutor
dartExecutor
=
mock
(
DartExecutor
.
class
);
TextInputChannel
textInputChannel
=
new
TextInputChannel
(
dartExecutor
);
// Execute behavior under test.
textInputChannel
.
onConnectionClosed
(
INPUT_CLIENT_ID
);
// Verify results.
verify
(
dartExecutor
,
times
(
1
)).
send
(
eq
(
"flutter/textinput"
),
ByteBufferMatcher
.
eqByteBuffer
(
JSONMethodCodec
.
INSTANCE
.
encodeMethodCall
(
new
MethodCall
(
"TextInputClient.onConnectionClosed"
,
Collections
.
singletonList
(
INPUT_CLIENT_ID
)
)
)),
eq
(
null
)
);
}
/**
* Mockito matcher that compares two {@link ByteBuffer}s by resetting both buffers and then
* utilizing their standard {@code equals()} method.
* <p>
* This matcher will change the state of the expected and actual buffers. The exact change in
* state depends on where the comparison fails or succeeds.
*/
static
class
ByteBufferMatcher
extends
ArgumentMatcher
<
ByteBuffer
>
{
static
ByteBuffer
eqByteBuffer
(
ByteBuffer
expected
)
{
return
argThat
(
new
ByteBufferMatcher
(
expected
));
}
private
ByteBuffer
expected
;
ByteBufferMatcher
(
ByteBuffer
expected
)
{
this
.
expected
=
expected
;
}
@Override
public
boolean
matches
(
Object
argument
)
{
if
(!(
argument
instanceof
ByteBuffer
))
{
return
false
;
}
// Reset the buffers for content comparison.
((
ByteBuffer
)
argument
).
position
(
0
);
expected
.
position
(
0
);
return
expected
.
equals
(
argument
);
}
// Implemented so that during a failure the expected value is
// shown in logs, rather than the name of this class.
@Override
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
expected
.
toString
());
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录