Access on/off labels accessibility setting for switches on iOS (flutter/engine#30764)
This commit is contained in:
@@ -771,6 +771,7 @@ class AccessibilityFeatures {
|
||||
static const int _kBoldTextIndex = 1 << 3;
|
||||
static const int _kReduceMotionIndex = 1 << 4;
|
||||
static const int _kHighContrastIndex = 1 << 5;
|
||||
static const int _kOnOffSwitchLabelsIndex = 1 << 6;
|
||||
|
||||
// A bitfield which represents each enabled feature.
|
||||
final int _index;
|
||||
@@ -803,6 +804,11 @@ class AccessibilityFeatures {
|
||||
/// Only supported on iOS.
|
||||
bool get highContrast => _kHighContrastIndex & _index != 0;
|
||||
|
||||
/// The platform is requesting to show on/off labels inside switches.
|
||||
///
|
||||
/// Only supported on iOS.
|
||||
bool get onOffSwitchLabels => _kOnOffSwitchLabelsIndex & _index != 0;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
final List<String> features = <String>[];
|
||||
@@ -818,6 +824,8 @@ class AccessibilityFeatures {
|
||||
features.add('reduceMotion');
|
||||
if (highContrast)
|
||||
features.add('highContrast');
|
||||
if (onOffSwitchLabels)
|
||||
features.add('onOffSwitchLabels');
|
||||
return 'AccessibilityFeatures$features';
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ enum class AccessibilityFeatureFlag : int32_t {
|
||||
kBoldText = 1 << 3,
|
||||
kReduceMotion = 1 << 4,
|
||||
kHighContrast = 1 << 5,
|
||||
kOnOffSwitchLabels = 1 << 6,
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -148,6 +148,7 @@ class AccessibilityFeatures {
|
||||
static const int _kBoldTextIndex = 1 << 3;
|
||||
static const int _kReduceMotionIndex = 1 << 4;
|
||||
static const int _kHighContrastIndex = 1 << 5;
|
||||
static const int _kOnOffSwitchLabelsIndex = 1 << 6;
|
||||
|
||||
// A bitfield which represents each enabled feature.
|
||||
final int _index;
|
||||
@@ -158,6 +159,7 @@ class AccessibilityFeatures {
|
||||
bool get boldText => _kBoldTextIndex & _index != 0;
|
||||
bool get reduceMotion => _kReduceMotionIndex & _index != 0;
|
||||
bool get highContrast => _kHighContrastIndex & _index != 0;
|
||||
bool get onOffSwitchLabels => _kOnOffSwitchLabelsIndex & _index != 0;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -180,6 +182,9 @@ class AccessibilityFeatures {
|
||||
if (highContrast) {
|
||||
features.add('highContrast');
|
||||
}
|
||||
if (onOffSwitchLabels) {
|
||||
features.add('onOffSwitchLabels');
|
||||
}
|
||||
return 'AccessibilityFeatures$features';
|
||||
}
|
||||
|
||||
|
||||
@@ -331,6 +331,13 @@ typedef enum UIAccessibilityContrast : NSInteger {
|
||||
name:UIAccessibilityDarkerSystemColorsStatusDidChangeNotification
|
||||
object:nil];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[center addObserver:self
|
||||
selector:@selector(onAccessibilityStatusChanged:)
|
||||
name:UIAccessibilityOnOffSwitchLabelsDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
[center addObserver:self
|
||||
selector:@selector(onUserSettingsChanged:)
|
||||
name:UIContentSizeCategoryDidChangeNotification
|
||||
@@ -1417,19 +1424,7 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
|
||||
return;
|
||||
}
|
||||
auto platformView = [_engine.get() platformView];
|
||||
int32_t flags = 0;
|
||||
if (UIAccessibilityIsInvertColorsEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kInvertColors);
|
||||
}
|
||||
if (UIAccessibilityIsReduceMotionEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kReduceMotion);
|
||||
}
|
||||
if (UIAccessibilityIsBoldTextEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kBoldText);
|
||||
}
|
||||
if (UIAccessibilityDarkerSystemColorsEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kHighContrast);
|
||||
}
|
||||
int32_t flags = [self accessibilityFlags];
|
||||
#if TARGET_OS_SIMULATOR
|
||||
// There doesn't appear to be any way to determine whether the accessibility
|
||||
// inspector is enabled on the simulator. We conservatively always turn on the
|
||||
@@ -1447,6 +1442,35 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
|
||||
#endif
|
||||
}
|
||||
|
||||
- (int32_t)accessibilityFlags {
|
||||
int32_t flags = 0;
|
||||
if (UIAccessibilityIsInvertColorsEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kInvertColors);
|
||||
}
|
||||
if (UIAccessibilityIsReduceMotionEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kReduceMotion);
|
||||
}
|
||||
if (UIAccessibilityIsBoldTextEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kBoldText);
|
||||
}
|
||||
if (UIAccessibilityDarkerSystemColorsEnabled()) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kHighContrast);
|
||||
}
|
||||
if ([FlutterViewController accessibilityIsOnOffSwitchLabelsEnabled]) {
|
||||
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kOnOffSwitchLabels);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
+ (BOOL)accessibilityIsOnOffSwitchLabelsEnabled {
|
||||
if (@available(iOS 13, *)) {
|
||||
return UIAccessibilityIsOnOffSwitchLabelsEnabled();
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Set user settings
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include "flutter/fml/platform/darwin/message_loop_darwin.h"
|
||||
#import "flutter/lib/ui/window/platform_configuration.h"
|
||||
#import "flutter/lib/ui/window/viewport_metrics.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
|
||||
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
|
||||
@@ -25,10 +26,6 @@ FLUTTER_ASSERT_ARC
|
||||
userData:(nullable void*)userData;
|
||||
@end
|
||||
|
||||
namespace flutter {
|
||||
class PointerDataPacket {};
|
||||
}
|
||||
|
||||
/// Sometimes we have to use a custom mock to avoid retain cycles in OCMock.
|
||||
/// Used for testing low memory notification.
|
||||
@interface FlutterEnginePartialMock : FlutterEngine
|
||||
@@ -617,6 +614,46 @@ typedef enum UIAccessibilityContrast : NSInteger {
|
||||
[mockTraitCollection stopMocking];
|
||||
}
|
||||
|
||||
- (void)testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet {
|
||||
if (@available(iOS 13, *)) {
|
||||
// noop
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup test.
|
||||
FlutterViewController* viewController =
|
||||
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
|
||||
id partialMockViewController = OCMPartialMock(viewController);
|
||||
OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(NO);
|
||||
|
||||
// Exercise behavior under test.
|
||||
int32_t flags = [partialMockViewController accessibilityFlags];
|
||||
|
||||
// Verify behavior.
|
||||
XCTAssert((flags & (int32_t)flutter::AccessibilityFeatureFlag::kOnOffSwitchLabels) == 0);
|
||||
}
|
||||
|
||||
- (void)testItReportsAccessibilityOnOffSwitchLabelsFlagSet {
|
||||
if (@available(iOS 13, *)) {
|
||||
// noop
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup test.
|
||||
FlutterViewController* viewController =
|
||||
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
|
||||
id partialMockViewController = OCMPartialMock(viewController);
|
||||
OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(YES);
|
||||
|
||||
// Exercise behavior under test.
|
||||
int32_t flags = [partialMockViewController accessibilityFlags];
|
||||
|
||||
// Verify behavior.
|
||||
XCTAssert((flags & (int32_t)flutter::AccessibilityFeatureFlag::kOnOffSwitchLabels) != 0);
|
||||
}
|
||||
|
||||
- (void)testPerformOrientationUpdateForcesOrientationChange {
|
||||
[self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortrait
|
||||
currentOrientation:UIInterfaceOrientationLandscapeLeft
|
||||
@@ -1052,7 +1089,7 @@ typedef enum UIAccessibilityContrast : NSInteger {
|
||||
[vc scrollEvent:mockPanGestureRecognizer];
|
||||
|
||||
[[[self.mockEngine verify] ignoringNonObjectArgs]
|
||||
dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>()];
|
||||
dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>(0)];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -29,6 +29,7 @@ extern NSNotificationName const FlutterViewControllerShowHomeIndicator;
|
||||
|
||||
@interface FlutterViewController () <FlutterViewResponder>
|
||||
|
||||
@property(class, nonatomic, readonly) BOOL accessibilityIsOnOffSwitchLabelsEnabled;
|
||||
@property(nonatomic, readonly) BOOL isPresentingViewController;
|
||||
@property(nonatomic, readonly) BOOL isVoiceOverRunning;
|
||||
@property(nonatomic, retain) FlutterKeyboardManager* keyboardManager;
|
||||
@@ -45,6 +46,7 @@ extern NSNotificationName const FlutterViewControllerShowHomeIndicator;
|
||||
nextAction:(void (^)())nextAction API_AVAILABLE(ios(13.4));
|
||||
- (void)addInternalPlugins;
|
||||
- (void)deregisterNotifications;
|
||||
- (int32_t)accessibilityFlags;
|
||||
@end
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERVIEWCONTROLLER_INTERNAL_H_
|
||||
|
||||
Reference in New Issue
Block a user