diff options
author | imcheng <imcheng@google.com> | 2015-05-12 12:27:01 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-12 19:27:44 +0000 |
commit | 9ce5394bf20f18b1413a214bef4548055c3bcb83 (patch) | |
tree | 7ad51d9e26e44cef9f2fe1c4ef940eed0da755c5 /content/browser/presentation/presentation_service_impl.cc | |
parent | e8b1380e33a4c3c435e442c750706555aba63d5f (diff) | |
download | chromium_src-9ce5394bf20f18b1413a214bef4548055c3bcb83.zip chromium_src-9ce5394bf20f18b1413a214bef4548055c3bcb83.tar.gz chromium_src-9ce5394bf20f18b1413a214bef4548055c3bcb83.tar.bz2 |
[Presentation API] Convert screen availability API into Client style.
Introduced a PresentationServiceClient mojo interface implemented by
PresentationDispatcher. On connection to PresentationService,
PDispatcher will pass a proxy of itself to PSImpl.
Please note that screen availability updates are already throttled
from the browser's perspective.
When a screen availability update is available, it will be transmitted
back to PSDispatcher via the PresentationServiceClient interface.
In the future, I plan to use the same interface for other types of
observer-style APIs (e.g. default session start, session state change,
on message).
Also, simplified the ScreenAvailability API so it only operates on
the DPU (or 1-UA mode if absent). The current semantics to support
listening on arbitrarily presentation URLs + handling behavior for
DPU is very confusing. We should revisit the implementation when we
decide to support it.
This will also hopefully fix the bug where ScreenAvailability mojo
callbacks accumulate over time.
Also fix mojom indent.
BUG=485337
Review URL: https://codereview.chromium.org/1131053005
Cr-Commit-Position: refs/heads/master@{#329457}
Diffstat (limited to 'content/browser/presentation/presentation_service_impl.cc')
-rw-r--r-- | content/browser/presentation/presentation_service_impl.cc | 189 |
1 files changed, 67 insertions, 122 deletions
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc index 1143ddd..7a0bab8 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( |