Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/media_router_mojo_impl.h" | 5 #include "chrome/browser/media/router/media_router_mojo_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/guid.h" | 8 #include "base/guid.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
| 11 #include "base/observer_list.h" | 11 #include "base/observer_list.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "chrome/browser/media/router/media_router_factory.h" | 13 #include "chrome/browser/media/router/media_router_factory.h" |
| 14 #include "chrome/browser/media/router/media_router_type_converters.h" | 14 #include "chrome/browser/media/router/media_router_type_converters.h" |
| 15 #include "chrome/browser/media/router/media_routes_observer.h" | 15 #include "chrome/browser/media/router/media_routes_observer.h" |
| 16 #include "chrome/browser/media/router/media_sinks_observer.h" | 16 #include "chrome/browser/media/router/media_sinks_observer.h" |
| 17 #include "chrome/browser/media/router/presentation_session_messages_observer.h" | |
| 17 #include "extensions/browser/process_manager.h" | 18 #include "extensions/browser/process_manager.h" |
| 18 | 19 |
| 19 #define DVLOG_WITH_INSTANCE(level) \ | 20 #define DVLOG_WITH_INSTANCE(level) \ |
| 20 DVLOG(level) << "MR #" << instance_id_ << ": " | 21 DVLOG(level) << "MR #" << instance_id_ << ": " |
| 21 | 22 |
| 22 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": " | 23 #define DLOG_WITH_INSTANCE(level) DLOG(level) << "MR #" << instance_id_ << ": " |
| 23 | 24 |
| 24 namespace media_router { | 25 namespace media_router { |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute() | 28 // Converts the callback result of calling Mojo CreateRoute()/JoinRoute() |
| 28 // into a local callback. | 29 // into a local callback. |
| 29 void RouteResponseReceived( | 30 void RouteResponseReceived( |
| 31 const std::string& presentation_id, | |
| 30 const std::vector<MediaRouteResponseCallback>& callbacks, | 32 const std::vector<MediaRouteResponseCallback>& callbacks, |
| 31 interfaces::MediaRoutePtr media_route, | 33 interfaces::MediaRoutePtr media_route, |
| 32 const mojo::String& error_text) { | 34 const mojo::String& error_text) { |
| 33 scoped_ptr<MediaRoute> route; | 35 scoped_ptr<MediaRoute> route; |
| 36 std::string actual_presentation_id; | |
| 34 std::string error; | 37 std::string error; |
| 35 if (media_route.is_null()) { | 38 if (media_route.is_null()) { |
| 36 // An error occurred. | 39 // An error occurred. |
| 37 DCHECK(!error_text.is_null()); | 40 DCHECK(!error_text.is_null()); |
| 38 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; | 41 error = !error_text.get().empty() ? error_text.get() : "Unknown error."; |
| 39 } else { | 42 } else { |
| 40 route = media_route.To<scoped_ptr<MediaRoute>>(); | 43 route = media_route.To<scoped_ptr<MediaRoute>>(); |
| 44 actual_presentation_id = presentation_id; | |
| 41 } | 45 } |
| 42 | 46 |
| 43 for (const MediaRouteResponseCallback& callback : callbacks) | 47 for (const MediaRouteResponseCallback& callback : callbacks) |
| 44 callback.Run(route.get(), error); | 48 callback.Run(route.get(), actual_presentation_id, error); |
| 45 } | 49 } |
| 46 | 50 |
| 47 // TODO(imcheng): We should handle failure in this case. One way is to invoke | 51 // TODO(imcheng): We should handle failure in this case. One way is to invoke |
| 48 // all pending requests with failure. (crbug.com/490787) | 52 // all pending requests with failure. (crbug.com/490787) |
| 49 void EventPageWakeComplete(bool success) { | 53 void EventPageWakeComplete(bool success) { |
| 50 if (!success) | 54 if (!success) |
| 51 LOG(ERROR) << "An error encountered while waking the event page."; | 55 LOG(ERROR) << "An error encountered while waking the event page."; |
| 52 } | 56 } |
| 53 | 57 |
| 54 scoped_ptr<content::PresentationSessionMessage> | 58 scoped_ptr<content::PresentationSessionMessage> |
| 55 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { | 59 ConvertToPresentationSessionMessage(interfaces::RouteMessagePtr input) { |
| 56 DCHECK(!input.is_null()); | 60 DCHECK(!input.is_null()); |
| 57 const auto& id_and_url = GetPresentationIdAndUrl(input->route_id); | |
| 58 const std::string& presentation_id = id_and_url.first; | |
| 59 const std::string& presentation_url = id_and_url.second; | |
| 60 scoped_ptr<content::PresentationSessionMessage> output; | 61 scoped_ptr<content::PresentationSessionMessage> output; |
| 61 switch (input->type) { | 62 switch (input->type) { |
| 62 case interfaces::RouteMessage::Type::TYPE_TEXT: { | 63 case interfaces::RouteMessage::Type::TYPE_TEXT: { |
| 63 DCHECK(!input->message.is_null()); | 64 DCHECK(!input->message.is_null()); |
| 64 DCHECK(input->data.is_null()); | 65 DCHECK(input->data.is_null()); |
| 65 output = content::PresentationSessionMessage::CreateStringMessage( | 66 output.reset(new content::PresentationSessionMessage( |
| 66 presentation_url, presentation_id, make_scoped_ptr(new std::string)); | 67 content::PresentationMessageType::TEXT)); |
| 67 input->message.Swap(output->message.get()); | 68 input->message.Swap(&output->message); |
| 68 return output.Pass(); | 69 return output.Pass(); |
| 69 } | 70 } |
| 70 case interfaces::RouteMessage::Type::TYPE_BINARY: { | 71 case interfaces::RouteMessage::Type::TYPE_BINARY: { |
| 71 DCHECK(!input->data.is_null()); | 72 DCHECK(!input->data.is_null()); |
| 72 DCHECK(input->message.is_null()); | 73 DCHECK(input->message.is_null()); |
| 73 output = content::PresentationSessionMessage::CreateArrayBufferMessage( | 74 output.reset(new content::PresentationSessionMessage( |
| 74 presentation_url, presentation_id, | 75 content::PresentationMessageType::ARRAY_BUFFER)); |
| 75 make_scoped_ptr(new std::vector<uint8_t>)); | 76 input->data.Swap(&output->data); |
| 76 input->data.Swap(output->data.get()); | |
| 77 return output.Pass(); | 77 return output.Pass(); |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 NOTREACHED() << "Invalid route message type " << input->type; | 81 NOTREACHED() << "Invalid route message type " << input->type; |
| 82 return output.Pass(); | 82 return output.Pass(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 } // namespace | 85 } // namespace |
| 86 | 86 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 const MediaSource::Id& source_id, | 192 const MediaSource::Id& source_id, |
| 193 const MediaSink::Id& sink_id, | 193 const MediaSink::Id& sink_id, |
| 194 const GURL& origin, | 194 const GURL& origin, |
| 195 int tab_id, | 195 int tab_id, |
| 196 const std::vector<MediaRouteResponseCallback>& callbacks) { | 196 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 197 DCHECK(thread_checker_.CalledOnValidThread()); | 197 DCHECK(thread_checker_.CalledOnValidThread()); |
| 198 | 198 |
| 199 if (!origin.is_valid()) { | 199 if (!origin.is_valid()) { |
| 200 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | 200 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
| 201 for (const MediaRouteResponseCallback& callback : callbacks) | 201 for (const MediaRouteResponseCallback& callback : callbacks) |
| 202 callback.Run(nullptr, "Invalid origin"); | 202 callback.Run(nullptr, "", "Invalid origin"); |
| 203 return; | 203 return; |
| 204 } | 204 } |
| 205 RunOrDefer(base::Bind( | 205 RunOrDefer(base::Bind( |
| 206 &MediaRouterMojoImpl::DoCreateRoute, base::Unretained(this), source_id, | 206 &MediaRouterMojoImpl::DoCreateRoute, base::Unretained(this), source_id, |
| 207 sink_id, origin.is_empty() ? "" : origin.spec(), tab_id, callbacks)); | 207 sink_id, origin.is_empty() ? "" : origin.spec(), tab_id, callbacks)); |
| 208 } | 208 } |
| 209 | 209 |
| 210 void MediaRouterMojoImpl::JoinRoute( | 210 void MediaRouterMojoImpl::JoinRoute( |
| 211 const MediaSource::Id& source_id, | 211 const MediaSource::Id& source_id, |
| 212 const std::string& presentation_id, | 212 const std::string& presentation_id, |
| 213 const GURL& origin, | 213 const GURL& origin, |
| 214 int tab_id, | 214 int tab_id, |
| 215 const std::vector<MediaRouteResponseCallback>& callbacks) { | 215 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 216 DCHECK(thread_checker_.CalledOnValidThread()); | 216 DCHECK(thread_checker_.CalledOnValidThread()); |
| 217 | 217 |
| 218 if (!origin.is_valid()) { | 218 if (!origin.is_valid()) { |
| 219 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; | 219 DVLOG_WITH_INSTANCE(1) << "Invalid origin: " << origin; |
| 220 for (const MediaRouteResponseCallback& callback : callbacks) | 220 for (const MediaRouteResponseCallback& callback : callbacks) |
| 221 callback.Run(nullptr, "Invalid origin"); | 221 callback.Run(nullptr, "", "Invalid origin"); |
| 222 return; | 222 return; |
| 223 } | 223 } |
| 224 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, | 224 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoJoinRoute, |
| 225 base::Unretained(this), source_id, presentation_id, | 225 base::Unretained(this), source_id, presentation_id, |
| 226 origin.is_empty() ? "" : origin.spec(), tab_id, | 226 origin.is_empty() ? "" : origin.spec(), tab_id, |
| 227 callbacks)); | 227 callbacks)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { | 230 void MediaRouterMojoImpl::CloseRoute(const MediaRoute::Id& route_id) { |
| 231 DCHECK(thread_checker_.CalledOnValidThread()); | 231 DCHECK(thread_checker_.CalledOnValidThread()); |
| 232 | 232 |
| 233 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, | 233 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoCloseRoute, |
| 234 base::Unretained(this), route_id)); | 234 base::Unretained(this), route_id)); |
| 235 } | 235 } |
| 236 | 236 |
| 237 void MediaRouterMojoImpl::SendRouteMessage( | 237 void MediaRouterMojoImpl::SendRouteMessage( |
| 238 const MediaRoute::Id& route_id, | 238 const MediaRoute::Id& route_id, |
| 239 const std::string& message, | 239 const std::string& message, |
| 240 const SendRouteMessageCallback& callback) { | 240 const SendRouteMessageCallback& callback) { |
| 241 DCHECK(thread_checker_.CalledOnValidThread()); | 241 DCHECK(thread_checker_.CalledOnValidThread()); |
| 242 | 242 |
| 243 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoSendSessionMessage, | 243 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoSendSessionMessage, |
| 244 base::Unretained(this), route_id, message, callback)); | 244 base::Unretained(this), route_id, message, callback)); |
| 245 } | 245 } |
| 246 | 246 |
| 247 void MediaRouterMojoImpl::ListenForRouteMessages( | |
| 248 const std::vector<MediaRoute::Id>& route_ids, | |
| 249 const PresentationSessionMessageCallback& message_cb) { | |
| 250 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 251 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoListenForRouteMessages, | |
| 252 base::Unretained(this), route_ids, message_cb)); | |
| 253 } | |
| 254 | |
| 255 void MediaRouterMojoImpl::ClearIssue(const Issue::Id& issue_id) { | 247 void MediaRouterMojoImpl::ClearIssue(const Issue::Id& issue_id) { |
| 256 DCHECK(thread_checker_.CalledOnValidThread()); | 248 DCHECK(thread_checker_.CalledOnValidThread()); |
| 257 | 249 |
| 258 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoClearIssue, | 250 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoClearIssue, |
| 259 base::Unretained(this), issue_id)); | 251 base::Unretained(this), issue_id)); |
| 260 } | 252 } |
| 261 | 253 |
| 262 void MediaRouterMojoImpl::RegisterMediaSinksObserver( | 254 void MediaRouterMojoImpl::RegisterMediaSinksObserver( |
| 263 MediaSinksObserver* observer) { | 255 MediaSinksObserver* observer) { |
| 264 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 280 // TODO(imcheng): Implement caching. (crbug.com/492451) | 272 // TODO(imcheng): Implement caching. (crbug.com/492451) |
| 281 observer_list->AddObserver(observer); | 273 observer_list->AddObserver(observer); |
| 282 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks, | 274 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoStartObservingMediaSinks, |
| 283 base::Unretained(this), source_id)); | 275 base::Unretained(this), source_id)); |
| 284 } | 276 } |
| 285 | 277 |
| 286 void MediaRouterMojoImpl::UnregisterMediaSinksObserver( | 278 void MediaRouterMojoImpl::UnregisterMediaSinksObserver( |
| 287 MediaSinksObserver* observer) { | 279 MediaSinksObserver* observer) { |
| 288 DCHECK(thread_checker_.CalledOnValidThread()); | 280 DCHECK(thread_checker_.CalledOnValidThread()); |
| 289 | 281 |
| 290 const std::string& source_id = observer->source().id(); | 282 const MediaSource::Id& source_id = observer->source().id(); |
| 291 auto* observer_list = sinks_observers_.get(source_id); | 283 auto* observer_list = sinks_observers_.get(source_id); |
| 292 if (!observer_list || !observer_list->HasObserver(observer)) { | 284 if (!observer_list || !observer_list->HasObserver(observer)) { |
| 293 return; | 285 return; |
| 294 } | 286 } |
| 295 | 287 |
| 296 // If we are removing the final observer for the source, then stop | 288 // If we are removing the final observer for the source, then stop |
| 297 // observing sinks for it. | 289 // observing sinks for it. |
| 298 // might_have_observers() is reliable here on the assumption that this call | 290 // might_have_observers() is reliable here on the assumption that this call |
| 299 // is not inside the ObserverList iteration. | 291 // is not inside the ObserverList iteration. |
| 300 observer_list->RemoveObserver(observer); | 292 observer_list->RemoveObserver(observer); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 330 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { | 322 void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) { |
| 331 // TODO(imcheng): Implement. (crbug.com/461815) | 323 // TODO(imcheng): Implement. (crbug.com/461815) |
| 332 NOTIMPLEMENTED(); | 324 NOTIMPLEMENTED(); |
| 333 } | 325 } |
| 334 | 326 |
| 335 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { | 327 void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) { |
| 336 // TODO(imcheng): Implement. (crbug.com/461815) | 328 // TODO(imcheng): Implement. (crbug.com/461815) |
| 337 NOTIMPLEMENTED(); | 329 NOTIMPLEMENTED(); |
| 338 } | 330 } |
| 339 | 331 |
| 332 void MediaRouterMojoImpl::RegisterPresentationSessionMessagesObserver( | |
| 333 PresentationSessionMessagesObserver* observer) { | |
| 334 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 335 DCHECK(observer); | |
| 336 const MediaRoute::Id& route_id = observer->route_id(); | |
| 337 auto* observer_list = messages_observers_.get(route_id); | |
| 338 if (!observer_list) { | |
| 339 observer_list = new base::ObserverList<PresentationSessionMessagesObserver>; | |
| 340 messages_observers_.add(route_id, make_scoped_ptr(observer_list)); | |
| 341 } else { | |
| 342 DCHECK(!observer_list->HasObserver(observer)); | |
| 343 } | |
| 344 | |
| 345 bool should_listen = !observer_list->might_have_observers(); | |
| 346 observer_list->AddObserver(observer); | |
| 347 if (should_listen) { | |
| 348 RunOrDefer(base::Bind(&MediaRouterMojoImpl::DoListenForRouteMessages, | |
| 349 base::Unretained(this), route_id)); | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 void MediaRouterMojoImpl::UnregisterPresentationSessionMessagesObserver( | |
| 354 PresentationSessionMessagesObserver* observer) { | |
| 355 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 356 DCHECK(observer); | |
| 357 | |
| 358 const MediaRoute::Id& route_id = observer->route_id(); | |
| 359 auto* observer_list = messages_observers_.get(route_id); | |
| 360 if (!observer_list || !observer_list->HasObserver(observer)) | |
| 361 return; | |
| 362 | |
| 363 observer_list->RemoveObserver(observer); | |
| 364 if (!observer_list->might_have_observers()) | |
| 365 messages_observers_.erase(route_id); | |
| 366 // Note that if we are still listening for messages for that route, we will | |
|
haibinlu
2015/07/30 23:59:11
issue stop listening right away.
imcheng
2015/08/03 18:56:33
Added a TODO here (see other comment). Also change
| |
| 367 // stop the next time |OnRouteMessagesReceived| is invoked. | |
| 368 } | |
| 369 | |
| 340 void MediaRouterMojoImpl::DoCreateRoute( | 370 void MediaRouterMojoImpl::DoCreateRoute( |
| 341 const MediaSource::Id& source_id, | 371 const MediaSource::Id& source_id, |
| 342 const MediaSink::Id& sink_id, | 372 const MediaSink::Id& sink_id, |
| 343 const std::string& origin, | 373 const std::string& origin, |
| 344 int tab_id, | 374 int tab_id, |
| 345 const std::vector<MediaRouteResponseCallback>& callbacks) { | 375 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 346 std::string presentation_id("mr_"); | 376 std::string presentation_id("mr_"); |
| 347 presentation_id += base::GenerateGUID(); | 377 presentation_id += base::GenerateGUID(); |
| 348 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id | 378 DVLOG_WITH_INSTANCE(1) << "DoCreateRoute " << source_id << "=>" << sink_id |
| 349 << ", presentation ID: " << presentation_id; | 379 << ", presentation ID: " << presentation_id; |
| 350 media_route_provider_->CreateRoute( | 380 media_route_provider_->CreateRoute( |
| 351 source_id, sink_id, presentation_id, origin, tab_id, | 381 source_id, sink_id, presentation_id, origin, tab_id, |
| 352 base::Bind(&RouteResponseReceived, callbacks)); | 382 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); |
| 353 } | 383 } |
| 354 | 384 |
| 355 void MediaRouterMojoImpl::DoJoinRoute( | 385 void MediaRouterMojoImpl::DoJoinRoute( |
| 356 const MediaSource::Id& source_id, | 386 const MediaSource::Id& source_id, |
| 357 const std::string& presentation_id, | 387 const std::string& presentation_id, |
| 358 const std::string& origin, | 388 const std::string& origin, |
| 359 int tab_id, | 389 int tab_id, |
| 360 const std::vector<MediaRouteResponseCallback>& callbacks) { | 390 const std::vector<MediaRouteResponseCallback>& callbacks) { |
| 361 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id | 391 DVLOG_WITH_INSTANCE(1) << "DoJoinRoute " << source_id |
| 362 << ", presentation ID: " << presentation_id; | 392 << ", presentation ID: " << presentation_id; |
| 363 media_route_provider_->JoinRoute( | 393 media_route_provider_->JoinRoute( |
| 364 source_id, presentation_id, origin, tab_id, | 394 source_id, presentation_id, origin, tab_id, |
| 365 base::Bind(&RouteResponseReceived, callbacks)); | 395 base::Bind(&RouteResponseReceived, presentation_id, callbacks)); |
| 366 } | 396 } |
| 367 | 397 |
| 368 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { | 398 void MediaRouterMojoImpl::DoCloseRoute(const MediaRoute::Id& route_id) { |
| 369 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; | 399 DVLOG_WITH_INSTANCE(1) << "DoCloseRoute " << route_id; |
| 370 media_route_provider_->CloseRoute(route_id); | 400 media_route_provider_->CloseRoute(route_id); |
| 371 } | 401 } |
| 372 | 402 |
| 373 void MediaRouterMojoImpl::DoSendSessionMessage( | 403 void MediaRouterMojoImpl::DoSendSessionMessage( |
| 374 const MediaRoute::Id& route_id, | 404 const MediaRoute::Id& route_id, |
| 375 const std::string& message, | 405 const std::string& message, |
| 376 const SendRouteMessageCallback& callback) { | 406 const SendRouteMessageCallback& callback) { |
| 377 DVLOG_WITH_INSTANCE(1) << "SendRouteMessage " << route_id; | 407 DVLOG_WITH_INSTANCE(1) << "SendRouteMessage " << route_id; |
| 378 media_route_provider_->SendRouteMessage(route_id, message, callback); | 408 media_route_provider_->SendRouteMessage(route_id, message, callback); |
| 379 } | 409 } |
| 380 | 410 |
| 381 void MediaRouterMojoImpl::DoListenForRouteMessages( | 411 void MediaRouterMojoImpl::DoListenForRouteMessages( |
| 382 const std::vector<MediaRoute::Id>& route_ids, | 412 const MediaRoute::Id& route_id) { |
| 383 const PresentationSessionMessageCallback& message_cb) { | |
| 384 DVLOG_WITH_INSTANCE(1) << "ListenForRouteMessages"; | 413 DVLOG_WITH_INSTANCE(1) << "ListenForRouteMessages"; |
| 385 media_route_provider_->ListenForRouteMessages( | 414 if (!ContainsValue(listening_messages_for_routes_, route_id)) { |
| 386 mojo::Array<mojo::String>::From(route_ids), | 415 listening_messages_for_routes_.insert(route_id); |
| 387 base::Bind(&MediaRouterMojoImpl::OnRouteMessageReceived, | 416 media_route_provider_->ListenForRouteMessages( |
| 388 base::Unretained(this), message_cb)); | 417 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, |
| 418 base::Unretained(this), route_id)); | |
| 419 } | |
| 389 } | 420 } |
| 390 | 421 |
| 391 void MediaRouterMojoImpl::OnRouteMessageReceived( | 422 void MediaRouterMojoImpl::OnRouteMessagesReceived( |
| 392 const PresentationSessionMessageCallback& message_cb, | 423 const MediaRoute::Id& route_id, |
| 393 mojo::Array<interfaces::RouteMessagePtr> messages) { | 424 mojo::Array<interfaces::RouteMessagePtr> messages) { |
| 394 scoped_ptr<ScopedVector<content::PresentationSessionMessage>> | 425 DVLOG(1) << "OnRouteMessagesReceived"; |
| 395 session_messages(new ScopedVector<content::PresentationSessionMessage>()); | 426 |
| 427 // First, check if there are any observers remaining. If not, the messages | |
| 428 // can be discarded and we can stop listening for the next batch of messages. | |
| 429 auto* observer_list = messages_observers_.get(route_id); | |
| 430 if (!observer_list) { | |
| 431 listening_messages_for_routes_.erase(route_id); | |
| 432 return; | |
| 433 } | |
| 434 | |
| 435 ScopedVector<content::PresentationSessionMessage> session_messages; | |
| 436 session_messages.reserve(messages.size()); | |
| 396 for (size_t i = 0; i < messages.size(); ++i) { | 437 for (size_t i = 0; i < messages.size(); ++i) { |
| 397 session_messages->push_back( | 438 session_messages.push_back( |
| 398 ConvertToPresentationSessionMessage(messages[i].Pass()).Pass()); | 439 ConvertToPresentationSessionMessage(messages[i].Pass()).Pass()); |
| 399 } | 440 } |
| 400 message_cb.Run(session_messages.Pass()); | 441 |
| 442 FOR_EACH_OBSERVER(PresentationSessionMessagesObserver, *observer_list, | |
| 443 OnMessagesReceived(session_messages)); | |
| 444 | |
| 445 // Listen for more messages. | |
| 446 media_route_provider_->ListenForRouteMessages( | |
| 447 route_id, base::Bind(&MediaRouterMojoImpl::OnRouteMessagesReceived, | |
| 448 base::Unretained(this), route_id)); | |
| 401 } | 449 } |
| 402 | 450 |
| 403 void MediaRouterMojoImpl::DoClearIssue(const Issue::Id& issue_id) { | 451 void MediaRouterMojoImpl::DoClearIssue(const Issue::Id& issue_id) { |
| 404 DVLOG_WITH_INSTANCE(1) << "DoClearIssue " << issue_id; | 452 DVLOG_WITH_INSTANCE(1) << "DoClearIssue " << issue_id; |
| 405 media_route_provider_->ClearIssue(issue_id); | 453 media_route_provider_->ClearIssue(issue_id); |
| 406 } | 454 } |
| 407 | 455 |
| 408 void MediaRouterMojoImpl::DoStartObservingMediaSinks( | 456 void MediaRouterMojoImpl::DoStartObservingMediaSinks( |
| 409 const MediaSource::Id& source_id) { | 457 const MediaSource::Id& source_id) { |
| 410 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; | 458 DVLOG_WITH_INSTANCE(1) << "DoStartObservingMediaSinks: " << source_id; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 471 return; | 519 return; |
| 472 } | 520 } |
| 473 | 521 |
| 474 for (const auto& next_request : pending_requests_) | 522 for (const auto& next_request : pending_requests_) |
| 475 next_request.Run(); | 523 next_request.Run(); |
| 476 | 524 |
| 477 pending_requests_.clear(); | 525 pending_requests_.clear(); |
| 478 } | 526 } |
| 479 | 527 |
| 480 } // namespace media_router | 528 } // namespace media_router |
| OLD | NEW |