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 package com.aurora.store
import androidx.activity.result.ActivityResult
import com.aurora.gplayapi.data.models.Category import com.aurora.gplayapi.data.models.Category
import com.aurora.gplayapi.data.models.StreamBundle import com.aurora.gplayapi.data.models.StreamBundle
import com.aurora.gplayapi.data.models.StreamCluster 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 TopChartStash = MutableMap<TopChartsContract.Type, MutableMap<TopChartsContract.Chart, StreamCluster>>
typealias HomeStash = MutableMap<StreamContract.Category, StreamBundle> typealias HomeStash = MutableMap<StreamContract.Category, StreamBundle>
typealias CategoryStash = MutableMap<Category.Type, List<Category>> 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.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -20,8 +21,11 @@ import com.aurora.extensions.isDomainVerified
import com.aurora.extensions.isExternalStorageAccessible import com.aurora.extensions.isExternalStorageAccessible
import com.aurora.extensions.isMAndAbove import com.aurora.extensions.isMAndAbove
import com.aurora.extensions.isOAndAbove import com.aurora.extensions.isOAndAbove
import com.aurora.extensions.toast
import com.aurora.store.BuildConfig import com.aurora.store.BuildConfig
import com.aurora.store.PermissionCallback
import com.aurora.store.PermissionType import com.aurora.store.PermissionType
import com.aurora.store.R
import com.aurora.store.util.Log import com.aurora.store.util.Log
import com.aurora.store.util.PackageUtil import com.aurora.store.util.PackageUtil
@@ -31,33 +35,47 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
private var intentLauncher: ActivityResultLauncher<Intent> private var intentLauncher: ActivityResultLauncher<Intent>
private var permissionLauncher: ActivityResultLauncher<String> private var permissionLauncher: ActivityResultLauncher<String>
constructor(activity: AppCompatActivity) { private var permissionCallback: PermissionCallback? = null
context = activity
constructor(activity: AppCompatActivity, callback: PermissionCallback? = null) {
this.context = activity
permissionCallback = callback
intentLauncher = activity.registerForActivityResult( intentLauncher = activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult(), ActivityResultContracts.StartActivityForResult(),
this this
) )
permissionLauncher = 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) { constructor(fragment: Fragment, callback: PermissionCallback? = null) {
context = fragment.requireContext() this.context = fragment.requireContext()
permissionCallback = callback
intentLauncher = fragment.registerForActivityResult( intentLauncher = fragment.registerForActivityResult(
ActivityResultContracts.StartActivityForResult(), ActivityResultContracts.StartActivityForResult(),
this this
) )
permissionLauncher = permissionLauncher =
fragment.registerForActivityResult(ActivityResultContracts.RequestPermission()) {} fragment.registerForActivityResult(ActivityResultContracts.RequestPermission()) {
} permissionCallback?.invoke(
ActivityResult(
fun unregister() { if (it) Activity.RESULT_OK else Activity.RESULT_CANCELED,
intentLauncher.unregister() null
permissionLauncher.unregister() )
)
}
} }
private val permissionMap: Map<PermissionType, Intent> = mapOf( 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( PermissionType.INSTALL_UNKNOWN_APPS to Intent(
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:${BuildConfig.APPLICATION_ID}") Uri.parse("package:${BuildConfig.APPLICATION_ID}")
@@ -72,32 +90,42 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
) )
) )
fun requestPermission(permissionType: PermissionType) { fun request(permissionType: PermissionType) {
try { try {
when (permissionType) { when (permissionType) {
PermissionType.EXTERNAL_STORAGE -> permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) PermissionType.EXTERNAL_STORAGE -> permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
PermissionType.POST_NOTIFICATIONS -> permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) PermissionType.POST_NOTIFICATIONS -> permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
else -> { else -> {
val intent = permissionMap[permissionType] ?: return 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) { } 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) { return when (permissionType) {
PermissionType.EXTERNAL_STORAGE, PermissionType.EXTERNAL_STORAGE,
PermissionType.STORAGE_MANAGER -> context.isExternalStorageAccessible() PermissionType.STORAGE_MANAGER -> context.isExternalStorageAccessible()
PermissionType.POST_NOTIFICATIONS -> context.checkManifestPermission(Manifest.permission.POST_NOTIFICATIONS) PermissionType.POST_NOTIFICATIONS -> context.checkManifestPermission(Manifest.permission.POST_NOTIFICATIONS)
PermissionType.INSTALL_UNKNOWN_APPS -> { PermissionType.INSTALL_UNKNOWN_APPS -> {
if (isOAndAbove()) if (isOAndAbove()) {
context.packageManager.canRequestPackageInstalls() context.packageManager.canRequestPackageInstalls()
else } else {
true true
}
} }
PermissionType.DOZE_WHITELIST -> { PermissionType.DOZE_WHITELIST -> {
@@ -116,7 +144,12 @@ class PermissionProvider : ActivityResultCallback<ActivityResult> {
} }
} }
fun unregister() {
intentLauncher.unregister()
permissionLauncher.unregister()
}
override fun onActivityResult(result: ActivityResult) { 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) updateActionState(State.PROGRESS)
if (PathUtil.needsStorageManagerPerm(app.fileList)) { if (PathUtil.needsStorageManagerPerm(app.fileList)) {
if (permissionProvider.isPermissionGranted(PermissionType.STORAGE_MANAGER)) { if (permissionProvider.isGranted(PermissionType.STORAGE_MANAGER)) {
viewModel.download(app) viewModel.download(app)
} else { } else {
permissionProvider.requestPermission(PermissionType.STORAGE_MANAGER) permissionProvider.request(PermissionType.STORAGE_MANAGER)
} }
} else { } else {
viewModel.download(app) viewModel.download(app)

View File

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

View File

@@ -1,16 +1,13 @@
package com.aurora.store.view.ui.sheets package com.aurora.store.view.ui.sheets
import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.provider.Settings
import android.view.View import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import com.aurora.extensions.isIgnoringBatteryOptimizations import com.aurora.extensions.isIgnoringBatteryOptimizations
import com.aurora.extensions.isMAndAbove
import com.aurora.extensions.toast import com.aurora.extensions.toast
import com.aurora.store.PermissionType
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.providers.PermissionProvider
import com.aurora.store.data.work.UpdateWorker import com.aurora.store.data.work.UpdateWorker
import com.aurora.store.databinding.SheetDozeWarningBinding import com.aurora.store.databinding.SheetDozeWarningBinding
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO 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 args: DozeWarningSheetArgs by navArgs()
private val startForDozeResult = private lateinit var permissionProvider: PermissionProvider
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()
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
binding.btnSecondary.setOnClickListener { dismissAllowingStateLoss() } permissionProvider = PermissionProvider(this) {
binding.btnPrimary.setOnClickListener { if (requireContext().isIgnoringBatteryOptimizations()) {
if (isMAndAbove()) { if (args.enableAutoUpdate) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { requireContext().save(PREFERENCE_UPDATES_AUTO, 2)
data = Uri.parse("package:${requireContext().packageName}") 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 viewModel.updateAllEnqueued = updateAll
if (PathUtil.needsStorageManagerPerm(update.fileList)) { if (PathUtil.needsStorageManagerPerm(update.fileList)) {
if (permissionProvider.isPermissionGranted(PermissionType.STORAGE_MANAGER)) { if (permissionProvider.isGranted(PermissionType.STORAGE_MANAGER)) {
viewModel.download(update) viewModel.download(update)
} else { } else {
permissionProvider.requestPermission(PermissionType.STORAGE_MANAGER) permissionProvider.request(PermissionType.STORAGE_MANAGER)
} }
} else { } else {
viewModel.download(update) viewModel.download(update)