mirror of
https://github.com/androidx/media.git
synced 2025-05-06 23:20:42 +08:00
Added storage not low as download requirement
Added monitoring storage levels in RequirementsWatcher Added dependency on extension-workmanager to the demo app to be able to test with WorkManagerScheduler Added getSupportedRequirements method to Scheduler interface Implemented getSupportedRequirements for schedulers
This commit is contained in:
parent
0de9c007af
commit
86b31e2954
@ -70,6 +70,7 @@ dependencies {
|
|||||||
implementation project(modulePrefix + 'library-hls')
|
implementation project(modulePrefix + 'library-hls')
|
||||||
implementation project(modulePrefix + 'library-smoothstreaming')
|
implementation project(modulePrefix + 'library-smoothstreaming')
|
||||||
implementation project(modulePrefix + 'library-ui')
|
implementation project(modulePrefix + 'library-ui')
|
||||||
|
withExtensionsImplementation project(path: modulePrefix + 'extension-workmanager')
|
||||||
withExtensionsImplementation project(path: modulePrefix + 'extension-av1')
|
withExtensionsImplementation project(path: modulePrefix + 'extension-av1')
|
||||||
withExtensionsImplementation project(path: modulePrefix + 'extension-ffmpeg')
|
withExtensionsImplementation project(path: modulePrefix + 'extension-ffmpeg')
|
||||||
withExtensionsImplementation project(path: modulePrefix + 'extension-flac')
|
withExtensionsImplementation project(path: modulePrefix + 'extension-flac')
|
||||||
|
@ -96,6 +96,19 @@ public final class JobDispatcherScheduler implements Scheduler {
|
|||||||
return result == FirebaseJobDispatcher.CANCEL_RESULT_SUCCESS;
|
return result == FirebaseJobDispatcher.CANCEL_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Requirements getSupportedRequirements(Requirements requirements) {
|
||||||
|
Requirements supportedRequirements = requirements;
|
||||||
|
if (requirements.isStorageNotLowRequired()) {
|
||||||
|
Log.w(TAG, "Storage not low requirement not supported on the JobDispatcherScheduler "
|
||||||
|
+ "Requirement removed.");
|
||||||
|
int newRequirements =
|
||||||
|
supportedRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW;
|
||||||
|
supportedRequirements = new Requirements(newRequirements);
|
||||||
|
}
|
||||||
|
return supportedRequirements;
|
||||||
|
}
|
||||||
|
|
||||||
private static Job buildJob(
|
private static Job buildJob(
|
||||||
FirebaseJobDispatcher dispatcher,
|
FirebaseJobDispatcher dispatcher,
|
||||||
Requirements requirements,
|
Requirements requirements,
|
||||||
|
@ -87,6 +87,12 @@ public final class WorkManagerScheduler implements Scheduler {
|
|||||||
|
|
||||||
if (requirements.isIdleRequired() && Util.SDK_INT >= 23) {
|
if (requirements.isIdleRequired() && Util.SDK_INT >= 23) {
|
||||||
setRequiresDeviceIdle(builder);
|
setRequiresDeviceIdle(builder);
|
||||||
|
} else if (requirements.isIdleRequired()) {
|
||||||
|
Log.w(TAG, "Is idle requirement is only available on API 23 and up.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requirements.isStorageNotLowRequired()) {
|
||||||
|
builder.setRequiresStorageNotLow(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
@ -108,6 +114,19 @@ public final class WorkManagerScheduler implements Scheduler {
|
|||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Requirements getSupportedRequirements(Requirements requirements) {
|
||||||
|
Requirements supportedRequirements = requirements;
|
||||||
|
if (requirements.isIdleRequired() && Util.SDK_INT < 23) {
|
||||||
|
Log.w(TAG, "Is idle requirement not supported on the WorkManagerScheduler on API below 23. "
|
||||||
|
+ "Requirement removed.");
|
||||||
|
int newRequirements =
|
||||||
|
supportedRequirements.getRequirements() ^ Requirements.DEVICE_IDLE;
|
||||||
|
supportedRequirements = new Requirements(newRequirements);
|
||||||
|
}
|
||||||
|
return supportedRequirements;
|
||||||
|
}
|
||||||
|
|
||||||
private static OneTimeWorkRequest buildWorkRequest(Constraints constraints, Data inputData) {
|
private static OneTimeWorkRequest buildWorkRequest(Constraints constraints, Data inputData) {
|
||||||
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SchedulerWorker.class);
|
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SchedulerWorker.class);
|
||||||
|
|
||||||
|
@ -658,6 +658,10 @@ public abstract class DownloadService extends Service {
|
|||||||
if (requirements == null) {
|
if (requirements == null) {
|
||||||
Log.e(TAG, "Ignored SET_REQUIREMENTS: Missing " + KEY_REQUIREMENTS + " extra");
|
Log.e(TAG, "Ignored SET_REQUIREMENTS: Missing " + KEY_REQUIREMENTS + " extra");
|
||||||
} else {
|
} else {
|
||||||
|
@Nullable Scheduler scheduler = getScheduler();
|
||||||
|
if (scheduler != null) {
|
||||||
|
requirements = scheduler.getSupportedRequirements(requirements);
|
||||||
|
}
|
||||||
downloadManager.setRequirements(requirements);
|
downloadManager.setRequirements(requirements);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -86,6 +86,21 @@ public final class PlatformScheduler implements Scheduler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Requirements getSupportedRequirements(Requirements requirements) {
|
||||||
|
Requirements supportedRequirements = requirements;
|
||||||
|
if (Util.SDK_INT < 26) {
|
||||||
|
if (requirements.isStorageNotLowRequired()) {
|
||||||
|
Log.w(TAG, "Storage not low requirement not supported on the PlatformScheduler"
|
||||||
|
+ "on API below 26. Requirement removed.");
|
||||||
|
int newRequirements =
|
||||||
|
supportedRequirements.getRequirements() ^ Requirements.DEVICE_STORAGE_NOT_LOW;
|
||||||
|
supportedRequirements = new Requirements(newRequirements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return supportedRequirements;
|
||||||
|
}
|
||||||
|
|
||||||
// @RequiresPermission constructor annotation should ensure the permission is present.
|
// @RequiresPermission constructor annotation should ensure the permission is present.
|
||||||
@SuppressWarnings("MissingPermission")
|
@SuppressWarnings("MissingPermission")
|
||||||
private static JobInfo buildJobInfo(
|
private static JobInfo buildJobInfo(
|
||||||
|
@ -45,7 +45,7 @@ public final class Requirements implements Parcelable {
|
|||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef(
|
@IntDef(
|
||||||
flag = true,
|
flag = true,
|
||||||
value = {NETWORK, NETWORK_UNMETERED, DEVICE_IDLE, DEVICE_CHARGING})
|
value = {NETWORK, NETWORK_UNMETERED, DEVICE_IDLE, DEVICE_CHARGING, DEVICE_STORAGE_NOT_LOW})
|
||||||
public @interface RequirementFlags {}
|
public @interface RequirementFlags {}
|
||||||
|
|
||||||
/** Requirement that the device has network connectivity. */
|
/** Requirement that the device has network connectivity. */
|
||||||
@ -56,6 +56,8 @@ public final class Requirements implements Parcelable {
|
|||||||
public static final int DEVICE_IDLE = 1 << 2;
|
public static final int DEVICE_IDLE = 1 << 2;
|
||||||
/** Requirement that the device is charging. */
|
/** Requirement that the device is charging. */
|
||||||
public static final int DEVICE_CHARGING = 1 << 3;
|
public static final int DEVICE_CHARGING = 1 << 3;
|
||||||
|
/** Requirement that the storage is not low. */
|
||||||
|
public static final int DEVICE_STORAGE_NOT_LOW = 1 << 4;
|
||||||
|
|
||||||
@RequirementFlags private final int requirements;
|
@RequirementFlags private final int requirements;
|
||||||
|
|
||||||
@ -94,6 +96,10 @@ public final class Requirements implements Parcelable {
|
|||||||
return (requirements & DEVICE_IDLE) != 0;
|
return (requirements & DEVICE_IDLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isStorageNotLowRequired() {
|
||||||
|
return (requirements & DEVICE_STORAGE_NOT_LOW) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the requirements are met.
|
* Returns whether the requirements are met.
|
||||||
*
|
*
|
||||||
@ -119,6 +125,9 @@ public final class Requirements implements Parcelable {
|
|||||||
if (isIdleRequired() && !isDeviceIdle(context)) {
|
if (isIdleRequired() && !isDeviceIdle(context)) {
|
||||||
notMetRequirements |= DEVICE_IDLE;
|
notMetRequirements |= DEVICE_IDLE;
|
||||||
}
|
}
|
||||||
|
if (isStorageNotLowRequired() && !isStorageNotLow(context)) {
|
||||||
|
notMetRequirements |= DEVICE_STORAGE_NOT_LOW;
|
||||||
|
}
|
||||||
return notMetRequirements;
|
return notMetRequirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +171,34 @@ public final class Requirements implements Parcelable {
|
|||||||
: Util.SDK_INT >= 20 ? !powerManager.isInteractive() : !powerManager.isScreenOn();
|
: Util.SDK_INT >= 20 ? !powerManager.isInteractive() : !powerManager.isScreenOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation taken from the the WorkManager source.
|
||||||
|
* @see <a href="https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager/src/main/java/androidx/work/impl/constraints/trackers/StorageNotLowTracker.java">StorageNotLowTracker</a>
|
||||||
|
*/
|
||||||
|
private boolean isStorageNotLow(Context context) {
|
||||||
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
|
||||||
|
intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
|
||||||
|
Intent intent = context.registerReceiver(null, intentFilter);
|
||||||
|
if (intent == null || intent.getAction() == null) {
|
||||||
|
// ACTION_DEVICE_STORAGE_LOW is a sticky broadcast that is removed when sufficient
|
||||||
|
// storage is available again. ACTION_DEVICE_STORAGE_OK is not sticky. So if we
|
||||||
|
// don't receive anything here, we can assume that the storage state is okay.
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
switch (intent.getAction()) {
|
||||||
|
case Intent.ACTION_DEVICE_STORAGE_OK:
|
||||||
|
return true;
|
||||||
|
case Intent.ACTION_DEVICE_STORAGE_LOW:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
// This should never happen because the intent filter is configured
|
||||||
|
// correctly.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isInternetConnectivityValidated(ConnectivityManager connectivityManager) {
|
private static boolean isInternetConnectivityValidated(ConnectivityManager connectivityManager) {
|
||||||
// It's possible to query NetworkCapabilities from API level 23, but RequirementsWatcher only
|
// It's possible to query NetworkCapabilities from API level 23, but RequirementsWatcher only
|
||||||
// fires an event to update its Requirements when NetworkCapabilities change from API level 24.
|
// fires an event to update its Requirements when NetworkCapabilities change from API level 24.
|
||||||
|
@ -104,6 +104,10 @@ public final class RequirementsWatcher {
|
|||||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (requirements.isStorageNotLowRequired()) {
|
||||||
|
filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
|
||||||
|
filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
|
||||||
|
}
|
||||||
receiver = new DeviceStatusChangeReceiver();
|
receiver = new DeviceStatusChangeReceiver();
|
||||||
context.registerReceiver(receiver, filter, null, handler);
|
context.registerReceiver(receiver, filter, null, handler);
|
||||||
return notMetRequirements;
|
return notMetRequirements;
|
||||||
|
@ -45,4 +45,13 @@ public interface Scheduler {
|
|||||||
* @return Whether cancellation was successful.
|
* @return Whether cancellation was successful.
|
||||||
*/
|
*/
|
||||||
boolean cancel();
|
boolean cancel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this {@link Scheduler} supports the provided {@link Requirements}. If all
|
||||||
|
* requirements are supported the same object is returned. If not all requirements are
|
||||||
|
* supported a new {@code Requirements} object is returned containing the supported requirements.
|
||||||
|
* @param requirements The requirements to check.
|
||||||
|
* @return The requirements supported by this scheduler.
|
||||||
|
*/
|
||||||
|
Requirements getSupportedRequirements(Requirements requirements);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user