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

Commit 99d6d47

Browse files
author
Ryan Feline
authored
Merge pull request #201 from novoda/develop
Allow redirects cross protocol
2 parents daff26e + 978ab99 commit 99d6d47

File tree

9 files changed

+101
-36
lines changed

9 files changed

+101
-36
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
allprojects {
2-
version = '4.5.2'
2+
version = '4.5.3'
33
}
44

55
def teamPropsFile(propsFile) {
@@ -14,7 +14,7 @@ buildscript {
1414
}
1515

1616
dependencies {
17-
classpath 'com.android.tools.build:gradle:3.3.0'
17+
classpath 'com.android.tools.build:gradle:3.3.1'
1818
classpath 'com.novoda:bintray-release:0.9'
1919
classpath 'com.novoda:gradle-static-analysis-plugin:0.8'
2020
classpath 'com.novoda:gradle-build-properties-plugin:0.4.1'

core/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ android {
5959
}
6060

6161
dependencies {
62-
implementation 'com.google.android.exoplayer:exoplayer:2.9.4'
62+
implementation 'com.google.android.exoplayer:exoplayer:2.9.6'
6363

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

6666
testImplementation 'junit:junit:4.12'
67-
testImplementation 'org.mockito:mockito-core:2.23.4'
67+
testImplementation 'org.mockito:mockito-core:2.24.0'
6868
testImplementation 'org.easytesting:fest-assert-core:2.0M10'
6969
}
7070

core/src/main/java/com/novoda/noplayer/NoPlayerCreator.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,32 @@ class NoPlayerCreator {
3232
this.drmSessionCreatorFactory = drmSessionCreatorFactory;
3333
}
3434

35-
NoPlayer create(DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder) {
35+
NoPlayer create(DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder, boolean allowCrossProtocolRedirects) {
3636
for (PlayerType player : prioritizedPlayerTypes) {
3737
if (player.supports(drmType)) {
38-
return createPlayerForType(player, drmType, drmHandler, downgradeSecureDecoder);
38+
return createPlayerForType(player, drmType, drmHandler, downgradeSecureDecoder, allowCrossProtocolRedirects);
3939
}
4040
}
4141
throw UnableToCreatePlayerException.unhandledDrmType(drmType);
4242
}
4343

44-
private NoPlayer createPlayerForType(PlayerType playerType, DrmType drmType, DrmHandler drmHandler, boolean downgradeSecureDecoder) {
44+
private NoPlayer createPlayerForType(PlayerType playerType,
45+
DrmType drmType,
46+
DrmHandler drmHandler,
47+
boolean downgradeSecureDecoder,
48+
boolean allowCrossProtocolRedirects) {
4549
switch (playerType) {
4650
case MEDIA_PLAYER:
4751
return noPlayerMediaPlayerCreator.createMediaPlayer(context);
4852
case EXO_PLAYER:
4953
try {
5054
DrmSessionCreator drmSessionCreator = drmSessionCreatorFactory.createFor(drmType, drmHandler);
51-
return noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, downgradeSecureDecoder);
55+
return noPlayerExoPlayerCreator.createExoPlayer(
56+
context,
57+
drmSessionCreator,
58+
downgradeSecureDecoder,
59+
allowCrossProtocolRedirects
60+
);
5261
} catch (DrmSessionCreatorException exception) {
5362
throw new UnableToCreatePlayerException(exception);
5463
}

core/src/main/java/com/novoda/noplayer/PlayerBuilder.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ public class PlayerBuilder {
2626
private DrmType drmType = DrmType.NONE;
2727
private DrmHandler drmHandler = DrmHandler.NO_DRM;
2828
private List<PlayerType> prioritizedPlayerTypes = Arrays.asList(PlayerType.EXO_PLAYER, PlayerType.MEDIA_PLAYER);
29-
private boolean downgradeSecureDecoder;
29+
private boolean downgradeSecureDecoder; /* initialised to false by default */
30+
private boolean allowCrossProtocolRedirects; /* initialised to false by default */
31+
private String userAgent = "user-agent";
3032

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

107+
/**
108+
* @param userAgent The application's user-agent value
109+
* @return {@link PlayerBuilder}
110+
*/
111+
public PlayerBuilder withUserAgent(String userAgent) {
112+
this.userAgent = userAgent;
113+
return this;
114+
}
115+
116+
/**
117+
* Network connections will be allowed to perform redirects between HTTP and HTTPS protocols
118+
* @return {@link PlayerBuilder}
119+
*/
120+
public PlayerBuilder allowCrossProtocolRedirects() {
121+
allowCrossProtocolRedirects = true;
122+
return this;
123+
}
124+
105125
/**
106126
* Builds a new {@link NoPlayer} instance.
107127
*
@@ -122,11 +142,11 @@ public NoPlayer build(Context context) throws UnableToCreatePlayerException {
122142
NoPlayerCreator noPlayerCreator = new NoPlayerCreator(
123143
applicationContext,
124144
prioritizedPlayerTypes,
125-
NoPlayerExoPlayerCreator.newInstance(handler),
145+
NoPlayerExoPlayerCreator.newInstance(userAgent, handler),
126146
NoPlayerMediaPlayerCreator.newInstance(handler),
127147
drmSessionCreatorFactory
128148
);
129-
return noPlayerCreator.create(drmType, drmHandler, downgradeSecureDecoder);
149+
return noPlayerCreator.create(drmType, drmHandler, downgradeSecureDecoder, allowCrossProtocolRedirects);
130150
}
131151

132152
}

core/src/main/java/com/novoda/noplayer/internal/exoplayer/NoPlayerExoPlayerCreator.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,25 @@ public class NoPlayerExoPlayerCreator {
2020

2121
private final InternalCreator internalCreator;
2222

23-
public static NoPlayerExoPlayerCreator newInstance(Handler handler) {
24-
InternalCreator internalCreator = new InternalCreator(handler, Optional.<DataSource.Factory>absent());
23+
public static NoPlayerExoPlayerCreator newInstance(String userAgent, Handler handler) {
24+
InternalCreator internalCreator = new InternalCreator(userAgent, handler, Optional.<DataSource.Factory>absent());
2525
return new NoPlayerExoPlayerCreator(internalCreator);
2626
}
2727

28-
public static NoPlayerExoPlayerCreator newInstance(Handler handler, DataSource.Factory dataSourceFactory) {
29-
InternalCreator internalCreator = new InternalCreator(handler, Optional.of(dataSourceFactory));
28+
public static NoPlayerExoPlayerCreator newInstance(String userAgent, Handler handler, DataSource.Factory dataSourceFactory) {
29+
InternalCreator internalCreator = new InternalCreator(userAgent, handler, Optional.of(dataSourceFactory));
3030
return new NoPlayerExoPlayerCreator(internalCreator);
3131
}
3232

3333
NoPlayerExoPlayerCreator(InternalCreator internalCreator) {
3434
this.internalCreator = internalCreator;
3535
}
3636

37-
public NoPlayer createExoPlayer(Context context, DrmSessionCreator drmSessionCreator, boolean downgradeSecureDecoder) {
38-
ExoPlayerTwoImpl player = internalCreator.create(context, drmSessionCreator, downgradeSecureDecoder);
37+
public NoPlayer createExoPlayer(Context context,
38+
DrmSessionCreator drmSessionCreator,
39+
boolean downgradeSecureDecoder,
40+
boolean allowCrossProtocolRedirects) {
41+
ExoPlayerTwoImpl player = internalCreator.create(context, drmSessionCreator, downgradeSecureDecoder, allowCrossProtocolRedirects);
3942
player.initialise();
4043
return player;
4144
}
@@ -44,14 +47,25 @@ static class InternalCreator {
4447

4548
private final Handler handler;
4649
private final Optional<DataSource.Factory> dataSourceFactory;
50+
private final String userAgent;
4751

48-
InternalCreator(Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
52+
InternalCreator(String userAgent, Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
53+
this.userAgent = userAgent;
4954
this.handler = handler;
5055
this.dataSourceFactory = dataSourceFactory;
5156
}
5257

53-
ExoPlayerTwoImpl create(Context context, DrmSessionCreator drmSessionCreator, boolean downgradeSecureDecoder) {
54-
MediaSourceFactory mediaSourceFactory = new MediaSourceFactory(context, handler, dataSourceFactory);
58+
ExoPlayerTwoImpl create(Context context,
59+
DrmSessionCreator drmSessionCreator,
60+
boolean downgradeSecureDecoder,
61+
boolean allowCrossProtocolRedirects) {
62+
MediaSourceFactory mediaSourceFactory = new MediaSourceFactory(
63+
context,
64+
userAgent,
65+
handler,
66+
dataSourceFactory,
67+
allowCrossProtocolRedirects
68+
);
5569

5670
MediaCodecSelector mediaCodecSelector = downgradeSecureDecoder
5771
? SecurityDowngradingCodecSelector.newInstance()

core/src/main/java/com/novoda/noplayer/internal/exoplayer/mediasource/MediaSourceFactory.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import com.google.android.exoplayer2.upstream.DataSource;
1515
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
1616
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
17+
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
18+
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
1719
import com.novoda.noplayer.Options;
1820
import com.novoda.noplayer.internal.utils.Optional;
1921

@@ -22,11 +24,19 @@ public class MediaSourceFactory {
2224
private final Context context;
2325
private final Handler handler;
2426
private final Optional<DataSource.Factory> dataSourceFactory;
27+
private final String userAgent;
28+
private final boolean allowCrossProtocolRedirects;
2529

26-
public MediaSourceFactory(Context context, Handler handler, Optional<DataSource.Factory> dataSourceFactory) {
30+
public MediaSourceFactory(Context context,
31+
String userAgent,
32+
Handler handler,
33+
Optional<DataSource.Factory> dataSourceFactory,
34+
boolean allowCrossProtocolRedirects) {
2735
this.context = context;
2836
this.handler = handler;
2937
this.dataSourceFactory = dataSourceFactory;
38+
this.userAgent = userAgent;
39+
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
3040
}
3141

3242
public MediaSource create(Options options,
@@ -50,7 +60,15 @@ private DefaultDataSourceFactory createDataSourceFactory(DefaultBandwidthMeter b
5060
if (dataSourceFactory.isPresent()) {
5161
return new DefaultDataSourceFactory(context, bandwidthMeter, dataSourceFactory.get());
5262
} else {
53-
return new DefaultDataSourceFactory(context, "user-agent", bandwidthMeter);
63+
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
64+
userAgent,
65+
bandwidthMeter,
66+
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
67+
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
68+
allowCrossProtocolRedirects
69+
);
70+
71+
return new DefaultDataSourceFactory(context, bandwidthMeter, httpDataSourceFactory);
5472
}
5573
}
5674

core/src/test/java/com/novoda/noplayer/NoPlayerCreatorTest.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
import com.novoda.noplayer.internal.exoplayer.drm.DrmSessionCreatorFactory;
1313
import com.novoda.noplayer.internal.mediaplayer.NoPlayerMediaPlayerCreator;
1414

15-
import java.util.Arrays;
16-
import java.util.List;
17-
1815
import org.junit.Before;
1916
import org.junit.Rule;
2017
import org.junit.Test;
@@ -24,6 +21,9 @@
2421
import org.mockito.junit.MockitoJUnit;
2522
import org.mockito.junit.MockitoRule;
2623

24+
import java.util.Arrays;
25+
import java.util.List;
26+
2727
import static org.fest.assertions.api.Assertions.assertThat;
2828
import static org.mockito.ArgumentMatchers.any;
2929
import static org.mockito.BDDMockito.given;
@@ -35,6 +35,7 @@ public class NoPlayerCreatorTest {
3535
public abstract static class Base {
3636

3737
static final boolean USE_SECURE_CODEC = false;
38+
static final boolean ALLOW_CROSS_PROTOCOL_REDIRECTS = false;
3839
static final StreamingModularDrm STREAMING_MODULAR_DRM = mock(StreamingModularDrm.class);
3940
static final DownloadedModularDrm DOWNLOADED_MODULAR_DRM = mock(DownloadedModularDrm.class);
4041
static final NoPlayer EXO_PLAYER = mock(NoPlayer.class);
@@ -60,7 +61,7 @@ public abstract static class Base {
6061
@Before
6162
public void setUp() throws DrmSessionCreatorException {
6263
given(drmSessionCreatorFactory.createFor(any(DrmType.class), any(DrmHandler.class))).willReturn(drmSessionCreator);
63-
given(noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC)).willReturn(EXO_PLAYER);
64+
given(noPlayerExoPlayerCreator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS)).willReturn(EXO_PLAYER);
6465
given(noPlayerMediaPlayerCreator.createMediaPlayer(context)).willReturn(MEDIA_PLAYER);
6566
noPlayerCreator = new NoPlayerCreator(context, prioritizedPlayerTypes(), noPlayerExoPlayerCreator, noPlayerMediaPlayerCreator, drmSessionCreatorFactory);
6667
}
@@ -77,28 +78,28 @@ List<PlayerType> prioritizedPlayerTypes() {
7778

7879
@Test
7980
public void whenCreatingPlayerWithDrmTypeNone_thenReturnsMediaPlayer() {
80-
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC);
81+
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
8182

8283
assertThat(player).isEqualTo(MEDIA_PLAYER);
8384
}
8485

8586
@Test
8687
public void whenCreatingPlayerWithDrmTypeWidevineClassic_thenReturnsMediaPlayer() {
87-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC);
88+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
8889

8990
assertThat(player).isEqualTo(MEDIA_PLAYER);
9091
}
9192

9293
@Test
9394
public void whenCreatingPlayerWithDrmTypeWidevineModularStream_thenReturnsExoPlayer() {
94-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC);
95+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
9596

9697
assertThat(player).isEqualTo(EXO_PLAYER);
9798
}
9899

99100
@Test
100101
public void whenCreatingPlayerWithDrmTypeWidevineModularDownload_thenReturnsExoPlayer() {
101-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC);
102+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
102103

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

114115
@Test
115116
public void whenCreatingPlayerWithDrmTypeNone_thenReturnsExoPlayer() {
116-
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC);
117+
NoPlayer player = noPlayerCreator.create(DrmType.NONE, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
117118

118119
assertThat(player).isEqualTo(EXO_PLAYER);
119120
}
120121

121122
@Test
122123
public void whenCreatingPlayerWithDrmTypeWidevineClassic_thenReturnsMediaPlayer() {
123-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC);
124+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_CLASSIC, DrmHandler.NO_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
124125

125126
assertThat(player).isEqualTo(MEDIA_PLAYER);
126127
}
127128

128129
@Test
129130
public void whenCreatingPlayerWithDrmTypeWidevineModularStream_thenReturnsExoPlayer() {
130-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC);
131+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_STREAM, STREAMING_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
131132

132133
assertThat(player).isEqualTo(EXO_PLAYER);
133134
}
134135

135136
@Test
136137
public void whenCreatingPlayerWithDrmTypeWidevineModularDownload_thenReturnsExoPlayer() {
137-
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC);
138+
NoPlayer player = noPlayerCreator.create(DrmType.WIDEVINE_MODULAR_DOWNLOAD, DOWNLOADED_MODULAR_DRM, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
138139

139140
assertThat(player).isEqualTo(EXO_PLAYER);
140141
}

core/src/test/java/com/novoda/noplayer/internal/exoplayer/NoPlayerExoPlayerCreatorTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
public class NoPlayerExoPlayerCreatorTest {
1818

1919
private static final boolean USE_SECURE_CODEC = true;
20+
private static final boolean ALLOW_CROSS_PROTOCOL_REDIRECTS = true;
2021

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

3536
@Before
3637
public void setUp() {
37-
given(internalCreator.create(context, drmSessionCreator, USE_SECURE_CODEC)).willReturn(player);
38+
given(internalCreator.create(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS)).willReturn(player);
3839
creator = new NoPlayerExoPlayerCreator(internalCreator);
3940
}
4041

4142
@Test
4243
public void whenCreatingExoPlayerTwo_thenInitialisesPlayer() {
43-
creator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC);
44+
creator.createExoPlayer(context, drmSessionCreator, USE_SECURE_CODEC, ALLOW_CROSS_PROTOCOL_REDIRECTS);
4445

4546
verify(player).initialise();
4647
}

demo/src/main/java/com/novoda/demo/MainActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ protected void onCreate(Bundle savedInstanceState) {
4646
player = new PlayerBuilder()
4747
.withWidevineModularStreamingDrm(drmHandler)
4848
.withDowngradedSecureDecoder()
49+
.withUserAgent("Android/Linux")
50+
.allowCrossProtocolRedirects()
4951
.build(this);
5052

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

0 commit comments

Comments
 (0)