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 5 define('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