OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // chrome.runtime.messaging API implementation. | 5 // chrome.runtime.messaging API implementation. |
6 // TODO(robwu): Fix this indentation. | 6 // TODO(robwu): Fix this indentation. |
7 | 7 |
8 // TODO(kalman): factor requiring chrome out of here. | 8 // TODO(kalman): factor requiring chrome out of here. |
9 var chrome = requireNative('chrome').GetChrome(); | 9 var chrome = requireNative('chrome').GetChrome(); |
10 var lastError = require('lastError'); | |
11 var logActivity = requireNative('activityLogger'); | 10 var logActivity = requireNative('activityLogger'); |
12 var logging = requireNative('logging'); | 11 var logging = requireNative('logging'); |
13 var messagingNatives = requireNative('messaging_natives'); | 12 var messagingNatives = requireNative('messaging_natives'); |
14 var processNatives = requireNative('process'); | 13 var processNatives = requireNative('process'); |
15 var utils = require('utils'); | 14 var utils = require('utils'); |
16 var messagingUtils = require('messaging_utils'); | 15 var messagingUtils = require('messaging_utils'); |
17 | 16 |
18 // The reserved channel name for the sendRequest/send(Native)Message APIs. | 17 // The reserved channel name for the sendRequest/send(Native)Message APIs. |
19 // Note: sendRequest is deprecated. | 18 // Note: sendRequest is deprecated. |
20 var kRequestChannel = "chrome.extension.sendRequest"; | 19 var kRequestChannel = "chrome.extension.sendRequest"; |
(...skipping 18 matching lines...) Expand all Loading... |
39 return new jsEvent(undefined, schema, options); | 38 return new jsEvent(undefined, schema, options); |
40 } | 39 } |
41 | 40 |
42 function invalidateEvent(event) { | 41 function invalidateEvent(event) { |
43 if (bindingUtil) | 42 if (bindingUtil) |
44 bindingUtil.invalidateEvent(event); | 43 bindingUtil.invalidateEvent(event); |
45 else | 44 else |
46 privates(event).impl.destroy_(); | 45 privates(event).impl.destroy_(); |
47 } | 46 } |
48 | 47 |
| 48 var jsLastError = bindingUtil ? undefined : require('lastError'); |
| 49 function setLastError(name, error) { |
| 50 if (bindingUtil) |
| 51 bindingUtil.setLastError(error); |
| 52 else |
| 53 jsLastError.set(name, error, null, chrome); |
| 54 } |
| 55 |
| 56 function clearLastError() { |
| 57 if (bindingUtil) |
| 58 bindingUtil.clearLastError(); |
| 59 else |
| 60 jsLastError.clear(chrome); |
| 61 } |
| 62 |
| 63 function hasLastError() { |
| 64 if (bindingUtil) |
| 65 return bindingUtil.hasLastError(); |
| 66 else |
| 67 return jsLastError.hasError(chrome); |
| 68 } |
| 69 |
49 // Map of port IDs to port object. | 70 // Map of port IDs to port object. |
50 var ports = {__proto__: null}; | 71 var ports = {__proto__: null}; |
51 | 72 |
52 // Port object. Represents a connection to another script context through | 73 // Port object. Represents a connection to another script context through |
53 // which messages can be passed. | 74 // which messages can be passed. |
54 function PortImpl(portId, opt_name) { | 75 function PortImpl(portId, opt_name) { |
55 this.portId_ = portId; | 76 this.portId_ = portId; |
56 this.name = opt_name; | 77 this.name = opt_name; |
57 | 78 |
58 // Note: Keep these schemas in sync with the documentation in runtime.json | 79 // Note: Keep these schemas in sync with the documentation in runtime.json |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 errorMsg = | 166 errorMsg = |
146 'Cannot send a response more than once per chrome.' + eventName + | 167 'Cannot send a response more than once per chrome.' + eventName + |
147 ' listener per document'; | 168 ' listener per document'; |
148 } | 169 } |
149 errorMsg += ' (message was sent by extension' + sourceExtensionId; | 170 errorMsg += ' (message was sent by extension' + sourceExtensionId; |
150 if (sourceExtensionId && sourceExtensionId !== targetExtensionId) | 171 if (sourceExtensionId && sourceExtensionId !== targetExtensionId) |
151 errorMsg += ' for extension ' + targetExtensionId; | 172 errorMsg += ' for extension ' + targetExtensionId; |
152 if (sourceUrl) | 173 if (sourceUrl) |
153 errorMsg += ' for URL ' + sourceUrl; | 174 errorMsg += ' for URL ' + sourceUrl; |
154 errorMsg += ').'; | 175 errorMsg += ').'; |
155 lastError.set(eventName, errorMsg, null, chrome); | 176 setLastError(eventName, errorMsg); |
156 } | 177 } |
157 | 178 |
158 // Helper function for dispatchOnConnect | 179 // Helper function for dispatchOnConnect |
159 function dispatchOnRequest(portId, channelName, sender, | 180 function dispatchOnRequest(portId, channelName, sender, |
160 sourceExtensionId, targetExtensionId, sourceUrl, | 181 sourceExtensionId, targetExtensionId, sourceUrl, |
161 isExternal) { | 182 isExternal) { |
162 var isSendMessage = channelName == kMessageChannel; | 183 var isSendMessage = channelName == kMessageChannel; |
163 var requestEvent = null; | 184 var requestEvent = null; |
164 if (isSendMessage) { | 185 if (isSendMessage) { |
165 if (chrome.runtime) { | 186 if (chrome.runtime) { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 [sourceExtensionId]); | 362 [sourceExtensionId]); |
342 return true; | 363 return true; |
343 }; | 364 }; |
344 | 365 |
345 // Called by native code when a channel has been closed. | 366 // Called by native code when a channel has been closed. |
346 function dispatchOnDisconnect(portId, errorMessage) { | 367 function dispatchOnDisconnect(portId, errorMessage) { |
347 var port = ports[portId]; | 368 var port = ports[portId]; |
348 if (port) { | 369 if (port) { |
349 delete ports[portId]; | 370 delete ports[portId]; |
350 if (errorMessage) | 371 if (errorMessage) |
351 lastError.set('Port', errorMessage, null, chrome); | 372 setLastError('Port', errorMessage); |
352 try { | 373 try { |
353 port.onDisconnect.dispatch(port); | 374 port.onDisconnect.dispatch(port); |
354 } finally { | 375 } finally { |
355 privates(port).impl.destroy_(); | 376 privates(port).impl.destroy_(); |
356 lastError.clear(chrome); | 377 clearLastError(); |
357 } | 378 } |
358 } | 379 } |
359 }; | 380 }; |
360 | 381 |
361 // Called by native code when a message has been sent to the given port. | 382 // Called by native code when a message has been sent to the given port. |
362 function dispatchOnMessage(msg, portId) { | 383 function dispatchOnMessage(msg, portId) { |
363 var port = ports[portId]; | 384 var port = ports[portId]; |
364 if (port) { | 385 if (port) { |
365 if (msg) | 386 if (msg) |
366 msg = $JSON.parse(msg); | 387 msg = $JSON.parse(msg); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 // Note: make sure to manually remove the onMessage/onDisconnect listeners | 420 // Note: make sure to manually remove the onMessage/onDisconnect listeners |
400 // that we added before destroying the Port, a workaround to a bug in Port | 421 // that we added before destroying the Port, a workaround to a bug in Port |
401 // where any onMessage/onDisconnect listeners added but not removed will | 422 // where any onMessage/onDisconnect listeners added but not removed will |
402 // be leaked when the Port is destroyed. | 423 // be leaked when the Port is destroyed. |
403 // http://crbug.com/320723 tracks a sustainable fix. | 424 // http://crbug.com/320723 tracks a sustainable fix. |
404 | 425 |
405 function disconnectListener() { | 426 function disconnectListener() { |
406 if (!responseCallback) | 427 if (!responseCallback) |
407 return; | 428 return; |
408 | 429 |
409 if (lastError.hasError(chrome)) { | 430 if (hasLastError()) { |
410 sendResponseAndClearCallback(); | 431 sendResponseAndClearCallback(); |
411 } else { | 432 } else { |
412 lastError.set( | 433 setLastError( |
413 port.name, | 434 port.name, |
414 'The message port closed before a response was received.', null, | 435 'The message port closed before a response was received.'); |
415 chrome); | |
416 try { | 436 try { |
417 sendResponseAndClearCallback(); | 437 sendResponseAndClearCallback(); |
418 } finally { | 438 } finally { |
419 lastError.clear(chrome); | 439 clearLastError(); |
420 } | 440 } |
421 } | 441 } |
422 } | 442 } |
423 | 443 |
424 function messageListener(response) { | 444 function messageListener(response) { |
425 try { | 445 try { |
426 if (responseCallback) | 446 if (responseCallback) |
427 sendResponseAndClearCallback(response); | 447 sendResponseAndClearCallback(response); |
428 } finally { | 448 } finally { |
429 port.disconnect(); | 449 port.disconnect(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 exports.$set('kNativeMessageChannel', kNativeMessageChannel); | 484 exports.$set('kNativeMessageChannel', kNativeMessageChannel); |
465 exports.$set('Port', Port); | 485 exports.$set('Port', Port); |
466 exports.$set('createPort', createPort); | 486 exports.$set('createPort', createPort); |
467 exports.$set('sendMessageImpl', sendMessageImpl); | 487 exports.$set('sendMessageImpl', sendMessageImpl); |
468 exports.$set('sendMessageUpdateArguments', sendMessageUpdateArguments); | 488 exports.$set('sendMessageUpdateArguments', sendMessageUpdateArguments); |
469 | 489 |
470 // For C++ code to call. | 490 // For C++ code to call. |
471 exports.$set('dispatchOnConnect', dispatchOnConnect); | 491 exports.$set('dispatchOnConnect', dispatchOnConnect); |
472 exports.$set('dispatchOnDisconnect', dispatchOnDisconnect); | 492 exports.$set('dispatchOnDisconnect', dispatchOnDisconnect); |
473 exports.$set('dispatchOnMessage', dispatchOnMessage); | 493 exports.$set('dispatchOnMessage', dispatchOnMessage); |
OLD | NEW |