From c0df86a5a1d1f7e17694f6a2629ec29961cbf0c4 Mon Sep 17 00:00:00 2001 From: EmmanuelMess Date: Sun, 6 Feb 2022 11:51:40 -0300 Subject: [PATCH] Fix some rootmode operations --- .../adapters/AppsRecyclerAdapter.kt | 2 +- .../filesystem/ExternalSdCardOperation.kt | 3 - .../filemanager/filesystem/HybridFile.java | 59 +------- .../files/DocumentFileAmazeFilesystem.kt | 9 +- .../filesystem/files}/FileAmazeFilesystem.kt | 141 ++++++++++-------- .../PreferencesConstants.kt | 5 +- .../filesystem/filetypes/AmazeFilesystem.kt | 2 +- 7 files changed, 95 insertions(+), 126 deletions(-) rename {file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/file => app/src/main/java/com/amaze/filemanager/filesystem/files}/FileAmazeFilesystem.kt (71%) diff --git a/app/src/main/java/com/amaze/filemanager/adapters/AppsRecyclerAdapter.kt b/app/src/main/java/com/amaze/filemanager/adapters/AppsRecyclerAdapter.kt index 0e3da282e2..72bd47dea7 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/AppsRecyclerAdapter.kt +++ b/app/src/main/java/com/amaze/filemanager/adapters/AppsRecyclerAdapter.kt @@ -52,6 +52,7 @@ import com.amaze.filemanager.asynchronous.asynctasks.DeleteTask import com.amaze.filemanager.asynchronous.management.ServiceWatcherUtil import com.amaze.filemanager.asynchronous.services.CopyService import com.amaze.filemanager.file_operations.filesystem.OpenMode +import com.amaze.filemanager.filesystem.files.FileAmazeFilesystem import com.amaze.filemanager.filesystem.HybridFileParcelable import com.amaze.filemanager.filesystem.RootHelper import com.amaze.filemanager.filesystem.files.FileUtils @@ -68,7 +69,6 @@ import com.amaze.filemanager.utils.AnimUtils.marqueeAfterDelay import com.amaze.filemanager.utils.Utils import com.amaze.filemanager.utils.safeLet import java.io.File -import java.util.* import kotlin.collections.ArrayList import kotlin.math.roundToInt diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ExternalSdCardOperation.kt b/app/src/main/java/com/amaze/filemanager/filesystem/ExternalSdCardOperation.kt index db4e344bcd..19996bca56 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ExternalSdCardOperation.kt +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ExternalSdCardOperation.kt @@ -26,10 +26,7 @@ import android.net.Uri import android.os.Build import android.util.Log import androidx.documentfile.provider.DocumentFile -import androidx.preference.PreferenceManager -import com.amaze.filemanager.file_operations.filesystem.filetypes.file.FileAmazeFilesystem import com.amaze.filemanager.file_operations.filesystem.filetypes.file.UriForSafPersistance -import com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants import java.io.File import java.io.IOException import java.util.* diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index 8f31f61b37..1fbbe8f0f9 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -42,11 +42,6 @@ import com.amaze.filemanager.file_operations.exceptions.ShellNotRunningException; import com.amaze.filemanager.file_operations.filesystem.OpenMode; import com.amaze.filemanager.file_operations.filesystem.filetypes.AmazeFile; -import com.amaze.filemanager.file_operations.filesystem.filetypes.ContextProvider; -import com.amaze.filemanager.file_operations.filesystem.filetypes.cloud.box.BoxAccount; -import com.amaze.filemanager.file_operations.filesystem.filetypes.cloud.dropbox.DropboxAccount; -import com.amaze.filemanager.file_operations.filesystem.filetypes.cloud.gdrive.GoogledriveAccount; -import com.amaze.filemanager.file_operations.filesystem.filetypes.cloud.onedrive.OnedriveAccount; import com.amaze.filemanager.file_operations.filesystem.root.NativeOperations; import com.amaze.filemanager.filesystem.cloud.CloudUtil; import com.amaze.filemanager.filesystem.files.DocumentFileAmazeFilesystem; @@ -54,19 +49,13 @@ import com.amaze.filemanager.filesystem.root.DeleteFileCommand; import com.amaze.filemanager.filesystem.root.ListFilesCommand; import com.amaze.filemanager.filesystem.ssh.SFtpClientTemplate; -import com.amaze.filemanager.filesystem.ssh.SshClientTemplate; import com.amaze.filemanager.filesystem.ssh.SshClientUtils; import com.amaze.filemanager.filesystem.ssh.SshConnectionPool; -import com.amaze.filemanager.filesystem.ssh.Statvfs; import com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants; import com.amaze.filemanager.utils.DataUtils; import com.amaze.filemanager.utils.OTGUtil; import com.amaze.filemanager.utils.OnFileFound; -import com.amaze.filemanager.utils.Utils; -import com.cloudrail.si.interfaces.CloudStorage; -import com.cloudrail.si.types.SpaceAllocation; -import android.content.ContentResolver; import android.content.Context; import android.net.Uri; import android.os.Build; @@ -79,13 +68,9 @@ import jcifs.smb.SmbException; import jcifs.smb.SmbFile; -import net.schmizz.sshj.SSHClient; -import net.schmizz.sshj.common.Buffer; -import net.schmizz.sshj.sftp.FileMode; -import net.schmizz.sshj.sftp.RemoteFile; + import net.schmizz.sshj.sftp.RemoteResourceInfo; import net.schmizz.sshj.sftp.SFTPClient; -import net.schmizz.sshj.sftp.SFTPException; /** * Hybrid file for handeling all types of files @@ -756,35 +741,12 @@ public OutputStream getOutputStream(Context context) { } public boolean exists() { - if (isSmb() || isLocal() || isDropBoxFile() || isBoxFile() || isGoogleDriveFile() - || isOneDriveFile() || isDocumentFile() || isSftp()) { - return new AmazeFile(path).exists(() -> null); - } else if (isRoot()) { - return RootHelper.fileExists(path); - } - - return false; + return new AmazeFile(path).exists(() -> null); } /** Helper method to check file existence in otg */ public boolean exists(Context context) { - boolean exists = false; - try { - if (isSmb() || isLocal() || isDropBoxFile() || isBoxFile() || isGoogleDriveFile() - || isOneDriveFile() || isOtgFile() || isSftp() || isDocumentFile()) { - return new AmazeFile(path).exists(() -> context); - } else if (isDocumentFile()) { - exists = - OTGUtil.getDocumentFile( - path, SafRootHolder.getUriRoot(), context, OpenMode.DOCUMENT_FILE, false) - != null; - } else { - return (exists()); - } - } catch (Exception e) { - Log.i(getClass().getSimpleName(), "Failed to find file", e); - } - return exists; + return new AmazeFile(path).exists(() -> context); } /** @@ -807,22 +769,11 @@ public boolean isSimpleFile() { } public boolean setLastModified(final long date) { - if (isSmb() || isLocal() || isOneDriveFile() || isBoxFile() || isGoogleDriveFile() - || isDropBoxFile() || isSftp() || isOtgFile()) { - return new AmazeFile(path).setLastModified(date); - } - File f = getFile(); - return f.setLastModified(date); + return new AmazeFile(path).setLastModified(date); } public void mkdir(Context context) { - if (isSftp() || isSmb() || isLocal() || isRoot() || isCustomPath() || isUnknownFile() - || isOneDriveFile() || isBoxFile() || isGoogleDriveFile() || isDropBoxFile() - || isOtgFile() || isDocumentFile()) { - new AmazeFile(path).mkdirs(() -> context); - } else { - throw new IllegalStateException(); - } + new AmazeFile(path).mkdirs(() -> context); } public boolean delete(Context context, boolean rootmode) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/files/DocumentFileAmazeFilesystem.kt b/app/src/main/java/com/amaze/filemanager/filesystem/files/DocumentFileAmazeFilesystem.kt index e06dec1fe7..b0575effbe 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/files/DocumentFileAmazeFilesystem.kt +++ b/app/src/main/java/com/amaze/filemanager/filesystem/files/DocumentFileAmazeFilesystem.kt @@ -11,7 +11,6 @@ import com.amaze.filemanager.file_operations.filesystem.filetypes.ContextProvide import com.amaze.filemanager.filesystem.FileProperties.getDeviceStorageRemainingSpace import com.amaze.filemanager.filesystem.SafRootHolder.uriRoot import com.amaze.filemanager.filesystem.SafRootHolder.volumeLabel -import com.amaze.filemanager.filesystem.otg.OtgAmazeFilesystem import com.amaze.filemanager.utils.OTGUtil.getDocumentFile import java.io.FileNotFoundException import java.io.IOException @@ -54,8 +53,12 @@ object DocumentFileAmazeFilesystem: AmazeFilesystem() { } override fun exists(f: AmazeFile, contextProvider: ContextProvider): Boolean { - val documentFile = getDocumentFile(f.path, false) ?: return false - return documentFile.exists() + val uriRoot = uriRoot ?: return false + val context = contextProvider.getContext() ?: return false + val documentFile = getDocumentFile( + f.path, uriRoot, context, OpenMode.DOCUMENT_FILE, false + ) + return documentFile != null } override fun isFile(f: AmazeFile, contextProvider: ContextProvider): Boolean { diff --git a/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/file/FileAmazeFilesystem.kt b/app/src/main/java/com/amaze/filemanager/filesystem/files/FileAmazeFilesystem.kt similarity index 71% rename from file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/file/FileAmazeFilesystem.kt rename to app/src/main/java/com/amaze/filemanager/filesystem/files/FileAmazeFilesystem.kt index 971929ba34..7d1b321468 100644 --- a/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/file/FileAmazeFilesystem.kt +++ b/app/src/main/java/com/amaze/filemanager/filesystem/files/FileAmazeFilesystem.kt @@ -1,35 +1,18 @@ -/* - * Copyright (C) 2014-2021 Arpit Khurana , Vishal Nehra , - * Emmanuel Messulam, Raymond Lai 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 . - */ - -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.* /** @@ -37,6 +20,8 @@ import java.io.* * 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 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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PreferencesConstants.kt b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PreferencesConstants.kt index 1ac49653ff..0bc0223dcd 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PreferencesConstants.kt +++ b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PreferencesConstants.kt @@ -20,8 +20,7 @@ package com.amaze.filemanager.ui.fragments.preference_fragments -import com.amaze.filemanager.file_operations.filesystem.filetypes.file.FileAmazeFilesystem -import com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_ROOTMODE +import com.amaze.filemanager.filesystem.files.FileAmazeFilesystem object PreferencesConstants { // appearance_prefs.xml @@ -71,7 +70,7 @@ object PreferencesConstants { // behavior_prefs.xml const val PREFERENCE_ROOT_LEGACY_LISTING = "legacyListing" - const val PREFERENCE_ROOTMODE = "rootmode" + const val PREFERENCE_ROOTMODE = FileAmazeFilesystem.PREFERENCE_ROOTMODE const val PREFERENCE_CHANGEPATHS = "typeablepaths" const val PREFERENCE_SAVED_PATHS = "savepaths" const val PREFERENCE_ZIP_EXTRACT_PATH = "extractpath" diff --git a/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/AmazeFilesystem.kt b/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/AmazeFilesystem.kt index 67f596f91c..283a9fa59a 100644 --- a/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/AmazeFilesystem.kt +++ b/file_operations/src/main/java/com/amaze/filemanager/file_operations/filesystem/filetypes/AmazeFilesystem.kt @@ -267,7 +267,7 @@ abstract class AmazeFilesystem { return `val`.equals("true", ignoreCase = true) } - /* + /* * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. *