Forráskód Böngészése

Make the file/folder chooser more intelligent about access permissions - parents are not parents if we can't access files inside of them.

Aidan Follestad 6 éve
szülő
commit
9d1e92d5d4

+ 2 - 2
files/src/main/java/com/afollestad/materialdialogs/files/DialogFileChooserExt.kt

@@ -30,8 +30,8 @@ import com.afollestad.materialdialogs.WhichButton.POSITIVE
 import com.afollestad.materialdialogs.actions.setActionButtonEnabled
 import com.afollestad.materialdialogs.customview.customView
 import com.afollestad.materialdialogs.customview.getCustomView
-import com.afollestad.materialdialogs.files.utilext.hasReadStoragePermission
-import com.afollestad.materialdialogs.files.utilext.hasWriteStoragePermission
+import com.afollestad.materialdialogs.files.util.hasReadStoragePermission
+import com.afollestad.materialdialogs.files.util.hasWriteStoragePermission
 import com.afollestad.materialdialogs.input.getInputField
 import com.afollestad.materialdialogs.input.input
 import com.afollestad.materialdialogs.internal.list.DialogRecyclerView

+ 2 - 2
files/src/main/java/com/afollestad/materialdialogs/files/DialogFolderChooserExt.kt

@@ -28,8 +28,8 @@ import com.afollestad.materialdialogs.WhichButton.POSITIVE
 import com.afollestad.materialdialogs.actions.setActionButtonEnabled
 import com.afollestad.materialdialogs.customview.customView
 import com.afollestad.materialdialogs.customview.getCustomView
-import com.afollestad.materialdialogs.files.utilext.hasReadStoragePermission
-import com.afollestad.materialdialogs.files.utilext.hasWriteStoragePermission
+import com.afollestad.materialdialogs.files.util.hasReadStoragePermission
+import com.afollestad.materialdialogs.files.util.hasWriteStoragePermission
 import com.afollestad.materialdialogs.internal.list.DialogRecyclerView
 import com.afollestad.materialdialogs.utils.MDUtil.maybeSetTextColor
 import java.io.File

+ 15 - 14
files/src/main/java/com/afollestad/materialdialogs/files/FileChooserAdapter.kt

@@ -28,14 +28,14 @@ import com.afollestad.materialdialogs.WhichButton.POSITIVE
 import com.afollestad.materialdialogs.actions.hasActionButtons
 import com.afollestad.materialdialogs.actions.setActionButtonEnabled
 import com.afollestad.materialdialogs.callbacks.onDismiss
-import com.afollestad.materialdialogs.files.utilext.betterParent
-import com.afollestad.materialdialogs.files.utilext.friendlyName
-import com.afollestad.materialdialogs.files.utilext.hasParent
-import com.afollestad.materialdialogs.files.utilext.jumpOverEmulated
-import com.afollestad.materialdialogs.utils.MDUtil.maybeSetTextColor
-import com.afollestad.materialdialogs.files.utilext.setVisible
+import com.afollestad.materialdialogs.files.util.betterParent
+import com.afollestad.materialdialogs.files.util.friendlyName
+import com.afollestad.materialdialogs.files.util.hasParent
+import com.afollestad.materialdialogs.files.util.jumpOverEmulated
+import com.afollestad.materialdialogs.files.util.setVisible
 import com.afollestad.materialdialogs.list.getItemSelector
 import com.afollestad.materialdialogs.utils.MDUtil.isColorDark
+import com.afollestad.materialdialogs.utils.MDUtil.maybeSetTextColor
 import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Dispatchers.Main
@@ -88,9 +88,10 @@ internal class FileChooserAdapter(
   }
 
   fun itemClicked(index: Int) {
-    if (currentFolder.hasParent() && index == goUpIndex()) {
+    val parent = currentFolder.betterParent(allowFolderCreation, filter)
+    if (parent != null && index == goUpIndex()) {
       // go up
-      switchDirectory(currentFolder.betterParent()!!)
+      switchDirectory(parent)
       return
     } else if (currentFolder.canWrite() && allowFolderCreation && index == newFolderIndex()) {
       // New folder
@@ -158,7 +159,7 @@ internal class FileChooserAdapter(
 
   override fun getItemCount(): Int {
     var count = contents?.size ?: 0
-    if (currentFolder.hasParent()) {
+    if (currentFolder.hasParent(allowFolderCreation, filter)) {
       count += 1
     }
     if (allowFolderCreation && currentFolder.canWrite()) {
@@ -184,7 +185,7 @@ internal class FileChooserAdapter(
     holder: FileChooserViewHolder,
     position: Int
   ) {
-    val currentParent = currentFolder.betterParent()
+    val currentParent = currentFolder.betterParent(allowFolderCreation, filter)
     if (currentParent != null && position == goUpIndex()) {
       // Go up
       holder.iconView.setImageResource(
@@ -216,13 +217,13 @@ internal class FileChooserAdapter(
     holder.itemView.isActivated = selectedFile?.absolutePath == item.absolutePath ?: false
   }
 
-  private fun goUpIndex() = if (currentFolder.hasParent()) 0 else -1
+  private fun goUpIndex() = if (currentFolder.hasParent(allowFolderCreation, filter)) 0 else -1
 
-  private fun newFolderIndex() = if (currentFolder.hasParent()) 1 else 0
+  private fun newFolderIndex() = if (currentFolder.hasParent(allowFolderCreation, filter)) 1 else 0
 
   private fun actualIndex(position: Int): Int {
     var actualIndex = position
-    if (currentFolder.hasParent()) {
+    if (currentFolder.hasParent(allowFolderCreation, filter)) {
       actualIndex -= 1
     }
     if (currentFolder.canWrite() && allowFolderCreation) {
@@ -245,6 +246,6 @@ internal class FileChooserAdapter(
     if (selectedFile == null) return -1
     else if (contents?.isEmpty() == true) return -1
     val index = contents?.indexOfFirst { it.absolutePath == selectedFile?.absolutePath } ?: -1
-    return if (index > -1 && currentFolder.hasParent()) index + 1 else index
+    return if (index > -1 && currentFolder.hasParent(allowFolderCreation, filter)) index + 1 else index
   }
 }

+ 28 - 13
files/src/main/java/com/afollestad/materialdialogs/files/utilext/FilesUtilExt.kt → files/src/main/java/com/afollestad/materialdialogs/files/util/FilesUtilExt.kt

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.afollestad.materialdialogs.files.utilext
+package com.afollestad.materialdialogs.files.util
 
 import android.Manifest.permission
 import android.content.Context
@@ -21,29 +21,44 @@ import android.content.pm.PackageManager
 import android.os.Environment.getExternalStorageDirectory
 import androidx.core.content.ContextCompat
 import com.afollestad.materialdialogs.MaterialDialog
+import com.afollestad.materialdialogs.files.FileFilter
 import java.io.File
 
-internal fun File.hasParent() = betterParent() != null
+internal fun File.hasParent(
+  writeable: Boolean,
+  filter: FileFilter
+) = betterParent(writeable, filter) != null
 
 internal fun File.isExternalStorage() =
   absolutePath == getExternalStorageDirectory().absolutePath
 
 internal fun File.isRoot() = absolutePath == "/"
 
-internal fun File.betterParent(): File? {
-  if (this.isExternalStorage()) {
+internal fun File.betterParent(
+  writeable: Boolean,
+  filter: FileFilter
+): File? {
+  val parentToUse = if (this.isExternalStorage()) {
     // Emulated external storage's parent is empty so jump over it
-    return getExternalStorageDirectory().parentFile.parentFile
+    getExternalStorageDirectory().parentFile.parentFile
+  } else {
+    parentFile
   }
-  if (parentFile?.isRoot() == true) {
-    val rootContent = parentFile.list() ?: emptyArray()
-    if (rootContent.isEmpty()) {
-      // If device isn't rooted, don't allow root dir access so we don't get stuck
-      return null
-    }
+
+  if ((writeable && !parentToUse.canWrite()) || !parentToUse.canRead()) {
+    // We can't access this folder
+    return null
+  }
+
+  val folderContent =
+    parentToUse.listFiles()?.filter { filter?.invoke(it) ?: true } ?: emptyList()
+  if (folderContent.isEmpty()) {
+    // There is nothing in this folder most likely because we can't access files inside of it.
+    // We don't want to get stuck here.
+    return null
   }
-  // Else normal operation
-  return parentFile
+
+  return parentToUse
 }
 
 internal fun File.jumpOverEmulated(): File {

+ 1 - 1
files/src/main/java/com/afollestad/materialdialogs/files/utilext/ViewExt.kt → files/src/main/java/com/afollestad/materialdialogs/files/util/ViewExt.kt

@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.afollestad.materialdialogs.files.utilext
+package com.afollestad.materialdialogs.files.util
 
 import android.view.View