Repo created
This commit is contained in:
parent
75dc487a7a
commit
39c29d175b
6317 changed files with 388324 additions and 2 deletions
17
core/android/network/build.gradle.kts
Normal file
17
core/android/network/build.gradle.kts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "net.thunderbird.core.android.network"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.core.common)
|
||||
|
||||
implementation(projects.core.logging.api)
|
||||
implementation(projects.core.logging.implLegacy)
|
||||
|
||||
testImplementation(projects.core.testing)
|
||||
testImplementation(libs.robolectric)
|
||||
}
|
||||
6
core/android/network/src/main/AndroidManifest.xml
Normal file
6
core/android/network/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import android.os.Build
|
||||
import android.net.ConnectivityManager as SystemConnectivityManager
|
||||
|
||||
interface ConnectivityManager {
|
||||
fun start()
|
||||
fun stop()
|
||||
fun isNetworkAvailable(): Boolean
|
||||
fun addListener(listener: ConnectivityChangeListener)
|
||||
fun removeListener(listener: ConnectivityChangeListener)
|
||||
}
|
||||
|
||||
interface ConnectivityChangeListener {
|
||||
fun onConnectivityChanged()
|
||||
fun onConnectivityLost()
|
||||
}
|
||||
|
||||
internal fun ConnectivityManager(systemConnectivityManager: SystemConnectivityManager): ConnectivityManager {
|
||||
return when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> ConnectivityManagerApi24(systemConnectivityManager)
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> ConnectivityManagerApi23(systemConnectivityManager)
|
||||
else -> ConnectivityManagerApi21(systemConnectivityManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.Network
|
||||
import android.net.NetworkRequest
|
||||
import net.thunderbird.core.logging.legacy.Log
|
||||
import android.net.ConnectivityManager as SystemConnectivityManager
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
internal class ConnectivityManagerApi21(
|
||||
private val systemConnectivityManager: SystemConnectivityManager,
|
||||
) : ConnectivityManagerBase() {
|
||||
private var isRunning = false
|
||||
private var lastNetworkType: Int? = null
|
||||
private var wasConnected: Boolean? = null
|
||||
|
||||
private val networkCallback = object : NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.v("Network available: $network")
|
||||
notifyIfConnectivityHasChanged()
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
Log.v("Network lost: $network")
|
||||
notifyIfConnectivityHasChanged()
|
||||
}
|
||||
|
||||
private fun notifyIfConnectivityHasChanged() {
|
||||
val networkType = systemConnectivityManager.activeNetworkInfo?.type
|
||||
val isConnected = isNetworkAvailable()
|
||||
|
||||
synchronized(this@ConnectivityManagerApi21) {
|
||||
if (networkType != lastNetworkType || isConnected != wasConnected) {
|
||||
lastNetworkType = networkType
|
||||
wasConnected = isConnected
|
||||
if (isConnected) {
|
||||
notifyOnConnectivityChanged()
|
||||
} else {
|
||||
notifyOnConnectivityLost()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun start() {
|
||||
if (!isRunning) {
|
||||
isRunning = true
|
||||
|
||||
val networkRequest = NetworkRequest.Builder().build()
|
||||
systemConnectivityManager.registerNetworkCallback(networkRequest, networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun stop() {
|
||||
if (isRunning) {
|
||||
isRunning = false
|
||||
|
||||
systemConnectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isNetworkAvailable(): Boolean = systemConnectivityManager.activeNetworkInfo?.isConnected == true
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import net.thunderbird.core.logging.legacy.Log
|
||||
import android.net.ConnectivityManager as SystemConnectivityManager
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
internal class ConnectivityManagerApi23(
|
||||
private val systemConnectivityManager: SystemConnectivityManager,
|
||||
) : ConnectivityManagerBase() {
|
||||
private var isRunning = false
|
||||
private var lastActiveNetwork: Network? = null
|
||||
private var wasConnected: Boolean? = null
|
||||
|
||||
private val networkCallback = object : NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.v("Network available: $network")
|
||||
notifyIfActiveNetworkOrConnectivityHasChanged()
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
Log.v("Network lost: $network")
|
||||
notifyIfActiveNetworkOrConnectivityHasChanged()
|
||||
}
|
||||
|
||||
private fun notifyIfActiveNetworkOrConnectivityHasChanged() {
|
||||
val activeNetwork = systemConnectivityManager.activeNetwork
|
||||
val isConnected = isNetworkAvailable()
|
||||
|
||||
synchronized(this@ConnectivityManagerApi23) {
|
||||
if (activeNetwork != lastActiveNetwork || isConnected != wasConnected) {
|
||||
lastActiveNetwork = activeNetwork
|
||||
wasConnected = isConnected
|
||||
if (isConnected) {
|
||||
notifyOnConnectivityChanged()
|
||||
} else {
|
||||
notifyOnConnectivityLost()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun start() {
|
||||
if (!isRunning) {
|
||||
isRunning = true
|
||||
|
||||
val networkRequest = NetworkRequest.Builder().build()
|
||||
systemConnectivityManager.registerNetworkCallback(networkRequest, networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun stop() {
|
||||
if (isRunning) {
|
||||
isRunning = false
|
||||
|
||||
systemConnectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isNetworkAvailable(): Boolean {
|
||||
val activeNetwork = systemConnectivityManager.activeNetwork ?: return false
|
||||
val networkCapabilities = systemConnectivityManager.getNetworkCapabilities(activeNetwork)
|
||||
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import net.thunderbird.core.logging.legacy.Log
|
||||
import android.net.ConnectivityManager as SystemConnectivityManager
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
internal class ConnectivityManagerApi24(
|
||||
private val systemConnectivityManager: SystemConnectivityManager,
|
||||
) : ConnectivityManagerBase() {
|
||||
private var isRunning = false
|
||||
private var isNetworkAvailable: Boolean? = null
|
||||
|
||||
private val networkCallback = object : NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.v("Network available: $network")
|
||||
synchronized(this@ConnectivityManagerApi24) {
|
||||
isNetworkAvailable = true
|
||||
notifyOnConnectivityChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
Log.v("Network lost: $network")
|
||||
synchronized(this@ConnectivityManagerApi24) {
|
||||
isNetworkAvailable = false
|
||||
notifyOnConnectivityLost()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun start() {
|
||||
if (!isRunning) {
|
||||
isRunning = true
|
||||
|
||||
systemConnectivityManager.registerDefaultNetworkCallback(networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun stop() {
|
||||
if (isRunning) {
|
||||
isRunning = false
|
||||
|
||||
systemConnectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isNetworkAvailable(): Boolean {
|
||||
return synchronized(this) { isNetworkAvailable } ?: isNetworkAvailableSynchronous()
|
||||
}
|
||||
|
||||
// Sometimes this will return 'true' even though networkCallback has already received onLost().
|
||||
// That's why isNetworkAvailable() prefers the state derived from the callbacks over this method.
|
||||
private fun isNetworkAvailableSynchronous(): Boolean {
|
||||
val activeNetwork = systemConnectivityManager.activeNetwork ?: return false
|
||||
val networkCapabilities = systemConnectivityManager.getNetworkCapabilities(activeNetwork)
|
||||
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import java.util.concurrent.CopyOnWriteArraySet
|
||||
|
||||
internal abstract class ConnectivityManagerBase : ConnectivityManager {
|
||||
private val listeners = CopyOnWriteArraySet<ConnectivityChangeListener>()
|
||||
|
||||
@Synchronized
|
||||
override fun addListener(listener: ConnectivityChangeListener) {
|
||||
listeners.add(listener)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun removeListener(listener: ConnectivityChangeListener) {
|
||||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
protected fun notifyOnConnectivityChanged() {
|
||||
for (listener in listeners) {
|
||||
listener.onConnectivityChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
protected fun notifyOnConnectivityLost() {
|
||||
for (listener in listeners) {
|
||||
listener.onConnectivityLost()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.thunderbird.core.android.network
|
||||
|
||||
import android.content.Context
|
||||
import org.koin.dsl.module
|
||||
import android.net.ConnectivityManager as SystemConnectivityManager
|
||||
|
||||
val coreAndroidNetworkModule = module {
|
||||
single { get<Context>().getSystemService(Context.CONNECTIVITY_SERVICE) as SystemConnectivityManager }
|
||||
single { ConnectivityManager(systemConnectivityManager = get()) }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue