Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
6114c894
authored
Dec 14, 2020
by
bachinger
Committed by
Christos Tsilopoulos
Dec 17, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Make OkHttpDataSourceFactory an inner class of OkHttpDataSource
#exofixit PiperOrigin-RevId: 347389531
parent
e18892cd
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
106 deletions
RELEASENOTES.md
extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java
extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSourceFactory.java
extensions/okhttp/src/test/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSourceTest.java
RELEASENOTES.md
View file @
6114c894
...
...
@@ -62,10 +62,16 @@
*
Text:
*
Gracefully handle null-terminated subtitle content in Matroska
containers.
*
OkHttp extension:
*
Add
`OkHttpDataSource.Factory`
and deprecate
`OkHttpDataSourceFactory`
.
*
Media2 extension
*
Make media2-extension depend on AndroidX media2:media2-session:1.1.0 to
fix a deadlock while creating PlaybackStateCompat internally.
(
[
#8011
](
https://github.com/google/ExoPlayer/issues/8011
)
).
*
MediaSession extension:
*
Support
`setPlaybackSpeed(float)`
and disable it by default. Use
`MediaSessionConnector.setEnabledPlaybackActions(long)`
to enable
(
[
#8229
](
https://github.com/google/ExoPlayer/issues/8229
)
).
### 2.12.2 (2020-12-01) ###
...
...
@@ -128,10 +134,6 @@
`STATE_IDLE`
or
`STATE_ENDED`
.
*
Allow to remove all playlist items that makes the player reset.
(
[
#8047
](
https://github.com/google/ExoPlayer/issues/8047
)
).
*
MediaSession extension:
*
Support
`setPlaybackSpeed(float)`
and disable it by default. Use
`MediaSessionConnector.setEnabledPlaybackActions(long)`
to enable
(
[
#8229
](
https://github.com/google/ExoPlayer/issues/8229
)
).
### 2.12.1 (2020-10-23) ###
...
...
extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java
View file @
6114c894
...
...
@@ -15,6 +15,7 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
ext
.
okhttp
;
import
static
com
.
google
.
android
.
exoplayer2
.
ExoPlayerLibraryInfo
.
DEFAULT_USER_AGENT
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Util
.
castNonNull
;
import
static
java
.
lang
.
Math
.
min
;
...
...
@@ -23,9 +24,11 @@ import androidx.annotation.Nullable;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.ExoPlayerLibraryInfo
;
import
com.google.android.exoplayer2.upstream.BaseDataSource
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSourceException
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.HttpDataSource
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.common.base.Predicate
;
...
...
@@ -41,6 +44,7 @@ import okhttp3.CacheControl;
import
okhttp3.Call
;
import
okhttp3.HttpUrl
;
import
okhttp3.MediaType
;
import
okhttp3.OkHttpClient
;
import
okhttp3.Request
;
import
okhttp3.RequestBody
;
import
okhttp3.Response
;
...
...
@@ -59,6 +63,111 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
ExoPlayerLibraryInfo
.
registerModule
(
"goog.exo.okhttp"
);
}
/** {@link DataSource.Factory} for {@link OkHttpDataSource} instances. */
public
static
final
class
Factory
implements
HttpDataSource
.
Factory
{
private
final
RequestProperties
defaultRequestProperties
;
private
final
Call
.
Factory
callFactory
;
@Nullable
private
String
userAgent
;
@Nullable
private
TransferListener
transferListener
;
@Nullable
private
CacheControl
cacheControl
;
@Nullable
private
Predicate
<
String
>
contentTypePredicate
;
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link OkHttpClient}) for use by the
* sources created by the factory.
*/
public
Factory
(
Call
.
Factory
callFactory
)
{
this
.
callFactory
=
callFactory
;
defaultRequestProperties
=
new
RequestProperties
();
userAgent
=
DEFAULT_USER_AGENT
;
}
/** @deprecated Use {@link #setDefaultRequestProperties(Map)} instead. */
@Deprecated
@Override
public
final
RequestProperties
getDefaultRequestProperties
()
{
return
defaultRequestProperties
;
}
@Override
public
final
Factory
setDefaultRequestProperties
(
Map
<
String
,
String
>
defaultRequestProperties
)
{
this
.
defaultRequestProperties
.
clearAndSet
(
defaultRequestProperties
);
return
this
;
}
/**
* Sets the user agent that will be used.
*
* <p>The default is {@link ExoPlayerLibraryInfo#DEFAULT_USER_AGENT}.
*
* @param userAgent The user agent that will be used.
* @return This factory.
*/
public
Factory
setUserAgent
(
String
userAgent
)
{
this
.
userAgent
=
userAgent
;
return
this
;
}
/**
* Sets the {@link CacheControl} that will be used.
*
* <p>The default is {@code null}.
*
* @param cacheControl The cache control that will be used.
* @return This factory.
*/
public
Factory
setCacheControl
(
@Nullable
CacheControl
cacheControl
)
{
this
.
cacheControl
=
cacheControl
;
return
this
;
}
/**
* Sets a content type {@link Predicate}. If a content type is rejected by the predicate then a
* {@link HttpDataSource.InvalidContentTypeException} is thrown from {@link
* OkHttpDataSource#open(DataSpec)}.
*
* <p>The default is {@code null}.
*
* @param contentTypePredicate The content type {@link Predicate}, or {@code null} to clear a
* predicate that was previously set.
* @return This factory.
*/
public
Factory
setContentTypePredicate
(
@Nullable
Predicate
<
String
>
contentTypePredicate
)
{
this
.
contentTypePredicate
=
contentTypePredicate
;
return
this
;
}
/**
* Sets the {@link TransferListener} that will be used.
*
* <p>The default is {@code null}.
*
* <p>See {@link DataSource#addTransferListener(TransferListener)}.
*
* @param transferListener The listener that will be used.
* @return This factory.
*/
public
Factory
setTransferListener
(
@Nullable
TransferListener
transferListener
)
{
this
.
transferListener
=
transferListener
;
return
this
;
}
@Override
public
OkHttpDataSource
createDataSource
()
{
OkHttpDataSource
dataSource
=
new
OkHttpDataSource
(
callFactory
,
userAgent
,
cacheControl
,
defaultRequestProperties
,
contentTypePredicate
);
if
(
transferListener
!=
null
)
{
dataSource
.
addTransferListener
(
transferListener
);
}
return
dataSource
;
}
}
private
static
final
byte
[]
SKIP_BUFFER
=
new
byte
[
4096
];
private
final
Call
.
Factory
callFactory
;
...
...
@@ -80,114 +189,54 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
private
long
bytesSkipped
;
private
long
bytesRead
;
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link okhttp3.OkHttpClient}) for use
* by the source.
*/
/** @deprecated Use {@link OkHttpDataSource.Factory} instead. */
@SuppressWarnings
(
"deprecation"
)
@Deprecated
public
OkHttpDataSource
(
Call
.
Factory
callFactory
)
{
this
(
callFactory
,
ExoPlayerLibraryInfo
.
DEFAULT_USER_AGENT
);
this
(
callFactory
,
DEFAULT_USER_AGENT
);
}
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link okhttp3.OkHttpClient}) for use
* by the source.
* @param userAgent An optional User-Agent string.
*/
/** @deprecated Use {@link OkHttpDataSource.Factory} instead. */
@SuppressWarnings
(
"deprecation"
)
@Deprecated
public
OkHttpDataSource
(
Call
.
Factory
callFactory
,
@Nullable
String
userAgent
)
{
this
(
callFactory
,
userAgent
,
/* cacheControl= */
null
,
/* defaultRequestProperties= */
null
);
}
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link okhttp3.OkHttpClient}) for use
* by the source.
* @param userAgent An optional User-Agent string.
* @param cacheControl An optional {@link CacheControl} for setting the Cache-Control header.
* @param defaultRequestProperties Optional default {@link RequestProperties} to be sent to the
* server as HTTP headers on every request.
*/
/** @deprecated Use {@link OkHttpDataSource.Factory} instead. */
@Deprecated
public
OkHttpDataSource
(
Call
.
Factory
callFactory
,
@Nullable
String
userAgent
,
@Nullable
CacheControl
cacheControl
,
@Nullable
RequestProperties
defaultRequestProperties
)
{
super
(
/* isNetwork= */
true
);
this
.
callFactory
=
Assertions
.
checkNotNull
(
callFactory
);
this
.
userAgent
=
userAgent
;
this
.
cacheControl
=
cacheControl
;
this
.
defaultRequestProperties
=
defaultRequestProperties
;
this
.
requestProperties
=
new
RequestProperties
();
}
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link okhttp3.OkHttpClient}) for use
* by the source.
* @param userAgent An optional User-Agent string.
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
* predicate then a {@link InvalidContentTypeException} is thrown from {@link
* #open(DataSpec)}.
* @deprecated Use {@link #OkHttpDataSource(Call.Factory, String)} and {@link
* #setContentTypePredicate(Predicate)}.
*/
@SuppressWarnings
(
"deprecation"
)
@Deprecated
public
OkHttpDataSource
(
Call
.
Factory
callFactory
,
@Nullable
String
userAgent
,
@Nullable
Predicate
<
String
>
contentTypePredicate
)
{
this
(
callFactory
,
userAgent
,
c
ontentTypePredicate
,
/* cacheControl= */
null
,
/*
defaultRequestProperties
= */
null
);
c
acheControl
,
defaultRequestProperties
,
/*
contentTypePredicate
= */
null
);
}
/**
* Creates an instance.
*
* @param callFactory A {@link Call.Factory} (typically an {@link okhttp3.OkHttpClient}) for use
* by the source.
* @param userAgent An optional User-Agent string.
* @param contentTypePredicate An optional {@link Predicate}. If a content type is rejected by the
* predicate then a {@link InvalidContentTypeException} is thrown from {@link
* #open(DataSpec)}.
* @param cacheControl An optional {@link CacheControl} for setting the Cache-Control header.
* @param defaultRequestProperties Optional default {@link RequestProperties} to be sent to the
* server as HTTP headers on every request.
* @deprecated Use {@link #OkHttpDataSource(Call.Factory, String, CacheControl,
* RequestProperties)} and {@link #setContentTypePredicate(Predicate)}.
*/
@Deprecated
public
OkHttpDataSource
(
private
OkHttpDataSource
(
Call
.
Factory
callFactory
,
@Nullable
String
userAgent
,
@Nullable
Predicate
<
String
>
contentTypePredicate
,
@Nullable
CacheControl
cacheControl
,
@Nullable
RequestProperties
defaultRequestProperties
)
{
@Nullable
RequestProperties
defaultRequestProperties
,
@Nullable
Predicate
<
String
>
contentTypePredicate
)
{
super
(
/* isNetwork= */
true
);
this
.
callFactory
=
Assertions
.
checkNotNull
(
callFactory
);
this
.
userAgent
=
userAgent
;
this
.
contentTypePredicate
=
contentTypePredicate
;
this
.
cacheControl
=
cacheControl
;
this
.
defaultRequestProperties
=
defaultRequestProperties
;
this
.
contentTypePredicate
=
contentTypePredicate
;
this
.
requestProperties
=
new
RequestProperties
();
}
/**
* Sets a content type {@link Predicate}. If a content type is rejected by the predicate then a
* {@link HttpDataSource.InvalidContentTypeException} is thrown from {@link #open(DataSpec)}.
*
* @param contentTypePredicate The content type {@link Predicate}, or {@code null} to clear a
* predicate that was previously set.
* @deprecated Use {@link OkHttpDataSource.Factory#setContentTypePredicate(Predicate)} instead.
*/
@Deprecated
public
void
setContentTypePredicate
(
@Nullable
Predicate
<
String
>
contentTypePredicate
)
{
this
.
contentTypePredicate
=
contentTypePredicate
;
}
...
...
@@ -274,7 +323,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
}
// Check for a valid content type.
MediaType
mediaType
=
responseBody
.
contentType
();
@Nullable
MediaType
mediaType
=
responseBody
.
contentType
();
String
contentType
=
mediaType
!=
null
?
mediaType
.
toString
()
:
""
;
if
(
contentTypePredicate
!=
null
&&
!
contentTypePredicate
.
apply
(
contentType
))
{
closeConnectionQuietly
();
...
...
@@ -357,7 +406,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
long
position
=
dataSpec
.
position
;
long
length
=
dataSpec
.
length
;
HttpUrl
url
=
HttpUrl
.
parse
(
dataSpec
.
uri
.
toString
());
@Nullable
HttpUrl
url
=
HttpUrl
.
parse
(
dataSpec
.
uri
.
toString
());
if
(
url
==
null
)
{
throw
new
HttpDataSourceException
(
"Malformed URL"
,
dataSpec
,
HttpDataSourceException
.
TYPE_OPEN
);
...
...
@@ -394,7 +443,7 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
builder
.
addHeader
(
"Accept-Encoding"
,
"identity"
);
}
RequestBody
requestBody
=
null
;
@Nullable
RequestBody
requestBody
=
null
;
if
(
dataSpec
.
httpBody
!=
null
)
{
requestBody
=
RequestBody
.
create
(
null
,
dataSpec
.
httpBody
);
}
else
if
(
dataSpec
.
httpMethod
==
DataSpec
.
HTTP_METHOD_POST
)
{
...
...
extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSourceFactory.java
View file @
6114c894
...
...
@@ -20,14 +20,12 @@ import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AG
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.upstream.HttpDataSource
;
import
com.google.android.exoplayer2.upstream.HttpDataSource.BaseFactory
;
import
com.google.android.exoplayer2.upstream.HttpDataSource.Factory
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
okhttp3.CacheControl
;
import
okhttp3.Call
;
/**
* A {@link Factory} that produces {@link OkHttpDataSource}.
*/
/** @deprecated Use {@link OkHttpDataSource.Factory} instead. */
@Deprecated
public
final
class
OkHttpDataSourceFactory
extends
BaseFactory
{
private
final
Call
.
Factory
callFactory
;
...
...
@@ -102,6 +100,8 @@ public final class OkHttpDataSourceFactory extends BaseFactory {
this
.
cacheControl
=
cacheControl
;
}
// Calls deprecated constructor.
@SuppressWarnings
(
"deprecation"
)
@Override
protected
OkHttpDataSource
createDataSourceInternal
(
HttpDataSource
.
RequestProperties
defaultRequestProperties
)
{
...
...
extensions/okhttp/src/test/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSourceTest.java
View file @
6114c894
...
...
@@ -59,15 +59,16 @@ public class OkHttpDataSourceTest {
MockWebServer
mockWebServer
=
new
MockWebServer
();
mockWebServer
.
enqueue
(
new
MockResponse
());
String
propertyFromConstructor
=
"fromConstructor"
;
HttpDataSource
.
RequestProperties
constructorProperties
=
new
HttpDataSource
.
RequestProperties
();
constructorProperties
.
set
(
"0"
,
propertyFromConstructor
);
constructorProperties
.
set
(
"1"
,
propertyFromConstructor
);
constructorProperties
.
set
(
"2"
,
propertyFromConstructor
);
constructorProperties
.
set
(
"4"
,
propertyFromConstructor
);
OkHttpDataSource
dataSource
=
new
OkHttpDataSource
(
new
OkHttpClient
(),
"testAgent"
,
/* cacheControl= */
null
,
constructorProperties
);
String
propertyFromFactory
=
"fromFactory"
;
Map
<
String
,
String
>
defaultRequestProperties
=
new
HashMap
<>();
defaultRequestProperties
.
put
(
"0"
,
propertyFromFactory
);
defaultRequestProperties
.
put
(
"1"
,
propertyFromFactory
);
defaultRequestProperties
.
put
(
"2"
,
propertyFromFactory
);
defaultRequestProperties
.
put
(
"4"
,
propertyFromFactory
);
HttpDataSource
dataSource
=
new
OkHttpDataSource
.
Factory
(
new
OkHttpClient
())
.
setDefaultRequestProperties
(
defaultRequestProperties
)
.
createDataSource
();
String
propertyFromSetter
=
"fromSetter"
;
dataSource
.
setRequestProperty
(
"1"
,
propertyFromSetter
);
...
...
@@ -91,7 +92,7 @@ public class OkHttpDataSourceTest {
dataSource
.
open
(
dataSpec
);
Headers
headers
=
mockWebServer
.
takeRequest
(
10
,
SECONDS
).
getHeaders
();
assertThat
(
headers
.
get
(
"0"
)).
isEqualTo
(
propertyFrom
Constructor
);
assertThat
(
headers
.
get
(
"0"
)).
isEqualTo
(
propertyFrom
Factory
);
assertThat
(
headers
.
get
(
"1"
)).
isEqualTo
(
propertyFromSetter
);
assertThat
(
headers
.
get
(
"2"
)).
isEqualTo
(
propertyFromDataSpec
);
assertThat
(
headers
.
get
(
"3"
)).
isEqualTo
(
propertyFromDataSpec
);
...
...
@@ -101,16 +102,13 @@ public class OkHttpDataSourceTest {
}
@Test
public
void
open_invalidResponseCode
()
throws
Exception
{
public
void
open_invalidResponseCode
()
{
MockWebServer
mockWebServer
=
new
MockWebServer
();
mockWebServer
.
enqueue
(
new
MockResponse
().
setResponseCode
(
404
).
setBody
(
"failure msg"
));
OkHttpDataSource
okHttpDataSource
=
new
OkHttpDataSource
(
new
OkHttpClient
(),
"testAgent"
,
/* cacheControl= */
null
,
/* defaultRequestProperties= */
null
);
HttpDataSource
okHttpDataSource
=
new
OkHttpDataSource
.
Factory
(
new
OkHttpClient
()).
createDataSource
();
DataSpec
dataSpec
=
new
DataSpec
.
Builder
().
setUri
(
mockWebServer
.
url
(
"/test-path"
).
toString
()).
build
();
...
...
@@ -122,4 +120,22 @@ public class OkHttpDataSourceTest {
assertThat
(
exception
.
responseCode
).
isEqualTo
(
404
);
assertThat
(
exception
.
responseBody
).
isEqualTo
(
"failure msg"
.
getBytes
(
Charsets
.
UTF_8
));
}
@Test
public
void
factory_setRequestPropertyAfterCreation_setsCorrectHeaders
()
throws
Exception
{
MockWebServer
mockWebServer
=
new
MockWebServer
();
mockWebServer
.
enqueue
(
new
MockResponse
());
DataSpec
dataSpec
=
new
DataSpec
.
Builder
().
setUri
(
mockWebServer
.
url
(
"/test-path"
).
toString
()).
build
();
OkHttpDataSource
.
Factory
factory
=
new
OkHttpDataSource
.
Factory
(
new
OkHttpClient
());
OkHttpDataSource
dataSource
=
factory
.
createDataSource
();
Map
<
String
,
String
>
defaultRequestProperties
=
new
HashMap
<>();
defaultRequestProperties
.
put
(
"0"
,
"afterCreation"
);
factory
.
setDefaultRequestProperties
(
defaultRequestProperties
);
dataSource
.
open
(
dataSpec
);
Headers
headers
=
mockWebServer
.
takeRequest
(
10
,
SECONDS
).
getHeaders
();
assertThat
(
headers
.
get
(
"0"
)).
isEqualTo
(
"afterCreation"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment