Commit 949135e0 authored by Thomas Guilbert's avatar Thomas Guilbert Committed by Commit Bot

Extract MediaSource interface

Currently, MediaSource and RemotingMediaSource have no common ancestor.
This makes code reuse between CastMediaRouteProvider and
RemotingMediaRouteProvider difficult.

This CL renames MediaSource into CastMediaSource, adds a MediaSource
interface, and updates RemotingMediaSource and CastMediaSources to both
derive from this interface. This paves the way for the introduction of
a BaseMediaRouteProvider.

Bug: 790766
Change-Id: I3f8e46816a1e9f8f2f617a43b1099c8614204efc
Reviewed-on: https://chromium-review.googlesource.com/783836
Commit-Queue: Thomas Guilbert <tguilbert@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarAnton Vayvod <avayvod@chromium.org>
Reviewed-by: default avatarZhiqiang Zhang <zqzhang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521578}
parent fb4046a4
......@@ -10,6 +10,7 @@ import android.support.v7.media.MediaRouteSelector;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.browser.media.router.cast.CastMediaSource;
import org.chromium.chrome.browser.media.router.cast.MediaSink;
import org.chromium.chrome.browser.media.router.cast.MediaSource;
import org.chromium.chrome.browser.media.router.cast.remoting.RemotingMediaSource;
......@@ -45,30 +46,23 @@ public class ChromeMediaRouterDialogController implements MediaRouteDialogDelega
public void openRouteChooserDialog(String[] sourceUrns) {
if (isShowingDialog()) return;
String sourceId = null;
MediaRouteSelector routeSelector = null;
MediaSource source = null;
for (String sourceUrn : sourceUrns) {
MediaSource source = MediaSource.from(sourceUrn);
if (source != null) {
sourceId = source.getUrn();
routeSelector = source.buildRouteSelector();
break;
}
RemotingMediaSource remotingSource = RemotingMediaSource.from(sourceUrn);
if (remotingSource != null) {
sourceId = remotingSource.getSourceId();
routeSelector = remotingSource.buildRouteSelector();
break;
}
source = CastMediaSource.from(sourceUrn);
if (source == null) source = RemotingMediaSource.from(sourceUrn);
if (source != null) break;
}
if (sourceId == null || routeSelector == null) {
MediaRouteSelector routeSelector = source == null ? null : source.buildRouteSelector();
if (routeSelector == null) {
nativeOnMediaSourceNotSupported(mNativeDialogController);
return;
}
mDialogManager = new MediaRouteChooserDialogManager(sourceId, routeSelector, this);
mDialogManager =
new MediaRouteChooserDialogManager(source.getSourceId(), routeSelector, this);
mDialogManager.openDialog();
}
......@@ -81,28 +75,18 @@ public class ChromeMediaRouterDialogController implements MediaRouteDialogDelega
public void openRouteControllerDialog(String sourceUrn, String mediaRouteId) {
if (isShowingDialog()) return;
String sourceId = null;
MediaRouteSelector routeSelector = null;
MediaSource source = MediaSource.from(sourceUrn);
if (source != null) {
sourceId = source.getUrn();
routeSelector = source.buildRouteSelector();
} else {
RemotingMediaSource remotingSource = RemotingMediaSource.from(sourceUrn);
if (remotingSource != null) {
sourceId = remotingSource.getSourceId();
routeSelector = remotingSource.buildRouteSelector();
}
}
MediaSource source = CastMediaSource.from(sourceUrn);
if (source == null) source = RemotingMediaSource.from(sourceUrn);
MediaRouteSelector routeSelector = source == null ? null : source.buildRouteSelector();
if (sourceId == null || routeSelector == null) {
if (routeSelector == null) {
nativeOnMediaSourceNotSupported(mNativeDialogController);
return;
}
mDialogManager =
new MediaRouteControllerDialogManager(sourceId, routeSelector, mediaRouteId, this);
mDialogManager = new MediaRouteControllerDialogManager(
source.getSourceId(), routeSelector, mediaRouteId, this);
mDialogManager.openDialog();
}
......
......@@ -166,7 +166,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
@Override
public boolean supportsSource(String sourceId) {
return MediaSource.from(sourceId) != null;
return CastMediaSource.from(sourceId) != null;
}
@Override
......@@ -178,7 +178,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
return;
}
MediaSource source = MediaSource.from(sourceId);
MediaSource source = CastMediaSource.from(sourceId);
if (source == null) {
// If the source is invalid, report no devices available.
onSinksReceived(sourceId, new ArrayList<MediaSink>());
......@@ -218,7 +218,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
public void stopObservingMediaSinks(String sourceId) {
if (mAndroidMediaRouter == null) return;
MediaSource source = MediaSource.from(sourceId);
MediaSource source = CastMediaSource.from(sourceId);
if (source == null) return;
String applicationId = source.getApplicationId();
......@@ -247,7 +247,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
return;
}
MediaSource source = MediaSource.from(sourceId);
MediaSource source = CastMediaSource.from(sourceId);
if (source == null) {
mManager.onRouteRequestError("Unsupported presentation URL", nativeRequestId);
return;
......@@ -270,15 +270,17 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
MediaSink sink = request.getSink();
MediaSource source = request.getSource();
MediaRoute route = new MediaRoute(
sink.getId(), source.getUrn(), request.getPresentationId());
MediaRoute route =
new MediaRoute(sink.getId(), source.getSourceId(), request.getPresentationId());
addRoute(route, request.getOrigin(), request.getTabId());
mManager.onRouteCreated(route.id, route.sinkId, request.getNativeRequestId(), this, true);
if (source.getClientId() != null) {
ClientRecord clientRecord = mClientRecords.get(source.getClientId());
String clientId = ((CastMediaSource) source).getClientId();
if (clientId != null) {
ClientRecord clientRecord = mClientRecords.get(clientId);
if (clientRecord != null) {
sendReceiverAction(clientRecord.routeId, sink, source.getClientId(), "cast");
sendReceiverAction(clientRecord.routeId, sink, clientId, "cast");
}
}
request.start();
......@@ -287,7 +289,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
@Override
public void joinRoute(String sourceId, String presentationId, String origin, int tabId,
int nativeRequestId) {
MediaSource source = MediaSource.from(sourceId);
CastMediaSource source = CastMediaSource.from(sourceId);
if (source == null || source.getClientId() == null) {
mManager.onRouteRequestError("Unsupported presentation URL", nativeRequestId);
return;
......@@ -420,10 +422,10 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
// Send a "disconnect_session" message to all the clients that match with the leaving
// client's auto join policy.
for (ClientRecord client : mClientRecords.values()) {
if ((MediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED.equals(leavingClient.autoJoinPolicy)
if ((CastMediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED.equals(leavingClient.autoJoinPolicy)
&& isSameOrigin(client.origin, leavingClient.origin)
&& client.tabId == leavingClient.tabId)
|| (MediaSource.AUTOJOIN_ORIGIN_SCOPED.equals(leavingClient.autoJoinPolicy)
|| (CastMediaSource.AUTOJOIN_ORIGIN_SCOPED.equals(leavingClient.autoJoinPolicy)
&& isSameOrigin(client.origin, leavingClient.origin))) {
onMessage(client.clientId,
buildInternalMessage("disconnect_session", -1, client.clientId, sessionId));
......@@ -451,10 +453,10 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
mMessageHandler = new CastMessageHandler(this);
}
private boolean canAutoJoin(MediaSource source, String origin, int tabId) {
if (source.getAutoJoinPolicy().equals(MediaSource.AUTOJOIN_PAGE_SCOPED)) return false;
private boolean canAutoJoin(CastMediaSource source, String origin, int tabId) {
if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_PAGE_SCOPED)) return false;
MediaSource currentSource = MediaSource.from(mSession.getSourceId());
CastMediaSource currentSource = CastMediaSource.from(mSession.getSourceId());
if (!currentSource.getApplicationId().equals(source.getApplicationId())) return false;
ClientRecord client = null;
......@@ -467,17 +469,18 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
if (client == null) return false;
boolean sameOrigin = isSameOrigin(origin, client.origin);
if (source.getAutoJoinPolicy().equals(MediaSource.AUTOJOIN_ORIGIN_SCOPED)) {
if (source.getAutoJoinPolicy().equals(CastMediaSource.AUTOJOIN_ORIGIN_SCOPED)) {
return sameOrigin;
} else if (source.getAutoJoinPolicy().equals(MediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED)) {
} else if (source.getAutoJoinPolicy().equals(
CastMediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED)) {
return sameOrigin && tabId == client.tabId;
}
return false;
}
private boolean canJoinExistingSession(String presentationId, String origin, int tabId,
MediaSource source) {
private boolean canJoinExistingSession(
String presentationId, String origin, int tabId, CastMediaSource source) {
if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) {
return canAutoJoin(source, origin, tabId);
} else if (presentationId.startsWith(PRESENTATION_ID_SESSION_ID_PREFIX)) {
......@@ -503,7 +506,7 @@ public class CastMediaRouteProvider implements MediaRouteProvider, DiscoveryDele
void addRoute(MediaRoute route, String origin, int tabId) {
mRoutes.put(route.id, route);
MediaSource source = MediaSource.from(route.sourceId);
CastMediaSource source = CastMediaSource.from(route.sourceId);
final String clientId = source.getClientId();
if (clientId == null || mClientRecords.get(clientId) != null) return;
......
......@@ -268,7 +268,7 @@ public class CastSessionImpl implements MediaNotificationListener, CastSession {
@Override
public String getSourceId() {
return mSource.getUrn();
return mSource.getSourceId();
}
@Override
......
......@@ -9,6 +9,7 @@ import android.util.Base64;
import com.google.android.gms.cast.CastMediaControlIntent;
import org.chromium.base.Log;
import org.chromium.chrome.browser.media.router.cast.MediaSource;
import java.io.UnsupportedEncodingException;
......@@ -17,7 +18,7 @@ import javax.annotation.Nullable;
/**
* Abstracts parsing the Cast application id and other parameters from the source id.
*/
public class RemotingMediaSource {
public class RemotingMediaSource implements MediaSource {
private static final String TAG = "MediaRemoting";
// Need to be in sync with third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp.
......@@ -71,6 +72,7 @@ public class RemotingMediaSource {
*
* @return an initialized route selector or null.
*/
@Override
public MediaRouteSelector buildRouteSelector() {
return new MediaRouteSelector.Builder()
.addControlCategory(CastMediaControlIntent.categoryForCast(mApplicationId))
......@@ -80,6 +82,7 @@ public class RemotingMediaSource {
/**
* @return the Cast application id corresponding to the source. Can be overridden downstream.
*/
@Override
public String getApplicationId() {
return mApplicationId;
}
......@@ -87,6 +90,7 @@ public class RemotingMediaSource {
/**
* @return the id identifying the media source
*/
@Override
public String getSourceId() {
return mSourceId;
}
......@@ -103,4 +107,4 @@ public class RemotingMediaSource {
mApplicationId = applicationId;
mMediaUrl = mediaUrl;
}
}
\ No newline at end of file
}
......@@ -594,6 +594,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/media/router/MediaRouteManager.java",
"java/src/org/chromium/chrome/browser/media/router/MediaRouteProvider.java",
"java/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProvider.java",
"java/src/org/chromium/chrome/browser/media/router/cast/CastMediaSource.java",
"java/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandler.java",
"java/src/org/chromium/chrome/browser/media/router/cast/CastRequestIdGenerator.java",
"java/src/org/chromium/chrome/browser/media/router/cast/CastSession.java",
......@@ -1893,10 +1894,10 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterSinkObservationTest.java",
"junit/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterTestBase.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/CastMediaRouteProviderTest.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/CastMediaSourceTest.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/CastMessageHandlerTest.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/DiscoveryCallbackTest.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/JSONTestUtils.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/MediaSourceTest.java",
"junit/src/org/chromium/chrome/browser/media/router/cast/TestUtils.java",
"junit/src/org/chromium/chrome/browser/media/ui/MediaImageManagerTest.java",
"junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java",
......
......@@ -34,7 +34,7 @@ public class CastMediaRouteProviderTest {
private static final String SUPPORTED_SOURCE = "cast:DEADBEEF";
private static final String SUPPORTED_AUTOJOIN_SOURCE = "cast:DEADBEEF"
+ "?clientId=12345&autoJoinPolicy=" + MediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED;
+ "?clientId=12345&autoJoinPolicy=" + CastMediaSource.AUTOJOIN_TAB_AND_ORIGIN_SCOPED;
// TODO(crbug.com/672704): Android does not currently support 1-UA mode.
private static final String UNSUPPORTED_SOURCE = "https://example.com";
......
......@@ -16,22 +16,20 @@ import org.chromium.base.test.util.Feature;
import org.chromium.testing.local.LocalRobolectricTestRunner;
/**
* Robolectric tests for {@link MediaSource} class.
* Robolectric tests for {@link CastMediaSource} class.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class MediaSourceTest {
public class CastMediaSourceTest {
@Test
@Feature({"MediaRouter"})
public void testCorrectSourceId() {
final String sourceId =
"https://example.com/path?query"
final String sourceId = "https://example.com/path?query"
+ "#__castAppId__=ABCD1234(video_out,audio_out)"
+ "/__castClientId__=1234567890"
+ "/__castAutoJoinPolicy__=tab_and_origin_scoped";
MediaSource source = MediaSource.from(sourceId);
CastMediaSource source = CastMediaSource.from(sourceId);
assertNotNull(source);
assertEquals("ABCD1234", source.getApplicationId());
......@@ -43,38 +41,39 @@ public class MediaSourceTest {
assertEquals("1234567890", source.getClientId());
assertEquals("tab_and_origin_scoped", source.getAutoJoinPolicy());
assertEquals(sourceId, source.getUrn());
assertEquals(sourceId, source.getSourceId());
}
@Test
@Feature({"MediaRouter"})
public void testNoFragment() {
assertNull(MediaSource.from("https://example.com/path?query"));
assertNull(CastMediaSource.from("https://example.com/path?query"));
}
@Test
@Feature({"MediaRouter"})
public void testEmptyFragment() {
assertNull(MediaSource.from("https://example.com/path?query#"));
assertNull(CastMediaSource.from("https://example.com/path?query#"));
}
@Test
@Feature({"MediaRouter"})
public void testNoAppId() {
assertNull(MediaSource.from("https://example.com/path?query#fragment"));
assertNull(CastMediaSource.from("https://example.com/path?query#fragment"));
}
@Test
@Feature({"MediaRouter"})
public void testNoValidAppId() {
// Invalid app id needs to indicate no availability so {@link MediaSource} needs to be
// Invalid app id needs to indicate no availability so {@link CastMediaSource} needs to be
// created.
MediaSource empty = MediaSource.from("https://example.com/path?query#__castAppId__=");
CastMediaSource empty =
CastMediaSource.from("https://example.com/path?query#__castAppId__=");
assertNotNull(empty);
assertEquals("", empty.getApplicationId());
MediaSource invalid = MediaSource.from(
"https://example.com/path?query#__castAppId__=INVALID-APP-ID");
CastMediaSource invalid =
CastMediaSource.from("https://example.com/path?query#__castAppId__=INVALID-APP-ID");
assertNotNull(invalid);
assertEquals("INVALID-APP-ID", invalid.getApplicationId());
}
......@@ -82,33 +81,35 @@ public class MediaSourceTest {
@Test
@Feature({"MediaRouter"})
public void testNoCapabilitiesSuffix() {
assertNull(MediaSource.from("https://example.com/path?query#__castAppId__=A("));
assertNull(CastMediaSource.from("https://example.com/path?query#__castAppId__=A("));
}
@Test
@Feature({"MediaRouter"})
public void testCapabilitiesEmpty() {
assertNull(MediaSource.from("https://example.com/path?query#__castAppId__=A()"));
assertNull(CastMediaSource.from("https://example.com/path?query#__castAppId__=A()"));
}
@Test
@Feature({"MediaRouter"})
public void testInvalidCapability() {
assertNull(MediaSource.from("https://example.com/path?query#__castAppId__=A(a)"));
assertNull(MediaSource.from("https://example.com/path?query#__castAppId__=A(video_in,b)"));
assertNull(CastMediaSource.from("https://example.com/path?query#__castAppId__=A(a)"));
assertNull(
CastMediaSource.from("https://example.com/path?query#__castAppId__=A(video_in,b)"));
}
@Test
@Feature({"MediaRouter"})
public void testInvalidAutoJoinPolicy() {
assertNull(MediaSource.from("https://example.com/path?query#__castAppId__=A"
assertNull(CastMediaSource.from("https://example.com/path?query#__castAppId__=A"
+ "/__castAutoJoinPolicy__=invalidPolicy"));
}
@Test
@Feature({"MediaRouter"})
public void testOptionalParameters() {
MediaSource source = MediaSource.from("https://example.com/path?query#__castAppId__=A");
CastMediaSource source =
CastMediaSource.from("https://example.com/path?query#__castAppId__=A");
assertNotNull(source);
assertEquals("A", source.getApplicationId());
......@@ -120,7 +121,7 @@ public class MediaSourceTest {
@Test
@Feature({"MediaRouter"})
public void testBasicCastPresentationUrl() {
MediaSource source = MediaSource.from("cast:ABCD1234");
CastMediaSource source = CastMediaSource.from("cast:ABCD1234");
assertNotNull(source);
assertEquals("ABCD1234", source.getApplicationId());
assertNull(source.getCapabilities());
......@@ -131,7 +132,7 @@ public class MediaSourceTest {
@Test
@Feature({"MediaRouter"})
public void testCastPresentationUrlWithParameters() {
MediaSource source = MediaSource.from("cast:ABCD1234?clientId=1234"
CastMediaSource source = CastMediaSource.from("cast:ABCD1234?clientId=1234"
+ "&capabilities=video_out,audio_out"
+ "&autoJoinPolicy=tab_and_origin_scoped");
assertNotNull(source);
......@@ -147,14 +148,14 @@ public class MediaSourceTest {
@Test
@Feature({"MediaRouter"})
public void testCastPresentationUrlInvalidCapability() {
assertNull(MediaSource.from("cast:ABCD1234?clientId=1234"
assertNull(CastMediaSource.from("cast:ABCD1234?clientId=1234"
+ "&capabilities=invalidCapability"));
}
@Test
@Feature({"MediaRouter"})
public void testCastPresentationUrlInvalidAutoJoinPolicy() {
assertNull(MediaSource.from("cast:ABCD1234?clientId=1234"
assertNull(CastMediaSource.from("cast:ABCD1234?clientId=1234"
+ "&autoJoinPolicy=invalidPolicy"));
}
}
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