Skip to content

Commit f63c156

Browse files
authored
Merge pull request #10907 from nextcloud/backport/10883/stable-3.22
[stable-3.22] Fix creation and result logic for StoragePermissionDialogFragment
2 parents 99ef1c2 + e867371 commit f63c156

File tree

4 files changed

+80
-37
lines changed

4 files changed

+80
-37
lines changed

app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java

+12
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,18 @@ public void testSslUntrustedCertDialog() {
484484
showDialog(sut);
485485
}
486486

487+
488+
@Test
489+
@ScreenshotTest
490+
public void testStoragePermissionDialog() {
491+
if (Looper.myLooper() == null) {
492+
Looper.prepare();
493+
}
494+
495+
StoragePermissionDialogFragment sut = StoragePermissionDialogFragment.Companion.newInstance(false);
496+
showDialog(sut);
497+
}
498+
487499
private FileDisplayActivity showDialog(DialogFragment dialog) {
488500
Intent intent = new Intent(targetContext, FileDisplayActivity.class);
489501

app/src/main/java/com/owncloud/android/ui/dialog/StoragePermissionDialogFragment.kt

+40-13
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,43 @@ package com.owncloud.android.ui.dialog
2323
import android.app.Dialog
2424
import android.os.Build
2525
import android.os.Bundle
26+
import android.os.Parcelable
2627
import android.view.View
2728
import androidx.annotation.RequiresApi
2829
import androidx.appcompat.app.AlertDialog
30+
import androidx.core.os.bundleOf
2931
import androidx.fragment.app.DialogFragment
3032
import com.google.android.material.dialog.MaterialAlertDialogBuilder
3133
import com.nextcloud.client.di.Injectable
3234
import com.owncloud.android.R
3335
import com.owncloud.android.databinding.StoragePermissionDialogBinding
34-
import com.owncloud.android.ui.dialog.StoragePermissionDialogFragment.Listener
3536
import com.owncloud.android.utils.theme.ViewThemeUtils
37+
import kotlinx.parcelize.Parcelize
3638
import javax.inject.Inject
3739

3840
/**
3941
* Dialog that shows permission options in SDK >= 30
4042
*
4143
* Allows choosing "full access" (MANAGE_ALL_FILES) or "read-only media" (READ_EXTERNAL_STORAGE)
42-
*
43-
* @param listener a [Listener] for button clicks. The dialog will auto-dismiss after the callback is called.
44-
* @param permissionRequired Whether the permission is absolutely required by the calling component.
45-
* This changes the texts to a more strict version.
4644
*/
4745
@RequiresApi(Build.VERSION_CODES.R)
48-
class StoragePermissionDialogFragment(val listener: Listener, val permissionRequired: Boolean = false) :
46+
class StoragePermissionDialogFragment :
4947
DialogFragment(), Injectable {
48+
5049
private lateinit var binding: StoragePermissionDialogBinding
5150

51+
private var permissionRequired = false
52+
5253
@Inject
5354
lateinit var viewThemeUtils: ViewThemeUtils
5455

56+
override fun onCreate(savedInstanceState: Bundle?) {
57+
super.onCreate(savedInstanceState)
58+
arguments?.let {
59+
permissionRequired = it.getBoolean(ARG_PERMISSION_REQUIRED, false)
60+
}
61+
}
62+
5563
override fun onStart() {
5664
super.onStart()
5765
dialog?.let {
@@ -75,12 +83,12 @@ class StoragePermissionDialogFragment(val listener: Listener, val permissionRequ
7583
// Setup layout
7684
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.btnFullAccess)
7785
binding.btnFullAccess.setOnClickListener {
78-
listener.onClickFullAccess()
86+
setResult(Result.FULL_ACCESS)
7987
dismiss()
8088
}
8189
viewThemeUtils.platform.colorTextButtons(binding.btnReadOnly)
8290
binding.btnReadOnly.setOnClickListener {
83-
listener.onClickMediaReadOnly()
91+
setResult(Result.MEDIA_READ_ONLY)
8492
dismiss()
8593
}
8694

@@ -94,7 +102,7 @@ class StoragePermissionDialogFragment(val listener: Listener, val permissionRequ
94102
.setTitle(titleResource)
95103
.setView(view)
96104
.setNegativeButton(R.string.common_cancel) { _, _ ->
97-
listener.onCancel()
105+
setResult(Result.CANCEL)
98106
dismiss()
99107
}
100108

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

106-
interface Listener {
107-
fun onCancel()
108-
fun onClickFullAccess()
109-
fun onClickMediaReadOnly()
114+
private fun setResult(result: Result) {
115+
parentFragmentManager.setFragmentResult(REQUEST_KEY, bundleOf(RESULT_KEY to result))
116+
}
117+
118+
@Parcelize
119+
enum class Result : Parcelable {
120+
CANCEL, FULL_ACCESS, MEDIA_READ_ONLY
121+
}
122+
123+
companion object {
124+
private const val ARG_PERMISSION_REQUIRED = "ARG_PERMISSION_REQUIRED"
125+
const val REQUEST_KEY = "REQUEST_KEY_STORAGE_PERMISSION"
126+
const val RESULT_KEY = "RESULT"
127+
128+
/**
129+
* @param permissionRequired Whether the permission is absolutely required by the calling component.
130+
* This changes the texts to a more strict version.
131+
*/
132+
fun newInstance(permissionRequired: Boolean): StoragePermissionDialogFragment {
133+
return StoragePermissionDialogFragment().apply {
134+
arguments = bundleOf(ARG_PERMISSION_REQUIRED to permissionRequired)
135+
}
136+
}
110137
}
111138
}

app/src/main/java/com/owncloud/android/utils/PermissionUtil.kt

+28-24
Original file line numberDiff line numberDiff line change
@@ -209,33 +209,37 @@ object PermissionUtil {
209209
viewThemeUtils: ViewThemeUtils
210210
) {
211211
val preferences: AppPreferences = AppPreferencesImpl.fromContext(activity)
212-
213-
if (!preferences.isStoragePermissionRequested || permissionRequired) {
214-
if (activity.supportFragmentManager.findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG) == null) {
215-
val listener = object : StoragePermissionDialogFragment.Listener {
216-
override fun onCancel() {
217-
preferences.isStoragePermissionRequested = true
218-
}
219-
220-
override fun onClickFullAccess() {
221-
preferences.isStoragePermissionRequested = true
222-
val intent = getManageAllFilesIntent(activity)
223-
activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_ALL_FILES)
224-
preferences.isStoragePermissionRequested = true
225-
}
226-
227-
override fun onClickMediaReadOnly() {
228-
preferences.isStoragePermissionRequested = true
229-
requestStoragePermission(
230-
activity,
231-
Manifest.permission.READ_EXTERNAL_STORAGE,
232-
viewThemeUtils
233-
)
212+
val shouldRequestPermission = !preferences.isStoragePermissionRequested || permissionRequired
213+
if (shouldRequestPermission &&
214+
activity.supportFragmentManager.findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG) == null
215+
) {
216+
activity.supportFragmentManager.setFragmentResultListener(
217+
StoragePermissionDialogFragment.REQUEST_KEY,
218+
activity
219+
) { _, resultBundle ->
220+
val result: StoragePermissionDialogFragment.Result? =
221+
resultBundle.getParcelable(StoragePermissionDialogFragment.RESULT_KEY)
222+
if (result != null) {
223+
preferences.isStoragePermissionRequested = true
224+
when (result) {
225+
StoragePermissionDialogFragment.Result.FULL_ACCESS -> {
226+
val intent = getManageAllFilesIntent(activity)
227+
activity.startActivityForResult(intent, REQUEST_CODE_MANAGE_ALL_FILES)
228+
}
229+
StoragePermissionDialogFragment.Result.MEDIA_READ_ONLY -> {
230+
requestStoragePermission(
231+
activity,
232+
Manifest.permission.READ_EXTERNAL_STORAGE,
233+
viewThemeUtils
234+
)
235+
}
236+
StoragePermissionDialogFragment.Result.CANCEL -> {}
234237
}
235238
}
236-
val dialogFragment = StoragePermissionDialogFragment(listener, permissionRequired)
237-
dialogFragment.show(activity.supportFragmentManager, PERMISSION_CHOICE_DIALOG_TAG)
238239
}
240+
241+
val dialogFragment = StoragePermissionDialogFragment.newInstance(permissionRequired)
242+
dialogFragment.show(activity.supportFragmentManager, PERMISSION_CHOICE_DIALOG_TAG)
239243
}
240244
}
241245

0 commit comments

Comments
 (0)