15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved. 268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file. 468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/local_discovery/service_discovery_client_mdns.h" 668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/memory/scoped_vector.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/histogram.h" 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/common/local_discovery/service_discovery_client_impl.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/dns/mdns_client.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/udp/datagram_server_socket.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace local_discovery { 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using content::BrowserThread; 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Base class for objects returned by ServiceDiscoveryClient implementation. 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Handles interaction of client code on UI thread end net code on mdns thread. 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ServiceDiscoveryClientMdns::Proxy { 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef base::WeakPtr<Proxy> WeakPtr; 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu explicit Proxy(ServiceDiscoveryClientMdns* client) 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : client_(client), 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_(this) { 275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client_->proxies_.AddObserver(this); 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual ~Proxy() { 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client_->proxies_.RemoveObserver(this); 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Returns true if object is not yet shutdown. 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual bool IsValid() = 0; 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Notifies proxies that mDNS layer is going to be destroyed. 405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void OnMdnsDestroy() = 0; 415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Notifies proxies that new mDNS instance is ready. 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void OnNewMdnsReady() { 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!client_->need_dalay_mdns_tasks_); 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (IsValid()) { 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) for (size_t i = 0; i < delayed_tasks_.size(); ++i) 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) client_->mdns_runner_->PostTask(FROM_HERE, delayed_tasks_[i]); 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) delayed_tasks_.clear(); 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Runs callback using this method to abort callback if instance of |Proxy| 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // is deleted. 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void RunCallback(const base::Closure& callback) { 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu callback.Run(); 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected: 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void PostToMdnsThread(const base::Closure& task) { 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(IsValid()); 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // The first task on IO thread for each |mdns_| instance must be |InitMdns|. 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |OnInterfaceListReady| could be delayed by |GetMDnsInterfacesToBind| 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // running on FILE thread, so |PostToMdnsThread| could be called to post 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // task for |mdns_| that is not initialized yet. 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!client_->need_dalay_mdns_tasks_) { 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) client_->mdns_runner_->PostTask(FROM_HERE, task); 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) delayed_tasks_.push_back(task); 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static bool PostToUIThread(const base::Closure& task) { 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, task); 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceDiscoveryClient* client() { 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return client_->client_.get(); 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu WeakPtr GetWeakPtr() { 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return weak_ptr_factory_.GetWeakPtr(); 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu template<class T> 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void DeleteOnMdnsThread(T* t) { 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!t) 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!client_->mdns_runner_->DeleteSoon(FROM_HERE, t)) 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu delete t; 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<ServiceDiscoveryClientMdns> client_; 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::WeakPtrFactory<Proxy> weak_ptr_factory_; 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Delayed |mdns_runner_| tasks. 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::vector<base::Closure> delayed_tasks_; 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(Proxy); 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace { 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMaxRestartAttempts = 10; 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kRestartDelayOnNetworkChangeSeconds = 3; 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutypedef base::Callback<void(bool)> MdnsInitCallback; 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass SocketFactory : public net::MDnsSocketFactory { 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu explicit SocketFactory(const net::InterfaceIndexFamilyList& interfaces) 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : interfaces_(interfaces) {} 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // net::MDnsSocketFactory implementation: 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void CreateSockets( 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedVector<net::DatagramServerSocket>* sockets) OVERRIDE { 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (size_t i = 0; i < interfaces_.size(); ++i) { 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(interfaces_[i].second == net::ADDRESS_FAMILY_IPV4 || 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu interfaces_[i].second == net::ADDRESS_FAMILY_IPV6); 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<net::DatagramServerSocket> socket( 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateAndBindMDnsSocket(interfaces_[i].second, interfaces_[i].first)); 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (socket) 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu sockets->push_back(socket.release()); 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::InterfaceIndexFamilyList interfaces_; 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid InitMdns(const MdnsInitCallback& on_initialized, 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::InterfaceIndexFamilyList& interfaces, 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::MDnsClient* mdns) { 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SocketFactory socket_factory(interfaces); 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(on_initialized, 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mdns->StartListening(&socket_factory))); 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate<class T> 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ProxyBase : public ServiceDiscoveryClientMdns::Proxy, public T { 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu typedef ProxyBase<T> Base; 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu explicit ProxyBase(ServiceDiscoveryClientMdns* client) 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : Proxy(client) { 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual ~ProxyBase() { 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DeleteOnMdnsThread(implementation_.release()); 1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual bool IsValid() OVERRIDE { 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return !!implementation(); 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void OnMdnsDestroy() OVERRIDE { 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DeleteOnMdnsThread(implementation_.release()); 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu }; 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected: 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void set_implementation(scoped_ptr<T> implementation) { 1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu implementation_ = implementation.Pass(); 1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu T* implementation() const { 1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return implementation_.get(); 1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<T> implementation_; 1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(ProxyBase); 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ServiceWatcherProxy : public ProxyBase<ServiceWatcher> { 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWatcherProxy(ServiceDiscoveryClientMdns* client_mdns, 1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& service_type, 1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ServiceWatcher::UpdatedCallback& callback) 1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : ProxyBase(client_mdns), 1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_type_(service_type), 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu callback_(callback) { 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It's safe to call |CreateServiceWatcher| on UI thread, because 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |MDnsClient| is not used there. It's simplify implementation. 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu set_implementation(client()->CreateServiceWatcher( 1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_type, 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ServiceWatcherProxy::OnCallback, GetWeakPtr(), callback))); 1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // ServiceWatcher methods. 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void Start() OVERRIDE { 1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (implementation()) { 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToMdnsThread(base::Bind(&ServiceWatcher::Start, 1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(implementation()))); 1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void DiscoverNewServices(bool force_update) OVERRIDE { 1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (implementation()) { 1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToMdnsThread(base::Bind(&ServiceWatcher::DiscoverNewServices, 2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(implementation()), 2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu force_update)); 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void SetActivelyRefreshServices( 2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool actively_refresh_services) OVERRIDE { 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (implementation()) { 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToMdnsThread(base::Bind(&ServiceWatcher::SetActivelyRefreshServices, 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(implementation()), 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu actively_refresh_services)); 2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual std::string GetServiceType() const OVERRIDE { 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return service_type_; 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void OnNewMdnsReady() OVERRIDE { 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ProxyBase<ServiceWatcher>::OnNewMdnsReady(); 2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!implementation()) 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu callback_.Run(ServiceWatcher::UPDATE_INVALIDATED, ""); 2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static void OnCallback(const WeakPtr& proxy, 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ServiceWatcher::UpdatedCallback& callback, 2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UpdateType a1, 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& a2) { 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToUIThread(base::Bind(&Base::RunCallback, proxy, 2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(callback, a1, a2))); 2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string service_type_; 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWatcher::UpdatedCallback callback_; 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(ServiceWatcherProxy); 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ServiceResolverProxy : public ProxyBase<ServiceResolver> { 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceResolverProxy(ServiceDiscoveryClientMdns* client_mdns, 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& service_name, 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ServiceResolver::ResolveCompleteCallback& callback) 2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : ProxyBase(client_mdns), 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_name_(service_name) { 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It's safe to call |CreateServiceResolver| on UI thread, because 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |MDnsClient| is not used there. It's simplify implementation. 2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu set_implementation(client()->CreateServiceResolver( 2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_name, 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ServiceResolverProxy::OnCallback, GetWeakPtr(), callback))); 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // ServiceResolver methods. 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void StartResolving() OVERRIDE { 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (implementation()) { 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToMdnsThread(base::Bind(&ServiceResolver::StartResolving, 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(implementation()))); 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu }; 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual std::string GetName() const OVERRIDE { 2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return service_name_; 2625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static void OnCallback( 2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const WeakPtr& proxy, 2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ServiceResolver::ResolveCompleteCallback& callback, 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu RequestStatus a1, 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const ServiceDescription& a2) { 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToUIThread(base::Bind(&Base::RunCallback, proxy, 2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(callback, a1, a2))); 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string service_name_; 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(ServiceResolverProxy); 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 2785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass LocalDomainResolverProxy : public ProxyBase<LocalDomainResolver> { 2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 2815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LocalDomainResolverProxy( 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceDiscoveryClientMdns* client_mdns, 2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& domain, 2845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::AddressFamily address_family, 2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const LocalDomainResolver::IPAddressCallback& callback) 2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : ProxyBase(client_mdns) { 2875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It's safe to call |CreateLocalDomainResolver| on UI thread, because 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // |MDnsClient| is not used there. It's simplify implementation. 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu set_implementation(client()->CreateLocalDomainResolver( 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu domain, 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu address_family, 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind( 2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &LocalDomainResolverProxy::OnCallback, GetWeakPtr(), callback))); 2945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // LocalDomainResolver methods. 2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual void Start() OVERRIDE { 2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (implementation()) { 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToMdnsThread(base::Bind(&LocalDomainResolver::Start, 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(implementation()))); 3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu }; 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static void OnCallback(const WeakPtr& proxy, 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const LocalDomainResolver::IPAddressCallback& callback, 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool a1, 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::IPAddressNumber& a2, 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::IPAddressNumber& a3) { 3105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 3115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu PostToUIThread(base::Bind(&Base::RunCallback, proxy, 3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(callback, a1, a2, a3))); 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverProxy); 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} // namespace 3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuServiceDiscoveryClientMdns::ServiceDiscoveryClientMdns() 3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : mdns_runner_( 3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)), 3235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu restart_attempts_(0), 3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu need_dalay_mdns_tasks_(true), 3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_(this) { 3265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu StartNewClient(); 32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 33168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)scoped_ptr<ServiceWatcher> ServiceDiscoveryClientMdns::CreateServiceWatcher( 33268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& service_type, 33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ServiceWatcher::UpdatedCallback& callback) { 33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return scoped_ptr<ServiceWatcher>( 3365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ServiceWatcherProxy(this, service_type, callback)); 33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 33868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 33968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)scoped_ptr<ServiceResolver> ServiceDiscoveryClientMdns::CreateServiceResolver( 34068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& service_name, 34168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ServiceResolver::ResolveCompleteCallback& callback) { 34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return scoped_ptr<ServiceResolver>( 3445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new ServiceResolverProxy(this, service_name, callback)); 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)scoped_ptr<LocalDomainResolver> 34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ServiceDiscoveryClientMdns::CreateLocalDomainResolver( 34968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& domain, 35068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::AddressFamily address_family, 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const LocalDomainResolver::IPAddressCallback& callback) { 35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return scoped_ptr<LocalDomainResolver>( 3545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu new LocalDomainResolverProxy(this, domain, address_family, callback)); 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ServiceDiscoveryClientMdns::~ServiceDiscoveryClientMdns() { 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DestroyMdns(); 36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ServiceDiscoveryClientMdns::OnNetworkChanged( 36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType type) { 36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Only network changes resets counter. 3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu restart_attempts_ = 0; 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScheduleStartNewClient(); 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 37168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ServiceDiscoveryClientMdns::ScheduleStartNewClient() { 37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnBeforeMdnsDestroy(); 3745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (restart_attempts_ < kMaxRestartAttempts) { 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 3775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ServiceDiscoveryClientMdns::StartNewClient, 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::TimeDelta::FromSeconds( 3805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu kRestartDelayOnNetworkChangeSeconds * (1 << restart_attempts_))); 38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ReportSuccess(); 38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceDiscoveryClientMdns::StartNewClient() { 3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ++restart_attempts_; 389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DestroyMdns(); 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mdns_.reset(net::MDnsClient::CreateDefault().release()); 3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu client_.reset(new ServiceDiscoveryClientImpl(mdns_.get())); 3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu BrowserThread::PostTaskAndReplyWithResult( 3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu BrowserThread::FILE, 3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, 3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&net::GetMDnsInterfacesToBind), 3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ServiceDiscoveryClientMdns::OnInterfaceListReady, 3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_.GetWeakPtr())); 3985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceDiscoveryClientMdns::OnInterfaceListReady( 4015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const net::InterfaceIndexFamilyList& interfaces) { 4025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mdns_runner_->PostTask( 4035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FROM_HERE, 4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&InitMdns, 4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ServiceDiscoveryClientMdns::OnMdnsInitialized, 4065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_.GetWeakPtr()), 4075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu interfaces, 4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Unretained(mdns_.get()))); 4095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ServiceDiscoveryClientMdns::OnMdnsInitialized(bool success) { 4125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!success) { 4145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScheduleStartNewClient(); 4155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 4165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ReportSuccess(); 4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Initialization is done, no need to delay tasks. 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) need_dalay_mdns_tasks_ = false; 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FOR_EACH_OBSERVER(Proxy, proxies_, OnNewMdnsReady()); 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ServiceDiscoveryClientMdns::ReportSuccess() { 4255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("LocalDiscovery.ClientRestartAttempts", 4275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu restart_attempts_); 4285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceDiscoveryClientMdns::OnBeforeMdnsDestroy() { 4315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu need_dalay_mdns_tasks_ = true; 4325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu weak_ptr_factory_.InvalidateWeakPtrs(); 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FOR_EACH_OBSERVER(Proxy, proxies_, OnMdnsDestroy()); 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 4355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ServiceDiscoveryClientMdns::DestroyMdns() { 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnBeforeMdnsDestroy(); 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // After calling |Proxy::OnMdnsDestroy| all references to client_ and mdns_ 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // should be destroyed. 4405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (client_) 4415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mdns_runner_->DeleteSoon(FROM_HERE, client_.release()); 4425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (mdns_) 4435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mdns_runner_->DeleteSoon(FROM_HERE, mdns_.release()); 4445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace local_discovery 447