| Index: chrome/browser/extensions/api/dial/dial_service.cc
|
| diff --git a/chrome/browser/extensions/api/dial/dial_service.cc b/chrome/browser/extensions/api/dial/dial_service.cc
|
| index 62702df824f2e98a2fb92d350bab578fbb858f55..d525a0547099c9f058dc71dbf3fa6c4c88a1a230 100644
|
| --- a/chrome/browser/extensions/api/dial/dial_service.cc
|
| +++ b/chrome/browser/extensions/api/dial/dial_service.cc
|
| @@ -42,8 +42,8 @@ namespace extensions {
|
|
|
| namespace {
|
|
|
| -// The total number of requests to make.
|
| -const int kDialNumRequests = 1;
|
| +// The total number of requests to make per discovery cycle.
|
| +const int kDialMaxRequests = 4;
|
|
|
| // The interval to wait between successive requests.
|
| const int kDialRequestIntervalMillis = 1000;
|
| @@ -113,8 +113,16 @@ void GetNetworkListOnFileThread(
|
| } // namespace
|
|
|
| DialServiceImpl::DialServiceImpl(net::NetLog* net_log)
|
| - : is_writing_(false), is_reading_(false), discovery_active_(false),
|
| - num_requests_sent_(0) {
|
| + : is_writing_(false),
|
| + is_reading_(false),
|
| + discovery_active_(false),
|
| + num_requests_sent_(0),
|
| + max_requests_(kDialMaxRequests),
|
| + finish_delay_(TimeDelta::FromMilliseconds((kDialMaxRequests - 1) *
|
| + kDialRequestIntervalMillis) +
|
| + TimeDelta::FromSeconds(kDialResponseTimeoutSecs)),
|
| + request_interval_(TimeDelta::FromMilliseconds(kDialRequestIntervalMillis))
|
| + {
|
| IPAddressNumber address;
|
| bool result = net::ParseIPLiteralToNumber(kDialRequestAddress, &address);
|
| DCHECK(result);
|
| @@ -123,9 +131,6 @@ DialServiceImpl::DialServiceImpl(net::NetLog* net_log)
|
| net_log_ = net_log;
|
| net_log_source_.type = net::NetLog::SOURCE_UDP_SOCKET;
|
| net_log_source_.id = net_log_->NextID();
|
| - finish_delay_ = TimeDelta::FromMilliseconds((kDialNumRequests - 1) *
|
| - kDialRequestIntervalMillis) +
|
| - TimeDelta::FromSeconds(kDialResponseTimeoutSecs);
|
| }
|
|
|
| DialServiceImpl::~DialServiceImpl() {
|
| @@ -155,24 +160,24 @@ bool DialServiceImpl::Discover() {
|
|
|
| DVLOG(1) << "Discovery started.";
|
|
|
| - // TODO(mfoltz): Send multiple requests.
|
| - StartRequest();
|
| + StartDiscovery();
|
| return true;
|
| }
|
|
|
| -void DialServiceImpl::FinishDiscovery() {
|
| +void DialServiceImpl::StartDiscovery() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(discovery_active_);
|
| - DVLOG(1) << "Discovery finished.";
|
| - CloseSocket();
|
| - finish_timer_.Stop();
|
| - discovery_active_ = false;
|
| - num_requests_sent_ = 0;
|
| - FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryFinished(this));
|
| + if (socket_.get())
|
| + return;
|
| +
|
| + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
|
| + &GetNetworkListOnFileThread,
|
| + base::MessageLoopProxy::current(), base::Bind(
|
| + &DialServiceImpl::SendNetworkList, AsWeakPtr())));
|
| }
|
|
|
| -bool DialServiceImpl::BindAndWriteSocket(
|
| - const NetworkInterface& bind_interface) {
|
| +bool DialServiceImpl::BindSocketAndSendRequest(
|
| + const IPAddressNumber& bind_ip_address) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(!socket_.get());
|
|
|
| @@ -184,13 +189,15 @@ bool DialServiceImpl::BindAndWriteSocket(
|
| socket_->AllowBroadcast();
|
|
|
| // Schedule a timer to finish the discovery process (and close the socket).
|
| - finish_timer_.Start(FROM_HERE,
|
| - finish_delay_,
|
| - this,
|
| - &DialServiceImpl::FinishDiscovery);
|
| + if (finish_delay_ > TimeDelta::FromSeconds(0)) {
|
| + finish_timer_.Start(FROM_HERE,
|
| + finish_delay_,
|
| + this,
|
| + &DialServiceImpl::FinishDiscovery);
|
| + }
|
|
|
| // 0 means bind a random port
|
| - IPEndPoint address(bind_interface.address, 0);
|
| + IPEndPoint address(bind_ip_address, 0);
|
|
|
| if (!CheckResult("Bind", socket_->Bind(address)))
|
| return false;
|
| @@ -198,12 +205,29 @@ bool DialServiceImpl::BindAndWriteSocket(
|
| DCHECK(socket_.get());
|
|
|
| recv_buffer_ = new IOBufferWithSize(kDialRecvBufferSize);
|
| - ReadSocket();
|
| + if (!ReadSocket())
|
| + return false;
|
| + SendOneRequest();
|
| + return true;
|
| +}
|
| +
|
| +void DialServiceImpl::SendOneRequest() {
|
| + if (num_requests_sent_ == max_requests_) {
|
| + request_timer_.Stop();
|
| + return;
|
| + }
|
| + num_requests_sent_++;
|
| + if (!socket_.get()) {
|
| + DLOG(WARNING) << "Socket not connected.";
|
| + return;
|
| + }
|
|
|
| if (is_writing_) {
|
| DVLOG(1) << "Already writing.";
|
| - return false;
|
| + return;
|
| }
|
| + DVLOG(1) << "Sending request " << num_requests_sent_ << "/"
|
| + << max_requests_;
|
| is_writing_ = true;
|
| int result = socket_->SendTo(
|
| send_buffer_.get(), send_buffer_->size(), send_address_,
|
| @@ -213,50 +237,6 @@ bool DialServiceImpl::BindAndWriteSocket(
|
| // Synchronous write.
|
| OnSocketWrite(result);
|
| }
|
| - return result_ok;
|
| -}
|
| -
|
| -void DialServiceImpl::StartRequest() {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - DCHECK(discovery_active_);
|
| - if (socket_.get())
|
| - return;
|
| -
|
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind(
|
| - &GetNetworkListOnFileThread,
|
| - base::MessageLoopProxy::current(), base::Bind(
|
| - &DialServiceImpl::SendNetworkList, AsWeakPtr())));
|
| -}
|
| -
|
| -void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - if (!networks.size()) {
|
| - DVLOG(1) << "No network interfaces found!";
|
| - FOR_EACH_OBSERVER(
|
| - Observer, observer_list_, OnError(this, DIAL_SERVICE_NO_INTERFACES));
|
| - return;
|
| - }
|
| -
|
| - const NetworkInterface* interface = NULL;
|
| - // Returns the first IPv4 address found. If there is a need for discovery
|
| - // across multiple networks, we could manage multiple sockets.
|
| -
|
| - // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
|
| - for (NetworkInterfaceList::const_iterator iter = networks.begin();
|
| - iter != networks.end(); ++iter) {
|
| - DVLOG(1) << "Found " << iter->name << ", "
|
| - << net::IPAddressToString(iter->address);
|
| - if (iter->address.size() == net::kIPv4AddressSize) {
|
| - interface = &*iter;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (interface == NULL) {
|
| - DVLOG(1) << "Could not find a valid interface to bind.";
|
| - } else {
|
| - BindAndWriteSocket(*interface);
|
| - }
|
| }
|
|
|
| void DialServiceImpl::OnSocketWrite(int result) {
|
| @@ -275,7 +255,13 @@ void DialServiceImpl::OnSocketWrite(int result) {
|
| return;
|
| }
|
| FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryRequest(this));
|
| - num_requests_sent_++;
|
| + // If we need to send additional requests, schedule a timer to do so.
|
| + if (num_requests_sent_ < max_requests_ && num_requests_sent_ == 1) {
|
| + request_timer_.Start(FROM_HERE,
|
| + request_interval_,
|
| + this,
|
| + &DialServiceImpl::SendOneRequest);
|
| + }
|
| }
|
|
|
| bool DialServiceImpl::ReadSocket() {
|
| @@ -404,6 +390,43 @@ bool DialServiceImpl::ParseResponse(const std::string& response,
|
| return true;
|
| }
|
|
|
| +void DialServiceImpl::SendNetworkList(const NetworkInterfaceList& networks) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + const NetworkInterface* interface = NULL;
|
| + // Returns the first IPv4 address found. If there is a need for discovery
|
| + // across multiple networks, we could manage multiple sockets.
|
| +
|
| + // TODO(mfoltz): Support IPV6 multicast. http://crbug.com/165286
|
| + for (NetworkInterfaceList::const_iterator iter = networks.begin();
|
| + iter != networks.end(); ++iter) {
|
| + DVLOG(1) << "Found " << iter->name << ", "
|
| + << net::IPAddressToString(iter->address);
|
| + if (iter->address.size() == net::kIPv4AddressSize) {
|
| + interface = &*iter;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (interface == NULL) {
|
| + DVLOG(1) << "Could not find a valid interface to bind.";
|
| + FinishDiscovery();
|
| + } else {
|
| + BindSocketAndSendRequest(interface->address);
|
| + }
|
| +}
|
| +
|
| +void DialServiceImpl::FinishDiscovery() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(discovery_active_);
|
| + DVLOG(1) << "Discovery finished.";
|
| + CloseSocket();
|
| + finish_timer_.Stop();
|
| + request_timer_.Stop();
|
| + discovery_active_ = false;
|
| + num_requests_sent_ = 0;
|
| + FOR_EACH_OBSERVER(Observer, observer_list_, OnDiscoveryFinished(this));
|
| +}
|
| +
|
| void DialServiceImpl::CloseSocket() {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| is_reading_ = false;
|
|
|