• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:typed_data';
7import 'package:flutter/services.dart';
8import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
9import 'pair.dart';
10import 'test_step.dart';
11
12class ExtendedStandardMessageCodec extends StandardMessageCodec {
13  const ExtendedStandardMessageCodec();
14
15  static const int _dateTime = 128;
16  static const int _pair = 129;
17
18  @override
19  void writeValue(WriteBuffer buffer, dynamic value) {
20    if (value is DateTime) {
21      buffer.putUint8(_dateTime);
22      buffer.putInt64(value.millisecondsSinceEpoch);
23    } else if (value is Pair) {
24      buffer.putUint8(_pair);
25      writeValue(buffer, value.left);
26      writeValue(buffer, value.right);
27    } else {
28      super.writeValue(buffer, value);
29    }
30  }
31
32  @override
33  dynamic readValueOfType(int type, ReadBuffer buffer) {
34    switch (type) {
35    case _dateTime:
36      return DateTime.fromMillisecondsSinceEpoch(buffer.getInt64());
37    case _pair:
38      return Pair(readValue(buffer), readValue(buffer));
39    default: return super.readValueOfType(type, buffer);
40    }
41  }
42}
43
44Future<TestStepResult> basicBinaryHandshake(ByteData message) async {
45  const BasicMessageChannel<ByteData> channel =
46      BasicMessageChannel<ByteData>(
47    'binary-msg',
48    BinaryCodec(),
49  );
50  return _basicMessageHandshake<ByteData>(
51      'Binary >${toString(message)}<', channel, message);
52}
53
54Future<TestStepResult> basicStringHandshake(String message) async {
55  const BasicMessageChannel<String> channel = BasicMessageChannel<String>(
56    'string-msg',
57    StringCodec(),
58  );
59  return _basicMessageHandshake<String>('String >$message<', channel, message);
60}
61
62Future<TestStepResult> basicJsonHandshake(dynamic message) async {
63  const BasicMessageChannel<dynamic> channel =
64      BasicMessageChannel<dynamic>(
65    'json-msg',
66    JSONMessageCodec(),
67  );
68  return _basicMessageHandshake<dynamic>('JSON >$message<', channel, message);
69}
70
71Future<TestStepResult> basicStandardHandshake(dynamic message) async {
72  const BasicMessageChannel<dynamic> channel =
73      BasicMessageChannel<dynamic>(
74    'std-msg',
75    ExtendedStandardMessageCodec(),
76  );
77  return _basicMessageHandshake<dynamic>(
78      'Standard >${toString(message)}<', channel, message);
79}
80
81Future<TestStepResult> basicBinaryMessageToUnknownChannel() async {
82  const BasicMessageChannel<ByteData> channel =
83      BasicMessageChannel<ByteData>(
84    'binary-unknown',
85    BinaryCodec(),
86  );
87  return _basicMessageToUnknownChannel<ByteData>('Binary', channel);
88}
89
90Future<TestStepResult> basicStringMessageToUnknownChannel() async {
91  const BasicMessageChannel<String> channel = BasicMessageChannel<String>(
92    'string-unknown',
93    StringCodec(),
94  );
95  return _basicMessageToUnknownChannel<String>('String', channel);
96}
97
98Future<TestStepResult> basicJsonMessageToUnknownChannel() async {
99  const BasicMessageChannel<dynamic> channel =
100      BasicMessageChannel<dynamic>(
101    'json-unknown',
102    JSONMessageCodec(),
103  );
104  return _basicMessageToUnknownChannel<dynamic>('JSON', channel);
105}
106
107Future<TestStepResult> basicStandardMessageToUnknownChannel() async {
108  const BasicMessageChannel<dynamic> channel =
109      BasicMessageChannel<dynamic>(
110    'std-unknown',
111    ExtendedStandardMessageCodec(),
112  );
113  return _basicMessageToUnknownChannel<dynamic>('Standard', channel);
114}
115
116/// Sends the specified message to the platform, doing a
117/// receive message/send reply/receive reply echo handshake initiated by the
118/// platform, then expecting a reply echo to the original message.
119///
120/// Fails, if an error occurs, or if any message seen is not deeply equal to
121/// the original message.
122Future<TestStepResult> _basicMessageHandshake<T>(
123  String description,
124  BasicMessageChannel<T> channel,
125  T message,
126) async {
127  final List<dynamic> received = <dynamic>[];
128  channel.setMessageHandler((T message) async {
129    received.add(message);
130    return message;
131  });
132  dynamic messageEcho = nothing;
133  dynamic error = nothing;
134  try {
135    messageEcho = await channel.send(message);
136  } catch (e) {
137    error = e;
138  }
139  return resultOfHandshake(
140    'Basic message handshake',
141    description,
142    message,
143    received,
144    messageEcho,
145    error,
146  );
147}
148
149/// Sends a message on a channel that no one listens on.
150Future<TestStepResult> _basicMessageToUnknownChannel<T>(
151  String description,
152  BasicMessageChannel<T> channel,
153) async {
154  dynamic messageEcho = nothing;
155  dynamic error = nothing;
156  try {
157    messageEcho = await channel.send(null);
158  } catch (e) {
159    error = e;
160  }
161  return resultOfHandshake(
162    'Message on unknown channel',
163    description,
164    null,
165    <dynamic>[null, null],
166    messageEcho,
167    error,
168  );
169}
170
171String toString(dynamic message) {
172  if (message is ByteData)
173    return message.buffer
174        .asUint8List(message.offsetInBytes, message.lengthInBytes)
175        .toString();
176  else
177    return '$message';
178}
179