Index: chrome/browser/local_discovery/service_discovery_host_client.cc |
diff --git a/chrome/browser/local_discovery/service_discovery_host_client.cc b/chrome/browser/local_discovery/service_discovery_host_client.cc |
index 0434d9c91164770c76508c4e9d98c017bd773df8..ac6356b11992a890cb896bfc78ac42c0bb1eebef 100644 |
--- a/chrome/browser/local_discovery/service_discovery_host_client.cc |
+++ b/chrome/browser/local_discovery/service_discovery_host_client.cc |
@@ -20,19 +20,20 @@ class ServiceDiscoveryHostClient::ServiceWatcherProxy : public ServiceWatcher { |
const ServiceWatcher::UpdatedCallback& callback) |
: host_(host), |
service_type_(service_type), |
- id_(host_->RegisterWatcherCallback(callback)), |
- started_(false) { |
+ id_(host_->RegisterWatcherProxy(this)), |
+ started_(false), |
+ callback_(callback) { |
} |
virtual ~ServiceWatcherProxy() { |
- host_->UnregisterWatcherCallback(id_); |
+ host_->UnregisterWatcherProxy(id_); |
if (started_) |
host_->Send(new LocalDiscoveryMsg_DestroyWatcher(id_)); |
} |
virtual void Start() OVERRIDE { |
DCHECK(!started_); |
- host_->Send(new LocalDiscoveryMsg_StartWatcher(id_, service_type_)); |
+ SendStartMessage(); |
started_ = true; |
} |
@@ -45,11 +46,25 @@ class ServiceDiscoveryHostClient::ServiceWatcherProxy : public ServiceWatcher { |
return service_type_; |
} |
+ void RestartIfNecessary() { |
+ if (started_) { |
+ SendStartMessage(); |
+ callback_.Run(ServiceWatcher::UPDATE_CACHE_FLUSHED, ""); |
+ } |
+ } |
+ |
+ ServiceWatcher::UpdatedCallback callback() { return callback_; } |
+ |
private: |
+ void SendStartMessage() { |
+ host_->Send(new LocalDiscoveryMsg_StartWatcher(id_, service_type_)); |
+ } |
+ |
scoped_refptr<ServiceDiscoveryHostClient> host_; |
const std::string service_type_; |
const uint64 id_; |
bool started_; |
+ ServiceWatcher::UpdatedCallback callback_; |
}; |
class ServiceDiscoveryHostClient::ServiceResolverProxy |
@@ -60,19 +75,21 @@ class ServiceDiscoveryHostClient::ServiceResolverProxy |
const ServiceResolver::ResolveCompleteCallback& callback) |
: host_(host), |
service_name_(service_name), |
- id_(host->RegisterResolverCallback(callback)), |
- started_(false) { |
+ id_(host->RegisterResolverProxy(this)), |
+ started_(false), |
+ finished_(false), |
+ callback_(callback) { |
} |
virtual ~ServiceResolverProxy() { |
- host_->UnregisterResolverCallback(id_); |
+ host_->UnregisterResolverProxy(id_); |
if (started_) |
host_->Send(new LocalDiscoveryMsg_DestroyResolver(id_)); |
} |
virtual void StartResolving() OVERRIDE { |
DCHECK(!started_); |
- host_->Send(new LocalDiscoveryMsg_ResolveService(id_, service_name_)); |
+ SendStartMessage(); |
started_ = true; |
} |
@@ -80,11 +97,33 @@ class ServiceDiscoveryHostClient::ServiceResolverProxy |
return service_name_; |
} |
+ void Finish() { |
+ finished_ = true; |
+ } |
+ |
+ void RestartIfNecessary() { |
+ if (started_) { |
+ if (finished_) { |
+ started_ = false; |
+ } else { |
+ SendStartMessage(); |
+ } |
+ } |
+ } |
+ |
+ ServiceResolver::ResolveCompleteCallback callback() { return callback_; } |
+ |
private: |
+ void SendStartMessage() { |
+ host_->Send(new LocalDiscoveryMsg_ResolveService(id_, service_name_)); |
+ } |
+ |
scoped_refptr<ServiceDiscoveryHostClient> host_; |
const std::string service_name_; |
const uint64 id_; |
bool started_; |
+ bool finished_; |
+ ServiceResolver::ResolveCompleteCallback callback_; |
}; |
class ServiceDiscoveryHostClient::LocalDomainResolverProxy |
@@ -97,29 +136,52 @@ class ServiceDiscoveryHostClient::LocalDomainResolverProxy |
: host_(host), |
domain_(domain), |
address_family_(address_family), |
- id_(host->RegisterLocalDomainResolverCallback(callback)), |
- started_(false) { |
+ id_(host->RegisterLocalDomainResolverProxy(this)), |
+ started_(false), |
+ callback_(callback) { |
} |
virtual ~LocalDomainResolverProxy() { |
- host_->UnregisterLocalDomainResolverCallback(id_); |
+ host_->UnregisterLocalDomainResolverProxy(id_); |
if (started_) |
host_->Send(new LocalDiscoveryMsg_DestroyLocalDomainResolver(id_)); |
} |
virtual void Start() OVERRIDE { |
DCHECK(!started_); |
- host_->Send(new LocalDiscoveryMsg_ResolveLocalDomain(id_, domain_, |
- address_family_)); |
+ SendStartMessage(); |
started_ = true; |
} |
+ void Finish() { |
+ finished_ = true; |
+ } |
+ |
+ void RestartIfNecessary() { |
+ if (started_) { |
+ if (finished_) { |
+ started_ = false; |
+ } else { |
+ SendStartMessage(); |
+ } |
+ } |
+ } |
+ |
+ LocalDomainResolver::IPAddressCallback callback() { return callback_; } |
+ |
private: |
+ void SendStartMessage() { |
+ host_->Send(new LocalDiscoveryMsg_ResolveLocalDomain(id_, domain_, |
+ address_family_)); |
+ } |
+ |
scoped_refptr<ServiceDiscoveryHostClient> host_; |
std::string domain_; |
net::AddressFamily address_family_; |
const uint64 id_; |
bool started_; |
+ bool finished_; |
+ LocalDomainResolver::IPAddressCallback callback_; |
}; |
ServiceDiscoveryHostClient::ServiceDiscoveryHostClient() : current_id_(0) { |
@@ -130,9 +192,9 @@ ServiceDiscoveryHostClient::~ServiceDiscoveryHostClient() { |
// The ServiceDiscoveryHostClient may be destroyed from the IO thread or the |
// owning thread. |
DetachFromThread(); |
- DCHECK(service_watcher_callbacks_.empty()); |
- DCHECK(service_resolver_callbacks_.empty()); |
- DCHECK(domain_resolver_callbacks_.empty()); |
+ DCHECK(service_watcher_proxies_.empty()); |
+ DCHECK(service_resolver_proxies_.empty()); |
+ DCHECK(domain_resolver_proxies_.empty()); |
} |
scoped_ptr<ServiceWatcher> ServiceDiscoveryHostClient::CreateServiceWatcher( |
@@ -161,51 +223,52 @@ ServiceDiscoveryHostClient::CreateLocalDomainResolver( |
this, domain, address_family, callback)); |
} |
-uint64 ServiceDiscoveryHostClient::RegisterWatcherCallback( |
- const ServiceWatcher::UpdatedCallback& callback) { |
+uint64 ServiceDiscoveryHostClient::RegisterWatcherProxy( |
+ ServiceWatcherProxy* proxy) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!ContainsKey(service_watcher_callbacks_, current_id_ + 1)); |
- service_watcher_callbacks_[++current_id_] = callback; |
+ DCHECK(!ContainsKey(service_watcher_proxies_, current_id_ + 1)); |
+ service_watcher_proxies_[++current_id_] = proxy; |
return current_id_; |
} |
-uint64 ServiceDiscoveryHostClient::RegisterResolverCallback( |
- const ServiceResolver::ResolveCompleteCallback& callback) { |
+uint64 ServiceDiscoveryHostClient::RegisterResolverProxy( |
+ ServiceResolverProxy* proxy) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!ContainsKey(service_resolver_callbacks_, current_id_ + 1)); |
- service_resolver_callbacks_[++current_id_] = callback; |
+ DCHECK(!ContainsKey(service_resolver_proxies_, current_id_ + 1)); |
+ service_resolver_proxies_[++current_id_] = proxy; |
return current_id_; |
} |
-uint64 ServiceDiscoveryHostClient::RegisterLocalDomainResolverCallback( |
- const LocalDomainResolver::IPAddressCallback& callback) { |
+uint64 ServiceDiscoveryHostClient::RegisterLocalDomainResolverProxy( |
+ LocalDomainResolverProxy* proxy) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!ContainsKey(domain_resolver_callbacks_, current_id_ + 1)); |
- domain_resolver_callbacks_[++current_id_] = callback; |
+ DCHECK(!ContainsKey(domain_resolver_proxies_, current_id_ + 1)); |
+ domain_resolver_proxies_[++current_id_] = proxy; |
return current_id_; |
} |
-void ServiceDiscoveryHostClient::UnregisterWatcherCallback(uint64 id) { |
+void ServiceDiscoveryHostClient::UnregisterWatcherProxy(uint64 id) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(ContainsKey(service_watcher_callbacks_, id)); |
- service_watcher_callbacks_.erase(id); |
+ DCHECK(ContainsKey(service_watcher_proxies_, id)); |
+ service_watcher_proxies_.erase(id); |
} |
-void ServiceDiscoveryHostClient::UnregisterResolverCallback(uint64 id) { |
+void ServiceDiscoveryHostClient::UnregisterResolverProxy(uint64 id) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(ContainsKey(service_resolver_callbacks_, id)); |
- service_resolver_callbacks_.erase(id); |
+ DCHECK(ContainsKey(service_resolver_proxies_, id)); |
+ service_resolver_proxies_.erase(id); |
} |
-void ServiceDiscoveryHostClient::UnregisterLocalDomainResolverCallback( |
+void ServiceDiscoveryHostClient::UnregisterLocalDomainResolverProxy( |
uint64 id) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(ContainsKey(domain_resolver_callbacks_, id)); |
- domain_resolver_callbacks_.erase(id); |
+ DCHECK(ContainsKey(domain_resolver_proxies_, id)); |
+ domain_resolver_proxies_.erase(id); |
} |
void ServiceDiscoveryHostClient::Start() { |
DCHECK(CalledOnValidThread()); |
+ net::NetworkChangeNotifier::AddIPAddressObserver(this); |
BrowserThread::PostTask( |
BrowserThread::IO, |
FROM_HERE, |
@@ -214,6 +277,7 @@ void ServiceDiscoveryHostClient::Start() { |
void ServiceDiscoveryHostClient::Shutdown() { |
DCHECK(CalledOnValidThread()); |
+ net::NetworkChangeNotifier::RemoveIPAddressObserver(this); |
BrowserThread::PostTask( |
BrowserThread::IO, |
FROM_HERE, |
@@ -239,6 +303,13 @@ void ServiceDiscoveryHostClient::ShutdownOnIOThread() { |
} |
} |
+void ServiceDiscoveryHostClient::RestartOnIOThread() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ ShutdownOnIOThread(); |
+ StartOnIOThread(); |
+} |
+ |
void ServiceDiscoveryHostClient::Send(IPC::Message* msg) { |
DCHECK(CalledOnValidThread()); |
BrowserThread::PostTask( |
@@ -253,6 +324,31 @@ void ServiceDiscoveryHostClient::SendOnIOThread(IPC::Message* msg) { |
utility_host_->Send(msg); |
} |
+void ServiceDiscoveryHostClient::OnIPAddressChanged() { |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&ServiceDiscoveryHostClient::RestartOnIOThread, this)); |
+ |
+ for (WatcherProxies::iterator i = service_watcher_proxies_.begin(); |
+ i != service_watcher_proxies_.end(); |
+ i++) { |
+ i->second->RestartIfNecessary(); |
+ } |
+ |
+ for (ResolverProxies::iterator i = service_resolver_proxies_.begin(); |
+ i != service_resolver_proxies_.end(); |
+ i++) { |
+ i->second->RestartIfNecessary(); |
+ } |
+ |
+ for (ResolverProxies::iterator i = service_resolver_proxies_.begin(); |
+ i != service_resolver_proxies_.end(); |
+ i++) { |
+ i->second->RestartIfNecessary(); |
+ } |
+} |
+ |
bool ServiceDiscoveryHostClient::OnMessageReceived( |
const IPC::Message& message) { |
bool handled = true; |
@@ -307,9 +403,9 @@ void ServiceDiscoveryHostClient::RunWatcherCallback( |
ServiceWatcher::UpdateType update, |
const std::string& service_name) { |
DCHECK(CalledOnValidThread()); |
- WatcherCallbacks::iterator it = service_watcher_callbacks_.find(id); |
- if (it != service_watcher_callbacks_.end() && !it->second.is_null()) |
- it->second.Run(update, service_name); |
+ WatcherProxies::iterator it = service_watcher_proxies_.find(id); |
+ if (it != service_watcher_proxies_.end() && !it->second->callback().is_null()) |
+ it->second->callback().Run(update, service_name); |
} |
void ServiceDiscoveryHostClient::RunResolverCallback( |
@@ -317,9 +413,10 @@ void ServiceDiscoveryHostClient::RunResolverCallback( |
ServiceResolver::RequestStatus status, |
const ServiceDescription& description) { |
DCHECK(CalledOnValidThread()); |
- ResolverCallbacks::iterator it = service_resolver_callbacks_.find(id); |
- if (it != service_resolver_callbacks_.end() && !it->second.is_null()) |
- it->second.Run(status, description); |
+ ResolverProxies::iterator it = service_resolver_proxies_.find(id); |
+ if (it != service_resolver_proxies_.end() |
+ && !it->second->callback().is_null()) |
+ it->second->callback().Run(status, description); |
} |
void ServiceDiscoveryHostClient::RunLocalDomainResolverCallback( |
@@ -328,9 +425,10 @@ void ServiceDiscoveryHostClient::RunLocalDomainResolverCallback( |
const net::IPAddressNumber& ip_address_ipv4, |
const net::IPAddressNumber& ip_address_ipv6) { |
DCHECK(CalledOnValidThread()); |
- DomainResolverCallbacks::iterator it = domain_resolver_callbacks_.find(id); |
- if (it != domain_resolver_callbacks_.end() && !it->second.is_null()) |
- it->second.Run(success, ip_address_ipv4, ip_address_ipv6); |
+ DomainResolverProxies::iterator it = domain_resolver_proxies_.find(id); |
+ if (it != domain_resolver_proxies_.end() |
+ && !it->second->callback().is_null()) |
+ it->second->callback().Run(success, ip_address_ipv4, ip_address_ipv6); |
} |
ServiceDiscoveryHostClientFactory::ServiceDiscoveryHostClientFactory() |