Commit 8979a892 authored by Zhiqiang Zhang's avatar Zhiqiang Zhang Committed by Commit Bot

Unit test for CafMediaRouteProvider

This CL adds unit test for CafMediaRouteProvider. Also to clean
up, the provider reads the sink directly from the session
controller when onSessionStarted().

Bug: 711860
Change-Id: I9c4001bc4d6a59f764b71bf90f9fd96761454963
Reviewed-on: https://chromium-review.googlesource.com/c/1339461
Commit-Queue: Zhiqiang Zhang <zqzhang@chromium.org>
Reviewed-by: default avatarThomas Guilbert <tguilbert@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609625}
parent 645a4900
...@@ -205,4 +205,12 @@ public class BaseSessionController { ...@@ -205,4 +205,12 @@ public class BaseSessionController {
public FlingingController getFlingingController() { public FlingingController getFlingingController() {
return null; return null;
} }
/**
* Helper message to get the session ID of the attached session. For stubbing in tests as
* {@link CastSession#getSessionId()} is final.
*/
public String getSessionId() {
return isConnected() ? getSession().getSessionId() : null;
}
} }
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.media.router.caf; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.media.router.caf;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.media.MediaRouteSelector; import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter;
import android.support.v7.media.MediaRouter.RouteInfo; import android.support.v7.media.MediaRouter.RouteInfo;
...@@ -43,7 +44,8 @@ public abstract class CafBaseMediaRouteProvider ...@@ -43,7 +44,8 @@ public abstract class CafBaseMediaRouteProvider
protected final MediaRouteManager mManager; protected final MediaRouteManager mManager;
protected final Map<String, DiscoveryCallback> mDiscoveryCallbacks = protected final Map<String, DiscoveryCallback> mDiscoveryCallbacks =
new HashMap<String, DiscoveryCallback>(); new HashMap<String, DiscoveryCallback>();
protected final Map<String, MediaRoute> mRoutes = new HashMap<String, MediaRoute>(); @VisibleForTesting
final Map<String, MediaRoute> mRoutes = new HashMap<String, MediaRoute>();
protected Handler mHandler = new Handler(); protected Handler mHandler = new Handler();
private CreateRouteRequestInfo mPendingCreateRouteRequestInfo; private CreateRouteRequestInfo mPendingCreateRouteRequestInfo;
...@@ -199,6 +201,8 @@ public abstract class CafBaseMediaRouteProvider ...@@ -199,6 +201,8 @@ public abstract class CafBaseMediaRouteProvider
return; return;
} }
// Don't remove the route while the session is still active. All the routes will be removed
// upon session end.
sessionController().endSession(); sessionController().endSession();
} }
......
...@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.media.router.caf.CastUtils.isSameOrigi ...@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.media.router.caf.CastUtils.isSameOrigi
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.media.MediaRouter; import android.support.v7.media.MediaRouter;
import com.google.android.gms.cast.framework.CastSession; import com.google.android.gms.cast.framework.CastSession;
...@@ -36,12 +37,14 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider { ...@@ -36,12 +37,14 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider {
private CreateRouteRequestInfo mPendingCreateRouteRequestInfo; private CreateRouteRequestInfo mPendingCreateRouteRequestInfo;
private ClientRecord mLastRemovedRouteRecord; @VisibleForTesting
ClientRecord mLastRemovedRouteRecord;
// The records for clients, which must match mRoutes. This is used for the saving last record // The records for clients, which must match mRoutes. This is used for the saving last record
// for autojoin. // for autojoin.
private final Map<String, ClientRecord> mClientIdToRecords = private final Map<String, ClientRecord> mClientIdToRecords =
new HashMap<String, ClientRecord>(); new HashMap<String, ClientRecord>();
private CafMessageHandler mMessageHandler; @VisibleForTesting
CafMessageHandler mMessageHandler;
// The session controller which is always attached to the current CastSession. // The session controller which is always attached to the current CastSession.
private final CastSessionController mSessionController; private final CastSessionController mSessionController;
...@@ -75,7 +78,6 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider { ...@@ -75,7 +78,6 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider {
MediaRoute route = MediaRoute route =
new MediaRoute(sessionController().getSink().getId(), sourceId, presentationId); new MediaRoute(sessionController().getSink().getId(), sourceId, presentationId);
addRoute(route, origin, tabId, nativeRequestId, /* wasLaunched= */ false); addRoute(route, origin, tabId, nativeRequestId, /* wasLaunched= */ false);
mManager.onRouteCreated(route.id, route.sinkId, nativeRequestId, this, false);
} }
// TODO(zqzhang): the clientRecord/route management is not clean and the logic seems to be // TODO(zqzhang): the clientRecord/route management is not clean and the logic seems to be
...@@ -90,8 +92,7 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider { ...@@ -90,8 +92,7 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider {
ClientRecord client = getClientRecordByRouteId(routeId); ClientRecord client = getClientRecordByRouteId(routeId);
if (client != null) { if (client != null) {
MediaSink sink = MediaSink.fromSinkId( MediaSink sink = sessionController().getSink();
sessionController().getSink().getId(), getAndroidMediaRouter());
if (sink != null) { if (sink != null) {
mMessageHandler.sendReceiverActionToClient(routeId, sink, client.clientId, "stop"); mMessageHandler.sendReceiverActionToClient(routeId, sink, client.clientId, "stop");
} }
...@@ -153,10 +154,8 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider { ...@@ -153,10 +154,8 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider {
for (ClientRecord clientRecord : mClientIdToRecords.values()) { for (ClientRecord clientRecord : mClientIdToRecords.values()) {
// Should be exactly one instance of MediaRoute/ClientRecord at this moment. // Should be exactly one instance of MediaRoute/ClientRecord at this moment.
MediaRoute route = mRoutes.get(clientRecord.routeId); mMessageHandler.sendReceiverActionToClient(clientRecord.routeId,
MediaSink sink = MediaSink.fromSinkId(route.sinkId, getAndroidMediaRouter()); sessionController().getSink(), clientRecord.clientId, "cast");
mMessageHandler.sendReceiverActionToClient(
clientRecord.routeId, sink, clientRecord.clientId, "cast");
} }
mMessageHandler.onSessionStarted(); mMessageHandler.onSessionStarted();
...@@ -200,14 +199,15 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider { ...@@ -200,14 +199,15 @@ public class CafMediaRouteProvider extends CafBaseMediaRouteProvider {
mMessageHandler = new CafMessageHandler(this, mSessionController); mMessageHandler = new CafMessageHandler(this, mSessionController);
} }
private boolean canJoinExistingSession( @VisibleForTesting
boolean canJoinExistingSession(
String presentationId, String origin, int tabId, CastMediaSource source) { String presentationId, String origin, int tabId, CastMediaSource source) {
if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) { if (AUTO_JOIN_PRESENTATION_ID.equals(presentationId)) {
return canAutoJoin(source, origin, tabId); return canAutoJoin(source, origin, tabId);
} }
if (presentationId.startsWith(PRESENTATION_ID_SESSION_ID_PREFIX)) { if (presentationId.startsWith(PRESENTATION_ID_SESSION_ID_PREFIX)) {
String sessionId = presentationId.substring(PRESENTATION_ID_SESSION_ID_PREFIX.length()); String sessionId = presentationId.substring(PRESENTATION_ID_SESSION_ID_PREFIX.length());
return sessionController().getSession().getSessionId().equals(sessionId); return sessionId != null && sessionId.equals(sessionController().getSessionId());
} }
for (MediaRoute route : mRoutes.values()) { for (MediaRoute route : mRoutes.values()) {
if (route.presentationId.equals(presentationId)) return true; if (route.presentationId.equals(presentationId)) return true;
......
...@@ -2378,9 +2378,11 @@ chrome_junit_test_java_sources = [ ...@@ -2378,9 +2378,11 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/media/router/caf/MediaRouterTestHelper.java", "junit/src/org/chromium/chrome/browser/media/router/caf/MediaRouterTestHelper.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/ShadowMediaRouter.java", "junit/src/org/chromium/chrome/browser/media/router/caf/ShadowMediaRouter.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastContext.java", "junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastContext.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/ShadowCastMediaSource.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java", "junit/src/org/chromium/chrome/browser/media/router/caf/BaseSessionControllerTest.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/CastSessionControllerTest.java", "junit/src/org/chromium/chrome/browser/media/router/caf/CastSessionControllerTest.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java", "junit/src/org/chromium/chrome/browser/media/router/caf/CafBaseMediaRouteProviderTest.java",
"junit/src/org/chromium/chrome/browser/media/router/caf/CafMediaRouteProviderTest.java",
"junit/src/org/chromium/chrome/browser/media/ui/MediaImageManagerTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaImageManagerTest.java",
"junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java",
"junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationButtonComputationTest.java", "junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationButtonComputationTest.java",
......
...@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.media.router.MediaSource; ...@@ -50,7 +50,6 @@ import org.chromium.chrome.browser.media.router.MediaSource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Robolectric tests for CafBaseMediaRouteProvider. * Robolectric tests for CafBaseMediaRouteProvider.
...@@ -394,9 +393,9 @@ public class CafBaseMediaRouteProviderTest { ...@@ -394,9 +393,9 @@ public class CafBaseMediaRouteProviderTest {
inOrder.verify(mSessionController).attachToCastSession(mCastSession); inOrder.verify(mSessionController).attachToCastSession(mCastSession);
inOrder.verify(mSessionController).onSessionStarted(); inOrder.verify(mSessionController).onSessionStarted();
assertEquals(mProvider.getRoutes().size(), 1); assertEquals(mProvider.mRoutes.size(), 1);
MediaRoute route = (MediaRoute) (mProvider.getRoutes().values().toArray()[0]); MediaRoute route = (MediaRoute) (mProvider.mRoutes.values().toArray()[0]);
assertEquals(route.sinkId, "cast-route"); assertEquals(route.sinkId, "cast-route");
assertEquals(route.sourceId, "source-id"); assertEquals(route.sourceId, "source-id");
assertEquals(route.presentationId, "presentation-id"); assertEquals(route.presentationId, "presentation-id");
...@@ -586,10 +585,10 @@ public class CafBaseMediaRouteProviderTest { ...@@ -586,10 +585,10 @@ public class CafBaseMediaRouteProviderTest {
} }
private void assertContainsRoutes(MediaRoute... routes) { private void assertContainsRoutes(MediaRoute... routes) {
assertEquals(mProvider.getRoutes().size(), routes.length); assertEquals(mProvider.mRoutes.size(), routes.length);
for (MediaRoute route : routes) { for (MediaRoute route : routes) {
assertEquals(mProvider.getRoutes().get(route.id), route); assertEquals(mProvider.mRoutes.get(route.id), route);
} }
} }
...@@ -614,9 +613,5 @@ public class CafBaseMediaRouteProviderTest { ...@@ -614,9 +613,5 @@ public class CafBaseMediaRouteProviderTest {
@Override @Override
public void joinRoute(String routeId, String presentationId, String origin, int tabId, public void joinRoute(String routeId, String presentationId, String origin, int tabId,
int nativeRequestId) {} int nativeRequestId) {}
public Map<String, MediaRoute> getRoutes() {
return mRoutes;
}
} }
} }
// Copyright 2018 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.
package org.chromium.chrome.browser.media.router.caf;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.chromium.chrome.browser.media.router.cast.CastMediaSource;
/** Shadow implementation for {@link MediaRouter}. */
@Implements(CastMediaSource.class)
public class ShadowCastMediaSource {
private static ShadowImplementation sImpl;
@Implementation
public static CastMediaSource from(String sourceId) {
return sImpl.from(sourceId);
}
public static void setImplementation(ShadowImplementation impl) {
sImpl = impl;
}
/** The implementation skeleton for the implementation backing the shadow. */
public static class ShadowImplementation {
public CastMediaSource from(String sourceId) {
return null;
}
}
}
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