| Index: third_party/mojo/src/mojo/public/dart/lib/src/proxy.dart
|
| diff --git a/third_party/mojo/src/mojo/public/dart/src/proxy.dart b/third_party/mojo/src/mojo/public/dart/lib/src/proxy.dart
|
| similarity index 55%
|
| rename from third_party/mojo/src/mojo/public/dart/src/proxy.dart
|
| rename to third_party/mojo/src/mojo/public/dart/lib/src/proxy.dart
|
| index 863e734d8df5f301078154f2c01cf4312f9ffa49..528e13a1d9c55b9a00bfeb9ddd31bdb7a22c605c 100644
|
| --- a/third_party/mojo/src/mojo/public/dart/src/proxy.dart
|
| +++ b/third_party/mojo/src/mojo/public/dart/lib/src/proxy.dart
|
| @@ -13,6 +13,10 @@ class ProxyCloseException {
|
| abstract class Proxy extends core.MojoEventStreamListener {
|
| Map<int, Completer> _completerMap;
|
| int _nextId = 0;
|
| + int _version = 0;
|
| + /// Version of this interface that the remote side supports. Updated when a
|
| + /// call to [queryVersion] or [requireVersion] is made.
|
| + int get version => _version;
|
|
|
| Proxy.fromEndpoint(core.MojoMessagePipeEndpoint endpoint)
|
| : _completerMap = {},
|
| @@ -39,6 +43,10 @@ abstract class Proxy extends core.MojoEventStreamListener {
|
| result = endpoint.read(bytes, result.bytesRead, handles);
|
| assert(result.status.isOk || result.status.isResourceExhausted);
|
| var message = new ServiceMessage.fromMessage(new Message(bytes, handles));
|
| + if (ControlMessageHandler.isControlMessage(message)) {
|
| + _handleControlMessageResponse(message);
|
| + return;
|
| + }
|
| handleResponse(message);
|
| }
|
|
|
| @@ -96,6 +104,63 @@ abstract class Proxy extends core.MojoEventStreamListener {
|
| var superString = super.toString();
|
| return "Proxy(${superString})";
|
| }
|
| +
|
| + /// Queries the max version that the remote side supports.
|
| + /// Updates [version].
|
| + Future<int> queryVersion() async {
|
| + var params = new icm.RunMessageParams();
|
| + params.reserved0 = 16;
|
| + params.reserved1 = 0;
|
| + params.queryVersion = new icm.QueryVersion();
|
| + var response = await
|
| + sendMessageWithRequestId(params,
|
| + icm.kRunMessageId,
|
| + -1,
|
| + MessageHeader.kMessageExpectsResponse);
|
| + _version = response.queryVersionResult.version;
|
| + return _version;
|
| + }
|
| +
|
| + /// If the remote side doesn't support the [requiredVersion], it will close
|
| + /// its end of the message pipe asynchronously. This does nothing if it's
|
| + /// already known that the remote side supports [requiredVersion].
|
| + /// Updates [version].
|
| + void requireVersion(int requiredVersion) {
|
| + if (requiredVersion <= _version) {
|
| + // Already supported.
|
| + return;
|
| + }
|
| +
|
| + // If the remote end doesn't close the pipe, we know that it supports
|
| + // required version.
|
| + _version = requiredVersion;
|
| +
|
| + var params = new icm.RunOrClosePipeMessageParams();
|
| + params.reserved0 = 16;
|
| + params.reserved1 = 0;
|
| + params.requireVersion = new icm.RequireVersion();
|
| + params.requireVersion.version = requiredVersion;
|
| + // TODO(johnmccutchan): We've set _version above but if this sendMessage
|
| + // throws an exception we may not have sent the RunOrClose message. Should
|
| + // we reset _version in that case?
|
| + sendMessage(params, icm.kRunOrClosePipeMessageId);
|
| + }
|
| +
|
| + _handleControlMessageResponse(ServiceMessage message) {
|
| + // We only expect to see Run messages.
|
| + assert(message.header.type == icm.kRunMessageId);
|
| + var response = icm.RunResponseMessageParams.deserialize(message.payload);
|
| + if (!message.header.hasRequestId) {
|
| + throw 'Expected a message with a valid request Id.';
|
| + }
|
| + Completer c = completerMap[message.header.requestId];
|
| + if (c == null) {
|
| + throw 'Message had unknown request Id: ${message.header.requestId}';
|
| + }
|
| + completerMap.remove(message.header.requestId);
|
| + assert(!c.isCompleted);
|
| + c.complete(response);
|
| + }
|
| }
|
|
|
| // Generated Proxy classes implement this interface.
|
|
|