Commit 3f19b2db authored by Adam Barth's avatar Adam Barth Committed by GitHub

Switch to using PlatformPlugin instead of mojom (#6292)

* Switch to using PlatformPlugin instead of mojom

* Update engine.version
parent 8f0f19a5
e8d046e9e208bbc026f0f0e81cac87bfd791b7a0 cf774d580c40767548cbf68a1f07f2b7657ff93b
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_services/platform/system_chrome.dart' as mojom;
import 'constants.dart'; import 'constants.dart';
import 'icon_theme.dart'; import 'icon_theme.dart';
...@@ -342,8 +341,8 @@ class AppBar extends StatelessWidget { ...@@ -342,8 +341,8 @@ class AppBar extends StatelessWidget {
Brightness brightness = this.brightness ?? themeData.primaryColorBrightness; Brightness brightness = this.brightness ?? themeData.primaryColorBrightness;
SystemChrome.setSystemUIOverlayStyle(brightness == Brightness.dark SystemChrome.setSystemUIOverlayStyle(brightness == Brightness.dark
? mojom.SystemUiOverlayStyle.light ? SystemUiOverlayStyle.light
: mojom.SystemUiOverlayStyle.dark); : SystemUiOverlayStyle.dark);
final double toolbarOpacity = _toolbarOpacity(size.height, statusBarHeight); final double toolbarOpacity = _toolbarOpacity(size.height, statusBarHeight);
if (toolbarOpacity != 1.0) { if (toolbarOpacity != 1.0) {
......
...@@ -4,15 +4,7 @@ ...@@ -4,15 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_services/platform/haptic_feedback.dart' as mojom; import 'platform_messages.dart';
import 'shell.dart';
mojom.HapticFeedbackProxy _initHapticFeedbackProxy() {
return shell.connectToApplicationService('mojo:flutter_platform', mojom.HapticFeedback.connectToService);
}
final mojom.HapticFeedbackProxy _hapticFeedbackProxy = _initHapticFeedbackProxy();
/// Allows access to the haptic feedback interface on the device. This API is /// Allows access to the haptic feedback interface on the device. This API is
/// intentionally terse since it calls default platform behavior. It is not /// intentionally terse since it calls default platform behavior. It is not
...@@ -29,18 +21,10 @@ class HapticFeedback { ...@@ -29,18 +21,10 @@ class HapticFeedback {
/// AudioServicesPlaySystemSound) /// AudioServicesPlaySystemSound)
/// * _Android_: Uses the platform haptic feedback API that simulates a short /// * _Android_: Uses the platform haptic feedback API that simulates a short
/// a short tap on a virtual keyboard. /// a short tap on a virtual keyboard.
/// static Future<Null> vibrate() async {
/// Return Value: await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
/// 'method': 'HapticFeedback.vibrate',
/// boolean indicating if the intent to provide haptic feedback to the user 'args': <Null>[],
/// was successfully conveyed to the embedder. There may not be any actual
/// feedback if the device does not have a vibrator or one is disabled in
/// system settings.
static Future<bool> vibrate() {
Completer<bool> completer = new Completer<bool>();
_hapticFeedbackProxy.vibrate((bool result) {
completer.complete(result);
}); });
return completer.future;
} }
} }
...@@ -5,15 +5,7 @@ ...@@ -5,15 +5,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter_services/platform/path_provider.dart' as mojom; import 'platform_messages.dart';
import 'shell.dart';
mojom.PathProviderProxy _initPathProviderProxy() {
return shell.connectToApplicationService('mojo:flutter_platform', mojom.PathProvider.connectToService);
}
final mojom.PathProviderProxy _pathProviderProxy = _initPathProviderProxy();
/// Returns commonly used locations on the filesystem. /// Returns commonly used locations on the filesystem.
class PathProvider { class PathProvider {
...@@ -29,12 +21,15 @@ class PathProvider { ...@@ -29,12 +21,15 @@ class PathProvider {
/// ///
/// * _iOS_: `NSTemporaryDirectory()` /// * _iOS_: `NSTemporaryDirectory()`
/// * _Android_: `getCacheDir()` on the context. /// * _Android_: `getCacheDir()` on the context.
static Future<Directory> getTemporaryDirectory() { static Future<Directory> getTemporaryDirectory() async {
Completer<Directory> completer = new Completer<Directory>(); Map<String, dynamic> result =
_pathProviderProxy.temporaryDirectory((String path) { await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
completer.complete(new Directory(path)); 'method': 'PathProvider.getTemporaryDirectory',
}); 'args': <Null>[],
return completer.future; });
if (result == null)
return null;
return new Directory(result['path']);
} }
/// Path to a directory where the application may place files that are private /// Path to a directory where the application may place files that are private
...@@ -45,11 +40,14 @@ class PathProvider { ...@@ -45,11 +40,14 @@ class PathProvider {
/// ///
/// * _iOS_: `NSDocumentsDirectory` /// * _iOS_: `NSDocumentsDirectory`
/// * _Android_: The AppData directory. /// * _Android_: The AppData directory.
static Future<Directory> getApplicationDocumentsDirectory() { static Future<Directory> getApplicationDocumentsDirectory() async {
Completer<Directory> completer = new Completer<Directory>(); Map<String, dynamic> result =
_pathProviderProxy.applicationDocumentsDirectory((String path) { await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
completer.complete(new Directory(path)); 'method': 'PathProvider.getApplicationDocumentsDirectory',
'args': <Null>[],
}); });
return completer.future; if (result == null)
return null;
return new Directory(result['path']);
} }
} }
...@@ -17,7 +17,7 @@ dynamic _decodeJSON(String message) { ...@@ -17,7 +17,7 @@ dynamic _decodeJSON(String message) {
void _sendString(String name, String message, void callback(String reply)) { void _sendString(String name, String message, void callback(String reply)) {
Uint8List encoded = UTF8.encoder.convert(message); Uint8List encoded = UTF8.encoder.convert(message);
ui.window.sendPlatformMesssage(name, encoded.buffer.asByteData(), (ByteData reply) { ui.window.sendPlatformMessage(name, encoded.buffer.asByteData(), (ByteData reply) {
callback(_decodeUTF8(reply)); callback(_decodeUTF8(reply));
}); });
} }
......
...@@ -4,20 +4,83 @@ ...@@ -4,20 +4,83 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_services/platform/system_chrome.dart' as mojom; import 'platform_messages.dart';
import 'package:flutter_services/platform/system_chrome.dart'
show DeviceOrientation, SystemUiOverlay, SystemUiOverlayStyle;
import 'shell.dart'; /// Specifies a particular device orientation.
///
/// Discussion:
///
/// To determine which values correspond to which orientations, first position
/// the device in its default orientation (this is the orientation that the
/// system first uses for its boot logo, or the orientation in which the
/// hardware logos or markings are upright, or the orientation in which the
/// cameras are at the top). If this is a portrait orientation, then this is
/// [portraitUp]. Otherwise, it's [landscapeLeft]. As you rotate the device by 90
/// degrees in a counter-clockwise direction around the axis that traverses the
/// screen, you step through each value in this enum in the order given. (For a
/// device with a landscape default orientation, the orientation obtained by
/// rotating the device 90 degrees clockwise from its default orientation is
/// [portraitUp].)
enum DeviceOrientation {
/// If the device shows its boot logo in portrait, then the boot logo is shown
/// in [portraitUp]. Otherwise, the device shows its boot logo in landscape
/// and this orientation is obtained by rotating the device 90 degrees
/// clockwise from its boot orientation.
portraitUp,
export 'package:flutter_services/platform/system_chrome.dart' /// The orientation that is 90 degrees clockwise from [portraitUp].
show DeviceOrientation, SystemUiOverlay, SystemUiOverlayStyle; landscapeLeft,
mojom.SystemChromeProxy _initSystemChromeProxy() { /// The orientation that is 180 degrees from [portraitUp].
return shell.connectToApplicationService('mojo:flutter_platform', mojom.SystemChrome.connectToService); portraitDown,
/// The orientation that is 90 degrees counterclockwise from [portraitUp].
landscapeRight,
}
/// Specifies a description of the application that is pertinent to the
/// embedder's application switcher (a.k.a. "recent tasks") user interface.
class ApplicationSwitcherDescription {
/// Creates an ApplicationSwitcherDescription.
const ApplicationSwitcherDescription({ this.label, this.primaryColor });
/// A label and description of the current state of the application.
final String label;
/// The application's primary color.
final int primaryColor;
}
/// Specifies a system overlay at a particular location. Certain platforms
/// may not use all overlays specified here.
enum SystemUiOverlay {
/// The status bar provided by the embedder on the top of the application
/// surface (optional)
top,
/// The status bar provided by the embedder on the bottom of the application
/// surface (optional)
bottom,
}
/// Specifies a preference for the style of the system overlays. Certain
/// platforms may not respect this preference.
enum SystemUiOverlayStyle {
/// System overlays should be drawn with a light color. Intended for
/// applications with a dark background.
light,
/// System overlays should be drawn with a dark color. Intended for
/// applications with a light background.
dark,
} }
final mojom.SystemChromeProxy _systemChromeProxy = _initSystemChromeProxy(); List<String> _stringify(List<dynamic> list) {
List<String> result = <String>[];
for (dynamic item in list)
result.add(item.toString());
return result;
}
/// Controls specific aspects of the embedder interface. /// Controls specific aspects of the embedder interface.
class SystemChrome { class SystemChrome {
...@@ -28,19 +91,13 @@ class SystemChrome { ...@@ -28,19 +91,13 @@ class SystemChrome {
/// ///
/// Arguments: /// Arguments:
/// ///
/// * [deviceOrientationMask]: A mask of [DeviceOrientation] enum values. /// * [orientation]: A list of [DeviceOrientation] enum values. The empty
/// The value 0 is synonymous with having all options enabled. /// list is synonymous with having all options enabled.
/// static Future<Null> setPreferredOrientations(List<DeviceOrientation> orientations) async {
/// Return Value: await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
/// 'method': 'SystemChrome.setPreferredOrientations',
/// boolean indicating if the orientation mask is valid and the changes 'args': <List<String>>[ _stringify(orientations) ],
/// could be conveyed successfully to the embedder.
static Future<bool> setPreferredOrientations(int deviceOrientationMask) {
Completer<bool> completer = new Completer<bool>();
_systemChromeProxy.setPreferredOrientations(deviceOrientationMask, (bool success) {
completer.complete(success);
}); });
return completer.future;
} }
/// Specifies the description of the current state of the application as it /// Specifies the description of the current state of the application as it
...@@ -50,21 +107,18 @@ class SystemChrome { ...@@ -50,21 +107,18 @@ class SystemChrome {
/// ///
/// * [description]: The application description. /// * [description]: The application description.
/// ///
/// Return Value:
///
/// boolean indicating if the description was conveyed successfully to the
/// embedder.
///
/// Platform Specific Notes: /// Platform Specific Notes:
/// ///
/// If application-specified metadata is unsupported on the platform, /// If application-specified metadata is unsupported on the platform,
/// specifying it is a no-op and always return true. /// specifying it is a no-op and always return true.
static Future<bool> setApplicationSwitcherDescription(mojom.ApplicationSwitcherDescription description) { static Future<Null> setApplicationSwitcherDescription(ApplicationSwitcherDescription description) async {
Completer<bool> completer = new Completer<bool>(); await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
_systemChromeProxy.setApplicationSwitcherDescription(description, (bool success) { 'method': 'SystemChrome.setApplicationSwitcherDescription',
completer.complete(success); 'args': <Map<String, dynamic>>[<String, dynamic>{
'label': description.label,
'primaryColor': description.primaryColor,
}],
}); });
return completer.future;
} }
/// Specifies the set of overlays visible on the embedder when the /// Specifies the set of overlays visible on the embedder when the
...@@ -76,21 +130,15 @@ class SystemChrome { ...@@ -76,21 +130,15 @@ class SystemChrome {
/// * [overlaysMask]: A mask of [SystemUiOverlay] enum values that denotes /// * [overlaysMask]: A mask of [SystemUiOverlay] enum values that denotes
/// the overlays to show. /// the overlays to show.
/// ///
/// Return Value:
///
/// boolean indicating if the preference was conveyed successfully to the
/// embedder.
///
/// Platform Specific Notes: /// Platform Specific Notes:
/// ///
/// If the overlay is unsupported on the platform, enabling or disabling /// If the overlay is unsupported on the platform, enabling or disabling
/// that overlay is a no-op and always return true. /// that overlay is a no-op and always return true.
static Future<bool> setEnabledSystemUIOverlays(int overlaysMask) { static Future<Null> setEnabledSystemUIOverlays(List<SystemUiOverlay> overlays) async {
Completer<bool> completer = new Completer<bool>(); await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
_systemChromeProxy.setEnabledSystemUiOverlays(overlaysMask, (bool success) { 'method': 'SystemChrome.setEnabledSystemUIOverlays',
completer.complete(success); 'args': <List<String>>[ _stringify(overlays) ],
}); });
return completer.future;
} }
/// Specifies the style of the system overlays that are visible on the /// Specifies the style of the system overlays that are visible on the
...@@ -118,8 +166,9 @@ class SystemChrome { ...@@ -118,8 +166,9 @@ class SystemChrome {
scheduleMicrotask(() { scheduleMicrotask(() {
assert(_pendingStyle != null); assert(_pendingStyle != null);
if (_pendingStyle != _latestStyle) { if (_pendingStyle != _latestStyle) {
_systemChromeProxy.setSystemUiOverlayStyle(_pendingStyle, (bool success) { PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
// Ignored. 'method': 'SystemChrome.setSystemUIOverlayStyle',
'args': <String>[ _pendingStyle.toString() ],
}); });
_latestStyle = _pendingStyle; _latestStyle = _pendingStyle;
} }
......
...@@ -4,37 +4,25 @@ ...@@ -4,37 +4,25 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_services/platform/system_sound.dart' as mojom; import 'platform_messages.dart';
import 'package:flutter_services/platform/system_sound.dart' show SystemSoundType;
import 'shell.dart'; /// A sound provided by the system
enum SystemSoundType {
export 'package:flutter_services/platform/system_sound.dart' show SystemSoundType; /// A short indication that a button was pressed.
click,
mojom.SystemSoundProxy _initSystemSoundProxy() {
return shell.connectToApplicationService('mojo:flutter_platform', mojom.SystemSound.connectToService);
} }
final mojom.SystemSoundProxy _systemChromeProxy = _initSystemSoundProxy();
/// Allows easy access to the library of short system specific sounds for /// Allows easy access to the library of short system specific sounds for
/// common tasks. /// common tasks.
class SystemSound { class SystemSound {
SystemSound._(); SystemSound._();
/// Play the specified system sound. If that sound is not present on the /// Play the specified system sound. If that sound is not present on the
/// system, this method is a no-op and returns `true`. /// system, this method is a no-op.
/// static Future<Null> play(SystemSoundType type) async {
/// Return Value: await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
/// 'method': 'SystemSound.play',
/// boolean indicating if the intent to play the specified sound was 'args': <String>[ type.toString() ],
/// successfully conveyed to the embedder. No sound may actually play if the
/// device is muted or the sound was not available on the platform.
static Future<bool> play(SystemSoundType type) {
Completer<bool> completer = new Completer<bool>();
_systemChromeProxy.play(type, (bool success) {
completer.complete(success);
}); });
return completer.future;
} }
} }
...@@ -4,16 +4,7 @@ ...@@ -4,16 +4,7 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter_services/platform/url_launcher.dart' as mojom; import 'platform_messages.dart';
import 'shell.dart';
mojom.UrlLauncherProxy _initUrlLauncherProxy() {
return shell.connectToApplicationService(
mojom.UrlLauncher.serviceName,
mojom.UrlLauncher.connectToService);
}
final mojom.UrlLauncherProxy _connectedUrlLauncherService = _initUrlLauncherProxy();
/// Allows applications to delegate responsbility of handling certain URLs to /// Allows applications to delegate responsbility of handling certain URLs to
/// the underlying platform. /// the underlying platform.
...@@ -27,18 +18,10 @@ class UrlLauncher { ...@@ -27,18 +18,10 @@ class UrlLauncher {
/// ///
/// * [urlString]: The URL string to be parsed by the underlying platform and /// * [urlString]: The URL string to be parsed by the underlying platform and
/// before it attempts to launch the same. /// before it attempts to launch the same.
/// static Future<Null> launch(String urlString) async {
/// Return Value: await PlatformMessages.sendJSON('flutter/platform', <String, dynamic>{
/// 'method': 'UrlLauncher.launch',
/// boolean indicating if the intent to handle the URL was successfully 'args': <String>[ urlString ],
/// conveyed to the to underlying platform and the platform could
/// successfully handle the same. The platform is responsible for URL
/// parsing.
static Future<bool> launch(String urlString) {
Completer<bool> completer = new Completer<bool>();
_connectedUrlLauncherService.launch(urlString, (bool success) {
completer.complete(success);
}); });
return completer.future;
} }
} }
...@@ -4,12 +4,11 @@ ...@@ -4,12 +4,11 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_services/platform/system_chrome.dart' as mojom;
void main() { void main() {
testWidgets('SystemChrome overlay style test', (WidgetTester tester) async { testWidgets('SystemChrome overlay style test', (WidgetTester tester) async {
// The first call is a cache miss and will queue a microtask // The first call is a cache miss and will queue a microtask
SystemChrome.setSystemUIOverlayStyle(mojom.SystemUiOverlayStyle.light); SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
expect(tester.binding.microtaskCount, equals(1)); expect(tester.binding.microtaskCount, equals(1));
// Flush all microtasks // Flush all microtasks
...@@ -17,7 +16,7 @@ void main() { ...@@ -17,7 +16,7 @@ void main() {
expect(tester.binding.microtaskCount, equals(0)); expect(tester.binding.microtaskCount, equals(0));
// The second call with the same value should be a no-op // The second call with the same value should be a no-op
SystemChrome.setSystemUIOverlayStyle(mojom.SystemUiOverlayStyle.light); SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
expect(tester.binding.microtaskCount, equals(0)); expect(tester.binding.microtaskCount, equals(0));
}); });
} }
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