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
a5e6e305
authored
Aug 07, 2020
by
christosts
Committed by
kim-vde
Aug 07, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Offline DRM in main demo app
PiperOrigin-RevId: 325413035
parent
c7a1151c
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
129 additions
and
33 deletions
RELEASENOTES.md
demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoUtil.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
demos/main/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java
demos/main/src/main/res/values/strings.xml
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadRequest.java
RELEASENOTES.md
View file @
a5e6e305
...
@@ -168,6 +168,7 @@
...
@@ -168,6 +168,7 @@
[
#6725
](
https://github.com/google/ExoPlayer/issues/6725
)
,
[
#6725
](
https://github.com/google/ExoPlayer/issues/6725
)
,
[
#7066
](
https://github.com/google/ExoPlayer/issues/7066
)
).
[
#7066
](
https://github.com/google/ExoPlayer/issues/7066
)
).
*
Downloads and caching:
*
Downloads and caching:
*
Add support for offline DRM playbacks.
*
Add builder in
`DownloadRequest`
.
*
Add builder in
`DownloadRequest`
.
*
Support passing an
`Executor`
to
`DefaultDownloaderFactory`
on which
*
Support passing an
`Executor`
to
`DefaultDownloaderFactory`
on which
data downloads are performed.
data downloads are performed.
...
...
demos/main/src/main/java/com/google/android/exoplayer2/demo/DemoUtil.java
View file @
a5e6e305
...
@@ -93,7 +93,7 @@ public final class DemoUtil {
...
@@ -93,7 +93,7 @@ public final class DemoUtil {
}
}
/** Returns a {@link DataSource.Factory}. */
/** Returns a {@link DataSource.Factory}. */
public
static
synchronized
DataSource
.
Factory
build
DataSourceFactory
(
Context
context
)
{
public
static
synchronized
DataSource
.
Factory
get
DataSourceFactory
(
Context
context
)
{
if
(
dataSourceFactory
==
null
)
{
if
(
dataSourceFactory
==
null
)
{
context
=
context
.
getApplicationContext
();
context
=
context
.
getApplicationContext
();
DefaultDataSourceFactory
upstreamFactory
=
DefaultDataSourceFactory
upstreamFactory
=
...
@@ -151,7 +151,7 @@ public final class DemoUtil {
...
@@ -151,7 +151,7 @@ public final class DemoUtil {
getHttpDataSourceFactory
(
context
),
getHttpDataSourceFactory
(
context
),
Executors
.
newFixedThreadPool
(
/* nThreads= */
6
));
Executors
.
newFixedThreadPool
(
/* nThreads= */
6
));
downloadTracker
=
downloadTracker
=
new
DownloadTracker
(
context
,
build
DataSourceFactory
(
context
),
downloadManager
);
new
DownloadTracker
(
context
,
getHttp
DataSourceFactory
(
context
),
downloadManager
);
}
}
}
}
...
...
demos/main/src/main/java/com/google/android/exoplayer2/demo/DownloadTracker.java
View file @
a5e6e305
...
@@ -23,9 +23,15 @@ import android.net.Uri;
...
@@ -23,9 +23,15 @@ import android.net.Uri;
import
android.widget.Toast
;
import
android.widget.Toast
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.RequiresApi
;
import
androidx.fragment.app.FragmentManager
;
import
androidx.fragment.app.FragmentManager
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.MediaItem
;
import
com.google.android.exoplayer2.RenderersFactory
;
import
com.google.android.exoplayer2.RenderersFactory
;
import
com.google.android.exoplayer2.drm.DrmInitData
;
import
com.google.android.exoplayer2.drm.DrmSession
;
import
com.google.android.exoplayer2.drm.DrmSessionEventListener
;
import
com.google.android.exoplayer2.drm.OfflineLicenseHelper
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.Download
;
import
com.google.android.exoplayer2.offline.DownloadCursor
;
import
com.google.android.exoplayer2.offline.DownloadCursor
;
import
com.google.android.exoplayer2.offline.DownloadHelper
;
import
com.google.android.exoplayer2.offline.DownloadHelper
;
...
@@ -33,9 +39,11 @@ import com.google.android.exoplayer2.offline.DownloadIndex;
...
@@ -33,9 +39,11 @@ import com.google.android.exoplayer2.offline.DownloadIndex;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadManager
;
import
com.google.android.exoplayer2.offline.DownloadRequest
;
import
com.google.android.exoplayer2.offline.DownloadRequest
;
import
com.google.android.exoplayer2.offline.DownloadService
;
import
com.google.android.exoplayer2.offline.DownloadService
;
import
com.google.android.exoplayer2.source.TrackGroup
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.trackselection.DefaultTrackSelector
;
import
com.google.android.exoplayer2.trackselection.DefaultTrackSelector
;
import
com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo
;
import
com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo
;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.
Http
DataSource
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.Log
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.util.Util
;
import
java.io.IOException
;
import
java.io.IOException
;
...
@@ -55,7 +63,7 @@ public class DownloadTracker {
...
@@ -55,7 +63,7 @@ public class DownloadTracker {
private
static
final
String
TAG
=
"DownloadTracker"
;
private
static
final
String
TAG
=
"DownloadTracker"
;
private
final
Context
context
;
private
final
Context
context
;
private
final
DataSource
.
Factory
d
ataSourceFactory
;
private
final
HttpDataSource
.
Factory
httpD
ataSourceFactory
;
private
final
CopyOnWriteArraySet
<
Listener
>
listeners
;
private
final
CopyOnWriteArraySet
<
Listener
>
listeners
;
private
final
HashMap
<
Uri
,
Download
>
downloads
;
private
final
HashMap
<
Uri
,
Download
>
downloads
;
private
final
DownloadIndex
downloadIndex
;
private
final
DownloadIndex
downloadIndex
;
...
@@ -64,9 +72,11 @@ public class DownloadTracker {
...
@@ -64,9 +72,11 @@ public class DownloadTracker {
@Nullable
private
StartDownloadDialogHelper
startDownloadDialogHelper
;
@Nullable
private
StartDownloadDialogHelper
startDownloadDialogHelper
;
public
DownloadTracker
(
public
DownloadTracker
(
Context
context
,
DataSource
.
Factory
dataSourceFactory
,
DownloadManager
downloadManager
)
{
Context
context
,
HttpDataSource
.
Factory
httpDataSourceFactory
,
DownloadManager
downloadManager
)
{
this
.
context
=
context
.
getApplicationContext
();
this
.
context
=
context
.
getApplicationContext
();
this
.
dataSourceFactory
=
d
ataSourceFactory
;
this
.
httpDataSourceFactory
=
httpD
ataSourceFactory
;
listeners
=
new
CopyOnWriteArraySet
<>();
listeners
=
new
CopyOnWriteArraySet
<>();
downloads
=
new
HashMap
<>();
downloads
=
new
HashMap
<>();
downloadIndex
=
downloadManager
.
getDownloadIndex
();
downloadIndex
=
downloadManager
.
getDownloadIndex
();
...
@@ -89,6 +99,7 @@ public class DownloadTracker {
...
@@ -89,6 +99,7 @@ public class DownloadTracker {
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
;
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
;
}
}
@Nullable
public
DownloadRequest
getDownloadRequest
(
Uri
uri
)
{
public
DownloadRequest
getDownloadRequest
(
Uri
uri
)
{
Download
download
=
downloads
.
get
(
uri
);
Download
download
=
downloads
.
get
(
uri
);
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
?
download
.
request
:
null
;
return
download
!=
null
&&
download
.
state
!=
Download
.
STATE_FAILED
?
download
.
request
:
null
;
...
@@ -107,7 +118,8 @@ public class DownloadTracker {
...
@@ -107,7 +118,8 @@ public class DownloadTracker {
startDownloadDialogHelper
=
startDownloadDialogHelper
=
new
StartDownloadDialogHelper
(
new
StartDownloadDialogHelper
(
fragmentManager
,
fragmentManager
,
DownloadHelper
.
forMediaItem
(
context
,
mediaItem
,
renderersFactory
,
dataSourceFactory
),
DownloadHelper
.
forMediaItem
(
context
,
mediaItem
,
renderersFactory
,
httpDataSourceFactory
),
mediaItem
);
mediaItem
);
}
}
}
}
...
@@ -157,6 +169,7 @@ public class DownloadTracker {
...
@@ -157,6 +169,7 @@ public class DownloadTracker {
private
TrackSelectionDialog
trackSelectionDialog
;
private
TrackSelectionDialog
trackSelectionDialog
;
private
MappedTrackInfo
mappedTrackInfo
;
private
MappedTrackInfo
mappedTrackInfo
;
@Nullable
private
byte
[]
keySetId
;
public
StartDownloadDialogHelper
(
public
StartDownloadDialogHelper
(
FragmentManager
fragmentManager
,
DownloadHelper
downloadHelper
,
MediaItem
mediaItem
)
{
FragmentManager
fragmentManager
,
DownloadHelper
downloadHelper
,
MediaItem
mediaItem
)
{
...
@@ -177,12 +190,43 @@ public class DownloadTracker {
...
@@ -177,12 +190,43 @@ public class DownloadTracker {
@Override
@Override
public
void
onPrepared
(
@NonNull
DownloadHelper
helper
)
{
public
void
onPrepared
(
@NonNull
DownloadHelper
helper
)
{
@Nullable
DrmInitData
drmInitData
=
findDrmInitData
(
helper
);
if
(
drmInitData
!=
null
)
{
if
(
Util
.
SDK_INT
<
18
)
{
Toast
.
makeText
(
context
,
R
.
string
.
error_drm_unsupported_before_api_18
,
Toast
.
LENGTH_LONG
)
.
show
();
Log
.
e
(
TAG
,
"Downloading DRM protected content is not supported on API versions below 18"
);
return
;
}
// TODO(internal b/163107948): Support cases where DrmInitData are not in the manifest.
if
(!
hasSchemaData
(
drmInitData
))
{
Toast
.
makeText
(
context
,
R
.
string
.
download_start_error_offline_license
,
Toast
.
LENGTH_LONG
)
.
show
();
Log
.
e
(
TAG
,
"Downloading content where DRM scheme data is not located in the manifest is not"
+
" supported"
);
return
;
}
try
{
// TODO(internal b/163107948): Download the license on another thread to keep the UI
// thread unblocked.
fetchOfflineLicense
(
drmInitData
);
}
catch
(
DrmSession
.
DrmSessionException
e
)
{
Toast
.
makeText
(
context
,
R
.
string
.
download_start_error_offline_license
,
Toast
.
LENGTH_LONG
)
.
show
();
Log
.
e
(
TAG
,
"Failed to fetch offline DRM license"
,
e
);
return
;
}
}
if
(
helper
.
getPeriodCount
()
==
0
)
{
if
(
helper
.
getPeriodCount
()
==
0
)
{
Log
.
d
(
TAG
,
"No periods found. Downloading entire stream."
);
Log
.
d
(
TAG
,
"No periods found. Downloading entire stream."
);
startDownload
();
startDownload
();
downloadHelper
.
release
();
downloadHelper
.
release
();
return
;
return
;
}
}
mappedTrackInfo
=
downloadHelper
.
getMappedTrackInfo
(
/* periodIndex= */
0
);
mappedTrackInfo
=
downloadHelper
.
getMappedTrackInfo
(
/* periodIndex= */
0
);
if
(!
TrackSelectionDialog
.
willHaveContent
(
mappedTrackInfo
))
{
if
(!
TrackSelectionDialog
.
willHaveContent
(
mappedTrackInfo
))
{
Log
.
d
(
TAG
,
"No dialog content. Downloading entire stream."
);
Log
.
d
(
TAG
,
"No dialog content. Downloading entire stream."
);
...
@@ -257,8 +301,59 @@ public class DownloadTracker {
...
@@ -257,8 +301,59 @@ public class DownloadTracker {
}
}
private
DownloadRequest
buildDownloadRequest
()
{
private
DownloadRequest
buildDownloadRequest
()
{
return
downloadHelper
.
getDownloadRequest
(
return
downloadHelper
Util
.
getUtf8Bytes
(
checkNotNull
(
mediaItem
.
mediaMetadata
.
title
)));
.
getDownloadRequest
(
Util
.
getUtf8Bytes
(
checkNotNull
(
mediaItem
.
mediaMetadata
.
title
)))
.
copyWithKeySetId
(
keySetId
);
}
@RequiresApi
(
18
)
private
void
fetchOfflineLicense
(
DrmInitData
drmInitData
)
throws
DrmSession
.
DrmSessionException
{
OfflineLicenseHelper
offlineLicenseHelper
=
OfflineLicenseHelper
.
newWidevineInstance
(
mediaItem
.
playbackProperties
.
drmConfiguration
.
licenseUri
.
toString
(),
httpDataSourceFactory
,
new
DrmSessionEventListener
.
EventDispatcher
());
keySetId
=
offlineLicenseHelper
.
downloadLicense
(
drmInitData
);
}
}
/**
* Returns whether any the {@link DrmInitData.SchemeData} contained in {@code drmInitData} has
* non-null {@link DrmInitData.SchemeData#data}.
*/
private
static
boolean
hasSchemaData
(
DrmInitData
drmInitData
)
{
for
(
int
i
=
0
;
i
<
drmInitData
.
schemeDataCount
;
i
++)
{
if
(
drmInitData
.
get
(
i
).
hasData
())
{
return
true
;
}
}
return
false
;
}
/**
* Returns the first non-null {@link DrmInitData} found in the content's tracks, or null if no
* {@link DrmInitData} are found.
*/
@Nullable
private
DrmInitData
findDrmInitData
(
DownloadHelper
helper
)
{
for
(
int
periodIndex
=
0
;
periodIndex
<
helper
.
getPeriodCount
();
periodIndex
++)
{
MappedTrackInfo
mappedTrackInfo
=
helper
.
getMappedTrackInfo
(
periodIndex
);
for
(
int
rendererIndex
=
0
;
rendererIndex
<
mappedTrackInfo
.
getRendererCount
();
rendererIndex
++)
{
TrackGroupArray
trackGroups
=
mappedTrackInfo
.
getTrackGroups
(
rendererIndex
);
for
(
int
trackGroupIndex
=
0
;
trackGroupIndex
<
trackGroups
.
length
;
trackGroupIndex
++)
{
TrackGroup
trackGroup
=
trackGroups
.
get
(
trackGroupIndex
);
for
(
int
formatIndex
=
0
;
formatIndex
<
trackGroup
.
length
;
formatIndex
++)
{
Format
format
=
trackGroup
.
getFormat
(
formatIndex
);
if
(
format
.
drmInitData
!=
null
)
{
return
format
.
drmInitData
;
}
}
}
}
}
}
return
null
;
}
}
}
}
demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java
View file @
a5e6e305
...
@@ -112,7 +112,7 @@ public class PlayerActivity extends AppCompatActivity
...
@@ -112,7 +112,7 @@ public class PlayerActivity extends AppCompatActivity
public
void
onCreate
(
Bundle
savedInstanceState
)
{
public
void
onCreate
(
Bundle
savedInstanceState
)
{
Intent
intent
=
getIntent
();
Intent
intent
=
getIntent
();
super
.
onCreate
(
savedInstanceState
);
super
.
onCreate
(
savedInstanceState
);
dataSourceFactory
=
buildDataSourceFactory
(
);
dataSourceFactory
=
DemoUtil
.
getDataSourceFactory
(
/* context= */
this
);
if
(
CookieHandler
.
getDefault
()
!=
DEFAULT_COOKIE_MANAGER
)
{
if
(
CookieHandler
.
getDefault
()
!=
DEFAULT_COOKIE_MANAGER
)
{
CookieHandler
.
setDefault
(
DEFAULT_COOKIE_MANAGER
);
CookieHandler
.
setDefault
(
DEFAULT_COOKIE_MANAGER
);
}
}
...
@@ -405,11 +405,6 @@ public class PlayerActivity extends AppCompatActivity
...
@@ -405,11 +405,6 @@ public class PlayerActivity extends AppCompatActivity
startPosition
=
C
.
TIME_UNSET
;
startPosition
=
C
.
TIME_UNSET
;
}
}
/** Returns a new DataSource factory. */
protected
DataSource
.
Factory
buildDataSourceFactory
()
{
return
DemoUtil
.
buildDataSourceFactory
(
/* context= */
this
);
}
// User controls
// User controls
private
void
updateButtonVisibility
()
{
private
void
updateButtonVisibility
()
{
...
...
demos/main/src/main/java/com/google/android/exoplayer2/demo/SampleChooserActivity.java
View file @
a5e6e305
...
@@ -253,9 +253,6 @@ public class SampleChooserActivity extends AppCompatActivity
...
@@ -253,9 +253,6 @@ public class SampleChooserActivity extends AppCompatActivity
}
}
MediaItem
.
PlaybackProperties
playbackProperties
=
MediaItem
.
PlaybackProperties
playbackProperties
=
checkNotNull
(
playlistHolder
.
mediaItems
.
get
(
0
).
playbackProperties
);
checkNotNull
(
playlistHolder
.
mediaItems
.
get
(
0
).
playbackProperties
);
if
(
playbackProperties
.
drmConfiguration
!=
null
)
{
return
R
.
string
.
download_drm_unsupported
;
}
if
(((
IntentUtil
.
Tag
)
checkNotNull
(
playbackProperties
.
tag
)).
isLive
)
{
if
(((
IntentUtil
.
Tag
)
checkNotNull
(
playbackProperties
.
tag
)).
isLive
)
{
return
R
.
string
.
download_live_unsupported
;
return
R
.
string
.
download_live_unsupported
;
}
}
...
...
demos/main/src/main/res/values/strings.xml
View file @
a5e6e305
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
<string
name=
"error_unrecognized_stereo_mode"
>
Unrecognized stereo mode
</string>
<string
name=
"error_unrecognized_stereo_mode"
>
Unrecognized stereo mode
</string>
<string
name=
"error_drm_unsupported_before_api_18"
>
Protected
content not supported on API levels below 18
</string>
<string
name=
"error_drm_unsupported_before_api_18"
>
DRM
content not supported on API levels below 18
</string>
<string
name=
"error_drm_unsupported_scheme"
>
This device does not support the required DRM scheme
</string>
<string
name=
"error_drm_unsupported_scheme"
>
This device does not support the required DRM scheme
</string>
...
@@ -55,9 +55,9 @@
...
@@ -55,9 +55,9 @@
<string
name=
"download_start_error"
>
Failed to start download
</string>
<string
name=
"download_start_error"
>
Failed to start download
</string>
<string
name=
"download_
playlist_unsupported"
>
This demo app does not support downloading playlists
</string>
<string
name=
"download_
start_error_offline_license"
>
Failed to obtain offline license
</string>
<string
name=
"download_
drm_unsupported"
>
This demo app does not support downloading protected content
</string>
<string
name=
"download_
playlist_unsupported"
>
This demo app does not support downloading playlists
</string>
<string
name=
"download_scheme_unsupported"
>
This demo app only supports downloading http streams
</string>
<string
name=
"download_scheme_unsupported"
>
This demo app only supports downloading http streams
</string>
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadHelper.java
View file @
a5e6e305
...
@@ -743,13 +743,17 @@ public final class DownloadHelper {
...
@@ -743,13 +743,17 @@ public final class DownloadHelper {
* @return The built {@link DownloadRequest}.
* @return The built {@link DownloadRequest}.
*/
*/
public
DownloadRequest
getDownloadRequest
(
String
id
,
@Nullable
byte
[]
data
)
{
public
DownloadRequest
getDownloadRequest
(
String
id
,
@Nullable
byte
[]
data
)
{
if
(
mediaSource
==
null
)
{
DownloadRequest
.
Builder
requestBuilder
=
// TODO: add support for DRM (keySetId) [Internal ref: b/158980798]
new
DownloadRequest
.
Builder
(
id
,
playbackProperties
.
uri
)
return
new
DownloadRequest
.
Builder
(
id
,
playbackProperties
.
uri
)
.
setMimeType
(
playbackProperties
.
mimeType
)
.
setMimeType
(
playbackProperties
.
mimeType
)
.
setKeySetId
(
playbackProperties
.
drmConfiguration
!=
null
?
playbackProperties
.
drmConfiguration
.
getKeySetId
()
:
null
)
.
setCustomCacheKey
(
playbackProperties
.
customCacheKey
)
.
setCustomCacheKey
(
playbackProperties
.
customCacheKey
)
.
setData
(
data
)
.
setData
(
data
);
.
build
();
if
(
mediaSource
==
null
)
{
return
requestBuilder
.
build
();
}
}
assertPreparedWithMedia
();
assertPreparedWithMedia
();
List
<
StreamKey
>
streamKeys
=
new
ArrayList
<>();
List
<
StreamKey
>
streamKeys
=
new
ArrayList
<>();
...
@@ -763,13 +767,7 @@ public final class DownloadHelper {
...
@@ -763,13 +767,7 @@ public final class DownloadHelper {
}
}
streamKeys
.
addAll
(
mediaPreparer
.
mediaPeriods
[
periodIndex
].
getStreamKeys
(
allSelections
));
streamKeys
.
addAll
(
mediaPreparer
.
mediaPeriods
[
periodIndex
].
getStreamKeys
(
allSelections
));
}
}
// TODO: add support for DRM (keySetId) [Internal ref: b/158980798]
return
requestBuilder
.
setStreamKeys
(
streamKeys
).
build
();
return
new
DownloadRequest
.
Builder
(
id
,
playbackProperties
.
uri
)
.
setMimeType
(
playbackProperties
.
mimeType
)
.
setStreamKeys
(
streamKeys
)
.
setCustomCacheKey
(
playbackProperties
.
customCacheKey
)
.
setData
(
data
)
.
build
();
}
}
// Initialization of array of Lists.
// Initialization of array of Lists.
...
...
library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadRequest.java
View file @
a5e6e305
...
@@ -175,6 +175,16 @@ public final class DownloadRequest implements Parcelable {
...
@@ -175,6 +175,16 @@ public final class DownloadRequest implements Parcelable {
}
}
/**
/**
* Returns a copy with the specified key set ID.
*
* @param keySetId The key set ID of the copy.
* @return The copy with the specified key set ID.
*/
public
DownloadRequest
copyWithKeySetId
(
@Nullable
byte
[]
keySetId
)
{
return
new
DownloadRequest
(
id
,
uri
,
mimeType
,
streamKeys
,
keySetId
,
customCacheKey
,
data
);
}
/**
* Returns the result of merging {@code newRequest} into this request. The requests must have the
* Returns the result of merging {@code newRequest} into this request. The requests must have the
* same {@link #id}.
* same {@link #id}.
*
*
...
...
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