[Windows] Remove redundant DirectSound error codes
[xbmc.git] / xbmc / platform / android / network / ZeroconfBrowserAndroid.cpp
blobd31564f5ea6b783fb3ff92bc866f3776243f14f5
1 /*
2 * Copyright (C) 2017 Christian Browet
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ZeroconfBrowserAndroid.h"
11 #include "ServiceBroker.h"
12 #include "interfaces/AnnouncementManager.h"
13 #include "network/DNSNameCache.h"
14 #include "utils/log.h"
16 #include <mutex>
18 #include <androidjni/Context.h>
19 #include <androidjni/jutils-details.hpp>
21 CZeroconfBrowserAndroid::CZeroconfBrowserAndroid()
22 : m_manager(CJNIContext::getSystemService(CJNIContext::NSD_SERVICE))
26 CZeroconfBrowserAndroid::~CZeroconfBrowserAndroid()
28 std::unique_lock<CCriticalSection> lock(m_data_guard);
29 //make sure there are no browsers anymore
30 for (const auto& it : m_service_browsers)
31 doRemoveServiceType(it.first);
34 bool CZeroconfBrowserAndroid::doAddServiceType(const std::string& fcr_service_type)
36 CZeroconfBrowserAndroidDiscover* discover = new CZeroconfBrowserAndroidDiscover(this);
38 // Remove trailing dot
39 // std::string nsdType = fcr_service_type;
40 // if (nsdType.compare(nsdType.size() - 1, 1, ".") == 0)
41 // nsdType = nsdType.substr(0, nsdType.size() - 1);
43 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroid::doAddServiceType: {}", fcr_service_type);
44 m_manager.discoverServices(fcr_service_type, 1 /* PROTOCOL_DNS_SD */, *discover);
46 //store the browser
48 std::unique_lock<CCriticalSection> lock(m_data_guard);
49 m_service_browsers.insert(std::make_pair(fcr_service_type, discover));
51 return true;
54 bool CZeroconfBrowserAndroid::doRemoveServiceType(const std::string& fcr_service_type)
56 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroid::doRemoveServiceType: {}", fcr_service_type);
58 CZeroconfBrowserAndroidDiscover* discover;
59 //search for this browser and remove it from the map
61 std::unique_lock<CCriticalSection> lock(m_data_guard);
62 tBrowserMap::iterator it = m_service_browsers.find(fcr_service_type);
63 if(it == m_service_browsers.end())
65 return false;
67 discover = it->second;
68 if (discover->IsActive())
69 m_manager.stopServiceDiscovery(*discover);
70 // Be extra careful: Discover listener is gone as of now
71 m_service_browsers.erase(it);
74 //remove the services of this browser
76 std::unique_lock<CCriticalSection> lock(m_data_guard);
77 tDiscoveredServicesMap::iterator it = m_discovered_services.find(discover);
78 if(it != m_discovered_services.end())
79 m_discovered_services.erase(it);
81 delete discover;
83 return true;
86 std::vector<CZeroconfBrowser::ZeroconfService> CZeroconfBrowserAndroid::doGetFoundServices()
88 std::vector<CZeroconfBrowser::ZeroconfService> ret;
89 std::unique_lock<CCriticalSection> lock(m_data_guard);
90 for (const auto& it : m_discovered_services)
92 const auto& services = it.second;
93 for (const auto& service : services)
95 ret.push_back(service.first);
98 return ret;
101 bool CZeroconfBrowserAndroid::doResolveService(CZeroconfBrowser::ZeroconfService& fr_service, double f_timeout)
103 jni::CJNINsdServiceInfo service;
104 service.setServiceName(fr_service.GetName());
105 service.setServiceType(fr_service.GetType());
107 CZeroconfBrowserAndroidResolve resolver;
108 m_manager.resolveService(service, resolver);
110 if (!resolver.m_resolutionDone.Wait(std::chrono::duration<double, std::milli>(f_timeout * 1000)))
112 CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve Timeout error");
113 return false;
116 if (resolver.m_errorCode != -1)
118 CLog::Log(LOGERROR, "ZeroconfBrowserAndroid: DNSServiceResolve returned (error = {})",
119 resolver.m_errorCode);
120 return false;
123 fr_service.SetHostname(resolver.m_retServiceInfo.getHost().getHostName());
124 fr_service.SetIP(resolver.m_retServiceInfo.getHost().getHostAddress());
125 fr_service.SetPort(resolver.m_retServiceInfo.getPort());
127 CZeroconfBrowser::ZeroconfService::tTxtRecordMap recordMap;
128 jni::CJNISet<jni::jhstring> txtKey = resolver.m_retServiceInfo.getAttributes().keySet();
129 jni::CJNIIterator<jni::jhstring> it = txtKey.iterator();
130 while (it.hasNext())
132 jni::jhstring k = it.next();
133 jni::jhbyteArray v = resolver.m_retServiceInfo.getAttributes().get(k);
135 std::string key = jni::jcast<std::string>(k);
136 std::vector<char> vv = jni::jcast<std::vector<char>>(v);
137 std::string value = std::string(vv.begin(), vv.end());
139 CLog::Log(LOGDEBUG, "ZeroconfBrowserAndroid: TXT record {} = {} ({})", key, value, vv.size());
141 recordMap.insert(std::make_pair(key, value));
143 fr_service.SetTxtRecords(recordMap);
144 return (!fr_service.GetIP().empty());
147 /// adds the service to list of found services
148 void CZeroconfBrowserAndroid::addDiscoveredService(CZeroconfBrowserAndroidDiscover* browser, CZeroconfBrowser::ZeroconfService const& fcr_service)
150 std::unique_lock<CCriticalSection> lock(m_data_guard);
151 tDiscoveredServicesMap::iterator browserIt = m_discovered_services.find(browser);
152 if(browserIt == m_discovered_services.end())
154 //first service by this browser
155 browserIt = m_discovered_services.insert(make_pair(browser, std::vector<std::pair<ZeroconfService, unsigned int> >())).first;
157 //search this service
158 std::vector<std::pair<ZeroconfService, unsigned int> >& services = browserIt->second;
159 std::vector<std::pair<ZeroconfService, unsigned int> >::iterator serviceIt = services.begin();
160 for( ; serviceIt != services.end(); ++serviceIt)
162 if(serviceIt->first == fcr_service)
163 break;
165 if(serviceIt == services.end())
166 services.emplace_back(fcr_service, 1);
167 else
168 ++serviceIt->second;
171 void CZeroconfBrowserAndroid::removeDiscoveredService(CZeroconfBrowserAndroidDiscover* browser, CZeroconfBrowser::ZeroconfService const& fcr_service)
173 std::unique_lock<CCriticalSection> lock(m_data_guard);
174 tDiscoveredServicesMap::iterator browserIt = m_discovered_services.find(browser);
175 //search this service
176 std::vector<std::pair<ZeroconfService, unsigned int> >& services = browserIt->second;
177 std::vector<std::pair<ZeroconfService, unsigned int> >::iterator serviceIt = services.begin();
178 for( ; serviceIt != services.end(); ++serviceIt)
179 if(serviceIt->first == fcr_service)
180 break;
181 if(serviceIt != services.end())
183 //decrease refCount
184 --serviceIt->second;
185 if(!serviceIt->second)
187 //eventually remove the service
188 services.erase(serviceIt);
190 } else
192 //looks like we missed the announce, no problem though..
197 /******************************************************************/
199 CZeroconfBrowserAndroidDiscover::CZeroconfBrowserAndroidDiscover(CZeroconfBrowserAndroid* browser)
200 : CJNIXBMCNsdManagerDiscoveryListener(), m_browser(browser)
204 void CZeroconfBrowserAndroidDiscover::onDiscoveryStarted(const std::string& serviceType)
206 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onDiscoveryStarted type: {}", serviceType);
207 m_isActive = true;
210 void CZeroconfBrowserAndroidDiscover::onDiscoveryStopped(const std::string& serviceType)
212 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onDiscoveryStopped type: {}", serviceType);
213 m_isActive = false;
216 void CZeroconfBrowserAndroidDiscover::onServiceFound(const jni::CJNINsdServiceInfo& serviceInfo)
218 //store the service
219 CZeroconfBrowser::ZeroconfService s(serviceInfo.getServiceName(), serviceInfo.getServiceType(), "local");
220 jni::CJNISet<jni::jhstring> txtKey = serviceInfo.getAttributes().keySet();
221 jni::CJNIIterator<jni::jhstring> it = txtKey.iterator();
222 while (it.hasNext())
224 jni::jhstring k = it.next();
225 jni::jhbyteArray v = serviceInfo.getAttributes().get(k);
227 std::string key = jni::jcast<std::string>(k);
228 std::vector<char> vv = jni::jcast<std::vector<char>>(v);
229 std::string value = std::string(vv.begin(), vv.end());
231 CLog::Log(LOGDEBUG, "ZeroconfBrowserAndroid::onServiceFound: TXT record {} = {} ({})", key,
232 value, vv.size());
235 CLog::Log(LOGDEBUG,
236 "CZeroconfBrowserAndroidDiscover::onServiceFound found service named: {}, type: {}, "
237 "domain: {}",
238 s.GetName(), s.GetType(), s.GetDomain());
239 m_browser->addDiscoveredService(this, s);
241 CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::Sources, "OnUpdated",
242 CVariant{"zeroconf://"});
243 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onServiceFound sent source update announce "
244 "for path zeroconf://");
247 void CZeroconfBrowserAndroidDiscover::onServiceLost(const jni::CJNINsdServiceInfo& serviceInfo)
249 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onServiceLost name: {}, type: {}",
250 serviceInfo.getServiceName(), serviceInfo.getServiceType());
253 void CZeroconfBrowserAndroidDiscover::onStartDiscoveryFailed(const std::string& serviceType, int errorCode)
255 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onStartDiscoveryFailed type: {}, error: {}",
256 serviceType, errorCode);
257 m_isActive = false;
260 void CZeroconfBrowserAndroidDiscover::onStopDiscoveryFailed(const std::string& serviceType, int errorCode)
262 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidDiscover::onStopDiscoveryFailed type: {}, error: {}",
263 serviceType, errorCode);
264 m_isActive = false;
267 /***************************************/
269 CZeroconfBrowserAndroidResolve::CZeroconfBrowserAndroidResolve()
270 : CJNIXBMCNsdManagerResolveListener()
274 void CZeroconfBrowserAndroidResolve::onResolveFailed(const jni::CJNINsdServiceInfo& serviceInfo, int errorCode)
276 CLog::Log(LOGDEBUG,
277 "CZeroconfBrowserAndroidResolve::onResolveFailed name: {}, type: {}, error: {}",
278 serviceInfo.getServiceName(), serviceInfo.getServiceType(), errorCode);
279 m_errorCode = errorCode;
280 m_resolutionDone.Set();
283 void CZeroconfBrowserAndroidResolve::onServiceResolved(const jni::CJNINsdServiceInfo& serviceInfo)
285 CLog::Log(LOGDEBUG, "CZeroconfBrowserAndroidResolve::onServiceResolved name: {}, type: {}",
286 serviceInfo.getServiceName(), serviceInfo.getServiceType());
287 m_errorCode = -1;
288 m_retServiceInfo = serviceInfo;
289 m_resolutionDone.Set();