Update engine to include new version of Mojo (#4668)
This required switching from the Future-based bindings to the callback-based bindings.
This commit is contained in:
parent
f307735edc
commit
a8f6f44a55
2
bin/cache/engine.version
vendored
2
bin/cache/engine.version
vendored
@ -1 +1 @@
|
||||
e0ae976409ccbf25e8e26d66c4575d081fc2abdf
|
||||
f91f5ad62f7a61de787e3e6397f0b63e9eab534e
|
||||
|
@ -42,7 +42,7 @@ class PianoKey {
|
||||
Future<Null> load(mojom.MediaServiceProxy mediaService) async {
|
||||
try {
|
||||
mediaService.createPlayer(player);
|
||||
await player.prepare(await http.readDataPipe(soundUrl));
|
||||
player.prepare(await http.readDataPipe(soundUrl), (bool ignored) { });
|
||||
} catch (e) {
|
||||
print("Error: failed to load sound file $soundUrl");
|
||||
player.close();
|
||||
|
@ -130,28 +130,26 @@ class MojoClient {
|
||||
///
|
||||
/// The Future will emit a [ClientException] if the response doesn't have a
|
||||
/// success status code.
|
||||
Future<mojo.MojoDataPipeConsumer> readDataPipe(dynamic url, { Map<String, String> headers }) async {
|
||||
Future<mojo.MojoDataPipeConsumer> readDataPipe(dynamic url, { Map<String, String> headers }) {
|
||||
Completer<mojo.MojoDataPipeConsumer> completer = new Completer<mojo.MojoDataPipeConsumer>();
|
||||
mojom.UrlLoaderProxy loader = new mojom.UrlLoaderProxy.unbound();
|
||||
mojom.UrlRequest request = _prepareRequest('GET', url, headers);
|
||||
mojom.UrlResponse response;
|
||||
try {
|
||||
networkService.createUrlLoader(loader);
|
||||
response = (await loader.start(request)).response;
|
||||
} catch (exception, stack) {
|
||||
FlutterError.reportError(new FlutterErrorDetails(
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
library: 'networking HTTP library',
|
||||
context: 'while sending bytes to the Mojo network library',
|
||||
silent: true
|
||||
));
|
||||
return null;
|
||||
} finally {
|
||||
networkService.createUrlLoader(loader);
|
||||
loader.start(_prepareRequest('GET', url, headers), (mojom.UrlResponse response) {
|
||||
loader.close();
|
||||
}
|
||||
if (response.statusCode < 400)
|
||||
return response.body;
|
||||
throw new Exception("Request to $url failed with status ${response.statusCode}.");
|
||||
if (response.statusCode < 400) {
|
||||
completer.complete(response.body);
|
||||
} else {
|
||||
Exception exception = new Exception("Request to $url failed with status ${response.statusCode}.");
|
||||
FlutterError.reportError(new FlutterErrorDetails(
|
||||
exception: exception,
|
||||
library: 'networking HTTP library',
|
||||
context: 'while sending bytes to the Mojo network library',
|
||||
silent: true
|
||||
));
|
||||
completer.completeError(exception);
|
||||
}
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
mojom.UrlRequest _prepareRequest(String method, dynamic url, Map<String, String> headers, [dynamic body, Encoding encoding = UTF8]) {
|
||||
@ -177,35 +175,37 @@ class MojoClient {
|
||||
return request;
|
||||
}
|
||||
|
||||
Future<Response> _send(String method, dynamic url, Map<String, String> headers, [dynamic body, Encoding encoding = UTF8]) async {
|
||||
Future<Response> _send(String method, dynamic url, Map<String, String> headers, [dynamic body, Encoding encoding = UTF8]) {
|
||||
Completer<Response> completer = new Completer<Response>();
|
||||
mojom.UrlLoaderProxy loader = new mojom.UrlLoaderProxy.unbound();
|
||||
networkService.createUrlLoader(loader);
|
||||
mojom.UrlRequest request = _prepareRequest(method, url, headers, body, encoding);
|
||||
try {
|
||||
networkService.createUrlLoader(loader);
|
||||
mojom.UrlResponse response = (await loader.start(request)).response;
|
||||
ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body);
|
||||
Uint8List bodyBytes = new Uint8List.view(data.buffer);
|
||||
Map<String, String> headers = <String, String>{};
|
||||
if (response.headers != null) {
|
||||
for (mojom.HttpHeader header in response.headers) {
|
||||
String headerName = header.name.toLowerCase();
|
||||
String existingValue = headers[headerName];
|
||||
headers[headerName] = existingValue != null ? '$existingValue, ${header.value}' : header.value;
|
||||
}
|
||||
}
|
||||
return new Response.bytes(bodyBytes, response.statusCode, headers: headers);
|
||||
} catch (exception, stack) {
|
||||
FlutterError.reportError(new FlutterErrorDetails(
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
library: 'networking HTTP library',
|
||||
context: 'while sending bytes to the Mojo network library',
|
||||
silent: true
|
||||
));
|
||||
return new Response.bytes(null, 500);
|
||||
} finally {
|
||||
loader.start(request, (mojom.UrlResponse response) async {
|
||||
loader.close();
|
||||
}
|
||||
try {
|
||||
ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body);
|
||||
Uint8List bodyBytes = new Uint8List.view(data.buffer);
|
||||
Map<String, String> headers = <String, String>{};
|
||||
if (response.headers != null) {
|
||||
for (mojom.HttpHeader header in response.headers) {
|
||||
String headerName = header.name.toLowerCase();
|
||||
String existingValue = headers[headerName];
|
||||
headers[headerName] = existingValue != null ? '$existingValue, ${header.value}' : header.value;
|
||||
}
|
||||
}
|
||||
completer.complete(new Response.bytes(bodyBytes, response.statusCode, headers: headers));
|
||||
} catch (exception, stack) {
|
||||
FlutterError.reportError(new FlutterErrorDetails(
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
library: 'networking HTTP library',
|
||||
context: 'while sending bytes to the Mojo network library',
|
||||
silent: true
|
||||
));
|
||||
completer.complete(new Response.bytes(null, 500));
|
||||
}
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void _checkResponseSuccess(dynamic url, Response response) {
|
||||
|
@ -79,11 +79,10 @@ class ChildViewConnection {
|
||||
url, mojom.ViewProvider.connectToService
|
||||
);
|
||||
mojom.ServiceProviderProxy incomingServices = new mojom.ServiceProviderProxy.unbound();
|
||||
mojom.ServiceProviderStub outgoingServices = new mojom.ServiceProviderStub.unbound();
|
||||
_viewOwner = new mojom.ViewOwnerProxy.unbound();
|
||||
viewProvider.createView(_viewOwner, incomingServices, outgoingServices);
|
||||
viewProvider.createView(_viewOwner, incomingServices);
|
||||
viewProvider.close();
|
||||
_connection = new ApplicationConnection(outgoingServices, incomingServices);
|
||||
_connection = new ApplicationConnection(null, incomingServices);
|
||||
}
|
||||
|
||||
/// Wraps an already-established connection to a child app.
|
||||
|
@ -180,8 +180,12 @@ class MojoAssetBundle extends CachingAssetBundle {
|
||||
mojom.AssetBundleProxy _bundle;
|
||||
|
||||
@override
|
||||
Future<core.MojoDataPipeConsumer> load(String key) async {
|
||||
return (await _bundle.getAsStream(key)).assetData;
|
||||
Future<core.MojoDataPipeConsumer> load(String key) {
|
||||
Completer<core.MojoDataPipeConsumer> completer = new Completer<core.MojoDataPipeConsumer>();
|
||||
_bundle.getAsStream(key, (core.MojoDataPipeConsumer assetData) {
|
||||
completer.complete(assetData);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,11 @@ class Clipboard {
|
||||
/// Retrieves data from the clipboard that matches the given format.
|
||||
///
|
||||
/// * `format` is a media type, such as `text/plain`.
|
||||
static Future<mojom.ClipboardData> getClipboardData(String format) async {
|
||||
return (await _clipboardProxy.getClipboardData(format)).clip;
|
||||
static Future<mojom.ClipboardData> getClipboardData(String format) {
|
||||
Completer<mojom.ClipboardData> completer = new Completer<mojom.ClipboardData>();
|
||||
_clipboardProxy.getClipboardData(format, (mojom.ClipboardData clip) {
|
||||
completer.complete(clip);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,11 @@ class HapticFeedback {
|
||||
/// 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() async {
|
||||
return (await _hapticFeedbackProxy.vibrate()).success;
|
||||
static Future<bool> vibrate() {
|
||||
Completer<bool> completer = new Completer<bool>();
|
||||
_hapticFeedbackProxy.vibrate((bool result) {
|
||||
completer.complete(result);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
@ -49,13 +49,21 @@ final _ApplicationMessagesImpl _appMessages = new _ApplicationMessagesImpl();
|
||||
/// Flutter framework to exchange application-specific messages.
|
||||
class HostMessages {
|
||||
/// Send a message to the host application.
|
||||
static Future<String> sendToHost(String messageName, [String message = '']) async {
|
||||
return (await _hostAppMessagesProxy.sendString(messageName, message)).reply;
|
||||
static Future<String> sendToHost(String messageName, [String message = '']) {
|
||||
Completer<String> completer = new Completer<String>();
|
||||
_hostAppMessagesProxy.sendString(messageName, message, (String reply) {
|
||||
completer.complete(reply);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Sends a JSON-encoded message to the host application and JSON-decodes the response.
|
||||
static Future<dynamic> sendJSON(String messageName, [dynamic json]) async {
|
||||
return JSON.decode((await _hostAppMessagesProxy.sendString(messageName, JSON.encode(json))).reply);
|
||||
Completer<dynamic> completer = new Completer<dynamic>();
|
||||
_hostAppMessagesProxy.sendString(messageName, JSON.encode(json), (String reply) {
|
||||
completer.complete(JSON.decode(reply));
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Register a callback for receiving messages from the host application.
|
||||
|
@ -29,8 +29,12 @@ class PathProvider {
|
||||
///
|
||||
/// * _iOS_: `NSTemporaryDirectory()`
|
||||
/// * _Android_: `getCacheDir()` on the context.
|
||||
static Future<Directory> getTemporaryDirectory() async {
|
||||
return new Directory((await _pathProviderProxy.temporaryDirectory()).path);
|
||||
static Future<Directory> getTemporaryDirectory() {
|
||||
Completer<Directory> completer = new Completer<Directory>();
|
||||
_pathProviderProxy.temporaryDirectory((String path) {
|
||||
completer.complete(new Directory(path));
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Path to a directory where the application may place files that are private
|
||||
@ -41,7 +45,11 @@ class PathProvider {
|
||||
///
|
||||
/// * _iOS_: `NSDocumentsDirectory`
|
||||
/// * _Android_: The AppData directory.
|
||||
static Future<Directory> getApplicationDocumentsDirectory() async {
|
||||
return new Directory((await _pathProviderProxy.applicationDocumentsDirectory()).path);
|
||||
static Future<Directory> getApplicationDocumentsDirectory() {
|
||||
Completer<Directory> completer = new Completer<Directory>();
|
||||
_pathProviderProxy.applicationDocumentsDirectory((String path) {
|
||||
completer.complete(new Directory(path));
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class _ShellServiceConnector extends bindings.ServiceConnector {
|
||||
return;
|
||||
}
|
||||
mojom.ServiceProviderProxy services = new mojom.ServiceProviderProxy.unbound();
|
||||
instance._shell.connectToApplication(url, services, null);
|
||||
instance._shell.connectToApplication(url, services);
|
||||
core.MojoMessagePipe pipe = new core.MojoMessagePipe();
|
||||
proxy.ctrl.bind(pipe.endpoints[0]);
|
||||
services.connectToService_(serviceName, pipe.endpoints[1]);
|
||||
@ -116,9 +116,8 @@ class MojoShell {
|
||||
if (_shell == null)
|
||||
return null;
|
||||
mojom.ServiceProviderProxy services = new mojom.ServiceProviderProxy.unbound();
|
||||
mojom.ServiceProviderStub exposedServices = new mojom.ServiceProviderStub.unbound();
|
||||
_shell.connectToApplication(url, services, exposedServices);
|
||||
return new ApplicationConnection(exposedServices, services);
|
||||
_shell.connectToApplication(url, services);
|
||||
return new ApplicationConnection(null, services);
|
||||
}
|
||||
|
||||
/// Interceptor for calls to [connectToService] and
|
||||
|
@ -33,8 +33,12 @@ class SystemChrome {
|
||||
///
|
||||
/// boolean indicating if the orientation mask is valid and the changes
|
||||
/// could be conveyed successfully to the embedder.
|
||||
static Future<bool> setPreferredOrientations(int deviceOrientationMask) async {
|
||||
return (await _systemChromeProxy.setPreferredOrientations(deviceOrientationMask)).success;
|
||||
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
|
||||
@ -53,32 +57,12 @@ class SystemChrome {
|
||||
///
|
||||
/// If application-specified metadata is unsupported on the platform,
|
||||
/// specifying it is a no-op and always return true.
|
||||
static Future<bool> setApplicationSwitcherDescription(mojom.ApplicationSwitcherDescription description) async {
|
||||
return (await _systemChromeProxy.setApplicationSwitcherDescription(
|
||||
description)).success;
|
||||
}
|
||||
|
||||
/// Specifies the set of overlays visible on the embedder when the
|
||||
/// application is running. The embedder may choose to ignore unsupported
|
||||
/// overlays
|
||||
///
|
||||
/// Arguments:
|
||||
///
|
||||
/// * [overlaysMask]: A mask of [SystemUIOverlay] enum values that denotes
|
||||
/// the overlays to show.
|
||||
///
|
||||
/// Return Value:
|
||||
///
|
||||
/// boolean indicating if the preference was conveyed successfully to the
|
||||
/// embedder.
|
||||
///
|
||||
/// Platform Specific Notes:
|
||||
///
|
||||
/// If the overlay is unsupported on the platform, enabling or disabling
|
||||
/// that overlay is a no-op and always return true.
|
||||
static Future<bool> setEnabledSystemUIOverlays(int overlaysMask) async {
|
||||
return (await _systemChromeProxy.setEnabledSystemUiOverlays(
|
||||
overlaysMask)).success;
|
||||
static Future<bool> setApplicationSwitcherDescription(mojom.ApplicationSwitcherDescription description) {
|
||||
Completer<bool> completer = new Completer<bool>();
|
||||
_systemChromeProxy.setApplicationSwitcherDescription(description, (bool success) {
|
||||
completer.complete(success);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Specifies the style of the system overlays that are visible on the
|
||||
@ -106,7 +90,9 @@ class SystemChrome {
|
||||
scheduleMicrotask(() {
|
||||
assert(_pendingStyle != null);
|
||||
if (_pendingStyle != _latestStyle) {
|
||||
_systemChromeProxy.setSystemUiOverlayStyle(_pendingStyle);
|
||||
_systemChromeProxy.setSystemUiOverlayStyle(_pendingStyle, (bool success) {
|
||||
// Ignored.
|
||||
});
|
||||
_latestStyle = _pendingStyle;
|
||||
}
|
||||
_pendingStyle = null;
|
||||
|
@ -30,7 +30,11 @@ class SystemSound {
|
||||
/// boolean indicating if the intent to play the specified sound was
|
||||
/// 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) async {
|
||||
return (await _systemChromeProxy.play(type)).success;
|
||||
static Future<bool> play(SystemSoundType type) {
|
||||
Completer<bool> completer = new Completer<bool>();
|
||||
_systemChromeProxy.play(type, (bool success) {
|
||||
completer.complete(success);
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
@ -38,8 +40,10 @@ class MockClipboard extends mojom.ClipboardProxy {
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic getClipboardData(String format,[Function responseFactory = null]) {
|
||||
return new mojom.ClipboardGetClipboardDataResponseParams()..clip = _clip;
|
||||
void getClipboardData(String format, void callback(mojom.ClipboardData clip)) {
|
||||
scheduleMicrotask(() {
|
||||
callback(_clip);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,12 +98,15 @@ class SoundEffectPlayer {
|
||||
int _nextStreamId = 0;
|
||||
|
||||
/// Loads a sound effect.
|
||||
Future<SoundEffect> load(MojoDataPipeConsumer data) async {
|
||||
SoundPoolLoadResponseParams result = await _soundPool.load(data);
|
||||
if (result.success)
|
||||
return new SoundEffect(result.soundId);
|
||||
|
||||
throw new Exception('Unable to load sound');
|
||||
Future<SoundEffect> load(MojoDataPipeConsumer data) {
|
||||
Completer<SoundEffect> completer = new Completer<SoundEffect>();
|
||||
_soundPool.load(data, (bool success, int soundId) {
|
||||
if (success)
|
||||
completer.complete(new SoundEffect(soundId));
|
||||
else
|
||||
completer.completeError(new Exception('Unable to load sound'));
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Plays a sound effect.
|
||||
@ -112,21 +115,26 @@ class SoundEffectPlayer {
|
||||
double rightVolume: 1.0,
|
||||
bool loop: false,
|
||||
double pitch: 1.0
|
||||
}) async {
|
||||
}) {
|
||||
Completer<SoundEffectStream> completer = new Completer<SoundEffectStream>();
|
||||
int streamId = _nextStreamId++;
|
||||
SoundPoolPlayResponseParams result = await _soundPool.play(
|
||||
sound._soundId, streamId, <double>[leftVolume, rightVolume], loop, pitch
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
return new SoundEffectStream(this, streamId,
|
||||
leftVolume: leftVolume,
|
||||
rightVolume: rightVolume,
|
||||
pitch: pitch
|
||||
);
|
||||
}
|
||||
|
||||
throw new Exception('Unable to play sound');
|
||||
_soundPool.play(sound._soundId,
|
||||
streamId,
|
||||
<double>[leftVolume, rightVolume],
|
||||
loop,
|
||||
pitch,
|
||||
(bool success) {
|
||||
if (success) {
|
||||
completer.complete(new SoundEffectStream(this, streamId,
|
||||
leftVolume: leftVolume,
|
||||
rightVolume: rightVolume,
|
||||
pitch: pitch
|
||||
));
|
||||
} else {
|
||||
completer.completeError(new Exception('Unable to play sound'));
|
||||
}
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Set to true to pause a sound effect.
|
||||
@ -203,8 +211,11 @@ class SoundTrackPlayer {
|
||||
soundTrack._player = new MediaPlayerProxy.unbound();
|
||||
_mediaService.createPlayer(soundTrack._player);
|
||||
|
||||
await soundTrack._player.prepare(await pipe);
|
||||
return soundTrack;
|
||||
Completer<SoundTrack> completer = new Completer<SoundTrack>();
|
||||
soundTrack._player.prepare(await pipe, (bool ignored) {
|
||||
completer.complete(soundTrack);
|
||||
});
|
||||
return await completer.future;
|
||||
}
|
||||
|
||||
/// Unloads a [SoundTrack] from memory.
|
||||
|
Loading…
x
Reference in New Issue
Block a user