| 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 define("mojo/public/js/bindings/router", [ | 5 define("mojo/public/js/bindings/router", [ | 
| 6   "mojo/public/js/bindings/codec", | 6   "mojo/public/js/bindings/codec", | 
| 7   "mojo/public/js/bindings/connector", | 7   "mojo/public/js/bindings/connector", | 
| 8   "mojo/public/js/bindings/validator", | 8   "mojo/public/js/bindings/validator", | 
| 9 ], function(codec, connector, validator) { | 9 ], function(codec, connector, validator) { | 
| 10 | 10 | 
| 11   function Router(handle, connectorFactory) { | 11   function Router(handle, connectorFactory) { | 
| 12     if (connectorFactory === undefined) | 12     if (connectorFactory === undefined) | 
| 13       connectorFactory = connector.Connector; | 13       connectorFactory = connector.Connector; | 
| 14     this.connector_ = new connectorFactory(handle); | 14     this.connector_ = new connectorFactory(handle); | 
| 15     this.incomingReceiver_ = null; | 15     this.incomingReceiver_ = null; | 
| 16     this.nextRequestID_ = 0; | 16     this.nextRequestID_ = 0; | 
| 17     this.responders_ = {}; | 17     this.completers_ = new Map(); | 
| 18     this.payloadValidators_ = []; | 18     this.payloadValidators_ = []; | 
| 19 | 19 | 
| 20     this.connector_.setIncomingReceiver({ | 20     this.connector_.setIncomingReceiver({ | 
| 21         accept: this.handleIncomingMessage_.bind(this), | 21         accept: this.handleIncomingMessage_.bind(this), | 
| 22     }); | 22     }); | 
| 23     this.connector_.setErrorHandler({ | 23     this.connector_.setErrorHandler({ | 
| 24         onError: this.handleConnectionError_.bind(this), | 24         onError: this.handleConnectionError_.bind(this), | 
| 25     }); | 25     }); | 
| 26   } | 26   } | 
| 27 | 27 | 
| 28   Router.prototype.close = function() { | 28   Router.prototype.close = function() { | 
| 29     this.responders_ = {};  // Drop any responders. | 29     this.completers_ = null;  // Drop any responders. | 
| 30     this.connector_.close(); | 30     this.connector_.close(); | 
| 31   }; | 31   }; | 
| 32 | 32 | 
| 33   Router.prototype.accept = function(message) { | 33   Router.prototype.accept = function(message) { | 
| 34     this.connector_.accept(message); | 34     this.connector_.accept(message); | 
| 35   }; | 35   }; | 
| 36 | 36 | 
| 37   Router.prototype.reject = function(message) { | 37   Router.prototype.reject = function(message) { | 
| 38     // TODO(mpcomplete): no way to trasmit errors over a Connection. | 38     // TODO(mpcomplete): no way to trasmit errors over a Connection. | 
| 39   }; | 39   }; | 
| 40 | 40 | 
| 41   Router.prototype.acceptWithResponder = function(message, responder) { | 41   Router.prototype.acceptAndExpectResponse = function(message) { | 
| 42     // Reserve 0 in case we want it to convey special meaning in the future. | 42     // Reserve 0 in case we want it to convey special meaning in the future. | 
| 43     var requestID = this.nextRequestID_++; | 43     var requestID = this.nextRequestID_++; | 
| 44     if (requestID == 0) | 44     if (requestID == 0) | 
| 45       requestID = this.nextRequestID_++; | 45       requestID = this.nextRequestID_++; | 
| 46 | 46 | 
| 47     message.setRequestID(requestID); | 47     message.setRequestID(requestID); | 
| 48     var result = this.connector_.accept(message); | 48     var result = this.connector_.accept(message); | 
|  | 49     if (!result) | 
|  | 50       return Promise.reject(Error("Connection error")); | 
| 49 | 51 | 
| 50     this.responders_[requestID] = responder; | 52     var completer = {}; | 
| 51 | 53     this.completers_.set(requestID, completer); | 
| 52     // TODO(mpcomplete): accept should return a Promise too, maybe? | 54     return new Promise(function(resolve, reject) { | 
| 53     if (result) | 55       completer.resolve = resolve; | 
| 54       return Promise.resolve(); | 56       completer.reject = reject; | 
| 55     return Promise.reject(Error("Connection error")); | 57     }); | 
| 56   }; | 58   }; | 
| 57 | 59 | 
| 58   Router.prototype.setIncomingReceiver = function(receiver) { | 60   Router.prototype.setIncomingReceiver = function(receiver) { | 
| 59     this.incomingReceiver_ = receiver; | 61     this.incomingReceiver_ = receiver; | 
| 60   }; | 62   }; | 
| 61 | 63 | 
| 62   Router.prototype.setPayloadValidators = function(payloadValidators) { | 64   Router.prototype.setPayloadValidators = function(payloadValidators) { | 
| 63     this.payloadValidators_ = payloadValidators; | 65     this.payloadValidators_ = payloadValidators; | 
| 64   }; | 66   }; | 
| 65 | 67 | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 85       if (this.incomingReceiver_) { | 87       if (this.incomingReceiver_) { | 
| 86         this.incomingReceiver_.acceptWithResponder(message, this); | 88         this.incomingReceiver_.acceptWithResponder(message, this); | 
| 87       } else { | 89       } else { | 
| 88         // If we receive a request expecting a response when the client is not | 90         // If we receive a request expecting a response when the client is not | 
| 89         // listening, then we have no choice but to tear down the pipe. | 91         // listening, then we have no choice but to tear down the pipe. | 
| 90         this.close(); | 92         this.close(); | 
| 91       } | 93       } | 
| 92     } else if (message.isResponse()) { | 94     } else if (message.isResponse()) { | 
| 93       var reader = new codec.MessageReader(message); | 95       var reader = new codec.MessageReader(message); | 
| 94       var requestID = reader.requestID; | 96       var requestID = reader.requestID; | 
| 95       var responder = this.responders_[requestID]; | 97       var completer = this.completers_.get(requestID); | 
| 96       delete this.responders_[requestID]; | 98       this.completers_.delete(requestID); | 
| 97       responder.accept(message); | 99       completer.resolve(message); | 
| 98     } else { | 100     } else { | 
| 99       if (this.incomingReceiver_) | 101       if (this.incomingReceiver_) | 
| 100         this.incomingReceiver_.accept(message); | 102         this.incomingReceiver_.accept(message); | 
| 101     } | 103     } | 
| 102   } | 104   } | 
| 103 | 105 | 
| 104   Router.prototype.handleInvalidIncomingMessage_ = function(message, error) { | 106   Router.prototype.handleInvalidIncomingMessage_ = function(message, error) { | 
| 105     this.close(); | 107     this.close(); | 
| 106   } | 108   } | 
| 107 | 109 | 
| 108   Router.prototype.handleConnectionError_ = function(result) { | 110   Router.prototype.handleConnectionError_ = function(result) { | 
| 109     for (var each in this.responders_) | 111     this.completers_.forEach(function(value) { | 
| 110       this.responders_[each].reject(result); | 112       value.reject(result); | 
|  | 113     }); | 
| 111     this.close(); | 114     this.close(); | 
| 112   }; | 115   }; | 
| 113 | 116 | 
| 114   // The TestRouter subclass is only intended to be used in unit tests. | 117   // The TestRouter subclass is only intended to be used in unit tests. | 
| 115   // It defeats valid message handling and delgates invalid message handling. | 118   // It defeats valid message handling and delgates invalid message handling. | 
| 116 | 119 | 
| 117   function TestRouter(handle, connectorFactory) { | 120   function TestRouter(handle, connectorFactory) { | 
| 118     Router.call(this, handle, connectorFactory); | 121     Router.call(this, handle, connectorFactory); | 
| 119   } | 122   } | 
| 120 | 123 | 
| 121   TestRouter.prototype = Object.create(Router.prototype); | 124   TestRouter.prototype = Object.create(Router.prototype); | 
| 122 | 125 | 
| 123   TestRouter.prototype.handleValidIncomingMessage_ = function() { | 126   TestRouter.prototype.handleValidIncomingMessage_ = function() { | 
| 124   }; | 127   }; | 
| 125 | 128 | 
| 126   TestRouter.prototype.handleInvalidIncomingMessage_ = | 129   TestRouter.prototype.handleInvalidIncomingMessage_ = | 
| 127       function(message, error) { | 130       function(message, error) { | 
| 128         this.validationErrorHandler(error); | 131         this.validationErrorHandler(error); | 
| 129       }; | 132       }; | 
| 130 | 133 | 
| 131   var exports = {}; | 134   var exports = {}; | 
| 132   exports.Router = Router; | 135   exports.Router = Router; | 
| 133   exports.TestRouter = TestRouter; | 136   exports.TestRouter = TestRouter; | 
| 134   return exports; | 137   return exports; | 
| 135 }); | 138 }); | 
| OLD | NEW | 
|---|