Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
f1d37398
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,发现更多精彩内容 >>
未验证
提交
f1d37398
编写于
6月 03, 2020
作者:
G
gaaclarke
提交者:
GitHub
6月 03, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ios accessibility: started ignoring route changes when presenting modal view controllers (#18544)
上级
895ef337
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
206 addition
and
8 deletion
+206
-8
shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
...form/darwin/ios/framework/Source/FlutterViewController.mm
+19
-0
shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h
...win/ios/framework/Source/FlutterViewController_Internal.h
+1
-0
shell/platform/darwin/ios/framework/Source/accessibility_bridge.h
...atform/darwin/ios/framework/Source/accessibility_bridge.h
+14
-1
shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm
...tform/darwin/ios/framework/Source/accessibility_bridge.mm
+48
-7
shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
.../darwin/ios/framework/Source/accessibility_bridge_test.mm
+124
-0
未找到文件。
shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
浏览文件 @
f1d37398
...
...
@@ -39,6 +39,7 @@ NSNotificationName const FlutterViewControllerShowHomeIndicator =
@interface
FlutterViewController
()
<
FlutterBinaryMessenger
,
UIScrollViewDelegate
>
@property
(
nonatomic
,
readwrite
,
getter
=
isDisplayingFlutterUI
)
BOOL
displayingFlutterUI
;
@property
(
nonatomic
,
assign
)
BOOL
isHomeIndicatorHidden
;
@property
(
nonatomic
,
assign
)
BOOL
isPresentingViewControllerAnimating
;
@end
// The following conditional compilation defines an API 13 concept on earlier API targets so that
...
...
@@ -1240,4 +1241,22 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
return
[
_engine
.
get
()
valuePublishedByPlugin
:
pluginKey
];
}
-
(
void
)
presentViewController
:(
UIViewController
*
)
viewControllerToPresent
animated
:(
BOOL
)
flag
completion
:(
void
(
^
)(
void
))
completion
{
self
.
isPresentingViewControllerAnimating
=
YES
;
[
super
presentViewController
:
viewControllerToPresent
animated:
flag
completion:
^
{
self
.
isPresentingViewControllerAnimating
=
NO
;
if
(
completion
)
{
completion
();
}
}];
}
-
(
BOOL
)
isPresentingViewController
{
return
self
.
presentedViewController
!=
nil
||
self
.
isPresentingViewControllerAnimating
;
}
@end
shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h
浏览文件 @
f1d37398
...
...
@@ -23,6 +23,7 @@ extern NSNotificationName const FlutterViewControllerShowHomeIndicator;
@interface
FlutterViewController
()
@property
(
nonatomic
,
readonly
)
BOOL
isPresentingViewController
;
-
(
fml
::
WeakPtr
<
FlutterViewController
>
)
getWeakPtr
;
-
(
flutter
::
FlutterPlatformViewsController
*
)
platformViewsController
;
...
...
shell/platform/darwin/ios/framework/Source/accessibility_bridge.h
浏览文件 @
f1d37398
...
...
@@ -36,9 +36,21 @@ class PlatformViewIOS;
*/
class
AccessibilityBridge
final
:
public
AccessibilityBridgeIos
{
public:
/** Delegate for handling iOS operations. */
class
IosDelegate
{
public:
virtual
~
IosDelegate
()
=
default
;
/// Returns true when the FlutterViewController associated with the `view`
/// is presenting a modal view controller.
virtual
bool
IsFlutterViewControllerPresentingModalViewController
(
UIView
*
view
)
=
0
;
virtual
void
PostAccessibilityNotification
(
UIAccessibilityNotifications
notification
,
id
argument
)
=
0
;
};
AccessibilityBridge
(
UIView
*
view
,
PlatformViewIOS
*
platform_view
,
FlutterPlatformViewsController
*
platform_views_controller
);
FlutterPlatformViewsController
*
platform_views_controller
,
std
::
unique_ptr
<
IosDelegate
>
ios_delegate
=
nullptr
);
~
AccessibilityBridge
();
void
UpdateSemantics
(
flutter
::
SemanticsNodeUpdates
nodes
,
...
...
@@ -75,6 +87,7 @@ class AccessibilityBridge final : public AccessibilityBridgeIos {
int32_t
previous_route_id_
;
std
::
unordered_map
<
int32_t
,
flutter
::
CustomAccessibilityAction
>
actions_
;
std
::
vector
<
int32_t
>
previous_routes_
;
std
::
unique_ptr
<
IosDelegate
>
ios_delegate_
;
FML_DISALLOW_COPY_AND_ASSIGN
(
AccessibilityBridge
);
};
...
...
shell/platform/darwin/ios/framework/Source/accessibility_bridge.mm
浏览文件 @
f1d37398
...
...
@@ -4,6 +4,7 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/accessibility_text_entry.h"
#import "flutter/shell/platform/darwin/ios/platform_view_ios.h"
...
...
@@ -13,17 +14,54 @@
FLUTTER_ASSERT_NOT_ARC
namespace
flutter
{
namespace
{
FlutterViewController
*
_Nullable
GetFlutterViewControllerForView
(
UIView
*
view
)
{
// There is no way to get a view's view controller in UIKit directly, this is
// somewhat of a hacky solution to get that. This could be eliminated if the
// bridge actually kept a reference to a FlutterViewController instead of a
// UIView.
id
nextResponder
=
[
view
nextResponder
];
if
([
nextResponder
isKindOfClass
:[
FlutterViewController
class
]])
{
return
nextResponder
;
}
else
if
([
nextResponder
isKindOfClass
:[
UIView
class
]])
{
return
GetFlutterViewControllerForView
(
nextResponder
);
}
else
{
return
nil
;
}
}
class
DefaultIosDelegate
:
public
AccessibilityBridge
::
IosDelegate
{
public:
bool
IsFlutterViewControllerPresentingModalViewController
(
UIView
*
view
)
override
{
FlutterViewController
*
viewController
=
GetFlutterViewControllerForView
(
view
);
if
(
viewController
)
{
return
viewController
.
isPresentingViewController
;
}
else
{
return
false
;
}
}
void
PostAccessibilityNotification
(
UIAccessibilityNotifications
notification
,
id
argument
)
override
{
UIAccessibilityPostNotification
(
notification
,
argument
);
}
};
}
// namespace
AccessibilityBridge
::
AccessibilityBridge
(
UIView
*
view
,
PlatformViewIOS
*
platform_view
,
FlutterPlatformViewsController
*
platform_views_controller
)
FlutterPlatformViewsController
*
platform_views_controller
,
std
::
unique_ptr
<
IosDelegate
>
ios_delegate
)
:
view_
(
view
),
platform_view_
(
platform_view
),
platform_views_controller_
(
platform_views_controller
),
objects_
([[
NSMutableDictionary
alloc
]
init
]),
weak_factory_
(
this
),
previous_route_id_
(
0
),
previous_routes_
({})
{
previous_routes_
({}),
ios_delegate_
(
ios_delegate
?
std
:
:
move
(
ios_delegate
)
:
std
::
make_unique
<
DefaultIosDelegate
>
())
{
accessibility_channel_
.
reset
([[
FlutterBasicMessageChannel
alloc
]
initWithName:
@"flutter/accessibility"
binaryMessenger:
platform_view
->
GetOwnerViewController
().
get
().
engine
.
binaryMessenger
...
...
@@ -137,15 +175,18 @@ void AccessibilityBridge::UpdateSemantics(flutter::SemanticsNodeUpdates nodes,
layoutChanged
=
layoutChanged
||
[
doomed_uids
count
]
>
0
;
if
(
routeChanged
)
{
NSString
*
routeName
=
[
lastAdded
routeName
];
UIAccessibilityPostNotification
(
UIAccessibilityScreenChangedNotification
,
routeName
);
if
(
!
ios_delegate_
->
IsFlutterViewControllerPresentingModalViewController
(
view_
))
{
NSString
*
routeName
=
[
lastAdded
routeName
];
ios_delegate_
->
PostAccessibilityNotification
(
UIAccessibilityScreenChangedNotification
,
routeName
);
}
}
else
if
(
layoutChanged
)
{
// TODO(goderbauer): figure out which node to focus next.
UIAccessibilityPost
Notification
(
UIAccessibilityLayoutChangedNotification
,
nil
);
ios_delegate_
->
PostAccessibility
Notification
(
UIAccessibilityLayoutChangedNotification
,
nil
);
}
if
(
scrollOccured
)
{
// TODO(tvolkert): provide meaningful string (e.g. "page 2 of 5")
UIAccessibilityPost
Notification
(
UIAccessibilityPageScrolledNotification
,
@""
);
ios_delegate_
->
PostAccessibility
Notification
(
UIAccessibilityPageScrolledNotification
,
@""
);
}
}
...
...
@@ -233,7 +274,7 @@ void AccessibilityBridge::HandleEvent(NSDictionary<NSString*, id>* annotatedEven
NSString
*
type
=
annotatedEvent
[
@"type"
];
if
([
type
isEqualToString
:
@"announce"
])
{
NSString
*
message
=
annotatedEvent
[
@"data"
][
@"message"
];
UIAccessibilityPost
Notification
(
UIAccessibilityAnnouncementNotification
,
message
);
ios_delegate_
->
PostAccessibility
Notification
(
UIAccessibilityAnnouncementNotification
,
message
);
}
}
...
...
shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm
浏览文件 @
f1d37398
...
...
@@ -86,6 +86,22 @@ class MockDelegate : public PlatformView::Delegate {
void
OnPlatformViewUnregisterTexture
(
int64_t
texture_id
)
override
{}
void
OnPlatformViewMarkTextureFrameAvailable
(
int64_t
texture_id
)
override
{}
};
class
MockIosDelegate
:
public
AccessibilityBridge
::
IosDelegate
{
public:
bool
IsFlutterViewControllerPresentingModalViewController
(
UIView
*
view
)
override
{
return
result_IsFlutterViewControllerPresentingModalViewController_
;
};
void
PostAccessibilityNotification
(
UIAccessibilityNotifications
notification
,
id
argument
)
override
{
if
(
on_PostAccessibilityNotification_
)
{
on_PostAccessibilityNotification_
(
notification
,
argument
);
}
}
std
::
function
<
void
(
UIAccessibilityNotifications
,
id
)
>
on_PostAccessibilityNotification_
;
bool
result_IsFlutterViewControllerPresentingModalViewController_
=
false
;
};
}
// namespace
}
// namespace flutter
...
...
@@ -238,4 +254,112 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
XCTAssertNil
(
gMockPlatformView
);
}
-
(
void
)
testAnnouncesRouteChanges
{
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"
;
NSMutableArray
<
NSDictionary
<
NSString
*
,
id
>*>*
accessibility_notifications
=
[[[
NSMutableArray
alloc
]
init
]
autorelease
];
auto
ios_delegate
=
std
::
make_unique
<
flutter
::
MockIosDelegate
>
();
ios_delegate
->
on_PostAccessibilityNotification_
=
[
accessibility_notifications
](
UIAccessibilityNotifications
notification
,
id
argument
)
{
[
accessibility_notifications
addObject
:@{
@"notification"
:
@
(
notification
),
@"argument"
:
argument
?
argument
:
[
NSNull
null
],
}];
};
__block
auto
bridge
=
std
::
make_unique
<
flutter
::
AccessibilityBridge
>
(
/*view=*/
mockFlutterView
,
/*platform_view=*/
platform_view
.
get
(),
/*platform_views_controller=*/
nil
,
/*ios_delegate=*/
std
::
move
(
ios_delegate
));
flutter
::
CustomAccessibilityActionUpdates
actions
;
flutter
::
SemanticsNodeUpdates
nodes
;
flutter
::
SemanticsNode
route_node
;
route_node
.
id
=
1
;
route_node
.
label
=
label
;
route_node
.
flags
=
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kScopesRoute
)
|
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kNamesRoute
);
route_node
.
label
=
"route"
;
nodes
[
route_node
.
id
]
=
route_node
;
flutter
::
SemanticsNode
root_node
;
root_node
.
id
=
kRootNodeId
;
root_node
.
label
=
label
;
root_node
.
childrenInTraversalOrder
=
{
1
};
root_node
.
childrenInHitTestOrder
=
{
1
};
nodes
[
root_node
.
id
]
=
root_node
;
bridge
->
UpdateSemantics
(
/*nodes=*/
nodes
,
/*actions=*/
actions
);
XCTAssertEqual
([
accessibility_notifications
count
],
1ul
);
XCTAssertEqualObjects
(
accessibility_notifications
[
0
][
@"argument"
],
@"route"
);
XCTAssertEqual
([
accessibility_notifications
[
0
][
@"notification"
]
unsignedIntValue
],
UIAccessibilityScreenChangedNotification
);
}
-
(
void
)
testAnnouncesIgnoresRouteChangesWhenModal
{
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"
;
NSMutableArray
<
NSDictionary
<
NSString
*
,
id
>*>*
accessibility_notifications
=
[[[
NSMutableArray
alloc
]
init
]
autorelease
];
auto
ios_delegate
=
std
::
make_unique
<
flutter
::
MockIosDelegate
>
();
ios_delegate
->
on_PostAccessibilityNotification_
=
[
accessibility_notifications
](
UIAccessibilityNotifications
notification
,
id
argument
)
{
[
accessibility_notifications
addObject
:@{
@"notification"
:
@
(
notification
),
@"argument"
:
argument
?
argument
:
[
NSNull
null
],
}];
};
ios_delegate
->
result_IsFlutterViewControllerPresentingModalViewController_
=
true
;
__block
auto
bridge
=
std
::
make_unique
<
flutter
::
AccessibilityBridge
>
(
/*view=*/
mockFlutterView
,
/*platform_view=*/
platform_view
.
get
(),
/*platform_views_controller=*/
nil
,
/*ios_delegate=*/
std
::
move
(
ios_delegate
));
flutter
::
CustomAccessibilityActionUpdates
actions
;
flutter
::
SemanticsNodeUpdates
nodes
;
flutter
::
SemanticsNode
route_node
;
route_node
.
id
=
1
;
route_node
.
label
=
label
;
route_node
.
flags
=
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kScopesRoute
)
|
static_cast
<
int32_t
>
(
flutter
::
SemanticsFlags
::
kNamesRoute
);
route_node
.
label
=
"route"
;
nodes
[
route_node
.
id
]
=
route_node
;
flutter
::
SemanticsNode
root_node
;
root_node
.
id
=
kRootNodeId
;
root_node
.
label
=
label
;
root_node
.
childrenInTraversalOrder
=
{
1
};
root_node
.
childrenInHitTestOrder
=
{
1
};
nodes
[
root_node
.
id
]
=
root_node
;
bridge
->
UpdateSemantics
(
/*nodes=*/
nodes
,
/*actions=*/
actions
);
XCTAssertEqual
([
accessibility_notifications
count
],
0ul
);
}
@end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录