Unverified Commit e9736efb authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

[Framework] Support for Android Fullscreen Modes (#81303)

parent de36e511
...@@ -15,6 +15,36 @@ ...@@ -15,6 +15,36 @@
version: 1 version: 1
transforms: transforms:
# Changes made in https://github.com/flutter/flutter/pull/81303
- title: "Migrate to 'setEnabledSystemUIMode'"
date: 2021-06-08
element:
uris: [ 'services.dart' ]
method: 'setEnabledSystemUIOverlays'
inClass: 'SystemChrome'
changes:
- kind: 'rename'
newName: 'setEnabledSystemUIMode'
- kind: 'removeParameter'
index: 0
- kind: 'addParameter'
index: 0
name: 'mode'
style: required_positional
argumentValue:
expression: 'SystemUiMode.manual'
- kind: 'addParameter'
index: 1
name: 'overlays'
style: optional_named
argumentValue:
expression: '{% overlays %}'
requiredIf: "overlays != ''"
variables:
overlays:
kind: 'fragment'
value: 'arguments[0]'
# Changes made in https://github.com/flutter/flutter/pull/64254 # Changes made in https://github.com/flutter/flutter/pull/64254
- title: "Migrate to 'removeRenderObjectChild'" - title: "Migrate to 'removeRenderObjectChild'"
date: 2020-08-20 date: 2020-08-20
......
...@@ -14,6 +14,7 @@ import 'package:flutter/scheduler.dart'; ...@@ -14,6 +14,7 @@ import 'package:flutter/scheduler.dart';
import 'asset_bundle.dart'; import 'asset_bundle.dart';
import 'binary_messenger.dart'; import 'binary_messenger.dart';
import 'message_codec.dart';
import 'restoration.dart'; import 'restoration.dart';
import 'system_channels.dart'; import 'system_channels.dart';
...@@ -33,6 +34,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding { ...@@ -33,6 +34,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
initLicenses(); initLicenses();
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object)); SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage); SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
SystemChannels.platform.setMethodCallHandler(_handlePlatformMessage);
readInitialLifecycleStateFromNativeWindow(); readInitialLifecycleStateFromNativeWindow();
} }
...@@ -229,6 +231,16 @@ mixin ServicesBinding on BindingBase, SchedulerBinding { ...@@ -229,6 +231,16 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
return null; return null;
} }
Future<void> _handlePlatformMessage(MethodCall methodCall) async {
final String method = methodCall.method;
// There is only one incoming method call currently possible.
assert(method == 'SystemChrome.systemUIChange');
final List<dynamic> args = methodCall.arguments as List<dynamic>;
if (_systemUiChangeCallback != null) {
await _systemUiChangeCallback!(args[0] as bool);
}
}
static AppLifecycleState? _parseAppLifecycleMessage(String message) { static AppLifecycleState? _parseAppLifecycleMessage(String message) {
switch (message) { switch (message) {
case 'AppLifecycleState.paused': case 'AppLifecycleState.paused':
...@@ -263,8 +275,32 @@ mixin ServicesBinding on BindingBase, SchedulerBinding { ...@@ -263,8 +275,32 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
RestorationManager createRestorationManager() { RestorationManager createRestorationManager() {
return RestorationManager(); return RestorationManager();
} }
SystemUiChangeCallback? _systemUiChangeCallback;
/// Sets the callback for the `SystemChrome.systemUIChange` method call
/// received on the [SystemChannels.platform] channel.
///
/// This is typically not called directly. System UI changes that this method
/// responds to are associated with [SystemUiMode]s, which are configured
/// using [SystemChrome]. Use [SystemChrome.setSystemUIChangeCallback] to configure
/// along with other SystemChrome settings.
///
/// See also:
///
/// * [SystemChrome.setEnabledSystemUIMode], which specifies the
/// [SystemUiMode] to have visible when the application is running.
void setSystemUiChangeCallback(SystemUiChangeCallback? callback) {
_systemUiChangeCallback = callback;
}
} }
/// Signature for listening to changes in the [SystemUiMode].
///
/// Set by [SystemChrome.setSystemUIChangeCallback].
typedef SystemUiChangeCallback = Future<void> Function(bool systemOverlaysAreVisible);
/// The default implementation of [BinaryMessenger]. /// The default implementation of [BinaryMessenger].
/// ///
/// This messenger sends messages from the app-side to the platform-side and /// This messenger sends messages from the app-side to the platform-side and
......
...@@ -100,7 +100,15 @@ class SystemChannels { ...@@ -100,7 +100,15 @@ class SystemChannels {
/// * `SystemChrome.setEnabledSystemUIOverlays`: Specifies the set of system /// * `SystemChrome.setEnabledSystemUIOverlays`: Specifies the set of system
/// overlays to have visible when the application is running. The argument /// overlays to have visible when the application is running. The argument
/// is a [List] of values which are string representations of values of the /// is a [List] of values which are string representations of values of the
/// [SystemUiOverlay] enum. See [SystemChrome.setEnabledSystemUIOverlays]. /// [SystemUiOverlay] enum. See [SystemChrome.setEnabledSystemUIMode].
/// [SystemUiOverlay]s can only be configured individually when using
/// [SystemUiMode.manual].
///
/// * `SystemChrome.setEnabledSystemUIMode`: Specifies the [SystemUiMode] for
/// the application. The optional `overlays` argument is a [List] of values
/// which are string representations of values of the [SystemUiOverlay]
/// enum when using [SystemUiMode.manual]. See
/// [SystemChrome.setEnabledSystemUIMode].
/// ///
/// * `SystemChrome.setSystemUIOverlayStyle`: Specifies whether system /// * `SystemChrome.setSystemUIOverlayStyle`: Specifies whether system
/// overlays (e.g. the status bar on Android or iOS) should be `light` or /// overlays (e.g. the status bar on Android or iOS) should be `light` or
...@@ -110,6 +118,15 @@ class SystemChannels { ...@@ -110,6 +118,15 @@ class SystemChannels {
/// * `SystemNavigator.pop`: Tells the operating system to close the /// * `SystemNavigator.pop`: Tells the operating system to close the
/// application, or the closest equivalent. See [SystemNavigator.pop]. /// application, or the closest equivalent. See [SystemNavigator.pop].
/// ///
/// The following incoming methods are defined for this channel (registered
/// using [MethodChannel.setMethodCallHandler]):
///
/// * `SystemChrome.systemUIChange`: The user has changed the visibility of
/// the system overlays. This is relevant when using [SystemUiMode]s
/// through [SystemChrome.setEnabledSystemUIMode]. See
/// [SystemChrome.setSystemUIChangeCallback] to respond to this change in
/// application state.
///
/// Calls to methods that are not implemented on the shell side are ignored /// Calls to methods that are not implemented on the shell side are ignored
/// (so it is safe to call methods when the relevant plugin might be missing). /// (so it is safe to call methods when the relevant plugin might be missing).
static const MethodChannel platform = OptionalMethodChannel( static const MethodChannel platform = OptionalMethodChannel(
......
...@@ -8,6 +8,7 @@ import 'dart:ui'; ...@@ -8,6 +8,7 @@ import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'binding.dart';
import 'system_channels.dart'; import 'system_channels.dart';
export 'dart:ui' show Brightness; export 'dart:ui' show Brightness;
...@@ -81,6 +82,103 @@ enum SystemUiOverlay { ...@@ -81,6 +82,103 @@ enum SystemUiOverlay {
bottom, bottom,
} }
/// Describes different display configurations for both Android and iOS.
///
/// These modes mimic Android-specific display setups.
///
/// Used by [SystemChrome.setEnabledSystemUIMode].
enum SystemUiMode {
/// Fullscreen display with status and navigation bars presentable by tapping
/// anywhere on the display.
///
/// Available starting at SDK 16 or Android J. Earlier versions of Android
/// will not be affected by this setting.
///
/// For applications running on iOS, the status bar and home indicator will be
/// hidden for a similar fullscreen experience.
///
/// Tapping on the screen displays overlays, this gesture is not received by
/// the application.
///
/// See also:
///
/// * [SystemUiChangeCallback], used to listen and respond to the change in
/// system overlays.
leanBack,
/// Fullscreen display with status and navigation bars presentable through a
/// swipe gesture at the edges of the display.
///
/// Available starting at SDK 19 or Android K. Earlier versions of Android
/// will not be affected by this setting.
///
/// For applications running on iOS, the status bar and home indicator will be
/// hidden for a similar fullscreen experience.
///
/// A swipe gesture from the edge of the screen displays overlays. In contrast
/// to [SystemUiMode.immersiveSticky], this gesture is not received by the
/// application.
///
/// See also:
///
/// * [SystemUiChangeCallback], used to listen and respond to the change in
/// system overlays.
immersive,
/// Fullscreen display with status and navigation bars presentable through a
/// swipe gesture at the edges of the display.
///
/// Available starting at SDK 19 or Android K. Earlier versions of Android
/// will not be affected by this setting.
///
/// For applications running on iOS, the status bar and home indicator will be
/// hidden for a similar fullscreen experience.
///
/// A swipe gesture from the edge of the screen displays overlays. In contrast
/// to [SystemUiMode.immersive], this gesture is received by the application.
///
/// See also:
///
/// * [SystemUiChangeCallback], used to listen and respond to the change in
/// system overlays.
immersiveSticky,
/// Fullscreen display with status and navigation elements rendered over the
/// application.
///
/// Available starting at SDK 16 or Android J. Earlier versions of Android
/// will not be affected by this setting.
///
/// For applications running on iOS, the status bar and home indicator will be
/// visible.
///
/// The system overlays will not disappear or reappear in this mode as they
/// are permanently displayed on top of the application.
///
/// See also:
///
/// * [SystemUiOverlayStyle], can be used to set transparent status and
/// navigation bars for an enhanced effect.
edgeToEdge,
/// Declares manually configured [SystemUiOverlay]s.
///
/// When using this mode with [SystemChrome.setEnabledSystemUIMode], the
/// preferred overlays must be set by the developer.
///
/// When [SystemUiOverlay.top] is enabled, the status bar will remain visible
/// on all platforms. Omitting this overlay will hide the status bar on iOS &
/// Android.
///
/// When [SystemUiOverlay.bottom] is enabled, the navigation bar and home
/// indicator of Android and iOS applications will remain visible. Omitting this
/// overlay will hide them.
///
/// Omitting both overlays will result in the same configuration as
/// [SystemUiMode.leanBack].
manual,
}
/// Specifies a preference for the style of the system overlays. /// Specifies a preference for the style of the system overlays.
/// ///
/// Used by [SystemChrome.setSystemUIOverlayStyle]. /// Used by [SystemChrome.setSystemUIOverlayStyle].
...@@ -91,9 +189,11 @@ class SystemUiOverlayStyle { ...@@ -91,9 +189,11 @@ class SystemUiOverlayStyle {
this.systemNavigationBarColor, this.systemNavigationBarColor,
this.systemNavigationBarDividerColor, this.systemNavigationBarDividerColor,
this.systemNavigationBarIconBrightness, this.systemNavigationBarIconBrightness,
this.systemNavigationBarContrastEnforced,
this.statusBarColor, this.statusBarColor,
this.statusBarBrightness, this.statusBarBrightness,
this.statusBarIconBrightness, this.statusBarIconBrightness,
this.systemStatusBarContrastEnforced,
}); });
/// The color of the system bottom navigation bar. /// The color of the system bottom navigation bar.
...@@ -113,6 +213,23 @@ class SystemUiOverlayStyle { ...@@ -113,6 +213,23 @@ class SystemUiOverlayStyle {
/// When set to [Brightness.dark], the system navigation bar icons are dark. /// When set to [Brightness.dark], the system navigation bar icons are dark.
final Brightness? systemNavigationBarIconBrightness; final Brightness? systemNavigationBarIconBrightness;
/// Overrides the contrast enforcement when setting a transparent navigation
/// bar.
///
/// When setting a transparent navigation bar in SDK 29+, or Android 10 and up,
/// a translucent body scrim may be applied behind the button navigation bar
/// to ensure contrast with buttons and the background of the application.
///
/// SDK 28-, or Android P and lower, will not apply this body scrim.
///
/// Setting this to false overrides the default body scrim.
///
/// See also:
///
/// * [SystemUiOverlayStyle.systemNavigationBarColor], which is overridden
/// when transparent to enforce this contrast policy.
final bool? systemNavigationBarContrastEnforced;
/// The color of top status bar. /// The color of top status bar.
/// ///
/// Only honored in Android version M and greater. /// Only honored in Android version M and greater.
...@@ -128,6 +245,23 @@ class SystemUiOverlayStyle { ...@@ -128,6 +245,23 @@ class SystemUiOverlayStyle {
/// Only honored in Android version M and greater. /// Only honored in Android version M and greater.
final Brightness? statusBarIconBrightness; final Brightness? statusBarIconBrightness;
/// Overrides the contrast enforcement when setting a transparent status
/// bar.
///
/// When setting a transparent status bar in SDK 29+, or Android 10 and up,
/// a translucent body scrim may be applied to ensure contrast with icons and
/// the background of the application.
///
/// SDK 28-, or Android P and lower, will not apply this body scrim.
///
/// Setting this to false overrides the default body scrim.
///
/// See also:
///
/// * [SystemUiOverlayStyle.statusBarColor], which is overridden
/// when transparent to enforce this contrast policy.
final bool? systemStatusBarContrastEnforced;
/// System overlays should be drawn with a light color. Intended for /// System overlays should be drawn with a light color. Intended for
/// applications with a dark background. /// applications with a dark background.
static const SystemUiOverlayStyle light = SystemUiOverlayStyle( static const SystemUiOverlayStyle light = SystemUiOverlayStyle(
...@@ -155,10 +289,12 @@ class SystemUiOverlayStyle { ...@@ -155,10 +289,12 @@ class SystemUiOverlayStyle {
return <String, dynamic>{ return <String, dynamic>{
'systemNavigationBarColor': systemNavigationBarColor?.value, 'systemNavigationBarColor': systemNavigationBarColor?.value,
'systemNavigationBarDividerColor': systemNavigationBarDividerColor?.value, 'systemNavigationBarDividerColor': systemNavigationBarDividerColor?.value,
'systemStatusBarContrastEnforced' : systemStatusBarContrastEnforced ?? true,
'statusBarColor': statusBarColor?.value, 'statusBarColor': statusBarColor?.value,
'statusBarBrightness': statusBarBrightness?.toString(), 'statusBarBrightness': statusBarBrightness?.toString(),
'statusBarIconBrightness': statusBarIconBrightness?.toString(), 'statusBarIconBrightness': statusBarIconBrightness?.toString(),
'systemNavigationBarIconBrightness': systemNavigationBarIconBrightness?.toString(), 'systemNavigationBarIconBrightness': systemNavigationBarIconBrightness?.toString(),
'systemNavigationBarContrastEnforced' : systemNavigationBarContrastEnforced ?? true,
}; };
} }
...@@ -169,17 +305,21 @@ class SystemUiOverlayStyle { ...@@ -169,17 +305,21 @@ class SystemUiOverlayStyle {
SystemUiOverlayStyle copyWith({ SystemUiOverlayStyle copyWith({
Color? systemNavigationBarColor, Color? systemNavigationBarColor,
Color? systemNavigationBarDividerColor, Color? systemNavigationBarDividerColor,
bool? systemNavigationBarContrastEnforced,
Color? statusBarColor, Color? statusBarColor,
Brightness? statusBarBrightness, Brightness? statusBarBrightness,
Brightness? statusBarIconBrightness, Brightness? statusBarIconBrightness,
bool? systemStatusBarContrastEnforced,
Brightness? systemNavigationBarIconBrightness, Brightness? systemNavigationBarIconBrightness,
}) { }) {
return SystemUiOverlayStyle( return SystemUiOverlayStyle(
systemNavigationBarColor: systemNavigationBarColor ?? this.systemNavigationBarColor, systemNavigationBarColor: systemNavigationBarColor ?? this.systemNavigationBarColor,
systemNavigationBarDividerColor: systemNavigationBarDividerColor ?? this.systemNavigationBarDividerColor, systemNavigationBarDividerColor: systemNavigationBarDividerColor ?? this.systemNavigationBarDividerColor,
systemNavigationBarContrastEnforced: systemNavigationBarContrastEnforced ?? this.systemNavigationBarContrastEnforced,
statusBarColor: statusBarColor ?? this.statusBarColor, statusBarColor: statusBarColor ?? this.statusBarColor,
statusBarIconBrightness: statusBarIconBrightness ?? this.statusBarIconBrightness, statusBarIconBrightness: statusBarIconBrightness ?? this.statusBarIconBrightness,
statusBarBrightness: statusBarBrightness ?? this.statusBarBrightness, statusBarBrightness: statusBarBrightness ?? this.statusBarBrightness,
systemStatusBarContrastEnforced: systemStatusBarContrastEnforced ?? this.systemStatusBarContrastEnforced,
systemNavigationBarIconBrightness: systemNavigationBarIconBrightness ?? this.systemNavigationBarIconBrightness, systemNavigationBarIconBrightness: systemNavigationBarIconBrightness ?? this.systemNavigationBarIconBrightness,
); );
} }
...@@ -189,9 +329,11 @@ class SystemUiOverlayStyle { ...@@ -189,9 +329,11 @@ class SystemUiOverlayStyle {
return hashValues( return hashValues(
systemNavigationBarColor, systemNavigationBarColor,
systemNavigationBarDividerColor, systemNavigationBarDividerColor,
systemNavigationBarContrastEnforced,
statusBarColor, statusBarColor,
statusBarBrightness, statusBarBrightness,
statusBarIconBrightness, statusBarIconBrightness,
systemStatusBarContrastEnforced,
systemNavigationBarIconBrightness, systemNavigationBarIconBrightness,
); );
} }
...@@ -203,9 +345,11 @@ class SystemUiOverlayStyle { ...@@ -203,9 +345,11 @@ class SystemUiOverlayStyle {
return other is SystemUiOverlayStyle return other is SystemUiOverlayStyle
&& other.systemNavigationBarColor == systemNavigationBarColor && other.systemNavigationBarColor == systemNavigationBarColor
&& other.systemNavigationBarDividerColor == systemNavigationBarDividerColor && other.systemNavigationBarDividerColor == systemNavigationBarDividerColor
&& other.systemNavigationBarContrastEnforced == systemNavigationBarContrastEnforced
&& other.statusBarColor == statusBarColor && other.statusBarColor == statusBarColor
&& other.statusBarIconBrightness == statusBarIconBrightness && other.statusBarIconBrightness == statusBarIconBrightness
&& other.statusBarBrightness == statusBarBrightness && other.statusBarBrightness == statusBarBrightness
&& other.systemStatusBarContrastEnforced == systemStatusBarContrastEnforced
&& other.systemNavigationBarIconBrightness == systemNavigationBarIconBrightness; && other.systemNavigationBarIconBrightness == systemNavigationBarIconBrightness;
} }
} }
...@@ -282,11 +426,90 @@ class SystemChrome { ...@@ -282,11 +426,90 @@ class SystemChrome {
/// after a delay of 1 second. This can be achieved through [restoreSystemUIOverlays] /// after a delay of 1 second. This can be achieved through [restoreSystemUIOverlays]
/// or calling this again. Otherwise, the original UI overlay settings will be /// or calling this again. Otherwise, the original UI overlay settings will be
/// automatically restored only when the application loses and regains focus. /// automatically restored only when the application loses and regains focus.
@Deprecated(
'Migrate to setEnabledSystemUIMode. '
'This feature was deprecated after v2.3.0-17.0.pre.'
)
static Future<void> setEnabledSystemUIOverlays(List<SystemUiOverlay> overlays) async { static Future<void> setEnabledSystemUIOverlays(List<SystemUiOverlay> overlays) async {
await SystemChannels.platform.invokeMethod<void>( await setEnabledSystemUIMode(SystemUiMode.manual, overlays: overlays);
'SystemChrome.setEnabledSystemUIOverlays', }
_stringify(overlays),
); /// Specifies the [SystemUiMode] to have visible when the application
/// is running.
///
/// The `overlays` argument is a list of [SystemUiOverlay] enum values
/// denoting the overlays to show when configured with [SystemUiMode.manual].
///
/// If a particular mode is unsupported on the platform, enabling or
/// disabling that mode will be ignored.
///
/// The settings here can be overridden by the platform when System UI becomes
/// necessary for functionality.
///
/// For example, on Android, when the keyboard becomes visible, it will enable the
/// navigation bar and status bar system UI overlays. When the keyboard is closed,
/// Android will not restore the previous UI visibility settings, and the UI
/// visibility cannot be changed until 1 second after the keyboard is closed to
/// prevent malware locking users from navigation buttons.
///
/// To regain "fullscreen" after text entry, the UI overlays can be set again
/// after a delay of at least 1 second through [restoreSystemUIOverlays] or
/// calling this again. Otherwise, the original UI overlay settings will be
/// automatically restored only when the application loses and regains focus.
///
/// Alternatively, a [SystemUiChangeCallback] can be provided to respond to
/// changes in the System UI. This will be called, for example, when in
/// [SystemUiMode.leanBack] and the user taps the screen to bring up the
/// system overlays. The callback provides a boolean to represent if the
/// application is currently in a fullscreen mode or not, so that the
/// application can respond to these changes. When `systemOverlaysAreVisible`
/// is true, the application is not fullscreen. See
/// [SystemChrome.setSystemUIChangeCallback] to respond to these changes in a
/// fullscreen application.
static Future<void> setEnabledSystemUIMode(SystemUiMode mode, { List<SystemUiOverlay>? overlays }) async {
if (mode != SystemUiMode.manual) {
await SystemChannels.platform.invokeMethod<void>(
'SystemChrome.setEnabledSystemUIMode',
mode.toString(),
);
} else {
assert(mode == SystemUiMode.manual && overlays != null);
await SystemChannels.platform.invokeMethod<void>(
'SystemChrome.setEnabledSystemUIOverlays',
_stringify(overlays!),
);
}
}
/// Sets the callback method for responding to changes in the system UI.
///
/// This is relevant when using [SystemUiMode.leanBack]
/// and [SystemUiMode.immersive] and [SystemUiMode.immersiveSticky] on Android
/// platforms, where the [SystemUiOverlay]s can appear and disappear based on
/// user interaction.
///
/// This will be called, for example, when in [SystemUiMode.leanBack] and the
/// user taps the screen to bring up the system overlays. The callback
/// provides a boolean to represent if the application is currently in a
/// fullscreen mode or not, so that the application can respond to these
/// changes. When `systemOverlaysAreVisible` is true, the application is not
/// fullscreen.
///
/// When using [SystemUiMode.edgeToEdge], system overlays are always visible
/// and do not change. When manually configuring [SystemUiOverlay]s with
/// [SystemUiMode.manual], this callback will only be triggered when all
/// overlays have been disabled. This results in the same behavior as
/// [SystemUiMode.leanBack].
///
static Future<void> setSystemUIChangeCallback(SystemUiChangeCallback? callback) async {
ServicesBinding.instance!.setSystemUiChangeCallback(callback);
// Skip setting up the listener if there is no callback.
if (callback != null) {
await SystemChannels.platform.invokeMethod<void>(
'SystemChrome.setSystemUIChangeListener',
null,
);
}
} }
/// Restores the system overlays to the last settings provided via /// Restores the system overlays to the last settings provided via
......
...@@ -89,16 +89,80 @@ void main() { ...@@ -89,16 +89,80 @@ void main() {
)); ));
}); });
test('setEnabledSystemUIMode control test', () async {
final List<MethodCall> log = <MethodCall>[];
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
log.add(methodCall);
});
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.leanBack);
expect(log, hasLength(1));
expect(log.single, isMethodCall(
'SystemChrome.setEnabledSystemUIMode',
arguments: 'SystemUiMode.leanBack',
));
});
test('setEnabledSystemUIMode asserts for overlays in manual configuration', () async {
expect(
() async {
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual);
},
throwsA(
isA<AssertionError>().having((AssertionError error) => error.toString(),
'description', contains('mode == SystemUiMode.manual && overlays != null')),
),
);
});
test('setEnabledSystemUIMode passes correct overlays for manual configuration', () async {
final List<MethodCall> log = <MethodCall>[];
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
log.add(methodCall);
});
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: <SystemUiOverlay>[SystemUiOverlay.top]);
expect(log, hasLength(1));
expect(log.single, isMethodCall(
'SystemChrome.setEnabledSystemUIOverlays',
arguments: <String>['SystemUiOverlay.top'],
));
});
test('setSystemUIChangeCallback control test', () async {
final List<MethodCall> log = <MethodCall>[];
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
log.add(methodCall);
});
await SystemChrome.setSystemUIChangeCallback(null);
expect(log, hasLength(0));
await SystemChrome.setSystemUIChangeCallback((bool overlaysAreVisible) async {});
expect(log, hasLength(1));
expect(log.single, isMethodCall(
'SystemChrome.setSystemUIChangeListener',
arguments: null,
));
});
test('toString works as intended', () async { test('toString works as intended', () async {
const SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(); const SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle();
expect(systemUiOverlayStyle.toString(), 'SystemUiOverlayStyle({' expect(systemUiOverlayStyle.toString(), 'SystemUiOverlayStyle({'
'systemNavigationBarColor: null, ' 'systemNavigationBarColor: null, '
'systemNavigationBarDividerColor: null, ' 'systemNavigationBarDividerColor: null, '
'systemStatusBarContrastEnforced: true, '
'statusBarColor: null, ' 'statusBarColor: null, '
'statusBarBrightness: null, ' 'statusBarBrightness: null, '
'statusBarIconBrightness: null, ' 'statusBarIconBrightness: null, '
'systemNavigationBarIconBrightness: null})', 'systemNavigationBarIconBrightness: null, '
'systemNavigationBarContrastEnforced: true})',
); );
}); });
} }
...@@ -18,4 +18,10 @@ void main() { ...@@ -18,4 +18,10 @@ void main() {
layoutDirection: TextDirection.ltr, layoutDirection: TextDirection.ltr,
); );
viewId = textureController.id; viewId = textureController.id;
// Changes made in https://github.com/flutter/flutter/pull/81303
await SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[SystemUiOverlay.top]);
await SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[SystemUiOverlay.bottom]);
await SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[SystemUiOverlay.top, SystemUiOverlay.bottom]);
await SystemChrome.setEnabledSystemUIOverlays(<SystemUiOverlay>[]);
} }
...@@ -18,4 +18,10 @@ void main() { ...@@ -18,4 +18,10 @@ void main() {
layoutDirection: TextDirection.ltr, layoutDirection: TextDirection.ltr,
); );
viewId = textureController.viewId; viewId = textureController.viewId;
// Changes made in https://github.com/flutter/flutter/pull/81303
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: <SystemUiOverlay>[SystemUiOverlay.top]);
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: <SystemUiOverlay>[SystemUiOverlay.bottom]);
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: <SystemUiOverlay>[SystemUiOverlay.top, SystemUiOverlay.bottom]);
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: <SystemUiOverlay>[]);
} }
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