service_discovery_client_mac.h revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
15267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// found in the LICENSE file.
45267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
55267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_
65267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_
75267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
85267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include <string>
95267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "base/mac/scoped_nsobject.h"
115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "base/memory/weak_ptr.h"
125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "chrome/browser/local_discovery/service_discovery_shared_client.h"
135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace base {
165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class Thread;
175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}
185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)namespace local_discovery {
205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)template <class T>
225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class ServiceDiscoveryThreadDeleter {
235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) public:
245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  inline void operator()(T* t) { t->DeleteSoon(); }
255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)};
265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// Implementation of ServiceDiscoveryClient that uses the Bonjour SDK.
285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// https://developer.apple.com/library/mac/documentation/Networking/Conceptual/
295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)// NSNetServiceProgGuide/Articles/BrowsingForServices.html
305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class ServiceDiscoveryClientMac : public ServiceDiscoverySharedClient {
315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) public:
325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  ServiceDiscoveryClientMac();
335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) private:
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)  virtual ~ServiceDiscoveryClientMac();
365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  // ServiceDiscoveryClient implementation.
385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      const std::string& service_type,
405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      const ServiceWatcher::UpdatedCallback& callback) OVERRIDE;
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)  virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      const std::string& service_name,
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE;
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)  virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      const std::string& domain,
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      net::AddressFamily address_family,
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)      const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE;
485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  void StartThreadIfNotStarted();
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  scoped_ptr<base::Thread> service_discovery_thread_;
525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientMac);
545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)};
555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class ServiceWatcherImplMac : public ServiceWatcher {
575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) public:
585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  class NetServiceBrowserContainer {
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)   public:
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    NetServiceBrowserContainer(
615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const std::string& service_type,
625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const ServiceWatcher::UpdatedCallback& callback,
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        scoped_refptr<base::MessageLoopProxy> service_discovery_runner);
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ~NetServiceBrowserContainer();
655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void Start();
675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void DiscoverNewServices();
685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void OnServicesUpdate(ServiceWatcher::UpdateType update,
705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                          const std::string& service);
715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void DeleteSoon();
735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)   private:
7519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    void StartOnDiscoveryThread();
765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void DiscoverOnDiscoveryThread();
775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool IsOnServiceDiscoveryThread() {
795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      return base::MessageLoopProxy::current() ==
805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)             service_discovery_runner_.get();
815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    std::string service_type_;
845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ServiceWatcher::UpdatedCallback callback_;
855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> callback_runner_;
875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> service_discovery_runner_;
885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::scoped_nsobject<id> delegate_;
905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::scoped_nsobject<NSNetServiceBrowser> browser_;
915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::WeakPtrFactory<NetServiceBrowserContainer> weak_factory_;
925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  };
935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  ServiceWatcherImplMac(
951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)      const std::string& service_type,
969bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)      const ServiceWatcher::UpdatedCallback& callback,
9719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)      scoped_refptr<base::MessageLoopProxy> service_discovery_runner);
9819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)
9919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)  void OnServicesUpdate(ServiceWatcher::UpdateType update,
1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                        const std::string& service);
1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1025267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) private:
1035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual ~ServiceWatcherImplMac();
1045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual void Start() OVERRIDE;
1065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual void DiscoverNewServices(bool force_update) OVERRIDE;
1075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual void SetActivelyRefreshServices(
1085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      bool actively_refresh_services) OVERRIDE;
1095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual std::string GetServiceType() const OVERRIDE;
1105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  std::string service_type_;
1125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  ServiceWatcher::UpdatedCallback callback_;
1135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  bool started_;
1145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  scoped_ptr<NetServiceBrowserContainer,
1161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)             ServiceDiscoveryThreadDeleter<NetServiceBrowserContainer> >
1171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)      container_;
1181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)  base::WeakPtrFactory<ServiceWatcherImplMac> weak_factory_;
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImplMac);
1211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)};
1225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class ServiceResolverImplMac : public ServiceResolver {
1245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) public:
1255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  class NetServiceContainer {
1265267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)   public:
1275267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    NetServiceContainer(
1285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const std::string& service_name,
1295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        const ServiceResolver::ResolveCompleteCallback& callback,
1305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        scoped_refptr<base::MessageLoopProxy> service_discovery_runner);
1315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    virtual ~NetServiceContainer();
1335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void StartResolving();
1355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void OnResolveUpdate(RequestStatus);
1371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    void SetServiceForTesting(base::scoped_nsobject<NSNetService> service);
1391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void DeleteSoon();
1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)   private:
1435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void StartResolvingOnDiscoveryThread();
1445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool IsOnServiceDiscoveryThread() {
1465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      return base::MessageLoopProxy::current() ==
1475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)             service_discovery_runner_.get();
1485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
1495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    const std::string service_name_;
1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ServiceResolver::ResolveCompleteCallback callback_;
1525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> callback_runner_;
154e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> service_discovery_runner_;
1555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::scoped_nsobject<id> delegate_;
1575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::scoped_nsobject<NSNetService> service_;
1585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ServiceDescription service_description_;
1595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    base::WeakPtrFactory<NetServiceContainer> weak_factory_;
1605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  };
1615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  ServiceResolverImplMac(
1635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      const std::string& service_name,
1645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      const ServiceResolver::ResolveCompleteCallback& callback,
1655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)      scoped_refptr<base::MessageLoopProxy> service_discovery_runner);
1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  // Testing methods.
1685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  NetServiceContainer* GetContainerForTesting();
1695267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) private:
1715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual ~ServiceResolverImplMac();
1725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual void StartResolving() OVERRIDE;
1745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  virtual std::string GetName() const OVERRIDE;
1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  void OnResolveComplete(RequestStatus status,
1775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)                         const ServiceDescription& description);
1785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  const std::string service_name_;
1805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  ServiceResolver::ResolveCompleteCallback callback_;
1815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  bool has_resolved_;
1825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  scoped_ptr<NetServiceContainer,
1845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)             ServiceDiscoveryThreadDeleter<NetServiceContainer> > container_;
1855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  base::WeakPtrFactory<ServiceResolverImplMac> weak_factory_;
1865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ServiceResolverImplMac);
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)};
1895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)}  // namespace local_discovery
1915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#endif  // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_
1935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)