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 "content/browser/presentation/presentation_service_impl.h" | 5 #include "content/browser/presentation/presentation_service_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "content/browser/presentation/presentation_type_converters.h" | 10 #include "content/browser/presentation/presentation_type_converters.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 binding_.reset(new mojo::Binding<presentation::PresentationService>( | 94 binding_.reset(new mojo::Binding<presentation::PresentationService>( |
| 95 this, request.Pass())); | 95 this, request.Pass())); |
| 96 binding_->set_error_handler(this); | 96 binding_->set_error_handler(this); |
| 97 } | 97 } |
| 98 | 98 |
| 99 void PresentationServiceImpl::OnConnectionError() { | 99 void PresentationServiceImpl::OnConnectionError() { |
| 100 DVLOG(1) << "OnConnectionError"; | 100 DVLOG(1) << "OnConnectionError"; |
| 101 delete this; | 101 delete this; |
| 102 } | 102 } |
| 103 | 103 |
| 104 PresentationServiceImpl::ScreenAvailabilityContext* | 104 void PresentationServiceImpl::SetClient( |
| 105 PresentationServiceImpl::GetOrCreateAvailabilityContext( | 105 presentation::PresentationServiceClientPtr client) { |
| 106 const std::string& presentation_url) { | 106 DCHECK(client_.is_null()); |
| 107 auto it = availability_contexts_.find(presentation_url); | 107 client_ = client.Pass(); |
| 108 if (it == availability_contexts_.end()) { | |
| 109 linked_ptr<ScreenAvailabilityContext> context( | |
| 110 new ScreenAvailabilityContext(presentation_url)); | |
| 111 if (!delegate_->AddScreenAvailabilityListener( | |
| 112 render_process_id_, render_frame_id_, context.get())) { | |
| 113 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; | |
| 114 return nullptr; | |
| 115 } | |
| 116 it = availability_contexts_.insert( | |
| 117 std::make_pair(context->GetPresentationUrl(), context)).first; | |
| 118 } | |
| 119 return it->second.get(); | |
| 120 } | 108 } |
| 121 | 109 |
| 122 void PresentationServiceImpl::ListenForScreenAvailability( | 110 void PresentationServiceImpl::ListenForScreenAvailability() { |
| 123 const mojo::String& presentation_url, | |
| 124 const ScreenAvailabilityMojoCallback& callback) { | |
| 125 DVLOG(2) << "ListenForScreenAvailability"; | 111 DVLOG(2) << "ListenForScreenAvailability"; |
| 126 if (!delegate_) { | 112 if (!delegate_) |
| 127 callback.Run(presentation_url, false); | 113 return; |
| 114 | |
| 115 if (screen_availability_listener_.get() && | |
|
mark a. foltz
2015/05/11 23:48:38
ISTM this check should go into ResetScreenAvailabi
imcheng (use chromium acct)
2015/05/12 00:14:03
In the two cases where ResetScreenAvailabilityList
| |
| 116 screen_availability_listener_->GetPresentationUrl() == | |
| 117 default_presentation_url_) { | |
| 128 return; | 118 return; |
| 129 } | 119 } |
| 130 | 120 |
| 131 ScreenAvailabilityContext* context = | 121 ResetScreenAvailabilityListener(default_presentation_url_); |
| 132 GetOrCreateAvailabilityContext(presentation_url.get()); | |
| 133 if (!context) { | |
| 134 callback.Run(presentation_url, false); | |
| 135 return; | |
| 136 } | |
| 137 context->CallbackReceived(callback); | |
| 138 } | 122 } |
| 139 | 123 |
| 140 void PresentationServiceImpl::RemoveScreenAvailabilityListener( | 124 void PresentationServiceImpl::ResetScreenAvailabilityListener( |
| 141 const mojo::String& presentation_url) { | 125 const std::string& presentation_url) { |
| 142 DVLOG(2) << "RemoveScreenAvailabilityListener"; | 126 DCHECK(delegate_); |
| 127 | |
| 128 // (1) Unregister old listener with delegate | |
| 129 StopListeningForScreenAvailability(); | |
| 130 | |
| 131 // (2) Replace old listener with new listener | |
| 132 screen_availability_listener_.reset(new ScreenAvailabilityListenerImpl( | |
| 133 presentation_url, this)); | |
| 134 | |
| 135 // (3) Register new listener with delegate | |
| 136 if (!delegate_->AddScreenAvailabilityListener( | |
| 137 render_process_id_, | |
| 138 render_frame_id_, | |
| 139 screen_availability_listener_.get())) { | |
| 140 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; | |
| 141 screen_availability_listener_.reset(); | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 void PresentationServiceImpl::StopListeningForScreenAvailability() { | |
| 146 DVLOG(2) << "StopListeningForScreenAvailability"; | |
| 143 if (!delegate_) | 147 if (!delegate_) |
| 144 return; | 148 return; |
| 145 | 149 |
| 146 const std::string& presentation_url_str = presentation_url.get(); | 150 if (screen_availability_listener_.get()) { |
| 147 auto it = availability_contexts_.find(presentation_url_str); | 151 delegate_->RemoveScreenAvailabilityListener( |
| 148 if (it == availability_contexts_.end()) | 152 render_process_id_, |
| 149 return; | 153 render_frame_id_, |
| 150 | 154 screen_availability_listener_.get()); |
| 151 delegate_->RemoveScreenAvailabilityListener( | 155 screen_availability_listener_.reset(); |
| 152 render_process_id_, render_frame_id_, it->second.get()); | 156 } |
| 153 // Resolve the context's pending callbacks before removing it. | |
| 154 it->second->OnScreenAvailabilityChanged(false); | |
| 155 availability_contexts_.erase(it); | |
| 156 } | 157 } |
| 157 | 158 |
| 158 void PresentationServiceImpl::ListenForDefaultSessionStart( | 159 void PresentationServiceImpl::ListenForDefaultSessionStart( |
| 159 const DefaultSessionMojoCallback& callback) { | 160 const DefaultSessionMojoCallback& callback) { |
| 160 if (!default_session_start_context_.get()) | 161 if (!default_session_start_context_.get()) |
| 161 default_session_start_context_.reset(new DefaultSessionStartContext); | 162 default_session_start_context_.reset(new DefaultSessionStartContext); |
| 162 default_session_start_context_->AddCallback(callback); | 163 default_session_start_context_->AddCallback(callback); |
| 163 } | 164 } |
| 164 | 165 |
| 165 void PresentationServiceImpl::StartSession( | 166 void PresentationServiceImpl::StartSession( |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 presentation::PresentationErrorPtr error) { | 279 presentation::PresentationErrorPtr error) { |
| 279 auto it = pending_session_cbs_.find(request_session_id); | 280 auto it = pending_session_cbs_.find(request_session_id); |
| 280 if (it == pending_session_cbs_.end()) | 281 if (it == pending_session_cbs_.end()) |
| 281 return; | 282 return; |
| 282 | 283 |
| 283 DCHECK(it->second.get()); | 284 DCHECK(it->second.get()); |
| 284 it->second->Run(session.Pass(), error.Pass()); | 285 it->second->Run(session.Pass(), error.Pass()); |
| 285 pending_session_cbs_.erase(it); | 286 pending_session_cbs_.erase(it); |
| 286 } | 287 } |
| 287 | 288 |
| 288 void PresentationServiceImpl::DoSetDefaultPresentationUrl( | |
| 289 const std::string& default_presentation_url, | |
| 290 const std::string& default_presentation_id) { | |
| 291 DCHECK(delegate_); | |
| 292 delegate_->SetDefaultPresentationUrl( | |
| 293 render_process_id_, | |
| 294 render_frame_id_, | |
| 295 default_presentation_url, | |
| 296 default_presentation_id); | |
| 297 default_presentation_url_ = default_presentation_url; | |
| 298 default_presentation_id_ = default_presentation_id; | |
| 299 } | |
| 300 | |
| 301 void PresentationServiceImpl::SetDefaultPresentationURL( | 289 void PresentationServiceImpl::SetDefaultPresentationURL( |
| 302 const mojo::String& default_presentation_url, | 290 const mojo::String& default_presentation_url, |
| 303 const mojo::String& default_presentation_id) { | 291 const mojo::String& default_presentation_id) { |
| 304 DVLOG(2) << "SetDefaultPresentationURL"; | 292 DVLOG(2) << "SetDefaultPresentationURL"; |
| 305 if (!delegate_) | 293 if (!delegate_) |
| 306 return; | 294 return; |
| 307 | 295 |
| 308 const std::string& old_default_url = default_presentation_url_; | 296 const std::string& old_default_url = default_presentation_url_; |
| 309 const std::string& new_default_url = default_presentation_url.get(); | 297 const std::string& new_default_url = default_presentation_url.get(); |
| 310 | 298 |
| 311 // Don't call delegate if nothing changed. | 299 // Don't call delegate if nothing changed. |
| 312 if (old_default_url == new_default_url && | 300 if (old_default_url == new_default_url && |
| 313 default_presentation_id_ == default_presentation_id) { | 301 default_presentation_id_ == default_presentation_id) { |
| 314 return; | 302 return; |
| 315 } | 303 } |
| 316 | 304 |
| 317 auto old_it = availability_contexts_.find(old_default_url); | 305 if (old_default_url != new_default_url) { |
| 318 // Haven't started listening yet. | 306 // If DPU changed, replace screen availability listeners if any. |
| 319 if (old_it == availability_contexts_.end()) { | 307 if (screen_availability_listener_.get()) |
| 320 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 308 ResetScreenAvailabilityListener(new_default_url); |
| 321 return; | |
| 322 } | 309 } |
| 323 | 310 |
| 324 // Have already started listening. Create a listener for the new URL and | 311 delegate_->SetDefaultPresentationUrl( |
| 325 // transfer the callbacks from the old listener, if any. | |
| 326 // This is done so that a listener added before default URL is changed | |
| 327 // will continue to work. | |
| 328 ScreenAvailabilityContext* context = | |
| 329 GetOrCreateAvailabilityContext(new_default_url); | |
| 330 old_it->second->PassPendingCallbacks(context); | |
| 331 | |
| 332 // Remove listener for old default presentation URL. | |
| 333 delegate_->RemoveScreenAvailabilityListener( | |
| 334 render_process_id_, | 312 render_process_id_, |
| 335 render_frame_id_, | 313 render_frame_id_, |
| 336 old_it->second.get()); | 314 default_presentation_url, |
| 337 availability_contexts_.erase(old_it); | 315 default_presentation_id); |
| 338 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 316 default_presentation_url_ = default_presentation_url; |
| 317 default_presentation_id_ = default_presentation_id; | |
| 339 } | 318 } |
| 340 | 319 |
| 341 void PresentationServiceImpl::CloseSession( | 320 void PresentationServiceImpl::CloseSession( |
| 342 const mojo::String& presentation_url, | 321 const mojo::String& presentation_url, |
| 343 const mojo::String& presentation_id) { | 322 const mojo::String& presentation_id) { |
| 344 NOTIMPLEMENTED(); | 323 NOTIMPLEMENTED(); |
| 345 } | 324 } |
| 346 | 325 |
| 347 void PresentationServiceImpl::ListenForSessionStateChange( | 326 void PresentationServiceImpl::ListenForSessionStateChange( |
| 348 const SessionStateCallback& callback) { | 327 const SessionStateCallback& callback) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 432 delete this; | 411 delete this; |
| 433 } | 412 } |
| 434 | 413 |
| 435 void PresentationServiceImpl::Reset() { | 414 void PresentationServiceImpl::Reset() { |
| 436 DVLOG(2) << "PresentationServiceImpl::Reset"; | 415 DVLOG(2) << "PresentationServiceImpl::Reset"; |
| 437 if (delegate_) | 416 if (delegate_) |
| 438 delegate_->Reset(render_process_id_, render_frame_id_); | 417 delegate_->Reset(render_process_id_, render_frame_id_); |
| 439 | 418 |
| 440 default_presentation_url_.clear(); | 419 default_presentation_url_.clear(); |
| 441 default_presentation_id_.clear(); | 420 default_presentation_id_.clear(); |
| 442 availability_contexts_.clear(); | 421 screen_availability_listener_.reset(); |
| 443 queued_start_session_requests_.clear(); | 422 queued_start_session_requests_.clear(); |
| 444 FlushNewSessionCallbacks(); | 423 FlushNewSessionCallbacks(); |
| 445 default_session_start_context_.reset(); | 424 default_session_start_context_.reset(); |
| 446 if (on_session_messages_callback_.get()) { | 425 if (on_session_messages_callback_.get()) { |
| 447 on_session_messages_callback_->Run( | 426 on_session_messages_callback_->Run( |
| 448 mojo::Array<presentation::SessionMessagePtr>()); | 427 mojo::Array<presentation::SessionMessagePtr>()); |
| 449 on_session_messages_callback_.reset(); | 428 on_session_messages_callback_.reset(); |
| 450 } | 429 } |
| 451 } | 430 } |
| 452 | 431 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 464 delegate_ = nullptr; | 443 delegate_ = nullptr; |
| 465 Reset(); | 444 Reset(); |
| 466 } | 445 } |
| 467 | 446 |
| 468 void PresentationServiceImpl::OnDefaultPresentationStarted( | 447 void PresentationServiceImpl::OnDefaultPresentationStarted( |
| 469 const PresentationSessionInfo& session) { | 448 const PresentationSessionInfo& session) { |
| 470 if (default_session_start_context_.get()) | 449 if (default_session_start_context_.get()) |
| 471 default_session_start_context_->set_session(session); | 450 default_session_start_context_->set_session(session); |
| 472 } | 451 } |
| 473 | 452 |
| 474 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( | 453 PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 475 const std::string& presentation_url) | 454 ::ScreenAvailabilityListenerImpl( |
| 476 : presentation_url_(presentation_url) { | 455 const std::string& presentation_url, |
| 456 PresentationServiceImpl* service) | |
| 457 : presentation_url_(presentation_url), | |
| 458 service_(service) { | |
| 459 DCHECK(service_); | |
| 460 DCHECK(!service_->client_.is_null()); | |
| 477 } | 461 } |
| 478 | 462 |
| 479 PresentationServiceImpl::ScreenAvailabilityContext:: | 463 PresentationServiceImpl::ScreenAvailabilityListenerImpl:: |
| 480 ~ScreenAvailabilityContext() { | 464 ~ScreenAvailabilityListenerImpl() { |
| 481 // Ensure that pending callbacks are flushed. | |
| 482 OnScreenAvailabilityChanged(false); | |
| 483 } | 465 } |
| 484 | 466 |
| 485 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( | 467 std::string PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 486 const ScreenAvailabilityMojoCallback& callback) { | |
| 487 // NOTE: This will overwrite previously registered callback if any. | |
| 488 if (!available_ptr_) { | |
| 489 // No results yet, store callback for later invocation. | |
| 490 callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback)); | |
| 491 } else { | |
| 492 // Run callback now, reset result. | |
| 493 // There shouldn't be any callbacks stored in this scenario. | |
| 494 DCHECK(!HasPendingCallbacks()); | |
| 495 callback.Run(presentation_url_, *available_ptr_); | |
| 496 available_ptr_.reset(); | |
| 497 } | |
| 498 } | |
| 499 | |
| 500 std::string PresentationServiceImpl::ScreenAvailabilityContext | |
| 501 ::GetPresentationUrl() const { | 468 ::GetPresentationUrl() const { |
| 502 return presentation_url_; | 469 return presentation_url_; |
| 503 } | 470 } |
| 504 | 471 |
| 505 void PresentationServiceImpl::ScreenAvailabilityContext | 472 void PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 506 ::OnScreenAvailabilityChanged(bool available) { | 473 ::OnScreenAvailabilityChanged(bool available) { |
| 507 if (!HasPendingCallbacks()) { | 474 service_->client_->OnScreenAvailabilityUpdated(available); |
| 508 // No callback, stash the result for now. | |
| 509 available_ptr_.reset(new bool(available)); | |
| 510 } else { | |
| 511 // Invoke callbacks and erase them. | |
| 512 // There shouldn't be any result stored in this scenario. | |
| 513 DCHECK(!available_ptr_); | |
| 514 ScopedVector<ScreenAvailabilityMojoCallback> callbacks; | |
| 515 callbacks.swap(callbacks_); | |
| 516 for (const auto& callback : callbacks) | |
| 517 callback->Run(presentation_url_, available); | |
| 518 } | |
| 519 } | |
| 520 | |
| 521 void PresentationServiceImpl::ScreenAvailabilityContext | |
| 522 ::PassPendingCallbacks( | |
| 523 PresentationServiceImpl::ScreenAvailabilityContext* other) { | |
| 524 std::vector<ScreenAvailabilityMojoCallback*> callbacks; | |
| 525 callbacks_.release(&callbacks); | |
| 526 std::copy(callbacks.begin(), callbacks.end(), | |
| 527 std::back_inserter(other->callbacks_)); | |
| 528 } | |
| 529 | |
| 530 bool PresentationServiceImpl::ScreenAvailabilityContext | |
| 531 ::HasPendingCallbacks() const { | |
| 532 return !callbacks_.empty(); | |
| 533 } | 475 } |
| 534 | 476 |
| 535 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( | 477 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( |
| 536 const std::string& presentation_url, | 478 const std::string& presentation_url, |
| 537 const std::string& presentation_id, | 479 const std::string& presentation_id, |
| 538 const NewSessionMojoCallback& callback) | 480 const NewSessionMojoCallback& callback) |
| 539 : presentation_url_(presentation_url), | 481 : presentation_url_(presentation_url), |
| 540 presentation_id_(presentation_id), | 482 presentation_id_(presentation_id), |
| 541 callback_(callback) { | 483 callback_(callback) { |
| 542 } | 484 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { | 532 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { |
| 591 ScopedVector<DefaultSessionMojoCallback> callbacks; | 533 ScopedVector<DefaultSessionMojoCallback> callbacks; |
| 592 callbacks.swap(callbacks_); | 534 callbacks.swap(callbacks_); |
| 593 for (const auto& callback : callbacks) | 535 for (const auto& callback : callbacks) |
| 594 callback->Run(presentation::PresentationSessionInfoPtr()); | 536 callback->Run(presentation::PresentationSessionInfoPtr()); |
| 595 session_.reset(); | 537 session_.reset(); |
| 596 } | 538 } |
| 597 | 539 |
| 598 } // namespace content | 540 } // namespace content |
| 599 | 541 |
| OLD | NEW |