summaryrefslogtreecommitdiffstats
path: root/content/browser/presentation/presentation_service_impl.cc
diff options
context:
space:
mode:
authorimcheng <imcheng@google.com>2015-05-12 12:27:01 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-12 19:27:44 +0000
commit9ce5394bf20f18b1413a214bef4548055c3bcb83 (patch)
tree7ad51d9e26e44cef9f2fe1c4ef940eed0da755c5 /content/browser/presentation/presentation_service_impl.cc
parente8b1380e33a4c3c435e442c750706555aba63d5f (diff)
downloadchromium_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.cc189
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(