diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/PermissionsFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/PermissionsFragment.kt index 6a75b1e91d773e381dec11d7771d5ca9fa1ac687..93e0ac1fc0d23bef957424c6cf9bab27fcea2ba0 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/PermissionsFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/PermissionsFragment.kt @@ -16,6 +16,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.MainThread import androidx.core.content.ContextCompat @@ -25,31 +26,42 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import at.bitfire.davdroid.BuildConfig import at.bitfire.davdroid.PackageChangedReceiver +import at.bitfire.davdroid.R +import at.bitfire.davdroid.databinding.ActivityPermissionsBinding import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.davdroid.util.PermissionUtils.CALENDAR_PERMISSIONS import at.bitfire.davdroid.util.PermissionUtils.CONTACT_PERMISSIONS import at.bitfire.davdroid.util.PermissionUtils.havePermissions -import at.bitfire.davdroid.R -import at.bitfire.davdroid.databinding.ActivityPermissionsBinding import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider.ProviderName class PermissionsFragment: Fragment() { val model by viewModels() - + private lateinit var requestPermission: ActivityResultLauncher> override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { val binding = ActivityPermissionsBinding.inflate(inflater, container, false) binding.lifecycleOwner = viewLifecycleOwner binding.model = model - binding.text.text = getString(R.string.permissions_text, getString(R.string.app_name)) - val requestPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { + initPermissionLauncher() + observePermissionToggles() + binding.appSettings.setOnClickListener { + PermissionUtils.showAppSettings(requireActivity()) + } + + return binding.root + } + + private fun initPermissionLauncher() { + requestPermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { model.checkPermissions() } + } + private fun observePermissionToggles() { model.needAutoResetPermission.observe(viewLifecycleOwner) { keepPermissions -> if (keepPermissions == true && model.haveAutoResetPermission.value == false) { Toast.makeText(requireActivity(), R.string.permissions_autoreset_instruction, Toast.LENGTH_LONG).show() @@ -95,12 +107,6 @@ class PermissionsFragment: Fragment() { requestPermission.launch(all.toTypedArray()) } } - - binding.appSettings.setOnClickListener { - PermissionUtils.showAppSettings(requireActivity()) - } - - return binding.root } override fun onResume() { diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/intro/PermissionsIntroFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/intro/PermissionsIntroFragment.kt index 98df793fd3383a5ed2047ab80f706f82e217aefc..13603e803cd74c7c0ae2aa7c8339e04930074122 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/intro/PermissionsIntroFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/intro/PermissionsIntroFragment.kt @@ -10,11 +10,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import at.bitfire.davdroid.util.PermissionUtils -import at.bitfire.davdroid.util.PermissionUtils.CALENDAR_PERMISSIONS -import at.bitfire.davdroid.util.PermissionUtils.CONTACT_PERMISSIONS import at.bitfire.davdroid.R -import at.bitfire.ical4android.TaskProvider +import at.bitfire.davdroid.util.PermissionUtils import javax.inject.Inject class PermissionsIntroFragment : Fragment() { @@ -26,19 +23,16 @@ class PermissionsIntroFragment : Fragment() { class Factory @Inject constructor(): IntroFragmentFactory { override fun getOrder(context: Context): Int { - // show PermissionsFragment as intro fragment when no permissions are granted - val permissions = CONTACT_PERMISSIONS + CALENDAR_PERMISSIONS + - TaskProvider.PERMISSIONS_JTX + - TaskProvider.PERMISSIONS_OPENTASKS + - TaskProvider.PERMISSIONS_TASKS_ORG - return if (PermissionUtils.haveAnyPermission(context, permissions)) + val permissions = PermissionUtils.requiredAccountPermissions(context) + return if (PermissionUtils.havePermissions(context, permissions)) { IntroFragmentFactory.DONT_SHOW - else + } else { 50 + } } override fun create() = PermissionsIntroFragment() } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt index 46e2c974d7c5c0ed195bb124bc04c05f89f19973..108cdc3515c8d57fe8157000b8a24660169fcf6a 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt @@ -51,7 +51,9 @@ import at.bitfire.davdroid.settings.SettingsManager import at.bitfire.davdroid.syncadapter.AccountUtils import at.bitfire.davdroid.syncadapter.SyncAllAccountWorker import at.bitfire.davdroid.syncadapter.SyncWorker +import at.bitfire.davdroid.ui.PermissionsActivity import at.bitfire.davdroid.util.AuthStatePrefUtils +import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.vcard4android.GroupMethod import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.utils.AccountManagerUtils @@ -126,7 +128,7 @@ class AccountDetailsFragment : Fragment() { GroupMethod.valueOf(groupMethodName), ).observe(viewLifecycleOwner, Observer { success -> if (success) { - // close Create account activity + requestMissingPermissionsIfNeeded() requireActivity().finish() } else { Snackbar.make(requireActivity().findViewById(android.R.id.content), R.string.login_account_not_created, Snackbar.LENGTH_LONG).show() @@ -186,6 +188,7 @@ class AccountDetailsFragment : Fragment() { if (success) { Toast.makeText(context, R.string.message_account_added_successfully, Toast.LENGTH_LONG).show() requireActivity().setResult(Activity.RESULT_OK) + requestMissingPermissionsIfNeeded() requireActivity().finish() if (requireActivity().intent.hasExtra(AccountManager @@ -216,6 +219,12 @@ class AccountDetailsFragment : Fragment() { return v.root } + private fun requestMissingPermissionsIfNeeded() { + if (PermissionUtils.collectMissingRequiredPermissions(requireContext()).isNotEmpty()) { + startActivity(Intent(requireActivity(), PermissionsActivity::class.java)) + } + } + private fun findBasicAuthMurenaAccount(accountName: String, accountType: String?): Account? { val requiredAccountType = requireContext().getString(R.string.eelo_account_type) if (accountType != requiredAccountType) { diff --git a/app/src/main/kotlin/at/bitfire/davdroid/util/PermissionUtils.kt b/app/src/main/kotlin/at/bitfire/davdroid/util/PermissionUtils.kt index d23070485f84e28a917428b417fdc241a2ff0023..b2333072bb0bd04e6f6543a3f4c9f06e26b58e03 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/util/PermissionUtils.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/util/PermissionUtils.kt @@ -23,6 +23,8 @@ import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.ui.NotificationUtils import at.bitfire.davdroid.ui.NotificationUtils.notifyIfPossible import at.bitfire.davdroid.ui.PermissionsActivity +import at.bitfire.ical4android.TaskProvider +import at.bitfire.ical4android.TaskProvider.ProviderName object PermissionUtils { @@ -104,6 +106,30 @@ object PermissionUtils { fun havePermissions(context: Context, permissions: Array) = permissions.all { ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED } + fun requiredAccountPermissions(context: Context): Array { + val requiredPermissions = mutableSetOf(*CONTACT_PERMISSIONS, *CALENDAR_PERMISSIONS) + val packageManager = context.packageManager + + if (packageManager.resolveContentProvider(ProviderName.OpenTasks.authority, 0) != null) { + requiredPermissions.addAll(TaskProvider.PERMISSIONS_OPENTASKS) + } + if (packageManager.resolveContentProvider(ProviderName.TasksOrg.authority, 0) != null) { + requiredPermissions.addAll(TaskProvider.PERMISSIONS_TASKS_ORG) + } + if (packageManager.resolveContentProvider(ProviderName.JtxBoard.authority, 0) != null) { + requiredPermissions.addAll(TaskProvider.PERMISSIONS_JTX) + } + + return requiredPermissions.toTypedArray() + } + + fun collectMissingRequiredPermissions(context: Context): List { + val required = requiredAccountPermissions(context) + return required.filter { + ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED + } + } + /** * Shows a notification about missing permissions. * @@ -133,4 +159,4 @@ object PermissionUtils { Logger.log.warning("App settings Intent not resolvable") } -} \ No newline at end of file +}