Add a Notification Settings Button to all web notifications behind the web platform...
[chromium-blink-merge.git] / remoting / webapp / base / js / tcp_socket.js
blobe4877a5d1bdb82052b1561f3c59816fe887573cf
1 // Copyright 2015 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.
5 'use strict';
7 /** @suppress {duplicate} */
8 var remoting = remoting || {};
10 (function() {
12 /** @type {Object<number, remoting.TcpSocket>} */
13 var sockets = {};
14 var receiveListenersAdded = false;
16 function addReceiveListeners() {
17 if (receiveListenersAdded) {
18 return;
21 receiveListenersAdded = true;
23 chrome.sockets.tcp.onReceive.addListener(function(
24 /** chrome.sockets.tcp.ReceiveEventData */ info) {
25 var socket = sockets[info.socketId];
26 if (socket === undefined) {
27 console.warn("Received data for unknown socket " + info.socketId);
28 return;
30 if (socket.receiveCallback_ === null) {
31 console.warn("Received data when socket was paused.");
32 return;
34 socket.receiveCallback_(info.data);
35 });
37 chrome.sockets.tcp.onReceiveError.addListener(function(
38 /** chrome.sockets.tcp.ReceiveErrorEventData */ info) {
39 var socket = sockets[info.socketId];
40 if (socket === undefined) {
41 console.warn("Received error for unknown socket " + info.socketId);
42 return;
44 if (socket.receiveErrorCallback_ === null) {
45 console.warn("Recv() failed when socket was paused: " + info.resultCode);
46 return;
48 socket.receiveErrorCallback_(info.resultCode);
49 });
52 /**
53 * Wrapper for chrome.sockets.tcp API.
55 * @constructor
56 * @implements {base.Disposable}
58 remoting.TcpSocket = function() {
59 /** @private */
60 this.destroyed_ = false;
61 /** @private */
62 this.socketId_ = -1;
63 /** @private {?function(ArrayBuffer):void} */
64 this.receiveCallback_ = null;
65 /** @private {?function(number):void} */
66 this.receiveErrorCallback_ = null;
68 addReceiveListeners();
71 /**
72 * Connects the socket to the specified host and port.
74 * @returns {Promise} Promise that's resolved when the socket is connected.
76 remoting.TcpSocket.prototype.connect = function(/** string */ host,
77 /** number */ port) {
78 var that = this;
80 return new Promise(function(resolve, reject) {
81 chrome.sockets.tcp.create({}, /** @type {function(Object)} */ (onCreated));
84 function onCreated(/** chrome.socket.CreateInfo */ createInfo) {
85 // Check if the socket was destroyed.
86 if (that.destroyed_) {
87 chrome.sockets.tcp.close(createInfo.socketId);
88 return;
91 that.socketId_ = createInfo.socketId;
92 sockets[that.socketId_] = that;
94 // Pause the socket so that we start receiving only after startReceiving()
95 // is called.
96 chrome.sockets.tcp.setPaused(that.socketId_, true);
98 chrome.sockets.tcp.connect(that.socketId_, host, port, onConnected);
101 function onConnected(/** number */ result) {
102 if (that.destroyed_) {
103 return;
106 if (result < 0) {
107 reject(result);
108 } else {
109 resolve(0);
115 remoting.TcpSocket.prototype.dispose = function() {
116 if (this.socketId_ != -1) {
117 chrome.sockets.tcp.close(this.socketId_);
118 delete sockets[this.socketId_];
119 this.socketId_ = -1;
121 this.destroyed_ = true;
122 this.receiveCallback_ = null;
126 * Starts receiving data on the socket. Calls receiveCallback when new data is
127 * received or receiveErrorCallback when recv() returns an error.
129 remoting.TcpSocket.prototype.startReceiving = function(
130 /** ?function(ArrayBuffer):void */ receiveCallback,
131 /** ?function(number):void */ receiveErrorCallback) {
132 console.assert(this.receiveCallback_ == null,
133 'Duplicate startReceiving() invocation.');
134 this.receiveCallback_ = receiveCallback;
135 this.receiveErrorCallback_ = receiveErrorCallback;
136 chrome.sockets.tcp.setPaused(this.socketId_, false);
140 * Sends |data|.
142 * @returns {Promise}
144 remoting.TcpSocket.prototype.send = function(/** !ArrayBuffer */ data) {
145 var that = this;
147 return new Promise(function(resolve, reject) {
148 chrome.sockets.tcp.send(that.socketId_, data,
149 function(/** chrome.socket.SendInfo */ sendInfo) {
150 if (sendInfo.resultCode < 0) {
151 reject(sendInfo.resultCode);
152 } else {
153 resolve(sendInfo.bytesSent);
160 * Starts TLS on the socket. Once TLS is negotiated the caller will need to call
161 * startReceiving() to start receiving data, even if startReceiving() was called
162 * before.
164 * @returns {Promise}
166 remoting.TcpSocket.prototype.startTls = function() {
167 var that = this;
169 return new Promise(function(resolve, reject) {
170 function doStartTls() {
171 chrome.sockets.tcp.secure(that.socketId_, {}, function(result) {
172 if (result < 0) {
173 reject(result);
174 } else {
175 resolve(0);
180 if (!that.receiveCallback_) {
181 // Socket is already paused.
182 doStartTls();
183 } else {
184 // Socket must be paused before staring TLS. This won't work correctly
185 // until crbug.com/403076 is fixed. Log a warning and try anyway.
186 console.warn(
187 "remoting.TcpSocket.secure() was called after some data was " +
188 "received on the socket. This won't work properly until " +
189 "crbug.com/403076 is fixed.");
190 chrome.sockets.tcp.setPaused(that.socketId_, true, function() {
191 if (that.destroyed_) {
192 return;
194 that.receiveCallback_ = null;
195 that.receiveErrorCallback_ = null;
196 doStartTls();
202 })();