Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1179)

Unified Diff: content/renderer/presentation/presentation_dispatcher.cc

Issue 2598063002: [Presentation API] Handle multiple Presentation URLs in PresentationRequest::getAvailability() (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/presentation/presentation_dispatcher.cc
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc
index d11943b79e404df99222a41641dd1e3910598231..ea70082b0746a3409dbe3fb8fd43d9706dce5fa6 100644
--- a/content/renderer/presentation/presentation_dispatcher.cc
+++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -76,6 +76,10 @@ GetWebPresentationConnectionCloseReasonFromMojo(
}
}
+constexpr char k_not_supported_error[] =
+ "getAvailability() isn't supported at the moment. It can be due to "
mark a. foltz 2016/12/23 01:04:22 kNotSupportedError per style guide
zhaobin 2016/12/29 18:48:38 Code removed.
+ "a permanent or temporary system limitation. It is recommended to "
+ "try to blindly start a session in that case.";
mark a. foltz 2016/12/23 01:04:22 I would keep this simple: Screen availability mo
zhaobin 2016/12/29 18:48:38 Code removed.
} // namespace
namespace content {
@@ -246,38 +250,59 @@ void PresentationDispatcher::terminateSession(
void PresentationDispatcher::getAvailability(
const blink::WebVector<blink::WebURL>& availabilityUrls,
std::unique_ptr<blink::WebPresentationAvailabilityCallbacks> callbacks) {
- // TODO(mfoltz): Pass all URLs to PresentationService. See crbug.com/627655.
- const blink::WebURL& availabilityUrl = availabilityUrls[0];
+ std::vector<GURL> urls;
+ for (const auto& url : availabilityUrls)
+ urls.push_back(url);
+
AvailabilityStatus* status = nullptr;
- auto status_it = availability_status_.find(availabilityUrl);
+ auto status_it = availability_status_.find(urls);
if (status_it == availability_status_.end()) {
- status = new AvailabilityStatus(availabilityUrl);
- availability_status_[availabilityUrl] = base::WrapUnique(status);
+ status = new AvailabilityStatus(urls);
+ availability_status_[urls] = base::WrapUnique(status);
mark a. foltz 2016/12/23 01:04:22 Would it be simpler to continue tracking status fo
zhaobin 2016/12/29 18:48:38 Done.
} else {
status = status_it->second.get();
}
DCHECK(status);
- if (status->listening_state == ListeningState::ACTIVE) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&blink::WebPresentationAvailabilityCallbacks::onSuccess,
- base::Passed(&callbacks), status->last_known_availability));
- return;
+ auto presentation_error = blink::WebPresentationError(
+ blink::WebPresentationError::ErrorTypeAvailabilityNotSupported,
+ blink::WebString::fromUTF8(k_not_supported_error));
+
+ auto request_availability = GetRequestAvailability(urls);
+
+ switch (request_availability) {
+ case ScreenAvailability::UNKNOWN:
+ status->availability_callbacks.Add(std::move(callbacks));
+ UpdateListeningState(status);
+ break;
+ case ScreenAvailability::UNSUPPORTED:
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&blink::WebPresentationAvailabilityCallbacks::onError,
+ base::Passed(&callbacks), presentation_error));
+ break;
+ case ScreenAvailability::AVAILABLE:
+ case ScreenAvailability::UNAVAILABLE:
+ bool is_available = request_availability == ScreenAvailability::AVAILABLE;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(&blink::WebPresentationAvailabilityCallbacks::onSuccess,
+ base::Passed(&callbacks), is_available));
+ break;
}
-
- status->availability_callbacks.Add(std::move(callbacks));
- UpdateListeningState(status);
}
void PresentationDispatcher::startListening(
blink::WebPresentationAvailabilityObserver* observer) {
- // TODO(mfoltz): Pass all URLs to PresentationService. See crbug.com/627655.
- const blink::WebURL& availabilityUrl = observer->urls()[0];
- auto status_it = availability_status_.find(availabilityUrl);
+ std::vector<GURL> urls;
+ for (const auto& url : observer->urls())
+ urls.push_back(url);
+
+ auto status_it = availability_status_.find(urls);
if (status_it == availability_status_.end()) {
- DLOG(WARNING) << "Start listening for availability for unknown URL "
- << GURL(availabilityUrl);
+ DLOG(WARNING) << "Start listening for availability for unknown URLs:";
+ for (const auto& url : urls)
+ DLOG(WARNING) << " " << url;
return;
}
status_it->second->availability_observers.insert(observer);
@@ -286,12 +311,15 @@ void PresentationDispatcher::startListening(
void PresentationDispatcher::stopListening(
blink::WebPresentationAvailabilityObserver* observer) {
- // TODO(mfoltz): Pass all URLs to PresentationService. See crbug.com/627655.
- const blink::WebURL& availabilityUrl = observer->urls()[0];
- auto status_it = availability_status_.find(availabilityUrl);
+ std::vector<GURL> urls;
+ for (const auto& url : observer->urls())
+ urls.push_back(url);
+
+ auto status_it = availability_status_.find(urls);
if (status_it == availability_status_.end()) {
- DLOG(WARNING) << "Stop listening for availability for unknown URL "
- << GURL(availabilityUrl);
+ DLOG(WARNING) << "Stop listening for availability for unknown URLs: ";
+ for (const auto& url : urls)
+ DLOG(WARNING) << " " << url;
return;
}
status_it->second->availability_observers.erase(observer);
@@ -334,44 +362,70 @@ void PresentationDispatcher::OnDestruct() {
void PresentationDispatcher::OnScreenAvailabilityUpdated(const GURL& url,
bool available) {
- auto status_it = availability_status_.find(url);
- if (status_it == availability_status_.end())
- return;
- AvailabilityStatus* status = status_it->second.get();
- DCHECK(status);
+ OnScreenAvailabilityUpdated(url, available ? ScreenAvailability::AVAILABLE
+ : ScreenAvailability::UNAVAILABLE);
+}
- if (status->listening_state == ListeningState::WAITING)
- status->listening_state = ListeningState::ACTIVE;
+void PresentationDispatcher::OnScreenAvailabilityNotSupported(const GURL& url) {
+ OnScreenAvailabilityUpdated(url, ScreenAvailability::UNSUPPORTED);
+}
+
+void PresentationDispatcher::OnScreenAvailabilityUpdated(
+ const GURL& url,
+ ScreenAvailability screen_availability) {
+ DCHECK(base::ContainsKey(url_listening_state_, url));
+
+ if (url_listening_state_[url] == ListeningState::WAITING)
+ url_listening_state_[url] = ListeningState::ACTIVE;
+
+ screen_availability_[url] = screen_availability;
+
+ for (auto& status_it : availability_status_) {
+ if (!base::ContainsValue(status_it.first, url))
+ continue;
+
+ auto request_availability = GetRequestAvailability(status_it.first);
+ switch (request_availability) {
+ case ScreenAvailability::UNKNOWN:
+ break;
+ case ScreenAvailability::UNSUPPORTED:
+ OnScreenAvailabilityNotSupported(status_it.second.get());
+ break;
+ case ScreenAvailability::AVAILABLE:
+ case ScreenAvailability::UNAVAILABLE:
+ OnScreenAvailabilityUpdated(
+ status_it.second.get(),
+ (request_availability == ScreenAvailability::AVAILABLE));
+ break;
+ }
+ }
+}
+
+void PresentationDispatcher::OnScreenAvailabilityUpdated(
+ AvailabilityStatus* status,
+ bool available) {
+ DCHECK(status);
for (auto* observer : status->availability_observers)
observer->availabilityChanged(available);
for (AvailabilityCallbacksMap::iterator iter(&status->availability_callbacks);
- !iter.IsAtEnd(); iter.Advance()) {
+ !iter.IsAtEnd(); iter.Advance())
iter.GetCurrentValue()->onSuccess(available);
- }
- status->last_known_availability = available;
+
status->availability_callbacks.Clear();
UpdateListeningState(status);
}
-void PresentationDispatcher::OnScreenAvailabilityNotSupported(const GURL& url) {
- auto status_it = availability_status_.find(url);
- if (status_it == availability_status_.end())
- return;
- AvailabilityStatus* status = status_it->second.get();
+void PresentationDispatcher::OnScreenAvailabilityNotSupported(
+ AvailabilityStatus* status) {
DCHECK(status);
- DCHECK(status->listening_state == ListeningState::WAITING);
- const blink::WebString& not_supported_error = blink::WebString::fromUTF8(
- "getAvailability() isn't supported at the moment. It can be due to "
- "a permanent or temporary system limitation. It is recommended to "
- "try to blindly start a session in that case.");
for (AvailabilityCallbacksMap::iterator iter(&status->availability_callbacks);
!iter.IsAtEnd(); iter.Advance()) {
iter.GetCurrentValue()->onError(blink::WebPresentationError(
blink::WebPresentationError::ErrorTypeAvailabilityNotSupported,
- not_supported_error));
+ blink::WebString::fromUTF8(k_not_supported_error)));
}
status->availability_callbacks.Clear();
UpdateListeningState(status);
@@ -484,22 +538,79 @@ void PresentationDispatcher::ConnectToPresentationServiceIfNeeded() {
presentation_service_->SetClient(binding_.CreateInterfacePtrAndBind());
}
-void PresentationDispatcher::UpdateListeningState(AvailabilityStatus* status) {
- bool should_listen = !status->availability_callbacks.IsEmpty() ||
- !status->availability_observers.empty();
- bool is_listening = status->listening_state != ListeningState::INACTIVE;
+void PresentationDispatcher::SetPresentationServiceForTest(
+ blink::mojom::PresentationServicePtr presentation_service) {
+ presentation_service_ = std::move(presentation_service);
+}
- if (should_listen == is_listening)
- return;
+void PresentationDispatcher::UpdateListeningState(AvailabilityStatus* status) {
+ // Calculate if we should listen to status->urls.
+ std::map<GURL, bool> url_should_listen;
+ for (const auto& it : availability_status_) {
+ bool should_listen = !it.second->availability_callbacks.IsEmpty() ||
+ !it.second->availability_observers.empty();
+
+ for (const auto& url : it.first) {
+ if (base::ContainsValue(status->urls, url))
+ url_should_listen[url] = url_should_listen[url] || should_listen;
+ }
+ }
ConnectToPresentationServiceIfNeeded();
- if (should_listen) {
- status->listening_state = ListeningState::WAITING;
- presentation_service_->ListenForScreenAvailability(status->url);
- } else {
- status->listening_state = ListeningState::INACTIVE;
- presentation_service_->StopListeningForScreenAvailability(status->url);
+
+ for (const auto& url : status->urls) {
+ bool is_listening = false;
+ if (base::ContainsKey(url_listening_state_, url))
+ is_listening = url_listening_state_[url] != ListeningState::INACTIVE;
+
+ bool should_listen = url_should_listen[url];
+
+ if (should_listen == is_listening)
+ continue;
+
+ if (should_listen) {
+ url_listening_state_[url] = ListeningState::WAITING;
+ presentation_service_->ListenForScreenAvailability(url);
+ } else {
+ url_listening_state_[url] = ListeningState::INACTIVE;
+ presentation_service_->StopListeningForScreenAvailability(url);
+ }
+ }
+}
+
+PresentationDispatcher::ScreenAvailability
+PresentationDispatcher::GetRequestAvailability(const std::vector<GURL>& urls) {
+ size_t available_cnt = 0;
+ size_t unavailable_cnt = 0;
+ size_t unsupport_cnt = 0;
+
+ for (const auto& url : urls) {
+ if (!base::ContainsKey(screen_availability_, url))
+ return ScreenAvailability::UNKNOWN;
+
+ auto url_availability = screen_availability_[url];
+ switch (url_availability) {
+ case ScreenAvailability::AVAILABLE:
+ available_cnt++;
+ break;
+ case ScreenAvailability::UNAVAILABLE:
+ unavailable_cnt++;
+ break;
+ case ScreenAvailability::UNSUPPORTED:
+ unsupport_cnt++;
+ break;
+ case ScreenAvailability::UNKNOWN:
+ break;
+ }
}
+
+ if (available_cnt > 0)
+ return ScreenAvailability::AVAILABLE;
+ if (unavailable_cnt > 0)
+ return ScreenAvailability::UNAVAILABLE;
+
+ DCHECK(unsupport_cnt == urls.size());
+ return ScreenAvailability::UNSUPPORTED;
}
PresentationDispatcher::SendMessageRequest::SendMessageRequest(
@@ -550,10 +661,8 @@ PresentationDispatcher::CreateSendBinaryMessageRequest(
}
PresentationDispatcher::AvailabilityStatus::AvailabilityStatus(
- const GURL& availability_url)
- : url(availability_url),
- last_known_availability(false),
- listening_state(ListeningState::INACTIVE) {}
+ const std::vector<GURL>& availability_urls)
+ : urls(availability_urls) {}
PresentationDispatcher::AvailabilityStatus::~AvailabilityStatus() {
}

Powered by Google App Engine
This is Rietveld 408576698