Skip to content

Commit

Permalink
Merge pull request #10907 from nextcloud/backport/10883/stable-3.22
Browse files Browse the repository at this point in the history
[stable-3.22] Fix creation and result logic for StoragePermissionDialogFragment
  • Loading branch information
AlvaroBrey authored Oct 24, 2022
2 parents 99ef1c2 + e867371 commit f63c156
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 37 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,18 @@ public void testSslUntrustedCertDialog() {
showDialog(sut);
}


@Test
@ScreenshotTest
public void testStoragePermissionDialog() {
if (Looper.myLooper() == null) {
Looper.prepare();
}

StoragePermissionDialogFragment sut = StoragePermissionDialogFragment.Companion.newInstance(false);
showDialog(sut);
}

private FileDisplayActivity showDialog(DialogFragment dialog) {
Intent intent = new Intent(targetContext, FileDisplayActivity.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,43 @@ package com.owncloud.android.ui.dialog
import android.app.Dialog
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.view.View
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.client.di.Injectable
import com.owncloud.android.R
import com.owncloud.android.databinding.StoragePermissionDialogBinding
import com.owncloud.android.ui.dialog.StoragePermissionDialogFragment.Listener
import com.owncloud.android.utils.theme.ViewThemeUtils
import kotlinx.parcelize.Parcelize
import javax.inject.Inject

/**
* Dialog that shows permission options in SDK >= 30
*
* Allows choosing "full access" (MANAGE_ALL_FILES) or "read-only media" (READ_EXTERNAL_STORAGE)
*
* @param listener a [Listener] for button clicks. The dialog will auto-dismiss after the callback is called.
* @param permissionRequired Whether the permission is absolutely required by the calling component.
* This changes the texts to a more strict version.
*/
@RequiresApi(Build.VERSION_CODES.R)
class StoragePermissionDialogFragment(val listener: Listener, val permissionRequired: Boolean = false) :
class StoragePermissionDialogFragment :
DialogFragment(), Injectable {

private lateinit var binding: StoragePermissionDialogBinding

private var permissionRequired = false

@Inject
lateinit var viewThemeUtils: ViewThemeUtils

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
permissionRequired = it.getBoolean(ARG_PERMISSION_REQUIRED, false)
}
}

override fun onStart() {
super.onStart()
dialog?.let {
Expand All @@ -75,12 +83,12 @@ class StoragePermissionDialogFragment(val listener: Listener, val permissionRequ
// Setup layout
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.btnFullAccess)
binding.btnFullAccess.setOnClickListener {
listener.onClickFullAccess()
setResult(Result.FULL_ACCESS)
dismiss()
}
viewThemeUtils.platform.colorTextButtons(binding.btnReadOnly)
binding.btnReadOnly.setOnClickListener {
listener.onClickMediaReadOnly()
setResult(Result.MEDIA_READ_ONLY)
dismiss()
}

Expand All @@ -94,7 +102,7 @@ class StoragePermissionDialogFragment(val listener: Listener, val permissionRequ
.setTitle(titleResource)
.setView(view)
.setNegativeButton(R.string.common_cancel) { _, _ ->
listener.onCancel()
setResult(Result.CANCEL)
dismiss()
}

Expand All @@ -103,9 +111,28 @@ class StoragePermissionDialogFragment(val listener: Listener, val permissionRequ
return builder.create()
}

interface Listener {
fun onCancel()
fun onClickFullAccess()
fun onClickMediaReadOnly()
private fun setResult(result: Result) {
parentFragmentManager.setFragmentResult(REQUEST_KEY, bundleOf(RESULT_KEY to result))
}

@Parcelize
enum class Result : Parcelable {
CANCEL, FULL_ACCESS, MEDIA_READ_ONLY
}

companion object {
private const val ARG_PERMISSION_REQUIRED = "ARG_PERMISSION_REQUIRED"
const val REQUEST_KEY = "REQUEST_KEY_STORAGE_PERMISSION"
const val RESULT_KEY = "RESULT"

/**
* @param permissionRequired Whether the permission is absolutely required by the calling component.
* This changes the texts to a more strict version.
*/
fun newInstance(permissionRequired: Boolean): StoragePermissionDialogFragment {
return StoragePermissionDialogFragment().apply {
arguments = bundleOf(ARG_PERMISSION_REQUIRED to permissionRequired)
}
}
}
}
52 changes: 28 additions & 24 deletions app/src/main/java/com/owncloud/android/utils/PermissionUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -209,33 +209,37 @@ object PermissionUtil {
viewThemeUtils: ViewThemeUtils
) {
val preferences: AppPreferences = AppPreferencesImpl.fromContext(activity)

if (!preferences.isStoragePermissionRequested || permissionRequired) {
if (activity.supportFragmentManager.findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG) == null) {
val listener = object : StoragePermissionDialogFragment.Listener {
override fun onCancel() {
preferences.isStoragePermissionRequested = true
}

override fun onClickFullAccess() {
preferences.isStoragePermissionRequested = true
val intent = getManageAllFilesIntent(activity)
activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_ALL_FILES)
preferences.isStoragePermissionRequested = true
}

override fun onClickMediaReadOnly() {
preferences.isStoragePermissionRequested = true
requestStoragePermission(
activity,
Manifest.permission.READ_EXTERNAL_STORAGE,
viewThemeUtils
)
val shouldRequestPermission = !preferences.isStoragePermissionRequested || permissionRequired
if (shouldRequestPermission &&
activity.supportFragmentManager.findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG) == null
) {
activity.supportFragmentManager.setFragmentResultListener(
StoragePermissionDialogFragment.REQUEST_KEY,
activity
) { _, resultBundle ->
val result: StoragePermissionDialogFragment.Result? =
resultBundle.getParcelable(StoragePermissionDialogFragment.RESULT_KEY)
if (result != null) {
preferences.isStoragePermissionRequested = true
when (result) {
StoragePermissionDialogFragment.Result.FULL_ACCESS -> {
val intent = getManageAllFilesIntent(activity)
activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_ALL_FILES)
}
StoragePermissionDialogFragment.Result.MEDIA_READ_ONLY -> {
requestStoragePermission(
activity,
Manifest.permission.READ_EXTERNAL_STORAGE,
viewThemeUtils
)
}
StoragePermissionDialogFragment.Result.CANCEL -> {}
}
}
val dialogFragment = StoragePermissionDialogFragment(listener, permissionRequired)
dialogFragment.show(activity.supportFragmentManager, PERMISSION_CHOICE_DIALOG_TAG)
}

val dialogFragment = StoragePermissionDialogFragment.newInstance(permissionRequired)
dialogFragment.show(activity.supportFragmentManager, PERMISSION_CHOICE_DIALOG_TAG)
}
}

Expand Down

0 comments on commit f63c156

Please sign in to comment.