iOS: Migrate accessibility_bridge to ARC (flutter/engine#55570)
Keeps fml::scoped_* wrappers used in C++ class declarations in headers, since those are injected into both ARC and non-ARC translation units and these classes are ARC-safe. Once we've migrated all users of those headers to ARC, we can use the underlying classes directly. No semantic changes, therefore not changes to tests. Issue: https://github.com/flutter/flutter/issues/137801 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
parent
c2ab019879
commit
86626a85fb
@ -112,6 +112,8 @@ source_set("flutter_framework_source_arc") {
|
|||||||
"framework/Source/TextInputSemanticsObject.mm",
|
"framework/Source/TextInputSemanticsObject.mm",
|
||||||
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h",
|
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.h",
|
||||||
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.mm",
|
"framework/Source/UIViewController+FlutterScreenAndSceneIfLoaded.mm",
|
||||||
|
"framework/Source/accessibility_bridge.h",
|
||||||
|
"framework/Source/accessibility_bridge.mm",
|
||||||
"framework/Source/connection_collection.h",
|
"framework/Source/connection_collection.h",
|
||||||
"framework/Source/connection_collection.mm",
|
"framework/Source/connection_collection.mm",
|
||||||
"framework/Source/overlay_layer_pool.h",
|
"framework/Source/overlay_layer_pool.h",
|
||||||
@ -188,8 +190,6 @@ source_set("flutter_framework_source") {
|
|||||||
"framework/Source/FlutterEngine_Internal.h",
|
"framework/Source/FlutterEngine_Internal.h",
|
||||||
"framework/Source/FlutterViewController.mm",
|
"framework/Source/FlutterViewController.mm",
|
||||||
"framework/Source/FlutterViewController_Internal.h",
|
"framework/Source/FlutterViewController_Internal.h",
|
||||||
"framework/Source/accessibility_bridge.h",
|
|
||||||
"framework/Source/accessibility_bridge.mm",
|
|
||||||
"platform_view_ios.h",
|
"platform_view_ios.h",
|
||||||
"platform_view_ios.mm",
|
"platform_view_ios.mm",
|
||||||
]
|
]
|
||||||
|
@ -97,6 +97,9 @@ class AccessibilityBridge final : public AccessibilityBridgeIos {
|
|||||||
// been focused or the focus is currently outside of the flutter application
|
// been focused or the focus is currently outside of the flutter application
|
||||||
// (i.e. the status bar or keyboard)
|
// (i.e. the status bar or keyboard)
|
||||||
int32_t last_focused_semantics_object_id_;
|
int32_t last_focused_semantics_object_id_;
|
||||||
|
|
||||||
|
// TODO(cbracken): https://github.com/flutter/flutter/issues/137801
|
||||||
|
// Eliminate use of fml::scoped_* wrappers here.
|
||||||
fml::scoped_nsobject<NSMutableDictionary<NSNumber*, SemanticsObject*>> objects_;
|
fml::scoped_nsobject<NSMutableDictionary<NSNumber*, SemanticsObject*>> objects_;
|
||||||
fml::scoped_nsprotocol<FlutterBasicMessageChannel*> accessibility_channel_;
|
fml::scoped_nsprotocol<FlutterBasicMessageChannel*> accessibility_channel_;
|
||||||
int32_t previous_route_id_ = 0;
|
int32_t previous_route_id_ = 0;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#pragma GCC diagnostic error "-Wundeclared-selector"
|
#pragma GCC diagnostic error "-Wundeclared-selector"
|
||||||
|
|
||||||
FLUTTER_ASSERT_NOT_ARC
|
FLUTTER_ASSERT_ARC
|
||||||
|
|
||||||
namespace flutter {
|
namespace flutter {
|
||||||
namespace {
|
namespace {
|
||||||
@ -101,14 +101,13 @@ void AccessibilityBridge::UpdateSemantics(
|
|||||||
needsAnnouncement = [object nodeShouldTriggerAnnouncement:&node];
|
needsAnnouncement = [object nodeShouldTriggerAnnouncement:&node];
|
||||||
[object setSemanticsNode:&node];
|
[object setSemanticsNode:&node];
|
||||||
NSUInteger newChildCount = node.childrenInTraversalOrder.size();
|
NSUInteger newChildCount = node.childrenInTraversalOrder.size();
|
||||||
NSMutableArray* newChildren =
|
NSMutableArray* newChildren = [[NSMutableArray alloc] initWithCapacity:newChildCount];
|
||||||
[[[NSMutableArray alloc] initWithCapacity:newChildCount] autorelease];
|
|
||||||
for (NSUInteger i = 0; i < newChildCount; ++i) {
|
for (NSUInteger i = 0; i < newChildCount; ++i) {
|
||||||
SemanticsObject* child = GetOrCreateObject(node.childrenInTraversalOrder[i], nodes);
|
SemanticsObject* child = GetOrCreateObject(node.childrenInTraversalOrder[i], nodes);
|
||||||
[newChildren addObject:child];
|
[newChildren addObject:child];
|
||||||
}
|
}
|
||||||
NSMutableArray* newChildrenInHitTestOrder =
|
NSMutableArray* newChildrenInHitTestOrder =
|
||||||
[[[NSMutableArray alloc] initWithCapacity:newChildCount] autorelease];
|
[[NSMutableArray alloc] initWithCapacity:newChildCount];
|
||||||
for (NSUInteger i = 0; i < newChildCount; ++i) {
|
for (NSUInteger i = 0; i < newChildCount; ++i) {
|
||||||
SemanticsObject* child = GetOrCreateObject(node.childrenInHitTestOrder[i], nodes);
|
SemanticsObject* child = GetOrCreateObject(node.childrenInHitTestOrder[i], nodes);
|
||||||
[newChildrenInHitTestOrder addObject:child];
|
[newChildrenInHitTestOrder addObject:child];
|
||||||
@ -117,7 +116,7 @@ void AccessibilityBridge::UpdateSemantics(
|
|||||||
object.childrenInHitTestOrder = newChildrenInHitTestOrder;
|
object.childrenInHitTestOrder = newChildrenInHitTestOrder;
|
||||||
if (!node.customAccessibilityActions.empty()) {
|
if (!node.customAccessibilityActions.empty()) {
|
||||||
NSMutableArray<FlutterCustomAccessibilityAction*>* accessibilityCustomActions =
|
NSMutableArray<FlutterCustomAccessibilityAction*>* accessibilityCustomActions =
|
||||||
[[[NSMutableArray alloc] init] autorelease];
|
[[NSMutableArray alloc] init];
|
||||||
for (int32_t action_id : node.customAccessibilityActions) {
|
for (int32_t action_id : node.customAccessibilityActions) {
|
||||||
flutter::CustomAccessibilityAction& action = actions_[action_id];
|
flutter::CustomAccessibilityAction& action = actions_[action_id];
|
||||||
if (action.overrideId != -1) {
|
if (action.overrideId != -1) {
|
||||||
@ -128,9 +127,9 @@ void AccessibilityBridge::UpdateSemantics(
|
|||||||
NSString* label = @(action.label.data());
|
NSString* label = @(action.label.data());
|
||||||
SEL selector = @selector(onCustomAccessibilityAction:);
|
SEL selector = @selector(onCustomAccessibilityAction:);
|
||||||
FlutterCustomAccessibilityAction* customAction =
|
FlutterCustomAccessibilityAction* customAction =
|
||||||
[[[FlutterCustomAccessibilityAction alloc] initWithName:label
|
[[FlutterCustomAccessibilityAction alloc] initWithName:label
|
||||||
target:object
|
target:object
|
||||||
selector:selector] autorelease];
|
selector:selector];
|
||||||
customAction.uid = action_id;
|
customAction.uid = action_id;
|
||||||
[accessibilityCustomActions addObject:customAction];
|
[accessibilityCustomActions addObject:customAction];
|
||||||
}
|
}
|
||||||
@ -143,14 +142,13 @@ void AccessibilityBridge::UpdateSemantics(
|
|||||||
// interrupting system notifications or other elements.
|
// interrupting system notifications or other elements.
|
||||||
// Expectation: roughly match the behavior of polite announcements on
|
// Expectation: roughly match the behavior of polite announcements on
|
||||||
// Android.
|
// Android.
|
||||||
NSString* announcement =
|
NSString* announcement = [[NSString alloc] initWithUTF8String:object.node.label.c_str()];
|
||||||
[[[NSString alloc] initWithUTF8String:object.node.label.c_str()] autorelease];
|
|
||||||
UIAccessibilityPostNotification(
|
UIAccessibilityPostNotification(
|
||||||
UIAccessibilityAnnouncementNotification,
|
UIAccessibilityAnnouncementNotification,
|
||||||
[[[NSAttributedString alloc] initWithString:announcement
|
[[NSAttributedString alloc] initWithString:announcement
|
||||||
attributes:@{
|
attributes:@{
|
||||||
UIAccessibilitySpeechAttributeQueueAnnouncement : @YES
|
UIAccessibilitySpeechAttributeQueueAnnouncement : @YES
|
||||||
}] autorelease]);
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +162,7 @@ void AccessibilityBridge::UpdateSemantics(
|
|||||||
view_controller_.view.accessibilityElements =
|
view_controller_.view.accessibilityElements =
|
||||||
@[ [root accessibilityContainer] ?: [NSNull null] ];
|
@[ [root accessibilityContainer] ?: [NSNull null] ];
|
||||||
}
|
}
|
||||||
NSMutableArray<SemanticsObject*>* newRoutes = [[[NSMutableArray alloc] init] autorelease];
|
NSMutableArray<SemanticsObject*>* newRoutes = [[NSMutableArray alloc] init];
|
||||||
[root collectRoutes:newRoutes];
|
[root collectRoutes:newRoutes];
|
||||||
// Finds the last route that is not in the previous routes.
|
// Finds the last route that is not in the previous routes.
|
||||||
for (SemanticsObject* route in newRoutes) {
|
for (SemanticsObject* route in newRoutes) {
|
||||||
@ -255,7 +253,6 @@ static void ReplaceSemanticsObject(SemanticsObject* oldObject,
|
|||||||
FML_DCHECK(oldObject.node.id == newObject.uid);
|
FML_DCHECK(oldObject.node.id == newObject.uid);
|
||||||
NSNumber* nodeId = @(oldObject.node.id);
|
NSNumber* nodeId = @(oldObject.node.id);
|
||||||
NSUInteger positionInChildlist = [oldObject.parent.children indexOfObject:oldObject];
|
NSUInteger positionInChildlist = [oldObject.parent.children indexOfObject:oldObject];
|
||||||
[[oldObject retain] autorelease];
|
|
||||||
oldObject.children = @[];
|
oldObject.children = @[];
|
||||||
[oldObject.parent replaceChildAtIndex:positionInChildlist withChild:newObject];
|
[oldObject.parent replaceChildAtIndex:positionInChildlist withChild:newObject];
|
||||||
[objects removeObjectForKey:nodeId];
|
[objects removeObjectForKey:nodeId];
|
||||||
@ -267,22 +264,21 @@ static SemanticsObject* CreateObject(const flutter::SemanticsNode& node,
|
|||||||
if (node.HasFlag(flutter::SemanticsFlags::kIsTextField) &&
|
if (node.HasFlag(flutter::SemanticsFlags::kIsTextField) &&
|
||||||
!node.HasFlag(flutter::SemanticsFlags::kIsReadOnly)) {
|
!node.HasFlag(flutter::SemanticsFlags::kIsReadOnly)) {
|
||||||
// Text fields are backed by objects that implement UITextInput.
|
// Text fields are backed by objects that implement UITextInput.
|
||||||
return [[[TextInputSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
|
return [[TextInputSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id];
|
||||||
} else if (!node.HasFlag(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup) &&
|
} else if (!node.HasFlag(flutter::SemanticsFlags::kIsInMutuallyExclusiveGroup) &&
|
||||||
(node.HasFlag(flutter::SemanticsFlags::kHasToggledState) ||
|
(node.HasFlag(flutter::SemanticsFlags::kHasToggledState) ||
|
||||||
node.HasFlag(flutter::SemanticsFlags::kHasCheckedState))) {
|
node.HasFlag(flutter::SemanticsFlags::kHasCheckedState))) {
|
||||||
return [[[FlutterSwitchSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
|
return [[FlutterSwitchSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id];
|
||||||
} else if (node.HasFlag(flutter::SemanticsFlags::kHasImplicitScrolling)) {
|
} else if (node.HasFlag(flutter::SemanticsFlags::kHasImplicitScrolling)) {
|
||||||
return [[[FlutterScrollableSemanticsObject alloc] initWithBridge:weak_ptr
|
return [[FlutterScrollableSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id];
|
||||||
uid:node.id] autorelease];
|
|
||||||
} else if (node.IsPlatformViewNode()) {
|
} else if (node.IsPlatformViewNode()) {
|
||||||
return [[[FlutterPlatformViewSemanticsContainer alloc]
|
return [[FlutterPlatformViewSemanticsContainer alloc]
|
||||||
initWithBridge:weak_ptr
|
initWithBridge:weak_ptr
|
||||||
uid:node.id
|
uid:node.id
|
||||||
platformView:weak_ptr->GetPlatformViewsController()->GetFlutterTouchInterceptingViewByID(
|
platformView:weak_ptr->GetPlatformViewsController()->GetFlutterTouchInterceptingViewByID(
|
||||||
node.platformViewId)] autorelease];
|
node.platformViewId)];
|
||||||
} else {
|
} else {
|
||||||
return [[[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id] autorelease];
|
return [[FlutterSemanticsObject alloc] initWithBridge:weak_ptr uid:node.id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user