Skip to content

Commit

Permalink
Declare foreground service type for DownloadService
Browse files Browse the repository at this point in the history
This ensures the DownloadService stays functional on Android 14
where defining this type is required. On Android 14 and above,
the app also needs to define the DATA_SYNC permission, which is
added to the demo app as well. In the future, this service type
will no longer be supported and DownloadService needs to be
rewritten with another background scheduling framework.

Issue: #11239
PiperOrigin-RevId: 548994842
  • Loading branch information
tonihei authored and icbaker committed Jul 20, 2023
1 parent aa2313d commit cf0ccf1
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
4 changes: 3 additions & 1 deletion demos/main/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<uses-feature android:name="android.software.leanback" android:required="false"/>
Expand Down Expand Up @@ -94,7 +95,8 @@
</activity>

<service android:name=".DemoDownloadService"
android:exported="false">
android:exported="false"
android:foregroundServiceType="dataSync">
<intent-filter>
<action android:name="com.google.android.exoplayer.downloadService.action.RESTART"/>
<category android:name="android.intent.category.DEFAULT"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import android.Manifest.permission;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.Service;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
Expand Down Expand Up @@ -296,6 +298,35 @@ public static ComponentName startForegroundService(Context context, Intent inten
}
}

/**
* Sets the notification required for a foreground service.
*
* @param service The foreground {@link Service}.
* @param notificationId The notification id.
* @param notification The {@link Notification}.
* @param foregroundServiceType The foreground service type defined in {@link
* android.content.pm.ServiceInfo}.
* @param foregroundServiceManifestType The required foreground service type string for the {@code
* <service>} element in the manifest.
*/
public static void setForegroundServiceNotification(
Service service,
int notificationId,
Notification notification,
int foregroundServiceType,
String foregroundServiceManifestType) {
if (Util.SDK_INT >= 29) {
Api29.startForeground(
service,
notificationId,
notification,
foregroundServiceType,
foregroundServiceManifestType);
} else {
service.startForeground(notificationId, notification);
}
}

/**
* Checks whether it's necessary to request the {@link permission#READ_EXTERNAL_STORAGE}
* permission read the specified {@link Uri}s, requesting the permission if necessary.
Expand Down Expand Up @@ -3234,4 +3265,29 @@ public static Drawable getDrawable(Context context, Resources resources, @Drawab
return resources.getDrawable(res, context.getTheme());
}
}

@RequiresApi(29)
private static class Api29 {

@DoNotInline
public static void startForeground(
Service mediaSessionService,
int notificationId,
Notification notification,
int foregroundServiceType,
String foregroundServiceManifestType) {
try {
// startForeground() will throw if the service's foregroundServiceType is not defined.
mediaSessionService.startForeground(notificationId, notification, foregroundServiceType);
} catch (RuntimeException e) {
Log.e(
TAG,
"The service must be declared with a foregroundServiceType that includes "
+ foregroundServiceManifestType);
throw e;
}
}

private Api29() {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@

import static com.google.android.exoplayer2.offline.Download.STOP_REASON_NONE;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
Expand Down Expand Up @@ -915,14 +917,20 @@ public void invalidate() {
}
}

@SuppressLint("InlinedApi") // Using compile time constant FOREGROUND_SERVICE_TYPE_DATA_SYNC
private void update() {
DownloadManager downloadManager =
Assertions.checkNotNull(downloadManagerHelper).downloadManager;
List<Download> downloads = downloadManager.getCurrentDownloads();
@RequirementFlags int notMetRequirements = downloadManager.getNotMetRequirements();
Notification notification = getForegroundNotification(downloads, notMetRequirements);
if (!notificationDisplayed) {
startForeground(notificationId, notification);
Util.setForegroundServiceNotification(
/* service= */ DownloadService.this,
notificationId,
notification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC,
"dataSync");
notificationDisplayed = true;
} else {
// Update the notification via NotificationManager rather than by repeatedly calling
Expand Down

0 comments on commit cf0ccf1

Please sign in to comment.