Features:
[chromium-blink-merge.git] / chrome / browser / extensions / api / cast_channel / cast_socket.h
blobc542fb9055a9d02c7acbabf447817f4f600e760a
1 // Copyright 2013 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 #ifndef CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
8 #include <queue>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/threading/non_thread_safe.h"
17 #include "chrome/browser/extensions/api/api_resource.h"
18 #include "chrome/browser/extensions/api/api_resource_manager.h"
19 #include "chrome/common/extensions/api/cast_channel.h"
20 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h"
22 #include "net/base/ip_endpoint.h"
23 #include "net/base/net_log.h"
24 #include "url/gurl.h"
26 namespace net {
27 class AddressList;
28 class TCPClientSocket;
31 namespace extensions {
32 namespace api {
33 namespace cast_channel {
35 class CastMessage;
37 // Size, in bytes, of the largest allowed message payload on the wire (without
38 // the header).
39 extern const uint32 kMaxMessageSize;
41 // This class implements a channel between Chrome and a Cast device using a TCP
42 // socket. The channel may be unauthenticated (cast://) or authenticated
43 // (casts://). All CastSocket objects must be used only on the IO thread.
45 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
46 // code.
47 class CastSocket : public ApiResource,
48 public base::SupportsWeakPtr<CastSocket>,
49 public base::NonThreadSafe {
50 public:
51 // Object to be informed of incoming messages and errors.
52 class Delegate {
53 public:
54 // An error occurred on the channel.
55 virtual void OnError(const CastSocket* socket,
56 ChannelError error) = 0;
57 // A string message was received on the channel.
58 virtual void OnMessage(const CastSocket* socket,
59 const MessageInfo& message) = 0;
60 protected:
61 virtual ~Delegate() {}
64 // Creates a new CastSocket to |url|. |owner_extension_id| is the id of the
65 // extension that opened the socket.
66 CastSocket(const std::string& owner_extension_id,
67 const GURL& url, CastSocket::Delegate* delegate,
68 net::NetLog* net_log);
69 virtual ~CastSocket();
71 // The URL for the channel.
72 const GURL& url() const;
74 // True if the protocol is casts:
75 bool is_secure() const { return is_secure_; }
77 // Channel id for the ApiResourceManager.
78 long id() const { return channel_id_; }
80 // Sets the channel id.
81 void set_id(long channel_id) { channel_id_ = channel_id; }
83 // Returns the state of the channel.
84 const ReadyState& ready_state() const { return ready_state_; }
86 // Returns the last error that occurred on this channel, or CHANNEL_ERROR_NONE
87 // if no error has occurred..
88 const ChannelError& error_state() const { return error_state_; }
90 // Connects the channel to the peer. If successful, the channel will be in
91 // READY_STATE_OPEN.
92 virtual void Connect(const net::CompletionCallback& callback);
94 // Sends a message over a connected channel. The channel must be in
95 // READY_STATE_OPEN.
96 virtual void SendMessage(const MessageInfo& message,
97 const net::CompletionCallback& callback);
99 // Closes the channel. On completion, the channel will be in
100 // READY_STATE_CLOSED.
101 virtual void Close(const net::CompletionCallback& callback);
103 // Fills |channel_info| with the status of this channel.
104 void FillChannelInfo(ChannelInfo* channel_info) const;
106 protected:
107 // Factory method for sockets.
108 virtual net::TCPClientSocket* CreateSocket(const net::AddressList& addresses,
109 net::NetLog* net_log,
110 const net::NetLog::Source& source);
112 private:
113 friend class ApiResourceManager<CastSocket>;
114 static const char* service_name() {
115 return "CastSocketManager";
118 // Verifies that the URL is a valid cast:// or casts:// URL and sets url_ to
119 // the result.
120 bool ParseChannelUrl(const GURL& url);
122 // Called when the socket is connected.
123 void OnConnectComplete(int result);
125 // Writes data to the socket from the WriteRequest at the head of the queue.
126 // Calls OnWriteData() on completion.
127 void WriteData();
128 void OnWriteData(int result);
130 // Reads data from the socket into one of the read buffers. Calls
131 // OnReadData() on completion.
132 void ReadData();
133 void OnReadData(int result);
135 // Processes the contents of header_read_buffer_ and returns true on success.
136 bool ProcessHeader();
137 // Processes the contents of body_read_buffer_ and returns true on success.
138 bool ProcessBody();
139 // Parses the message held in body_read_buffer_ and notifies |delegate_| if a
140 // message was extracted from the buffer. Returns true on success.
141 bool ParseMessageFromBody();
143 // Serializes the content of message_proto (with a header) to |message_data|.
144 static bool Serialize(const CastMessage& message_proto,
145 std::string* message_data);
147 // Closes the socket and sets |error_state_|. Also signals |error| via
148 // |delegate_|.
149 void CloseWithError(ChannelError error);
151 // The id of the channel.
152 long channel_id_;
154 // The URL of the peer (cast:// or casts://).
155 GURL url_;
156 // Delegate to inform of incoming messages and errors.
157 Delegate* delegate_;
158 // True if the channel is using a secure transport.
159 bool is_secure_;
160 // The IP endpoint of the peer.
161 net::IPEndPoint ip_endpoint_;
162 // The last error encountered by the channel.
163 ChannelError error_state_;
164 // The current status of the channel.
165 ReadyState ready_state_;
167 // True when there is a write callback pending.
168 bool write_callback_pending_;
169 // True when there is a read callback pending.
170 bool read_callback_pending_;
172 // IOBuffer for reading the message header.
173 scoped_refptr<net::GrowableIOBuffer> header_read_buffer_;
174 // IOBuffer for reading the message body.
175 scoped_refptr<net::GrowableIOBuffer> body_read_buffer_;
176 // IOBuffer we are currently reading into.
177 scoped_refptr<net::GrowableIOBuffer> current_read_buffer_;
178 // The number of bytes in the current message body.
179 uint32 current_message_size_;
181 // The NetLog for this service.
182 net::NetLog* net_log_;
183 // The NetLog source for this service.
184 net::NetLog::Source net_log_source_;
186 // Owned ptr to the underlying socket.
188 // NOTE(mfoltz): We'll have to refactor this to allow substitution of an
189 // SSLClientSocket, since the APIs are different.
190 scoped_ptr<net::TCPClientSocket> socket_;
192 // Callback invoked when the socket is connected.
193 net::CompletionCallback connect_callback_;
195 // Message header struct. If fields are added, be sure to update
196 // kMessageHeaderSize in the .cc.
197 struct MessageHeader {
198 MessageHeader();
199 // Sets the message size.
200 void SetMessageSize(size_t message_size);
201 // Prepends this header to |str|.
202 void PrependToString(std::string* str);
203 // Reads |header| from the beginning of |buffer|.
204 static void ReadFromIOBuffer(net::GrowableIOBuffer* buffer,
205 MessageHeader* header);
206 std::string ToString();
207 // The size of the following protocol message in bytes, in host byte order.
208 uint32 message_size;
211 // Holds a message to be written to the socket. |callback| is invoked when the
212 // message is fully written or an error occurrs.
213 struct WriteRequest {
214 explicit WriteRequest(const net::CompletionCallback& callback);
215 ~WriteRequest();
216 // Sets the content of the request by serializing |message| into |io_buffer|
217 // and prepending the header. Must only be called once.
218 bool SetContent(const CastMessage& message_proto);
220 net::CompletionCallback callback;
221 scoped_refptr<net::DrainableIOBuffer> io_buffer;
223 // Queue of pending writes. The message at the front of the queue is the one
224 // being written.
225 std::queue<WriteRequest> write_queue_;
227 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestCastURLs);
228 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead);
229 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany);
230 DISALLOW_COPY_AND_ASSIGN(CastSocket);
233 } // namespace cast_channel
234 } // namespace api
235 } // namespace extensions
237 #endif // CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_