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

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

Merge branch '2203-show_notification' into 'main'

feat: added notification during fetching content ratings

See merge request !459
parents a15613e1 4b50ce44
Loading
Loading
Loading
Loading
Loading
+50 −3
Original line number Original line Diff line number Diff line
@@ -19,17 +19,23 @@


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


import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.ContentProvider
import android.content.ContentProvider
import android.content.ContentValues
import android.content.ContentValues
import android.content.Context
import android.content.UriMatcher
import android.content.UriMatcher
import android.database.Cursor
import android.database.Cursor
import android.database.MatrixCursor
import android.database.MatrixCursor
import android.net.Uri
import android.net.Uri
import android.os.Build
import androidx.core.app.NotificationCompat
import dagger.hilt.EntryPoint
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.BuildConfig
import foundation.e.apps.BuildConfig
import foundation.e.apps.R
import foundation.e.apps.contract.ParentalControlContract.COLUMN_LOGIN_TYPE
import foundation.e.apps.contract.ParentalControlContract.COLUMN_LOGIN_TYPE
import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME
import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME
import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST
import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST
@@ -48,6 +54,7 @@ import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withContext
import timber.log.Timber
import timber.log.Timber
import javax.inject.Inject


class AgeRatingProvider : ContentProvider() {
class AgeRatingProvider : ContentProvider() {


@@ -59,6 +66,13 @@ class AgeRatingProvider : ContentProvider() {
        fun provideContentRatingsRepository(): ContentRatingsRepository
        fun provideContentRatingsRepository(): ContentRatingsRepository
        fun provideValidateAppAgeLimitUseCase(): ValidateAppAgeLimitUseCase
        fun provideValidateAppAgeLimitUseCase(): ValidateAppAgeLimitUseCase
        fun provideDataStoreManager(): DataStoreManager
        fun provideDataStoreManager(): DataStoreManager

        fun provideNotificationManager(): NotificationManager
    }

    companion object {
        private const val CHANNEL_ID = "applounge_provider"
        private const val NOTIFICATION_ID = 77
    }
    }


    private lateinit var authenticatorRepository: AuthenticatorRepository
    private lateinit var authenticatorRepository: AuthenticatorRepository
@@ -66,6 +80,7 @@ class AgeRatingProvider : ContentProvider() {
    private lateinit var contentRatingsRepository: ContentRatingsRepository
    private lateinit var contentRatingsRepository: ContentRatingsRepository
    private lateinit var validateAppAgeLimitUseCase: ValidateAppAgeLimitUseCase
    private lateinit var validateAppAgeLimitUseCase: ValidateAppAgeLimitUseCase
    private lateinit var dataStoreManager: DataStoreManager
    private lateinit var dataStoreManager: DataStoreManager
    private lateinit var notificationManager: NotificationManager


    private enum class UriCode(val code: Int) {
    private enum class UriCode(val code: Int) {
        LoginType(1),
        LoginType(1),
@@ -105,25 +120,56 @@ class AgeRatingProvider : ContentProvider() {


    private fun getAgeRatings(): Cursor {
    private fun getAgeRatings(): Cursor {
        val cursor = MatrixCursor(arrayOf(COLUMN_PACKAGE_NAME))
        val cursor = MatrixCursor(arrayOf(COLUMN_PACKAGE_NAME))
        val packageNames = appLoungePackageManager.getAllUserApps().map { it.packageName }

        runBlocking {
        runBlocking {
            showNotification()
            val packageNames = appLoungePackageManager.getAllUserApps().map { it.packageName }
            Timber.d("Start preparing blocklist from ${packageNames.size} apps.")
            Timber.d("Start preparing blocklist from ${packageNames.size} apps.")
            withContext(IO) {
            withContext(IO) {
                try {
                try {
                    if (packageNames.isEmpty()) return@withContext cursor
                    if (packageNames.isEmpty()) return@withContext cursor

                    ensureAgeGroupDataExists()
                    if (!setupAuthDataIfExists()) return@withContext null
                    if (!setupAuthDataIfExists()) return@withContext null


                    ensureAgeGroupDataExists()
                    compileAppBlockList(cursor, packageNames)
                    compileAppBlockList(cursor, packageNames)
                } catch (e: Exception) {
                } catch (e: Exception) {
                    Timber.e("AgeRatingProvider", "Error fetching age ratings", e)
                    Timber.e("AgeRatingProvider", "Error fetching age ratings", e)
                }
                }
            }
            }

            hideNotification()
        }
        }

        return cursor
        return cursor
    }
    }


    private fun showNotification() {
        val context = context ?: return
        val title = context.getString(R.string.app_name)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                title,
                NotificationManager.IMPORTANCE_HIGH
            )
            channel.setSound(null, null)
            notificationManager.createNotificationChannel(channel)
        }

        val builder = NotificationCompat.Builder(context, CHANNEL_ID)
            .setSmallIcon(R.drawable.app_lounge_notification_icon)
            .setContentTitle(title)
            .setContentText(context.getString(R.string.message_fetching_content_rating))
            .setPriority(NotificationCompat.PRIORITY_HIGH)

        notificationManager.notify(NOTIFICATION_ID, builder.build())
    }

    private fun hideNotification() {
        notificationManager.cancel(NOTIFICATION_ID)
    }

    private suspend fun ensureAgeGroupDataExists() {
    private suspend fun ensureAgeGroupDataExists() {
        withContext(IO) {
        withContext(IO) {
            val deferredFetchRatings = async {
            val deferredFetchRatings = async {
@@ -209,6 +255,7 @@ class AgeRatingProvider : ContentProvider() {
        contentRatingsRepository = hiltEntryPoint.provideContentRatingsRepository()
        contentRatingsRepository = hiltEntryPoint.provideContentRatingsRepository()
        validateAppAgeLimitUseCase = hiltEntryPoint.provideValidateAppAgeLimitUseCase()
        validateAppAgeLimitUseCase = hiltEntryPoint.provideValidateAppAgeLimitUseCase()
        dataStoreManager = hiltEntryPoint.provideDataStoreManager()
        dataStoreManager = hiltEntryPoint.provideDataStoreManager()
        notificationManager = hiltEntryPoint.provideNotificationManager()


        return true
        return true
    }
    }
+1 −0
Original line number Original line Diff line number Diff line
@@ -231,5 +231,6 @@
    <!-- F-Droid Anti-Features-->
    <!-- F-Droid Anti-Features-->
    <string name="nsfw_dialog_title">Content Warning</string>
    <string name="nsfw_dialog_title">Content Warning</string>
    <string name="nsfw_dialog_message">The app may contain nudity, profanity, slurs, violence, intense sexuality, political incorrectness, or other potentially disturbing subject matter. This is especially relevant in environments like workplaces, schools, religious and family settings.</string>
    <string name="nsfw_dialog_message">The app may contain nudity, profanity, slurs, violence, intense sexuality, political incorrectness, or other potentially disturbing subject matter. This is especially relevant in environments like workplaces, schools, religious and family settings.</string>
    <string name="message_fetching_content_rating">Gathering content rating for all the apps you\'ve installed.</string>


</resources>
</resources>