Forwards iOS dark mode trait to the Flutter framework (#34441). (flutter/engine#9722)

This commit is contained in:
Matt Carroll 2019-08-08 16:22:45 -07:00 committed by GitHub
parent ea073bcba4
commit 51904fc4bd
3 changed files with 115 additions and 1 deletions

View File

@ -681,6 +681,11 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
[_engine.get() updateViewportMetrics:_viewportMetrics];
}
- (void)updateViewConstraints {
[super updateViewConstraints];
[self onUserSettingsChanged:nil];
}
- (CGFloat)statusBarPadding {
UIScreen* screen = self.view.window.screen;
CGRect statusFrame = [UIApplication sharedApplication].statusBarFrame;
@ -690,6 +695,11 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
return CGRectIsNull(intersection) ? 0.0 : intersection.size.height;
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self onUserSettingsChanged:nil];
}
- (void)viewDidLayoutSubviews {
CGSize viewSize = self.view.bounds.size;
CGFloat scale = [UIScreen mainScreen].scale;
@ -702,6 +712,7 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
[self updateViewportPadding];
[self updateViewportMetrics];
[self onUserSettingsChanged:nil];
// This must run after updateViewportMetrics so that the surface creation tasks are queued after
// the viewport metrics update tasks.
@ -863,10 +874,16 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
#pragma mark - Set user settings
- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
[self onUserSettingsChanged:nil];
}
- (void)onUserSettingsChanged:(NSNotification*)notification {
[[_engine.get() settingsChannel] sendMessage:@{
@"textScaleFactor" : @([self textScaleFactor]),
@"alwaysUse24HourFormat" : @([self isAlwaysUse24HourFormat]),
@"platformBrightness" : [self brightnessMode]
}];
}
@ -940,6 +957,20 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
return [dateFormat rangeOfString:@"a"].location == NSNotFound;
}
- (NSString*)brightnessMode {
if (@available(iOS 13, *)) {
UIUserInterfaceStyle style = UITraitCollection.currentTraitCollection.userInterfaceStyle;
if (style == UIUserInterfaceStyleDark) {
return @"dark";
} else {
return @"light";
}
} else {
return @"light";
}
}
#pragma mark - Status Bar touch event handling
// Standard iOS status bar height in pixels.

View File

@ -6,6 +6,8 @@
#import <XCTest/XCTest.h>
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#include "FlutterBinaryMessenger.h"
@interface FlutterViewControllerTest : XCTestCase
@end
@ -23,4 +25,85 @@
OCMVerify([engine binaryMessenger]);
}
- (void)testItReportsLightPlatformBrightnessByDefault {
// Setup test.
id engine = OCMClassMock([FlutterEngine class]);
id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
OCMStub([engine settingsChannel]).andReturn(settingsChannel);
FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine
nibName:nil
bundle:nil];
// Exercise behavior under test.
[vc traitCollectionDidChange:nil];
// Verify behavior.
OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
return [message[@"platformBrightness"] isEqualToString:@"light"];
}]]);
}
- (void)testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt {
// Setup test.
id engine = OCMClassMock([FlutterEngine class]);
id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
OCMStub([engine settingsChannel]).andReturn(settingsChannel);
FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine
nibName:nil
bundle:nil];
id mockTraitCollection = [self setupFakeUserInterfaceStyle:UIUserInterfaceStyleDark];
// Exercise behavior under test.
[vc traitCollectionDidChange:nil];
// Verify behavior.
OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
return [message[@"platformBrightness"] isEqualToString:@"light"];
}]]);
// Restore UIUserInterfaceStyle
[mockTraitCollection stopMocking];
}
- (void)testItReportsPlatformBrightnessWhenExpected {
// Setup test.
id engine = OCMClassMock([FlutterEngine class]);
id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
OCMStub([engine settingsChannel]).andReturn(settingsChannel);
FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine
nibName:nil
bundle:nil];
id mockTraitCollection = [self setupFakeUserInterfaceStyle:UIUserInterfaceStyleDark];
__block int messageCount = 0;
OCMStub([settingsChannel sendMessage:[OCMArg any]]).andDo(^(NSInvocation* invocation) {
messageCount = messageCount + 1;
});
// Exercise behavior under test.
[vc updateViewConstraints];
[vc viewWillLayoutSubviews];
[vc traitCollectionDidChange:nil];
[vc onUserSettingsChanged:nil];
// Verify behavior.
XCTAssertEqual(messageCount, 4);
// Restore UIUserInterfaceStyle
[mockTraitCollection stopMocking];
}
- (UITraitCollection*)setupFakeUserInterfaceStyle:(UIUserInterfaceStyle)style {
id mockTraitCollection = OCMClassMock([UITraitCollection class]);
OCMStub([mockTraitCollection userInterfaceStyle]).andReturn(UIUserInterfaceStyleDark);
OCMStub([mockTraitCollection currentTraitCollection]).andReturn(mockTraitCollection);
return mockTraitCollection;
}
@end

View File

@ -12,6 +12,6 @@ fi
set -o pipefail && xcodebuild -sdk iphonesimulator \
-scheme IosUnitTests \
-destination 'platform=iOS Simulator,name=iPhone SE,OS=12.2' \
-destination 'platform=iOS Simulator,name=iPhone 8,OS=13.0' \
test \
FLUTTER_ENGINE=$FLUTTER_ENGINE | $PRETTY