ExoPlayer: Crash: DownloadManager Assertion fails for STATE_DOWNLOADING

Issue description

In our project, we currently see a crash in the exoplayer DownloadManager, when starting the download of a Podcast Episode. Let me give you the crash snippet and my suspicions first, more details below

Fatal Exception: java.lang.NullPointerException
       at com.google.android.exoplayer2.util.Assertions.checkNotNull(Assertions.java:5)
       at com.google.android.exoplayer2.offline.DownloadManager$InternalHandler.syncTasks(DownloadManager.java:57)
       at com.google.android.exoplayer2.offline.DownloadManager$InternalHandler.initialize(DownloadManager.java:83)
       at com.google.android.exoplayer2.offline.DownloadManager$InternalHandler.handleMessage(DownloadManager.java:98)
       at android.os.Handler.dispatchMessage(Handler.java:108)
       at android.os.Looper.loop(Looper.java:166)
       at android.os.HandlerThread.run(HandlerThread.java:65)

After accounting for Proguard, that’s this line: grafik

It is very hard to reproduce and does not happen often. At the moment I suspect a threading issue, I suspect that the two variables…

private final ArrayList<Download> downloads;
private final HashMap<String, Task> activeTasks;

… need to be declared volatile. Why? Because I managed to write a bit of reflection code that accesses those variables when the crash occurs, and today the Google Play Pre-Lanch report encountered the crash and it printed: did it work?? -> downloads=[[]], activeTasks=[{}] But how could the downloads list be empty? This crash happens inside a loop that iterates over that very list.

Reproduction steps

Still working on reproduction steps. We have about 10 users and this happens about once per week. I will update this ticket as soon as I can This is a video from the pre-launch report: https://drive.google.com/file/d/1rPwRBqij7BKr6JPspsy7XLcjQNBWQC-M/view?usp=sharing As you can see the crash happens immediately upon clicking the download button (so when adding a new download). And it also appears to me like the click on download happens almost exactly when another download is finished (which could explain the empty download and activeTasks lists that I saw above)

Link to test content

Still working on test content. At the moment it seems this can happen with any URL that is downloaded

A full bug report captured from the device

I have not been able to get my hand on a device right after it happened. In the beginning we saw it once or twice on a developer phone but did not consider it important and failed to give it any attention. But this ticket is now my main focus and as I said above I will update this page with any details I’ll find, hopefully a bug report soon. For now I can only attach the full logcat of the Pre-Launch Report. The crash happens at 10-04 07:31:49.632, the UnsupportedOperationException is the one I throw to hint that the UncaughtExceptionHandler from the snippet linked above has caught the error logcat.txt

Version of ExoPlayer being used

Seen in: 2.10.4, 2.10.7, 2.11.1

Device(s) and version(s) of Android being used

Huawei Mate 10 Lite, Android 8.0 Google Pixel 3, Android 10 Google Pixel 2, Android 9 Google Pixel, Android 7.1 in Pre-Launch Report Emulator

More Code

This is how I start the download

DownloadRequest request = new DownloadRequest(downloadData.getId(), DownloadRequest.TYPE_PROGRESSIVE, playlistData.getUri(), Collections.emptyList(), null, ByteArrayUtil.toCustomDownloadArray(downloadData));
DownloadService.sendAddDownload(mContext, EpisodeDownloadService.class, request, true);

This is my DownloadManager Implementation

@Provides
@FeatureScope
DownloadManager provideDownloadManager(DownloadTracker tracker, Cache cache, DataSource.Factory factory,
        DatabaseProvider databaseProvider, PreferenceDomain preferences) {
    DownloadManager downloadManager = new DownloadManager(mAppContext, databaseProvider, cache, factory);
    downloadManager.addListener(tracker);
    downloadManager.setRequirements(preferences.isMeteredDownloadAllowed() ? new Requirements(Requirements.NETWORK) : new Requirements(Requirements.NETWORK_UNMETERED));
    return downloadManager;
}

As I said I cannot reproduce it, or prove it in the demo app. Sorry for that. But I would be deeply grateful for any input and promise to update with more info as best I can, I hope you can see from my efforts above that I wish I could do more than just dump a stacktrace here and ask for your help

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 16 (6 by maintainers)

Most upvoted comments

Hi Team, hi @google-oss-bot 😉 Here’s my long-overdue update on this. The fix has been released for about a month now, and I have not seen the crash even once since then. I will therefore conclude that this bug is indeed caused by multiple DownloadManagers existing and accessing the same resources at the same time

For anybody else coming across this I can only recommend

  • check instance creation for DownloadManager, DownloadService and the like
  • check dependency injections setup if you have it, remember that @Singleton will do nothing for you if you have multiple modules or variable scopes, because each of which will get a “singleton” object for ITS respective needs
  • Check my first post for some advice on logging, maybe extend that log by a hash of the instances you’re monitoring

@christosts thank you so much

I would like to just inform that I’m also facing this problem. Occasionally I’m getting exactly the same crash.

Just letting you know that I read your answers with gratitude and am thoroughly investigating in the meantime, please don’t take my silence as ignoring this, I’m just not the fastest coder 😄