| Index: content/browser/presentation/presentation_service_impl.cc
|
| diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc
|
| index 1143ddd065b430f5d136d889b9cbe62894fe3dff..7a0bab8da3a7438f0c27ec6a33adf7af5f753de9 100644
|
| --- a/content/browser/presentation/presentation_service_impl.cc
|
| +++ b/content/browser/presentation/presentation_service_impl.cc
|
| @@ -138,58 +138,62 @@ void PresentationServiceImpl::OnConnectionError() {
|
| delete this;
|
| }
|
|
|
| -PresentationServiceImpl::ScreenAvailabilityContext*
|
| -PresentationServiceImpl::GetOrCreateAvailabilityContext(
|
| - const std::string& presentation_url) {
|
| - auto it = availability_contexts_.find(presentation_url);
|
| - if (it == availability_contexts_.end()) {
|
| - linked_ptr<ScreenAvailabilityContext> context(
|
| - new ScreenAvailabilityContext(presentation_url));
|
| - if (!delegate_->AddScreenAvailabilityListener(
|
| - render_process_id_, render_frame_id_, context.get())) {
|
| - DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request.";
|
| - return nullptr;
|
| - }
|
| - it = availability_contexts_.insert(
|
| - std::make_pair(context->GetPresentationUrl(), context)).first;
|
| - }
|
| - return it->second.get();
|
| +void PresentationServiceImpl::SetClient(
|
| + presentation::PresentationServiceClientPtr client) {
|
| + DCHECK(!client_.get());
|
| + // TODO(imcheng): Set ErrorHandler to listen for errors.
|
| + client_ = client.Pass();
|
| }
|
|
|
| -void PresentationServiceImpl::ListenForScreenAvailability(
|
| - const mojo::String& presentation_url,
|
| - const ScreenAvailabilityMojoCallback& callback) {
|
| +void PresentationServiceImpl::ListenForScreenAvailability() {
|
| DVLOG(2) << "ListenForScreenAvailability";
|
| - if (!delegate_) {
|
| - callback.Run(presentation_url, false);
|
| + if (!delegate_)
|
| return;
|
| - }
|
|
|
| - ScreenAvailabilityContext* context =
|
| - GetOrCreateAvailabilityContext(presentation_url.get());
|
| - if (!context) {
|
| - callback.Run(presentation_url, false);
|
| + if (screen_availability_listener_.get() &&
|
| + screen_availability_listener_->GetPresentationUrl() ==
|
| + default_presentation_url_) {
|
| return;
|
| }
|
| - context->CallbackReceived(callback);
|
| +
|
| + ResetScreenAvailabilityListener(default_presentation_url_);
|
| }
|
|
|
| -void PresentationServiceImpl::RemoveScreenAvailabilityListener(
|
| - const mojo::String& presentation_url) {
|
| - DVLOG(2) << "RemoveScreenAvailabilityListener";
|
| - if (!delegate_)
|
| - return;
|
| +void PresentationServiceImpl::ResetScreenAvailabilityListener(
|
| + const std::string& presentation_url) {
|
| + DCHECK(delegate_);
|
| + DCHECK(!screen_availability_listener_.get() ||
|
| + presentation_url != default_presentation_url_);
|
| +
|
| + // (1) Unregister old listener with delegate
|
| + StopListeningForScreenAvailability();
|
| +
|
| + // (2) Replace old listener with new listener
|
| + screen_availability_listener_.reset(new ScreenAvailabilityListenerImpl(
|
| + presentation_url, this));
|
|
|
| - const std::string& presentation_url_str = presentation_url.get();
|
| - auto it = availability_contexts_.find(presentation_url_str);
|
| - if (it == availability_contexts_.end())
|
| + // (3) Register new listener with delegate
|
| + if (!delegate_->AddScreenAvailabilityListener(
|
| + render_process_id_,
|
| + render_frame_id_,
|
| + screen_availability_listener_.get())) {
|
| + DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request.";
|
| + screen_availability_listener_.reset();
|
| + }
|
| +}
|
| +
|
| +void PresentationServiceImpl::StopListeningForScreenAvailability() {
|
| + DVLOG(2) << "StopListeningForScreenAvailability";
|
| + if (!delegate_)
|
| return;
|
|
|
| - delegate_->RemoveScreenAvailabilityListener(
|
| - render_process_id_, render_frame_id_, it->second.get());
|
| - // Resolve the context's pending callbacks before removing it.
|
| - it->second->OnScreenAvailabilityChanged(false);
|
| - availability_contexts_.erase(it);
|
| + if (screen_availability_listener_.get()) {
|
| + delegate_->RemoveScreenAvailabilityListener(
|
| + render_process_id_,
|
| + render_frame_id_,
|
| + screen_availability_listener_.get());
|
| + screen_availability_listener_.reset();
|
| + }
|
| }
|
|
|
| void PresentationServiceImpl::ListenForDefaultSessionStart(
|
| @@ -322,19 +326,6 @@ void PresentationServiceImpl::RunAndEraseNewSessionMojoCallback(
|
| pending_session_cbs_.erase(it);
|
| }
|
|
|
| -void PresentationServiceImpl::DoSetDefaultPresentationUrl(
|
| - const std::string& default_presentation_url,
|
| - const std::string& default_presentation_id) {
|
| - DCHECK(delegate_);
|
| - delegate_->SetDefaultPresentationUrl(
|
| - render_process_id_,
|
| - render_frame_id_,
|
| - default_presentation_url,
|
| - default_presentation_id);
|
| - default_presentation_url_ = default_presentation_url;
|
| - default_presentation_id_ = default_presentation_id;
|
| -}
|
| -
|
| void PresentationServiceImpl::SetDefaultPresentationURL(
|
| const mojo::String& default_presentation_url,
|
| const mojo::String& default_presentation_id) {
|
| @@ -351,28 +342,19 @@ void PresentationServiceImpl::SetDefaultPresentationURL(
|
| return;
|
| }
|
|
|
| - auto old_it = availability_contexts_.find(old_default_url);
|
| - // Haven't started listening yet.
|
| - if (old_it == availability_contexts_.end()) {
|
| - DoSetDefaultPresentationUrl(new_default_url, default_presentation_id);
|
| - return;
|
| + if (old_default_url != new_default_url) {
|
| + // If DPU changed, replace screen availability listeners if any.
|
| + if (screen_availability_listener_.get())
|
| + ResetScreenAvailabilityListener(new_default_url);
|
| }
|
|
|
| - // Have already started listening. Create a listener for the new URL and
|
| - // transfer the callbacks from the old listener, if any.
|
| - // This is done so that a listener added before default URL is changed
|
| - // will continue to work.
|
| - ScreenAvailabilityContext* context =
|
| - GetOrCreateAvailabilityContext(new_default_url);
|
| - old_it->second->PassPendingCallbacks(context);
|
| -
|
| - // Remove listener for old default presentation URL.
|
| - delegate_->RemoveScreenAvailabilityListener(
|
| + delegate_->SetDefaultPresentationUrl(
|
| render_process_id_,
|
| render_frame_id_,
|
| - old_it->second.get());
|
| - availability_contexts_.erase(old_it);
|
| - DoSetDefaultPresentationUrl(new_default_url, default_presentation_id);
|
| + default_presentation_url,
|
| + default_presentation_id);
|
| + default_presentation_url_ = default_presentation_url;
|
| + default_presentation_id_ = default_presentation_id;
|
| }
|
|
|
|
|
| @@ -507,7 +489,7 @@ void PresentationServiceImpl::Reset() {
|
|
|
| default_presentation_url_.clear();
|
| default_presentation_id_.clear();
|
| - availability_contexts_.clear();
|
| + screen_availability_listener_.reset();
|
| queued_start_session_requests_.clear();
|
| FlushNewSessionCallbacks();
|
| default_session_start_context_.reset();
|
| @@ -545,65 +527,28 @@ void PresentationServiceImpl::OnDefaultPresentationStarted(
|
| default_session_start_context_->set_session(session);
|
| }
|
|
|
| -PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext(
|
| - const std::string& presentation_url)
|
| - : presentation_url_(presentation_url) {
|
| -}
|
| -
|
| -PresentationServiceImpl::ScreenAvailabilityContext::
|
| -~ScreenAvailabilityContext() {
|
| - // Ensure that pending callbacks are flushed.
|
| - OnScreenAvailabilityChanged(false);
|
| +PresentationServiceImpl::ScreenAvailabilityListenerImpl
|
| +::ScreenAvailabilityListenerImpl(
|
| + const std::string& presentation_url,
|
| + PresentationServiceImpl* service)
|
| + : presentation_url_(presentation_url),
|
| + service_(service) {
|
| + DCHECK(service_);
|
| + DCHECK(service_->client_.get());
|
| }
|
|
|
| -void PresentationServiceImpl::ScreenAvailabilityContext::CallbackReceived(
|
| - const ScreenAvailabilityMojoCallback& callback) {
|
| - // NOTE: This will overwrite previously registered callback if any.
|
| - if (!available_ptr_) {
|
| - // No results yet, store callback for later invocation.
|
| - callbacks_.push_back(new ScreenAvailabilityMojoCallback(callback));
|
| - } else {
|
| - // Run callback now, reset result.
|
| - // There shouldn't be any callbacks stored in this scenario.
|
| - DCHECK(!HasPendingCallbacks());
|
| - callback.Run(presentation_url_, *available_ptr_);
|
| - available_ptr_.reset();
|
| - }
|
| +PresentationServiceImpl::ScreenAvailabilityListenerImpl::
|
| +~ScreenAvailabilityListenerImpl() {
|
| }
|
|
|
| -std::string PresentationServiceImpl::ScreenAvailabilityContext
|
| +std::string PresentationServiceImpl::ScreenAvailabilityListenerImpl
|
| ::GetPresentationUrl() const {
|
| return presentation_url_;
|
| }
|
|
|
| -void PresentationServiceImpl::ScreenAvailabilityContext
|
| +void PresentationServiceImpl::ScreenAvailabilityListenerImpl
|
| ::OnScreenAvailabilityChanged(bool available) {
|
| - if (!HasPendingCallbacks()) {
|
| - // No callback, stash the result for now.
|
| - available_ptr_.reset(new bool(available));
|
| - } else {
|
| - // Invoke callbacks and erase them.
|
| - // There shouldn't be any result stored in this scenario.
|
| - DCHECK(!available_ptr_);
|
| - ScopedVector<ScreenAvailabilityMojoCallback> callbacks;
|
| - callbacks.swap(callbacks_);
|
| - for (const auto& callback : callbacks)
|
| - callback->Run(presentation_url_, available);
|
| - }
|
| -}
|
| -
|
| -void PresentationServiceImpl::ScreenAvailabilityContext
|
| - ::PassPendingCallbacks(
|
| - PresentationServiceImpl::ScreenAvailabilityContext* other) {
|
| - std::vector<ScreenAvailabilityMojoCallback*> callbacks;
|
| - callbacks_.release(&callbacks);
|
| - std::copy(callbacks.begin(), callbacks.end(),
|
| - std::back_inserter(other->callbacks_));
|
| -}
|
| -
|
| -bool PresentationServiceImpl::ScreenAvailabilityContext
|
| - ::HasPendingCallbacks() const {
|
| - return !callbacks_.empty();
|
| + service_->client_->OnScreenAvailabilityUpdated(available);
|
| }
|
|
|
| PresentationServiceImpl::StartSessionRequest::StartSessionRequest(
|
|
|