google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.72k stars 6.03k forks source link

[demo app] Ongoing downloads not resumed after reboot #10903

Open nikitamarysolomanpvt opened 1 year ago

nikitamarysolomanpvt commented 1 year ago

ExoPlayer Version

2.18.2

Devices that reproduce the issue

I posted it here https://github.com/google/ExoPlayer/issues/8645#issuecomment-1369657451 after which, I checked on your demo app RECEIVE_BOOT_COMPLETED is not working/ once we restart mobile downloads wont resume. In my app i noticed this issue (the downloads dont resume in it unless we open the app again)am using https://exoplayer.dev/downloading-media.html but still its not working on device reboot. Is there a way i could get logs when on action.BOOT_COMPLETED? could we get some logs or to test this?. Also i want to listen to this, show notification of download progress and check that iam connected to a specific server. I want to make sure with less user intervention once requested for download it should complete when connected.

Devices that do not reproduce the issue

checked on OPPO A74 5G Model CPH2263. Android 12

Reproducible in the demo app?

Yes

Reproduction steps

In demo app (com.google.android.exoplayer2.demo)

  1. Download multiple files ->it will show download progress in notification.
  2. restart mobile
  3. download not restarted

Expected result

the download should resume

Actual result

no download progress notification displayed, download not resumed

Media

I cannot record it as it happening when mobile restarted.

Bug Report

yoobi commented 1 year ago

As an additional comment, I'm getting report from Crashlytics, I've tried to reproduce this crash but didn't succeed.

Fatal Exception: java.lang.IllegalArgumentException: Error: requested job be persisted without holding RECEIVE_BOOT_COMPLETED permission.
       at android.os.Parcel.createException(Parcel.java:2078)
       at android.os.Parcel.readException(Parcel.java:2042)
       at android.os.Parcel.readException(Parcel.java:1990)
       at android.app.job.IJobScheduler$Stub$Proxy.schedule(IJobScheduler.java:308)
       at android.app.JobSchedulerImpl.schedule(JobSchedulerImpl.java:43)
       at com.google.android.exoplayer2.scheduler.PlatformScheduler.b(PlatformScheduler.java:197)
       at com.google.android.exoplayer2.offline.DownloadService$DownloadManagerHelper.j(DownloadService.java:85)
       at com.google.android.exoplayer2.offline.DownloadService.g(DownloadService.java:28)
       at com.google.android.exoplayer2.offline.DownloadService$DownloadManagerHelper.e(DownloadService.java:10)
       at y4.DownloadManager$$ExternalSyntheticLambda0.handleMessage(R8$$SyntheticClass:193)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:223)
       at android.app.ActivityThread.main(ActivityThread.java:7562)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

Below my AndroidManifest.

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<service android:name="com.my.app.service.LocalExoplayerDownloadService" android:exported="false">
    <!-- This is needed for Scheduler -->
    <intent-filter>
        <action android:name="com.google.android.exoplayer.downloadService.action.RESTART"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</service>
<service android:name="com.google.android.exoplayer2.scheduler.PlatformScheduler$PlatformSchedulerService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="true"/>

Tell me if it's a separate issue and I'll create a new one

marcbaechinger commented 1 year ago

@nikitamarysolomanpvt

I think resuming a download that was ongoing while the device is rebooted is not supposed to work with the demo app.

I assume your expectation is coming from the demo app having a permission for RECEIVE_BOOT_COMPLETED in the manifest. As far as I understand this permission is required to persist a job to resume downloads when a certain requirement is meet after downloads having been paused. This is not to restart ongoing downloads when the device is rebooted.

Additionally, on Android 12 and above the scheduler is not used at all because it is not allowed to start a foreground service from the background. Please see the JavaDoc of DownloadService.getScheduler() for more details.

As far as I can tell, the only thing that can work is starting the service from a broadcast receiver that receives a BOOT_COMPLETED intent action. This worked for me when adding a content receiver to the AndroidManifest.xml:

<application>
   <receiver android:name=".BootCompletedReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
      </intent-filter>
    </receiver>
</application>
public class BootCompletedReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
      Log.d("boot-comp", "starting download service in foreground after boot");
      DownloadService.startForeground(context, DemoDownloadService.class);
    }
  }
}

The above works because such an intent received with a BroadcastReceveiver is exempted from the foreground service start restriction. The service is then started in the foreground and in case there are pending downloads, these are processed. It comes with the extra cost of the service being briefly started at boot even when no downloads are available. I don't see another way to achieve this though.

@yoobi Please open a new issue. Probably difficult to help but if you do, please add some Android version info where the reports are coming from.