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