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