Drop dependency upon Merlin

Use ConnectivityManager to monitor network status. This does takes away the ability to
auto-retry requests when network is restored but we can look into that later on.

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-08-07 20:49:43 +05:30
parent 6e11229f49
commit 0030e959d1
7 changed files with 81 additions and 154 deletions

View File

@@ -155,9 +155,6 @@ dependencies {
implementation "com.airbnb.android:epoxy:$epoxy_version"
kapt "com.airbnb.android:epoxy-processor:$epoxy_version"
//Merlin
implementation "com.novoda:merlin:1.2.1"
//HTTP Clients
implementation "com.squareup.okhttp3:okhttp:4.11.0"
@@ -176,7 +173,6 @@ dependencies {
//Browser
implementation 'androidx.browser:browser:1.5.0'
//Shizuku
def shizuku_version = '13.1.1'
compileOnly "dev.rikka.hidden:stub:4.2.0"

View File

@@ -28,7 +28,6 @@ import androidx.appcompat.app.AppCompatDelegate
import com.aurora.Constants
import com.aurora.extensions.isPAndAbove
import com.aurora.store.data.downloader.DownloadManager
import com.aurora.store.data.providers.NetworkProvider
import com.aurora.store.data.receiver.PackageManagerReceiver
import com.aurora.store.data.service.NotificationService
import com.aurora.store.util.CommonUtil
@@ -71,27 +70,9 @@ class AuroraApplication : Application() {
//Register broadcast receiver for package install/uninstall
registerReceiver(packageManagerReceiver, PackageUtil.getFilter())
NetworkProvider
.with(this)
.bind()
CommonUtil.cleanupInstallationSessions(applicationContext)
}
override fun onTerminate() {
NetworkProvider
.with(this)
.unbind()
super.onTerminate()
}
override fun onLowMemory() {
NetworkProvider
.with(this)
.unbind()
super.onLowMemory()
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

View File

@@ -39,7 +39,9 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.view.GravityCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.navigation.fragment.NavHostFragment
@@ -50,6 +52,7 @@ import androidx.navigation.ui.setupWithNavController
import com.aurora.Constants
import com.aurora.extensions.*
import com.aurora.gplayapi.data.models.AuthData
import com.aurora.store.data.model.NetworkStatus
import com.aurora.store.data.model.SelfUpdate
import com.aurora.store.data.providers.AuthProvider
import com.aurora.store.data.providers.NetworkProvider
@@ -68,7 +71,7 @@ import kotlinx.coroutines.launch
import java.lang.reflect.Modifier
class MainActivity : AppCompatActivity(), NetworkProvider.NetworkListener {
class MainActivity : AppCompatActivity() {
private lateinit var B: ActivityMainBinding
private lateinit var navController: NavController
@@ -92,32 +95,6 @@ class MainActivity : AppCompatActivity(), NetworkProvider.NetworkListener {
private lateinit var appConfig: AppBarConfiguration
override fun onConnected() {
runOnUiThread {
if (!supportFragmentManager.isDestroyed) {
val fragment = supportFragmentManager.findFragmentByTag(NetworkDialogSheet.TAG)
fragment?.let {
supportFragmentManager.beginTransaction().remove(fragment)
.commitAllowingStateLoss()
}
}
}
}
override fun onDisconnected() {
runOnUiThread {
if (!supportFragmentManager.isDestroyed) {
supportFragmentManager.beginTransaction()
.add(NetworkDialogSheet.newInstance(), NetworkDialogSheet.TAG)
.commitAllowingStateLoss()
}
}
}
override fun onReconnected() {
}
companion object {
@JvmStatic
private fun matchDestination(
@@ -142,6 +119,31 @@ class MainActivity : AppCompatActivity(), NetworkProvider.NetworkListener {
setContentView(B.root)
this.lifecycleScope.launch {
NetworkProvider(this@MainActivity).networkStatus.collect {
when(it) {
NetworkStatus.AVAILABLE -> {
if (!supportFragmentManager.isDestroyed) {
val fragment = supportFragmentManager
.findFragmentByTag(NetworkDialogSheet.TAG)
fragment?.let {
supportFragmentManager.beginTransaction()
.remove(fragment)
.commitAllowingStateLoss()
}
}
}
NetworkStatus.LOST -> {
if (!supportFragmentManager.isDestroyed) {
supportFragmentManager.beginTransaction()
.add(NetworkDialogSheet.newInstance(), NetworkDialogSheet.TAG)
.commitAllowingStateLoss()
}
}
}
}
}
authData = AuthProvider.with(this).getAuthData()
// Toolbar
@@ -290,14 +292,4 @@ class MainActivity : AppCompatActivity(), NetworkProvider.NetworkListener {
sheet.show(supportFragmentManager, SelfUpdateSheet.TAG)
}
}
override fun onStart() {
super.onStart()
NetworkProvider.addListener(this)
}
override fun onStop() {
NetworkProvider.removeListener(this)
super.onStop()
}
}

View File

@@ -0,0 +1,6 @@
package com.aurora.store.data.model
enum class NetworkStatus {
AVAILABLE,
LOST
}

View File

@@ -20,82 +20,57 @@
package com.aurora.store.data.providers
import android.content.Context
import com.aurora.store.data.SingletonHolder
import com.aurora.store.util.Log
import com.novoda.merlin.Merlin
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.util.Log
import com.aurora.extensions.isMAndAbove
import com.aurora.store.data.model.NetworkStatus
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
class NetworkProvider(var context: Context) {
@OptIn(DelicateCoroutinesApi::class)
class NetworkProvider(context: Context) {
companion object : SingletonHolder<NetworkProvider, Context>(::NetworkProvider) {
private val TAG = NetworkProvider::class.java.simpleName
private var networkListeners: MutableList<NetworkListener> = mutableListOf()
private val _networkStatus = MutableStateFlow(NetworkStatus.AVAILABLE)
val networkStatus = _networkStatus.asStateFlow()
fun addListener(networkListener: NetworkListener) {
Log.i("Network-Provider added to ${networkListener.javaClass.simpleName}")
networkListeners.add(networkListener)
}
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
fun removeListener(networkListener: NetworkListener) {
Log.i("Network-Provider removed from ${networkListener.javaClass.simpleName}")
networkListeners.remove(networkListener)
}
init {
networkStatus.launchIn(GlobalScope)
// Monitor network
connectivityManager.registerNetworkCallback(getNetworkRequest(),
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.d(TAG, "Network available!")
_networkStatus.value = NetworkStatus.AVAILABLE
}
override fun onLost(network: Network) {
super.onLost(network)
Log.d(TAG, "Network unavailable!")
_networkStatus.value = NetworkStatus.LOST
}
})
}
private var merlin: Merlin = Merlin.Builder()
.withAllCallbacks()
.build(context)
private fun getNetworkRequest(): NetworkRequest {
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
private var isDisconnected = true
fun bind() {
merlin.bind()
merlin.registerConnectable {
if (isDisconnected) {
isDisconnected = false
onReConnected()
} else {
onConnected()
}
if (isMAndAbove()) {
networkRequest.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}
merlin.registerDisconnectable {
isDisconnected = true
onDisconnected()
}
}
fun unbind() {
networkListeners.clear()
merlin.unbind()
Log.i("Network-Provider destroyed")
}
private fun onConnected() {
Log.i("Network-Provider connected")
isDisconnected = false
networkListeners.forEach {
it.onConnected()
}
}
private fun onReConnected() {
Log.i("Network-Provider reconnected")
networkListeners.forEach {
it.onReconnected()
}
}
private fun onDisconnected() {
Log.e("Network-Provider disconnected")
networkListeners.forEach {
it.onDisconnected()
}
}
interface NetworkListener {
fun onConnected()
fun onDisconnected()
fun onReconnected()
return networkRequest.build()
}
}

View File

@@ -33,10 +33,7 @@ import java.lang.reflect.Modifier
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel(application),
NetworkProvider.NetworkListener {
private lateinit var networkListener: NetworkProvider.NetworkListener
abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel(application) {
val responseCode = HttpClient.getPreferredClient().responseCode
@@ -51,26 +48,12 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
requestState = RequestState.Init
NetworkProvider.addListener(this)
// Start collecting response code for requests
responseCode.launchIn(viewModelScope)
}
abstract fun observe()
override fun onConnected() {
}
override fun onDisconnected() {
}
override fun onReconnected() {
redoLastNetworkTask()
}
private fun redoLastNetworkTask() {
when (requestState) {
RequestState.Pending -> {
@@ -81,10 +64,4 @@ abstract class BaseAndroidViewModel(application: Application) : AndroidViewModel
}
}
}
override fun onCleared() {
Log.i("${javaClass.simpleName} Destroyed")
NetworkProvider.removeListener(this)
super.onCleared()
}
}

View File

@@ -29,7 +29,7 @@ dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
jcenter() // Required for com.novoda:merlin:1.2.0
jcenter() // Required for androidx.tonyodev.fetch2
mavenCentral()
maven {
name 'JitPack'
@@ -42,4 +42,4 @@ dependencyResolutionManagement {
}
}
include ':app'
rootProject.name = "AuroraStore4"
rootProject.name = "AuroraStore4"