-
Notifications
You must be signed in to change notification settings - Fork 6k
Access on/off labels accessibility setting for switches on iOS #30764
Access on/off labels accessibility setting for switches on iOS #30764
Conversation
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
3359419
to
fc64f83
Compare
I've looked into adding unit testing to the code but it seems to be either not possible or very relevant:
Please let me know what you think, I'm open to any other suggestions I might have overlooked. π |
fc64f83
to
6795625
Compare
Gold has detected about 2 new digest(s) on patchset 1. |
9a3da84
to
58e7e56
Compare
Gold has detected about 2 new digest(s) on patchset 1. |
718ae5d
to
65c9d03
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Obj-C parts look good with request for minor changes.
I'm less familiar with the dart code, but it looks really similar to other iOS-only accessibility support like BoldText
and ReduceMotion
.
LGTM, will let engine PR chime for the second review.
int32_t flags = [viewController accessibilityFlags]; | ||
|
||
// Verify behavior. | ||
XCTAssert(flags == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in case the test device has some other UIAccessibility
features on can you instead just check that the kOnOffSwitchLabels
bit is off?
int32_t flags = [viewController accessibilityFlags]; | ||
|
||
// Verify behavior. | ||
XCTAssert(flags == 1 << 6); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, just check that the kOnOffSwitchLabels
bit is on?
@@ -0,0 +1,18 @@ | |||
// Copyright 2013 The Flutter Authors. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you added this for testability, but it seems like overkill to add a new header and implementation file for a single wrapper around a function. FlutterPlatformViews_Internal
might be a better spot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried adding it to FlutterPlatformViews_Internal
, but in the end, failed to do so. I struggled with some ARC-related errors coming in from the underlying imports having an effect on existing test cases.
Instead of going for FlutterPlatformViews
, I was able to add it to the FlutterViewController_Internal
instead. Hope that will also work for you. Please let me know!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FlutterViewController_Internal.mm
doesn't make sense, the implementation is already "internal", the _Internal.h
suffix is used to indicate it's not a "public" header and is not exported in the module.
What ARC errors were you seeing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can commit the changes if you like if that gives a clearer view. A grasp of the console log, there is more but similair. Do you know how to resolve these issues?
../../flutter/fml/platform/darwin/scoped_nsobject.h:153:28: error: 'NSAutoreleasePool' is unavailable: not available in automatic reference counting mode
explicit scoped_nsobject(NSAutoreleasePool* object = nil);
^
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.0.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSAutoreleasePool.h:10:12: note: 'NSAutoreleasePool' has been explicitly marked unavailable here
@interface NSAutoreleasePool : NSObject {
^
In file included from ../../flutter/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm:16:
In file included from ../../flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h:10:
../../flutter/fml/platform/darwin/scoped_nsobject.h:51:35: error: 'release' is unavailable: not available in automatic reference counting mode
~scoped_nsprotocol() { [object_ release]; }
^
../../flutter/fml/platform/darwin/scoped_nsobject.h:133:12: note: in instantiation of member function 'fml::scoped_nsprotocol<id>::~scoped_nsprotocol' requested here
explicit scoped_nsobject(id object = nil) : scoped_nsprotocol<id>(object) {}
^
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.0.sdk/usr/include/objc/NSObject.h:37:1: note: 'release' has been explicitly marked unavailable here
- (oneway void)release OBJC_ARC_UNAVAILABLE;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pasted AccessibilityValueProvider
at the bottom of FlutterViewController.m
and it compiled fine. You can push up your change if you want me to take a look though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that's also an option ofcourse, I didn't consider that one yet. Thanks! Will take a look.
65c9d03
to
40c0faf
Compare
Thanks for ur review! Will fix the minor requests. |
157745b
to
61a8bae
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution, we're almost there!
- (int32_t)accessibilityFlags; | ||
@end | ||
|
||
@interface AccessibilityValueProvider : NSObject | ||
+ (BOOL)accessibilityIsOnOffSwitchLabelsEnabled; | ||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try just adding it (as a class property) as the first declaration of FlutterViewController
, then testing a partial mock in the test. Kind of a smell to mock out the object under test, but adding a new class for this just to wrap the test still seems like overkill.
@interface FlutterViewController () <FlutterViewResponder>
@property(class, nonatomic, readonly) BOOL accessibilityIsOnOffSwitchLabelsEnabled;
@property(nonatomic, readonly) BOOL isPresentingViewController;
...
Then move the implementation to right under accessibilityFlags
if ([self class].accessibilityIsOnOffSwitchLabelsEnabled) {
flags |= static_cast<int32_t>(flutter::AccessibilityFeatureFlag::kOnOffSwitchLabels);
}
return flags;
}
+ (BOOL)accessibilityIsOnOffSwitchLabelsEnabled {
if (@available(iOS 13, *)) {
return UIAccessibilityIsOnOffSwitchLabelsEnabled();
} else {
return NO;
}
}
FlutterViewController* viewController = | ||
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; | ||
|
||
id valueProvider = OCMClassMock([AccessibilityValueProvider class]); | ||
OCMStub([valueProvider accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(false); | ||
|
||
// Exercise behavior under test. | ||
int32_t flags = [viewController accessibilityFlags]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then (also not the NO
and YES
BOOLs):
FlutterViewController* viewController = | |
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; | |
id valueProvider = OCMClassMock([AccessibilityValueProvider class]); | |
OCMStub([valueProvider accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(false); | |
// Exercise behavior under test. | |
int32_t flags = [viewController accessibilityFlags]; | |
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] |
FlutterViewController* viewController = | ||
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; | ||
|
||
id valueProvider = OCMClassMock([AccessibilityValueProvider class]); | ||
OCMStub([valueProvider accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(true); | ||
|
||
// Exercise behavior under test. | ||
int32_t flags = [viewController accessibilityFlags]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FlutterViewController* viewController = | |
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; | |
id valueProvider = OCMClassMock([AccessibilityValueProvider class]); | |
OCMStub([valueProvider accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(true); | |
// Exercise behavior under test. | |
int32_t flags = [viewController accessibilityFlags]; | |
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]; |
dbe49bf
to
83be62f
Compare
83be62f
to
b49fa74
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding @cyanglaz as second reviewer
namespace flutter { | ||
class PointerDataPacket {}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to change this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if I didn't it wouldn't compile.
I had to import
#import "flutter/lib/ui/window/platform_configuration.h"
to get access to the AccessibilityFeatureFlag enum.
platform_configuration imports the implementation of the PointerDataPacket class. Making the one in the tests obsolete.
#include "flutter/lib/ui/window/pointer_data_packet.h"
@@ -1052,7 +1089,7 @@ - (void)testMouseSupport API_AVAILABLE(ios(13.4)) { | |||
[vc scrollEvent:mockPanGestureRecognizer]; | |||
|
|||
[[[self.mockEngine verify] ignoringNonObjectArgs] | |||
dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>()]; | |||
dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>(0)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
Read the "On/Off switch labels enabled" setting from iOS accessibility settings and pass it together with the rest of the accessibility flags.
Issue: flutter/flutter#4830
This was the previous attempt to add the feature to the flutter engine but was reverted due to iOS version compatibility issues: #12404
Used a different PR (adding high contrast accessibility feature) as a reference: #15343
Tests
I wasn't able to find a similair test for any of the other platform-specific accessibility flags.