Download offline DRM license from non-UI thread

PiperOrigin-RevId: 328904901
This commit is contained in:
christosts 2020-08-28 10:27:15 +01:00 committed by Oliver Woodman
parent e1c3da2a74
commit 603dcf4978

View File

@ -16,10 +16,12 @@
package com.google.android.exoplayer2.demo; package com.google.android.exoplayer2.demo;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -170,6 +172,7 @@ public class DownloadTracker {
private TrackSelectionDialog trackSelectionDialog; private TrackSelectionDialog trackSelectionDialog;
private MappedTrackInfo mappedTrackInfo; private MappedTrackInfo mappedTrackInfo;
private WidevineOfflineLicenseFetchTask widevineOfflineLicenseFetchTask;
@Nullable private byte[] keySetId; @Nullable private byte[] keySetId;
public StartDownloadDialogHelper( public StartDownloadDialogHelper(
@ -185,6 +188,9 @@ public class DownloadTracker {
if (trackSelectionDialog != null) { if (trackSelectionDialog != null) {
trackSelectionDialog.dismiss(); trackSelectionDialog.dismiss();
} }
if (widevineOfflineLicenseFetchTask != null) {
widevineOfflineLicenseFetchTask.cancel(false);
}
} }
// DownloadHelper.Callback implementation. // DownloadHelper.Callback implementation.
@ -192,7 +198,12 @@ public class DownloadTracker {
@Override @Override
public void onPrepared(@NonNull DownloadHelper helper) { public void onPrepared(@NonNull DownloadHelper helper) {
@Nullable Format format = getFirstFormatWithDrmInitData(helper); @Nullable Format format = getFirstFormatWithDrmInitData(helper);
if (format != null) { if (format == null) {
onDownloadPrepared(helper);
return;
}
// The content is DRM protected. We need to acquire an offline license.
if (Util.SDK_INT < 18) { if (Util.SDK_INT < 18) {
Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG) Toast.makeText(context, R.string.error_drm_unsupported_before_api_18, Toast.LENGTH_LONG)
.show(); .show();
@ -209,42 +220,10 @@ public class DownloadTracker {
+ " supported"); + " supported");
return; return;
} }
try { widevineOfflineLicenseFetchTask =
// TODO(internal b/163107948): Download the license on another thread to keep the UI new WidevineOfflineLicenseFetchTask(
// thread unblocked. format, mediaItem.playbackProperties.drmConfiguration.licenseUri, this, helper);
fetchOfflineLicense(format); widevineOfflineLicenseFetchTask.execute();
} 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) {
Log.d(TAG, "No periods found. Downloading entire stream.");
startDownload();
downloadHelper.release();
return;
}
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
if (!TrackSelectionDialog.willHaveContent(mappedTrackInfo)) {
Log.d(TAG, "No dialog content. Downloading entire stream.");
startDownload();
downloadHelper.release();
return;
}
trackSelectionDialog =
TrackSelectionDialog.createForMappedTrackInfoAndParameters(
/* titleId= */ R.string.exo_download_description,
mappedTrackInfo,
trackSelectorParameters,
/* allowAdaptiveSelections =*/ false,
/* allowMultipleOverrides= */ true,
/* onClickListener= */ this,
/* onDismissListener= */ this);
trackSelectionDialog.show(fragmentManager, /* tag= */ null);
} }
@Override @Override
@ -292,6 +271,44 @@ public class DownloadTracker {
// Internal methods. // Internal methods.
private void onOfflineLicenseFetched(DownloadHelper helper, byte[] keySetId) {
this.keySetId = keySetId;
onDownloadPrepared(helper);
}
private void onOfflineLicenseFetchedError(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);
}
private void onDownloadPrepared(DownloadHelper helper) {
if (helper.getPeriodCount() == 0) {
Log.d(TAG, "No periods found. Downloading entire stream.");
startDownload();
downloadHelper.release();
return;
}
mappedTrackInfo = downloadHelper.getMappedTrackInfo(/* periodIndex= */ 0);
if (!TrackSelectionDialog.willHaveContent(mappedTrackInfo)) {
Log.d(TAG, "No dialog content. Downloading entire stream.");
startDownload();
downloadHelper.release();
return;
}
trackSelectionDialog =
TrackSelectionDialog.createForMappedTrackInfoAndParameters(
/* titleId= */ R.string.exo_download_description,
mappedTrackInfo,
trackSelectorParameters,
/* allowAdaptiveSelections =*/ false,
/* allowMultipleOverrides= */ true,
/* onClickListener= */ this,
/* onDismissListener= */ this);
trackSelectionDialog.show(fragmentManager, /* tag= */ null);
}
private void startDownload() { private void startDownload() {
startDownload(buildDownloadRequest()); startDownload(buildDownloadRequest());
} }
@ -306,15 +323,54 @@ public class DownloadTracker {
.getDownloadRequest(Util.getUtf8Bytes(checkNotNull(mediaItem.mediaMetadata.title))) .getDownloadRequest(Util.getUtf8Bytes(checkNotNull(mediaItem.mediaMetadata.title)))
.copyWithKeySetId(keySetId); .copyWithKeySetId(keySetId);
} }
}
/** Downloads a Widevine offline license in a background thread. */
@RequiresApi(18) @RequiresApi(18)
private void fetchOfflineLicense(Format format) throws DrmSession.DrmSessionException { private final class WidevineOfflineLicenseFetchTask extends AsyncTask<Void, Void, Void> {
private final Format format;
private final Uri licenseUri;
private final StartDownloadDialogHelper dialogHelper;
private final DownloadHelper downloadHelper;
@Nullable private byte[] keySetId;
@Nullable private DrmSession.DrmSessionException drmSessionException;
public WidevineOfflineLicenseFetchTask(
Format format,
Uri licenseUri,
StartDownloadDialogHelper dialogHelper,
DownloadHelper downloadHelper) {
this.format = format;
this.licenseUri = licenseUri;
this.dialogHelper = dialogHelper;
this.downloadHelper = downloadHelper;
}
@Override
protected Void doInBackground(Void... voids) {
OfflineLicenseHelper offlineLicenseHelper = OfflineLicenseHelper offlineLicenseHelper =
OfflineLicenseHelper.newWidevineInstance( OfflineLicenseHelper.newWidevineInstance(
mediaItem.playbackProperties.drmConfiguration.licenseUri.toString(), licenseUri.toString(),
httpDataSourceFactory, httpDataSourceFactory,
new DrmSessionEventListener.EventDispatcher()); new DrmSessionEventListener.EventDispatcher());
try {
keySetId = offlineLicenseHelper.downloadLicense(format); keySetId = offlineLicenseHelper.downloadLicense(format);
} catch (DrmSession.DrmSessionException e) {
drmSessionException = e;
} finally {
offlineLicenseHelper.release();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if (drmSessionException != null) {
dialogHelper.onOfflineLicenseFetchedError(drmSessionException);
} else {
dialogHelper.onOfflineLicenseFetched(downloadHelper, checkStateNotNull(keySetId));
}
} }
} }