Commit 4b0784d1 authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Commit Bot

[Media Router] Support Cast-SDK-specific presentation IDs

Cast SDK uses some special strings (auto-join, cast-session) for presentation ID that may not correspond to that of existing routes.
This CL handles those cases and sends the requests to the extension MRP.

Bug: 786654
Change-Id: Ib32befe63936473edd71d16959e7a8caf8db81a9
Reviewed-on: https://chromium-review.googlesource.com/780584
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: default avatarDerek Cheng <imcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519818}
parent 42e15918
......@@ -4,6 +4,7 @@
#include "chrome/browser/media/router/mojo/media_router_desktop.h"
#include "base/strings/string_util.h"
#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service_proxy.h"
#include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h"
#include "chrome/browser/media/router/media_router_factory.h"
......@@ -59,6 +60,19 @@ void MediaRouterDesktop::OnUserGesture() {
#endif
}
base::Optional<mojom::MediaRouteProvider::Id>
MediaRouterDesktop::GetProviderIdForPresentation(
const std::string& presentation_id) {
// TODO(takumif): Once the Android Media Router also uses MediaRouterMojoImpl,
// we must support these presentation IDs in Android as well.
if (presentation_id == kAutoJoinPresentationId ||
base::StartsWith(presentation_id, kCastPresentationIdPrefix,
base::CompareCase::SENSITIVE)) {
return mojom::MediaRouteProvider::Id::EXTENSION;
}
return MediaRouterMojoImpl::GetProviderIdForPresentation(presentation_id);
}
MediaRouterDesktop::MediaRouterDesktop(content::BrowserContext* context,
FirewallCheck check_firewall)
: MediaRouterMojoImpl(context),
......
......@@ -46,6 +46,11 @@ class MediaRouterDesktop : public MediaRouterMojoImpl {
// MediaRouter implementation.
void OnUserGesture() override;
protected:
// MediaRouterMojoImpl override:
base::Optional<mojom::MediaRouteProvider::Id> GetProviderIdForPresentation(
const std::string& presentation_id) override;
private:
friend class MediaRouterDesktopTest;
friend class MediaRouterDesktopTestTest;
......
......@@ -146,4 +146,11 @@ TEST_F(MediaRouterDesktopTest, TestProvideSinks) {
base::RunLoop().RunUntilIdle();
}
// Tests that auto-join and Cast SDK join requests are routed to the extension
// MediaRouteProvider.
TEST_F(MediaRouterDesktopTest, SendCastJoinRequestsToExtension) {
TestJoinRoute(kAutoJoinPresentationId);
TestJoinRoute(kCastPresentationIdPrefix + std::string("123"));
}
} // namespace media_router
......@@ -121,6 +121,11 @@ class MediaRouterMojoImpl : public MediaRouterBase,
// Creates a binding between |this| and |request|.
void BindToMojoRequest(mojo::InterfaceRequest<mojom::MediaRouter> request);
// Returns the ID of the provider associated with the presentation ID, or
// nullopt if not found.
virtual base::Optional<mojom::MediaRouteProvider::Id>
GetProviderIdForPresentation(const std::string& presentation_id);
content::BrowserContext* context() const { return context_; }
// Mojo pointers to media route providers. Providers are added via
......@@ -386,16 +391,12 @@ class MediaRouterMojoImpl : public MediaRouterBase,
// routes do not appear in |routes|.
void RemoveInvalidRouteControllers(const std::vector<MediaRoute>& routes);
// Methods for obtaining a pointer to the provider associated with the given
// object. They return a nullptr when such a provider is not found. The
// returned pointer should not be stored or passed to another object, as the
// Mojo connection may be terminated at any later time.
// Methods for obtaining the ID of the provider associated with the given
// object. They return a nullopt when such a provider is not found.
base::Optional<mojom::MediaRouteProvider::Id> GetProviderIdForRoute(
const MediaRoute::Id& route_id);
base::Optional<mojom::MediaRouteProvider::Id> GetProviderIdForSink(
const MediaSink::Id& sink_id);
base::Optional<mojom::MediaRouteProvider::Id> GetProviderIdForPresentation(
const std::string& presentation_id);
base::flat_map<MediaSource::Id, std::unique_ptr<MediaSinksQuery>>
sinks_queries_;
......
......@@ -325,7 +325,7 @@ TEST_F(MediaRouterMojoImplTest, IncognitoRoutesTerminatedOnProfileShutdown) {
}
TEST_F(MediaRouterMojoImplTest, JoinRoute) {
TestJoinRoute();
TestJoinRoute(kPresentationId);
ExpectResultBucketCount("JoinRoute", RouteRequestResult::OK, 1);
}
......
......@@ -258,7 +258,7 @@ void MediaRouterMojoTest::TestCreateRoute() {
base::RunLoop().RunUntilIdle();
}
void MediaRouterMojoTest::TestJoinRoute() {
void MediaRouterMojoTest::TestJoinRoute(const std::string& presentation_id) {
MediaSource media_source(kSource);
MediaRoute expected_route(kRouteId, media_source, kSinkId, "", false, "",
false);
......@@ -277,7 +277,7 @@ void MediaRouterMojoTest::TestJoinRoute() {
// in runnable parameter lists.
EXPECT_CALL(mock_extension_provider_,
JoinRouteInternal(
kSource, kPresentationId, url::Origin::Create(GURL(kOrigin)),
kSource, presentation_id, url::Origin::Create(GURL(kOrigin)),
kInvalidTabId,
base::TimeDelta::FromMilliseconds(kTimeoutMillis), _, _))
.WillOnce(
......@@ -295,7 +295,7 @@ void MediaRouterMojoTest::TestJoinRoute() {
std::vector<MediaRouteResponseCallback> route_response_callbacks;
route_response_callbacks.push_back(base::BindOnce(
&RouteResponseCallbackHandler::Invoke, base::Unretained(&handler)));
router()->JoinRoute(kSource, kPresentationId,
router()->JoinRoute(kSource, presentation_id,
url::Origin::Create(GURL(kOrigin)), nullptr,
std::move(route_response_callbacks),
base::TimeDelta::FromMilliseconds(kTimeoutMillis), false);
......
......@@ -296,7 +296,7 @@ class MediaRouterMojoTest : public ::testing::Test {
// Tests that calling MediaRouter methods result in calls to corresponding
// MediaRouteProvider methods.
void TestCreateRoute();
void TestJoinRoute();
void TestJoinRoute(const std::string& presentation_id);
void TestConnectRouteByRouteId();
void TestTerminateRoute();
void TestSendRouteMessage();
......
......@@ -28,10 +28,6 @@ constexpr char kTabRemotingUrnFormat[] =
constexpr char kCastPresentationUrlDomain[] = "google.com";
constexpr char kCastPresentationUrlPath[] = "/cast";
// This value must be the same as |chrome.cast.AUTO_JOIN_PRESENTATION_ID| in the
// component extension.
constexpr char kAutoJoinPresentationId[] = "auto-join";
// List of non-http(s) schemes that are allowed in a Presentation URL.
constexpr std::array<const char* const, 5> kAllowedSchemes{
{kCastPresentationUrlScheme, kCastDialPresentationUrlScheme,
......
......@@ -24,6 +24,17 @@ constexpr char kRemotePlaybackPresentationUrlScheme[] = "remote-playback";
constexpr char kLegacyCastPresentationUrlPrefix[] =
"https://google.com/cast#__castAppId__=";
// Strings used in presentation IDs by the Cast SDK implementation.
// TODO(takumif): Move them out of media_source_helper, since they are not
// directly related to MediaSource.
//
// This value must be the same as |chrome.cast.AUTO_JOIN_PRESENTATION_ID| in the
// component extension.
constexpr char kAutoJoinPresentationId[] = "auto-join";
// This value must be the same as |chrome.cast.PRESENTATION_ID_PREFIX| in the
// component extension.
constexpr char kCastPresentationIdPrefix[] = "cast-session_";
// Helper library for protocol-specific media source object creation.
// Returns MediaSource URI depending on the type of source.
MediaSource MediaSourceForTab(int tab_id);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment