mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add WifiLock management to SimpleExoPlayer.
Issue:#6914 PiperOrigin-RevId: 297598910
This commit is contained in:
parent
e4e56fac09
commit
83c2ca5902
5 changed files with 203 additions and 25 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
# Release notes #
|
# Release notes #
|
||||||
|
|
||||||
### 2.11.4 (2020-04-01) ###
|
### 2.11.4 (2020-04-08) ###
|
||||||
|
|
||||||
|
* Add optional automatic `WifiLock` handling to `SimpleExoPlayer`
|
||||||
|
([#6914](https://github.com/google/ExoPlayer/issues/6914)).
|
||||||
* Text:
|
* Text:
|
||||||
* Catch and log exceptions in `TextRenderer` rather than re-throwing. This
|
* Catch and log exceptions in `TextRenderer` rather than re-throwing. This
|
||||||
allows playback to continue even if subtitle decoding fails
|
allows playback to continue even if subtitle decoding fails
|
||||||
|
|
|
||||||
|
|
@ -1019,6 +1019,37 @@ public final class C {
|
||||||
/** Network type for other connections which are not Wifi or cellular (e.g. VPN, Bluetooth). */
|
/** Network type for other connections which are not Wifi or cellular (e.g. VPN, Bluetooth). */
|
||||||
public static final int NETWORK_TYPE_OTHER = 8;
|
public static final int NETWORK_TYPE_OTHER = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode specifying whether the player should hold a WakeLock and a WifiLock. One of {@link
|
||||||
|
* #WAKE_MODE_NONE}, {@link #WAKE_MODE_LOCAL} and {@link #WAKE_MODE_NETWORK}.
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef({WAKE_MODE_NONE, WAKE_MODE_LOCAL, WAKE_MODE_NETWORK})
|
||||||
|
public @interface WakeMode {}
|
||||||
|
/**
|
||||||
|
* A wake mode that will not cause the player to hold any locks.
|
||||||
|
*
|
||||||
|
* <p>This is suitable for applications that do not play media with the screen off.
|
||||||
|
*/
|
||||||
|
public static final int WAKE_MODE_NONE = 0;
|
||||||
|
/**
|
||||||
|
* A wake mode that will cause the player to hold a {@link android.os.PowerManager.WakeLock}
|
||||||
|
* during playback.
|
||||||
|
*
|
||||||
|
* <p>This is suitable for applications that play media with the screen off and do not load media
|
||||||
|
* over wifi.
|
||||||
|
*/
|
||||||
|
public static final int WAKE_MODE_LOCAL = 1;
|
||||||
|
/**
|
||||||
|
* A wake mode that will cause the player to hold a {@link android.os.PowerManager.WakeLock} and a
|
||||||
|
* {@link android.net.wifi.WifiManager.WifiLock} during playback.
|
||||||
|
*
|
||||||
|
* <p>This is suitable for applications that play media with the screen off and may load media
|
||||||
|
* over wifi.
|
||||||
|
*/
|
||||||
|
public static final int WAKE_MODE_NETWORK = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track role flags. Possible flag values are {@link #ROLE_FLAG_MAIN}, {@link
|
* Track role flags. Possible flag values are {@link #ROLE_FLAG_MAIN}, {@link
|
||||||
* #ROLE_FLAG_ALTERNATE}, {@link #ROLE_FLAG_SUPPLEMENTARY}, {@link #ROLE_FLAG_COMMENTARY}, {@link
|
* #ROLE_FLAG_ALTERNATE}, {@link #ROLE_FLAG_SUPPLEMENTARY}, {@link #ROLE_FLAG_COMMENTARY}, {@link
|
||||||
|
|
|
||||||
|
|
@ -325,6 +325,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
private final AudioBecomingNoisyManager audioBecomingNoisyManager;
|
private final AudioBecomingNoisyManager audioBecomingNoisyManager;
|
||||||
private final AudioFocusManager audioFocusManager;
|
private final AudioFocusManager audioFocusManager;
|
||||||
private final WakeLockManager wakeLockManager;
|
private final WakeLockManager wakeLockManager;
|
||||||
|
private final WifiLockManager wifiLockManager;
|
||||||
|
|
||||||
@Nullable private Format videoFormat;
|
@Nullable private Format videoFormat;
|
||||||
@Nullable private Format audioFormat;
|
@Nullable private Format audioFormat;
|
||||||
|
|
@ -460,6 +461,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
new AudioBecomingNoisyManager(context, eventHandler, componentListener);
|
new AudioBecomingNoisyManager(context, eventHandler, componentListener);
|
||||||
audioFocusManager = new AudioFocusManager(context, eventHandler, componentListener);
|
audioFocusManager = new AudioFocusManager(context, eventHandler, componentListener);
|
||||||
wakeLockManager = new WakeLockManager(context);
|
wakeLockManager = new WakeLockManager(context);
|
||||||
|
wifiLockManager = new WifiLockManager(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1294,6 +1296,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
audioBecomingNoisyManager.setEnabled(false);
|
audioBecomingNoisyManager.setEnabled(false);
|
||||||
audioFocusManager.handleStop();
|
audioFocusManager.handleStop();
|
||||||
wakeLockManager.setStayAwake(false);
|
wakeLockManager.setStayAwake(false);
|
||||||
|
wifiLockManager.setStayAwake(false);
|
||||||
player.release();
|
player.release();
|
||||||
removeSurfaceCallbacks();
|
removeSurfaceCallbacks();
|
||||||
if (surface != null) {
|
if (surface != null) {
|
||||||
|
|
@ -1432,9 +1435,45 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
*
|
*
|
||||||
* @param handleWakeLock Whether the player should use a {@link android.os.PowerManager.WakeLock}
|
* @param handleWakeLock Whether the player should use a {@link android.os.PowerManager.WakeLock}
|
||||||
* to ensure the device stays awake for playback, even when the screen is off.
|
* to ensure the device stays awake for playback, even when the screen is off.
|
||||||
|
* @deprecated Use {@link #setWakeMode(int)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setHandleWakeLock(boolean handleWakeLock) {
|
public void setHandleWakeLock(boolean handleWakeLock) {
|
||||||
wakeLockManager.setEnabled(handleWakeLock);
|
setWakeMode(handleWakeLock ? C.WAKE_MODE_LOCAL : C.WAKE_MODE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets how the player should keep the device awake for playback when the screen is off.
|
||||||
|
*
|
||||||
|
* <p>Enabling this feature requires the {@link android.Manifest.permission#WAKE_LOCK} permission.
|
||||||
|
* It should be used together with a foreground {@link android.app.Service} for use cases where
|
||||||
|
* playback occurs and the screen is off (e.g. background audio playback). It is not useful when
|
||||||
|
* the screen will be kept on during playback (e.g. foreground video playback).
|
||||||
|
*
|
||||||
|
* <p>When enabled, the locks ({@link android.os.PowerManager.WakeLock} / {@link
|
||||||
|
* android.net.wifi.WifiManager.WifiLock}) will be held whenever the player is in the {@link
|
||||||
|
* #STATE_READY} or {@link #STATE_BUFFERING} states with {@code playWhenReady = true}. The locks
|
||||||
|
* held depends on the specified {@link C.WakeMode}.
|
||||||
|
*
|
||||||
|
* @param wakeMode The {@link C.WakeMode} option to keep the device awake during playback.
|
||||||
|
*/
|
||||||
|
public void setWakeMode(@C.WakeMode int wakeMode) {
|
||||||
|
switch (wakeMode) {
|
||||||
|
case C.WAKE_MODE_NONE:
|
||||||
|
wakeLockManager.setEnabled(false);
|
||||||
|
wifiLockManager.setEnabled(false);
|
||||||
|
break;
|
||||||
|
case C.WAKE_MODE_LOCAL:
|
||||||
|
wakeLockManager.setEnabled(true);
|
||||||
|
wifiLockManager.setEnabled(false);
|
||||||
|
break;
|
||||||
|
case C.WAKE_MODE_NETWORK:
|
||||||
|
wakeLockManager.setEnabled(true);
|
||||||
|
wifiLockManager.setEnabled(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
@ -1537,6 +1576,24 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateWakeAndWifiLock() {
|
||||||
|
@State int playbackState = getPlaybackState();
|
||||||
|
switch (playbackState) {
|
||||||
|
case Player.STATE_READY:
|
||||||
|
case Player.STATE_BUFFERING:
|
||||||
|
wakeLockManager.setStayAwake(getPlayWhenReady());
|
||||||
|
wifiLockManager.setStayAwake(getPlayWhenReady());
|
||||||
|
break;
|
||||||
|
case Player.STATE_ENDED:
|
||||||
|
case Player.STATE_IDLE:
|
||||||
|
wakeLockManager.setStayAwake(false);
|
||||||
|
wifiLockManager.setStayAwake(false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class ComponentListener
|
private final class ComponentListener
|
||||||
implements VideoRendererEventListener,
|
implements VideoRendererEventListener,
|
||||||
AudioRendererEventListener,
|
AudioRendererEventListener,
|
||||||
|
|
@ -1781,16 +1838,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {
|
public void onPlayerStateChanged(boolean playWhenReady, @State int playbackState) {
|
||||||
switch (playbackState) {
|
updateWakeAndWifiLock();
|
||||||
case Player.STATE_READY:
|
|
||||||
case Player.STATE_BUFFERING:
|
|
||||||
wakeLockManager.setStayAwake(playWhenReady);
|
|
||||||
break;
|
|
||||||
case Player.STATE_ENDED:
|
|
||||||
case Player.STATE_IDLE:
|
|
||||||
wakeLockManager.setStayAwake(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ import com.google.android.exoplayer2.util.Log;
|
||||||
private boolean stayAwake;
|
private boolean stayAwake;
|
||||||
|
|
||||||
public WakeLockManager(Context context) {
|
public WakeLockManager(Context context) {
|
||||||
powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
powerManager =
|
||||||
|
(PowerManager) context.getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,15 +49,15 @@ import com.google.android.exoplayer2.util.Log;
|
||||||
* <p>By default, wake lock handling is not enabled. Enabling this will acquire the wake lock if
|
* <p>By default, wake lock handling is not enabled. Enabling this will acquire the wake lock if
|
||||||
* necessary. Disabling this will release the wake lock if it is held.
|
* necessary. Disabling this will release the wake lock if it is held.
|
||||||
*
|
*
|
||||||
* @param enabled True if the player should handle a {@link WakeLock}, false otherwise. Please
|
* <p>Enabling {@link WakeLock} requires the {@link android.Manifest.permission#WAKE_LOCK}.
|
||||||
* note that enabling this requires the {@link android.Manifest.permission#WAKE_LOCK}
|
*
|
||||||
* permission.
|
* @param enabled True if the player should handle a {@link WakeLock}, false otherwise.
|
||||||
*/
|
*/
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (wakeLock == null) {
|
if (wakeLock == null) {
|
||||||
if (powerManager == null) {
|
if (powerManager == null) {
|
||||||
Log.w(TAG, "PowerManager was null, therefore the WakeLock was not created.");
|
Log.w(TAG, "PowerManager is null, therefore not creating the WakeLock.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
|
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
|
||||||
|
|
@ -86,15 +87,16 @@ import com.google.android.exoplayer2.util.Log;
|
||||||
// reasonable timeout that would not affect the user.
|
// reasonable timeout that would not affect the user.
|
||||||
@SuppressLint("WakelockTimeout")
|
@SuppressLint("WakelockTimeout")
|
||||||
private void updateWakeLock() {
|
private void updateWakeLock() {
|
||||||
// Needed for the library nullness check. If enabled is true, the wakelock will not be null.
|
if (wakeLock == null) {
|
||||||
if (wakeLock != null) {
|
return;
|
||||||
if (enabled && stayAwake) {
|
}
|
||||||
if (!wakeLock.isHeld()) {
|
|
||||||
wakeLock.acquire();
|
if (enabled && stayAwake) {
|
||||||
}
|
if (!wakeLock.isHeld()) {
|
||||||
} else if (wakeLock.isHeld()) {
|
wakeLock.acquire();
|
||||||
wakeLock.release();
|
|
||||||
}
|
}
|
||||||
|
} else if (wakeLock.isHeld()) {
|
||||||
|
wakeLock.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.net.wifi.WifiManager.WifiLock;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a {@link WifiLock}
|
||||||
|
*
|
||||||
|
* <p>The handling of wifi locks requires the {@link android.Manifest.permission#WAKE_LOCK}
|
||||||
|
* permission.
|
||||||
|
*/
|
||||||
|
/* package */ final class WifiLockManager {
|
||||||
|
|
||||||
|
private static final String TAG = "WifiLockManager";
|
||||||
|
private static final String WIFI_LOCK_TAG = "ExoPlayer:WifiLockManager";
|
||||||
|
|
||||||
|
@Nullable private final WifiManager wifiManager;
|
||||||
|
@Nullable private WifiLock wifiLock;
|
||||||
|
private boolean enabled;
|
||||||
|
private boolean stayAwake;
|
||||||
|
|
||||||
|
public WifiLockManager(Context context) {
|
||||||
|
wifiManager =
|
||||||
|
(WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to enable the usage of a {@link WifiLock}.
|
||||||
|
*
|
||||||
|
* <p>By default, wifi lock handling is not enabled. Enabling will acquire the wifi lock if
|
||||||
|
* necessary. Disabling will release the wifi lock if held.
|
||||||
|
*
|
||||||
|
* <p>Enabling {@link WifiLock} requires the {@link android.Manifest.permission#WAKE_LOCK}.
|
||||||
|
*
|
||||||
|
* @param enabled True if the player should handle a {@link WifiLock}.
|
||||||
|
*/
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
if (enabled && wifiLock == null) {
|
||||||
|
if (wifiManager == null) {
|
||||||
|
Log.w(TAG, "WifiManager is null, therefore not creating the WifiLock.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, WIFI_LOCK_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.enabled = enabled;
|
||||||
|
updateWifiLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to acquire or release the {@link WifiLock}.
|
||||||
|
*
|
||||||
|
* <p>The wifi lock will not be acquired unless handling has been enabled through {@link
|
||||||
|
* #setEnabled(boolean)}.
|
||||||
|
*
|
||||||
|
* @param stayAwake True if the player should acquire the {@link WifiLock}. False if it should
|
||||||
|
* release.
|
||||||
|
*/
|
||||||
|
public void setStayAwake(boolean stayAwake) {
|
||||||
|
this.stayAwake = stayAwake;
|
||||||
|
updateWifiLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateWifiLock() {
|
||||||
|
if (wifiLock == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled && stayAwake) {
|
||||||
|
if (!wifiLock.isHeld()) {
|
||||||
|
wifiLock.acquire();
|
||||||
|
}
|
||||||
|
} else if (wifiLock.isHeld()) {
|
||||||
|
wifiLock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue