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