Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(495)

Side by Side Diff: remoting/protocol/protocol_test_client.cc

Issue 4313001: Rename classes for Chromoting: (Closed) Base URL: http://git.chromium.org/git/chromium.git
Patch Set: Resolve merge conflicts Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/protocol/protobuf_video_writer.cc ('k') | remoting/protocol/rtp_video_reader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #include "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #if !defined(OS_WIN) 7 #if !defined(OS_WIN)
8 extern "C" { 8 extern "C" {
9 #include <unistd.h> 9 #include <unistd.h>
10 } 10 }
11 #endif // !defined(OS_WIN) 11 #endif // !defined(OS_WIN)
12 12
13 #include <iostream> 13 #include <iostream>
14 #include <list> 14 #include <list>
15 15
16 #include "base/at_exit.h" 16 #include "base/at_exit.h"
17 #include "base/command_line.h" 17 #include "base/command_line.h"
18 #include "base/nss_util.h" 18 #include "base/nss_util.h"
19 #include "base/time.h" 19 #include "base/time.h"
20 #include "net/base/completion_callback.h" 20 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h" 21 #include "net/base/io_buffer.h"
22 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
23 #include "net/socket/socket.h" 23 #include "net/socket/socket.h"
24 #include "remoting/base/constants.h" 24 #include "remoting/base/constants.h"
25 #include "remoting/jingle_glue/jingle_client.h" 25 #include "remoting/jingle_glue/jingle_client.h"
26 #include "remoting/jingle_glue/jingle_thread.h" 26 #include "remoting/jingle_glue/jingle_thread.h"
27 #include "remoting/protocol/jingle_chromotocol_server.h" 27 #include "remoting/protocol/jingle_session_manager.h"
28 28
29 using remoting::kChromotingTokenServiceName; 29 using remoting::kChromotingTokenServiceName;
30 30
31 namespace remoting { 31 namespace remoting {
32 32
33 namespace protocol {
34
33 namespace { 35 namespace {
34 const int kBufferSize = 4096; 36 const int kBufferSize = 4096;
35 } // namespace 37 } // namespace
36 38
37 class ProtocolTestClient; 39 class ProtocolTestClient;
38 40
39 class ProtocolTestConnection 41 class ProtocolTestConnection
40 : public base::RefCountedThreadSafe<ProtocolTestConnection> { 42 : public base::RefCountedThreadSafe<ProtocolTestConnection> {
41 public: 43 public:
42 ProtocolTestConnection(ProtocolTestClient* client, MessageLoop* message_loop) 44 ProtocolTestConnection(ProtocolTestClient* client, MessageLoop* message_loop)
43 : client_(client), 45 : client_(client),
44 message_loop_(message_loop), 46 message_loop_(message_loop),
45 connection_(NULL), 47 session_(NULL),
46 ALLOW_THIS_IN_INITIALIZER_LIST( 48 ALLOW_THIS_IN_INITIALIZER_LIST(
47 write_cb_(this, &ProtocolTestConnection::OnWritten)), 49 write_cb_(this, &ProtocolTestConnection::OnWritten)),
48 pending_write_(false), 50 pending_write_(false),
49 ALLOW_THIS_IN_INITIALIZER_LIST( 51 ALLOW_THIS_IN_INITIALIZER_LIST(
50 read_cb_(this, &ProtocolTestConnection::OnRead)), 52 read_cb_(this, &ProtocolTestConnection::OnRead)),
51 closed_event_(true, false) { 53 closed_event_(true, false) {
52 } 54 }
53 55
54 void Init(ChromotocolConnection* connection); 56 void Init(Session* session);
55 void Write(const std::string& str); 57 void Write(const std::string& str);
56 void Read(); 58 void Read();
57 void Close(); 59 void Close();
58 60
59 // ChromotocolConnection::Callback interface. 61 // Session::Callback interface.
60 virtual void OnStateChange(ChromotocolConnection::State state); 62 virtual void OnStateChange(Session::State state);
61 private: 63 private:
62 void DoWrite(scoped_refptr<net::IOBuffer> buf, int size); 64 void DoWrite(scoped_refptr<net::IOBuffer> buf, int size);
63 void DoRead(); 65 void DoRead();
64 66
65 void HandleReadResult(int result); 67 void HandleReadResult(int result);
66 68
67 void OnWritten(int result); 69 void OnWritten(int result);
68 void OnRead(int result); 70 void OnRead(int result);
69 71
70 void OnFinishedClosing(); 72 void OnFinishedClosing();
71 73
72 ProtocolTestClient* client_; 74 ProtocolTestClient* client_;
73 MessageLoop* message_loop_; 75 MessageLoop* message_loop_;
74 scoped_refptr<ChromotocolConnection> connection_; 76 scoped_refptr<Session> session_;
75 net::CompletionCallbackImpl<ProtocolTestConnection> write_cb_; 77 net::CompletionCallbackImpl<ProtocolTestConnection> write_cb_;
76 bool pending_write_; 78 bool pending_write_;
77 net::CompletionCallbackImpl<ProtocolTestConnection> read_cb_; 79 net::CompletionCallbackImpl<ProtocolTestConnection> read_cb_;
78 scoped_refptr<net::IOBuffer> read_buffer_; 80 scoped_refptr<net::IOBuffer> read_buffer_;
79 base::WaitableEvent closed_event_; 81 base::WaitableEvent closed_event_;
80 }; 82 };
81 83
82 class ProtocolTestClient 84 class ProtocolTestClient
83 : public JingleClient::Callback, 85 : public JingleClient::Callback,
84 public base::RefCountedThreadSafe<ProtocolTestClient> { 86 public base::RefCountedThreadSafe<ProtocolTestClient> {
85 public: 87 public:
86 ProtocolTestClient() 88 ProtocolTestClient()
87 : closed_event_(true, false) { 89 : closed_event_(true, false) {
88 } 90 }
89 91
90 virtual ~ProtocolTestClient() {} 92 virtual ~ProtocolTestClient() {}
91 93
92 void Run(const std::string& username, const std::string& auth_token, 94 void Run(const std::string& username, const std::string& auth_token,
93 const std::string& host_jid); 95 const std::string& host_jid);
94 96
95 void OnConnectionClosed(ProtocolTestConnection* connection); 97 void OnConnectionClosed(ProtocolTestConnection* connection);
96 98
97 // JingleClient::Callback interface. 99 // JingleClient::Callback interface.
98 virtual void OnStateChange(JingleClient* client, JingleClient::State state); 100 virtual void OnStateChange(JingleClient* client, JingleClient::State state);
99 101
100 // callback for JingleChromotocolServer interface. 102 // callback for JingleSessionManager interface.
101 virtual void OnNewChromotocolConnection( 103 virtual void OnNewSession(
102 ChromotocolConnection* connection, 104 Session* session,
103 ChromotocolServer::IncomingConnectionResponse* response); 105 SessionManager::IncomingSessionResponse* response);
104 106
105 private: 107 private:
106 typedef std::list<scoped_refptr<ProtocolTestConnection> > ConnectionsList; 108 typedef std::list<scoped_refptr<ProtocolTestConnection> > ConnectionsList;
107 109
108 void OnFinishedClosing(); 110 void OnFinishedClosing();
109 void DestroyConnection(scoped_refptr<ProtocolTestConnection> connection); 111 void DestroyConnection(scoped_refptr<ProtocolTestConnection> connection);
110 112
111 std::string host_jid_; 113 std::string host_jid_;
112 scoped_refptr<JingleClient> client_; 114 scoped_refptr<JingleClient> client_;
113 scoped_refptr<JingleChromotocolServer> server_; 115 scoped_refptr<JingleSessionManager> session_manager_;
114 ConnectionsList connections_; 116 ConnectionsList connections_;
115 Lock connections_lock_; 117 Lock connections_lock_;
116 base::WaitableEvent closed_event_; 118 base::WaitableEvent closed_event_;
117 }; 119 };
118 120
119 121
120 void ProtocolTestConnection::Init(ChromotocolConnection* connection) { 122 void ProtocolTestConnection::Init(Session* session) {
121 connection_ = connection; 123 session_ = session;
122 } 124 }
123 125
124 void ProtocolTestConnection::Write(const std::string& str) { 126 void ProtocolTestConnection::Write(const std::string& str) {
125 if (str.empty()) 127 if (str.empty())
126 return; 128 return;
127 129
128 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(str.length())); 130 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(str.length()));
129 memcpy(buf->data(), str.c_str(), str.length()); 131 memcpy(buf->data(), str.c_str(), str.length());
130 message_loop_->PostTask( 132 message_loop_->PostTask(
131 FROM_HERE, NewRunnableMethod( 133 FROM_HERE, NewRunnableMethod(
132 this, &ProtocolTestConnection::DoWrite, buf, str.length())); 134 this, &ProtocolTestConnection::DoWrite, buf, str.length()));
133 } 135 }
134 136
135 void ProtocolTestConnection::DoWrite( 137 void ProtocolTestConnection::DoWrite(
136 scoped_refptr<net::IOBuffer> buf, int size) { 138 scoped_refptr<net::IOBuffer> buf, int size) {
137 if (pending_write_) { 139 if (pending_write_) {
138 LOG(ERROR) << "Cannot write because there is another pending write."; 140 LOG(ERROR) << "Cannot write because there is another pending write.";
139 return; 141 return;
140 } 142 }
141 143
142 net::Socket* channel = connection_->event_channel(); 144 net::Socket* channel = session_->event_channel();
143 if (channel != NULL) { 145 if (channel != NULL) {
144 int result = channel->Write(buf, size, &write_cb_); 146 int result = channel->Write(buf, size, &write_cb_);
145 if (result < 0) { 147 if (result < 0) {
146 if (result == net::ERR_IO_PENDING) 148 if (result == net::ERR_IO_PENDING)
147 pending_write_ = true; 149 pending_write_ = true;
148 else 150 else
149 LOG(ERROR) << "Write() returned error " << result; 151 LOG(ERROR) << "Write() returned error " << result;
150 } 152 }
151 } else { 153 } else {
152 LOG(ERROR) << "Cannot write because the channel isn't intialized yet."; 154 LOG(ERROR) << "Cannot write because the channel isn't intialized yet.";
153 } 155 }
154 } 156 }
155 157
156 void ProtocolTestConnection::Read() { 158 void ProtocolTestConnection::Read() {
157 message_loop_->PostTask( 159 message_loop_->PostTask(
158 FROM_HERE, NewRunnableMethod( 160 FROM_HERE, NewRunnableMethod(
159 this, &ProtocolTestConnection::DoRead)); 161 this, &ProtocolTestConnection::DoRead));
160 } 162 }
161 163
162 void ProtocolTestConnection::DoRead() { 164 void ProtocolTestConnection::DoRead() {
163 read_buffer_ = new net::IOBuffer(kBufferSize); 165 read_buffer_ = new net::IOBuffer(kBufferSize);
164 while (true) { 166 while (true) {
165 int result = connection_->event_channel()->Read( 167 int result = session_->event_channel()->Read(
166 read_buffer_, kBufferSize, &read_cb_); 168 read_buffer_, kBufferSize, &read_cb_);
167 if (result < 0) { 169 if (result < 0) {
168 if (result != net::ERR_IO_PENDING) 170 if (result != net::ERR_IO_PENDING)
169 LOG(ERROR) << "Read failed: " << result; 171 LOG(ERROR) << "Read failed: " << result;
170 break; 172 break;
171 } else { 173 } else {
172 HandleReadResult(result); 174 HandleReadResult(result);
173 } 175 }
174 } 176 }
175 } 177 }
176 178
177 void ProtocolTestConnection::Close() { 179 void ProtocolTestConnection::Close() {
178 connection_->Close( 180 session_->Close(
179 NewRunnableMethod(this, &ProtocolTestConnection::OnFinishedClosing)); 181 NewRunnableMethod(this, &ProtocolTestConnection::OnFinishedClosing));
180 closed_event_.Wait(); 182 closed_event_.Wait();
181 } 183 }
182 184
183 void ProtocolTestConnection::OnFinishedClosing() { 185 void ProtocolTestConnection::OnFinishedClosing() {
184 closed_event_.Signal(); 186 closed_event_.Signal();
185 } 187 }
186 188
187 void ProtocolTestConnection::OnStateChange( 189 void ProtocolTestConnection::OnStateChange(Session::State state) {
188 ChromotocolConnection::State state) { 190 LOG(INFO) << "State of " << session_->jid() << " changed to " << state;
189 LOG(INFO) << "State of " << connection_->jid() << " changed to " << state; 191 if (state == Session::CONNECTED) {
190 if (state == ChromotocolConnection::CONNECTED) {
191 // Start reading after we've connected. 192 // Start reading after we've connected.
192 Read(); 193 Read();
193 } else if (state == ChromotocolConnection::CLOSED) { 194 } else if (state == Session::CLOSED) {
194 std::cerr << "Connection to " << connection_->jid() 195 std::cerr << "Connection to " << session_->jid()
195 << " closed" << std::endl; 196 << " closed" << std::endl;
196 client_->OnConnectionClosed(this); 197 client_->OnConnectionClosed(this);
197 } 198 }
198 } 199 }
199 200
200 void ProtocolTestConnection::OnWritten(int result) { 201 void ProtocolTestConnection::OnWritten(int result) {
201 pending_write_ = false; 202 pending_write_ = false;
202 if (result < 0) 203 if (result < 0)
203 LOG(ERROR) << "Write() returned error " << result; 204 LOG(ERROR) << "Write() returned error " << result;
204 } 205 }
205 206
206 void ProtocolTestConnection::OnRead(int result) { 207 void ProtocolTestConnection::OnRead(int result) {
207 HandleReadResult(result); 208 HandleReadResult(result);
208 DoRead(); 209 DoRead();
209 } 210 }
210 211
211 void ProtocolTestConnection::HandleReadResult(int result) { 212 void ProtocolTestConnection::HandleReadResult(int result) {
212 if (result > 0) { 213 if (result > 0) {
213 std::string str(reinterpret_cast<const char*>(read_buffer_->data()), 214 std::string str(reinterpret_cast<const char*>(read_buffer_->data()),
214 result); 215 result);
215 std::cout << "(" << connection_->jid() << "): " << str << std::endl; 216 std::cout << "(" << session_->jid() << "): " << str << std::endl;
216 } else { 217 } else {
217 LOG(ERROR) << "Read() returned error " << result; 218 LOG(ERROR) << "Read() returned error " << result;
218 } 219 }
219 } 220 }
220 221
221 void ProtocolTestClient::Run(const std::string& username, 222 void ProtocolTestClient::Run(const std::string& username,
222 const std::string& auth_token, 223 const std::string& auth_token,
223 const std::string& host_jid) { 224 const std::string& host_jid) {
224 remoting::JingleThread jingle_thread; 225 remoting::JingleThread jingle_thread;
225 jingle_thread.Start(); 226 jingle_thread.Start();
226 client_ = new JingleClient(&jingle_thread); 227 client_ = new JingleClient(&jingle_thread);
227 client_->Init(username, auth_token, kChromotingTokenServiceName, this); 228 client_->Init(username, auth_token, kChromotingTokenServiceName, this);
228 229
229 server_ = new JingleChromotocolServer(&jingle_thread); 230 session_manager_ = new JingleSessionManager(&jingle_thread);
230 231
231 host_jid_ = host_jid; 232 host_jid_ = host_jid;
232 233
233 while (true) { 234 while (true) {
234 std::string line; 235 std::string line;
235 std::getline(std::cin, line); 236 std::getline(std::cin, line);
236 237
237 { 238 {
238 AutoLock auto_lock(connections_lock_); 239 AutoLock auto_lock(connections_lock_);
239 240
240 // Broadcast message to all clients. 241 // Broadcast message to all clients.
241 for (ConnectionsList::iterator it = connections_.begin(); 242 for (ConnectionsList::iterator it = connections_.begin();
242 it != connections_.end(); ++it) { 243 it != connections_.end(); ++it) {
243 (*it)->Write(line); 244 (*it)->Write(line);
244 } 245 }
245 } 246 }
246 247
247 if (line == "exit") 248 if (line == "exit")
248 break; 249 break;
249 } 250 }
250 251
251 while (!connections_.empty()) { 252 while (!connections_.empty()) {
252 connections_.front()->Close(); 253 connections_.front()->Close();
253 connections_.pop_front(); 254 connections_.pop_front();
254 } 255 }
255 256
256 if (server_) { 257 if (session_manager_) {
257 server_->Close( 258 session_manager_->Close(
258 NewRunnableMethod(this, &ProtocolTestClient::OnFinishedClosing)); 259 NewRunnableMethod(this, &ProtocolTestClient::OnFinishedClosing));
259 closed_event_.Wait(); 260 closed_event_.Wait();
260 } 261 }
261 262
262 client_->Close(); 263 client_->Close();
263 jingle_thread.Stop(); 264 jingle_thread.Stop();
264 } 265 }
265 266
266 void ProtocolTestClient::OnConnectionClosed( 267 void ProtocolTestClient::OnConnectionClosed(
267 ProtocolTestConnection* connection) { 268 ProtocolTestConnection* connection) {
268 client_->message_loop()->PostTask( 269 client_->message_loop()->PostTask(
269 FROM_HERE, NewRunnableMethod( 270 FROM_HERE, NewRunnableMethod(
270 this, &ProtocolTestClient::DestroyConnection, 271 this, &ProtocolTestClient::DestroyConnection,
271 scoped_refptr<ProtocolTestConnection>(connection))); 272 scoped_refptr<ProtocolTestConnection>(connection)));
272 } 273 }
273 274
274 void ProtocolTestClient::OnStateChange( 275 void ProtocolTestClient::OnStateChange(
275 JingleClient* client, JingleClient::State state) { 276 JingleClient* client, JingleClient::State state) {
276 if (state == JingleClient::CONNECTED) { 277 if (state == JingleClient::CONNECTED) {
277 std::cerr << "Connected as " << client->GetFullJid() << std::endl; 278 std::cerr << "Connected as " << client->GetFullJid() << std::endl;
278 279
279 server_->Init( 280 session_manager_->Init(
280 client_->GetFullJid(), client_->session_manager(), 281 client_->GetFullJid(), client_->session_manager(),
281 NewCallback(this, &ProtocolTestClient::OnNewChromotocolConnection)); 282 NewCallback(this, &ProtocolTestClient::OnNewSession));
282 server_->set_allow_local_ips(true); 283 session_manager_->set_allow_local_ips(true);
283 284
284 if (host_jid_ != "") { 285 if (host_jid_ != "") {
285 ProtocolTestConnection* connection = 286 ProtocolTestConnection* connection =
286 new ProtocolTestConnection(this, client_->message_loop()); 287 new ProtocolTestConnection(this, client_->message_loop());
287 connection->Init(server_->Connect( 288 connection->Init(session_manager_->Connect(
288 host_jid_, CandidateChromotocolConfig::CreateDefault(), 289 host_jid_, CandidateChromotocolConfig::CreateDefault(),
289 NewCallback(connection, 290 NewCallback(connection,
290 &ProtocolTestConnection::OnStateChange))); 291 &ProtocolTestConnection::OnStateChange)));
291 connections_.push_back(make_scoped_refptr(connection)); 292 connections_.push_back(make_scoped_refptr(connection));
292 } 293 }
293 } else if (state == JingleClient::CLOSED) { 294 } else if (state == JingleClient::CLOSED) {
294 std::cerr << "Connection closed" << std::endl; 295 std::cerr << "Connection closed" << std::endl;
295 } 296 }
296 } 297 }
297 298
298 void ProtocolTestClient::OnNewChromotocolConnection( 299 void ProtocolTestClient::OnNewSession(
299 ChromotocolConnection* connection, 300 Session* session,
300 ChromotocolServer::IncomingConnectionResponse* response) { 301 SessionManager::IncomingSessionResponse* response) {
301 std::cerr << "Accepting connection from " << connection->jid() << std::endl; 302 std::cerr << "Accepting connection from " << session->jid() << std::endl;
302 303
303 connection->set_config(ChromotocolConfig::CreateDefault()); 304 session->set_config(ChromotocolConfig::CreateDefault());
304 *response = ChromotocolServer::ACCEPT; 305 *response = SessionManager::ACCEPT;
305 306
306 ProtocolTestConnection* test_connection = 307 ProtocolTestConnection* test_connection =
307 new ProtocolTestConnection(this, client_->message_loop()); 308 new ProtocolTestConnection(this, client_->message_loop());
308 connection->SetStateChangeCallback( 309 session->SetStateChangeCallback(
309 NewCallback(test_connection, &ProtocolTestConnection::OnStateChange)); 310 NewCallback(test_connection, &ProtocolTestConnection::OnStateChange));
310 test_connection->Init(connection); 311 test_connection->Init(session);
311 AutoLock auto_lock(connections_lock_); 312 AutoLock auto_lock(connections_lock_);
312 connections_.push_back(make_scoped_refptr(test_connection)); 313 connections_.push_back(make_scoped_refptr(test_connection));
313 } 314 }
314 315
315 void ProtocolTestClient::OnFinishedClosing() { 316 void ProtocolTestClient::OnFinishedClosing() {
316 closed_event_.Signal(); 317 closed_event_.Signal();
317 } 318 }
318 319
319 void ProtocolTestClient::DestroyConnection( 320 void ProtocolTestClient::DestroyConnection(
320 scoped_refptr<ProtocolTestConnection> connection) { 321 scoped_refptr<ProtocolTestConnection> connection) {
321 connection->Close(); 322 connection->Close();
322 AutoLock auto_lock(connections_lock_); 323 AutoLock auto_lock(connections_lock_);
323 for (ConnectionsList::iterator it = connections_.begin(); 324 for (ConnectionsList::iterator it = connections_.begin();
324 it != connections_.end(); ++it) { 325 it != connections_.end(); ++it) {
325 if ((*it) == connection) { 326 if ((*it) == connection) {
326 connections_.erase(it); 327 connections_.erase(it);
327 return; 328 return;
328 } 329 }
329 } 330 }
330 } 331 }
331 332
333 } // namespace protocol
334
332 } // namespace remoting 335 } // namespace remoting
333 336
334 using remoting::ProtocolTestClient; 337 using remoting::protocol::ProtocolTestClient;
335 338
336 void usage(char* command) { 339 void usage(char* command) {
337 std::cerr << "Usage: " << command << "--username=<username>" << std::endl 340 std::cerr << "Usage: " << command << "--username=<username>" << std::endl
338 << "\t--auth_token=<auth_token>" << std::endl 341 << "\t--auth_token=<auth_token>" << std::endl
339 << "\t[--host_jid=<host_jid>]" << std::endl; 342 << "\t[--host_jid=<host_jid>]" << std::endl;
340 exit(1); 343 exit(1);
341 } 344 }
342 345
343 int main(int argc, char** argv) { 346 int main(int argc, char** argv) {
344 CommandLine::Init(argc, argv); 347 CommandLine::Init(argc, argv);
(...skipping 16 matching lines...) Expand all
361 if (!cmd_line->HasSwitch("auth_token")) 364 if (!cmd_line->HasSwitch("auth_token"))
362 usage(argv[0]); 365 usage(argv[0]);
363 std::string auth_token(cmd_line->GetSwitchValueASCII("auth_token")); 366 std::string auth_token(cmd_line->GetSwitchValueASCII("auth_token"));
364 367
365 scoped_refptr<ProtocolTestClient> client(new ProtocolTestClient()); 368 scoped_refptr<ProtocolTestClient> client(new ProtocolTestClient());
366 369
367 client->Run(username, auth_token, host_jid); 370 client->Run(username, auth_token, host_jid);
368 371
369 return 0; 372 return 0;
370 } 373 }
OLDNEW
« no previous file with comments | « remoting/protocol/protobuf_video_writer.cc ('k') | remoting/protocol/rtp_video_reader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698