| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:isolate'; |
| import 'dart:typed_data'; |
| import 'mojo:bindings' as bindings; |
| import 'mojo:core' as core; |
| |
| import 'package:mojo/dart/testing/expect.dart'; |
| |
| const int kEchoesCount = 100; |
| |
| class EchoString extends bindings.Struct { |
| static const int kStructSize = 16; |
| static const bindings.StructDataHeader kDefaultStructInfo = |
| const bindings.StructDataHeader(kStructSize, 1); |
| String a = null; |
| |
| EchoString() : super(kStructSize); |
| |
| static EchoString deserialize(bindings.Message message) { |
| return decode(new bindings.Decoder(message)); |
| } |
| |
| static EchoString decode(bindings.Decoder decoder0) { |
| if (decoder0 == null) { |
| return null; |
| } |
| EchoString result = new EchoString(); |
| var mainDataHeader = decoder0.decodeStructDataHeader(); |
| if (mainDataHeader.version > 0) { |
| result.a = decoder0.decodeString(8, false); |
| } |
| return result; |
| } |
| |
| void encode(bindings.Encoder encoder) { |
| var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo); |
| encoder0.encodeString(a, 8, false); |
| } |
| } |
| |
| |
| class EchoStringResponse extends bindings.Struct { |
| static const int kStructSize = 16; |
| static const bindings.StructDataHeader kDefaultStructInfo = |
| const bindings.StructDataHeader(kStructSize, 1); |
| String a = null; |
| |
| EchoStringResponse() : super(kStructSize); |
| |
| static EchoStringResponse deserialize(bindings.Message message) { |
| return decode(new bindings.Decoder(message)); |
| } |
| |
| static EchoStringResponse decode(bindings.Decoder decoder0) { |
| if (decoder0 == null) { |
| return null; |
| } |
| EchoStringResponse result = new EchoStringResponse(); |
| var mainDataHeader = decoder0.decodeStructDataHeader(); |
| if (mainDataHeader.version > 0) { |
| result.a = decoder0.decodeString(8, false); |
| } |
| return result; |
| } |
| |
| void encode(bindings.Encoder encoder) { |
| var encoder0 = encoder.getStructEncoderAtOffset(kDefaultStructInfo); |
| encoder0.encodeString(a, 8, false); |
| } |
| } |
| |
| |
| const int kEchoString_name = 0; |
| const int kEchoStringResponse_name = 1; |
| |
| class EchoStub extends bindings.Stub { |
| EchoStub(core.MojoMessagePipeEndpoint endpoint) : super(endpoint); |
| |
| Future<EchoStringResponse> echoString(EchoString es) { |
| var response = new EchoStringResponse(); |
| response.a = es.a; |
| return new Future.value(response); |
| } |
| |
| Future<bindings.Message> handleMessage(bindings.ServiceMessage message) { |
| switch (message.header.type) { |
| case kEchoString_name: |
| var es = EchoString.deserialize(message.payload); |
| return echoString(es).then((response) { |
| if (response != null) { |
| return buildResponseWithId( |
| response, |
| kEchoStringResponse_name, |
| message.header.requestId, |
| bindings.MessageHeader.kMessageIsResponse); |
| } |
| }); |
| break; |
| default: |
| throw new Exception("Unexpected case"); |
| break; |
| } |
| return null; |
| } |
| } |
| |
| |
| class EchoProxy extends bindings.Proxy { |
| EchoProxy(core.MojoMessagePipeEndpoint endpoint) : super(endpoint); |
| |
| Future<EchoStringResponse> echoString(String a) { |
| // compose message. |
| var es = new EchoString(); |
| es.a = a; |
| return sendMessageWithRequestId( |
| es, |
| kEchoString_name, |
| -1, |
| bindings.MessageHeader.kMessageExpectsResponse); |
| } |
| |
| void handleResponse(bindings.ServiceMessage message) { |
| switch (message.header.type) { |
| case kEchoStringResponse_name: |
| var esr = EchoStringResponse.deserialize(message.payload); |
| Completer c = completerMap[message.header.requestId]; |
| completerMap[message.header.requestId] = null; |
| c.complete(esr); |
| break; |
| default: |
| throw new Exception("Unexpected case"); |
| break; |
| } |
| } |
| } |
| |
| |
| void providerIsolate(core.MojoMessagePipeEndpoint endpoint) { |
| var provider = new EchoStub(endpoint); |
| provider.listen(); |
| } |
| |
| |
| Future<int> runTest() async { |
| var testCompleter = new Completer(); |
| |
| var pipe = new core.MojoMessagePipe(); |
| var proxy = new EchoProxy(pipe.endpoints[0]); |
| await Isolate.spawn(providerIsolate, pipe.endpoints[1]); |
| |
| int n = kEchoesCount; |
| int count = 0; |
| for (int i = 0; i < n; i++) { |
| proxy.echoString("hello").then((response) { |
| Expect.equals("hello", response.a); |
| count++; |
| if (i == (n - 1)) { |
| proxy.close(); |
| testCompleter.complete(count); |
| } |
| }); |
| } |
| |
| return testCompleter.future; |
| } |
| |
| |
| Future runAwaitTest() async { |
| var pipe = new core.MojoMessagePipe(); |
| var proxy = new EchoProxy(pipe.endpoints[0]); |
| await Isolate.spawn(providerIsolate, pipe.endpoints[1]); |
| |
| int n = kEchoesCount; |
| for (int i = 0; i < n; i++) { |
| var response = await proxy.echoString("Hello"); |
| Expect.equals("Hello", response.a); |
| } |
| proxy.close(); |
| } |
| |
| |
| void closingProviderIsolate(core.MojoMessagePipeEndpoint endpoint) { |
| var provider = new EchoStub(endpoint); |
| provider.close(); |
| } |
| |
| |
| Future<bool> runOnClosedTest() async { |
| var testCompleter = new Completer(); |
| |
| var pipe = new core.MojoMessagePipe(); |
| var proxy = new EchoProxy(pipe.endpoints[0]); |
| await Isolate.spawn(closingProviderIsolate, pipe.endpoints[1]); |
| proxy.listen(onClosed: () { |
| testCompleter.complete(true); |
| }); |
| |
| return testCompleter.future.timeout( |
| new Duration(seconds: 1), |
| onTimeout: () => false); |
| } |
| |
| |
| main() async { |
| Expect.equals(kEchoesCount, await runTest()); |
| await runAwaitTest(); |
| Expect.isTrue(await runOnClosedTest()); |
| } |