Skip to content

Commit

Permalink
[RemotePlayback, Presentation] ScreenAvailability - part 1
Browse files Browse the repository at this point in the history
Adds blink::mojom::ScreenAvailability in presentation.mojom to
be used by both RemotePlayback and Presentation APIs.

Replace PresentationDispatcher::ScreenAvailability with it.

Switches the plumbing from PresentationAvailability to
PresentationServiceImpl to use the enums instead of bool.

Updates the tests.

(part 2 will update the plumbing from PresentationServiceImpl to
MediaRouter).

BUG=723032
TEST=existing/mofidied tests

Change-Id: I818e46507ffb02ca6f1d1a526832b734b8011891
Reviewed-on: https://chromium-review.googlesource.com/527376
Commit-Queue: Anton Vayvod <avayvod@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Derek Cheng <imcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#478460}
  • Loading branch information
avayvod authored and Commit Bot committed Jun 9, 2017
1 parent a2c8ec6 commit 1275d66
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 118 deletions.
8 changes: 6 additions & 2 deletions content/browser/presentation/presentation_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ void PresentationServiceImpl::SetClient(
void PresentationServiceImpl::ListenForScreenAvailability(const GURL& url) {
DVLOG(2) << "ListenForScreenAvailability " << url.spec();
if (!controller_delegate_) {
client_->OnScreenAvailabilityUpdated(url, false);
client_->OnScreenAvailabilityUpdated(
url, blink::mojom::ScreenAvailability::UNAVAILABLE);
return;
}

Expand Down Expand Up @@ -491,7 +492,10 @@ GURL PresentationServiceImpl::ScreenAvailabilityListenerImpl::

void PresentationServiceImpl::ScreenAvailabilityListenerImpl
::OnScreenAvailabilityChanged(bool available) {
service_->client_->OnScreenAvailabilityUpdated(availability_url_, available);
service_->client_->OnScreenAvailabilityUpdated(
availability_url_, available
? blink::mojom::ScreenAvailability::AVAILABLE
: blink::mojom::ScreenAvailability::UNAVAILABLE);
}

void PresentationServiceImpl::ScreenAvailabilityListenerImpl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ class MockPresentationServiceClient
: public blink::mojom::PresentationServiceClient {
public:
MOCK_METHOD2(OnScreenAvailabilityUpdated,
void(const GURL& url, bool available));
void(const GURL& url,
blink::mojom::ScreenAvailability availability));
MOCK_METHOD2(OnConnectionStateChanged,
void(const PresentationInfo& connection,
PresentationConnectionState new_state));
Expand Down Expand Up @@ -317,7 +318,11 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
ASSERT_TRUE(listener_it->second);

base::RunLoop run_loop;
EXPECT_CALL(mock_client_, OnScreenAvailabilityUpdated(url, available))
blink::mojom::ScreenAvailability expected_availability =
available ? blink::mojom::ScreenAvailability::AVAILABLE
: blink::mojom::ScreenAvailability::UNAVAILABLE;
EXPECT_CALL(mock_client_,
OnScreenAvailabilityUpdated(url, expected_availability))
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
listener_it->second->OnScreenAvailabilityChanged(available);
run_loop.Run();
Expand Down
84 changes: 52 additions & 32 deletions content/renderer/presentation/presentation_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void PresentationDispatcher::GetAvailability(

auto screen_availability = GetScreenAvailability(urls);
// Reject Promise if screen availability is unsupported for all URLs.
if (screen_availability == ScreenAvailability::UNSUPPORTED) {
if (screen_availability == blink::mojom::ScreenAvailability::DISABLED) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(
Expand All @@ -321,12 +321,13 @@ void PresentationDispatcher::GetAvailability(
availability_set_.insert(base::WrapUnique(listener));
}

if (screen_availability != ScreenAvailability::UNKNOWN) {
if (screen_availability != blink::mojom::ScreenAvailability::UNKNOWN) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&blink::WebPresentationAvailabilityCallbacks::OnSuccess,
base::Passed(&callback),
screen_availability == ScreenAvailability::AVAILABLE));
screen_availability ==
blink::mojom::ScreenAvailability::AVAILABLE));
} else {
listener->availability_callbacks.Add(std::move(callback));
}
Expand Down Expand Up @@ -423,39 +424,37 @@ void PresentationDispatcher::WidgetWillClose() {
blink::WebPresentationConnectionState::kTerminated);
}

void PresentationDispatcher::OnScreenAvailabilityUpdated(const GURL& url,
bool available) {
void PresentationDispatcher::OnScreenAvailabilityUpdated(
const GURL& url,
blink::mojom::ScreenAvailability availability) {
auto* listening_status = GetListeningStatus(url);
if (!listening_status)
return;

if (listening_status->listening_state == ListeningState::WAITING)
listening_status->listening_state = ListeningState::ACTIVE;

auto new_screen_availability = available ? ScreenAvailability::AVAILABLE
: ScreenAvailability::UNAVAILABLE;
if (listening_status->last_known_availability == new_screen_availability)
if (listening_status->last_known_availability == availability)
return;

listening_status->last_known_availability = new_screen_availability;
listening_status->last_known_availability = availability;

std::set<AvailabilityListener*> modified_listeners;
for (auto& listener : availability_set_) {
if (!base::ContainsValue(listener->urls, url))
continue;

auto screen_availability = GetScreenAvailability(listener->urls);
DCHECK(screen_availability == ScreenAvailability::AVAILABLE ||
screen_availability == ScreenAvailability::UNAVAILABLE);
bool is_available = (screen_availability == ScreenAvailability::AVAILABLE);

DCHECK(screen_availability != blink::mojom::ScreenAvailability::UNKNOWN &&
screen_availability != blink::mojom::ScreenAvailability::DISABLED);
for (auto* observer : listener->availability_observers)
observer->AvailabilityChanged(is_available);
observer->AvailabilityChanged(screen_availability);

for (AvailabilityCallbacksMap::iterator iter(
&listener->availability_callbacks);
!iter.IsAtEnd(); iter.Advance()) {
iter.GetCurrentValue()->OnSuccess(is_available);
iter.GetCurrentValue()->OnSuccess(
screen_availability == blink::mojom::ScreenAvailability::AVAILABLE);
}
listener->availability_callbacks.Clear();

Expand All @@ -478,11 +477,12 @@ void PresentationDispatcher::OnScreenAvailabilityNotSupported(const GURL& url) {
listening_status->listening_state = ListeningState::ACTIVE;

if (listening_status->last_known_availability ==
ScreenAvailability::UNSUPPORTED) {
blink::mojom::ScreenAvailability::DISABLED) {
return;
}

listening_status->last_known_availability = ScreenAvailability::UNSUPPORTED;
listening_status->last_known_availability =
blink::mojom::ScreenAvailability::DISABLED;

const blink::WebString& not_supported_error = blink::WebString::FromUTF8(
"getAvailability() isn't supported at the moment. It can be due to "
Expand All @@ -496,10 +496,15 @@ void PresentationDispatcher::OnScreenAvailabilityNotSupported(const GURL& url) {

// ScreenAvailabilityNotSupported should be a browser side setting, which
// means all urls in PresentationAvailability should report NotSupported.
// It is not possible to change listening status from Available or
// Unavailable to NotSupported. No need to update observer.
// It is not possible to change listening status from AVAILABLE or
// UNAVAILABLE to DISABLED.
auto screen_availability = GetScreenAvailability(listener->urls);
DCHECK_EQ(screen_availability, ScreenAvailability::UNSUPPORTED);
DCHECK_EQ(screen_availability, blink::mojom::ScreenAvailability::DISABLED);

// RemotePlayback is using a listener but doesn't use callbacks.
// So update observers even though it's not necessary for Presentation API.
for (auto* observer : listener->availability_observers)
observer->AvailabilityChanged(screen_availability);

for (AvailabilityCallbacksMap::iterator iter(
&listener->availability_callbacks);
Expand Down Expand Up @@ -730,23 +735,38 @@ void PresentationDispatcher::TryRemoveAvailabilityListener(
}
}

// Given a screen availability vector and integer value for each availability:
// UNKNOWN = 0, UNAVAILABLE = 1, UNSUPPORTED = 2, and AVAILABLE = 3, the max
// value of the vector is the overall availability.
PresentationDispatcher::ScreenAvailability
PresentationDispatcher::GetScreenAvailability(
blink::mojom::ScreenAvailability PresentationDispatcher::GetScreenAvailability(
const std::vector<GURL>& urls) const {
int current_availability = 0; // UNKNOWN;
bool has_disabled = false;
bool has_source_not_supported = false;
bool has_unavailable = false;

for (const auto& url : urls) {
auto* status = GetListeningStatus(url);
auto screen_availability =
status ? status->last_known_availability : ScreenAvailability::UNKNOWN;
current_availability =
std::max(current_availability, static_cast<int>(screen_availability));
auto screen_availability = status
? status->last_known_availability
: blink::mojom::ScreenAvailability::UNKNOWN;
if (screen_availability == blink::mojom::ScreenAvailability::AVAILABLE) {
return blink::mojom::ScreenAvailability::AVAILABLE;
} else if (screen_availability ==
blink::mojom::ScreenAvailability::DISABLED) {
has_disabled = true;
} else if (screen_availability ==
blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED) {
has_source_not_supported = true;
} else if (screen_availability ==
blink::mojom::ScreenAvailability::UNAVAILABLE) {
has_unavailable = true;
}
}

return static_cast<ScreenAvailability>(current_availability);
if (has_disabled)
return blink::mojom::ScreenAvailability::DISABLED;
if (has_source_not_supported)
return blink::mojom::ScreenAvailability::SOURCE_NOT_SUPPORTED;
if (has_unavailable)
return blink::mojom::ScreenAvailability::UNAVAILABLE;
return blink::mojom::ScreenAvailability::UNKNOWN;
}

PresentationDispatcher::SendMessageRequest::SendMessageRequest(
Expand Down Expand Up @@ -799,7 +819,7 @@ PresentationDispatcher::AvailabilityListener::~AvailabilityListener() {}
PresentationDispatcher::ListeningStatus::ListeningStatus(
const GURL& availability_url)
: url(availability_url),
last_known_availability(ScreenAvailability::UNKNOWN),
last_known_availability(blink::mojom::ScreenAvailability::UNKNOWN),
listening_state(ListeningState::INACTIVE) {}

PresentationDispatcher::ListeningStatus::~ListeningStatus() {}
Expand Down
31 changes: 13 additions & 18 deletions content/renderer/presentation/presentation_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ class CONTENT_EXPORT PresentationDispatcher

// blink::mojom::PresentationServiceClient
void OnScreenAvailabilityNotSupported(const GURL& url) override;
void OnScreenAvailabilityUpdated(const GURL& url, bool available) override;
void OnScreenAvailabilityUpdated(
const GURL& url,
blink::mojom::ScreenAvailability availability) override;
void OnConnectionStateChanged(const PresentationInfo& presentation_info,
PresentationConnectionState state) override;
void OnConnectionClosed(const PresentationInfo& presentation_info,
Expand Down Expand Up @@ -219,15 +221,6 @@ class CONTENT_EXPORT PresentationDispatcher
ACTIVE,
};

// Do not change order or add new enum values. |GetScreenAvailability| impl
// depends on the order of the enum values.
enum class ScreenAvailability {
UNKNOWN = 0,
UNAVAILABLE,
UNSUPPORTED,
AVAILABLE
};

using AvailabilityCallbacksMap =
IDMap<std::unique_ptr<blink::WebPresentationAvailabilityCallbacks>>;
using AvailabilityObserversSet =
Expand All @@ -250,7 +243,7 @@ class CONTENT_EXPORT PresentationDispatcher
~ListeningStatus();

const GURL url;
ScreenAvailability last_known_availability;
blink::mojom::ScreenAvailability last_known_availability;
ListeningState listening_state;
};

Expand Down Expand Up @@ -279,13 +272,15 @@ class CONTENT_EXPORT PresentationDispatcher
void TryRemoveAvailabilityListener(AvailabilityListener* listener);

// Returns AVAILABLE if any url in |urls| has screen availability AVAILABLE;
// Returns UNSUPPORTED if any url in |urls| have screen availability
// UNSUPPORTED, and no url has screen availability AVAILABLE;
// Returns UNAVAILABLE if at least one url in |urls| has screen availability
// UNAVAILABLE, and no url has screen availability AVAILABLE or UNSUPPORTED;
// Returns UNKNOWN if all urls in |urls| have screen availability
// UNKNOWN.
ScreenAvailability GetScreenAvailability(const std::vector<GURL>& urls) const;
// otherwise returns DISABLED if at least one url in |urls| has screen
// availability DISABLED;
// otherwise, returns SOURCE_NOT_SUPPORTED if any url in |urls| has screen
// availability SOURCE_NOT_SUPPORTED;
// otherwise, returns UNAVAILABLE if any url in |urls| has screen
// availability UNAVAILABLE;
// otherwise returns UNKNOWN.
blink::mojom::ScreenAvailability GetScreenAvailability(
const std::vector<GURL>& urls) const;

DISALLOW_COPY_AND_ASSIGN(PresentationDispatcher);
};
Expand Down
Loading

0 comments on commit 1275d66

Please sign in to comment.