[web] Implement setPreferredOrientation (#18432)
* Implement preferred orientation
* update comments
diff --git a/lib/web_ui/lib/src/engine/dom_renderer.dart b/lib/web_ui/lib/src/engine/dom_renderer.dart
index 7884a54..9d4101e 100644
--- a/lib/web_ui/lib/src/engine/dom_renderer.dart
+++ b/lib/web_ui/lib/src/engine/dom_renderer.dart
@@ -516,6 +516,74 @@
}
}
+ static const String orientationLockTypeAny = 'any';
+ static const String orientationLockTypeNatural = 'natural';
+ static const String orientationLockTypeLandscape = 'landscape';
+ static const String orientationLockTypePortrait = 'portrait';
+ static const String orientationLockTypePortraitPrimary = 'portrait-primary';
+ static const String orientationLockTypePortraitSecondary = 'portrait-secondary';
+ static const String orientationLockTypeLandscapePrimary = 'landscape-primary';
+ static const String orientationLockTypeLandscapeSecondary = 'landscape-secondary';
+
+ /// Sets preferred screen orientation.
+ ///
+ /// Specifies the set of orientations the application interface can be
+ /// displayed in.
+ ///
+ /// The [orientations] argument is a list of DeviceOrientation values.
+ /// The empty list uses Screen unlock api and causes the application to
+ /// defer to the operating system default.
+ ///
+ /// See w3c screen api: https://www.w3.org/TR/screen-orientation/
+ Future<bool> setPreferredOrientation(List<dynamic> orientations) {
+ final html.Screen screen = html.window.screen;
+ if (screen != null) {
+ final html.ScreenOrientation screenOrientation =
+ screen.orientation;
+ if (screenOrientation != null) {
+ if (orientations.isEmpty) {
+ screenOrientation.unlock();
+ return Future.value(true);
+ } else {
+ String lockType = _deviceOrientationToLockType(orientations.first);
+ if (lockType != null) {
+ final Completer<bool> completer = Completer<bool>();
+ try {
+ screenOrientation.lock(lockType).then((dynamic _) {
+ completer.complete(true);
+ }).catchError((dynamic error) {
+ // On Chrome desktop an error with 'not supported on this device
+ // error' is fired.
+ completer.complete(false);
+ });
+ } catch (_) {
+ return Future.value(false);
+ }
+ return completer.future;
+ }
+ }
+ }
+ }
+ // API is not supported on this browser return false.
+ return Future.value(false);
+ }
+
+ // Converts device orientation to w3c OrientationLockType enum.
+ static String _deviceOrientationToLockType(String deviceOrientation) {
+ switch(deviceOrientation) {
+ case 'DeviceOrientation.portraitUp':
+ return orientationLockTypePortraitPrimary;
+ case 'DeviceOrientation.landscapeLeft':
+ return orientationLockTypePortraitSecondary;
+ case 'DeviceOrientation.portraitDown':
+ return orientationLockTypeLandscapePrimary;
+ case 'DeviceOrientation.landscapeRight':
+ return orientationLockTypeLandscapeSecondary;
+ default:
+ return null;
+ }
+ }
+
/// The element corresponding to the only child of the root surface.
html.Element get _rootApplicationElement {
final html.Element lastElement = rootElement.children.last;
diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart
index 7c94fff..1d29c31 100644
--- a/lib/web_ui/lib/src/engine/window.dart
+++ b/lib/web_ui/lib/src/engine/window.dart
@@ -442,6 +442,13 @@
domRenderer.setThemeColor(ui.Color(arguments['primaryColor']));
_replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true));
return;
+ case 'SystemChrome.setPreferredOrientations':
+ final List<dynamic> arguments = decoded.arguments;
+ domRenderer.setPreferredOrientation(arguments).then((bool success) {
+ _replyToPlatformMessage(callback,
+ codec.encodeSuccessEnvelope(success));
+ });
+ return;
case 'SystemSound.play':
// There are no default system sounds on web.
_replyToPlatformMessage(callback, codec.encodeSuccessEnvelope(true));