Loading app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt +2 −1 Original line number Diff line number Diff line Loading @@ -143,8 +143,9 @@ class AppInstallProcessor @Inject constructor( if (ageLimitValidationResult.data?.isValid != true) { if (ageLimitValidationResult.isSuccess()) { awaitInvokeAgeLimitEvent(appInstall.name) Timber.d(" ageLimitValidationResult = $ageLimitValidationResult.") if (ageLimitValidationResult.data?.requestPin == true){ val isAuthenticated = ParentalControlAuthenticator.awaitAuthentication() val isAuthenticated = ParentalControlAuthenticator.awaitAuthentication(appInstall) if (isAuthenticated) { ageLimitValidationResult.setData(ContentRatingValidity(true)) } Loading app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +39 −0 Original line number Diff line number Diff line Loading @@ -27,13 +27,16 @@ import android.database.Cursor import android.database.MatrixCursor import android.net.Uri import androidx.core.app.NotificationCompat import com.aurora.gplayapi.data.models.ContentRating import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.android.EntryPointAccessors import dagger.hilt.components.SingletonComponent import foundation.e.apps.R import foundation.e.apps.contract.ParentalControlContract.COLUMN_AGE_GROUP import foundation.e.apps.contract.ParentalControlContract.COLUMN_LOGIN_TYPE import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME import foundation.e.apps.contract.ParentalControlContract.PATH_AGE_GROUP import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST import foundation.e.apps.contract.ParentalControlContract.PATH_LOGIN_TYPE import foundation.e.apps.data.ResultSupreme Loading @@ -57,6 +60,7 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import timber.log.Timber import kotlin.collections.set class AgeRatingProvider : ContentProvider() { Loading Loading @@ -93,6 +97,7 @@ class AgeRatingProvider : ContentProvider() { private enum class UriCode(val code: Int) { LoginType(1), AgeRating(2), AgeGroup(3), ; } Loading @@ -100,6 +105,7 @@ class AgeRatingProvider : ContentProvider() { UriMatcher(UriMatcher.NO_MATCH).apply { addURI(AUTHORITY, PATH_LOGIN_TYPE, UriCode.LoginType.code) addURI(AUTHORITY, PATH_BLOCKLIST, UriCode.AgeRating.code) addURI(AUTHORITY, PATH_AGE_GROUP, UriCode.AgeGroup.code) } } Loading @@ -114,6 +120,7 @@ class AgeRatingProvider : ContentProvider() { return when (code) { UriCode.LoginType.code -> getLoginType() UriCode.AgeRating.code -> getAgeRatings() UriCode.AgeGroup.code -> getAgeGroup(uri.lastPathSegment ?: "", selection, selectionArgs) else -> null } } Loading Loading @@ -149,6 +156,38 @@ class AgeRatingProvider : ContentProvider() { return cursor } private fun getAgeGroup(packageName: String, filterSelection: String?, filterSelectionArgs: Array<out String>?): Cursor { Timber.d("Fetching content rating for ${packageName}") val columnNames = arrayOf(COLUMN_AGE_GROUP) val matrixCursor = MatrixCursor(columnNames) runBlocking { showNotification() val fetchedContentRating = gPlayContentRatingRepository.getEnglishContentRating(packageName) Timber.d("Fetched content rating - ${packageName} - ${fetchedContentRating?.id}") val contentRatingDb = contentRatingDao.getContentRating(packageName) Timber.d("Content rating from DB - ${packageName} - ${contentRatingDb?.ratingId}") var app = ContentRating( id = contentRatingDb?.ratingId ?: "", title = contentRatingDb?.ratingTitle ?: "", ) Timber.d("Content rating - ${app.title}") matrixCursor.addRow(arrayOf(app.title)) hideNotification() } return matrixCursor } private fun showNotification() { val context = context ?: return val title = context.getString(R.string.app_name) Loading app/src/main/java/foundation/e/apps/utils/ParentalControlAuthenticator.kt +6 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package foundation.e.apps.utils import android.content.Intent import androidx.activity.result.ActivityResultLauncher import foundation.e.apps.data.install.models.AppInstall import kotlinx.coroutines.CompletableDeferred import timber.log.Timber Loading @@ -13,6 +14,8 @@ object ParentalControlAuthenticator { private const val KEY_PARENTAL_CONTROL_AUTHENTICATION = "foundation.e.parentalcontrol.START_AUTHENTICATE" //Parental Control intent private const val KEY_PARENTAL_CONTROL_PACKAGE_NAME = "package_name" private const val KEY_PARENTAL_CONTROL_AGE_GROUP = "age_group" const val KEY_PARENTAL_CONTROL_RESULT = "authentication_result" //Parental Control Key private var launcher: ActivityResultLauncher<Intent>? = null Loading @@ -22,10 +25,12 @@ object ParentalControlAuthenticator { this.launcher = launcher } suspend fun awaitAuthentication(): Boolean { suspend fun awaitAuthentication(appInstall: AppInstall): Boolean { authResultDeferred = CompletableDeferred() launcher?.let { val intent = Intent(KEY_PARENTAL_CONTROL_AUTHENTICATION) intent.putExtra(KEY_PARENTAL_CONTROL_PACKAGE_NAME, appInstall.packageName) intent.putExtra(KEY_PARENTAL_CONTROL_AGE_GROUP, appInstall.contentRating) it.launch(intent) } ?: run { Timber.e("Err: the launcher is NOT started") Loading parental-control-data/src/main/java/foundation/e/apps/contract/ParentalControlContract.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ package foundation.e.apps.contract object ParentalControlContract { const val COLUMN_PACKAGE_NAME = "package_name" const val COLUMN_LOGIN_TYPE = "login_type" const val COLUMN_AGE_GROUP = "age_group" const val PATH_LOGIN_TYPE = "login_type" const val PATH_BLOCKLIST = "block_list" const val PATH_AGE_GROUP = "age_group/*" } Loading
app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt +2 −1 Original line number Diff line number Diff line Loading @@ -143,8 +143,9 @@ class AppInstallProcessor @Inject constructor( if (ageLimitValidationResult.data?.isValid != true) { if (ageLimitValidationResult.isSuccess()) { awaitInvokeAgeLimitEvent(appInstall.name) Timber.d(" ageLimitValidationResult = $ageLimitValidationResult.") if (ageLimitValidationResult.data?.requestPin == true){ val isAuthenticated = ParentalControlAuthenticator.awaitAuthentication() val isAuthenticated = ParentalControlAuthenticator.awaitAuthentication(appInstall) if (isAuthenticated) { ageLimitValidationResult.setData(ContentRatingValidity(true)) } Loading
app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +39 −0 Original line number Diff line number Diff line Loading @@ -27,13 +27,16 @@ import android.database.Cursor import android.database.MatrixCursor import android.net.Uri import androidx.core.app.NotificationCompat import com.aurora.gplayapi.data.models.ContentRating import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.android.EntryPointAccessors import dagger.hilt.components.SingletonComponent import foundation.e.apps.R import foundation.e.apps.contract.ParentalControlContract.COLUMN_AGE_GROUP import foundation.e.apps.contract.ParentalControlContract.COLUMN_LOGIN_TYPE import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME import foundation.e.apps.contract.ParentalControlContract.PATH_AGE_GROUP import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST import foundation.e.apps.contract.ParentalControlContract.PATH_LOGIN_TYPE import foundation.e.apps.data.ResultSupreme Loading @@ -57,6 +60,7 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import timber.log.Timber import kotlin.collections.set class AgeRatingProvider : ContentProvider() { Loading Loading @@ -93,6 +97,7 @@ class AgeRatingProvider : ContentProvider() { private enum class UriCode(val code: Int) { LoginType(1), AgeRating(2), AgeGroup(3), ; } Loading @@ -100,6 +105,7 @@ class AgeRatingProvider : ContentProvider() { UriMatcher(UriMatcher.NO_MATCH).apply { addURI(AUTHORITY, PATH_LOGIN_TYPE, UriCode.LoginType.code) addURI(AUTHORITY, PATH_BLOCKLIST, UriCode.AgeRating.code) addURI(AUTHORITY, PATH_AGE_GROUP, UriCode.AgeGroup.code) } } Loading @@ -114,6 +120,7 @@ class AgeRatingProvider : ContentProvider() { return when (code) { UriCode.LoginType.code -> getLoginType() UriCode.AgeRating.code -> getAgeRatings() UriCode.AgeGroup.code -> getAgeGroup(uri.lastPathSegment ?: "", selection, selectionArgs) else -> null } } Loading Loading @@ -149,6 +156,38 @@ class AgeRatingProvider : ContentProvider() { return cursor } private fun getAgeGroup(packageName: String, filterSelection: String?, filterSelectionArgs: Array<out String>?): Cursor { Timber.d("Fetching content rating for ${packageName}") val columnNames = arrayOf(COLUMN_AGE_GROUP) val matrixCursor = MatrixCursor(columnNames) runBlocking { showNotification() val fetchedContentRating = gPlayContentRatingRepository.getEnglishContentRating(packageName) Timber.d("Fetched content rating - ${packageName} - ${fetchedContentRating?.id}") val contentRatingDb = contentRatingDao.getContentRating(packageName) Timber.d("Content rating from DB - ${packageName} - ${contentRatingDb?.ratingId}") var app = ContentRating( id = contentRatingDb?.ratingId ?: "", title = contentRatingDb?.ratingTitle ?: "", ) Timber.d("Content rating - ${app.title}") matrixCursor.addRow(arrayOf(app.title)) hideNotification() } return matrixCursor } private fun showNotification() { val context = context ?: return val title = context.getString(R.string.app_name) Loading
app/src/main/java/foundation/e/apps/utils/ParentalControlAuthenticator.kt +6 −1 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package foundation.e.apps.utils import android.content.Intent import androidx.activity.result.ActivityResultLauncher import foundation.e.apps.data.install.models.AppInstall import kotlinx.coroutines.CompletableDeferred import timber.log.Timber Loading @@ -13,6 +14,8 @@ object ParentalControlAuthenticator { private const val KEY_PARENTAL_CONTROL_AUTHENTICATION = "foundation.e.parentalcontrol.START_AUTHENTICATE" //Parental Control intent private const val KEY_PARENTAL_CONTROL_PACKAGE_NAME = "package_name" private const val KEY_PARENTAL_CONTROL_AGE_GROUP = "age_group" const val KEY_PARENTAL_CONTROL_RESULT = "authentication_result" //Parental Control Key private var launcher: ActivityResultLauncher<Intent>? = null Loading @@ -22,10 +25,12 @@ object ParentalControlAuthenticator { this.launcher = launcher } suspend fun awaitAuthentication(): Boolean { suspend fun awaitAuthentication(appInstall: AppInstall): Boolean { authResultDeferred = CompletableDeferred() launcher?.let { val intent = Intent(KEY_PARENTAL_CONTROL_AUTHENTICATION) intent.putExtra(KEY_PARENTAL_CONTROL_PACKAGE_NAME, appInstall.packageName) intent.putExtra(KEY_PARENTAL_CONTROL_AGE_GROUP, appInstall.contentRating) it.launch(intent) } ?: run { Timber.e("Err: the launcher is NOT started") Loading
parental-control-data/src/main/java/foundation/e/apps/contract/ParentalControlContract.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,7 +22,9 @@ package foundation.e.apps.contract object ParentalControlContract { const val COLUMN_PACKAGE_NAME = "package_name" const val COLUMN_LOGIN_TYPE = "login_type" const val COLUMN_AGE_GROUP = "age_group" const val PATH_LOGIN_TYPE = "login_type" const val PATH_BLOCKLIST = "block_list" const val PATH_AGE_GROUP = "age_group/*" }