add WorkManager extension
This commit is contained in:
parent
f35dbeb567
commit
0ea023047d
@ -38,6 +38,7 @@ include modulePrefix + 'extension-vp9'
|
|||||||
include modulePrefix + 'extension-rtmp'
|
include modulePrefix + 'extension-rtmp'
|
||||||
include modulePrefix + 'extension-leanback'
|
include modulePrefix + 'extension-leanback'
|
||||||
include modulePrefix + 'extension-jobdispatcher'
|
include modulePrefix + 'extension-jobdispatcher'
|
||||||
|
include modulePrefix + 'extension-workmanager'
|
||||||
|
|
||||||
project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all')
|
project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all')
|
||||||
project(modulePrefix + 'library-core').projectDir = new File(rootDir, 'library/core')
|
project(modulePrefix + 'library-core').projectDir = new File(rootDir, 'library/core')
|
||||||
@ -60,3 +61,4 @@ project(modulePrefix + 'extension-vp9').projectDir = new File(rootDir, 'extensio
|
|||||||
project(modulePrefix + 'extension-rtmp').projectDir = new File(rootDir, 'extensions/rtmp')
|
project(modulePrefix + 'extension-rtmp').projectDir = new File(rootDir, 'extensions/rtmp')
|
||||||
project(modulePrefix + 'extension-leanback').projectDir = new File(rootDir, 'extensions/leanback')
|
project(modulePrefix + 'extension-leanback').projectDir = new File(rootDir, 'extensions/leanback')
|
||||||
project(modulePrefix + 'extension-jobdispatcher').projectDir = new File(rootDir, 'extensions/jobdispatcher')
|
project(modulePrefix + 'extension-jobdispatcher').projectDir = new File(rootDir, 'extensions/jobdispatcher')
|
||||||
|
project(modulePrefix + 'extension-workmanager').projectDir = new File(rootDir, 'extensions/workmanager')
|
||||||
|
23
extensions/workmanager/README.md
Normal file
23
extensions/workmanager/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# ExoPlayer WorkManager extension #
|
||||||
|
|
||||||
|
This extension provides a Scheduler implementation which uses [Android Arch WorkManager][].
|
||||||
|
|
||||||
|
[Android Arch WorkManager]: https://developer.android.com/topic/libraries/architecture/workmanager.html
|
||||||
|
|
||||||
|
## Getting the extension ##
|
||||||
|
|
||||||
|
The easiest way to use the extension is to add it as a gradle dependency:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
implementation 'com.google.android.exoplayer:extension-workmanager:2.X.X'
|
||||||
|
```
|
||||||
|
|
||||||
|
where `2.X.X` is the version, which must match the version of the ExoPlayer
|
||||||
|
library being used.
|
||||||
|
|
||||||
|
Alternatively, you can clone the ExoPlayer repository and depend on the module
|
||||||
|
locally. Instructions for doing this can be found in ExoPlayer's
|
||||||
|
[top level README][].
|
||||||
|
|
||||||
|
[top level README]: https://github.com/google/ExoPlayer/blob/release-v2/README.md
|
||||||
|
|
49
extensions/workmanager/build.gradle
Normal file
49
extensions/workmanager/build.gradle
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
apply from: '../../constants.gradle'
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion project.ext.compileSdkVersion
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion project.ext.minSdkVersion
|
||||||
|
targetSdkVersion project.ext.targetSdkVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
testOptions.unitTests.includeAndroidResources = true
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(modulePrefix + 'library-core')
|
||||||
|
implementation 'android.arch.work:work-runtime:1.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
javadocTitle = 'Android Arch WorkManager extension'
|
||||||
|
}
|
||||||
|
apply from: '../../javadoc_library.gradle'
|
||||||
|
|
||||||
|
ext {
|
||||||
|
releaseArtifact = 'extension-workmanager'
|
||||||
|
releaseDescription = 'Android Arch WorkManager extension for ExoPlayer.'
|
||||||
|
}
|
||||||
|
apply from: '../../publish.gradle'
|
18
extensions/workmanager/src/main/AndroidManifest.xml
Normal file
18
extensions/workmanager/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2018 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest package="com.google.android.exoplayer2.ext.workmanager"/>
|
@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.workmanager;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.scheduler.Requirements;
|
||||||
|
import com.google.android.exoplayer2.scheduler.Scheduler;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.work.Constraints;
|
||||||
|
import androidx.work.Data;
|
||||||
|
import androidx.work.ExistingWorkPolicy;
|
||||||
|
import androidx.work.NetworkType;
|
||||||
|
import androidx.work.OneTimeWorkRequest;
|
||||||
|
import androidx.work.WorkManager;
|
||||||
|
import androidx.work.Worker;
|
||||||
|
import androidx.work.WorkerParameters;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* A {@link Scheduler} that uses {@link WorkManager}.
|
||||||
|
*/
|
||||||
|
public final class WorkManagerScheduler implements Scheduler {
|
||||||
|
|
||||||
|
private static final String TAG = "WorkManagerScheduler";
|
||||||
|
private static final String KEY_SERVICE_ACTION = "service_action";
|
||||||
|
private static final String KEY_SERVICE_PACKAGE = "service_package";
|
||||||
|
private static final String KEY_REQUIREMENTS = "requirements";
|
||||||
|
|
||||||
|
private final String workName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param workName A name for work scheduled by this instance. If the same name was used by a previous
|
||||||
|
* instance, anything scheduled by the previous instance will be canceled by this instance if
|
||||||
|
* {@link #schedule(Requirements, String, String)} or {@link #cancel()} are called.
|
||||||
|
*/
|
||||||
|
public WorkManagerScheduler(String workName) {
|
||||||
|
this.workName = workName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean schedule(Requirements requirements, String servicePackage, String serviceAction) {
|
||||||
|
Constraints constraints = buildConstraints(requirements);
|
||||||
|
Data inputData = buildInputData(requirements, servicePackage, serviceAction);
|
||||||
|
OneTimeWorkRequest workRequest = buildWorkRequest(constraints, inputData);
|
||||||
|
logd("Scheduling work: " + workName);
|
||||||
|
WorkManager.getInstance().enqueueUniqueWork(workName, ExistingWorkPolicy.KEEP, workRequest);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean cancel() {
|
||||||
|
logd("Canceling work: " + workName);
|
||||||
|
WorkManager.getInstance().cancelUniqueWork(workName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Constraints buildConstraints(Requirements requirements) {
|
||||||
|
Constraints.Builder builder = new Constraints.Builder();
|
||||||
|
|
||||||
|
switch (requirements.getRequiredNetworkType()) {
|
||||||
|
case Requirements.NETWORK_TYPE_NONE:
|
||||||
|
builder.setRequiredNetworkType(NetworkType.NOT_REQUIRED);
|
||||||
|
break;
|
||||||
|
case Requirements.NETWORK_TYPE_ANY:
|
||||||
|
builder.setRequiredNetworkType(NetworkType.CONNECTED);
|
||||||
|
break;
|
||||||
|
case Requirements.NETWORK_TYPE_UNMETERED:
|
||||||
|
builder.setRequiredNetworkType(NetworkType.UNMETERED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requirements.isChargingRequired()) {
|
||||||
|
builder.setRequiresCharging(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requirements.isIdleRequired() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
builder.setRequiresDeviceIdle(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Data buildInputData(Requirements requirements, String servicePackage, String serviceAction) {
|
||||||
|
Data.Builder builder = new Data.Builder();
|
||||||
|
|
||||||
|
builder.putInt(KEY_REQUIREMENTS, requirements.getRequirements());
|
||||||
|
builder.putString(KEY_SERVICE_PACKAGE, servicePackage);
|
||||||
|
builder.putString(KEY_SERVICE_ACTION, serviceAction);
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OneTimeWorkRequest buildWorkRequest(Constraints constraints, Data inputData) {
|
||||||
|
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SchedulerWorker.class);
|
||||||
|
|
||||||
|
builder.setConstraints(constraints);
|
||||||
|
builder.setInputData(inputData);
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void logd(String message) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A {@link Worker} that starts the target service if the requirements are met. */
|
||||||
|
public static final class SchedulerWorker extends Worker {
|
||||||
|
|
||||||
|
private final WorkerParameters workerParams;
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
public SchedulerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
|
||||||
|
super(context, workerParams);
|
||||||
|
this.workerParams = workerParams;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Result doWork() {
|
||||||
|
logd("SchedulerWorker is started");
|
||||||
|
Data inputData = workerParams.getInputData();
|
||||||
|
Assertions.checkNotNull(inputData, "Work started without input data.");
|
||||||
|
Requirements requirements = new Requirements(inputData.getInt(KEY_REQUIREMENTS, 0));
|
||||||
|
if (requirements.checkRequirements(context)) {
|
||||||
|
logd("Requirements are met");
|
||||||
|
String serviceAction = inputData.getString(KEY_SERVICE_ACTION);
|
||||||
|
String servicePackage = inputData.getString(KEY_SERVICE_PACKAGE);
|
||||||
|
Assertions.checkNotNull(serviceAction, "Service action missing.");
|
||||||
|
Assertions.checkNotNull(servicePackage, "Service package missing.");
|
||||||
|
Intent intent = new Intent(serviceAction).setPackage(servicePackage);
|
||||||
|
logd("Starting service action: " + serviceAction + " package: " + servicePackage);
|
||||||
|
Util.startForegroundService(context, intent);
|
||||||
|
return Result.success();
|
||||||
|
} else {
|
||||||
|
logd("Requirements are not met");
|
||||||
|
return Result.retry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user