Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
d1b0c466
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
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,发现更多精彩内容 >>
未验证
提交
d1b0c466
编写于
5月 15, 2020
作者:
G
gaaclarke
提交者:
GitHub
5月 15, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added a unit test for the iOS AccessibilityBridge. (#18281)
上级
dc7e24e1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
207 addition
and
44 deletion
+207
-44
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+1
-0
shell/platform/darwin/ios/BUILD.gn
shell/platform/darwin/ios/BUILD.gn
+26
-0
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
+46
-0
shell/platform/darwin/ios/framework/Source/SemanticsObject.mm
...l/platform/darwin/ios/framework/Source/SemanticsObject.mm
+0
-44
shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
.../darwin/ios/framework/Source/accessibility_bridge_test.mm
+134
-0
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
d1b0c466
...
...
@@ -903,6 +903,7 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/SemanticsObjec
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_ios.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h
...
...
shell/platform/darwin/ios/BUILD.gn
浏览文件 @
d1b0c466
...
...
@@ -152,6 +152,28 @@ source_set("flutter_framework_source") {
ios_test_flutter_path = rebase_path("$root_out_dir/libios_test_flutter.dylib")
platform_frameworks_path = "$ios_sdk_path/../../Library/Frameworks/"
# For tests that rely on manual reference counting.
source_set("ios_test_flutter_mrc") {
visibility = [ ":*" ]
cflags = [
"-fvisibility=default",
"-F$platform_frameworks_path",
"-mios-simulator-version-min=$ios_testing_deployment_target",
]
sources = [
"framework/Source/accessibility_bridge_test.mm",
]
deps = [
":flutter_framework_source",
"//flutter/shell/platform/darwin/common:framework_shared",
"//flutter/third_party/tonic",
"//flutter/third_party/txt",
"//third_party/ocmock:ocmock",
"//third_party/rapidjson",
"//third_party/skia",
]
}
# NOTE: This currently only supports simulator targets because of the install_name.
# TODO(54504): Switch the install_name and make the test runner copy the dynamic
# library into the testing bundle.
...
...
@@ -182,8 +204,12 @@ shared_library("ios_test_flutter") {
]
deps = [
":flutter_framework_source",
":ios_test_flutter_mrc",
"//flutter/shell/platform/darwin/common:framework_shared",
"//flutter/third_party/tonic",
"//flutter/third_party/txt",
"//third_party/ocmock:ocmock",
"//third_party/rapidjson",
"//third_party/skia",
]
public_configs = [ "//flutter:config" ]
...
...
shell/platform/darwin/ios/framework/Source/SemanticsObject.h
浏览文件 @
d1b0c466
...
...
@@ -155,4 +155,50 @@ constexpr int32_t kRootNodeId = 0;
-
(
instancetype
)
initWithSemanticsObject
:(
SemanticsObject
*
)
semanticsObject
;
@end
/**
* Represents a semantics object that has children and hence has to be presented to the OS as a
* UIAccessibilityContainer.
*
* The SemanticsObject class cannot implement the UIAccessibilityContainer protocol because an
* object that returns YES for isAccessibilityElement cannot also implement
* UIAccessibilityContainer.
*
* With the help of SemanticsObjectContainer, the hierarchy of semantic objects received from
* the framework, such as:
*
* SemanticsObject1
* SemanticsObject2
* SemanticsObject3
* SemanticsObject4
*
* is translated into the following hierarchy, which is understood by iOS:
*
* SemanticsObjectContainer1
* SemanticsObject1
* SemanticsObjectContainer2
* SemanticsObject2
* SemanticsObject3
* SemanticsObject4
*
* From Flutter's view of the world (the first tree seen above), we construct iOS's view of the
* world (second tree) as follows: We replace each SemanticsObjects that has children with a
* SemanticsObjectContainer, which has the original SemanticsObject and its children as children.
*
* SemanticsObjects have semantic information attached to them which is interpreted by
* VoiceOver (they return YES for isAccessibilityElement). The SemanticsObjectContainers are just
* there for structure and they don't provide any semantic information to VoiceOver (they return
* NO for isAccessibilityElement).
*/
@interface
SemanticsObjectContainer
:
UIAccessibilityElement
-
(
instancetype
)
init
NS_UNAVAILABLE
;
+
(
instancetype
)
new
NS_UNAVAILABLE
;
-
(
instancetype
)
initWithAccessibilityContainer
:(
id
)
container
NS_UNAVAILABLE
;
-
(
instancetype
)
initWithSemanticsObject
:(
SemanticsObject
*
)
semanticsObject
bridge
:(
fml
::
WeakPtr
<
flutter
::
AccessibilityBridgeIos
>
)
bridge
NS_DESIGNATED_INITIALIZER
;
@property
(
nonatomic
,
weak
)
SemanticsObject
*
semanticsObject
;
@end
#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_SEMANTICS_OBJECT_H_
shell/platform/darwin/ios/framework/Source/SemanticsObject.mm
浏览文件 @
d1b0c466
...
...
@@ -103,50 +103,6 @@ flutter::SemanticsAction GetSemanticsActionForScrollDirection(
}
@end
/**
* Represents a semantics object that has children and hence has to be presented to the OS as a
* UIAccessibilityContainer.
*
* The SemanticsObject class cannot implement the UIAccessibilityContainer protocol because an
* object that returns YES for isAccessibilityElement cannot also implement
* UIAccessibilityContainer.
*
* With the help of SemanticsObjectContainer, the hierarchy of semantic objects received from
* the framework, such as:
*
* SemanticsObject1
* SemanticsObject2
* SemanticsObject3
* SemanticsObject4
*
* is translated into the following hierarchy, which is understood by iOS:
*
* SemanticsObjectContainer1
* SemanticsObject1
* SemanticsObjectContainer2
* SemanticsObject2
* SemanticsObject3
* SemanticsObject4
*
* From Flutter's view of the world (the first tree seen above), we construct iOS's view of the
* world (second tree) as follows: We replace each SemanticsObjects that has children with a
* SemanticsObjectContainer, which has the original SemanticsObject and its children as children.
*
* SemanticsObjects have semantic information attached to them which is interpreted by
* VoiceOver (they return YES for isAccessibilityElement). The SemanticsObjectContainers are just
* there for structure and they don't provide any semantic information to VoiceOver (they return
* NO for isAccessibilityElement).
*/
@interface
SemanticsObjectContainer
:
UIAccessibilityElement
-
(
instancetype
)
init
__attribute__
((
unavailable
(
"Use initWithSemanticsObject instead"
)));
-
(
instancetype
)
initWithSemanticsObject
:(
SemanticsObject
*
)
semanticsObject
bridge
:(
fml
::
WeakPtr
<
flutter
::
AccessibilityBridgeIos
>
)
bridge
NS_DESIGNATED_INITIALIZER
;
@property
(
nonatomic
,
weak
)
SemanticsObject
*
semanticsObject
;
@end
@interface
SemanticsObject
()
/** Should only be called in conjunction with setting child/parent relationship. */
-
(
void
)
privateSetParent
:(
SemanticsObject
*
)
parent
;
...
...
shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
0 → 100644
浏览文件 @
d1b0c466
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <XCTest/XCTest.h>
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h"
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
#import "third_party/ocmock/Source/OCMock/OCMock.h"
FLUTTER_ASSERT_NOT_ARC
namespace
flutter
{
namespace
{
class
MockDelegate
:
public
PlatformView
::
Delegate
{
void
OnPlatformViewCreated
(
std
::
unique_ptr
<
Surface
>
surface
)
override
{}
void
OnPlatformViewDestroyed
()
override
{}
void
OnPlatformViewSetNextFrameCallback
(
const
fml
::
closure
&
closure
)
override
{}
void
OnPlatformViewSetViewportMetrics
(
const
ViewportMetrics
&
metrics
)
override
{}
void
OnPlatformViewDispatchPlatformMessage
(
fml
::
RefPtr
<
PlatformMessage
>
message
)
override
{}
void
OnPlatformViewDispatchPointerDataPacket
(
std
::
unique_ptr
<
PointerDataPacket
>
packet
)
override
{
}
void
OnPlatformViewDispatchSemanticsAction
(
int32_t
id
,
SemanticsAction
action
,
std
::
vector
<
uint8_t
>
args
)
override
{}
void
OnPlatformViewSetSemanticsEnabled
(
bool
enabled
)
override
{}
void
OnPlatformViewSetAccessibilityFeatures
(
int32_t
flags
)
override
{}
void
OnPlatformViewRegisterTexture
(
std
::
shared_ptr
<
Texture
>
texture
)
override
{}
void
OnPlatformViewUnregisterTexture
(
int64_t
texture_id
)
override
{}
void
OnPlatformViewMarkTextureFrameAvailable
(
int64_t
texture_id
)
override
{}
};
}
// namespace
}
// namespace flutter
namespace
{
fml
::
RefPtr
<
fml
::
TaskRunner
>
CreateNewThread
(
std
::
string
name
)
{
auto
thread
=
std
::
make_unique
<
fml
::
Thread
>
(
name
);
auto
runner
=
thread
->
GetTaskRunner
();
return
runner
;
}
}
// namespace
@interface
AccessibilityBridgeTest
:
XCTestCase
@end
@implementation
AccessibilityBridgeTest
-
(
void
)
testCreate
{
flutter
::
MockDelegate
mock_delegate
;
auto
thread_task_runner
=
CreateNewThread
(
"AccessibilityBridgeTest"
);
flutter
::
TaskRunners
runners
(
/*label=*/
self
.
name
.
UTF8String
,
/*platform=*/
thread_task_runner
,
/*raster=*/
thread_task_runner
,
/*ui=*/
thread_task_runner
,
/*io=*/
thread_task_runner
);
auto
platform_view
=
std
::
make_unique
<
flutter
::
PlatformViewIOS
>
(
/*delegate=*/
mock_delegate
,
/*rendering_api=*/
flutter
::
IOSRenderingAPI
::
kSoftware
,
/*task_runners=*/
runners
);
auto
bridge
=
std
::
make_unique
<
flutter
::
AccessibilityBridge
>
(
/*view=*/
nil
,
/*platform_view=*/
platform_view
.
get
(),
/*platform_views_controller=*/
nil
);
XCTAssertTrue
(
bridge
.
get
());
}
-
(
void
)
testUpdateSemanticsEmpty
{
flutter
::
MockDelegate
mock_delegate
;
auto
thread_task_runner
=
CreateNewThread
(
"AccessibilityBridgeTest"
);
flutter
::
TaskRunners
runners
(
/*label=*/
self
.
name
.
UTF8String
,
/*platform=*/
thread_task_runner
,
/*raster=*/
thread_task_runner
,
/*ui=*/
thread_task_runner
,
/*io=*/
thread_task_runner
);
auto
platform_view
=
std
::
make_unique
<
flutter
::
PlatformViewIOS
>
(
/*delegate=*/
mock_delegate
,
/*rendering_api=*/
flutter
::
IOSRenderingAPI
::
kSoftware
,
/*task_runners=*/
runners
);
id
mockFlutterView
=
OCMClassMock
([
FlutterView
class
]);
OCMExpect
([
mockFlutterView
setAccessibilityElements
:[
OCMArg
isNil
]]);
auto
bridge
=
std
::
make_unique
<
flutter
::
AccessibilityBridge
>
(
/*view=*/
mockFlutterView
,
/*platform_view=*/
platform_view
.
get
(),
/*platform_views_controller=*/
nil
);
flutter
::
SemanticsNodeUpdates
nodes
;
flutter
::
CustomAccessibilityActionUpdates
actions
;
bridge
->
UpdateSemantics
(
/*nodes=*/
nodes
,
/*actions=*/
actions
);
OCMVerifyAll
(
mockFlutterView
);
}
-
(
void
)
testUpdateSemanticsOneNode
{
flutter
::
MockDelegate
mock_delegate
;
auto
thread_task_runner
=
CreateNewThread
(
"AccessibilityBridgeTest"
);
flutter
::
TaskRunners
runners
(
/*label=*/
self
.
name
.
UTF8String
,
/*platform=*/
thread_task_runner
,
/*raster=*/
thread_task_runner
,
/*ui=*/
thread_task_runner
,
/*io=*/
thread_task_runner
);
auto
platform_view
=
std
::
make_unique
<
flutter
::
PlatformViewIOS
>
(
/*delegate=*/
mock_delegate
,
/*rendering_api=*/
flutter
::
IOSRenderingAPI
::
kSoftware
,
/*task_runners=*/
runners
);
id
mockFlutterView
=
OCMClassMock
([
FlutterView
class
]);
std
::
string
label
=
"some label"
;
__block
auto
bridge
=
std
::
make_unique
<
flutter
::
AccessibilityBridge
>
(
/*view=*/
mockFlutterView
,
/*platform_view=*/
platform_view
.
get
(),
/*platform_views_controller=*/
nil
);
OCMExpect
([
mockFlutterView
setAccessibilityElements
:[
OCMArg
checkWithBlock
:
^
BOOL
(
NSArray
*
value
)
{
if
([
value
count
]
!=
1
)
{
return
NO
;
}
else
{
SemanticsObjectContainer
*
container
=
value
[
0
];
SemanticsObject
*
object
=
container
.
semanticsObject
;
return
object
.
uid
==
kRootNodeId
&&
object
.
bridge
.
get
()
==
bridge
.
get
()
&&
object
.
node
.
label
==
label
;
}
}]]);
flutter
::
SemanticsNodeUpdates
nodes
;
flutter
::
SemanticsNode
semantics_node
;
semantics_node
.
id
=
kRootNodeId
;
semantics_node
.
label
=
label
;
nodes
[
kRootNodeId
]
=
semantics_node
;
flutter
::
CustomAccessibilityActionUpdates
actions
;
bridge
->
UpdateSemantics
(
/*nodes=*/
nodes
,
/*actions=*/
actions
);
OCMVerifyAll
(
mockFlutterView
);
}
@end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录