From 24a19264dbf35e326bbd7bb36c232eb180e1e26d Mon Sep 17 00:00:00 2001 From: olly Date: Fri, 20 Dec 2019 20:23:02 +0000 Subject: [PATCH] Fix handling of network transitions in RequirementsWatcher Issue: #6733 PiperOrigin-RevId: 286621715 --- RELEASENOTES.md | 4 ++ .../exoplayer2/scheduler/Requirements.java | 13 +++-- .../scheduler/RequirementsWatcher.java | 54 +++++++++++-------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 67987f8852..d3f7cf8067 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -28,6 +28,10 @@ developers to handle data that's neither UTF-8 nor ISO-8859-1 ([#6753](https://github.com/google/ExoPlayer/issues/6753)). * Add playlist API ([#6161](https://github.com/google/ExoPlayer/issues/6161)). +* Fix handling of network transitions in `RequirementsWatcher` + ([#6733](https://github.com/google/ExoPlayer/issues/6733)). Incorrect handling + could previously cause downloads to be paused when they should have been able + to proceed. ### 2.11.1 (2019-12-20) ### diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java index 35f8e37dcf..87ea60bf73 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/Requirements.java @@ -163,9 +163,10 @@ public final class Requirements implements Parcelable { } private static boolean isInternetConnectivityValidated(ConnectivityManager connectivityManager) { - if (Util.SDK_INT < 23) { - // TODO Check internet connectivity using http://clients3.google.com/generate_204 on API - // levels prior to 23. + // 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. + // Since Requirements wont be updated, we assume connectivity is validated on API level 23. + if (Util.SDK_INT < 24) { return true; } Network activeNetwork = connectivityManager.getActiveNetwork(); @@ -174,10 +175,8 @@ public final class Requirements implements Parcelable { } NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork); - boolean validated = - networkCapabilities == null - || !networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); - return !validated; + return networkCapabilities != null + && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); } @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java index 0d9b8261d9..f55978c28a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/scheduler/RequirementsWatcher.java @@ -23,7 +23,6 @@ import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; -import android.net.NetworkRequest; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; @@ -62,7 +61,7 @@ public final class RequirementsWatcher { @Nullable private DeviceStatusChangeReceiver receiver; @Requirements.RequirementFlags private int notMetRequirements; - @Nullable private CapabilityValidatedCallback networkCallback; + @Nullable private NetworkCallback networkCallback; /** * @param context Any context. @@ -88,8 +87,8 @@ public final class RequirementsWatcher { IntentFilter filter = new IntentFilter(); if (requirements.isNetworkRequired()) { - if (Util.SDK_INT >= 23) { - registerNetworkCallbackV23(); + if (Util.SDK_INT >= 24) { + registerNetworkCallbackV24(); } else { filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); } @@ -115,8 +114,8 @@ public final class RequirementsWatcher { public void stop() { context.unregisterReceiver(Assertions.checkNotNull(receiver)); receiver = null; - if (networkCallback != null) { - unregisterNetworkCallback(); + if (Util.SDK_INT >= 24 && networkCallback != null) { + unregisterNetworkCallbackV24(); } } @@ -125,26 +124,21 @@ public final class RequirementsWatcher { return requirements; } - @TargetApi(23) - private void registerNetworkCallbackV23() { + @TargetApi(24) + private void registerNetworkCallbackV24() { ConnectivityManager connectivityManager = Assertions.checkNotNull( (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); - NetworkRequest request = - new NetworkRequest.Builder() - .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) - .build(); - networkCallback = new CapabilityValidatedCallback(); - connectivityManager.registerNetworkCallback(request, networkCallback); + networkCallback = new NetworkCallback(); + connectivityManager.registerDefaultNetworkCallback(networkCallback); } - private void unregisterNetworkCallback() { - if (Util.SDK_INT >= 21) { - ConnectivityManager connectivityManager = - (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - connectivityManager.unregisterNetworkCallback(Assertions.checkNotNull(networkCallback)); - networkCallback = null; - } + @TargetApi(24) + private void unregisterNetworkCallbackV24() { + ConnectivityManager connectivityManager = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + connectivityManager.unregisterNetworkCallback(Assertions.checkNotNull(networkCallback)); + networkCallback = null; } private void checkRequirements() { @@ -165,8 +159,11 @@ public final class RequirementsWatcher { } } - @RequiresApi(api = 21) - private final class CapabilityValidatedCallback extends ConnectivityManager.NetworkCallback { + @RequiresApi(24) + private final class NetworkCallback extends ConnectivityManager.NetworkCallback { + boolean receivedCapabilitiesChange; + boolean networkValidated; + @Override public void onAvailable(Network network) { onNetworkCallback(); @@ -177,6 +174,17 @@ public final class RequirementsWatcher { onNetworkCallback(); } + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { + boolean networkValidated = + networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); + if (!receivedCapabilitiesChange || this.networkValidated != networkValidated) { + receivedCapabilitiesChange = true; + this.networkValidated = networkValidated; + onNetworkCallback(); + } + } + private void onNetworkCallback() { handler.post( () -> {