service_discovery_client_mdns.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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. 4 5#include "chrome/browser/local_discovery/service_discovery_client_mdns.h" 6 7#include "base/metrics/histogram.h" 8#include "chrome/browser/local_discovery/service_discovery_host_client.h" 9#include "content/public/browser/browser_thread.h" 10 11namespace local_discovery { 12 13using content::BrowserThread; 14 15namespace { 16const int kMaxRestartAttempts = 10; 17const int kRestartDelayOnNetworkChangeSeconds = 3; 18const int kReportSuccessAfterSeconds = 10; 19} 20 21scoped_ptr<ServiceWatcher> ServiceDiscoveryClientMdns::CreateServiceWatcher( 22 const std::string& service_type, 23 const ServiceWatcher::UpdatedCallback& callback) { 24 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 25 return host_client_->CreateServiceWatcher(service_type, callback); 26} 27 28scoped_ptr<ServiceResolver> ServiceDiscoveryClientMdns::CreateServiceResolver( 29 const std::string& service_name, 30 const ServiceResolver::ResolveCompleteCallback& callback) { 31 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 32 return host_client_->CreateServiceResolver(service_name, callback); 33} 34 35scoped_ptr<LocalDomainResolver> 36ServiceDiscoveryClientMdns::CreateLocalDomainResolver( 37 const std::string& domain, 38 net::AddressFamily address_family, 39 const LocalDomainResolver::IPAddressCallback& callback) { 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 41 return host_client_->CreateLocalDomainResolver(domain, address_family, 42 callback); 43} 44 45ServiceDiscoveryClientMdns::ServiceDiscoveryClientMdns() 46 : restart_attempts_(kMaxRestartAttempts), 47 weak_ptr_factory_(this) { 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 49 net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 50 StartNewClient(); 51} 52 53ServiceDiscoveryClientMdns::~ServiceDiscoveryClientMdns() { 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 55 net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 56 host_client_->Shutdown(); 57} 58 59void ServiceDiscoveryClientMdns::OnNetworkChanged( 60 net::NetworkChangeNotifier::ConnectionType type) { 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 62 // Only network changes resets kMaxRestartAttempts. 63 restart_attempts_ = kMaxRestartAttempts; 64 ScheduleStartNewClient(); 65} 66 67void ServiceDiscoveryClientMdns::ScheduleStartNewClient() { 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 69 host_client_->Shutdown(); 70 weak_ptr_factory_.InvalidateWeakPtrs(); 71 base::MessageLoop::current()->PostDelayedTask( 72 FROM_HERE, 73 base::Bind(&ServiceDiscoveryClientMdns::StartNewClient, 74 weak_ptr_factory_.GetWeakPtr()), 75 base::TimeDelta::FromSeconds(kRestartDelayOnNetworkChangeSeconds)); 76} 77 78void ServiceDiscoveryClientMdns::StartNewClient() { 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 80 scoped_refptr<ServiceDiscoveryHostClient> old_client = host_client_; 81 if ((restart_attempts_--) > 0) { 82 host_client_ = new ServiceDiscoveryHostClient(); 83 host_client_->Start( 84 base::Bind(&ServiceDiscoveryClientMdns::ScheduleStartNewClient, 85 weak_ptr_factory_.GetWeakPtr())); 86 87 base::MessageLoop::current()->PostDelayedTask( 88 FROM_HERE, 89 base::Bind(&ServiceDiscoveryClientMdns::ReportSuccess, 90 weak_ptr_factory_.GetWeakPtr()), 91 base::TimeDelta::FromSeconds(kReportSuccessAfterSeconds)); 92 } else { 93 restart_attempts_ = -1; 94 ReportSuccess(); 95 } 96 // Run when host_client_ is created. Callbacks created by InvalidateWatchers 97 // may create new watchers. 98 if (old_client) 99 old_client->InvalidateWatchers(); 100} 101 102void ServiceDiscoveryClientMdns::ReportSuccess() { 103 UMA_HISTOGRAM_COUNTS_100("LocalDiscovery.ClientRestartAttempts", 104 kMaxRestartAttempts - restart_attempts_); 105} 106 107} // namespace local_discovery 108