diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3394214225..ad88f3b24e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,14 +4,18 @@ * Add Java FLAC extractor ([#6406](https://github.com/google/ExoPlayer/issues/6406)). +* Downloads: + * Merge downloads in `SegmentDownloader` to improve overall download + speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)). + * Fix download resumption when the requirements for them to continue are + met ([#6733](https://github.com/google/ExoPlayer/issues/6733), + [#6798](https://github.com/google/ExoPlayer/issues/6798)). + * Fix `DownloadHelper.createMediaSource` to use `customCacheKey` when creating + `ProgressiveMediaSource` instances. * Update `IcyDecoder` to try ISO-8859-1 decoding if UTF-8 decoding fails. Also change `IcyInfo.rawMetadata` from `String` to `byte[]` to allow developers to handle data that's neither UTF-8 nor ISO-8859-1 ([#6753](https://github.com/google/ExoPlayer/issues/6753)). -* Fix handling of network transitions in `RequirementsWatcher` - ([#6733](https://github.com/google/ExoPlayer/issues/6733)). Incorrect handling - could previously cause downloads to be paused when they should have been able - to proceed. * Fix handling of E-AC-3 streams that contain AC-3 syncframes ([#6602](https://github.com/google/ExoPlayer/issues/6602)). * Fix playback of TrueHD streams in Matroska diff --git a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java index c8975275f1..8841f8355f 100644 --- a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java +++ b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java @@ -76,8 +76,8 @@ public final class JobDispatcherScheduler implements Scheduler { * {@link #schedule(Requirements, String, String)} or {@link #cancel()} are called. */ public JobDispatcherScheduler(Context context, String jobTag) { - this.jobDispatcher = - new FirebaseJobDispatcher(new GooglePlayDriver(context.getApplicationContext())); + context = context.getApplicationContext(); + this.jobDispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context)); this.jobTag = jobTag; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java index 5fad4ad2e1..7d1ec48b64 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/offline/DownloadService.java @@ -578,13 +578,13 @@ public abstract class DownloadService extends Service { NotificationUtil.IMPORTANCE_LOW); } Class extends DownloadService> clazz = getClass(); - DownloadManagerHelper downloadManagerHelper = downloadManagerHelpers.get(clazz); + @Nullable DownloadManagerHelper downloadManagerHelper = downloadManagerHelpers.get(clazz); if (downloadManagerHelper == null) { + @Nullable Scheduler scheduler = foregroundNotificationUpdater == null ? null : getScheduler(); downloadManager = getDownloadManager(); downloadManager.resumeDownloads(); downloadManagerHelper = - new DownloadManagerHelper( - getApplicationContext(), downloadManager, getScheduler(), clazz); + new DownloadManagerHelper(getApplicationContext(), downloadManager, scheduler, clazz); downloadManagerHelpers.put(clazz, downloadManagerHelper); } else { downloadManager = downloadManagerHelper.downloadManager; @@ -600,9 +600,9 @@ public abstract class DownloadService extends Service { @Nullable String contentId = null; if (intent != null) { intentAction = intent.getAction(); + contentId = intent.getStringExtra(KEY_CONTENT_ID); startedInForeground |= intent.getBooleanExtra(KEY_FOREGROUND, false) || ACTION_RESTART.equals(intentAction); - contentId = intent.getStringExtra(KEY_CONTENT_ID); } // intentAction is null if the service is restarted or no action is specified. if (intentAction == null) { @@ -660,6 +660,10 @@ public abstract class DownloadService extends Service { break; } + if (Util.SDK_INT >= 26 && startedInForeground && foregroundNotificationUpdater != null) { + // From API level 26, services started in the foreground are required to show a notification. + foregroundNotificationUpdater.showNotificationIfNotAlready(); + } if (downloadManager.isIdle()) { stop(); } @@ -701,21 +705,21 @@ public abstract class DownloadService extends Service { * Returns a {@link Scheduler} to restart the service when requirements allowing downloads to take * place are met. If {@code null}, the service will only be restarted if the process is still in * memory when the requirements are met. + * + *
This method is not called for services whose {@code foregroundNotificationId} is set to + * {@link #FOREGROUND_NOTIFICATION_ID_NONE}. Such services will only be restarted if the process + * is still in memory and considered non-idle, meaning that it's either in the foreground or was + * backgrounded within the last few minutes. */ - protected abstract @Nullable Scheduler getScheduler(); + @Nullable + protected abstract Scheduler getScheduler(); /** - * Returns a notification to be displayed when this service running in the foreground. This method - * is called when there is a download state change and periodically while there are active - * downloads. The periodic update interval can be set using {@link #DownloadService(int, long)}. - * - *
On API level 26 and above, this method may also be called just before the service stops, - * with an empty {@code downloads} array. The returned notification is used to satisfy system - * requirements for foreground services. + * Returns a notification to be displayed when this service running in the foreground. * *
Download services that do not wish to run in the foreground should be created by setting the
* {@code foregroundNotificationId} constructor argument to {@link
- * #FOREGROUND_NOTIFICATION_ID_NONE}. This method will not be called in this case, meaning it can
+ * #FOREGROUND_NOTIFICATION_ID_NONE}. This method is not called for such services, meaning it can
* be implemented to throw {@link UnsupportedOperationException}.
*
* @param downloads The current downloads.
@@ -754,13 +758,32 @@ public abstract class DownloadService extends Service {
// Do nothing.
}
+ /**
+ * Called after the service is created, once the downloads are known.
+ *
+ * @param downloads The current downloads.
+ */
+ private void notifyDownloads(List