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#ifndef CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_ 6#define CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_ 7 8#include <string> 9 10#include "base/mac/scoped_nsobject.h" 11#include "base/memory/weak_ptr.h" 12#include "chrome/browser/local_discovery/service_discovery_shared_client.h" 13#include "content/public/browser/browser_thread.h" 14 15namespace base { 16class Thread; 17} 18 19namespace local_discovery { 20 21template <class T> 22class ServiceDiscoveryThreadDeleter { 23 public: 24 inline void operator()(T* t) { t->DeleteSoon(); } 25}; 26 27// Implementation of ServiceDiscoveryClient that uses the Bonjour SDK. 28// https://developer.apple.com/library/mac/documentation/Networking/Conceptual/ 29// NSNetServiceProgGuide/Articles/BrowsingForServices.html 30class ServiceDiscoveryClientMac : public ServiceDiscoverySharedClient { 31 public: 32 ServiceDiscoveryClientMac(); 33 34 private: 35 virtual ~ServiceDiscoveryClientMac(); 36 37 // ServiceDiscoveryClient implementation. 38 virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher( 39 const std::string& service_type, 40 const ServiceWatcher::UpdatedCallback& callback) OVERRIDE; 41 virtual scoped_ptr<ServiceResolver> CreateServiceResolver( 42 const std::string& service_name, 43 const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE; 44 virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver( 45 const std::string& domain, 46 net::AddressFamily address_family, 47 const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE; 48 49 void StartThreadIfNotStarted(); 50 51 scoped_ptr<base::Thread> service_discovery_thread_; 52 53 DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientMac); 54}; 55 56class ServiceWatcherImplMac : public ServiceWatcher { 57 public: 58 class NetServiceBrowserContainer { 59 public: 60 NetServiceBrowserContainer( 61 const std::string& service_type, 62 const ServiceWatcher::UpdatedCallback& callback, 63 scoped_refptr<base::MessageLoopProxy> service_discovery_runner); 64 ~NetServiceBrowserContainer(); 65 66 void Start(); 67 void DiscoverNewServices(); 68 69 void OnServicesUpdate(ServiceWatcher::UpdateType update, 70 const std::string& service); 71 72 void DeleteSoon(); 73 74 private: 75 void StartOnDiscoveryThread(); 76 void DiscoverOnDiscoveryThread(); 77 78 bool IsOnServiceDiscoveryThread() { 79 return base::MessageLoopProxy::current() == 80 service_discovery_runner_.get(); 81 } 82 83 std::string service_type_; 84 ServiceWatcher::UpdatedCallback callback_; 85 86 scoped_refptr<base::MessageLoopProxy> callback_runner_; 87 scoped_refptr<base::MessageLoopProxy> service_discovery_runner_; 88 89 base::scoped_nsobject<id> delegate_; 90 base::scoped_nsobject<NSNetServiceBrowser> browser_; 91 base::WeakPtrFactory<NetServiceBrowserContainer> weak_factory_; 92 }; 93 94 ServiceWatcherImplMac( 95 const std::string& service_type, 96 const ServiceWatcher::UpdatedCallback& callback, 97 scoped_refptr<base::MessageLoopProxy> service_discovery_runner); 98 99 void OnServicesUpdate(ServiceWatcher::UpdateType update, 100 const std::string& service); 101 102 private: 103 virtual ~ServiceWatcherImplMac(); 104 105 virtual void Start() OVERRIDE; 106 virtual void DiscoverNewServices(bool force_update) OVERRIDE; 107 virtual void SetActivelyRefreshServices( 108 bool actively_refresh_services) OVERRIDE; 109 virtual std::string GetServiceType() const OVERRIDE; 110 111 std::string service_type_; 112 ServiceWatcher::UpdatedCallback callback_; 113 bool started_; 114 115 scoped_ptr<NetServiceBrowserContainer, 116 ServiceDiscoveryThreadDeleter<NetServiceBrowserContainer> > 117 container_; 118 base::WeakPtrFactory<ServiceWatcherImplMac> weak_factory_; 119 120 DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImplMac); 121}; 122 123class ServiceResolverImplMac : public ServiceResolver { 124 public: 125 class NetServiceContainer { 126 public: 127 NetServiceContainer( 128 const std::string& service_name, 129 const ServiceResolver::ResolveCompleteCallback& callback, 130 scoped_refptr<base::MessageLoopProxy> service_discovery_runner); 131 132 virtual ~NetServiceContainer(); 133 134 void StartResolving(); 135 136 void OnResolveUpdate(RequestStatus); 137 138 void SetServiceForTesting(base::scoped_nsobject<NSNetService> service); 139 140 void DeleteSoon(); 141 142 private: 143 void StartResolvingOnDiscoveryThread(); 144 145 bool IsOnServiceDiscoveryThread() { 146 return base::MessageLoopProxy::current() == 147 service_discovery_runner_.get(); 148 } 149 150 const std::string service_name_; 151 ServiceResolver::ResolveCompleteCallback callback_; 152 153 scoped_refptr<base::MessageLoopProxy> callback_runner_; 154 scoped_refptr<base::MessageLoopProxy> service_discovery_runner_; 155 156 base::scoped_nsobject<id> delegate_; 157 base::scoped_nsobject<NSNetService> service_; 158 ServiceDescription service_description_; 159 base::WeakPtrFactory<NetServiceContainer> weak_factory_; 160 }; 161 162 ServiceResolverImplMac( 163 const std::string& service_name, 164 const ServiceResolver::ResolveCompleteCallback& callback, 165 scoped_refptr<base::MessageLoopProxy> service_discovery_runner); 166 167 // Testing methods. 168 NetServiceContainer* GetContainerForTesting(); 169 170 private: 171 virtual ~ServiceResolverImplMac(); 172 173 virtual void StartResolving() OVERRIDE; 174 virtual std::string GetName() const OVERRIDE; 175 176 void OnResolveComplete(RequestStatus status, 177 const ServiceDescription& description); 178 179 const std::string service_name_; 180 ServiceResolver::ResolveCompleteCallback callback_; 181 bool has_resolved_; 182 183 scoped_ptr<NetServiceContainer, 184 ServiceDiscoveryThreadDeleter<NetServiceContainer> > container_; 185 base::WeakPtrFactory<ServiceResolverImplMac> weak_factory_; 186 187 DISALLOW_COPY_AND_ASSIGN(ServiceResolverImplMac); 188}; 189 190} // namespace local_discovery 191 192#endif // CHROME_BROWSER_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_MAC_H_ 193