OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h" | 5 #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
9 #include "chrome/common/media_router/discovery/media_sink_internal.h" | 9 #include "chrome/common/media_router/discovery/media_sink_internal.h" |
10 #include "components/cast_channel/cast_socket_service.h" | 10 #include "components/cast_channel/cast_socket_service.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 enum ErrorType { | 21 enum ErrorType { |
22 NONE, | 22 NONE, |
23 NOT_CAST_DEVICE, | 23 NOT_CAST_DEVICE, |
24 MISSING_ID, | 24 MISSING_ID, |
25 MISSING_FRIENDLY_NAME, | 25 MISSING_FRIENDLY_NAME, |
26 MISSING_OR_INVALID_IP_ADDRESS, | 26 MISSING_OR_INVALID_IP_ADDRESS, |
27 MISSING_OR_INVALID_PORT, | 27 MISSING_OR_INVALID_PORT, |
28 }; | 28 }; |
29 | 29 |
30 ErrorType CreateCastMediaSink(const media_router::DnsSdService& service, | 30 ErrorType CreateCastMediaSink(const media_router::DnsSdService& service, |
31 int channel_id, | |
32 bool audio_only, | |
33 media_router::MediaSinkInternal* cast_sink) { | 31 media_router::MediaSinkInternal* cast_sink) { |
34 DCHECK(cast_sink); | 32 DCHECK(cast_sink); |
35 if (service.service_name.find( | 33 if (service.service_name.find( |
36 media_router::CastMediaSinkService::kCastServiceType) == | 34 media_router::CastMediaSinkService::kCastServiceType) == |
37 std::string::npos) | 35 std::string::npos) |
38 return ErrorType::NOT_CAST_DEVICE; | 36 return ErrorType::NOT_CAST_DEVICE; |
39 | 37 |
40 net::IPAddress ip_address; | 38 net::IPAddress ip_address; |
41 if (!ip_address.AssignFromIPLiteral(service.ip_address)) | 39 if (!ip_address.AssignFromIPLiteral(service.ip_address)) |
42 return ErrorType::MISSING_OR_INVALID_IP_ADDRESS; | 40 return ErrorType::MISSING_OR_INVALID_IP_ADDRESS; |
43 | 41 |
| 42 // TODO(zhaobin): Make DnsSdService's service_host_port take net::HostPortPair |
| 43 // type instead of plain string. |
| 44 net::HostPortPair host_port_pair = |
| 45 net::HostPortPair::FromString(service.service_host_port); |
| 46 int port = host_port_pair.port(); |
| 47 |
44 std::map<std::string, std::string> service_data; | 48 std::map<std::string, std::string> service_data; |
45 for (const auto& item : service.service_data) { | 49 for (const auto& item : service.service_data) { |
46 // |item| format should be "id=xxxxxx", etc. | 50 // |item| format should be "id=xxxxxx", etc. |
47 size_t split_idx = item.find('='); | 51 size_t split_idx = item.find('='); |
48 if (split_idx == std::string::npos) | 52 if (split_idx == std::string::npos) |
49 continue; | 53 continue; |
50 | 54 |
51 std::string key = item.substr(0, split_idx); | 55 std::string key = item.substr(0, split_idx); |
52 std::string val = | 56 std::string val = |
53 split_idx < item.length() ? item.substr(split_idx + 1) : ""; | 57 split_idx < item.length() ? item.substr(split_idx + 1) : ""; |
54 service_data[key] = val; | 58 service_data[key] = val; |
55 } | 59 } |
56 | 60 |
57 // When use this "sink" within browser, please note it will have a different | 61 // When use this "sink" within browser, please note it will have a different |
58 // ID when it is sent to the extension, because it derives a different sink ID | 62 // ID when it is sent to the extension, because it derives a different sink ID |
59 // using the given sink ID. | 63 // using the given sink ID. |
60 std::string unique_id = service_data["id"]; | 64 std::string unique_id = service_data["id"]; |
61 if (unique_id.empty()) | 65 if (unique_id.empty()) |
62 return ErrorType::MISSING_ID; | 66 return ErrorType::MISSING_ID; |
63 std::string friendly_name = service_data["fn"]; | 67 std::string friendly_name = service_data["fn"]; |
64 if (friendly_name.empty()) | 68 if (friendly_name.empty()) |
65 return ErrorType::MISSING_FRIENDLY_NAME; | 69 return ErrorType::MISSING_FRIENDLY_NAME; |
66 media_router::MediaSink sink(unique_id, friendly_name, | 70 media_router::MediaSink sink(unique_id, friendly_name, |
67 media_router::MediaSink::IconType::CAST); | 71 media_router::MediaSink::IconType::CAST); |
68 | 72 |
69 media_router::CastSinkExtraData extra_data; | 73 media_router::CastSinkExtraData extra_data; |
70 extra_data.ip_address = ip_address; | 74 extra_data.ip_address = ip_address; |
71 extra_data.model_name = service_data["md"]; | 75 extra_data.model_name = service_data["md"]; |
72 extra_data.capabilities = cast_channel::CastDeviceCapability::AUDIO_OUT; | 76 extra_data.port = port; |
73 if (!audio_only) | 77 extra_data.discovered_by_dial = false; |
74 extra_data.capabilities |= cast_channel::CastDeviceCapability::VIDEO_OUT; | |
75 extra_data.cast_channel_id = channel_id; | |
76 | 78 |
77 cast_sink->set_sink(sink); | 79 cast_sink->set_sink(sink); |
78 cast_sink->set_cast_data(extra_data); | 80 cast_sink->set_cast_data(extra_data); |
79 | 81 |
80 return ErrorType::NONE; | 82 return ErrorType::NONE; |
81 } | 83 } |
82 | 84 |
| 85 static media_router::MediaSinkInternal CreateCastSinkFromDialSink( |
| 86 const media_router::MediaSinkInternal& dial_sink) { |
| 87 std::string unique_id = dial_sink.sink().id(); |
| 88 std::string friendly_name = dial_sink.sink().name(); |
| 89 media_router::MediaSink sink(unique_id, friendly_name, |
| 90 media_router::MediaSink::IconType::CAST); |
| 91 |
| 92 media_router::CastSinkExtraData extra_data; |
| 93 extra_data.ip_address = dial_sink.dial_data().ip_address; |
| 94 extra_data.port = media_router::CastMediaSinkService::kCastControlPort; |
| 95 extra_data.model_name = dial_sink.dial_data().model_name; |
| 96 extra_data.discovered_by_dial = true; |
| 97 |
| 98 return media_router::MediaSinkInternal(sink, extra_data); |
| 99 } |
| 100 |
83 } // namespace | 101 } // namespace |
84 | 102 |
85 namespace media_router { | 103 namespace media_router { |
86 | 104 |
87 // static | 105 // static |
88 const char CastMediaSinkService::kCastServiceType[] = "_googlecast._tcp.local"; | 106 const char CastMediaSinkService::kCastServiceType[] = "_googlecast._tcp.local"; |
89 | 107 |
| 108 // static |
| 109 const int CastMediaSinkService::kCastControlPort = 8009; |
| 110 |
90 CastMediaSinkService::CastMediaSinkService( | 111 CastMediaSinkService::CastMediaSinkService( |
91 const OnSinksDiscoveredCallback& callback, | 112 const OnSinksDiscoveredCallback& callback, |
92 content::BrowserContext* browser_context) | 113 content::BrowserContext* browser_context) |
93 : MediaSinkServiceBase(callback) { | 114 : MediaSinkServiceBase(callback) { |
94 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | 115 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
95 cast_socket_service_ = cast_channel::CastSocketServiceFactory::GetInstance() | 116 cast_socket_service_ = cast_channel::CastSocketServiceFactory::GetInstance() |
96 ->GetForBrowserContext(browser_context); | 117 ->GetForBrowserContext(browser_context); |
97 DCHECK(cast_socket_service_); | 118 DCHECK(cast_socket_service_); |
98 } | 119 } |
99 | 120 |
100 CastMediaSinkService::CastMediaSinkService( | 121 CastMediaSinkService::CastMediaSinkService( |
101 const OnSinksDiscoveredCallback& callback, | 122 const OnSinksDiscoveredCallback& callback, |
102 cast_channel::CastSocketService* cast_socket_service) | 123 cast_channel::CastSocketService* cast_socket_service) |
103 : MediaSinkServiceBase(callback), | 124 : MediaSinkServiceBase(callback), |
104 cast_socket_service_(cast_socket_service) { | 125 cast_socket_service_(cast_socket_service) { |
105 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | 126 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
106 DCHECK(cast_socket_service_); | 127 DCHECK(cast_socket_service_); |
107 } | 128 } |
108 | 129 |
109 CastMediaSinkService::~CastMediaSinkService() {} | 130 CastMediaSinkService::~CastMediaSinkService() {} |
110 | 131 |
111 void CastMediaSinkService::Start() { | 132 void CastMediaSinkService::Start() { |
112 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | 133 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
113 if (dns_sd_registry_) | 134 if (dns_sd_registry_) |
114 return; | 135 return; |
115 | 136 |
116 dns_sd_registry_ = DnsSdRegistry::GetInstance(); | 137 dns_sd_registry_ = DnsSdRegistry::GetInstance(); |
117 dns_sd_registry_->AddObserver(this); | 138 dns_sd_registry_->AddObserver(this); |
118 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType); | 139 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType); |
119 MediaSinkServiceBase::StartTimer(); | 140 MediaSinkServiceBase::StartTimer(); |
120 } | 141 } |
121 | 142 |
122 void CastMediaSinkService::Stop() { | 143 void CastMediaSinkService::Stop() { |
123 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | 144 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
124 if (!dns_sd_registry_) | 145 if (!dns_sd_registry_) |
125 return; | 146 return; |
126 | 147 |
127 dns_sd_registry_->UnregisterDnsSdListener(kCastServiceType); | 148 dns_sd_registry_->UnregisterDnsSdListener(kCastServiceType); |
128 dns_sd_registry_->RemoveObserver(this); | 149 dns_sd_registry_->RemoveObserver(this); |
129 dns_sd_registry_ = nullptr; | 150 dns_sd_registry_ = nullptr; |
130 MediaSinkServiceBase::StopTimer(); | 151 MediaSinkServiceBase::StopTimer(); |
131 } | 152 } |
132 | 153 |
133 void CastMediaSinkService::SetDnsSdRegistryForTest(DnsSdRegistry* registry) { | 154 void CastMediaSinkService::SetDnsSdRegistryForTest(DnsSdRegistry* registry) { |
134 DCHECK(!dns_sd_registry_); | 155 DCHECK(!dns_sd_registry_); |
135 dns_sd_registry_ = registry; | 156 dns_sd_registry_ = registry; |
136 dns_sd_registry_->AddObserver(this); | 157 dns_sd_registry_->AddObserver(this); |
137 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType); | 158 dns_sd_registry_->RegisterDnsSdListener(kCastServiceType); |
138 MediaSinkServiceBase::StartTimer(); | 159 MediaSinkServiceBase::StartTimer(); |
139 } | 160 } |
140 | 161 |
| 162 void CastMediaSinkService::OnFetchCompleted() { |
| 163 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 164 |
| 165 auto task_runner = content::BrowserThread::GetTaskRunnerForThread( |
| 166 content::BrowserThread::IO); |
| 167 base::PostTaskAndReplyWithResult( |
| 168 task_runner.get(), FROM_HERE, |
| 169 base::BindOnce(&CastMediaSinkService::GetCastSinksOnIOThread, this), |
| 170 base::BindOnce(&CastMediaSinkService::OnFetchCompletedOnUIThread, this)); |
| 171 } |
| 172 |
| 173 std::set<MediaSinkInternal> CastMediaSinkService::GetCastSinksOnIOThread() { |
| 174 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 175 |
| 176 std::set<MediaSinkInternal> sinks; |
| 177 // Copy cast sink from mDNS service to |current_sinks_|. |
| 178 for (const auto& sink_it : current_sinks_by_mdns_) { |
| 179 DVLOG(2) << "Discovered by mdns [name]: " << sink_it.second.sink().name(); |
| 180 sinks.insert(sink_it.second); |
| 181 } |
| 182 |
| 183 // Copy cast sink from DIAL discovery to |current_sinks_|. |
| 184 for (const auto& sink_it : current_sinks_by_dial_) { |
| 185 DVLOG(2) << "Discovered by dial [name]: " << sink_it.second.sink().name(); |
| 186 if (!base::ContainsKey(current_sinks_by_mdns_, sink_it.first)) |
| 187 sinks.insert(sink_it.second); |
| 188 } |
| 189 return sinks; |
| 190 } |
| 191 |
| 192 void CastMediaSinkService::OnFetchCompletedOnUIThread( |
| 193 std::set<MediaSinkInternal> cast_sinks) { |
| 194 MediaSinkServiceBase::current_sinks_ = cast_sinks; |
| 195 MediaSinkServiceBase::OnFetchCompleted(); |
| 196 } |
| 197 |
141 void CastMediaSinkService::OnDnsSdEvent( | 198 void CastMediaSinkService::OnDnsSdEvent( |
142 const std::string& service_type, | 199 const std::string& service_type, |
143 const DnsSdRegistry::DnsSdServiceList& services) { | 200 const DnsSdRegistry::DnsSdServiceList& services) { |
144 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | 201 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
145 DVLOG(2) << "CastMediaSinkService::OnDnsSdEvent found " << services.size() | 202 DVLOG(2) << "CastMediaSinkService::OnDnsSdEvent found " << services.size() |
146 << " services"; | 203 << " services"; |
147 | 204 |
148 current_sinks_.clear(); | 205 std::vector<MediaSinkInternal> cast_sinks; |
149 current_services_ = services; | |
150 | |
151 for (const auto& service : services) { | 206 for (const auto& service : services) { |
152 net::IPAddress ip_address; | 207 // Create Cast sink from mDNS service description. |
153 if (!ip_address.AssignFromIPLiteral(service.ip_address)) { | 208 MediaSinkInternal cast_sink; |
154 DVLOG(2) << "Invalid ip_addresss: " << service.ip_address; | 209 ErrorType error = CreateCastMediaSink(service, &cast_sink); |
| 210 if (error != ErrorType::NONE) { |
| 211 DVLOG(2) << "Fail to create Cast device [error]: " << error; |
155 continue; | 212 continue; |
156 } | 213 } |
157 net::HostPortPair host_port_pair = | |
158 net::HostPortPair::FromString(service.service_host_port); | |
159 | 214 |
160 content::BrowserThread::PostTask( | 215 cast_sinks.push_back(std::move(cast_sink)); |
161 content::BrowserThread::IO, FROM_HERE, | |
162 base::Bind(&CastMediaSinkService::OpenChannelOnIOThread, this, service, | |
163 net::IPEndPoint(ip_address, host_port_pair.port()))); | |
164 } | 216 } |
165 | 217 |
| 218 content::BrowserThread::PostTask( |
| 219 content::BrowserThread::IO, FROM_HERE, |
| 220 base::Bind(&CastMediaSinkService::OpenChannelsOnIOThread, this, |
| 221 std::move(cast_sinks))); |
| 222 |
166 MediaSinkServiceBase::RestartTimer(); | 223 MediaSinkServiceBase::RestartTimer(); |
167 } | 224 } |
168 | 225 |
| 226 void CastMediaSinkService::OpenChannelsOnIOThread( |
| 227 std::vector<MediaSinkInternal> cast_sinks) { |
| 228 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 229 |
| 230 current_sinks_by_mdns_.clear(); |
| 231 current_service_ip_endpoints_.clear(); |
| 232 |
| 233 for (const auto& cast_sink : cast_sinks) { |
| 234 net::IPEndPoint ip_endpoint(cast_sink.cast_data().ip_address, |
| 235 cast_sink.cast_data().port); |
| 236 current_service_ip_endpoints_.insert(ip_endpoint); |
| 237 |
| 238 OpenChannelOnIOThread(ip_endpoint, cast_sink); |
| 239 } |
| 240 } |
| 241 |
| 242 void CastMediaSinkService::OnDialSinkAdded(const MediaSinkInternal& sink) { |
| 243 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 244 |
| 245 auto ip_address = sink.dial_data().ip_address; |
| 246 net::IPEndPoint ip_endpoint(ip_address, kCastControlPort); |
| 247 |
| 248 if (base::ContainsKey(current_service_ip_endpoints_, ip_endpoint)) { |
| 249 DVLOG(2) << "Sink discovered by mDNS, skip adding [name]: " |
| 250 << sink.sink().name(); |
| 251 return; |
| 252 } |
| 253 |
| 254 OpenChannelOnIOThread(ip_endpoint, CreateCastSinkFromDialSink(sink)); |
| 255 } |
| 256 |
| 257 void CastMediaSinkService::OnDialSinksRemoved() { |
| 258 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 259 |
| 260 current_sinks_by_dial_.clear(); |
| 261 } |
| 262 |
169 void CastMediaSinkService::OpenChannelOnIOThread( | 263 void CastMediaSinkService::OpenChannelOnIOThread( |
170 const DnsSdService& service, | 264 const net::IPEndPoint& ip_endpoint, |
171 const net::IPEndPoint& ip_endpoint) { | 265 MediaSinkInternal cast_sink) { |
172 auto* observer = cast_socket_service_->GetObserver(kObserverId); | 266 auto* observer = cast_socket_service_->GetObserver(kObserverId); |
173 if (!observer) { | 267 if (!observer) { |
174 observer = new CastSocketObserver(); | 268 observer = new CastSocketObserver(); |
175 cast_socket_service_->AddObserver(kObserverId, base::WrapUnique(observer)); | 269 cast_socket_service_->AddObserver(kObserverId, base::WrapUnique(observer)); |
176 } | 270 } |
177 | 271 |
| 272 // TODO(zhaobin): Use base::BindOnce instead of base::Bind here. |
178 cast_socket_service_->OpenSocket( | 273 cast_socket_service_->OpenSocket( |
179 ip_endpoint, g_browser_process->net_log(), | 274 ip_endpoint, g_browser_process->net_log(), |
180 base::Bind(&CastMediaSinkService::OnChannelOpenedOnIOThread, this, | 275 base::Bind(&CastMediaSinkService::OnChannelOpenedOnIOThread, this, |
181 service), | 276 std::move(cast_sink)), |
182 observer); | 277 observer); |
183 } | 278 } |
184 | 279 |
185 void CastMediaSinkService::OnChannelOpenedOnIOThread( | 280 void CastMediaSinkService::OnChannelOpenedOnIOThread( |
186 const DnsSdService& service, | 281 MediaSinkInternal cast_sink, |
187 int channel_id, | 282 int channel_id, |
188 cast_channel::ChannelError channel_error) { | 283 cast_channel::ChannelError channel_error) { |
189 if (channel_error != cast_channel::ChannelError::NONE) { | 284 if (channel_error != cast_channel::ChannelError::NONE) { |
190 DVLOG(2) << "Fail to open channel " << service.ip_address << ": " | 285 DVLOG(2) << "Fail to open channel " |
191 << service.service_host_port | 286 << cast_sink.cast_data().ip_address.ToString() |
| 287 << " [name]: " << cast_sink.sink().name() |
192 << " [ChannelError]: " << (int)channel_error; | 288 << " [ChannelError]: " << (int)channel_error; |
193 return; | 289 return; |
194 } | 290 } |
195 | 291 |
196 auto* socket = cast_socket_service_->GetSocket(channel_id); | 292 auto* socket = cast_socket_service_->GetSocket(channel_id); |
197 if (!socket) { | 293 if (!socket) { |
198 DVLOG(2) << "Fail to find socket with [channel_id]: " << channel_id; | 294 DVLOG(2) << "Fail to find socket with [channel_id]: " << channel_id; |
199 return; | 295 return; |
200 } | 296 } |
201 | 297 |
| 298 // Skip adding if IP address not found in current round of mDNS discovery. |
| 299 net::IPEndPoint ip_endpoint(cast_sink.cast_data().ip_address, |
| 300 cast_sink.cast_data().port); |
| 301 if (!cast_sink.cast_data().discovered_by_dial) { |
| 302 if (current_service_ip_endpoints_.find(ip_endpoint) == |
| 303 current_service_ip_endpoints_.end()) { |
| 304 DVLOG(2) << "Service data not found in current service data list..." |
| 305 << ip_endpoint.ToString(); |
| 306 return; |
| 307 } |
| 308 } |
| 309 |
| 310 media_router::CastSinkExtraData extra_data = cast_sink.cast_data(); |
| 311 extra_data.capabilities = cast_channel::CastDeviceCapability::AUDIO_OUT; |
| 312 if (!socket->audio_only()) |
| 313 extra_data.capabilities |= cast_channel::CastDeviceCapability::VIDEO_OUT; |
| 314 extra_data.cast_channel_id = channel_id; |
| 315 |
| 316 MediaSinkInternal updated_sink(cast_sink.sink(), extra_data); |
| 317 DVLOG(2) << "Ading sink to current_sinks_ [name]: " |
| 318 << updated_sink.sink().name(); |
| 319 |
| 320 // Add or update existing cast sink. |
| 321 if (updated_sink.cast_data().discovered_by_dial) { |
| 322 current_sinks_by_dial_[ip_endpoint] = updated_sink; |
| 323 } else { |
| 324 current_sinks_by_mdns_[ip_endpoint] = updated_sink; |
| 325 } |
| 326 |
202 content::BrowserThread::PostTask( | 327 content::BrowserThread::PostTask( |
203 content::BrowserThread::UI, FROM_HERE, | 328 content::BrowserThread::UI, FROM_HERE, |
204 base::Bind(&CastMediaSinkService::OnChannelOpenedOnUIThread, this, | 329 base::Bind(&CastMediaSinkService::RestartTimer, this)); |
205 service, channel_id, socket->audio_only())); | |
206 } | |
207 | |
208 void CastMediaSinkService::OnChannelOpenedOnUIThread( | |
209 const DnsSdService& service, | |
210 int channel_id, | |
211 bool audio_only) { | |
212 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | |
213 MediaSinkInternal sink; | |
214 ErrorType error = CreateCastMediaSink(service, channel_id, audio_only, &sink); | |
215 if (error != ErrorType::NONE) { | |
216 DVLOG(2) << "Fail to create Cast device [error]: " << error; | |
217 return; | |
218 } | |
219 | |
220 if (!base::ContainsValue(current_services_, service)) { | |
221 DVLOG(2) << "Service data not found in current service data list..."; | |
222 return; | |
223 } | |
224 | |
225 DVLOG(2) << "Ading sink to current_sinks_ [id]: " << sink.sink().id(); | |
226 current_sinks_.insert(sink); | |
227 MediaSinkServiceBase::RestartTimer(); | |
228 } | 330 } |
229 | 331 |
230 CastMediaSinkService::CastSocketObserver::CastSocketObserver() {} | 332 CastMediaSinkService::CastSocketObserver::CastSocketObserver() {} |
231 CastMediaSinkService::CastSocketObserver::~CastSocketObserver() {} | 333 CastMediaSinkService::CastSocketObserver::~CastSocketObserver() {} |
232 | 334 |
233 void CastMediaSinkService::CastSocketObserver::OnError( | 335 void CastMediaSinkService::CastSocketObserver::OnError( |
234 const cast_channel::CastSocket& socket, | 336 const cast_channel::CastSocket& socket, |
235 cast_channel::ChannelError error_state) { | 337 cast_channel::ChannelError error_state) { |
236 DVLOG(1) << "OnError [ip_endpoint]: " << socket.ip_endpoint().ToString() | 338 DVLOG(1) << "OnError [ip_endpoint]: " << socket.ip_endpoint().ToString() |
237 << " [error_state]: " | 339 << " [error_state]: " |
238 << cast_channel::ChannelErrorToString(error_state); | 340 << cast_channel::ChannelErrorToString(error_state); |
239 } | 341 } |
240 | 342 |
241 void CastMediaSinkService::CastSocketObserver::OnMessage( | 343 void CastMediaSinkService::CastSocketObserver::OnMessage( |
242 const cast_channel::CastSocket& socket, | 344 const cast_channel::CastSocket& socket, |
243 const cast_channel::CastMessage& message) {} | 345 const cast_channel::CastMessage& message) {} |
244 | 346 |
245 } // namespace media_router | 347 } // namespace media_router |
OLD | NEW |