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

Side by Side Diff: extensions/browser/api/cast_channel/cast_channel_api.cc

Issue 555283002: Create new class "CastTransport", which encapsulates the message read and write event loops. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed wez's feedback. Created 6 years, 3 months 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
OLDNEW
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 #include "extensions/browser/api/cast_channel/cast_channel_api.h" 5 #include "extensions/browser/api/cast_channel/cast_channel_api.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 9
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
(...skipping 15 matching lines...) Expand all
26 // Used if not otherwise specified at ConnectInfo::timeout. 26 // Used if not otherwise specified at ConnectInfo::timeout.
27 const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds. 27 const int kDefaultConnectTimeoutMillis = 5000; // 5 seconds.
28 28
29 namespace extensions { 29 namespace extensions {
30 30
31 namespace Close = cast_channel::Close; 31 namespace Close = cast_channel::Close;
32 namespace OnError = cast_channel::OnError; 32 namespace OnError = cast_channel::OnError;
33 namespace OnMessage = cast_channel::OnMessage; 33 namespace OnMessage = cast_channel::OnMessage;
34 namespace Open = cast_channel::Open; 34 namespace Open = cast_channel::Open;
35 namespace Send = cast_channel::Send; 35 namespace Send = cast_channel::Send;
36 using cast_channel::CastSocket; 36 using cast_channel::CastSocketImpl;
37 using cast_channel::ChannelAuthType; 37 using cast_channel::ChannelAuthType;
38 using cast_channel::ChannelError; 38 using cast_channel::ChannelError;
39 using cast_channel::ChannelInfo; 39 using cast_channel::ChannelInfo;
40 using cast_channel::ConnectInfo; 40 using cast_channel::ConnectInfo;
41 using cast_channel::ErrorInfo; 41 using cast_channel::ErrorInfo;
42 using cast_channel::LastErrors; 42 using cast_channel::LastErrors;
43 using cast_channel::Logger; 43 using cast_channel::Logger;
44 using cast_channel::MessageInfo; 44 using cast_channel::MessageInfo;
45 using cast_channel::ReadyState; 45 using cast_channel::ReadyState;
46 using content::BrowserThread; 46 using content::BrowserThread;
47 47
48 namespace { 48 namespace {
49 49
50 // T is an extension dictionary (MessageInfo or ChannelInfo) 50 // T is an extension dictionary (MessageInfo or ChannelInfo)
51 template <class T> 51 template <class T>
52 std::string ParamToString(const T& info) { 52 std::string ParamToString(const T& info) {
53 scoped_ptr<base::DictionaryValue> dict = info.ToValue(); 53 scoped_ptr<base::DictionaryValue> dict = info.ToValue();
54 std::string out; 54 std::string out;
55 base::JSONWriter::Write(dict.get(), &out); 55 base::JSONWriter::Write(dict.get(), &out);
56 return out; 56 return out;
57 } 57 }
58 58
59 // Fills |channel_info| from the destination and state of |socket|. 59 // Fills |channel_info| from the destination and state of |socket|.
60 void FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) { 60 void FillChannelInfo(const CastSocketImpl& socket, ChannelInfo* channel_info) {
61 DCHECK(channel_info); 61 DCHECK(channel_info);
62 channel_info->channel_id = socket.id(); 62 channel_info->channel_id = socket.id();
63 channel_info->url = socket.CastUrl(); 63 channel_info->url = socket.CastUrl();
64 const net::IPEndPoint& ip_endpoint = socket.ip_endpoint(); 64 const net::IPEndPoint& ip_endpoint = socket.ip_endpoint();
65 channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort(); 65 channel_info->connect_info.ip_address = ip_endpoint.ToStringWithoutPort();
66 channel_info->connect_info.port = ip_endpoint.port(); 66 channel_info->connect_info.port = ip_endpoint.port();
67 channel_info->connect_info.auth = socket.channel_auth(); 67 channel_info->connect_info.auth = socket.channel_auth();
68 channel_info->ready_state = socket.ready_state(); 68 channel_info->ready_state = socket.ready_state();
69 channel_info->error_state = socket.error_state(); 69 channel_info->error_state = socket.error_state();
70 } 70 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 123
124 static base::LazyInstance<BrowserContextKeyedAPIFactory<CastChannelAPI> > 124 static base::LazyInstance<BrowserContextKeyedAPIFactory<CastChannelAPI> >
125 g_factory = LAZY_INSTANCE_INITIALIZER; 125 g_factory = LAZY_INSTANCE_INITIALIZER;
126 126
127 // static 127 // static
128 BrowserContextKeyedAPIFactory<CastChannelAPI>* 128 BrowserContextKeyedAPIFactory<CastChannelAPI>*
129 CastChannelAPI::GetFactoryInstance() { 129 CastChannelAPI::GetFactoryInstance() {
130 return g_factory.Pointer(); 130 return g_factory.Pointer();
131 } 131 }
132 132
133 scoped_ptr<CastSocket> CastChannelAPI::CreateCastSocket( 133 scoped_ptr<CastSocketImpl> CastChannelAPI::CreateCastSocketImpl(
134 const std::string& extension_id, const net::IPEndPoint& ip_endpoint, 134 const std::string& extension_id,
135 ChannelAuthType channel_auth, const base::TimeDelta& timeout) { 135 const net::IPEndPoint& ip_endpoint,
136 ChannelAuthType channel_auth,
137 const base::TimeDelta& timeout) {
136 if (socket_for_test_.get()) { 138 if (socket_for_test_.get()) {
137 return socket_for_test_.Pass(); 139 return socket_for_test_.Pass();
138 } else { 140 } else {
139 return scoped_ptr<CastSocket>( 141 return scoped_ptr<CastSocketImpl>(
140 new CastSocket(extension_id, 142 new CastSocketImpl(extension_id,
141 ip_endpoint, 143 ip_endpoint,
142 channel_auth, 144 channel_auth,
143 this, 145 this,
144 ExtensionsBrowserClient::Get()->GetNetLog(), 146 ExtensionsBrowserClient::Get()->GetNetLog(),
145 timeout, 147 timeout,
146 logger_)); 148 logger_));
147 } 149 }
148 } 150 }
149 151
150 void CastChannelAPI::SetSocketForTest(scoped_ptr<CastSocket> socket_for_test) { 152 void CastChannelAPI::SetSocketForTest(
153 scoped_ptr<CastSocketImpl> socket_for_test) {
151 socket_for_test_ = socket_for_test.Pass(); 154 socket_for_test_ = socket_for_test.Pass();
152 } 155 }
153 156
154 void CastChannelAPI::OnError(const CastSocket* socket, 157 void CastChannelAPI::OnError(const CastSocketImpl* socket,
155 cast_channel::ChannelError error_state, 158 cast_channel::ChannelError error_state,
156 const cast_channel::LastErrors& last_errors) { 159 const cast_channel::LastErrors& last_errors) {
157 DCHECK_CURRENTLY_ON(BrowserThread::IO); 160 DCHECK_CURRENTLY_ON(BrowserThread::IO);
158 ChannelInfo channel_info; 161 ChannelInfo channel_info;
159 FillChannelInfo(*socket, &channel_info); 162 FillChannelInfo(*socket, &channel_info);
160 channel_info.error_state = error_state; 163 channel_info.error_state = error_state;
161 ErrorInfo error_info; 164 ErrorInfo error_info;
162 FillErrorInfo(error_state, last_errors, &error_info); 165 FillErrorInfo(error_state, last_errors, &error_info);
163 scoped_ptr<base::ListValue> results = 166 scoped_ptr<base::ListValue> results =
164 OnError::Create(channel_info, error_info); 167 OnError::Create(channel_info, error_info);
165 scoped_ptr<Event> event(new Event(OnError::kEventName, results.Pass())); 168 scoped_ptr<Event> event(new Event(OnError::kEventName, results.Pass()));
166 extensions::EventRouter::Get(browser_context_) 169 extensions::EventRouter::Get(browser_context_)
167 ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass()); 170 ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass());
168 } 171 }
169 172
170 void CastChannelAPI::OnMessage(const CastSocket* socket, 173 void CastChannelAPI::OnMessage(const CastSocketImpl* socket,
171 const MessageInfo& message_info) { 174 const MessageInfo& message_info) {
172 DCHECK_CURRENTLY_ON(BrowserThread::IO); 175 DCHECK_CURRENTLY_ON(BrowserThread::IO);
173 ChannelInfo channel_info; 176 ChannelInfo channel_info;
174 FillChannelInfo(*socket, &channel_info); 177 FillChannelInfo(*socket, &channel_info);
175 scoped_ptr<base::ListValue> results = 178 scoped_ptr<base::ListValue> results =
176 OnMessage::Create(channel_info, message_info); 179 OnMessage::Create(channel_info, message_info);
177 VLOG(1) << "Sending message " << ParamToString(message_info) 180 VLOG(1) << "Sending message " << ParamToString(message_info)
178 << " to channel " << ParamToString(channel_info); 181 << " to channel " << ParamToString(channel_info);
179 scoped_ptr<Event> event(new Event(OnMessage::kEventName, results.Pass())); 182 scoped_ptr<Event> event(new Event(OnMessage::kEventName, results.Pass()));
180 extensions::EventRouter::Get(browser_context_) 183 extensions::EventRouter::Get(browser_context_)
181 ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass()); 184 ->DispatchEventToExtension(socket->owner_extension_id(), event.Pass());
182 } 185 }
183 186
184 CastChannelAPI::~CastChannelAPI() {} 187 CastChannelAPI::~CastChannelAPI() {}
185 188
186 CastChannelAsyncApiFunction::CastChannelAsyncApiFunction() 189 CastChannelAsyncApiFunction::CastChannelAsyncApiFunction()
187 : manager_(NULL), error_(cast_channel::CHANNEL_ERROR_NONE) { } 190 : manager_(NULL), error_(cast_channel::CHANNEL_ERROR_NONE) { }
188 191
189 CastChannelAsyncApiFunction::~CastChannelAsyncApiFunction() { } 192 CastChannelAsyncApiFunction::~CastChannelAsyncApiFunction() { }
190 193
191 bool CastChannelAsyncApiFunction::PrePrepare() { 194 bool CastChannelAsyncApiFunction::PrePrepare() {
192 manager_ = ApiResourceManager<CastSocket>::Get(browser_context()); 195 manager_ = ApiResourceManager<CastSocketImpl>::Get(browser_context());
193 return true; 196 return true;
194 } 197 }
195 198
196 bool CastChannelAsyncApiFunction::Respond() { 199 bool CastChannelAsyncApiFunction::Respond() {
197 return error_ == cast_channel::CHANNEL_ERROR_NONE; 200 return error_ == cast_channel::CHANNEL_ERROR_NONE;
198 } 201 }
199 202
200 CastSocket* CastChannelAsyncApiFunction::GetSocketOrCompleteWithError( 203 CastSocketImpl* CastChannelAsyncApiFunction::GetSocketOrCompleteWithError(
201 int channel_id) { 204 int channel_id) {
202 CastSocket* socket = GetSocket(channel_id); 205 CastSocketImpl* socket = GetSocket(channel_id);
203 if (!socket) { 206 if (!socket) {
204 SetResultFromError(channel_id, 207 SetResultFromError(channel_id,
205 cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID); 208 cast_channel::CHANNEL_ERROR_INVALID_CHANNEL_ID);
206 AsyncWorkCompleted(); 209 AsyncWorkCompleted();
207 } 210 }
208 return socket; 211 return socket;
209 } 212 }
210 213
211 int CastChannelAsyncApiFunction::AddSocket(CastSocket* socket) { 214 int CastChannelAsyncApiFunction::AddSocket(CastSocketImpl* socket) {
212 DCHECK_CURRENTLY_ON(BrowserThread::IO); 215 DCHECK_CURRENTLY_ON(BrowserThread::IO);
213 DCHECK(socket); 216 DCHECK(socket);
214 DCHECK(manager_); 217 DCHECK(manager_);
215 const int id = manager_->Add(socket); 218 const int id = manager_->Add(socket);
216 socket->set_id(id); 219 socket->set_id(id);
217 return id; 220 return id;
218 } 221 }
219 222
220 void CastChannelAsyncApiFunction::RemoveSocket(int channel_id) { 223 void CastChannelAsyncApiFunction::RemoveSocket(int channel_id) {
221 DCHECK_CURRENTLY_ON(BrowserThread::IO); 224 DCHECK_CURRENTLY_ON(BrowserThread::IO);
222 DCHECK(manager_); 225 DCHECK(manager_);
223 manager_->Remove(extension_->id(), channel_id); 226 manager_->Remove(extension_->id(), channel_id);
224 } 227 }
225 228
226 void CastChannelAsyncApiFunction::SetResultFromSocket( 229 void CastChannelAsyncApiFunction::SetResultFromSocket(
227 const CastSocket& socket) { 230 const CastSocketImpl& socket) {
228 ChannelInfo channel_info; 231 ChannelInfo channel_info;
229 FillChannelInfo(socket, &channel_info); 232 FillChannelInfo(socket, &channel_info);
230 error_ = socket.error_state(); 233 error_ = socket.error_state();
231 SetResultFromChannelInfo(channel_info); 234 SetResultFromChannelInfo(channel_info);
232 } 235 }
233 236
234 void CastChannelAsyncApiFunction::SetResultFromError(int channel_id, 237 void CastChannelAsyncApiFunction::SetResultFromError(int channel_id,
235 ChannelError error) { 238 ChannelError error) {
236 ChannelInfo channel_info; 239 ChannelInfo channel_info;
237 channel_info.channel_id = channel_id; 240 channel_info.channel_id = channel_id;
238 channel_info.url = ""; 241 channel_info.url = "";
239 channel_info.ready_state = cast_channel::READY_STATE_CLOSED; 242 channel_info.ready_state = cast_channel::READY_STATE_CLOSED;
240 channel_info.error_state = error; 243 channel_info.error_state = error;
241 channel_info.connect_info.ip_address = ""; 244 channel_info.connect_info.ip_address = "";
242 channel_info.connect_info.port = 0; 245 channel_info.connect_info.port = 0;
243 channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL; 246 channel_info.connect_info.auth = cast_channel::CHANNEL_AUTH_TYPE_SSL;
244 SetResultFromChannelInfo(channel_info); 247 SetResultFromChannelInfo(channel_info);
245 error_ = error; 248 error_ = error;
246 } 249 }
247 250
248 CastSocket* CastChannelAsyncApiFunction::GetSocket(int channel_id) { 251 CastSocketImpl* CastChannelAsyncApiFunction::GetSocket(int channel_id) {
249 DCHECK_CURRENTLY_ON(BrowserThread::IO); 252 DCHECK_CURRENTLY_ON(BrowserThread::IO);
250 DCHECK(manager_); 253 DCHECK(manager_);
251 return manager_->Get(extension_->id(), channel_id); 254 return manager_->Get(extension_->id(), channel_id);
252 } 255 }
253 256
254 void CastChannelAsyncApiFunction::SetResultFromChannelInfo( 257 void CastChannelAsyncApiFunction::SetResultFromChannelInfo(
255 const ChannelInfo& channel_info) { 258 const ChannelInfo& channel_info) {
256 DCHECK_CURRENTLY_ON(BrowserThread::IO); 259 DCHECK_CURRENTLY_ON(BrowserThread::IO);
257 SetResult(channel_info.ToValue().release()); 260 SetResult(channel_info.ToValue().release());
258 } 261 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 return false; 362 return false;
360 } 363 }
361 channel_auth_ = connect_info_->auth; 364 channel_auth_ = connect_info_->auth;
362 ip_endpoint_.reset(ParseConnectInfo(*connect_info_)); 365 ip_endpoint_.reset(ParseConnectInfo(*connect_info_));
363 return true; 366 return true;
364 } 367 }
365 368
366 void CastChannelOpenFunction::AsyncWorkStart() { 369 void CastChannelOpenFunction::AsyncWorkStart() {
367 DCHECK(api_); 370 DCHECK(api_);
368 DCHECK(ip_endpoint_.get()); 371 DCHECK(ip_endpoint_.get());
369 scoped_ptr<CastSocket> socket = api_->CreateCastSocket( 372 scoped_ptr<CastSocketImpl> socket = api_->CreateCastSocketImpl(
370 extension_->id(), 373 extension_->id(),
371 *ip_endpoint_, 374 *ip_endpoint_,
372 channel_auth_, 375 channel_auth_,
373 base::TimeDelta::FromMilliseconds(connect_info_->timeout.get() 376 base::TimeDelta::FromMilliseconds(connect_info_->timeout.get()
374 ? *connect_info_->timeout 377 ? *connect_info_->timeout
375 : kDefaultConnectTimeoutMillis)); 378 : kDefaultConnectTimeoutMillis));
376 new_channel_id_ = AddSocket(socket.release()); 379 new_channel_id_ = AddSocket(socket.release());
377 CastSocket* new_socket = GetSocket(new_channel_id_); 380 CastSocketImpl* new_socket = GetSocket(new_channel_id_);
378 api_->GetLogger()->LogNewSocketEvent(*new_socket); 381 api_->GetLogger()->LogNewSocketEvent(*new_socket);
379 new_socket->Connect(base::Bind(&CastChannelOpenFunction::OnOpen, this)); 382 new_socket->Connect(base::Bind(&CastChannelOpenFunction::OnOpen, this));
380 } 383 }
381 384
382 void CastChannelOpenFunction::OnOpen(int result) { 385 void CastChannelOpenFunction::OnOpen(int result) {
383 DCHECK_CURRENTLY_ON(BrowserThread::IO); 386 DCHECK_CURRENTLY_ON(BrowserThread::IO);
384 VLOG(1) << "Connect finished, OnOpen invoked."; 387 VLOG(1) << "Connect finished, OnOpen invoked.";
385 CastSocket* socket = GetSocket(new_channel_id_); 388 CastSocketImpl* socket = GetSocket(new_channel_id_);
386 if (!socket) { 389 if (!socket) {
387 SetResultFromError(new_channel_id_, 390 SetResultFromError(new_channel_id_,
388 cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 391 cast_channel::CHANNEL_ERROR_CONNECT_ERROR);
389 } else { 392 } else {
390 SetResultFromSocket(*socket); 393 SetResultFromSocket(*socket);
391 } 394 }
392 AsyncWorkCompleted(); 395 AsyncWorkCompleted();
393 } 396 }
394 397
395 CastChannelSendFunction::CastChannelSendFunction() { } 398 CastChannelSendFunction::CastChannelSendFunction() { }
(...skipping 20 matching lines...) Expand all
416 case base::Value::TYPE_BINARY: 419 case base::Value::TYPE_BINARY:
417 break; 420 break;
418 default: 421 default:
419 SetError("Invalid type of message_info.data"); 422 SetError("Invalid type of message_info.data");
420 return false; 423 return false;
421 } 424 }
422 return true; 425 return true;
423 } 426 }
424 427
425 void CastChannelSendFunction::AsyncWorkStart() { 428 void CastChannelSendFunction::AsyncWorkStart() {
426 CastSocket* socket = GetSocketOrCompleteWithError( 429 CastSocketImpl* socket =
427 params_->channel.channel_id); 430 GetSocketOrCompleteWithError(params_->channel.channel_id);
428 if (socket) 431 if (socket)
429 socket->SendMessage(params_->message, 432 socket->SendMessage(params_->message,
430 base::Bind(&CastChannelSendFunction::OnSend, this)); 433 base::Bind(&CastChannelSendFunction::OnSend, this));
431 } 434 }
432 435
433 void CastChannelSendFunction::OnSend(int result) { 436 void CastChannelSendFunction::OnSend(int result) {
434 DCHECK_CURRENTLY_ON(BrowserThread::IO); 437 DCHECK_CURRENTLY_ON(BrowserThread::IO);
435 int channel_id = params_->channel.channel_id; 438 int channel_id = params_->channel.channel_id;
436 CastSocket* socket = GetSocket(channel_id); 439 CastSocketImpl* socket = GetSocket(channel_id);
437 if (result < 0 || !socket) { 440 if (result < 0 || !socket) {
438 SetResultFromError(channel_id, 441 SetResultFromError(channel_id,
439 cast_channel::CHANNEL_ERROR_SOCKET_ERROR); 442 cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
440 } else { 443 } else {
441 SetResultFromSocket(*socket); 444 SetResultFromSocket(*socket);
442 } 445 }
443 AsyncWorkCompleted(); 446 AsyncWorkCompleted();
444 } 447 }
445 448
446 CastChannelCloseFunction::CastChannelCloseFunction() { } 449 CastChannelCloseFunction::CastChannelCloseFunction() { }
447 450
448 CastChannelCloseFunction::~CastChannelCloseFunction() { } 451 CastChannelCloseFunction::~CastChannelCloseFunction() { }
449 452
450 bool CastChannelCloseFunction::Prepare() { 453 bool CastChannelCloseFunction::Prepare() {
451 params_ = Close::Params::Create(*args_); 454 params_ = Close::Params::Create(*args_);
452 EXTENSION_FUNCTION_VALIDATE(params_.get()); 455 EXTENSION_FUNCTION_VALIDATE(params_.get());
453 return true; 456 return true;
454 } 457 }
455 458
456 void CastChannelCloseFunction::AsyncWorkStart() { 459 void CastChannelCloseFunction::AsyncWorkStart() {
457 CastSocket* socket = GetSocketOrCompleteWithError( 460 CastSocketImpl* socket =
458 params_->channel.channel_id); 461 GetSocketOrCompleteWithError(params_->channel.channel_id);
459 if (socket) 462 if (socket)
460 socket->Close(base::Bind(&CastChannelCloseFunction::OnClose, this)); 463 socket->Close(base::Bind(&CastChannelCloseFunction::OnClose, this));
461 } 464 }
462 465
463 void CastChannelCloseFunction::OnClose(int result) { 466 void CastChannelCloseFunction::OnClose(int result) {
464 DCHECK_CURRENTLY_ON(BrowserThread::IO); 467 DCHECK_CURRENTLY_ON(BrowserThread::IO);
465 VLOG(1) << "CastChannelCloseFunction::OnClose result = " << result; 468 VLOG(1) << "CastChannelCloseFunction::OnClose result = " << result;
466 int channel_id = params_->channel.channel_id; 469 int channel_id = params_->channel.channel_id;
467 CastSocket* socket = GetSocket(channel_id); 470 CastSocketImpl* socket = GetSocket(channel_id);
468 if (result < 0 || !socket) { 471 if (result < 0 || !socket) {
469 SetResultFromError(channel_id, 472 SetResultFromError(channel_id,
470 cast_channel::CHANNEL_ERROR_SOCKET_ERROR); 473 cast_channel::CHANNEL_ERROR_SOCKET_ERROR);
471 } else { 474 } else {
472 SetResultFromSocket(*socket); 475 SetResultFromSocket(*socket);
473 // This will delete |socket|. 476 // This will delete |socket|.
474 RemoveSocket(channel_id); 477 RemoveSocket(channel_id);
475 socket = NULL; 478 socket = NULL;
476 } 479 }
477 AsyncWorkCompleted(); 480 AsyncWorkCompleted();
(...skipping 24 matching lines...) Expand all
502 } else { 505 } else {
503 SetError("Unable to get logs."); 506 SetError("Unable to get logs.");
504 } 507 }
505 508
506 api_->GetLogger()->Reset(); 509 api_->GetLogger()->Reset();
507 510
508 AsyncWorkCompleted(); 511 AsyncWorkCompleted();
509 } 512 }
510 513
511 } // namespace extensions 514 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698