@@ -150,6 +150,11 @@ - (void)loadAOTData:(NSString*)assetsDir;
150150 */
151151- (void )setUpPlatformViewChannel ;
152152
153+ /* *
154+ * Creates an accessibility channel and sets up the message handler.
155+ */
156+ - (void )setUpAccessibilityChannel ;
157+
153158/* *
154159 * Handles messages received from the Flutter engine on the _*Channel channels.
155160 */
@@ -366,6 +371,9 @@ @implementation FlutterEngine {
366371 // A message channel for sending user settings to the flutter engine.
367372 FlutterBasicMessageChannel* _settingsChannel;
368373
374+ // A message channel for accessibility.
375+ FlutterBasicMessageChannel* _accessibilityChannel;
376+
369377 // A method channel for miscellaneous platform functionality.
370378 FlutterMethodChannel* _platformChannel;
371379
@@ -409,6 +417,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
409417
410418 _platformViewController = [[FlutterPlatformViewController alloc ] init ];
411419 [self setUpPlatformViewChannel ];
420+ [self setUpAccessibilityChannel ];
412421 [self setUpNotificationCenterListeners ];
413422
414423 return self;
@@ -923,6 +932,16 @@ - (void)setUpPlatformViewChannel {
923932 }];
924933}
925934
935+ - (void )setUpAccessibilityChannel {
936+ _accessibilityChannel = [FlutterBasicMessageChannel
937+ messageChannelWithName: @" flutter/accessibility"
938+ binaryMessenger: self .binaryMessenger
939+ codec: [FlutterStandardMessageCodec sharedInstance ]];
940+ __weak FlutterEngine* weakSelf = self;
941+ [_accessibilityChannel setMessageHandler: ^(id message, FlutterReply reply) {
942+ [weakSelf handleAccessibilityEvent: message];
943+ }];
944+ }
926945- (void )setUpNotificationCenterListeners {
927946 NSNotificationCenter * center = [NSNotificationCenter defaultCenter ];
928947 // macOS fires this private message when VoiceOver turns on or off.
@@ -967,7 +986,30 @@ - (void)onAccessibilityStatusChanged:(NSNotification*)notification {
967986
968987 self.semanticsEnabled = enabled;
969988}
989+ - (void )handleAccessibilityEvent : (NSDictionary <NSString*, id>*)annotatedEvent {
990+ NSString * type = annotatedEvent[@" type" ];
991+ if ([type isEqualToString: @" announce" ]) {
992+ NSString * message = annotatedEvent[@" data" ][@" message" ];
993+ NSNumber * assertiveness = annotatedEvent[@" data" ][@" assertiveness" ];
994+ if (message == nil ) {
995+ return ;
996+ }
970997
998+ NSAccessibilityPriorityLevel priority = [assertiveness isEqualToNumber: @1 ]
999+ ? NSAccessibilityPriorityHigh
1000+ : NSAccessibilityPriorityMedium;
1001+
1002+ [self announceAccessibilityMessage: message withPriority: priority];
1003+ }
1004+ }
1005+
1006+ - (void )announceAccessibilityMessage : (NSString *)message
1007+ withPriority : (NSAccessibilityPriorityLevel )priority {
1008+ NSAccessibilityPostNotificationWithUserInfo (
1009+ [self viewControllerForId: kFlutterDefaultViewId ].flutterView,
1010+ NSAccessibilityAnnouncementRequestedNotification ,
1011+ @{NSAccessibilityAnnouncementKey : message, NSAccessibilityPriorityKey : @(priority)});
1012+ }
9711013- (void )handleMethodCall : (FlutterMethodCall*)call result : (FlutterResult)result {
9721014 if ([call.method isEqualToString: @" SystemNavigator.pop" ]) {
9731015 [NSApp terminate: self ];
0 commit comments