Redo Permissions [2/2]

This commit is contained in:
Rahul Patel
2024-07-27 14:40:04 +05:30
parent 44b9a1a7b2
commit 464aff4d64
6 changed files with 83 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
package com.aurora.store
import androidx.activity.result.ActivityResult
import com.aurora.gplayapi.data.models.Category
import com.aurora.gplayapi.data.models.StreamBundle
import com.aurora.gplayapi.data.models.StreamCluster
@@ -9,4 +10,6 @@ import com.aurora.gplayapi.helpers.contracts.TopChartsContract
typealias TopChartStash = MutableMap<TopChartsContract.Type, MutableMap<TopChartsContract.Chart, StreamCluster>>
typealias HomeStash = MutableMap<StreamContract.Category, StreamBundle>
typealias CategoryStash = MutableMap<Category.Type, List<Category>>
typealias AppStreamStash = MutableMap<String, StreamBundle>
typealias AppStreamStash = MutableMap<String, StreamBundle>
typealias PermissionCallback = (ActivityResult) -> Unit

View File

@@ -2,6 +2,7 @@ package com.aurora.store.data.providers
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
@@ -20,8 +21,11 @@ import com.aurora.extensions.isDomainVerified
import com.aurora.extensions.isExternalStorageAccessible
import com.aurora.extensions.isMAndAbove
import com.aurora.extensions.isOAndAbove
import com.aurora.extensions.toast
import com.aurora.store.BuildConfig
import com.aurora.store.PermissionCallback
import com.aurora.store.PermissionType
import com.aurora.store.R
import com.aurora.store.util.Log
import com.aurora.store.util.PackageUtil
@@ -31,33 +35,47 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
private var intentLauncher: ActivityResultLauncher<Intent>
private var permissionLauncher: ActivityResultLauncher<String>
constructor(activity: AppCompatActivity) {
context = activity
private var permissionCallback: PermissionCallback? = null
constructor(activity: AppCompatActivity, callback: PermissionCallback? = null) {
this.context = activity
permissionCallback = callback
intentLauncher = activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
this
)
permissionLauncher =
activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) {
permissionCallback?.invoke(
ActivityResult(
if (it) Activity.RESULT_OK else Activity.RESULT_CANCELED,
null
)
)
}
}
constructor(fragment: Fragment) {
context = fragment.requireContext()
constructor(fragment: Fragment, callback: PermissionCallback? = null) {
this.context = fragment.requireContext()
permissionCallback = callback
intentLauncher = fragment.registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
this
)
permissionLauncher =
fragment.registerForActivityResult(ActivityResultContracts.RequestPermission()) {}
}
fun unregister() {
intentLauncher.unregister()
permissionLauncher.unregister()
fragment.registerForActivityResult(ActivityResultContracts.RequestPermission()) {
permissionCallback?.invoke(
ActivityResult(
if (it) Activity.RESULT_OK else Activity.RESULT_CANCELED,
null
)
)
}
}
private val permissionMap: Map<PermissionType, Intent> = mapOf(
PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(safe = true),
PermissionType.STORAGE_MANAGER to PackageUtil.getStorageManagerIntent(safe = false),
PermissionType.INSTALL_UNKNOWN_APPS to Intent(
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:${BuildConfig.APPLICATION_ID}")
@@ -72,32 +90,42 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
)
)
fun requestPermission(permissionType: PermissionType) {
fun request(permissionType: PermissionType) {
try {
when (permissionType) {
PermissionType.EXTERNAL_STORAGE -> permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
PermissionType.POST_NOTIFICATIONS -> permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
else -> {
val intent = permissionMap[permissionType] ?: return
intentLauncher.launch(intent)
if (permissionType == PermissionType.STORAGE_MANAGER
&& !isGranted(PermissionType.INSTALL_UNKNOWN_APPS)
) {
context.toast(R.string.toast_permission_installer_required)
} else {
intentLauncher.launch(intent)
}
}
}
} catch (e: ActivityNotFoundException) {
Log.e("PermissionProvider", "Activity not found for $permissionType")
Log.e("PermissionProvider", "Activity not found for $permissionType: ${e.message}")
} catch (e: Exception) {
Log.e("PermissionProvider", "Error requesting permission: ${e.message}")
}
}
fun isPermissionGranted(permissionType: PermissionType): Boolean {
fun isGranted(permissionType: PermissionType): Boolean {
return when (permissionType) {
PermissionType.EXTERNAL_STORAGE,
PermissionType.STORAGE_MANAGER -> context.isExternalStorageAccessible()
PermissionType.POST_NOTIFICATIONS -> context.checkManifestPermission(Manifest.permission.POST_NOTIFICATIONS)
PermissionType.INSTALL_UNKNOWN_APPS -> {
if (isOAndAbove())
if (isOAndAbove()) {
context.packageManager.canRequestPackageInstalls()
else
} else {
true
}
}
PermissionType.DOZE_WHITELIST -> {
@@ -116,7 +144,12 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
}
}
fun unregister() {
intentLauncher.unregister()
permissionLauncher.unregister()
}
override fun onActivityResult(result: ActivityResult) {
// We don't need to do anything here, as we anyway do permission re-checks using @isPermissionGranted
permissionCallback?.invoke(result)
}
}

View File

@@ -550,10 +550,10 @@ class AppDetailsFragment : BaseFragment<FragmentDetailsBinding>() {
updateActionState(State.PROGRESS)
if (PathUtil.needsStorageManagerPerm(app.fileList)) {
if (permissionProvider.isPermissionGranted(PermissionType.STORAGE_MANAGER)) {
if (permissionProvider.isGranted(PermissionType.STORAGE_MANAGER)) {
viewModel.download(app)
} else {
permissionProvider.requestPermission(PermissionType.STORAGE_MANAGER)
permissionProvider.request(PermissionType.STORAGE_MANAGER)
}
} else {
viewModel.download(app)

View File

@@ -156,7 +156,7 @@ class PermissionsFragment : BaseFragment<FragmentOnboardingPermissionsBinding>()
return PermissionViewModel_()
.id(permission.type.name)
.permission(permission)
.isGranted(permissionProvider.isPermissionGranted(permission.type))
.click { _ -> permissionProvider.requestPermission(permission.type) }
.isGranted(permissionProvider.isGranted(permission.type))
.click { _ -> permissionProvider.request(permission.type) }
}
}

View File

@@ -1,16 +1,13 @@
package com.aurora.store.view.ui.sheets
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.navigation.fragment.navArgs
import com.aurora.extensions.isIgnoringBatteryOptimizations
import com.aurora.extensions.isMAndAbove
import com.aurora.extensions.toast
import com.aurora.store.PermissionType
import com.aurora.store.R
import com.aurora.store.data.providers.PermissionProvider
import com.aurora.store.data.work.UpdateWorker
import com.aurora.store.databinding.SheetDozeWarningBinding
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO
@@ -20,34 +17,31 @@ class DozeWarningSheet : BaseDialogSheet<SheetDozeWarningBinding>() {
private val args: DozeWarningSheetArgs by navArgs()
private val startForDozeResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
context?.let {
if (it.isIgnoringBatteryOptimizations()) {
if (args.enableAutoUpdate) {
requireContext().save(PREFERENCE_UPDATES_AUTO, 2)
UpdateWorker.scheduleAutomatedCheck(requireContext())
}
toast(R.string.toast_permission_granted)
activity?.recreate()
} else {
toast(R.string.permissions_denied)
}
dismissAllowingStateLoss()
}
}
private lateinit var permissionProvider: PermissionProvider
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.btnSecondary.setOnClickListener { dismissAllowingStateLoss() }
binding.btnPrimary.setOnClickListener {
if (isMAndAbove()) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:${requireContext().packageName}")
permissionProvider = PermissionProvider(this) {
if (requireContext().isIgnoringBatteryOptimizations()) {
if (args.enableAutoUpdate) {
requireContext().save(PREFERENCE_UPDATES_AUTO, 2)
UpdateWorker.scheduleAutomatedCheck(requireContext())
}
startForDozeResult.launch(intent)
toast(R.string.toast_permission_granted)
activity?.recreate()
} else {
toast(R.string.permissions_denied)
}
dismissAllowingStateLoss()
}
binding.btnSecondary.setOnClickListener { dismissAllowingStateLoss() }
binding.btnPrimary.setOnClickListener { permissionProvider.request(PermissionType.DOZE_WHITELIST) }
}
override fun onDestroy() {
permissionProvider.unregister()
super.onDestroy()
}
}

View File

@@ -194,10 +194,10 @@ class UpdatesFragment : BaseFragment<FragmentUpdatesBinding>() {
viewModel.updateAllEnqueued = updateAll
if (PathUtil.needsStorageManagerPerm(update.fileList)) {
if (permissionProvider.isPermissionGranted(PermissionType.STORAGE_MANAGER)) {
if (permissionProvider.isGranted(PermissionType.STORAGE_MANAGER)) {
viewModel.download(update)
} else {
permissionProvider.requestPermission(PermissionType.STORAGE_MANAGER)
permissionProvider.request(PermissionType.STORAGE_MANAGER)
}
} else {
viewModel.download(update)