Skip to content

Crash in OfflineLicenseHelper #10329

@utonautes

Description

@utonautes

ExoPlayer Version

2.17.1

Devices that reproduce the issue

Any. devices.

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

  1. In Widevine DASH (MP4, H264) -> HD (cenc) in media.exolist.json, modify the drm_license_uri to https://proxy.uat.widevine.com/1234567890proxy?video_id=2015_tears&provider=widevine_test to force to receive 404 not found error.
  2. Launch the demo app.
  3. Click the download button of Widevine DASH (MP4, H264) -> HD (cenc) in media.exolist.json.
  4. Do something (play other videos, seek video, download other media...)
  5. Repeat step 3 and 4.

Just call OfflineLicenseHelper.downloadLicense() many times at the same time.

Expected result

offline license failure

Actual result

The app crashes with an NPE rarely (under 5%).

2022-06-10 20:53:52.899 30707-31080/com.google.android.exoplayer2.demo E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #11
    Process: com.google.android.exoplayer2.demo, PID: 30707
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$4.done(AsyncTask.java:415)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
     Caused by: java.lang.NullPointerException
        at com.google.android.exoplayer2.util.Assertions.checkNotNull(Assertions.java:154)
        at com.google.android.exoplayer2.drm.OfflineLicenseHelper.blockingKeyRequest(OfflineLicenseHelper.java:277)
        at com.google.android.exoplayer2.drm.OfflineLicenseHelper.downloadLicense(OfflineLicenseHelper.java:193)
        at com.google.android.exoplayer2.demo.DownloadTracker$WidevineOfflineLicenseFetchTask.doInBackground(DownloadTracker.java:392)
        at com.google.android.exoplayer2.demo.DownloadTracker$WidevineOfflineLicenseFetchTask.doInBackground(DownloadTracker.java:357)
        at android.os.AsyncTask$3.call(AsyncTask.java:394)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:923) 

DefaultDrmSession.onError() changes its state after dispatching the error event and getError() returns null if the state is not STATE_ERROR.

  public final DrmSessionException getError() {
    return state == STATE_ERROR ? lastException : null;
  }

  private void onError(Exception e, @DrmUtil.ErrorSource int errorSource) {
    lastException =
        new DrmSessionException(e, DrmUtil.getErrorCodeForMediaDrmException(e, errorSource));
    Log.e(TAG, "DRM session error", e);
    dispatchEvent(eventDispatcher -> eventDispatcher.drmSessionManagerError(e));
    if (state != STATE_OPENED_WITH_KEYS) {
      state = STATE_ERROR;
    }
  }

In OfflineLicenseHelper.blockingKeyRequest(), both drmSession.getError() and drmSession.getOfflineKeySetId() returns null at the same time with a low probability.

    DrmSessionException error = drmSession.getError();
    byte[] keySetId = drmSession.getOfflineLicenseKeySetId();
    // error == null && keySetId == null

Media

Widevine DASH (MP4, H264) -> HD (cenc) , modify the widevine license URL.
(https://proxy.uat.widevine.com/pppppproxy?video_id=2015_tears&provider=widevine_test)

Bug Report

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions