mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
Merge pull request #5617 from loki666:workmanager
PiperOrigin-RevId: 248533906
This commit is contained in:
parent
51acd8150c
commit
f045bb2d07
6 changed files with 256 additions and 0 deletions
|
|
@ -1,5 +1,9 @@
|
|||
# Release notes #
|
||||
|
||||
### 2.10.4 ###
|
||||
|
||||
* Offline: Add Scheduler implementation which uses WorkManager.
|
||||
|
||||
### 2.10.3 ###
|
||||
|
||||
* Display last frame when seeking to end of stream
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ include modulePrefix + 'extension-vp9'
|
|||
include modulePrefix + 'extension-rtmp'
|
||||
include modulePrefix + 'extension-leanback'
|
||||
include modulePrefix + 'extension-jobdispatcher'
|
||||
include modulePrefix + 'extension-workmanager'
|
||||
|
||||
project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all')
|
||||
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-leanback').projectDir = new File(rootDir, 'extensions/leanback')
|
||||
project(modulePrefix + 'extension-jobdispatcher').projectDir = new File(rootDir, 'extensions/jobdispatcher')
|
||||
project(modulePrefix + 'extension-workmanager').projectDir = new File(rootDir, 'extensions/workmanager')
|
||||
|
|
|
|||
22
extensions/workmanager/README.md
Normal file
22
extensions/workmanager/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# ExoPlayer WorkManager extension
|
||||
|
||||
This extension provides a Scheduler implementation which uses [WorkManager][].
|
||||
|
||||
[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) 2019 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 'androidx.work:work-runtime:2.0.1'
|
||||
}
|
||||
|
||||
ext {
|
||||
javadocTitle = 'WorkManager extension'
|
||||
}
|
||||
apply from: '../../javadoc_library.gradle'
|
||||
|
||||
ext {
|
||||
releaseArtifact = 'extension-workmanager'
|
||||
releaseDescription = '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) 2019 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,161 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
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;
|
||||
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;
|
||||
|
||||
/** A {@link Scheduler} that uses {@link WorkManager}. */
|
||||
public final class WorkManagerScheduler implements Scheduler {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
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.REPLACE, 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();
|
||||
|
||||
if (requirements.isUnmeteredNetworkRequired()) {
|
||||
builder.setRequiredNetworkType(NetworkType.UNMETERED);
|
||||
} else if (requirements.isNetworkRequired()) {
|
||||
builder.setRequiredNetworkType(NetworkType.CONNECTED);
|
||||
} else {
|
||||
builder.setRequiredNetworkType(NetworkType.NOT_REQUIRED);
|
||||
}
|
||||
|
||||
if (requirements.isChargingRequired()) {
|
||||
builder.setRequiresCharging(true);
|
||||
}
|
||||
|
||||
if (requirements.isIdleRequired() && Util.SDK_INT >= 23) {
|
||||
setRequiresDeviceIdle(builder);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@TargetApi(23)
|
||||
private static void setRequiresDeviceIdle(Constraints.Builder builder) {
|
||||
builder.setRequiresDeviceIdle(true);
|
||||
}
|
||||
|
||||
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. */
|
||||
// This class needs to be public so that WorkManager can instantiate it.
|
||||
public static final class SchedulerWorker extends Worker {
|
||||
|
||||
private final WorkerParameters workerParams;
|
||||
private final Context context;
|
||||
|
||||
public SchedulerWorker(Context context, WorkerParameters workerParams) {
|
||||
super(context, workerParams);
|
||||
this.workerParams = workerParams;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@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…
Reference in a new issue