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