Skip to content
This repository has been archived by the owner on Feb 11, 2022. It is now read-only.

Commit

Permalink
Merge pull request #201 from novoda/develop
Browse files Browse the repository at this point in the history
Allow redirects cross protocol
  • Loading branch information
Ryan Feline authored Feb 25, 2019
2 parents daff26e + 978ab99 commit 99d6d47
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 36 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
allprojects {
version = '4.5.2'
version = '4.5.3'
}

def teamPropsFile(propsFile) {
Expand All @@ -14,7 +14,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.3.1'
classpath 'com.novoda:bintray-release:0.9'
classpath 'com.novoda:gradle-static-analysis-plugin:0.8'
classpath 'com.novoda:gradle-build-properties-plugin:0.4.1'
Expand Down
4 changes: 2 additions & 2 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ android {
}

dependencies {
implementation 'com.google.android.exoplayer:exoplayer:2.9.4'
implementation 'com.google.android.exoplayer:exoplayer:2.9.6'

implementation 'com.android.support:support-annotations:28.0.0'

testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.23.4'
testImplementation 'org.mockito:mockito-core:2.24.0'
testImplementation 'org.easytesting:fest-assert-core:2.0M10'
}

Expand Down
17 changes: 13 additions & 4 deletions core/src/main/java/com/novoda/noplayer/NoPlayerCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,32 @@ class NoPlayerCreator {
this.drmSessionCreatorFactory = drmSessionCreatorFactory;
}

NoPlayer create(DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder) {
NoPlayer create(DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder, boolean allowCrossProtocolRedirects) {
for (PlayerType player : prioritizedPlayerTypes) {
if (player.supports(drmType)) {
return createPlayerForType(player, drmType, drmHandler, downgradeSecureDecoder);
return createPlayerForType(player, drmType, drmHandler, downgradeSecureDecoder, allowCrossProtocolRedirects);
}
}
throw UnableToCreatePlayerException.unhandledDrmType(drmType);
}

private NoPlayer createPlayerForType(PlayerType playerType, DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder) {
private NoPlayer createPlayerForType(PlayerType playerType,
DrmType drmType,
DrmHandler drmHandler,
boolean downgradeSecureDecoder,
boolean allowCrossProtocolRedirects) {
switch (playerType) {
case MEDIA_PLAYER:
return noPlayerMediaPlayerCreator.createMediaPlayer(context);
case EXO_PLAYER:
try {
DrmSessionCreator drmSessionCreator = drmSessionCreatorFactory.createFor(drmType, drmHandler);
return noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, downgradeSecureDecoder);
return noPlayerExoPlayerCreator.createExoPlayer(
context,
drmSessionCreator,
downgradeSecureDecoder,
allowCrossProtocolRedirects
);
} catch (DrmSessionCreatorException exception) {
throw new UnableToCreatePlayerException(exception);
}
Expand Down
26 changes: 23 additions & 3 deletions core/src/main/java/com/novoda/noplayer/PlayerBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class PlayerBuilder {
private DrmType drmType = DrmType.NONE;
private DrmHandler drmHandler = DrmHandler.NO_DRM;
private List<PlayerType> prioritizedPlayerTypes = Arrays.asList(PlayerType.EXO_PLAYER, PlayerType.MEDIA_PLAYER);
private boolean downgradeSecureDecoder;
private boolean downgradeSecureDecoder; /* initialised to false by default */
private boolean allowCrossProtocolRedirects; /* initialised to false by default */
private String userAgent = "user-agent";

/**
* Sets {@link PlayerBuilder} to build a {@link NoPlayer} which supports Widevine classic DRM.
Expand Down Expand Up @@ -102,6 +104,24 @@ public PlayerBuilder withDowngradedSecureDecoder() {
return this;
}

/**
* @param userAgent The application's user-agent value
* @return {@link PlayerBuilder}
*/
public PlayerBuilder withUserAgent(String userAgent) {
this.userAgent = userAgent;
return this;
}

/**
* Network connections will be allowed to perform redirects between HTTP and HTTPS protocols
* @return {@link PlayerBuilder}
*/
public PlayerBuilder allowCrossProtocolRedirects() {
allowCrossProtocolRedirects = true;
return this;
}

/**
* Builds a new {@link NoPlayer} instance.
*
Expand All @@ -122,11 +142,11 @@ public NoPlayer build(Context context) throws UnableToCreatePlayerException {
NoPlayerCreator noPlayerCreator = new NoPlayerCreator(
applicationContext,
prioritizedPlayerTypes,
NoPlayerExoPlayerCreator.newInstance(handler),
NoPlayerExoPlayerCreator.newInstance(userAgent, handler),
NoPlayerMediaPlayerCreator.newInstance(handler),
drmSessionCreatorFactory
);
return noPlayerCreator.create(drmType, drmHandler, downgradeSecureDecoder);
return noPlayerCreator.create(drmType, drmHandler, downgradeSecureDecoder, allowCrossProtocolRedirects);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,25 @@ public class NoPlayerExoPlayerCreator {

private final InternalCreator internalCreator;

public static NoPlayerExoPlayerCreator newInstance(Handler handler) {
InternalCreator internalCreator = new InternalCreator(handler, Optional.<DataSource.Factory>absent());
public static NoPlayerExoPlayerCreator newInstance(String userAgent, Handler handler) {
InternalCreator internalCreator = new InternalCreator(userAgent, handler, Optional.<DataSource.Factory>absent());
return new NoPlayerExoPlayerCreator(internalCreator);
}

public static NoPlayerExoPlayerCreator newInstance(Handler handler, DataSource.Factory dataSourceFactory) {
InternalCreator internalCreator = new InternalCreator(handler, Optional.of(dataSourceFactory));
public static NoPlayerExoPlayerCreator newInstance(String userAgent, Handler handler, DataSource.Factory dataSourceFactory) {
InternalCreator internalCreator = new InternalCreator(userAgent, handler, Optional.of(dataSourceFactory));
return new NoPlayerExoPlayerCreator(internalCreator);
}

NoPlayerExoPlayerCreator(InternalCreator internalCreator) {
this.internalCreator = internalCreator;
}

public NoPlayer createExoPlayer(Context context, DrmSessionCreator drmSessionCreator, boolean downgradeSecureDecoder) {
ExoPlayerTwoImpl player = internalCreator.create(context, drmSessionCreator, downgradeSecureDecoder);
public NoPlayer createExoPlayer(Context context,
DrmSessionCreator drmSessionCreator,
boolean downgradeSecureDecoder,
boolean allowCrossProtocolRedirects) {
ExoPlayerTwoImpl player = internalCreator.create(context, drmSessionCreator, downgradeSecureDecoder, allowCrossProtocolRedirects);
player.initialise();
return player;
}
Expand All @@ -44,14 +47,25 @@ static class InternalCreator {

private final Handler handler;
private final Optional<DataSource.Factory> dataSourceFactory;
private final String userAgent;

InternalCreator(Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
InternalCreator(String userAgent, Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
this.userAgent = userAgent;
this.handler = handler;
this.dataSourceFactory = dataSourceFactory;
}

ExoPlayerTwoImpl create(Context context, DrmSessionCreator drmSessionCreator, boolean downgradeSecureDecoder) {
MediaSourceFactory mediaSourceFactory = new MediaSourceFactory(context, handler, dataSourceFactory);
ExoPlayerTwoImpl create(Context context,
DrmSessionCreator drmSessionCreator,
boolean downgradeSecureDecoder,
boolean allowCrossProtocolRedirects) {
MediaSourceFactory mediaSourceFactory = new MediaSourceFactory(
context,
userAgent,
handler,
dataSourceFactory,
allowCrossProtocolRedirects
);

MediaCodecSelector mediaCodecSelector = downgradeSecureDecoder
? SecurityDowngradingCodecSelector.newInstance()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.novoda.noplayer.Options;
import com.novoda.noplayer.internal.utils.Optional;

Expand All @@ -22,11 +24,19 @@ public class MediaSourceFactory {
private final Context context;
private final Handler handler;
private final Optional<DataSource.Factory> dataSourceFactory;
private final String userAgent;
private final boolean allowCrossProtocolRedirects;

public MediaSourceFactory(Context context, Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
public MediaSourceFactory(Context context,
String userAgent,
Handler handler,
Optional<DataSource.Factory> dataSourceFactory,
boolean allowCrossProtocolRedirects) {
this.context = context;
this.handler = handler;
this.dataSourceFactory = dataSourceFactory;
this.userAgent = userAgent;
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
}

public MediaSource create(Options options,
Expand All @@ -50,7 +60,15 @@ private DefaultDataSourceFactory createDataSourceFactory(DefaultBandwidthMeter b
if (dataSourceFactory.isPresent()) {
return new DefaultDataSourceFactory(context, bandwidthMeter, dataSourceFactory.get());
} else {
return new DefaultDataSourceFactory(context, "user-agent", bandwidthMeter);
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
userAgent,
bandwidthMeter,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
allowCrossProtocolRedirects
);

return new DefaultDataSourceFactory(context, bandwidthMeter, httpDataSourceFactory);
}
}

Expand Down
25 changes: 13 additions & 12 deletions core/src/test/java/com/novoda/noplayer/NoPlayerCreatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
import com.novoda.noplayer.internal.exoplayer.drm.DrmSessionCreatorFactory;
import com.novoda.noplayer.internal.mediaplayer.NoPlayerMediaPlayerCreator;

import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -24,6 +21,9 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.Arrays;
import java.util.List;

import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
Expand All @@ -35,6 +35,7 @@ public class NoPlayerCreatorTest {
public abstract static class Base {

static final boolean USE_SECURE_CODEC = false;
static final boolean ALLOW_CROSS_PROTOCOL_REDIRECTS = false;
static final StreamingModularDrm STREAMING_MODULAR_DRM = mock(StreamingModularDrm.class);
static final DownloadedModularDrm DOWNLOADED_MODULAR_DRM = mock(DownloadedModularDrm.class);
static final NoPlayer EXO_PLAYER = mock(NoPlayer.class);
Expand All @@ -60,7 +61,7 @@ public abstract static class Base {
@Before
public void setUp() throws DrmSessionCreatorException {
given(drmSessionCreatorFactory.createFor(any(DrmType.class), any(DrmHandler.class))).willReturn(drmSessionCreator);
given(noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC)).willReturn(EXO_PLAYER);
given(noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS)).willReturn(EXO_PLAYER);
given(noPlayerMediaPlayerCreator.createMediaPlayer(context)).willReturn(MEDIA_PLAYER);
noPlayerCreator = new NoPlayerCreator(context, prioritizedPlayerTypes(), noPlayerExoPlayerCreator, noPlayerMediaPlayerCreator, drmSessionCreatorFactory);
}
Expand All @@ -77,28 +78,28 @@ List<PlayerType> prioritizedPlayerTypes() {

@Test
public void whenCreatingPlayerWithDrmTypeNone_thenReturnsMediaPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(MEDIA_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineClassic_thenReturnsMediaPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(MEDIA_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineModularStream_thenReturnsExoPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(EXO_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineModularDownload_thenReturnsExoPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(EXO_PLAYER);
}
Expand All @@ -113,28 +114,28 @@ List<PlayerType> prioritizedPlayerTypes() {

@Test
public void whenCreatingPlayerWithDrmTypeNone_thenReturnsExoPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(EXO_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineClassic_thenReturnsMediaPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(MEDIA_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineModularStream_thenReturnsExoPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(EXO_PLAYER);
}

@Test
public void whenCreatingPlayerWithDrmTypeWidevineModularDownload_thenReturnsExoPlayer() {
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC);
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

assertThat(player).isEqualTo(EXO_PLAYER);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
public class NoPlayerExoPlayerCreatorTest {

private static final boolean USE_SECURE_CODEC = true;
private static final boolean ALLOW_CROSS_PROTOCOL_REDIRECTS = true;

@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
Expand All @@ -34,13 +35,13 @@ public class NoPlayerExoPlayerCreatorTest {

@Before
public void setUp() {
given(internalCreator.create(context, drmSessionCreator, USE_SECURE_CODEC)).willReturn(player);
given(internalCreator.create(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS)).willReturn(player);
creator = new NoPlayerExoPlayerCreator(internalCreator);
}

@Test
public void whenCreatingExoPlayerTwo_thenInitialisesPlayer() {
creator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC);
creator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);

verify(player).initialise();
}
Expand Down
2 changes: 2 additions & 0 deletions demo/src/main/java/com/novoda/demo/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ protected void onCreate(Bundle savedInstanceState) {
player = new PlayerBuilder()
.withWidevineModularStreamingDrm(drmHandler)
.withDowngradedSecureDecoder()
.withUserAgent("Android/Linux")
.allowCrossProtocolRedirects()
.build(this);

demoPresenter = new DemoPresenter(controllerView, player, player.getListeners(), playerView);
Expand Down

0 comments on commit 99d6d47

Please sign in to comment.