Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5cfb5f6 authored by Hasib Prince's avatar Hasib Prince
Browse files

Merge branch '1837-check_connectivity' into 'main'

fixed: checking interent connectivity

See merge request !415
parents f9d76fc7 c0935caa
Loading
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -80,8 +80,6 @@ class MainActivity : AppCompatActivity() {

        val (bottomNavigationView, navController) = setupBootomNav()

        var hasInternet = true

        setupViewModels()

        setupNavigations(navController)
@@ -94,13 +92,14 @@ class MainActivity : AppCompatActivity() {
            viewModel.createNotificationChannels()
        }


        viewModel.setupConnectivityManager(this.applicationContext)

        hasInternet = observeInternetConnections(hasInternet)
        observeInternetConnections()

        observeAuthObjects(navController)

        setupDestinationChangedListener(navController, hasInternet, bottomNavigationView)
        setupDestinationChangedListener(navController, bottomNavigationView)

        observePurchaseAppPage()

@@ -121,6 +120,7 @@ class MainActivity : AppCompatActivity() {
        observeEvents()
    }


    private fun setupNavigations(navController: NavController) {
        val navOptions = NavOptions.Builder()
            .setPopUpTo(R.id.navigation_resource, true)
@@ -207,25 +207,22 @@ class MainActivity : AppCompatActivity() {
        }
    }

    private fun observeInternetConnections(hasInternet: Boolean): Boolean {
        var mutableHasInternet = hasInternet
        viewModel.internetConnection.observe(this) { isInternetAvailable ->
            mutableHasInternet = isInternetAvailable
    private fun observeInternetConnections() {
        viewModel.internetConnection.distinctUntilChanged().observe(this) { isInternetAvailable ->
            Timber.d("Observe internetConnection: $isInternetAvailable")
            if (isInternetAvailable) {
                binding.noInternet.visibility = View.GONE
                binding.fragment.visibility = View.VISIBLE
            }
        }
        return mutableHasInternet
    }

    private fun setupDestinationChangedListener(
        navController: NavController,
        hasInternet: Boolean,
        bottomNavigationView: BottomNavigationView
    ) {
        navController.addOnDestinationChangedListener { _, destination, _ ->
            if (!hasInternet) {
            if (viewModel.internetConnection.value == false) {
                showNoInternet()
            }
            when (destination.id) {
+3 −70
Original line number Diff line number Diff line
@@ -21,9 +21,6 @@ package foundation.e.apps.ui
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
@@ -31,7 +28,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.viewModelScope
import com.aurora.gplayapi.data.models.AuthData
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -50,9 +46,7 @@ import foundation.e.apps.install.pkg.PWAManager
import foundation.e.apps.install.pkg.AppLoungePackageManager
import foundation.e.apps.install.workmanager.AppInstallProcessor
import foundation.e.apps.data.preference.getSync
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import foundation.e.apps.utils.NetworkStatusManager
import kotlinx.coroutines.launch
import javax.inject.Inject

@@ -74,6 +68,7 @@ class MainActivityViewModel @Inject constructor(
    val purchaseAppLiveData: LiveData<FusedDownload> = _purchaseAppLiveData
    val isAppPurchased: MutableLiveData<String> = MutableLiveData()
    val purchaseDeclined: MutableLiveData<String> = MutableLiveData()
    lateinit var internetConnection: LiveData<Boolean>

    var gPlayAuthData = AuthData("", "")

@@ -210,69 +205,7 @@ class MainActivityViewModel @Inject constructor(
    }

    fun setupConnectivityManager(context: Context) {
        connectivityManager =
            context.getSystemService(ConnectivityManager::class.java) as ConnectivityManager
    }

    val internetConnection =
        callbackFlow {
            if (!this@MainActivityViewModel::connectivityManager.isInitialized) {
                awaitClose { }
                return@callbackFlow
            }

            sendInternetStatus(connectivityManager)
            val networkCallback = getNetworkCallback(this)
            connectivityManager.registerNetworkCallback(networkRequest, networkCallback)

            awaitClose {
                connectivityManager.unregisterNetworkCallback(networkCallback)
            }
        }.asLiveData().distinctUntilChanged()

    private val networkRequest = NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
        .build()

    private fun getNetworkCallback(
        callbackFlowScope: ProducerScope<Boolean>,
    ): ConnectivityManager.NetworkCallback {
        return object : ConnectivityManager.NetworkCallback() {

            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                callbackFlowScope.sendInternetStatus(connectivityManager)
            }

            override fun onCapabilitiesChanged(
                network: Network,
                networkCapabilities: NetworkCapabilities
            ) {
                super.onCapabilitiesChanged(network, networkCapabilities)
                callbackFlowScope.sendInternetStatus(connectivityManager)
            }

            override fun onLost(network: Network) {
                super.onLost(network)
                callbackFlowScope.sendInternetStatus(connectivityManager)
            }
        }
    }

    // protected to avoid SyntheticAccessor
    protected fun ProducerScope<Boolean>.sendInternetStatus(connectivityManager: ConnectivityManager) {

        val capabilities =
            connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)

        val hasInternet =
            capabilities != null &&
                capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)

        trySend(hasInternet)
        internetConnection = NetworkStatusManager.init(context)
    }

    fun updateStatusOfFusedApps(
+91 −0
Original line number Diff line number Diff line
/*
 *  Copyright MURENA SAS 2024
 *  Apps  Quickly and easily install Android apps onto your device!
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.utils

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import androidx.lifecycle.MutableLiveData
import timber.log.Timber

object NetworkStatusManager {

    private lateinit var connectivityManager: ConnectivityManager
    private var internetConnectionLiveData: MutableLiveData<Boolean> = MutableLiveData()

    /**
     * Registers for network callback with [ConnectivityManager]
     * @param context should be applicationContext
     * @return [MutableLiveData], holds the [Boolean] value as status of internet availability
     */
    fun init(context: Context): MutableLiveData<Boolean> {
        connectivityManager =
            context.getSystemService(ConnectivityManager::class.java) as ConnectivityManager

        val networkRequest = NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
            .build()

        connectivityManager.registerNetworkCallback(networkRequest, createNetworkCallback())

        return internetConnectionLiveData
    }

    private fun createNetworkCallback(
    ): ConnectivityManager.NetworkCallback {
        return object : ConnectivityManager.NetworkCallback() {

            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                Timber.d("Network: onAvailable: ${network.networkHandle}")
                sendInternetStatus(true)
            }

            override fun onCapabilitiesChanged(
                network: Network,
                networkCapabilities: NetworkCapabilities
            ) {
                super.onCapabilitiesChanged(network, networkCapabilities)
                val hasInternet =
                    networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
                            networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)

                Timber.d("Network: onCapabilitiesChanged: ${network.networkHandle}, hasInternet: $hasInternet")
                sendInternetStatus(hasInternet)
            }

            override fun onLost(network: Network) {
                super.onLost(network)
                Timber.d("Network: onLost: ${network.networkHandle}")
                sendInternetStatus(false)
            }

            private fun sendInternetStatus(hasInternet: Boolean?) {
                hasInternet?.let {
                    internetConnectionLiveData.postValue(it)
                }
            }
        }
    }
}