Unverified Commit bdbe3a15 authored by amirh's avatar amirh Committed by GitHub

Add an accessibility service with an announce method. (#12594)

parent beb4004f
......@@ -14,3 +14,4 @@
library semantics;
export 'src/semantics/semantics.dart';
export 'src/semantics/semantics_service.dart';
......@@ -14,7 +14,7 @@ abstract class SemanticsEvent {
/// Initializes internal fields.
///
/// [type] is a string that identifies this class of [SemanticsEvent]s.
SemanticsEvent(this.type);
const SemanticsEvent(this.type);
/// The type of this event.
///
......@@ -121,3 +121,40 @@ class ScrollCompletedSemanticsEvent extends SemanticsEvent {
return map;
}
}
/// An event for a semantic announcement.
///
/// This should be used for announcement that are not seamlessly announced by
/// the system as a result of a UI state change.
///
/// For example a camera application can use this method to make accessibility
/// announcements regarding objects in the viewfinder.
///
/// When possible, prefer using mechanisms like [Semantics] to implicitly
/// trigger announcements over using this event.
class AnnounceSemanticsEvent extends SemanticsEvent {
/// Constructs an event that triggers an announcement by the platform.
const AnnounceSemanticsEvent(this.message, this.textDirection) :
assert(message != null),
assert(textDirection != null),
super('announce');
/// The message to announce.
///
/// This property must not be null.
final String message;
/// Text direction for [message].
///
/// This property must not be null.
final TextDirection textDirection;
@override
Map<String, dynamic> getDataMap() {
return <String, dynamic>{
'message': message,
'textDirection': textDirection.index,
};
}
}
// Copyright 2017 The Chromium 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 'dart:async';
import 'dart:ui' show TextDirection;
import 'package:flutter/services.dart' show SystemChannels;
import 'semantics_event.dart' show AnnounceSemanticsEvent;
/// Allows access to the platform's accessibility services.
///
/// Events sent by this service are handled by the platform-specific
/// accessibility bridge in Flutter's engine.
///
/// When possible, prefer using mechanisms like [Semantics] to implicitly
/// trigger announcements over using this event.
class SemanticsService {
SemanticsService._();
/// Sends a semantic announcement.
///
/// This should be used for announcement that are not seamlessly announced by
/// the system as a result of a UI state change.
///
/// For example a camera application can use this method to make accessibility
/// announcements regarding objects in the viewfinder.
static Future<Null> announce(String message, TextDirection textDirection) async {
final AnnounceSemanticsEvent event = new AnnounceSemanticsEvent(message, textDirection);
await SystemChannels.accessibility.send(event.toMap());
}
}
// Copyright 2017 The Chromium 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 'dart:ui' show TextDirection;
import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart' show SystemChannels;
import 'package:test/test.dart';
void main() {
test('Semantic announcement', () async {
final List<Map<String, dynamic>> log = <Map<String, dynamic>>[];
SystemChannels.accessibility.setMockMessageHandler((Map<String, dynamic> message) async {
log.add(message);
});
await SemanticsService.announce('announcement 1', TextDirection.ltr);
await SemanticsService.announce('announcement 2', TextDirection.rtl);
expect(log, equals(<Map<String, dynamic>>[
<String, dynamic> {'type': 'announce', 'data': <String, dynamic> {'message': 'announcement 1', 'textDirection': 1}},
<String, dynamic> {'type': 'announce', 'data': <String, dynamic> {'message': 'announcement 2', 'textDirection': 0}},
]));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment