Fix more cases of downloads not being resumed

Issue: #7453
PiperOrigin-RevId: 314710328
This commit is contained in:
olly 2020-06-04 13:15:51 +01:00 committed by Oliver Woodman
parent a818049143
commit 1347a2200f
3 changed files with 60 additions and 18 deletions

View File

@ -1,6 +1,6 @@
# Release notes # # Release notes #
### 2.11.5 (2020-06-03) ### ### 2.11.5 (2020-06-04) ###
* Improve the smoothness of video playback immediately after starting, seeking * Improve the smoothness of video playback immediately after starting, seeking
or resuming a playback or resuming a playback
@ -17,6 +17,9 @@
* Fix issue in `AudioTrackPositionTracker` that could cause negative positions * Fix issue in `AudioTrackPositionTracker` that could cause negative positions
to be reported at the start of playback and immediately after seeking to be reported at the start of playback and immediately after seeking
([#7456](https://github.com/google/ExoPlayer/issues/7456). ([#7456](https://github.com/google/ExoPlayer/issues/7456).
* Fix further cases where downloads would sometimes not resume after their
network requirements are met
([#7453](https://github.com/google/ExoPlayer/issues/7453).
* DASH: * DASH:
* Merge trick play adaptation sets (i.e., adaptation sets marked with * Merge trick play adaptation sets (i.e., adaptation sets marked with
`http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as `http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as

View File

@ -129,11 +129,9 @@ public final class Requirements implements Parcelable {
} }
ConnectivityManager connectivityManager = ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); (ConnectivityManager)
NetworkInfo networkInfo = Assertions.checkNotNull(connectivityManager).getActiveNetworkInfo(); Assertions.checkNotNull(context.getSystemService(Context.CONNECTIVITY_SERVICE));
if (networkInfo == null if (!isInternetConnectivityValidated(connectivityManager)) {
|| !networkInfo.isConnected()
|| !isInternetConnectivityValidated(connectivityManager)) {
return requirements & (NETWORK | NETWORK_UNMETERED); return requirements & (NETWORK | NETWORK_UNMETERED);
} }
@ -156,23 +154,28 @@ public final class Requirements implements Parcelable {
} }
private boolean isDeviceIdle(Context context) { private boolean isDeviceIdle(Context context) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager powerManager =
(PowerManager) Assertions.checkNotNull(context.getSystemService(Context.POWER_SERVICE));
return Util.SDK_INT >= 23 return Util.SDK_INT >= 23
? powerManager.isDeviceIdleMode() ? powerManager.isDeviceIdleMode()
: Util.SDK_INT >= 20 ? !powerManager.isInteractive() : !powerManager.isScreenOn(); : Util.SDK_INT >= 20 ? !powerManager.isInteractive() : !powerManager.isScreenOn();
} }
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 check NetworkCapabilities.NET_CAPABILITY_VALIDATED from API level 23, but
// fires an event to update its Requirements when NetworkCapabilities change from API level 24. // RequirementsWatcher only fires an event to re-check the requirements when NetworkCapabilities
// Since Requirements won't be updated, we assume connectivity is validated on API level 23. // change from API level 24. We use the legacy path for API level 23 here to keep in sync.
if (Util.SDK_INT < 24) { if (Util.SDK_INT < 24) {
return true; // Legacy path.
@Nullable NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
} }
Network activeNetwork = connectivityManager.getActiveNetwork();
@Nullable Network activeNetwork = connectivityManager.getActiveNetwork();
if (activeNetwork == null) { if (activeNetwork == null) {
return false; return false;
} }
@Nullable
NetworkCapabilities networkCapabilities = NetworkCapabilities networkCapabilities =
connectivityManager.getNetworkCapabilities(activeNetwork); connectivityManager.getNetworkCapabilities(activeNetwork);
return networkCapabilities != null return networkCapabilities != null

View File

@ -150,6 +150,23 @@ public final class RequirementsWatcher {
} }
} }
/**
* Re-checks the requirements if there are network requirements that are currently not met.
*
* <p>When we receive an event that implies newly established network connectivity, we re-check
* the requirements by calling {@link #checkRequirements()}. This check sometimes sees that there
* is still no active network, meaning that any network requirements will remain not met. By
* calling this method when we receive other events that imply continued network connectivity, we
* can detect that the requirements are met once an active network does exist.
*/
private void recheckNotMetNetworkRequirements() {
if ((notMetRequirements & (Requirements.NETWORK | Requirements.NETWORK_UNMETERED)) == 0) {
// No unmet network requirements to recheck.
return;
}
checkRequirements();
}
private class DeviceStatusChangeReceiver extends BroadcastReceiver { private class DeviceStatusChangeReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -161,17 +178,25 @@ public final class RequirementsWatcher {
@RequiresApi(24) @RequiresApi(24)
private final class NetworkCallback extends ConnectivityManager.NetworkCallback { private final class NetworkCallback extends ConnectivityManager.NetworkCallback {
boolean receivedCapabilitiesChange;
boolean networkValidated; private boolean receivedCapabilitiesChange;
private boolean networkValidated;
@Override @Override
public void onAvailable(Network network) { public void onAvailable(Network network) {
onNetworkCallback(); postCheckRequirements();
} }
@Override @Override
public void onLost(Network network) { public void onLost(Network network) {
onNetworkCallback(); postCheckRequirements();
}
@Override
public void onBlockedStatusChanged(Network network, boolean blocked) {
if (!blocked) {
postRecheckNotMetNetworkRequirements();
}
} }
@Override @Override
@ -181,11 +206,13 @@ public final class RequirementsWatcher {
if (!receivedCapabilitiesChange || this.networkValidated != networkValidated) { if (!receivedCapabilitiesChange || this.networkValidated != networkValidated) {
receivedCapabilitiesChange = true; receivedCapabilitiesChange = true;
this.networkValidated = networkValidated; this.networkValidated = networkValidated;
onNetworkCallback(); postCheckRequirements();
} else if (networkValidated) {
postRecheckNotMetNetworkRequirements();
} }
} }
private void onNetworkCallback() { private void postCheckRequirements() {
handler.post( handler.post(
() -> { () -> {
if (networkCallback != null) { if (networkCallback != null) {
@ -193,5 +220,14 @@ public final class RequirementsWatcher {
} }
}); });
} }
private void postRecheckNotMetNetworkRequirements() {
handler.post(
() -> {
if (networkCallback != null) {
recheckNotMetNetworkRequirements();
}
});
}
} }
} }