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

Commit 43b8aacc authored by Hasib Prince's avatar Hasib Prince
Browse files

App Lounge: storage and internet checking before install

parent f565a8ab
Loading
Loading
Loading
Loading
Loading
+64 −5
Original line number Original line Diff line number Diff line
@@ -18,8 +18,12 @@


package foundation.e.apps
package foundation.e.apps


import android.app.usage.StorageStatsManager
import android.os.Build
import android.os.Build
import android.os.Bundle
import android.os.Bundle
import android.os.Environment
import android.os.StatFs
import android.os.storage.StorageManager
import android.util.Log
import android.util.Log
import android.view.View
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
@@ -34,6 +38,7 @@ import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.apps.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.databinding.ActivityMainBinding
import foundation.e.apps.databinding.ActivityMainBinding
import foundation.e.apps.manager.database.fusedDownload.FusedDownload
import foundation.e.apps.manager.workmanager.InstallWorkManager
import foundation.e.apps.manager.workmanager.InstallWorkManager
import foundation.e.apps.purchase.AppPurchaseFragmentDirections
import foundation.e.apps.purchase.AppPurchaseFragmentDirections
import foundation.e.apps.setup.signin.SignInViewModel
import foundation.e.apps.setup.signin.SignInViewModel
@@ -42,6 +47,8 @@ import foundation.e.apps.utils.enums.Status
import foundation.e.apps.utils.enums.User
import foundation.e.apps.utils.enums.User
import foundation.e.apps.utils.modules.CommonUtilsModule
import foundation.e.apps.utils.modules.CommonUtilsModule
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import java.io.File
import java.util.*


@AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity() {
@@ -161,11 +168,7 @@ class MainActivity : AppCompatActivity() {
        viewModel.downloadList.observe(this) { list ->
        viewModel.downloadList.observe(this) { list ->
            list.forEach {
            list.forEach {
                if (it.status == Status.QUEUED) {
                if (it.status == Status.QUEUED) {
                    lifecycleScope.launch {
                    handleFusedDownloadQueued(it, viewModel)
                        viewModel.updateAwaiting(it)
                        InstallWorkManager.enqueueWork(applicationContext, it)
                        Log.d(TAG, "===> onCreate: AWAITING ${it.name}")
                    }
                }
                }
            }
            }
        }
        }
@@ -213,6 +216,27 @@ class MainActivity : AppCompatActivity() {
        }
        }
    }
    }


    private fun handleFusedDownloadQueued(
        it: FusedDownload,
        viewModel: MainActivityViewModel
    ) {
        lifecycleScope.launch {
            if (!checkStorageAvailability(it)) {
                showSnackbarMessage(getString(R.string.not_enough_storage))
                viewModel.updateUnAvailable(it)
                return@launch
            }
            if (viewModel.internetConnection.value == false) {
                showNoInternet()
                viewModel.updateUnAvailable(it)
                return@launch
            }
            viewModel.updateAwaiting(it)
            InstallWorkManager.enqueueWork(applicationContext, it)
            Log.d(TAG, "===> onCreate: AWAITING ${it.name}")
        }
    }

    private fun startInstallationOfPurchasedApp(
    private fun startInstallationOfPurchasedApp(
        viewModel: MainActivityViewModel,
        viewModel: MainActivityViewModel,
        it: String
        it: String
@@ -235,4 +259,39 @@ class MainActivity : AppCompatActivity() {
        binding.noInternet.visibility = View.VISIBLE
        binding.noInternet.visibility = View.VISIBLE
        binding.fragment.visibility = View.GONE
        binding.fragment.visibility = View.GONE
    }
    }

    // TODO: move storage availability code to FileManager Class
    private fun checkStorageAvailability(fusedDownload: FusedDownload): Boolean {
        var availableSpace = 0L
        availableSpace = calculateAvailableDiskSpace()
        return availableSpace > fusedDownload.appSize + (500 * (1000 * 1000))
    }

    private fun calculateAvailableDiskSpace(): Long {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val storageManager = getSystemService(STORAGE_SERVICE) as StorageManager
            val statsManager = getSystemService(STORAGE_STATS_SERVICE) as StorageStatsManager
            val uuid = storageManager.primaryStorageVolume.uuid
            try {
                if (uuid != null) {
                    statsManager.getFreeBytes(UUID.fromString(uuid))
                } else {
                    statsManager.getFreeBytes(StorageManager.UUID_DEFAULT)
                }
            } catch (e: Exception) {
                Log.e(TAG, "calculateAvailableDiskSpace: ${e.stackTraceToString()}")
                getAvailableInternalMemorySize()
            }
        } else {
            getAvailableInternalMemorySize()
        }
    }

    private fun getAvailableInternalMemorySize(): Long {
        val path: File = Environment.getDataDirectory()
        val stat = StatFs(path.path)
        val blockSize = stat.blockSizeLong
        val availableBlocks = stat.availableBlocksLong
        return availableBlocks * blockSize
    }
}
}
+8 −2
Original line number Original line Diff line number Diff line
@@ -162,7 +162,8 @@ class MainActivityViewModel @Inject constructor(
                    appIcon,
                    appIcon,
                    app.latest_version_code,
                    app.latest_version_code,
                    app.offer_type,
                    app.offer_type,
                    app.isFree
                    app.isFree,
                    app.originalSize
                )
                )
            } catch (e: Exception) {
            } catch (e: Exception) {
                if (e is ApiException.AppNotPurchased) {
                if (e is ApiException.AppNotPurchased) {
@@ -198,7 +199,8 @@ class MainActivityViewModel @Inject constructor(
            appIcon,
            appIcon,
            app.latest_version_code,
            app.latest_version_code,
            app.offer_type,
            app.offer_type,
            app.isFree
            app.isFree,
            app.originalSize
        )
        )
        viewModelScope.launch {
        viewModelScope.launch {
            fusedManagerRepository.addFusedDownloadPurchaseNeeded(fusedDownload)
            fusedManagerRepository.addFusedDownloadPurchaseNeeded(fusedDownload)
@@ -210,6 +212,10 @@ class MainActivityViewModel @Inject constructor(
        fusedManagerRepository.updateAwaiting(fusedDownload)
        fusedManagerRepository.updateAwaiting(fusedDownload)
    }
    }


    suspend fun updateUnAvailable(fusedDownload: FusedDownload) {
        fusedManagerRepository.updateUnavailable(fusedDownload)
    }

    suspend fun updateAwaitingForPurchasedApp(packageName: String): FusedDownload? {
    suspend fun updateAwaitingForPurchasedApp(packageName: String): FusedDownload? {
        val fusedDownload = fusedManagerRepository.getFusedDownload(packageName = packageName)
        val fusedDownload = fusedManagerRepository.getFusedDownload(packageName = packageName)
        authData.value?.let {
        authData.value?.let {
+1 −0
Original line number Original line Diff line number Diff line
@@ -639,6 +639,7 @@ class FusedAPIImpl @Inject constructor(
            offer_type = this.offerType,
            offer_type = this.offerType,
            origin = Origin.GPLAY,
            origin = Origin.GPLAY,
            shareUrl = this.shareUrl,
            shareUrl = this.shareUrl,
            originalSize = this.size,
            appSize = Formatter.formatFileSize(context, this.size),
            appSize = Formatter.formatFileSize(context, this.size),
            isFree = this.isFree,
            isFree = this.isFree,
            price = this.price
            price = this.price
+1 −0
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ data class FusedApp(
    var status: Status = Status.UNAVAILABLE,
    var status: Status = Status.UNAVAILABLE,
    var origin: Origin = Origin.CLEANAPK,
    var origin: Origin = Origin.CLEANAPK,
    val shareUrl: String = String(),
    val shareUrl: String = String(),
    val originalSize: Long = 0,
    val appSize: String = String(),
    val appSize: String = String(),
    var source: String = String(),
    var source: String = String(),
    val price: String = String(),
    val price: String = String(),
+2 −1
Original line number Original line Diff line number Diff line
@@ -20,5 +20,6 @@ data class FusedDownload(
    val iconByteArray: String = String(),
    val iconByteArray: String = String(),
    val versionCode: Int = 1,
    val versionCode: Int = 1,
    val offerType: Int = -1,
    val offerType: Int = -1,
    val isFree: Boolean = true
    val isFree: Boolean = true,
    val appSize: Long = 0
)
)
Loading