From 1aa0b0dda298b39efe5826a20791a6af484d22b4 Mon Sep 17 00:00:00 2001 From: tzugen Date: Sun, 11 Dec 2022 00:18:30 +0100 Subject: [PATCH] Use network detection logic from AntennaPod --- .../ultrasonic/service/DownloadService.kt | 2 +- .../subsonic/NetworkAndStorageChecker.kt | 2 +- .../moire/ultrasonic/subsonic/VideoPlayer.kt | 2 +- .../ultrasonic/util/CommunicationError.kt | 2 +- .../org/moire/ultrasonic/util/Settings.kt | 10 +-- .../kotlin/org/moire/ultrasonic/util/Util.kt | 80 +++++++++---------- 6 files changed, 45 insertions(+), 53 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt index e574c24a..725be386 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadService.kt @@ -124,7 +124,7 @@ class DownloadService : Service(), KoinComponent { fun processNextTracks() { retrying = false if ( - !Util.isNetworkConnected() || + !Util.hasUsableNetwork() || !Util.isExternalStoragePresent() || !storageMonitor.isExternalStorageAvailable ) { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/NetworkAndStorageChecker.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/NetworkAndStorageChecker.kt index 1bab7f17..22e73d33 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/NetworkAndStorageChecker.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/NetworkAndStorageChecker.kt @@ -12,7 +12,7 @@ class NetworkAndStorageChecker(val context: Context) { fun warnIfNetworkOrStorageUnavailable() { if (!Util.isExternalStoragePresent()) { Util.toast(context, R.string.select_album_no_sdcard) - } else if (!isOffline() && !Util.isNetworkConnected()) { + } else if (!isOffline() && !Util.hasUsableNetwork()) { Util.toast(context, R.string.select_album_no_network) } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/VideoPlayer.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/VideoPlayer.kt index 6ad3fe0e..a91fcea9 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/VideoPlayer.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/subsonic/VideoPlayer.kt @@ -15,7 +15,7 @@ import org.moire.ultrasonic.util.Util class VideoPlayer { companion object { fun playVideo(context: Context, track: Track?) { - if (!Util.isNetworkConnected() || track == null) { + if (!Util.hasUsableNetwork() || track == null) { Util.toast(context, R.string.select_album_no_network) return } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CommunicationError.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CommunicationError.kt index 725f095c..917afda5 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CommunicationError.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/CommunicationError.kt @@ -54,7 +54,7 @@ object CommunicationError { @Suppress("ReturnCount") fun getErrorMessage(error: Throwable, context: Context?): String { if (context == null) return "Couldn't get Error message, Context is null" - if (error is IOException && !Util.isNetworkConnected()) { + if (error is IOException && !Util.hasUsableNetwork()) { return context.resources.getString(R.string.background_task_no_network) } else if (error is FileNotFoundException) { return context.resources.getString(R.string.background_task_not_found) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt index 55fa7d3f..501573eb 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Settings.kt @@ -32,14 +32,10 @@ object Settings { @JvmStatic val maxBitRate: Int get() { - val network = Util.networkInfo() - - if (!network.connected) return 0 - - return if (network.unmetered) { - maxWifiBitRate - } else { + return if (Util.isNetworkRestricted()) { maxMobileBitRate + } else { + maxWifiBitRate } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt index d9a188bb..df63bd7b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/Util.kt @@ -17,13 +17,10 @@ import android.content.ContentResolver import android.content.Context import android.content.Intent import android.content.pm.PackageManager -import android.graphics.Bitmap import android.graphics.BitmapFactory import android.media.MediaScannerConnection import android.net.ConnectivityManager -import android.net.Network -import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET -import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED +import android.net.NetworkCapabilities import android.net.Uri import android.net.wifi.WifiManager import android.net.wifi.WifiManager.WifiLock @@ -317,39 +314,50 @@ object Util { * @return Boolean */ @JvmStatic - fun isNetworkConnected(): Boolean { - val info = networkInfo() - val isUnmetered = info.unmetered + fun hasUsableNetwork(): Boolean { + val isUnmetered = !isNetworkRestricted() val wifiRequired = Settings.isWifiRequiredForDownload - return info.connected && (!wifiRequired || isUnmetered) + return (!wifiRequired || isUnmetered) } - /** - * Query connectivity status - * - * @return NetworkInfo object - */ - @Suppress("DEPRECATION") - fun networkInfo(): NetworkInfo { - val manager = connectivityManager - val info = NetworkInfo() + fun isNetworkRestricted(): Boolean { + return isNetworkMetered() || isNetworkCellular() + } + private fun isNetworkMetered(): Boolean { + val connManager = connectivityManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val network: Network? = manager.activeNetwork - val capabilities = manager.getNetworkCapabilities(network) - - if (capabilities != null) { - info.unmetered = capabilities.hasCapability(NET_CAPABILITY_NOT_METERED) - info.connected = capabilities.hasCapability(NET_CAPABILITY_INTERNET) - } - } else { - val networkInfo = manager.activeNetworkInfo - if (networkInfo != null) { - info.unmetered = networkInfo.type == ConnectivityManager.TYPE_WIFI - info.connected = networkInfo.isConnected + val capabilities = connManager.getNetworkCapabilities( + connManager.activeNetwork + ) + if (capabilities != null && + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) && + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) + ) { + return false } } - return info + return connManager.isActiveNetworkMetered + } + + @Suppress("DEPRECATION") + private fun isNetworkCellular(): Boolean { + val connManager = connectivityManager + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val network = connManager.activeNetwork + ?: return false // Nothing connected + connManager.getNetworkInfo(network) + ?: return true // Better be safe than sorry + val capabilities = connManager.getNetworkCapabilities(network) + ?: return true // Better be safe than sorry + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) + } else { + // if the default network is a VPN, + // this method will return the NetworkInfo for one of its underlying networks + val info = connManager.activeNetworkInfo + ?: return false // Nothing connected + info.type == ConnectivityManager.TYPE_MOBILE + } } @JvmStatic @@ -380,10 +388,6 @@ object Util { return (newWidth * aspectRatio).roundToInt() } - private fun getScaledHeight(bitmap: Bitmap, width: Int): Int { - return getScaledHeight(bitmap.height.toDouble(), bitmap.width.toDouble(), width) - } - fun getSongsFromSearchResult(searchResult: SearchResult): MusicDirectory { val musicDirectory = MusicDirectory() for (entry in searchResult.songs) { @@ -752,14 +756,6 @@ object Util { return this?.let(block) } - /** - * Small data class to store information about the current network - **/ - data class NetworkInfo( - var connected: Boolean = false, - var unmetered: Boolean = false - ) - /** * Closes a Closeable while ignoring any errors. **/