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

Commit 8bd706b5 authored by Hasib Prince's avatar Hasib Prince
Browse files

App lounge: UI and logics for blocked app

parent 5076760a
Loading
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope
import com.aurora.gplayapi.data.models.AuthData
import com.google.gson.Gson
import dagger.hilt.android.lifecycle.HiltViewModel
import foundation.e.apps.api.BlockedAppRepository
import foundation.e.apps.api.fdroid.FdroidRepository
import foundation.e.apps.api.fdroid.models.FdroidEntity
import foundation.e.apps.api.fused.data.FusedApp
@@ -27,6 +28,7 @@ class AppInfoFetchViewModel @Inject constructor(
    private val fdroidRepository: FdroidRepository,
    private val gPlayAPIRepository: GPlayAPIRepository,
    private val dataStoreModule: DataStoreModule,
    private val blockedAppRepository: BlockedAppRepository,
    private val gson: Gson
) : ViewModel() {

@@ -83,4 +85,8 @@ class AppInfoFetchViewModel @Inject constructor(
            }
        }
    }

    fun isAppInBlockedList(fusedApp: FusedApp): Boolean {
        return blockedAppRepository.getBlockedAppPackages().contains(fusedApp.package_name)
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.Application
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import dagger.hilt.android.HiltAndroidApp
import foundation.e.apps.api.BlockedAppRepository
import foundation.e.apps.manager.pkg.PkgManagerBR
import foundation.e.apps.manager.pkg.PkgManagerModule
import foundation.e.apps.manager.workmanager.InstallWorkManager
@@ -46,6 +47,9 @@ class AppLoungeApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var dataStoreModule: DataStoreModule

    @Inject
    lateinit var blockedAppRepository: BlockedAppRepository

    override fun onCreate() {
        super.onCreate()

@@ -60,6 +64,8 @@ class AppLoungeApplication : Application(), Configuration.Provider {
                dataStoreModule.saveTOCStatus(false, "")
            }
        }

        blockedAppRepository.fetchUpdateOfAppWarningList()
    }

    override fun getWorkManagerConfiguration() =
+21 −0
Original line number Diff line number Diff line
package foundation.e.apps.api

import foundation.e.apps.api.cleanapk.data.download.DownloadManager
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class BlockedAppRepository @Inject constructor(private val downloadManager: DownloadManager) {

    companion object {
        const val APP_WARNING_LIST_FILE_URL = "https://gitlab.e.foundation/e/os/blocklist-app-lounge/-/raw/main/app-lounge-warning-list.json?inline=false"
    }

    fun getBlockedAppPackages(): List<String> {
        return listOf()
    }

    fun fetchUpdateOfAppWarningList() {
        downloadManager.downloadFile(APP_WARNING_LIST_FILE_URL, "app-lounge-warning-list.json")
    }
}
 No newline at end of file
+83 −0
Original line number Diff line number Diff line
package foundation.e.apps.api.cleanapk.data.download

import android.app.DownloadManager
import android.net.Uri
import android.util.Log
import foundation.e.apps.manager.workmanager.InstallAppWorker
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach
import java.io.File
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

@Singleton
class DownloadManager @Inject constructor(
    private val downloadManager: DownloadManager,
    @Named("cacheDir") private val cacheDir: String,
    private val downloadManagerQuery: DownloadManager.Query,
    ) {
    private var isDownloading = false

    fun downloadFile(url: String, fileName: String): Long {
        val directoryFile = File(cacheDir)
        val downloadFile = File("$cacheDir/$fileName")
        if(!directoryFile.exists()) {
            directoryFile.mkdirs()
        }
//        if(downloadFile.exists()) {
//            downloadFile.delete()
//        }
        val request = DownloadManager.Request(Uri.parse(url))
            .setTitle("Downloading...")
            .setDestinationUri(Uri.fromFile(downloadFile))
        val downloadId = downloadManager.enqueue(request)
        isDownloading = true
        tickerFlow(1.seconds).onEach {
            checkDownloadProgress(downloadId)
        }
        return downloadId
    }

    private fun checkDownloadProgress(downloadId: Long, fileName: String = "") {
        downloadManager.query(downloadManagerQuery.setFilterById(downloadId))
            .use { cursor ->
                if (cursor.moveToFirst()) {
                    val id =
                        cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID))
                    val status =
                        cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                    val totalSizeBytes =
                        cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
                    val bytesDownloadedSoFar =
                        cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
                    Log.d(
                        "DownloadManager",
                        "checkDownloadProcess: $fileName=> $bytesDownloadedSoFar/$totalSizeBytes $status"
                    )
                    if (status == DownloadManager.STATUS_FAILED) {
                        Log.d(
                            "DownloadManager",
                            "Download Failed: $fileName=> $bytesDownloadedSoFar/$totalSizeBytes $status"
                        )
                    } else if(status == DownloadManager.STATUS_SUCCESSFUL) {
                        Log.d(
                            "DownloadManager",
                            "Download Successful: $fileName=> $bytesDownloadedSoFar/$totalSizeBytes $status"
                        )
                    }
                }
            }
    }

    private fun tickerFlow(period: Duration, initialDelay: Duration = Duration.ZERO) = flow {
        delay(initialDelay)
        while (isDownloading) {
            emit(Unit)
            delay(period)
        }
    }
}
 No newline at end of file
+35 −9
Original line number Diff line number Diff line
@@ -25,7 +25,9 @@ import android.os.Bundle
import android.text.Html
import android.text.format.Formatter
import android.util.Log
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
@@ -44,11 +46,7 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textview.MaterialTextView
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.apps.AppInfoFetchViewModel
import foundation.e.apps.MainActivity
import foundation.e.apps.MainActivityViewModel
import foundation.e.apps.PrivacyInfoViewModel
import foundation.e.apps.R
import foundation.e.apps.*
import foundation.e.apps.api.cleanapk.CleanAPKInterface
import foundation.e.apps.api.fused.data.FusedApp
import foundation.e.apps.application.model.ApplicationScreenshotsRVAdapter
@@ -65,6 +63,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject


@AndroidEntryPoint
class ApplicationFragment : Fragment(R.layout.fragment_application) {

@@ -256,6 +255,10 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                }
            }

            if (appInfoFetchViewModel.isAppInBlockedList(it)) {
                binding.snackbarLayout.visibility = View.VISIBLE
            }

            observeDownloadStatus(view)
            fetchAppTracker(it)
        }
@@ -414,6 +417,7 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
            text = when {
                mainActivityViewModel.checkUnsupportedApplication(fusedApp) ->
                    getString(R.string.not_available)
                appInfoFetchViewModel.isAppInBlockedList(fusedApp) -> getString(R.string.force_installation)
                fusedApp.isFree -> getString(R.string.install)
                else -> fusedApp.price
            }
@@ -423,15 +427,19 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
                }
                applicationIcon?.let {
                    if (fusedApp.isFree) {
                        mainActivityViewModel.getApplication(fusedApp, it)
                        installApplication(fusedApp, it)
                    } else {
                        if (!mainActivityViewModel.shouldShowPaidAppsSnackBar(fusedApp)) {
                            ApplicationDialogFragment(
                                title = getString(R.string.dialog_title_paid_app, fusedApp.name),
                                message = getString(R.string.dialog_paidapp_message, fusedApp.name, fusedApp.price),
                                message = getString(
                                    R.string.dialog_paidapp_message,
                                    fusedApp.name,
                                    fusedApp.price
                                ),
                                positiveButtonText = getString(R.string.dialog_confirm),
                                positiveButtonAction = {
                                    mainActivityViewModel.getApplication(fusedApp, it)
                                    installApplication(fusedApp, it)
                                },
                                cancelButtonText = getString(R.string.dialog_cancel),
                            ).show(childFragmentManager, "ApplicationFragment")
@@ -444,6 +452,24 @@ class ApplicationFragment : Fragment(R.layout.fragment_application) {
        appSize.visibility = View.VISIBLE
    }

    private fun installApplication(
        fusedApp: FusedApp,
        it: ImageView
    ) {
        if (appInfoFetchViewModel.isAppInBlockedList(fusedApp)) {
            ApplicationDialogFragment(
                title = getString(R.string.this_app_may_not_work_properly),
                message = getString(R.string.may_not_work_warning_message),
                positiveButtonText = getString(R.string.ok),
                positiveButtonAction = {
                    mainActivityViewModel.getApplication(fusedApp, it)
                }
            )
        } else {
            mainActivityViewModel.getApplication(fusedApp, it)
        }
    }

    private fun handleUpdatable(
        installButton: MaterialButton,
        view: View,
Loading