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 Diff line number Diff line
@@ -18,8 +18,12 @@

package foundation.e.apps

import android.app.usage.StorageStatsManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.StatFs
import android.os.storage.StorageManager
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
@@ -34,6 +38,7 @@ import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.apps.application.subFrags.ApplicationDialogFragment
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.purchase.AppPurchaseFragmentDirections
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.modules.CommonUtilsModule
import kotlinx.coroutines.launch
import java.io.File
import java.util.*

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@@ -161,11 +168,7 @@ class MainActivity : AppCompatActivity() {
        viewModel.downloadList.observe(this) { list ->
            list.forEach {
                if (it.status == Status.QUEUED) {
                    lifecycleScope.launch {
                        viewModel.updateAwaiting(it)
                        InstallWorkManager.enqueueWork(applicationContext, it)
                        Log.d(TAG, "===> onCreate: AWAITING ${it.name}")
                    }
                    handleFusedDownloadQueued(it, viewModel)
                }
            }
        }
@@ -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(
        viewModel: MainActivityViewModel,
        it: String
@@ -235,4 +259,39 @@ class MainActivity : AppCompatActivity() {
        binding.noInternet.visibility = View.VISIBLE
        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 Diff line number Diff line
@@ -162,7 +162,8 @@ class MainActivityViewModel @Inject constructor(
                    appIcon,
                    app.latest_version_code,
                    app.offer_type,
                    app.isFree
                    app.isFree,
                    app.originalSize
                )
            } catch (e: Exception) {
                if (e is ApiException.AppNotPurchased) {
@@ -198,7 +199,8 @@ class MainActivityViewModel @Inject constructor(
            appIcon,
            app.latest_version_code,
            app.offer_type,
            app.isFree
            app.isFree,
            app.originalSize
        )
        viewModelScope.launch {
            fusedManagerRepository.addFusedDownloadPurchaseNeeded(fusedDownload)
@@ -210,6 +212,10 @@ class MainActivityViewModel @Inject constructor(
        fusedManagerRepository.updateAwaiting(fusedDownload)
    }

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

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