[RemotePlayback] Keep track of source compatibility and reject prompt() correspondingly
BUG=659675,659677,659679
TEST=manual on avayvod.github.io/remote-playback/test.html
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Review-Url: https://codereview.chromium.org/2480003002
Cr-Commit-Position: refs/heads/master@{#431516}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
index 33dbff5..829330db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/RemoteMediaPlayerBridge.java
@@ -9,6 +9,7 @@
import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
+import org.chromium.blink_public.platform.modules.remoteplayback.WebRemotePlaybackAvailability;
import org.chromium.chrome.browser.media.remote.RemoteVideoInfo.PlayerState;
/**
@@ -318,9 +319,19 @@
}
private void onRouteAvailabilityChange() {
+ Log.d(TAG, "onRouteAvailabilityChange: " + mRouteIsAvailable + ", " + mIsPlayable);
if (mNativeRemoteMediaPlayerBridge == 0) return;
- boolean usable = mRouteIsAvailable && mIsPlayable;
- nativeOnRouteAvailabilityChanged(mNativeRemoteMediaPlayerBridge, usable);
+
+ int availability = WebRemotePlaybackAvailability.DeviceNotAvailable;
+ if (!mRouteIsAvailable && !mIsPlayable) {
+ availability = WebRemotePlaybackAvailability.SourceNotSupported;
+ } else if (mRouteIsAvailable && mIsPlayable) {
+ availability = WebRemotePlaybackAvailability.DeviceAvailable;
+ } else if (mRouteIsAvailable) {
+ // mIsPlayable is false here.
+ availability = WebRemotePlaybackAvailability.SourceNotCompatible;
+ }
+ nativeOnRouteAvailabilityChanged(mNativeRemoteMediaPlayerBridge, availability);
}
@CalledByNative
@@ -354,8 +365,8 @@
private native void nativeOnPaused(long nativeRemoteMediaPlayerBridge);
private native void nativeOnRouteUnselected(long nativeRemoteMediaPlayerBridge);
private native void nativeOnPlaybackFinished(long nativeRemoteMediaPlayerBridge);
- private native void nativeOnRouteAvailabilityChanged(long nativeRemoteMediaPlayerBridge,
- boolean available);
+ private native void nativeOnRouteAvailabilityChanged(
+ long nativeRemoteMediaPlayerBridge, int availability);
private native void nativeOnCancelledRemotePlaybackRequest(long nativeRemoteMediaPlayerBridge);
private native String nativeGetTitle(long nativeRemoteMediaPlayerBridge);
private native void nativePauseLocal(long nativeRemoteMediaPlayerBridge);
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index f7846c9..0eebd89 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -99,6 +99,7 @@
"+third_party/WebKit/public/platform/modules/budget_service/budget_service.mojom.h",
"+third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h",
"+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h",
+ "+third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h",
"+third_party/WebKit/public/platform/modules/permissions/permission_status.mojom.h",
"+third_party/WebKit/public/platform/modules/webshare/webshare.mojom.h",
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
index 8a11cf5..2979d24 100644
--- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc
+++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -18,6 +18,7 @@
#include "media/base/android/media_resource_getter.h"
#include "media/base/timestamp_constants.h"
#include "net/base/escape.h"
+#include "third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/android/java_bitmap.h"
@@ -252,9 +253,11 @@
void RemoteMediaPlayerBridge::OnRouteAvailabilityChanged(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
- jboolean available) {
+ int availability) {
static_cast<RemoteMediaPlayerManager *>(manager())->
- OnRouteAvailabilityChanged(player_id(), available);
+ OnRouteAvailabilityChanged(
+ player_id(),
+ static_cast<blink::WebRemotePlaybackAvailability>(availability));
}
// static
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.h b/chrome/browser/media/android/remote/remote_media_player_bridge.h
index 42425a5..5840e34 100644
--- a/chrome/browser/media/android/remote/remote_media_player_bridge.h
+++ b/chrome/browser/media/android/remote/remote_media_player_bridge.h
@@ -64,7 +64,7 @@
void OnRouteAvailabilityChanged(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
- jboolean available);
+ int availability);
base::android::ScopedJavaLocalRef<jstring> GetTitle(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/media/android/remote/remote_media_player_manager.cc b/chrome/browser/media/android/remote/remote_media_player_manager.cc
index e5dcc15dc..83d8a438 100644
--- a/chrome/browser/media/android/remote/remote_media_player_manager.cc
+++ b/chrome/browser/media/android/remote/remote_media_player_manager.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/android/tab_android.h"
#include "chrome/common/chrome_content_client.h"
#include "content/common/media/media_player_messages_android.h"
+#include "third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/android/java_bitmap.h"
@@ -217,10 +218,9 @@
}
void RemoteMediaPlayerManager::OnRouteAvailabilityChanged(
- int player_id, bool routes_available) {
- Send(
- new MediaPlayerMsg_RemoteRouteAvailabilityChanged(RoutingID(), player_id,
- routes_available));
+ int player_id, blink::WebRemotePlaybackAvailability availability) {
+ Send(new MediaPlayerMsg_RemoteRouteAvailabilityChanged(
+ RoutingID(), player_id, availability));
}
void RemoteMediaPlayerManager::OnCancelledRemotePlaybackRequest(int player_id) {
diff --git a/chrome/browser/media/android/remote/remote_media_player_manager.h b/chrome/browser/media/android/remote/remote_media_player_manager.h
index 0e1e6c7..d57e3d7 100644
--- a/chrome/browser/media/android/remote/remote_media_player_manager.h
+++ b/chrome/browser/media/android/remote/remote_media_player_manager.h
@@ -18,6 +18,10 @@
struct MediaPlayerHostMsg_Initialize_Params;
+namespace blink {
+enum class WebRemotePlaybackAvailability;
+}
+
namespace remote_media {
// media::MediaPlayerManager implementation that allows the user to play media
@@ -41,7 +45,8 @@
void OnRemotePlaybackFinished(int player_id);
// Callback to trigger when the availability of remote routes changes.
- void OnRouteAvailabilityChanged(int tab_id, bool routes_available);
+ void OnRouteAvailabilityChanged(
+ int player_id, blink::WebRemotePlaybackAvailability availability);
// Callback to trigger when the device picker dialog was dismissed.
void OnCancelledRemotePlaybackRequest(int player_id);
diff --git a/content/common/DEPS b/content/common/DEPS
index 1708c6d1..c00eeb5f 100644
--- a/content/common/DEPS
+++ b/content/common/DEPS
@@ -38,6 +38,7 @@
"+third_party/WebKit/public/platform/modules/permissions/WebPermissionType.h",
"+third_party/WebKit/public/platform/modules/push_messaging/WebPushError.h",
"+third_party/WebKit/public/platform/modules/push_messaging/WebPushPermissionStatus.h",
+ "+third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebLockOrientationError.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h",
"+third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationType.h",
diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h
index 9e02b9b..d7b93e6 100644
--- a/content/common/media/media_player_messages_android.h
+++ b/content/common/media/media_player_messages_android.h
@@ -10,6 +10,7 @@
#include "ipc/ipc_message_macros.h"
#include "media/blink/renderer_media_player_interface.h"
#include "media/gpu/ipc/common/media_param_traits.h"
+#include "third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
@@ -20,6 +21,9 @@
IPC_ENUM_TRAITS_MAX_VALUE(MediaPlayerHostMsg_Initialize_Type,
MEDIA_PLAYER_TYPE_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebRemotePlaybackAvailability,
+ blink::WebRemotePlaybackAvailability::Last)
+
// Parameters to describe a media player
IPC_STRUCT_BEGIN(MediaPlayerHostMsg_Initialize_Params)
IPC_STRUCT_MEMBER(MediaPlayerHostMsg_Initialize_Type, type)
@@ -131,7 +135,7 @@
// The availability of remote devices has changed
IPC_MESSAGE_ROUTED2(MediaPlayerMsg_RemoteRouteAvailabilityChanged,
int /* player_id */,
- bool /* routes_available */)
+ blink::WebRemotePlaybackAvailability /* availability */)
// Messages for controlling the media playback in browser process ----------
diff --git a/content/renderer/media/android/renderer_media_player_manager.cc b/content/renderer/media/android/renderer_media_player_manager.cc
index 27ebfd7..699fb428 100644
--- a/content/renderer/media/android/renderer_media_player_manager.cc
+++ b/content/renderer/media/android/renderer_media_player_manager.cc
@@ -10,10 +10,13 @@
#include "content/renderer/media/android/webmediaplayer_android.h"
#include "content/renderer/render_view_impl.h"
#include "media/base/media_switches.h"
+#include "third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "ui/gfx/geometry/rect_f.h"
namespace content {
+using ::blink::WebRemotePlaybackAvailability;
+
RendererMediaPlayerManager::RendererMediaPlayerManager(
RenderFrame* render_frame)
: RenderFrameObserver(render_frame),
@@ -244,10 +247,10 @@
void RendererMediaPlayerManager::OnRemoteRouteAvailabilityChanged(
int player_id,
- bool routes_available) {
+ blink::WebRemotePlaybackAvailability availability) {
media::RendererMediaPlayerInterface* player = GetMediaPlayer(player_id);
if (player)
- player->OnRemoteRouteAvailabilityChanged(routes_available);
+ player->OnRemoteRouteAvailabilityChanged(availability);
}
void RendererMediaPlayerManager::EnterFullscreen(int player_id) {
diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h
index f7007001cd..a2ea4fb 100644
--- a/content/renderer/media/android/renderer_media_player_manager.h
+++ b/content/renderer/media/android/renderer_media_player_manager.h
@@ -15,6 +15,10 @@
#include "media/blink/renderer_media_player_interface.h"
#include "url/gurl.h"
+namespace blink {
+enum class WebRemotePlaybackAvailability;
+}
+
namespace content {
class WebMediaPlayerAndroid;
@@ -114,7 +118,8 @@
void OnDidEnterFullscreen(int player_id);
void OnPlayerPlay(int player_id);
void OnPlayerPause(int player_id);
- void OnRemoteRouteAvailabilityChanged(int player_id, bool routes_available);
+ void OnRemoteRouteAvailabilityChanged(
+ int player_id, blink::WebRemotePlaybackAvailability availability);
// Info for all available WebMediaPlayerAndroid on a page; kept so that
// we can enumerate them to send updates about tab focus and visibility.
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 0a160a3..518a138d 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -918,8 +918,8 @@
}
void WebMediaPlayerAndroid::OnRemoteRouteAvailabilityChanged(
- bool routes_available) {
- client_->remoteRouteAvailabilityChanged(routes_available);
+ blink::WebRemotePlaybackAvailability availability) {
+ client_->remoteRouteAvailabilityChanged(availability);
}
void WebMediaPlayerAndroid::UpdateNetworkState(
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index e604b7d..8f73bbe 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -42,6 +42,7 @@
class WebMediaPlayerClient;
class WebMediaPlayerEncryptedMediaClient;
class WebURL;
+enum class WebRemotePlaybackAvailability;
}
namespace cc_blink {
@@ -202,7 +203,8 @@
void OnDidExitFullscreen() override;
void OnMediaPlayerPlay() override;
void OnMediaPlayerPause() override;
- void OnRemoteRouteAvailabilityChanged(bool routes_available) override;
+ void OnRemoteRouteAvailabilityChanged(
+ blink::WebRemotePlaybackAvailability availability) override;
// Called when the player is released.
void OnPlayerReleased() override;
diff --git a/content/renderer/media/webmediaplayer_ms_unittest.cc b/content/renderer/media/webmediaplayer_ms_unittest.cc
index f89a797..64f3c9f0 100644
--- a/content/renderer/media/webmediaplayer_ms_unittest.cc
+++ b/content/renderer/media/webmediaplayer_ms_unittest.cc
@@ -422,7 +422,8 @@
void removeTextTrack(blink::WebInbandTextTrack*) override {}
void mediaSourceOpened(blink::WebMediaSource*) override {}
void requestSeek(double) override {}
- void remoteRouteAvailabilityChanged(bool) override {}
+ void remoteRouteAvailabilityChanged(
+ blink::WebRemotePlaybackAvailability) override {}
void connectedToRemoteDevice() override {}
void disconnectedFromRemoteDevice() override {}
void cancelledRemotePlaybackRequest() override {}
diff --git a/media/blink/renderer_media_player_interface.h b/media/blink/renderer_media_player_interface.h
index d3af5fad..0f1bc34 100644
--- a/media/blink/renderer_media_player_interface.h
+++ b/media/blink/renderer_media_player_interface.h
@@ -17,6 +17,10 @@
#include "ui/gfx/geometry/rect_f.h"
#include "url/gurl.h"
+namespace blink {
+enum class WebRemotePlaybackAvailability;
+}
+
// Dictates which type of media playback is being initialized.
enum MediaPlayerHostMsg_Initialize_Type {
MEDIA_PLAYER_TYPE_URL,
@@ -54,7 +58,8 @@
virtual void OnDidExitFullscreen() = 0;
virtual void OnMediaPlayerPlay() = 0;
virtual void OnMediaPlayerPause() = 0;
- virtual void OnRemoteRouteAvailabilityChanged(bool routes_available) = 0;
+ virtual void OnRemoteRouteAvailabilityChanged(
+ blink::WebRemotePlaybackAvailability availability) = 0;
// Getters of playback state.
virtual bool paused() const = 0;
diff --git a/media/blink/webmediaplayer_cast_android.cc b/media/blink/webmediaplayer_cast_android.cc
index 22dcbb7..c9e66937 100644
--- a/media/blink/webmediaplayer_cast_android.cc
+++ b/media/blink/webmediaplayer_cast_android.cc
@@ -332,9 +332,9 @@
}
void WebMediaPlayerCast::OnRemoteRouteAvailabilityChanged(
- bool routes_available) {
+ blink::WebRemotePlaybackAvailability availability) {
DVLOG(1) << __FUNCTION__;
- client_->remoteRouteAvailabilityChanged(routes_available);
+ client_->remoteRouteAvailabilityChanged(availability);
}
void WebMediaPlayerCast::SuspendAndReleaseResources() {}
diff --git a/media/blink/webmediaplayer_cast_android.h b/media/blink/webmediaplayer_cast_android.h
index 69766bc..9fdcb6e0 100644
--- a/media/blink/webmediaplayer_cast_android.h
+++ b/media/blink/webmediaplayer_cast_android.h
@@ -80,7 +80,8 @@
void OnDidExitFullscreen() override;
void OnMediaPlayerPlay() override;
void OnMediaPlayerPause() override;
- void OnRemoteRouteAvailabilityChanged(bool routes_available) override;
+ void OnRemoteRouteAvailabilityChanged(
+ blink::WebRemotePlaybackAvailability availability) override;
// Getters of playback state.
// bool paused() const override;
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc
index cf50ffd..55cf6b0 100644
--- a/media/blink/webmediaplayer_impl_unittest.cc
+++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -82,7 +82,8 @@
void removeTextTrack(blink::WebInbandTextTrack*) override {}
void mediaSourceOpened(blink::WebMediaSource*) override {}
void requestSeek(double) override {}
- void remoteRouteAvailabilityChanged(bool) override {}
+ void remoteRouteAvailabilityChanged(
+ blink::WebRemotePlaybackAvailability) override {}
void connectedToRemoteDevice() override {}
void disconnectedFromRemoteDevice() override {}
void cancelledRemotePlaybackRequest() override {}
diff --git a/third_party/WebKit/LayoutTests/media/remoteplayback/prompt-twice-throws.html b/third_party/WebKit/LayoutTests/media/remoteplayback/prompt-twice-throws.html
index 9a14115..bacf9a0 100644
--- a/third_party/WebKit/LayoutTests/media/remoteplayback/prompt-twice-throws.html
+++ b/third_party/WebKit/LayoutTests/media/remoteplayback/prompt-twice-throws.html
@@ -23,6 +23,8 @@
v.src = findMediaFile('video', 'content/test');
document.body.appendChild(v);
+ internals.mediaPlayerRemoteRouteAvailabilityChanged(v, true);
+
var btn = document.getElementById('button');
btn.onclick = function() {
v.remote.prompt();
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index 1d90b0d..c812add 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -89,6 +89,7 @@
#include "public/platform/WebInbandTextTrack.h"
#include "public/platform/WebMediaPlayerSource.h"
#include "public/platform/WebMediaStream.h"
+#include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h"
#include "public/platform/modules/remoteplayback/WebRemotePlaybackState.h"
#include "wtf/CurrentTime.h"
@@ -444,7 +445,6 @@
m_shouldPerformAutomaticTrackSelection(true),
m_tracksAreReady(true),
m_processingPreferenceChange(false),
- m_remoteRoutesAvailable(false),
m_playingRemotely(false),
m_inOverlayFullscreenVideo(false),
m_audioTracks(this, AudioTrackList::create(*this)),
@@ -3168,12 +3168,17 @@
setCurrentTime(time);
}
-void HTMLMediaElement::remoteRouteAvailabilityChanged(bool routesAvailable) {
- m_remoteRoutesAvailable = routesAvailable;
+void HTMLMediaElement::remoteRouteAvailabilityChanged(
+ WebRemotePlaybackAvailability availability) {
+ if (remotePlaybackClient())
+ remotePlaybackClient()->availabilityChanged(availability);
if (mediaControls())
mediaControls()->refreshCastButtonVisibility();
- if (remotePlaybackClient())
- remotePlaybackClient()->availabilityChanged(routesAvailable);
+}
+
+bool HTMLMediaElement::hasRemoteRoutes() const {
+ return remotePlaybackClient() &&
+ remotePlaybackClient()->remotePlaybackAvailable();
}
void HTMLMediaElement::connectedToRemoteDevice() {
@@ -3403,10 +3408,8 @@
m_loadState = WaitingForSource;
// We can't cast if we don't have a media player.
- m_remoteRoutesAvailable = false;
m_playingRemotely = false;
- if (mediaControls())
- mediaControls()->refreshCastButtonVisibilityWithoutUpdate();
+ remoteRouteAvailabilityChanged(WebRemotePlaybackAvailability::Unknown);
if (layoutObject())
layoutObject()->setShouldDoFullPaintInvalidation();
@@ -3764,8 +3767,8 @@
}
// We haven't yet found out if any remote routes are available.
- m_remoteRoutesAvailable = false;
m_playingRemotely = false;
+ remoteRouteAvailabilityChanged(WebRemotePlaybackAvailability::Unknown);
if (m_audioSourceNode)
getAudioSourceProvider().setClient(m_audioSourceNode);
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 7e93de2..68c5c31 100644
--- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -117,7 +117,7 @@
};
void scheduleTextTrackResourceLoad();
- bool hasRemoteRoutes() const { return m_remoteRoutesAvailable; }
+ bool hasRemoteRoutes() const;
bool isPlayingRemotely() const { return m_playingRemotely; }
// error state
@@ -308,6 +308,9 @@
WebRemotePlaybackClient* remotePlaybackClient() {
return m_remotePlaybackClient;
}
+ const WebRemotePlaybackClient* remotePlaybackClient() const {
+ return m_remotePlaybackClient;
+ }
protected:
HTMLMediaElement(const QualifiedName&, Document&);
@@ -386,7 +389,7 @@
void removeTextTrack(WebInbandTextTrack*) final;
void mediaSourceOpened(WebMediaSource*) final;
void requestSeek(double) final;
- void remoteRouteAvailabilityChanged(bool) final;
+ void remoteRouteAvailabilityChanged(WebRemotePlaybackAvailability) final;
void connectedToRemoteDevice() final;
void disconnectedFromRemoteDevice() final;
void cancelledRemotePlaybackRequest() final;
@@ -641,7 +644,6 @@
bool m_tracksAreReady : 1;
bool m_processingPreferenceChange : 1;
- bool m_remoteRoutesAvailable : 1;
bool m_playingRemotely : 1;
// Whether this element is in overlay fullscreen mode.
bool m_inOverlayFullscreenVideo : 1;
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
index 303eb67f..cea984fc 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsTest.cpp
@@ -17,6 +17,7 @@
#include "platform/testing/UnitTestHelpers.h"
#include "public/platform/WebMediaPlayer.h"
#include "public/platform/WebSize.h"
+#include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <memory>
@@ -62,6 +63,23 @@
void paint(WebCanvas*, const WebRect&, SkPaint&) override{};
};
+class MockWebRemotePlaybackClient : public WebRemotePlaybackClient {
+ public:
+ void stateChanged(WebRemotePlaybackState) override {}
+ void availabilityChanged(
+ WebRemotePlaybackAvailability availability) override {
+ m_availability = availability;
+ }
+ void promptCancelled() override {}
+ bool remotePlaybackAvailable() const override {
+ return m_availability == WebRemotePlaybackAvailability::DeviceAvailable;
+ }
+
+ private:
+ WebRemotePlaybackAvailability m_availability =
+ WebRemotePlaybackAvailability::Unknown;
+};
+
class StubFrameLoaderClient : public EmptyFrameLoaderClient {
public:
static StubFrameLoaderClient* create() { return new StubFrameLoaderClient; }
@@ -72,6 +90,17 @@
WebMediaPlayerClient*) override {
return wrapUnique(new MockVideoWebMediaPlayer);
}
+
+ WebRemotePlaybackClient* createWebRemotePlaybackClient(
+ HTMLMediaElement&) override {
+ if (!m_remotePlaybackClient) {
+ m_remotePlaybackClient = wrapUnique(new MockWebRemotePlaybackClient);
+ }
+ return m_remotePlaybackClient.get();
+ }
+
+ private:
+ std::unique_ptr<MockWebRemotePlaybackClient> m_remotePlaybackClient;
};
Element* getElementByShadowPseudoId(Node& rootNode,
@@ -125,7 +154,8 @@
}
void simulateRouteAvailabe() {
- m_mediaControls->mediaElement().remoteRouteAvailabilityChanged(true);
+ m_mediaControls->mediaElement().remoteRouteAvailabilityChanged(
+ WebRemotePlaybackAvailability::DeviceAvailable);
}
void ensureLayout() {
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index 581c8bba..94c6379 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -144,6 +144,7 @@
#include "public/platform/WebConnectionType.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
#include "public/platform/WebLayer.h"
+#include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "wtf/InstanceCounter.h"
#include "wtf/PtrUtil.h"
#include "wtf/dtoa.h"
@@ -2194,7 +2195,9 @@
HTMLMediaElement* mediaElement,
bool available) {
ASSERT(mediaElement);
- mediaElement->remoteRouteAvailabilityChanged(available);
+ mediaElement->remoteRouteAvailabilityChanged(
+ available ? WebRemotePlaybackAvailability::DeviceAvailable
+ : WebRemotePlaybackAvailability::SourceNotSupported);
}
void Internals::mediaPlayerPlayingRemotelyChanged(
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
index 55de180..26e3ada76 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
+++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
@@ -49,7 +49,7 @@
m_state(element.isPlayingRemotely()
? WebRemotePlaybackState::Connected
: WebRemotePlaybackState::Disconnected),
- m_availability(element.hasRemoteRoutes()),
+ m_availability(WebRemotePlaybackAvailability::Unknown),
m_mediaElement(&element) {}
const AtomicString& RemotePlayback::interfaceName() const {
@@ -141,8 +141,6 @@
}
ScriptPromise RemotePlayback::prompt(ScriptState* scriptState) {
- // TODO(avayvod): implement steps 5, 8, 9 of the algorithm.
- // https://crbug.com/647441
ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
ScriptPromise promise = resolver->promise();
@@ -165,6 +163,22 @@
return promise;
}
+ // TODO(avayvod): don't do this check on low-end devices - merge with
+ // https://codereview.chromium.org/2475293003
+ if (m_availability == WebRemotePlaybackAvailability::DeviceNotAvailable) {
+ resolver->reject(DOMException::create(NotFoundError,
+ "No remote playback devices found."));
+ return promise;
+ }
+
+ if (m_availability == WebRemotePlaybackAvailability::SourceNotSupported ||
+ m_availability == WebRemotePlaybackAvailability::SourceNotCompatible) {
+ resolver->reject(DOMException::create(
+ NotSupportedError,
+ "The currentSrc is not compatible with remote playback"));
+ return promise;
+ }
+
if (m_state == WebRemotePlaybackState::Disconnected) {
m_promptPromiseResolver = resolver;
m_mediaElement->requestRemotePlayback();
@@ -191,7 +205,7 @@
if (iter == m_availabilityCallbacks.end())
return;
- iter->value->call(this, m_availability);
+ iter->value->call(this, remotePlaybackAvailable());
}
void RemotePlayback::stateChanged(WebRemotePlaybackState state) {
@@ -231,13 +245,19 @@
}
}
-void RemotePlayback::availabilityChanged(bool available) {
- if (m_availability == available)
+void RemotePlayback::availabilityChanged(
+ WebRemotePlaybackAvailability availability) {
+ if (m_availability == availability)
return;
- m_availability = available;
+ bool oldAvailability = remotePlaybackAvailable();
+ m_availability = availability;
+ bool newAvailability = remotePlaybackAvailable();
+ if (newAvailability == oldAvailability)
+ return;
+
for (auto& callback : m_availabilityCallbacks.values())
- callback->call(this, m_availability);
+ callback->call(this, newAvailability);
}
void RemotePlayback::promptCancelled() {
@@ -249,6 +269,10 @@
m_promptPromiseResolver = nullptr;
}
+bool RemotePlayback::remotePlaybackAvailable() const {
+ return m_availability == WebRemotePlaybackAvailability::DeviceAvailable;
+}
+
void RemotePlayback::remotePlaybackDisabled() {
if (m_promptPromiseResolver) {
m_promptPromiseResolver->reject(DOMException::create(
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
index f8b4371..0023126 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
+++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
@@ -11,6 +11,7 @@
#include "core/events/EventTarget.h"
#include "modules/ModulesExport.h"
#include "platform/heap/Handle.h"
+#include "public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h"
#include "public/platform/modules/remoteplayback/WebRemotePlaybackClient.h"
#include "public/platform/modules/remoteplayback/WebRemotePlaybackState.h"
#include "wtf/Compiler.h"
@@ -84,8 +85,9 @@
// WebRemotePlaybackClient implementation.
void stateChanged(WebRemotePlaybackState) override;
- void availabilityChanged(bool available) override;
+ void availabilityChanged(WebRemotePlaybackAvailability) override;
void promptCancelled() override;
+ bool remotePlaybackAvailable() const override;
// Prevent v8 from garbage collecting the availability callbacks.
// TODO(avayvod): remove when crbug.com/468240 is fixed and the references
@@ -94,7 +96,7 @@
const v8::Persistent<v8::Object>& wrapper);
WebRemotePlaybackState m_state;
- bool m_availability;
+ WebRemotePlaybackAvailability m_availability;
HeapHashMap<int, TraceWrapperMember<RemotePlaybackAvailabilityCallback>>
m_availabilityCallbacks;
Member<HTMLMediaElement> m_mediaElement;
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp
index 9f5d4f6..19a40a93 100644
--- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp
+++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp
@@ -55,10 +55,6 @@
void setState(RemotePlayback* remotePlayback, WebRemotePlaybackState state) {
remotePlayback->stateChanged(state);
}
-
- void setAvailability(RemotePlayback* remotePlayback, bool available) {
- remotePlayback->availabilityChanged(available);
- }
};
TEST_F(RemotePlaybackTest, PromptCancelledRejectsWithNotAllowedError) {
@@ -258,7 +254,6 @@
HTMLMediaElementRemotePlayback::setBooleanAttribute(
HTMLNames::disableremoteplaybackAttr, *element, true);
- setAvailability(remotePlayback, true);
// Runs pending promises.
v8::MicrotasksScope::PerformCheckpoint(scope.isolate());
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn
index 8276020..502fef7e 100644
--- a/third_party/WebKit/public/BUILD.gn
+++ b/third_party/WebKit/public/BUILD.gn
@@ -80,6 +80,7 @@
"./platform/WebDisplayMode.h",
"./platform/WebInputEvent.h",
"./platform/WebTextInputType.h",
+ "./platform/modules/remoteplayback/WebRemotePlaybackAvailability.h",
]
}
@@ -367,6 +368,7 @@
"platform/modules/push_messaging/WebPushProvider.h",
"platform/modules/push_messaging/WebPushSubscription.h",
"platform/modules/push_messaging/WebPushSubscriptionOptions.h",
+ "platform/modules/remoteplayback/WebRemotePlaybackAvailability.h",
"platform/modules/remoteplayback/WebRemotePlaybackClient.h",
"platform/modules/remoteplayback/WebRemotePlaybackState.h",
"platform/modules/screen_orientation/WebLockOrientationCallback.h",
diff --git a/third_party/WebKit/public/platform/WebMediaPlayerClient.h b/third_party/WebKit/public/platform/WebMediaPlayerClient.h
index 50e0588..f9e4dbd 100644
--- a/third_party/WebKit/public/platform/WebMediaPlayerClient.h
+++ b/third_party/WebKit/public/platform/WebMediaPlayerClient.h
@@ -40,6 +40,8 @@
class WebLayer;
class WebMediaSource;
+enum class WebRemotePlaybackAvailability;
+
class BLINK_PLATFORM_EXPORT WebMediaPlayerClient {
public:
enum VideoTrackKind {
@@ -86,7 +88,8 @@
virtual void removeTextTrack(WebInbandTextTrack*) = 0;
virtual void mediaSourceOpened(WebMediaSource*) = 0;
virtual void requestSeek(double) = 0;
- virtual void remoteRouteAvailabilityChanged(bool) = 0;
+ virtual void remoteRouteAvailabilityChanged(
+ WebRemotePlaybackAvailability) = 0;
virtual void connectedToRemoteDevice() = 0;
virtual void disconnectedFromRemoteDevice() = 0;
virtual void cancelledRemotePlaybackRequest() = 0;
diff --git a/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
new file mode 100644
index 0000000..1bc8f5f
--- /dev/null
+++ b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackAvailability.h
@@ -0,0 +1,38 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebRemotePlaybackAvailability_h
+#define WebRemotePlaybackAvailability_h
+
+namespace blink {
+
+// GENERATED_JAVA_ENUM_PACKAGE: (
+// org.chromium.blink_public.platform.modules.remoteplayback)
+// Various states for the remote playback availability.
+enum class WebRemotePlaybackAvailability {
+ // The availability is unknown.
+ Unknown,
+
+ // The media source is not supported by the browser - device availability
+ // monitoring is unnecessary.
+ SourceNotSupported,
+
+ // The media source is compatible with some supported device types but
+ // no devices were found.
+ DeviceNotAvailable,
+
+ // There're available devices but the current media source is not compatible
+ // with any of those.
+ SourceNotCompatible,
+
+ // There're available remote playback devices and the media source is
+ // compatible with at least one of them.
+ DeviceAvailable,
+
+ Last = DeviceAvailable
+};
+
+} // namespace blink
+
+#endif // WebRemotePlaybackState_h
diff --git a/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackClient.h b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackClient.h
index 6131d9eb2..7e66857 100644
--- a/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackClient.h
+++ b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackClient.h
@@ -7,6 +7,7 @@
namespace blink {
+enum class WebRemotePlaybackAvailability;
enum class WebRemotePlaybackState;
// The interface between the HTMLMediaElement and its
@@ -19,10 +20,13 @@
virtual void stateChanged(WebRemotePlaybackState) = 0;
// Notifies the client of the remote playback device availability change.
- virtual void availabilityChanged(bool availability) = 0;
+ virtual void availabilityChanged(WebRemotePlaybackAvailability) = 0;
// Notifies the client that the user cancelled the prompt shown via the API.
virtual void promptCancelled() = 0;
+
+ // Returns if the remote playback available for this media element.
+ virtual bool remotePlaybackAvailable() const = 0;
};
} // namespace blink