• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 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
5define('mojo/edk/js/tests/js_to_cpp_tests', [
6  'console',
7  'mojo/edk/js/tests/js_to_cpp.mojom',
8  'mojo/public/js/bindings',
9  'mojo/public/js/connector',
10  'mojo/public/js/core',
11], function (console, jsToCpp, bindings, connector, core) {
12  var retainedJsSide;
13  var retainedJsSideStub;
14  var sampleData;
15  var sampleMessage;
16  var BAD_VALUE = 13;
17  var DATA_PIPE_PARAMS = {
18    flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
19    elementNumBytes: 1,
20    capacityNumBytes: 64
21  };
22
23  function JsSideConnection() {
24    this.binding = new bindings.Binding(jsToCpp.JsSide, this);
25  }
26
27  JsSideConnection.prototype.setCppSide = function(cppSide) {
28    this.cppSide_ = cppSide;
29    this.cppSide_.startTest();
30  };
31
32  JsSideConnection.prototype.ping = function (arg) {
33    this.cppSide_.pingResponse();
34  };
35
36  JsSideConnection.prototype.echo = function (numIterations, arg) {
37    var dataPipe1;
38    var dataPipe2;
39    var i;
40    var messagePipe1;
41    var messagePipe2;
42    var specialArg;
43
44    // Ensure expected negative values are negative.
45    if (arg.si64 > 0)
46      arg.si64 = BAD_VALUE;
47
48    if (arg.si32 > 0)
49      arg.si32 = BAD_VALUE;
50
51    if (arg.si16 > 0)
52      arg.si16 = BAD_VALUE;
53
54    if (arg.si8 > 0)
55      arg.si8 = BAD_VALUE;
56
57    for (i = 0; i < numIterations; ++i) {
58      dataPipe1 = core.createDataPipe(DATA_PIPE_PARAMS);
59      dataPipe2 = core.createDataPipe(DATA_PIPE_PARAMS);
60      messagePipe1 = core.createMessagePipe();
61      messagePipe2 = core.createMessagePipe();
62
63      arg.data_handle = dataPipe1.consumerHandle;
64      arg.message_handle = messagePipe1.handle1;
65
66      specialArg = new jsToCpp.EchoArgs();
67      specialArg.si64 = -1;
68      specialArg.si32 = -1;
69      specialArg.si16 = -1;
70      specialArg.si8 = -1;
71      specialArg.name = 'going';
72      specialArg.data_handle = dataPipe2.consumerHandle;
73      specialArg.message_handle = messagePipe2.handle1;
74
75      writeDataPipe(dataPipe1, sampleData);
76      writeDataPipe(dataPipe2, sampleData);
77      writeMessagePipe(messagePipe1, sampleMessage);
78      writeMessagePipe(messagePipe2, sampleMessage);
79
80      this.cppSide_.echoResponse(createEchoArgsList(specialArg, arg));
81
82      core.close(dataPipe1.producerHandle);
83      core.close(dataPipe2.producerHandle);
84      core.close(messagePipe1.handle0);
85      core.close(messagePipe2.handle0);
86    }
87    this.cppSide_.testFinished();
88  };
89
90  JsSideConnection.prototype.bitFlip = function (arg) {
91    var iteration = 0;
92    var dataPipe;
93    var messagePipe;
94    var proto = connector.Connector.prototype;
95    var stopSignalled = false;
96
97    proto.realAccept = proto.accept;
98    proto.accept = function (message) {
99      var offset = iteration / 8;
100      var mask;
101      var value;
102      if (offset < message.buffer.arrayBuffer.byteLength) {
103        mask = 1 << (iteration % 8);
104        value = message.buffer.getUint8(offset) ^ mask;
105        message.buffer.setUint8(offset, value);
106        return this.realAccept(message);
107      }
108      stopSignalled = true;
109      return false;
110    };
111
112    while (!stopSignalled) {
113      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
114      messagePipe = core.createMessagePipe();
115      writeDataPipe(dataPipe, sampleData);
116      writeMessagePipe(messagePipe, sampleMessage);
117      arg.data_handle = dataPipe.consumerHandle;
118      arg.message_handle = messagePipe.handle1;
119
120      this.cppSide_.bitFlipResponse(createEchoArgsList(arg));
121
122      core.close(dataPipe.producerHandle);
123      core.close(messagePipe.handle0);
124      iteration += 1;
125    }
126
127    proto.accept = proto.realAccept;
128    proto.realAccept = null;
129    this.cppSide_.testFinished();
130  };
131
132  JsSideConnection.prototype.backPointer = function (arg) {
133    var iteration = 0;
134    var dataPipe;
135    var messagePipe;
136    var proto = connector.Connector.prototype;
137    var stopSignalled = false;
138
139    proto.realAccept = proto.accept;
140    proto.accept = function (message) {
141      var delta = 8 * (1 + iteration % 32);
142      var offset = 8 * ((iteration / 32) | 0);
143      if (offset < message.buffer.arrayBuffer.byteLength - 4) {
144        message.buffer.dataView.setUint32(offset, 0x100000000 - delta, true);
145        message.buffer.dataView.setUint32(offset + 4, 0xffffffff, true);
146        return this.realAccept(message);
147      }
148      stopSignalled = true;
149      return false;
150    };
151
152    while (!stopSignalled) {
153      dataPipe = core.createDataPipe(DATA_PIPE_PARAMS);
154      messagePipe = core.createMessagePipe();
155      writeDataPipe(dataPipe, sampleData);
156      writeMessagePipe(messagePipe, sampleMessage);
157      arg.data_handle = dataPipe.consumerHandle;
158      arg.message_handle = messagePipe.handle1;
159
160      this.cppSide_.backPointerResponse(createEchoArgsList(arg));
161
162      core.close(dataPipe.producerHandle);
163      core.close(messagePipe.handle0);
164      iteration += 1;
165    }
166
167    proto.accept = proto.realAccept;
168    proto.realAccept = null;
169    this.cppSide_.testFinished();
170  };
171
172  function writeDataPipe(pipe, data) {
173    var writeResult = core.writeData(
174      pipe.producerHandle, data, core.WRITE_DATA_FLAG_ALL_OR_NONE);
175
176    if (writeResult.result != core.RESULT_OK) {
177      console.log('ERROR: Data pipe write result was ' + writeResult.result);
178      return false;
179    }
180    if (writeResult.numBytes != data.length) {
181      console.log('ERROR: Data pipe write length was ' + writeResult.numBytes);
182      return false;
183    }
184    return true;
185  }
186
187  function writeMessagePipe(pipe, arrayBuffer) {
188    var result = core.writeMessage(pipe.handle0, arrayBuffer, [], 0);
189    if (result != core.RESULT_OK) {
190      console.log('ERROR: Message pipe write result was ' + result);
191      return false;
192    }
193    return true;
194  }
195
196  function createEchoArgsListElement(item, next) {
197    var list = new jsToCpp.EchoArgsList();
198    list.item = item;
199    list.next = next;
200    return list;
201  }
202
203  function createEchoArgsList() {
204    var genuineArray = Array.prototype.slice.call(arguments);
205    return genuineArray.reduceRight(function (previous, current) {
206      return createEchoArgsListElement(current, previous);
207    }, null);
208  }
209
210  return function(jsSideRequestHandle) {
211    var i;
212    sampleData = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
213    for (i = 0; i < sampleData.length; ++i) {
214      sampleData[i] = i;
215    }
216    sampleMessage = new Uint8Array(DATA_PIPE_PARAMS.capacityNumBytes);
217    for (i = 0; i < sampleMessage.length; ++i) {
218      sampleMessage[i] = 255 - i;
219    }
220    retainedJsSide = new JsSideConnection;
221    retainedJsSide.binding.bind(jsSideRequestHandle);
222  };
223});
224