blob: bb81b55f563f535d5497452c44b33f6b7f978b77 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/local_discovery/service_discovery_client_mdns.h"
#include "chrome/browser/local_discovery/service_discovery_host_client.h"
#include "content/public/browser/browser_thread.h"
namespace local_discovery {
using content::BrowserThread;
namespace {
const int kMaxRestartAttempts = 10;
const int kRestartDelayOnNetworkChangeSeconds = 3;
}
scoped_ptr<ServiceWatcher> ServiceDiscoveryClientMdns::CreateServiceWatcher(
const std::string& service_type,
const ServiceWatcher::UpdatedCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return host_client_->CreateServiceWatcher(service_type, callback);
}
scoped_ptr<ServiceResolver> ServiceDiscoveryClientMdns::CreateServiceResolver(
const std::string& service_name,
const ServiceResolver::ResolveCompleteCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return host_client_->CreateServiceResolver(service_name, callback);
}
scoped_ptr<LocalDomainResolver>
ServiceDiscoveryClientMdns::CreateLocalDomainResolver(
const std::string& domain,
net::AddressFamily address_family,
const LocalDomainResolver::IPAddressCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return host_client_->CreateLocalDomainResolver(domain, address_family,
callback);
}
ServiceDiscoveryClientMdns::ServiceDiscoveryClientMdns()
: restart_attempts_(kMaxRestartAttempts),
weak_ptr_factory_(this) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
StartNewClient();
}
ServiceDiscoveryClientMdns::~ServiceDiscoveryClientMdns() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
host_client_->Shutdown();
}
void ServiceDiscoveryClientMdns::OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Only network changes resets kMaxRestartAttempts.
restart_attempts_ = kMaxRestartAttempts;
ScheduleStartNewClient();
}
void ServiceDiscoveryClientMdns::ScheduleStartNewClient() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
host_client_->Shutdown();
weak_ptr_factory_.InvalidateWeakPtrs();
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&ServiceDiscoveryClientMdns::StartNewClient,
weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(kRestartDelayOnNetworkChangeSeconds));
}
void ServiceDiscoveryClientMdns::StartNewClient() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
scoped_refptr<ServiceDiscoveryHostClient> old_client = host_client_;
if ((restart_attempts_--) > 0) {
host_client_ = new ServiceDiscoveryHostClient();
host_client_->Start(
base::Bind(&ServiceDiscoveryClientMdns::ScheduleStartNewClient,
weak_ptr_factory_.GetWeakPtr()));
} else {
host_client_ = NULL;
}
// Run when host_client_ is created. Callbacks created by InvalidateWatchers
// may create new watchers.
if (old_client)
old_client->InvalidateWatchers();
}
} // namespace local_discovery