-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d554bb3
commit c0df86a
Showing
7 changed files
with
95 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,27 @@ | ||
/* | ||
* Copyright (C) 2014-2021 Arpit Khurana <[email protected]>, Vishal Nehra <[email protected]>, | ||
* Emmanuel Messulam<[email protected]>, Raymond Lai <airwave209gt at gmail.com> and Contributors. | ||
* | ||
* This file is part of Amaze File Manager. | ||
* | ||
* Amaze File Manager is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
package com.amaze.filemanager.file_operations.filesystem.filetypes.file | ||
package com.amaze.filemanager.filesystem.files | ||
|
||
import android.content.ContentValues | ||
import android.os.Build | ||
import android.provider.MediaStore | ||
import android.util.Log | ||
import androidx.preference.PreferenceManager | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.AmazeFile | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.AmazeFilesystem | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.ContextProvider | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.ExternalSdCardOperation.getDocumentFile | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.ExternalSdCardOperation.isOnExtSdCard | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.UriForSafPersistance.get | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.ExternalSdCardOperation | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.MediaStoreHack | ||
import com.amaze.filemanager.file_operations.filesystem.filetypes.file.UriForSafPersistance | ||
import com.amaze.filemanager.filesystem.RootHelper | ||
import com.amaze.filemanager.filesystem.root.MakeDirectoryCommand | ||
import java.io.* | ||
|
||
/** | ||
* This is in in essence calls to UnixFilesystem, but that class is not public so all calls must go | ||
* through java.io.File | ||
*/ | ||
object FileAmazeFilesystem : AmazeFilesystem() { | ||
const val PREFERENCE_ROOTMODE = "rootmode" | ||
|
||
@JvmStatic | ||
val TAG = FileAmazeFilesystem::class.java.simpleName | ||
|
||
|
@@ -48,8 +33,7 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
return path[0] == getSeparator() | ||
} | ||
|
||
override val prefix: String | ||
get() = throw NotImplementedError() | ||
override val prefix: String = "" | ||
|
||
override fun getSeparator(): Char { | ||
return File.separatorChar | ||
|
@@ -85,7 +69,11 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
} | ||
|
||
override fun exists(f: AmazeFile, contextProvider: ContextProvider): Boolean { | ||
return f.exists(contextProvider) | ||
return runAsNormalOrRoot(f, contextProvider, { | ||
File(f.path).exists() | ||
}) { | ||
RootHelper.fileExists(f.path) | ||
} | ||
} | ||
|
||
override fun isFile(f: AmazeFile, contextProvider: ContextProvider): Boolean { | ||
|
@@ -143,6 +131,7 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
} | ||
|
||
override fun delete(f: AmazeFile, contextProvider: ContextProvider): Boolean { | ||
|
||
if (f.isDirectory(contextProvider)) { | ||
val children = f.listFiles(contextProvider) | ||
if (children != null) { | ||
|
@@ -159,8 +148,8 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
|
||
// Try with Storage Access Framework. | ||
if (context != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||
val document = getDocumentFile( | ||
f, true, context, get(context) | ||
val document = ExternalSdCardOperation.getDocumentFile( | ||
f, true, context, UriForSafPersistance.get(context) | ||
) | ||
if (document != null && document.delete()) { | ||
return true | ||
|
@@ -176,7 +165,7 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
|
||
// Delete the created entry, such that content provider will delete the file. | ||
resolver.delete( | ||
MediaStore.Files.getContentUri("external"), | ||
MediaStore.Files.getContentUri("external"), | ||
MediaStore.MediaColumns.DATA + "=?", arrayOf(f.absolutePath) | ||
) | ||
} | ||
|
@@ -189,10 +178,10 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
|
||
// Try with Storage Access Framework. | ||
if (context != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && | ||
isOnExtSdCard(f, context) | ||
ExternalSdCardOperation.isOnExtSdCard(f, context) | ||
) { | ||
val document = getDocumentFile( | ||
f, false, context, get(context) | ||
val document = ExternalSdCardOperation.getDocumentFile( | ||
f, false, context, UriForSafPersistance.get(context) | ||
) ?: return true | ||
if (document.delete()) { | ||
return true | ||
|
@@ -235,8 +224,8 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
val context = contextProvider.getContext() ?: return null | ||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | ||
// Storage Access Framework | ||
val targetDocument = getDocumentFile( | ||
f, false, context, get(context) | ||
val targetDocument = ExternalSdCardOperation.getDocumentFile( | ||
f, false, context, UriForSafPersistance.get(context) | ||
) ?: return null | ||
return context.contentResolver.openOutputStream(targetDocument.uri) | ||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { | ||
|
@@ -252,36 +241,42 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
} | ||
|
||
override fun createDirectory(f: AmazeFile, contextProvider: ContextProvider): Boolean { | ||
if (File(f.path).mkdir()) { | ||
return true | ||
} | ||
val context = contextProvider.getContext() | ||
|
||
// Try with Storage Access Framework. | ||
if (context != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && | ||
isOnExtSdCard(f, context) | ||
) { | ||
val preferenceUri = get(context) | ||
val document = getDocumentFile(f, true, context, preferenceUri) | ||
?: return false | ||
// getDocumentFile implicitly creates the directory. | ||
return document.exists() | ||
} | ||
return runAsNormalOrRoot(f, contextProvider, { | ||
if (File(f.path).mkdir()) { | ||
return@runAsNormalOrRoot true | ||
} | ||
val context = contextProvider.getContext() | ||
|
||
// Try the Kitkat workaround. | ||
return if (context != null && Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { | ||
try { | ||
MediaStoreHack.mkdir(context, f) | ||
} catch (e: IOException) { | ||
false | ||
// Try with Storage Access Framework. | ||
if (context != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && | ||
ExternalSdCardOperation.isOnExtSdCard(f, context) | ||
) { | ||
val preferenceUri = UriForSafPersistance.get(context) | ||
val document = ExternalSdCardOperation.getDocumentFile(f, true, context, preferenceUri) | ||
?: return@runAsNormalOrRoot false | ||
// getDocumentFile implicitly creates the directory. | ||
return@runAsNormalOrRoot document.exists() | ||
} | ||
} else false | ||
|
||
// Try the Kitkat workaround. | ||
return@runAsNormalOrRoot if (context != null && Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { | ||
try { | ||
MediaStoreHack.mkdir(context, f) | ||
} catch (e: IOException) { | ||
false | ||
} | ||
} else false | ||
}) { | ||
val parent = f.parent ?: return@runAsNormalOrRoot false | ||
MakeDirectoryCommand.makeDirectory(parent, f.name) | ||
return@runAsNormalOrRoot true | ||
} | ||
} | ||
|
||
override fun rename( | ||
file1: AmazeFile, | ||
file2: AmazeFile, | ||
contextProvider: ContextProvider | ||
file1: AmazeFile, | ||
file2: AmazeFile, | ||
contextProvider: ContextProvider | ||
): Boolean { | ||
return File(file1.path).renameTo(File(file2.path)) | ||
} | ||
|
@@ -313,4 +308,28 @@ object FileAmazeFilesystem : AmazeFilesystem() { | |
override fun hashCode(f: AmazeFile): Int { | ||
return File(f.path).hashCode() | ||
} | ||
} | ||
|
||
private fun <T> runAsNormalOrRoot(file: AmazeFile, contextProvider: ContextProvider, | ||
normalMode: () -> T, rootMode: () -> T): T { | ||
val context = contextProvider.getContext() ?: return normalMode() | ||
|
||
val rootmode = PreferenceManager.getDefaultSharedPreferences(context) | ||
.getBoolean(PREFERENCE_ROOTMODE, false) | ||
|
||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { | ||
if (rootmode && !canRead(file, contextProvider)) { | ||
return rootMode() | ||
} | ||
|
||
return normalMode() | ||
} | ||
|
||
if (ExternalSdCardOperation.isOnExtSdCard(file, context)) { | ||
return normalMode() | ||
} else if (rootmode && !canRead(file, contextProvider)) { | ||
return rootMode() | ||
} | ||
|
||
return normalMode() | ||
} | ||
} |
Oops, something went wrong.