From 0030e959d15b713c490e74e11dbb7b4fc87a2e3e Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Mon, 7 Aug 2023 20:49:43 +0530 Subject: [PATCH] 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 --- app/build.gradle | 4 - .../com/aurora/store/AuroraApplication.kt | 19 --- .../java/com/aurora/store/MainActivity.kt | 66 +++++------ .../aurora/store/data/model/NetworkStatus.kt | 6 + .../store/data/providers/NetworkProvider.kt | 111 +++++++----------- .../store/viewmodel/BaseAndroidViewModel.kt | 25 +--- settings.gradle | 4 +- 7 files changed, 81 insertions(+), 154 deletions(-) create mode 100644 app/src/main/java/com/aurora/store/data/model/NetworkStatus.kt diff --git a/app/build.gradle b/app/build.gradle index 0d71e4b11..7aa5fee4c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/com/aurora/store/AuroraApplication.kt b/app/src/main/java/com/aurora/store/AuroraApplication.kt index a64276b52..cb118f149 100644 --- a/app/src/main/java/com/aurora/store/AuroraApplication.kt +++ b/app/src/main/java/com/aurora/store/AuroraApplication.kt @@ -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 diff --git a/app/src/main/java/com/aurora/store/MainActivity.kt b/app/src/main/java/com/aurora/store/MainActivity.kt index f7c9d6738..ed183dabf 100644 --- a/app/src/main/java/com/aurora/store/MainActivity.kt +++ b/app/src/main/java/com/aurora/store/MainActivity.kt @@ -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() - } } diff --git a/app/src/main/java/com/aurora/store/data/model/NetworkStatus.kt b/app/src/main/java/com/aurora/store/data/model/NetworkStatus.kt new file mode 100644 index 000000000..b5c687b26 --- /dev/null +++ b/app/src/main/java/com/aurora/store/data/model/NetworkStatus.kt @@ -0,0 +1,6 @@ +package com.aurora.store.data.model + +enum class NetworkStatus { + AVAILABLE, + LOST +} diff --git a/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt b/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt index 4d7150cf1..268b3c9ef 100644 --- a/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt +++ b/app/src/main/java/com/aurora/store/data/providers/NetworkProvider.kt @@ -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) { + private val TAG = NetworkProvider::class.java.simpleName - private var networkListeners: MutableList = 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() } } diff --git a/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt index 7501f9675..239412364 100644 --- a/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt +++ b/app/src/main/java/com/aurora/store/viewmodel/BaseAndroidViewModel.kt @@ -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() - } } diff --git a/settings.gradle b/settings.gradle index 86276b882..d90c9ec0f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -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" \ No newline at end of file +rootProject.name = "AuroraStore4"