| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 binding_.reset(new mojo::Binding<presentation::PresentationService>( | 131 binding_.reset(new mojo::Binding<presentation::PresentationService>( |
| 132 this, request.Pass())); | 132 this, request.Pass())); |
| 133 binding_->set_error_handler(this); | 133 binding_->set_error_handler(this); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void PresentationServiceImpl::OnConnectionError() { | 136 void PresentationServiceImpl::OnConnectionError() { |
| 137 DVLOG(1) << "OnConnectionError"; | 137 DVLOG(1) << "OnConnectionError"; |
| 138 delete this; | 138 delete this; |
| 139 } | 139 } |
| 140 | 140 |
| 141 PresentationServiceImpl::ScreenAvailabilityContext* | 141 void PresentationServiceImpl::SetClient( |
| 142 PresentationServiceImpl::GetOrCreateAvailabilityContext( | 142 presentation::PresentationServiceClientPtr client) { |
| 143 const std::string& presentation_url) { | 143 DCHECK(!client_.get()); |
| 144 auto it = availability_contexts_.find(presentation_url); | 144 // TODO(imcheng): Set ErrorHandler to listen for errors. |
| 145 if (it == availability_contexts_.end()) { | 145 client_ = client.Pass(); |
| 146 linked_ptr<ScreenAvailabilityContext> context( | |
| 147 new ScreenAvailabilityContext(presentation_url)); | |
| 148 if (!delegate_->AddScreenAvailabilityListener( | |
| 149 render_process_id_, render_frame_id_, context.get())) { | |
| 150 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; | |
| 151 return nullptr; | |
| 152 } | |
| 153 it = availability_contexts_.insert( | |
| 154 std::make_pair(context->GetPresentationUrl(), context)).first; | |
| 155 } | |
| 156 return it->second.get(); | |
| 157 } | 146 } |
| 158 | 147 |
| 159 void PresentationServiceImpl::ListenForScreenAvailability( | 148 void PresentationServiceImpl::ListenForScreenAvailability() { |
| 160 const mojo::String& presentation_url, | |
| 161 const ScreenAvailabilityMojoCallback& callback) { | |
| 162 DVLOG(2) << "ListenForScreenAvailability"; | 149 DVLOG(2) << "ListenForScreenAvailability"; |
| 163 if (!delegate_) { | 150 if (!delegate_) |
| 164 callback.Run(presentation_url, false); | 151 return; |
| 152 |
| 153 if (screen_availability_listener_.get() && |
| 154 screen_availability_listener_->GetPresentationUrl() == |
| 155 default_presentation_url_) { |
| 165 return; | 156 return; |
| 166 } | 157 } |
| 167 | 158 |
| 168 ScreenAvailabilityContext* context = | 159 ResetScreenAvailabilityListener(default_presentation_url_); |
| 169 GetOrCreateAvailabilityContext(presentation_url.get()); | |
| 170 if (!context) { | |
| 171 callback.Run(presentation_url, false); | |
| 172 return; | |
| 173 } | |
| 174 context->CallbackReceived(callback); | |
| 175 } | 160 } |
| 176 | 161 |
| 177 void PresentationServiceImpl::RemoveScreenAvailabilityListener( | 162 void PresentationServiceImpl::ResetScreenAvailabilityListener( |
| 178 const mojo::String& presentation_url) { | 163 const std::string& presentation_url) { |
| 179 DVLOG(2) << "RemoveScreenAvailabilityListener"; | 164 DCHECK(delegate_); |
| 165 DCHECK(!screen_availability_listener_.get() || |
| 166 presentation_url != default_presentation_url_); |
| 167 |
| 168 // (1) Unregister old listener with delegate |
| 169 StopListeningForScreenAvailability(); |
| 170 |
| 171 // (2) Replace old listener with new listener |
| 172 screen_availability_listener_.reset(new ScreenAvailabilityListenerImpl( |
| 173 presentation_url, this)); |
| 174 |
| 175 // (3) Register new listener with delegate |
| 176 if (!delegate_->AddScreenAvailabilityListener( |
| 177 render_process_id_, |
| 178 render_frame_id_, |
| 179 screen_availability_listener_.get())) { |
| 180 DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request."; |
| 181 screen_availability_listener_.reset(); |
| 182 } |
| 183 } |
| 184 |
| 185 void PresentationServiceImpl::StopListeningForScreenAvailability() { |
| 186 DVLOG(2) << "StopListeningForScreenAvailability"; |
| 180 if (!delegate_) | 187 if (!delegate_) |
| 181 return; | 188 return; |
| 182 | 189 |
| 183 const std::string& presentation_url_str = presentation_url.get(); | 190 if (screen_availability_listener_.get()) { |
| 184 auto it = availability_contexts_.find(presentation_url_str); | 191 delegate_->RemoveScreenAvailabilityListener( |
| 185 if (it == availability_contexts_.end()) | 192 render_process_id_, |
| 186 return; | 193 render_frame_id_, |
| 187 | 194 screen_availability_listener_.get()); |
| 188 delegate_->RemoveScreenAvailabilityListener( | 195 screen_availability_listener_.reset(); |
| 189 render_process_id_, render_frame_id_, it->second.get()); | 196 } |
| 190 // Resolve the context's pending callbacks before removing it. | |
| 191 it->second->OnScreenAvailabilityChanged(false); | |
| 192 availability_contexts_.erase(it); | |
| 193 } | 197 } |
| 194 | 198 |
| 195 void PresentationServiceImpl::ListenForDefaultSessionStart( | 199 void PresentationServiceImpl::ListenForDefaultSessionStart( |
| 196 const DefaultSessionMojoCallback& callback) { | 200 const DefaultSessionMojoCallback& callback) { |
| 197 if (!default_session_start_context_.get()) | 201 if (!default_session_start_context_.get()) |
| 198 default_session_start_context_.reset(new DefaultSessionStartContext); | 202 default_session_start_context_.reset(new DefaultSessionStartContext); |
| 199 default_session_start_context_->AddCallback(callback); | 203 default_session_start_context_->AddCallback(callback); |
| 200 } | 204 } |
| 201 | 205 |
| 202 void PresentationServiceImpl::StartSession( | 206 void PresentationServiceImpl::StartSession( |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 presentation::PresentationErrorPtr error) { | 319 presentation::PresentationErrorPtr error) { |
| 316 auto it = pending_session_cbs_.find(request_session_id); | 320 auto it = pending_session_cbs_.find(request_session_id); |
| 317 if (it == pending_session_cbs_.end()) | 321 if (it == pending_session_cbs_.end()) |
| 318 return; | 322 return; |
| 319 | 323 |
| 320 DCHECK(it->second.get()); | 324 DCHECK(it->second.get()); |
| 321 it->second->Run(session.Pass(), error.Pass()); | 325 it->second->Run(session.Pass(), error.Pass()); |
| 322 pending_session_cbs_.erase(it); | 326 pending_session_cbs_.erase(it); |
| 323 } | 327 } |
| 324 | 328 |
| 325 void PresentationServiceImpl::DoSetDefaultPresentationUrl( | |
| 326 const std::string& default_presentation_url, | |
| 327 const std::string& default_presentation_id) { | |
| 328 DCHECK(delegate_); | |
| 329 delegate_->SetDefaultPresentationUrl( | |
| 330 render_process_id_, | |
| 331 render_frame_id_, | |
| 332 default_presentation_url, | |
| 333 default_presentation_id); | |
| 334 default_presentation_url_ = default_presentation_url; | |
| 335 default_presentation_id_ = default_presentation_id; | |
| 336 } | |
| 337 | |
| 338 void PresentationServiceImpl::SetDefaultPresentationURL( | 329 void PresentationServiceImpl::SetDefaultPresentationURL( |
| 339 const mojo::String& default_presentation_url, | 330 const mojo::String& default_presentation_url, |
| 340 const mojo::String& default_presentation_id) { | 331 const mojo::String& default_presentation_id) { |
| 341 DVLOG(2) << "SetDefaultPresentationURL"; | 332 DVLOG(2) << "SetDefaultPresentationURL"; |
| 342 if (!delegate_) | 333 if (!delegate_) |
| 343 return; | 334 return; |
| 344 | 335 |
| 345 const std::string& old_default_url = default_presentation_url_; | 336 const std::string& old_default_url = default_presentation_url_; |
| 346 const std::string& new_default_url = default_presentation_url.get(); | 337 const std::string& new_default_url = default_presentation_url.get(); |
| 347 | 338 |
| 348 // Don't call delegate if nothing changed. | 339 // Don't call delegate if nothing changed. |
| 349 if (old_default_url == new_default_url && | 340 if (old_default_url == new_default_url && |
| 350 default_presentation_id_ == default_presentation_id) { | 341 default_presentation_id_ == default_presentation_id) { |
| 351 return; | 342 return; |
| 352 } | 343 } |
| 353 | 344 |
| 354 auto old_it = availability_contexts_.find(old_default_url); | 345 if (old_default_url != new_default_url) { |
| 355 // Haven't started listening yet. | 346 // If DPU changed, replace screen availability listeners if any. |
| 356 if (old_it == availability_contexts_.end()) { | 347 if (screen_availability_listener_.get()) |
| 357 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 348 ResetScreenAvailabilityListener(new_default_url); |
| 358 return; | |
| 359 } | 349 } |
| 360 | 350 |
| 361 // Have already started listening. Create a listener for the new URL and | 351 delegate_->SetDefaultPresentationUrl( |
| 362 // transfer the callbacks from the old listener, if any. | |
| 363 // This is done so that a listener added before default URL is changed | |
| 364 // will continue to work. | |
| 365 ScreenAvailabilityContext* context = | |
| 366 GetOrCreateAvailabilityContext(new_default_url); | |
| 367 old_it->second->PassPendingCallbacks(context); | |
| 368 | |
| 369 // Remove listener for old default presentation URL. | |
| 370 delegate_->RemoveScreenAvailabilityListener( | |
| 371 render_process_id_, | 352 render_process_id_, |
| 372 render_frame_id_, | 353 render_frame_id_, |
| 373 old_it->second.get()); | 354 default_presentation_url, |
| 374 availability_contexts_.erase(old_it); | 355 default_presentation_id); |
| 375 DoSetDefaultPresentationUrl(new_default_url, default_presentation_id); | 356 default_presentation_url_ = default_presentation_url; |
| 357 default_presentation_id_ = default_presentation_id; |
| 376 } | 358 } |
| 377 | 359 |
| 378 | 360 |
| 379 void PresentationServiceImpl::SendSessionMessage( | 361 void PresentationServiceImpl::SendSessionMessage( |
| 380 presentation::SessionMessagePtr session_message, | 362 presentation::SessionMessagePtr session_message, |
| 381 const SendMessageMojoCallback& callback) { | 363 const SendMessageMojoCallback& callback) { |
| 382 DVLOG(2) << "SendSessionMessage"; | 364 DVLOG(2) << "SendSessionMessage"; |
| 383 DCHECK(!session_message.is_null()); | 365 DCHECK(!session_message.is_null()); |
| 384 // send_message_callback_ should be null by now, otherwise resetting of | 366 // send_message_callback_ should be null by now, otherwise resetting of |
| 385 // send_message_callback_ with new callback will drop the old callback. | 367 // send_message_callback_ with new callback will drop the old callback. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 delete this; | 482 delete this; |
| 501 } | 483 } |
| 502 | 484 |
| 503 void PresentationServiceImpl::Reset() { | 485 void PresentationServiceImpl::Reset() { |
| 504 DVLOG(2) << "PresentationServiceImpl::Reset"; | 486 DVLOG(2) << "PresentationServiceImpl::Reset"; |
| 505 if (delegate_) | 487 if (delegate_) |
| 506 delegate_->Reset(render_process_id_, render_frame_id_); | 488 delegate_->Reset(render_process_id_, render_frame_id_); |
| 507 | 489 |
| 508 default_presentation_url_.clear(); | 490 default_presentation_url_.clear(); |
| 509 default_presentation_id_.clear(); | 491 default_presentation_id_.clear(); |
| 510 availability_contexts_.clear(); | 492 screen_availability_listener_.reset(); |
| 511 queued_start_session_requests_.clear(); | 493 queued_start_session_requests_.clear(); |
| 512 FlushNewSessionCallbacks(); | 494 FlushNewSessionCallbacks(); |
| 513 default_session_start_context_.reset(); | 495 default_session_start_context_.reset(); |
| 514 if (on_session_messages_callback_.get()) { | 496 if (on_session_messages_callback_.get()) { |
| 515 on_session_messages_callback_->Run( | 497 on_session_messages_callback_->Run( |
| 516 mojo::Array<presentation::SessionMessagePtr>()); | 498 mojo::Array<presentation::SessionMessagePtr>()); |
| 517 on_session_messages_callback_.reset(); | 499 on_session_messages_callback_.reset(); |
| 518 } | 500 } |
| 519 if (send_message_callback_) { | 501 if (send_message_callback_) { |
| 520 // Run the callback with false, indicating the renderer to stop sending | 502 // Run the callback with false, indicating the renderer to stop sending |
| (...skipping 17 matching lines...) Expand all Loading... |
| 538 delegate_ = nullptr; | 520 delegate_ = nullptr; |
| 539 Reset(); | 521 Reset(); |
| 540 } | 522 } |
| 541 | 523 |
| 542 void PresentationServiceImpl::OnDefaultPresentationStarted( | 524 void PresentationServiceImpl::OnDefaultPresentationStarted( |
| 543 const PresentationSessionInfo& session) { | 525 const PresentationSessionInfo& session) { |
| 544 if (default_session_start_context_.get()) | 526 if (default_session_start_context_.get()) |
| 545 default_session_start_context_->set_session(session); | 527 default_session_start_context_->set_session(session); |
| 546 } | 528 } |
| 547 | 529 |
| 548 PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext( | 530 PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 549 const std::string& presentation_url) | 531 ::ScreenAvailabilityListenerImpl( |
| 550 : presentation_url_(presentation_url) { | 532 const std::string& presentation_url, |
| 533 PresentationServiceImpl* service) |
| 534 : presentation_url_(presentation_url), |
| 535 service_(service) { |
| 536 DCHECK(service_); |
| 537 DCHECK(service_->client_.get()); |
| 551 } | 538 } |
| 552 | 539 |
| 553 PresentationServiceImpl::ScreenAvailabilityContext:: | 540 PresentationServiceImpl::ScreenAvailabilityListenerImpl:: |
| 554 ~ScreenAvailabilityContext() { | 541 ~ScreenAvailabilityListenerImpl() { |
| 555 // Ensure that pending callbacks are flushed. | |
| 556 OnScreenAvailabilityChanged(false); | |
| 557 } | 542 } |
| 558 | 543 |
| 559 void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived( | 544 std::string PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 560 const ScreenAvailabilityMojoCallback& callback) { | |
| 561 // NOTE: This will overwrite previously registered callback if any. | |
| 562 if (!available_ptr_) { | |
| 563 // No results yet, store callback for later invocation. | |
| 564 callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback)); | |
| 565 } else { | |
| 566 // Run callback now, reset result. | |
| 567 // There shouldn't be any callbacks stored in this scenario. | |
| 568 DCHECK(!HasPendingCallbacks()); | |
| 569 callback.Run(presentation_url_, *available_ptr_); | |
| 570 available_ptr_.reset(); | |
| 571 } | |
| 572 } | |
| 573 | |
| 574 std::string PresentationServiceImpl::ScreenAvailabilityContext | |
| 575 ::GetPresentationUrl() const { | 545 ::GetPresentationUrl() const { |
| 576 return presentation_url_; | 546 return presentation_url_; |
| 577 } | 547 } |
| 578 | 548 |
| 579 void PresentationServiceImpl::ScreenAvailabilityContext | 549 void PresentationServiceImpl::ScreenAvailabilityListenerImpl |
| 580 ::OnScreenAvailabilityChanged(bool available) { | 550 ::OnScreenAvailabilityChanged(bool available) { |
| 581 if (!HasPendingCallbacks()) { | 551 service_->client_->OnScreenAvailabilityUpdated(available); |
| 582 // No callback, stash the result for now. | |
| 583 available_ptr_.reset(new bool(available)); | |
| 584 } else { | |
| 585 // Invoke callbacks and erase them. | |
| 586 // There shouldn't be any result stored in this scenario. | |
| 587 DCHECK(!available_ptr_); | |
| 588 ScopedVector<ScreenAvailabilityMojoCallback> callbacks; | |
| 589 callbacks.swap(callbacks_); | |
| 590 for (const auto& callback : callbacks) | |
| 591 callback->Run(presentation_url_, available); | |
| 592 } | |
| 593 } | |
| 594 | |
| 595 void PresentationServiceImpl::ScreenAvailabilityContext | |
| 596 ::PassPendingCallbacks( | |
| 597 PresentationServiceImpl::ScreenAvailabilityContext* other) { | |
| 598 std::vector<ScreenAvailabilityMojoCallback*> callbacks; | |
| 599 callbacks_.release(&callbacks); | |
| 600 std::copy(callbacks.begin(), callbacks.end(), | |
| 601 std::back_inserter(other->callbacks_)); | |
| 602 } | |
| 603 | |
| 604 bool PresentationServiceImpl::ScreenAvailabilityContext | |
| 605 ::HasPendingCallbacks() const { | |
| 606 return !callbacks_.empty(); | |
| 607 } | 552 } |
| 608 | 553 |
| 609 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( | 554 PresentationServiceImpl::StartSessionRequest::StartSessionRequest( |
| 610 const std::string& presentation_url, | 555 const std::string& presentation_url, |
| 611 const std::string& presentation_id, | 556 const std::string& presentation_id, |
| 612 const NewSessionMojoCallback& callback) | 557 const NewSessionMojoCallback& callback) |
| 613 : presentation_url_(presentation_url), | 558 : presentation_url_(presentation_url), |
| 614 presentation_id_(presentation_id), | 559 presentation_id_(presentation_id), |
| 615 callback_(callback) { | 560 callback_(callback) { |
| 616 } | 561 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { | 609 void PresentationServiceImpl::DefaultSessionStartContext::Reset() { |
| 665 ScopedVector<DefaultSessionMojoCallback> callbacks; | 610 ScopedVector<DefaultSessionMojoCallback> callbacks; |
| 666 callbacks.swap(callbacks_); | 611 callbacks.swap(callbacks_); |
| 667 for (const auto& callback : callbacks) | 612 for (const auto& callback : callbacks) |
| 668 callback->Run(presentation::PresentationSessionInfoPtr()); | 613 callback->Run(presentation::PresentationSessionInfoPtr()); |
| 669 session_.reset(); | 614 session_.reset(); |
| 670 } | 615 } |
| 671 | 616 |
| 672 } // namespace content | 617 } // namespace content |
| 673 | 618 |
| OLD | NEW |