Chromium Code Reviews| Index: third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| index 0140200e09678985f03cafb2d369e712fca8ad64..98fc8c4fa0fdfc51b57de279b13078abb69f5e22 100644 |
| --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp |
| @@ -16,8 +16,11 @@ |
| #include "core/html/HTMLVideoElement.h" |
| #include "core/probe/CoreProbes.h" |
| #include "modules/EventTargetModules.h" |
| +#include "modules/presentation/PresentationController.h" |
| #include "modules/remoteplayback/AvailabilityCallbackWrapper.h" |
| #include "platform/MemoryCoordinator.h" |
| +#include "platform/json/JSONValues.h" |
| +#include "platform/wtf/text/Base64.h" |
| namespace blink { |
| @@ -59,7 +62,8 @@ RemotePlayback::RemotePlayback(HTMLMediaElement& element) |
| ? WebRemotePlaybackState::kConnected |
| : WebRemotePlaybackState::kDisconnected), |
| availability_(WebRemotePlaybackAvailability::kUnknown), |
| - media_element_(&element) {} |
| + media_element_(&element), |
| + is_listening_(false) {} |
| const AtomicString& RemotePlayback::InterfaceName() const { |
| return EventTargetNames::RemotePlayback; |
| @@ -134,6 +138,7 @@ ScriptPromise RemotePlayback::cancelWatchAvailability( |
| } |
| availability_callbacks_.clear(); |
| + UpdateListeningState(); |
| resolver->Resolve(); |
| return promise; |
| @@ -170,6 +175,8 @@ ScriptPromise RemotePlayback::prompt(ScriptState* script_state) { |
| return promise; |
| } |
| + // TODO(avayvod): none of these two states is propagated with the new |
| + // pipeline. |
|
mark a. foltz
2017/05/31 21:16:41
So kNotSupported error will not be thrown going fo
|
| if (availability_ == WebRemotePlaybackAvailability::kSourceNotSupported || |
| availability_ == WebRemotePlaybackAvailability::kSourceNotCompatible) { |
| resolver->Reject(DOMException::Create( |
| @@ -223,6 +230,8 @@ int RemotePlayback::WatchAvailabilityInternal( |
| WTF::Bind(RunNotifyInitialAvailabilityTask, |
| WrapPersistent(GetExecutionContext()), |
| WTF::Passed(std::move(task)))); |
| + |
| + UpdateListeningState(); |
| return id; |
| } |
| @@ -231,6 +240,8 @@ bool RemotePlayback::CancelWatchAvailabilityInternal(int id) { |
| if (iter == availability_callbacks_.end()) |
| return false; |
| availability_callbacks_.erase(iter); |
| + UpdateListeningState(); |
| + |
| return true; |
| } |
| @@ -312,6 +323,24 @@ void RemotePlayback::PromptCancelled() { |
| prompt_promise_resolver_ = nullptr; |
| } |
| +void RemotePlayback::SourceChanged(const WebURL& source) { |
| + DCHECK(RuntimeEnabledFeatures::newRemotePlaybackPipelineEnabled()); |
| + |
| + // If we're listening for the previous source, we should stop listening to |
|
mark a. foltz
2017/05/31 21:16:41
Do you want to restrict source URLs considered to
|
| + // update the source for the WebPresentationClient. |
| + if (!availability_urls_.empty()) { |
| + WebVector<WebURL> empty_urls; |
| + availability_urls_.Swap(empty_urls); |
| + UpdateListeningState(); |
| + } |
| + |
| + // Ignore the new source if it's not meaningful. |
| + if (!source.IsEmpty() && source.IsValid()) { |
| + UpdateAvailabilityUrls(source); |
| + UpdateListeningState(); |
| + } |
| +} |
| + |
| bool RemotePlayback::RemotePlaybackAvailable() const { |
| return availability_ == WebRemotePlaybackAvailability::kDeviceAvailable; |
| } |
| @@ -324,11 +353,69 @@ void RemotePlayback::RemotePlaybackDisabled() { |
| } |
| availability_callbacks_.clear(); |
| + UpdateListeningState(); |
| if (state_ != WebRemotePlaybackState::kDisconnected) |
| media_element_->RequestRemotePlaybackStop(); |
| } |
| +void RemotePlayback::AvailabilityChanged(bool availability) { |
| + DCHECK(RuntimeEnabledFeatures::newRemotePlaybackPipelineEnabled()); |
| + AvailabilityChanged(availability |
| + ? WebRemotePlaybackAvailability::kDeviceAvailable |
| + : WebRemotePlaybackAvailability::kDeviceNotAvailable); |
| +} |
| + |
| +const WebVector<WebURL>& RemotePlayback::Urls() const { |
| + DCHECK(RuntimeEnabledFeatures::newRemotePlaybackPipelineEnabled()); |
| + // TODO(avayvod): update the URL format and add frame url, mime type and |
| + // response headers when available. |
| + return availability_urls_; |
| +} |
| + |
| +void RemotePlayback::UpdateListeningState() { |
| + if (!RuntimeEnabledFeatures::newRemotePlaybackPipelineEnabled()) |
| + return; |
| + |
| + bool will_be_listening = |
| + !availability_urls_.empty() && !availability_callbacks_.IsEmpty(); |
| + if (is_listening_ == will_be_listening) |
| + return; |
| + |
| + WebPresentationClient* client = |
| + PresentationController::ClientFromContext(GetExecutionContext()); |
| + if (!client) |
| + return; |
| + |
| + if (will_be_listening) { |
| + client->StartListening(this); |
| + } else { |
| + client->StopListening(this); |
| + } |
| + is_listening_ = will_be_listening; |
| +} |
| + |
| +void RemotePlayback::UpdateAvailabilityUrls(const WebURL& source) { |
| + // The URL for each media element's source looks like the following: |
| + // chrome-media-source://<encoded-data> where |encoded-data| is base64 URL |
| + // encoded string representation of a JSON structure with various information |
| + // about the media element's source that looks like this: |
| + // { |
| + // "sourceUrl": "<sourceUrl>", |
| + // } |
| + // TODO(avayvod): add and fill more info to the JSON structure. |
|
mark a. foltz
2017/05/31 21:16:41
Can you explain why URL-encoding is not sufficient
|
| + std::unique_ptr<JSONObject> source_info = JSONObject::Create(); |
| + source_info->SetString("sourceUrl", source.GetString()); |
| + CString json_source_info = source_info->ToJSONString().Utf8(); |
| + String encoded_source_info = |
| + WTF::Base64URLEncode(json_source_info.data(), json_source_info.length()); |
| + |
| + WebVector<WebURL> new_availability_urls((size_t)1); |
| + new_availability_urls[0] = |
| + KURL(kParsedURLString, "chrome-media-source://" + encoded_source_info); |
| + availability_urls_.Swap(new_availability_urls); |
| +} |
| + |
| DEFINE_TRACE(RemotePlayback) { |
| visitor->Trace(availability_callbacks_); |
| visitor->Trace(prompt_promise_resolver_); |