Merge branch 'dev'
This commit is contained in:
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2025 The Calyx Institute
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.aurora.store.compose.composable
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.provider.Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.dimensionResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.aurora.extensions.isTAndAbove
|
||||||
|
import com.aurora.extensions.toast
|
||||||
|
import com.aurora.store.BuildConfig
|
||||||
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.compose.preview.PreviewTemplate
|
||||||
|
import com.aurora.store.data.model.Permission
|
||||||
|
import com.aurora.store.data.model.PermissionType
|
||||||
|
import com.aurora.store.data.providers.PermissionProvider.Companion.isGranted
|
||||||
|
import com.aurora.store.util.PackageUtil
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
private const val TAG = "PermissionsScreen"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composable to request known set of permissions
|
||||||
|
* @param modifier Modifier to apply to the composable
|
||||||
|
* @param permissions Set of known permissions to request from the user
|
||||||
|
* @param onPermissionCallback Callback when a permission is granted or denied
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun PermissionList(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
permissions: Set<Permission>,
|
||||||
|
onPermissionCallback: (type: PermissionType) -> Unit = {}
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
var permissionRequested by rememberSaveable { mutableStateOf<PermissionType?>(null) }
|
||||||
|
|
||||||
|
@SuppressLint("InlinedApi", "BatteryLife")
|
||||||
|
val intentMap = mapOf(
|
||||||
|
PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(context),
|
||||||
|
PermissionType.INSTALL_UNKNOWN_APPS to PackageUtil.getInstallUnknownAppsIntent(),
|
||||||
|
PermissionType.DOZE_WHITELIST to Intent(
|
||||||
|
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||||
|
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
||||||
|
),
|
||||||
|
PermissionType.APP_LINKS to Intent(
|
||||||
|
ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
|
||||||
|
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun onResult() {
|
||||||
|
permissionRequested?.let {
|
||||||
|
if (!isGranted(context, it)) context.toast(R.string.permissions_denied)
|
||||||
|
onPermissionCallback(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val intentLauncher = rememberLauncherForActivityResult(
|
||||||
|
contract = ActivityResultContracts.StartActivityForResult(),
|
||||||
|
onResult = { onResult() }
|
||||||
|
)
|
||||||
|
val permissionLauncher = rememberLauncherForActivityResult(
|
||||||
|
contract = ActivityResultContracts.RequestPermission(),
|
||||||
|
onResult = {
|
||||||
|
when (permissionRequested) {
|
||||||
|
PermissionType.STORAGE_MANAGER -> {
|
||||||
|
intentLauncher.launch(intentMap[PermissionType.STORAGE_MANAGER]!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> onResult()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
fun requestPermission(type: PermissionType) {
|
||||||
|
try {
|
||||||
|
permissionRequested = type
|
||||||
|
when (type) {
|
||||||
|
PermissionType.EXTERNAL_STORAGE -> {
|
||||||
|
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
PermissionType.POST_NOTIFICATIONS -> {
|
||||||
|
if (isTAndAbove) {
|
||||||
|
permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PermissionType.STORAGE_MANAGER -> {
|
||||||
|
if (!isGranted(context, PermissionType.INSTALL_UNKNOWN_APPS)) {
|
||||||
|
context.toast(R.string.toast_permission_installer_required)
|
||||||
|
} else {
|
||||||
|
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val intent = intentMap[type] ?: return
|
||||||
|
intentLauncher.launch(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
Log.e(TAG, "Error requesting permission", exception)
|
||||||
|
permissionRequested = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
modifier = modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_xxsmall))
|
||||||
|
) {
|
||||||
|
permissions.sortedBy { it.optional }
|
||||||
|
.groupBy { permission -> permission.optional }
|
||||||
|
.forEach { (key, value) ->
|
||||||
|
stickyHeader {
|
||||||
|
TextDividerComposable(
|
||||||
|
title = if (!key) {
|
||||||
|
stringResource(R.string.item_required)
|
||||||
|
} else {
|
||||||
|
stringResource(R.string.item_optional)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
items(items = value, key = { p -> p.type.name }) { permission ->
|
||||||
|
PermissionListItem(
|
||||||
|
permission = permission,
|
||||||
|
onAction = { requestPermission(permission.type) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true)
|
||||||
|
@Composable
|
||||||
|
private fun PermissionListPreview() {
|
||||||
|
val permissions = PermissionType.entries.map { type ->
|
||||||
|
Permission(
|
||||||
|
type = type,
|
||||||
|
title = LoremIpsum(3).values.first(),
|
||||||
|
subtitle = LoremIpsum(7).values.first(),
|
||||||
|
optional = Random.nextBoolean(),
|
||||||
|
isGranted = Random.nextBoolean()
|
||||||
|
)
|
||||||
|
}.toSet()
|
||||||
|
PreviewTemplate {
|
||||||
|
PermissionList(permissions = permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,58 +5,33 @@
|
|||||||
|
|
||||||
package com.aurora.store.compose.ui.commons
|
package com.aurora.store.compose.ui.commons
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.provider.Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
|
import androidx.compose.material3.adaptive.WindowAdaptiveInfo
|
||||||
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.dimensionResource
|
|
||||||
import androidx.compose.ui.res.pluralStringResource
|
import androidx.compose.ui.res.pluralStringResource
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
|
||||||
import androidx.core.net.toUri
|
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.aurora.extensions.adaptiveNavigationIcon
|
import com.aurora.extensions.adaptiveNavigationIcon
|
||||||
import com.aurora.extensions.isTAndAbove
|
|
||||||
import com.aurora.extensions.toast
|
|
||||||
import com.aurora.store.BuildConfig
|
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
import com.aurora.store.compose.composable.PermissionListItem
|
import com.aurora.store.compose.composable.PermissionList
|
||||||
import com.aurora.store.compose.composable.TextDividerComposable
|
|
||||||
import com.aurora.store.compose.composable.TopAppBar
|
import com.aurora.store.compose.composable.TopAppBar
|
||||||
import com.aurora.store.compose.preview.PreviewTemplate
|
import com.aurora.store.compose.preview.PreviewTemplate
|
||||||
import com.aurora.store.data.model.Permission
|
import com.aurora.store.data.model.Permission
|
||||||
import com.aurora.store.data.model.PermissionType
|
import com.aurora.store.data.model.PermissionType
|
||||||
import com.aurora.store.data.providers.PermissionProvider.Companion.isGranted
|
|
||||||
import com.aurora.store.util.PackageUtil
|
|
||||||
import com.aurora.store.viewmodel.commons.PermissionRationaleViewModel
|
import com.aurora.store.viewmodel.commons.PermissionRationaleViewModel
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
private const val TAG = "PermissionsScreen"
|
/**
|
||||||
|
* Screen to request specific set of permissions expected to be used during installing an app
|
||||||
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun PermissionRationaleScreen(
|
fun PermissionRationaleScreen(
|
||||||
isOnboarding: Boolean = false,
|
|
||||||
requiredPermissions: Set<PermissionType> = emptySet(),
|
requiredPermissions: Set<PermissionType> = emptySet(),
|
||||||
onNavigateUp: () -> Unit,
|
onNavigateUp: () -> Unit,
|
||||||
onPermissionCallback: (type: PermissionType) -> Unit = {},
|
onPermissionCallback: (type: PermissionType) -> Unit = {},
|
||||||
@@ -65,13 +40,11 @@ fun PermissionRationaleScreen(
|
|||||||
val permissions by viewModel.permissions.collectAsStateWithLifecycle()
|
val permissions by viewModel.permissions.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
ScreenContent(
|
ScreenContent(
|
||||||
isOnboarding = isOnboarding,
|
|
||||||
permissions = when {
|
|
||||||
requiredPermissions.isEmpty() -> permissions
|
|
||||||
else -> permissions.filter { it.type in requiredPermissions }
|
|
||||||
.map { permission -> permission.copy(optional = false) }
|
|
||||||
},
|
|
||||||
onNavigateUp = onNavigateUp,
|
onNavigateUp = onNavigateUp,
|
||||||
|
permissions = permissions
|
||||||
|
.filter { it.type in requiredPermissions }
|
||||||
|
.map { permission -> permission.copy(optional = false) }
|
||||||
|
.toSet(),
|
||||||
onPermissionCallback = { type ->
|
onPermissionCallback = { type ->
|
||||||
viewModel.refreshPermissionsList()
|
viewModel.refreshPermissionsList()
|
||||||
onPermissionCallback(type)
|
onPermissionCallback(type)
|
||||||
@@ -81,124 +54,25 @@ fun PermissionRationaleScreen(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ScreenContent(
|
private fun ScreenContent(
|
||||||
isOnboarding: Boolean = false,
|
permissions: Set<Permission> = emptySet(),
|
||||||
permissions: List<Permission> = emptyList(),
|
|
||||||
onNavigateUp: () -> Unit = {},
|
onNavigateUp: () -> Unit = {},
|
||||||
onPermissionCallback: (type: PermissionType) -> Unit = {},
|
onPermissionCallback: (type: PermissionType) -> Unit = {},
|
||||||
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()
|
windowAdaptiveInfo: WindowAdaptiveInfo = currentWindowAdaptiveInfo()
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
var permissionRequested by rememberSaveable { mutableStateOf<PermissionType?>(null) }
|
|
||||||
|
|
||||||
@SuppressLint("InlinedApi", "BatteryLife")
|
|
||||||
val intentMap = mapOf(
|
|
||||||
PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(context),
|
|
||||||
PermissionType.INSTALL_UNKNOWN_APPS to PackageUtil.getInstallUnknownAppsIntent(),
|
|
||||||
PermissionType.DOZE_WHITELIST to Intent(
|
|
||||||
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
|
||||||
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
|
||||||
),
|
|
||||||
PermissionType.APP_LINKS to Intent(
|
|
||||||
ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
|
|
||||||
"package:${BuildConfig.APPLICATION_ID}".toUri()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
fun onResult() {
|
|
||||||
permissionRequested?.let {
|
|
||||||
if (!isGranted(context, it)) context.toast(R.string.permissions_denied)
|
|
||||||
onPermissionCallback(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val intentLauncher = rememberLauncherForActivityResult(
|
|
||||||
contract = ActivityResultContracts.StartActivityForResult(),
|
|
||||||
onResult = { onResult() }
|
|
||||||
)
|
|
||||||
val permissionLauncher = rememberLauncherForActivityResult(
|
|
||||||
contract = ActivityResultContracts.RequestPermission(),
|
|
||||||
onResult = {
|
|
||||||
when (permissionRequested) {
|
|
||||||
PermissionType.STORAGE_MANAGER -> {
|
|
||||||
intentLauncher.launch(intentMap[PermissionType.STORAGE_MANAGER]!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> onResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
fun requestPermission(type: PermissionType) {
|
|
||||||
try {
|
|
||||||
permissionRequested = type
|
|
||||||
when (type) {
|
|
||||||
PermissionType.EXTERNAL_STORAGE -> {
|
|
||||||
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
}
|
|
||||||
|
|
||||||
PermissionType.POST_NOTIFICATIONS -> {
|
|
||||||
if (isTAndAbove) {
|
|
||||||
permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PermissionType.STORAGE_MANAGER -> {
|
|
||||||
if (!isGranted(context, PermissionType.INSTALL_UNKNOWN_APPS)) {
|
|
||||||
context.toast(R.string.toast_permission_installer_required)
|
|
||||||
} else {
|
|
||||||
permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
val intent = intentMap[type] ?: return
|
|
||||||
intentLauncher.launch(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.e(TAG, "Error requesting permission", exception)
|
|
||||||
permissionRequested = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
if (!isOnboarding) {
|
TopAppBar(
|
||||||
TopAppBar(
|
title = pluralStringResource(R.plurals.permissions_required, permissions.size),
|
||||||
title = pluralStringResource(R.plurals.permissions_required, permissions.size),
|
navigationIcon = windowAdaptiveInfo.adaptiveNavigationIcon,
|
||||||
navigationIcon = windowAdaptiveInfo.adaptiveNavigationIcon,
|
onNavigateUp = onNavigateUp
|
||||||
onNavigateUp = onNavigateUp
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
LazyColumn(
|
PermissionList(
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(paddingValues),
|
||||||
.fillMaxWidth()
|
permissions = permissions,
|
||||||
.padding(paddingValues),
|
onPermissionCallback = onPermissionCallback
|
||||||
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.margin_xxsmall))
|
)
|
||||||
) {
|
|
||||||
permissions.sortedBy { it.optional }
|
|
||||||
.groupBy { permission -> permission.optional }
|
|
||||||
.forEach { (key, value) ->
|
|
||||||
stickyHeader {
|
|
||||||
TextDividerComposable(
|
|
||||||
title = if (!key) {
|
|
||||||
stringResource(R.string.item_required)
|
|
||||||
} else {
|
|
||||||
stringResource(R.string.item_optional)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
items(items = value, key = { p -> p.type.name }) { permission ->
|
|
||||||
PermissionListItem(
|
|
||||||
permission = permission,
|
|
||||||
onAction = { requestPermission(permission.type) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +87,7 @@ private fun PermissionsScreenPreview() {
|
|||||||
optional = Random.nextBoolean(),
|
optional = Random.nextBoolean(),
|
||||||
isGranted = Random.nextBoolean()
|
isGranted = Random.nextBoolean()
|
||||||
)
|
)
|
||||||
}
|
}.toSet()
|
||||||
PreviewTemplate {
|
PreviewTemplate {
|
||||||
ScreenContent(permissions = permissions)
|
ScreenContent(permissions = permissions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ import com.aurora.extensions.checkManifestPermission
|
|||||||
import com.aurora.extensions.isDomainVerified
|
import com.aurora.extensions.isDomainVerified
|
||||||
import com.aurora.extensions.isExternalStorageAccessible
|
import com.aurora.extensions.isExternalStorageAccessible
|
||||||
import com.aurora.extensions.isIgnoringBatteryOptimizations
|
import com.aurora.extensions.isIgnoringBatteryOptimizations
|
||||||
|
import com.aurora.extensions.isOAndAbove
|
||||||
|
import com.aurora.extensions.isRAndAbove
|
||||||
|
import com.aurora.extensions.isSAndAbove
|
||||||
import com.aurora.extensions.isTAndAbove
|
import com.aurora.extensions.isTAndAbove
|
||||||
import com.aurora.extensions.requiresObbDir
|
import com.aurora.extensions.requiresObbDir
|
||||||
import com.aurora.extensions.toast
|
import com.aurora.extensions.toast
|
||||||
import com.aurora.gplayapi.data.models.App
|
import com.aurora.gplayapi.data.models.App
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
|
import com.aurora.store.data.model.Permission
|
||||||
import com.aurora.store.data.model.PermissionType
|
import com.aurora.store.data.model.PermissionType
|
||||||
import com.aurora.store.util.PackageUtil
|
import com.aurora.store.util.PackageUtil
|
||||||
|
|
||||||
@@ -74,6 +78,98 @@ class PermissionProvider(private val fragment: Fragment) :
|
|||||||
context.isDomainVerified("market.android.com")
|
context.isDomainVerified("market.android.com")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all known permissions that can be requested by Aurora Store
|
||||||
|
*/
|
||||||
|
fun getAllKnownPermissions(context: Context): List<Permission> {
|
||||||
|
val permissions = mutableListOf(
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.INSTALL_UNKNOWN_APPS,
|
||||||
|
title = context.getString(R.string.onboarding_permission_installer),
|
||||||
|
subtitle = if (isOAndAbove) {
|
||||||
|
context.getString(R.string.onboarding_permission_installer_desc)
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.onboarding_permission_installer_legacy_desc)
|
||||||
|
},
|
||||||
|
optional = false,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.INSTALL_UNKNOWN_APPS
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.DOZE_WHITELIST,
|
||||||
|
title = context.getString(R.string.onboarding_permission_doze),
|
||||||
|
subtitle = context.getString(R.string.onboarding_permission_doze_desc),
|
||||||
|
optional = true,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.DOZE_WHITELIST
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isRAndAbove) {
|
||||||
|
permissions.add(
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.STORAGE_MANAGER,
|
||||||
|
title = context.getString(R.string.onboarding_permission_esm),
|
||||||
|
subtitle = context.getString(R.string.onboarding_permission_esa_desc),
|
||||||
|
optional = false,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.STORAGE_MANAGER
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
permissions.add(
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.EXTERNAL_STORAGE,
|
||||||
|
title = context.getString(R.string.onboarding_permission_esa),
|
||||||
|
subtitle = context.getString(R.string.onboarding_permission_esa_desc),
|
||||||
|
optional = false,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTAndAbove) {
|
||||||
|
permissions.add(
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.POST_NOTIFICATIONS,
|
||||||
|
title = context.getString(R.string.onboarding_permission_notifications),
|
||||||
|
subtitle = context.getString(R.string.onboarding_permission_notifications_desc),
|
||||||
|
optional = true,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.POST_NOTIFICATIONS
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSAndAbove) {
|
||||||
|
permissions.add(
|
||||||
|
Permission(
|
||||||
|
type = PermissionType.APP_LINKS,
|
||||||
|
title = context.getString(R.string.app_links_title),
|
||||||
|
subtitle = context.getString(R.string.app_links_desc),
|
||||||
|
optional = true,
|
||||||
|
isGranted = PermissionProvider.isGranted(
|
||||||
|
context,
|
||||||
|
PermissionType.APP_LINKS
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val TAG = PermissionProvider::class.java.simpleName
|
private val TAG = PermissionProvider::class.java.simpleName
|
||||||
|
|||||||
@@ -7,13 +7,6 @@ package com.aurora.store.viewmodel.commons
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.aurora.extensions.isOAndAbove
|
|
||||||
import com.aurora.extensions.isRAndAbove
|
|
||||||
import com.aurora.extensions.isSAndAbove
|
|
||||||
import com.aurora.extensions.isTAndAbove
|
|
||||||
import com.aurora.store.R
|
|
||||||
import com.aurora.store.data.model.Permission
|
|
||||||
import com.aurora.store.data.model.PermissionType
|
|
||||||
import com.aurora.store.data.providers.PermissionProvider
|
import com.aurora.store.data.providers.PermissionProvider
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
@@ -26,101 +19,12 @@ class PermissionRationaleViewModel @Inject constructor(
|
|||||||
@ApplicationContext private val context: Context
|
@ApplicationContext private val context: Context
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _permissions = MutableStateFlow(getPermissions(context))
|
private val _permissions = MutableStateFlow(PermissionProvider.getAllKnownPermissions(context))
|
||||||
val permissions = _permissions.asStateFlow()
|
val permissions = _permissions.asStateFlow()
|
||||||
|
|
||||||
private fun getPermissions(context: Context): List<Permission> {
|
|
||||||
val list = mutableListOf(
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.INSTALL_UNKNOWN_APPS,
|
|
||||||
title = context.getString(R.string.onboarding_permission_installer),
|
|
||||||
subtitle = if (isOAndAbove) {
|
|
||||||
context.getString(R.string.onboarding_permission_installer_desc)
|
|
||||||
} else {
|
|
||||||
context.getString(R.string.onboarding_permission_installer_legacy_desc)
|
|
||||||
},
|
|
||||||
optional = false,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.INSTALL_UNKNOWN_APPS
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.DOZE_WHITELIST,
|
|
||||||
title = context.getString(R.string.onboarding_permission_doze),
|
|
||||||
subtitle = context.getString(R.string.onboarding_permission_doze_desc),
|
|
||||||
optional = true,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.DOZE_WHITELIST
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isRAndAbove) {
|
|
||||||
list.add(
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.STORAGE_MANAGER,
|
|
||||||
title = context.getString(R.string.onboarding_permission_esm),
|
|
||||||
subtitle = context.getString(R.string.onboarding_permission_esa_desc),
|
|
||||||
optional = false,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.STORAGE_MANAGER
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
list.add(
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.EXTERNAL_STORAGE,
|
|
||||||
title = context.getString(R.string.onboarding_permission_esa),
|
|
||||||
subtitle = context.getString(R.string.onboarding_permission_esa_desc),
|
|
||||||
optional = false,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.EXTERNAL_STORAGE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTAndAbove) {
|
|
||||||
list.add(
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.POST_NOTIFICATIONS,
|
|
||||||
title = context.getString(R.string.onboarding_permission_notifications),
|
|
||||||
subtitle = context.getString(R.string.onboarding_permission_notifications_desc),
|
|
||||||
optional = true,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.POST_NOTIFICATIONS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSAndAbove) {
|
|
||||||
list.add(
|
|
||||||
Permission(
|
|
||||||
type = PermissionType.APP_LINKS,
|
|
||||||
title = context.getString(R.string.app_links_title),
|
|
||||||
subtitle = context.getString(R.string.app_links_desc),
|
|
||||||
optional = true,
|
|
||||||
isGranted = PermissionProvider.Companion.isGranted(
|
|
||||||
context,
|
|
||||||
PermissionType.APP_LINKS
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refreshPermissionsList() {
|
fun refreshPermissionsList() {
|
||||||
_permissions.value = _permissions.value.map { permission ->
|
_permissions.value = _permissions.value.map { permission ->
|
||||||
permission.copy(isGranted = PermissionProvider.Companion.isGranted(
|
permission.copy(isGranted = PermissionProvider.isGranted(
|
||||||
context,
|
context,
|
||||||
permission.type
|
permission.type
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user