From 27572446cd0310389500e926fd6e3d29943c0e66 Mon Sep 17 00:00:00 2001 From: Jens Mueller Date: Mon, 15 Apr 2019 09:36:41 +0200 Subject: [PATCH 1/6] remove unused code Signed-off-by: Jens Mueller --- .../com/owncloud/android/utils/UriUtils.java | 179 +----------------- 1 file changed, 9 insertions(+), 170 deletions(-) diff --git a/src/main/java/com/owncloud/android/utils/UriUtils.java b/src/main/java/com/owncloud/android/utils/UriUtils.java index c2dea45223af..d57a03c550b1 100644 --- a/src/main/java/com/owncloud/android/utils/UriUtils.java +++ b/src/main/java/com/owncloud/android/utils/UriUtils.java @@ -18,15 +18,10 @@ package com.owncloud.android.utils; -import android.annotation.TargetApi; import android.content.ContentResolver; -import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.provider.DocumentsContract; import android.provider.MediaStore; import android.webkit.MimeTypeMap; @@ -34,15 +29,13 @@ import java.util.Locale; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - /** * A helper class for some Uri operations. */ public final class UriUtils { - public static final String TAG = UriUtils.class.getSimpleName(); + private static final String TAG = UriUtils.class.getSimpleName(); public static final String URI_CONTENT_SCHEME = "content://"; @@ -50,161 +43,13 @@ private UriUtils() { // utility class -> private constructor } - /** - * Get the value of the data column for this Uri. This is useful for - * MediaStore Uris, and other file-based ContentProviders. - * - * @param context The context. - * @param uri The Uri to query. - * @param selection (Optional) Filter used in the query. - * @param selectionArgs (Optional) Selection arguments used in the query. - * @return The value of the _data column, which is typically a file path. - */ - public static String getDataColumn(Context context, Uri uri, String selection, String... selectionArgs) { - - Cursor cursor = null; - final String column = "_data"; - final String[] projection = {column}; - - try { - cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); - if (cursor != null && cursor.moveToFirst()) { - - final int column_index = cursor.getColumnIndexOrThrow(column); - return cursor.getString(column_index); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - return null; - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is ExternalStorageProvider. - */ - public static boolean isExternalStorageDocument(Uri uri) { - return "com.android.externalstorage.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is DownloadsProvider. - */ - public static boolean isDownloadsDocument(Uri uri) { - return "com.android.providers.downloads.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is MediaProvider. - */ - public static boolean isMediaDocument(Uri uri) { - return "com.android.providers.media.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is Google Photos. - */ - public static boolean isGooglePhotosUri(Uri uri) { - return "com.google.android.apps.photos.content".equals(uri.getAuthority()); - } - - /** - * - * @param uri The Uri to check. - * @return Whether the Uri is from a content provider as kind "content://..." - */ - public static boolean isContentDocument(Uri uri) { - return uri.toString().startsWith(URI_CONTENT_SCHEME); - } - - - /** - * Translates a content:// URI referred to a local file file to a path on the local filesystem - * - * @param uri The URI to resolve - * @return The path in the file system to the content or null if it could not be found (not a file) - */ - @TargetApi(Build.VERSION_CODES.KITKAT) - @SuppressFBWarnings("Bx") - public static String getLocalPath(Uri uri, Context context) { - final boolean isKitKatOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - - // DocumentProvider - if (isKitKatOrLater && DocumentsContract.isDocumentUri(context, uri)) { - // ExternalStorageProvider - if (UriUtils.isExternalStorageDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - if ("primary".equalsIgnoreCase(type)) { - return Environment.getExternalStorageDirectory() + "/" + split[1]; - } - } - // DownloadsProvider - else if (UriUtils.isDownloadsDocument(uri)) { - - final String id = DocumentsContract.getDocumentId(uri); - final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), - Long.valueOf(id)); - - return UriUtils.getDataColumn(context, contentUri, null, (String) null); - } - // MediaProvider - else if (UriUtils.isMediaDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - Uri contentUri = null; - if ("image".equals(type)) { - contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - } else if ("video".equals(type)) { - contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - } else if ("audio".equals(type)) { - contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - } - - final String selection = "_id=?"; - final String[] selectionArgs = new String[]{split[1]}; - - return UriUtils.getDataColumn(context, contentUri, selection, selectionArgs); - } - // Documents providers returned as content://... - else if (UriUtils.isContentDocument(uri)) { - return uri.toString(); - } - } - // MediaStore (and general) - else if ("content".equalsIgnoreCase(uri.getScheme())) { - - // Return the remote address - if (UriUtils.isGooglePhotosUri(uri)) { - return uri.getLastPathSegment(); - } - - return UriUtils.getDataColumn(context, uri, null, (String) null); - } - // File - else if ("file".equalsIgnoreCase(uri.getScheme())) { - return uri.getPath(); - } - return null; - } - - public static String getDisplayNameForUri(Uri uri, Context context) { if (uri == null || context == null) { throw new IllegalArgumentException("Received NULL!"); } - String displayName = null; + String displayName; if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { displayName = uri.getLastPathSegment(); // ready to return @@ -258,15 +103,13 @@ private static String getDisplayNameFromContentResolver(Uri uri, Context context displayNameColumn = MediaStore.Files.FileColumns.DISPLAY_NAME; } - Cursor cursor = null; - try { - cursor = context.getContentResolver().query( - uri, - new String[]{displayNameColumn}, - null, - null, - null - ); + try (Cursor cursor = context.getContentResolver().query( + uri, + new String[]{displayNameColumn}, + null, + null, + null + )) { if (cursor != null) { cursor.moveToFirst(); displayName = cursor.getString(cursor.getColumnIndex(displayNameColumn)); @@ -276,10 +119,6 @@ private static String getDisplayNameFromContentResolver(Uri uri, Context context Log_OC.e(TAG, "Could not retrieve display name for " + uri.toString()); // nothing else, displayName keeps null - } finally { - if (cursor != null) { - cursor.close(); - } } } return displayName; From 2a08cb47d9f0e85d0f20e3eb9cf0fef8f120b424 Mon Sep 17 00:00:00 2001 From: Chris Narkiewicz Date: Tue, 16 Apr 2019 15:36:14 +0100 Subject: [PATCH 2/6] Initialize global context before MainApp.onCreate() Initialize global context just after attaching base context. ContentProvider depend on MainApp.getAppContext(), but ContentProvider.onCreate() is called *before* Application.onCreate(). This hack should improve stability of ContentProviders at process bring-up time until we address this with a proper DI. Signed-off-by: Chris Narkiewicz --- src/main/java/com/owncloud/android/MainApp.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/owncloud/android/MainApp.java b/src/main/java/com/owncloud/android/MainApp.java index 9dce6bb6bead..c54db07e165d 100644 --- a/src/main/java/com/owncloud/android/MainApp.java +++ b/src/main/java/com/owncloud/android/MainApp.java @@ -49,7 +49,6 @@ import com.nextcloud.client.di.DaggerAppComponent; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.client.preferences.AppPreferencesImpl; -import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.authentication.PassCodeManager; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.MediaFolder; @@ -163,9 +162,17 @@ public class MainApp extends MultiDexApplication implements @SuppressWarnings("unused") private boolean mBound; + /** + * Temporary hack + */ + private static void initGlobalContext(Context context) { + mContext = context; + } + @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); + initGlobalContext(this); DaggerAppComponent.builder() .application(this) .build() @@ -187,7 +194,6 @@ public void onCreate() { uploadsStorageManager ) ); - MainApp.mContext = getApplicationContext(); new SecurityUtils(); DisplayUtils.useCompatVectorIfNeeded(); From 52020a9bf32492befdbe1420d61810ed890b0f16 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 17 Apr 2019 07:17:24 +0200 Subject: [PATCH 3/6] direct usage of library project Signed-off-by: tobiasKaminsky --- SETUP.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/SETUP.md b/SETUP.md index 2b620cbd6777..5de4d029725e 100644 --- a/SETUP.md +++ b/SETUP.md @@ -85,3 +85,23 @@ The app is currently equipped to be built with three flavours: [6]: https://developer.android.com/sdk/installing/index.html?pkg=studio [7]: https://gradle.org/ [8]: https://docs.gradle.org/current/userguide/gradle_wrapper.html + +### 5. How-To + +#### 1. Direct usage of library project + +This is handy if one wants to make changes both to files app and library: +- in files app root: ln -s $pathToLibraryProject nextcloud-android-library +- uncomment in build.gradle: + - `// implementation project('nextcloud-android-library')` +- comment in build.gradle: + - `genericImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT'` + - `gplayImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT'` + - `versionDevImplementation 'com.github.nextcloud:android-library:master-SNAPSHOT'` +- comment in settings.gradle: + - `include ':'` +- uncomment in settings.gradle: + - `//include 'nextcloud-android-library'` +- sync project with gradle files + +Now every change in library can be directly used in files app. From 2afb934b4140ef43c2826cd723d888d38bee677e Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Wed, 17 Apr 2019 09:10:13 +0000 Subject: [PATCH 4/6] Drone: update FindBugs results to reflect reduced error/warning count [skip ci] Signed-off-by: nextcloud-android-bot --- scripts/analysis/findbugs-results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 662d98cc9235..5a40cf687a21 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -436 \ No newline at end of file +435 \ No newline at end of file From e6604c81015d71e6012c7c632b32c9b01bf69929 Mon Sep 17 00:00:00 2001 From: Jens Mueller Date: Wed, 17 Apr 2019 13:12:11 +0200 Subject: [PATCH 5/6] use constant Signed-off-by: Jens Mueller --- .../java/com/owncloud/android/datamodel/OCFile.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/owncloud/android/datamodel/OCFile.java b/src/main/java/com/owncloud/android/datamodel/OCFile.java index dbb5d7972e85..843a767a4a24 100644 --- a/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -199,17 +199,17 @@ public String getRemotePath() { if (isEncrypted() && !isFolder()) { String parentPath = new File(remotePath).getParent(); - if (parentPath.endsWith("/")) { + if (parentPath.endsWith(PATH_SEPARATOR)) { return parentPath + getEncryptedFileName(); } else { - return parentPath + "/" + getEncryptedFileName(); + return parentPath + PATH_SEPARATOR + getEncryptedFileName(); } } else { if (isFolder()) { - if (remotePath.endsWith("/")) { + if (remotePath.endsWith(PATH_SEPARATOR)) { return remotePath; } else { - return remotePath + "/"; + return remotePath + PATH_SEPARATOR; } } else { return remotePath; @@ -412,7 +412,7 @@ private void resetData() { */ public String getParentRemotePath() { String parentPath = new File(this.getRemotePath()).getParent(); - return parentPath.endsWith("/") ? parentPath : parentPath + "/"; + return parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR; } @Override From c7c6a989b4087f990c32cca1529ad1537a2670ba Mon Sep 17 00:00:00 2001 From: Jens Mueller Date: Wed, 17 Apr 2019 20:37:21 +0200 Subject: [PATCH 6/6] use constant Signed-off-by: Jens Mueller --- .../authentication/AuthenticatorAsyncTask.java | 5 +++-- .../datamodel/FileDataStorageManager.java | 4 +++- .../android/datamodel/SyncedFolderProvider.java | 4 +++- .../com/owncloud/android/jobs/FilesSyncJob.java | 4 +++- .../owncloud/android/jobs/OfflineSyncJob.java | 7 +++++-- .../operations/CreateFolderOperation.java | 9 ++++++--- .../providers/DocumentsStorageProvider.java | 13 ++++++++----- .../android/ui/activity/FileDisplayActivity.java | 4 +++- .../activity/ReceiveExternalFilesActivity.java | 11 +++++++---- .../android/ui/adapter/TrashbinListAdapter.java | 7 +++++-- .../android/ui/components/CustomEditText.java | 16 +++------------- .../android/ui/fragment/OCFileListFragment.java | 6 ++++-- .../android/ui/trashbin/TrashbinPresenter.java | 10 ++++++---- .../owncloud/android/utils/FilesSyncHelper.java | 9 +++++---- .../nextcloud/providers/cursors/RootCursor.java | 4 +++- 15 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java b/src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java index a18595bccc80..3a0c883b476d 100644 --- a/src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java +++ b/src/main/java/com/owncloud/android/authentication/AuthenticatorAsyncTask.java @@ -34,13 +34,14 @@ import java.lang.ref.WeakReference; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * Async Task to verify the credentials of a user */ public class AuthenticatorAsyncTask extends AsyncTask { - private static final String REMOTE_PATH = "/"; private static final boolean SUCCESS_IF_ABSENT = false; private WeakReference mWeakContext; @@ -66,7 +67,7 @@ protected RemoteOperationResult doInBackground(Object... params) { client.setCredentials(credentials); // Operation - try credentials - ExistenceCheckRemoteOperation operation = new ExistenceCheckRemoteOperation(REMOTE_PATH, SUCCESS_IF_ABSENT); + ExistenceCheckRemoteOperation operation = new ExistenceCheckRemoteOperation(ROOT_PATH, SUCCESS_IF_ABSENT); result = operation.execute(client); if (operation.wasRedirected()) { diff --git a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 09366886607b..1e0f62562725 100644 --- a/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -67,6 +67,8 @@ import lombok.Getter; import lombok.Setter; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + @Getter public class FileDataStorageManager { private static final String TAG = FileDataStorageManager.class.getSimpleName(); @@ -264,7 +266,7 @@ public boolean saveFile(OCFile file) { * @return the parent file */ public OCFile saveFileWithParent(OCFile file, Context context) { - if (file.getParentId() == 0 && !"/".equals(file.getRemotePath())) { + if (file.getParentId() == 0 && !ROOT_PATH.equals(file.getRemotePath())) { String remotePath = file.getRemotePath(); String parentPath = remotePath.substring(0, remotePath.lastIndexOf(file.getFileName())); diff --git a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java index e50210410381..eebb20093520 100644 --- a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java +++ b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java @@ -39,6 +39,8 @@ import androidx.annotation.NonNull; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; + /** * Database provider for handling the persistence aspects of {@link SyncedFolder}s. */ @@ -251,7 +253,7 @@ public void updateAutoUploadPaths(Context context) { for (SyncedFolder syncedFolder : syncedFolders) { if (!new File(syncedFolder.getLocalPath()).exists()) { String localPath = syncedFolder.getLocalPath(); - if (localPath.endsWith("/")) { + if (localPath.endsWith(PATH_SEPARATOR)) { localPath = localPath.substring(0, localPath.lastIndexOf('/')); } localPath = localPath.substring(0, localPath.lastIndexOf('/')); diff --git a/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java b/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java index 52f620d7c548..154b6580cd35 100644 --- a/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java +++ b/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java @@ -64,6 +64,8 @@ import androidx.annotation.NonNull; import androidx.exifinterface.media.ExifInterface; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; + /* Job that: - restarts existing jobs if required @@ -190,7 +192,7 @@ private void syncFolder(Context context, Resources resources, boolean lightVersi if (!subfolderByDate) { String adaptedPath = file.getAbsolutePath() .replace(syncedFolder.getLocalPath(), "") - .replace("/" + file.getName(), ""); + .replace(PATH_SEPARATOR + file.getName(), ""); remotePath += adaptedPath; } diff --git a/src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java b/src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java index fe433bde0979..2e4487e4c1e6 100644 --- a/src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java +++ b/src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java @@ -48,6 +48,9 @@ import androidx.annotation.NonNull; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + public class OfflineSyncJob extends Job { public static final String TAG = "OfflineSyncJob"; @@ -90,7 +93,7 @@ protected Result onRunJob(@NonNull Params params) { FileDataStorageManager storageManager = new FileDataStorageManager(account, getContext().getContentResolver()); - OCFile ocRoot = storageManager.getFileByPath("/"); + OCFile ocRoot = storageManager.getFileByPath(ROOT_PATH); if (ocRoot.getStoragePath() == null) { break; @@ -109,7 +112,7 @@ protected Result onRunJob(@NonNull Params params) { private void recursive(File folder, FileDataStorageManager storageManager, Account account) { String downloadFolder = FileStorageUtils.getSavePath(account.name); - String folderName = folder.getAbsolutePath().replaceFirst(downloadFolder, "") + "/"; + String folderName = folder.getAbsolutePath().replaceFirst(downloadFolder, "") + PATH_SEPARATOR; Log_OC.d(TAG, folderName + ": enter"); // exit diff --git a/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java b/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java index 792936f653a7..45c8b024b93d 100644 --- a/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java +++ b/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java @@ -34,6 +34,9 @@ import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.MimeType; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * Access to remote operation performing the creation of a new folder in the ownCloud server. @@ -99,13 +102,13 @@ private void saveFolderInDB() { getFileByPath(FileStorageUtils.getParentPath(mRemotePath)) == null){// When parent // of remote path // is not created - String[] subFolders = mRemotePath.split("/"); - String composedRemotePath = "/"; + String[] subFolders = mRemotePath.split(PATH_SEPARATOR); + String composedRemotePath = ROOT_PATH; // For each ancestor folders create them recursively for (String subFolder : subFolders) { if (!subFolder.isEmpty()) { - composedRemotePath = composedRemotePath + subFolder + "/"; + composedRemotePath = composedRemotePath + subFolder + PATH_SEPARATOR; mRemotePath = composedRemotePath; saveFolderInDB(); } diff --git a/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java b/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java index 790f89cb9978..d0f8296ef154 100644 --- a/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java +++ b/src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java @@ -89,6 +89,9 @@ import dagger.android.AndroidInjection; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + @TargetApi(Build.VERSION_CODES.KITKAT) public class DocumentsStorageProvider extends DocumentsProvider { @@ -396,7 +399,7 @@ public String copyDocument(String sourceDocumentId, String targetParentDocumentI String newPath = targetFolder.getRemotePath() + file.getFileName(); if (file.isFolder()) { - newPath = newPath + "/"; + newPath = newPath + PATH_SEPARATOR; } OCFile newFile = currentStorageManager.getFileByPath(newPath); @@ -438,7 +441,7 @@ public String moveDocument(String sourceDocumentId, String sourceParentDocumentI public Cursor querySearchDocuments(String rootId, String query, String[] projection) { updateCurrentStorageManagerIfNeeded(rootId); - OCFile root = currentStorageManager.getFileByPath("/"); + OCFile root = currentStorageManager.getFileByPath(ROOT_PATH); FileCursor result = new FileCursor(projection); for (OCFile f : findFiles(root, query)) { @@ -469,7 +472,7 @@ public String createDocument(String documentId, String mimeType, String displayN private String createFolder(OCFile parent, String displayName, String documentId) throws FileNotFoundException { CreateFolderOperation createFolderOperation = new CreateFolderOperation(parent.getRemotePath() + displayName - + "/", true); + + PATH_SEPARATOR, true); RemoteOperationResult result = createFolderOperation.execute(client, currentStorageManager); @@ -479,7 +482,7 @@ private String createFolder(OCFile parent, String displayName, String documentId } - String newDirPath = parent.getRemotePath() + displayName + "/"; + String newDirPath = parent.getRemotePath() + displayName + PATH_SEPARATOR; OCFile newFolder = currentStorageManager.getFileByPath(newDirPath); return String.valueOf(newFolder.getFileId()); @@ -601,7 +604,7 @@ private void initiateStorageMap() throws FileNotFoundException { for (Account account : accountManager.getAccounts()) { final FileDataStorageManager storageManager = new FileDataStorageManager(account, contentResolver); - final OCFile rootDir = storageManager.getFileByPath("/"); + final OCFile rootDir = storageManager.getFileByPath(ROOT_PATH); rootIdToStorageManager.put(rootDir.getFileId(), storageManager); } } diff --git a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java index cde483679ead..6ad33c85cce5 100644 --- a/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -148,6 +148,8 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; + /** * Displays, what files the user has available in his ownCloud. This is the main view. */ @@ -983,7 +985,7 @@ public void onCheckAvailableSpaceFinish(boolean hasEnoughSpaceAvailable, String. if (hasEnoughSpaceAvailable) { File file = new File(filesToUpload[0]); - File renamedFile = new File(file.getParent() + "/" + FileOperationsHelper.getCapturedImageName()); + File renamedFile = new File(file.getParent() + PATH_SEPARATOR + FileOperationsHelper.getCapturedImageName()); if (!file.renameTo(renamedFile)) { DisplayUtils.showSnackMessage(getActivity(), "Fail to upload taken image!"); diff --git a/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java b/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java index 9f28bb2059f3..683426418b61 100755 --- a/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java @@ -123,6 +123,9 @@ import javax.inject.Inject; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * This can be used to upload things to an ownCloud instance. */ @@ -174,7 +177,7 @@ protected void onCreate(Bundle savedInstanceState) { String parentPath = savedInstanceState.getString(KEY_PARENTS); if (parentPath != null) { - mParents.addAll(Arrays.asList(parentPath.split("/"))); + mParents.addAll(Arrays.asList(parentPath.split(PATH_SEPARATOR))); } mFile = savedInstanceState.getParcelable(KEY_FILE); @@ -884,7 +887,7 @@ private String generatePath(Stack dirs) { String full_path = ""; for (String a : dirs) { - full_path += a + "/"; + full_path += a + PATH_SEPARATOR; } return full_path; } @@ -1034,10 +1037,10 @@ private void initTargetFolder() { if (mParents.empty()) { String lastPath = preferences.getLastUploadPath(); // "/" equals root-directory - if ("/".equals(lastPath)) { + if (ROOT_PATH.equals(lastPath)) { mParents.add(""); } else { - String[] dir_names = lastPath.split("/"); + String[] dir_names = lastPath.split(PATH_SEPARATOR); mParents.clear(); mParents.addAll(Arrays.asList(dir_names)); } diff --git a/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java index 61cdba4e03bd..ffce386cdaae 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/TrashbinListAdapter.java @@ -51,6 +51,9 @@ import butterknife.BindView; import butterknife.ButterKnife; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * Adapter for the trashbin view */ @@ -134,9 +137,9 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi String location; int lastIndex = file.getOriginalLocation().lastIndexOf('/'); if (lastIndex != -1) { - location = "/" + file.getOriginalLocation().substring(0, lastIndex) + "/"; + location = ROOT_PATH + file.getOriginalLocation().substring(0, lastIndex) + PATH_SEPARATOR; } else { - location = "/"; + location = ROOT_PATH; } trashbinFileViewHolder.originalLocation.setText(location); diff --git a/src/main/java/com/owncloud/android/ui/components/CustomEditText.java b/src/main/java/com/owncloud/android/ui/components/CustomEditText.java index dc7463932de7..75540d836c75 100644 --- a/src/main/java/com/owncloud/android/ui/components/CustomEditText.java +++ b/src/main/java/com/owncloud/android/ui/components/CustomEditText.java @@ -30,6 +30,8 @@ import com.owncloud.android.R; import com.owncloud.android.authentication.AuthenticatorActivity; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; + /** * Custom edit text to support fixed suffix or prefix */ @@ -45,7 +47,7 @@ public CustomEditText(Context context, AttributeSet attrs) { if (AuthenticatorActivity.DIRECTORY_SERVER_INPUT_TYPE.equals(serverInputType)) { isPrefixFixed = true; - fixedText = getResources().getString(R.string.server_url) + "/"; + fixedText = getResources().getString(R.string.server_url) + PATH_SEPARATOR; } else if (AuthenticatorActivity.SUBDOMAIN_SERVER_INPUT_TYPE.equals(serverInputType)) { isPrefixFixed = false; fixedText = "." + getResources().getString(R.string.server_url); @@ -56,18 +58,6 @@ public CustomEditText(Context context, AttributeSet attrs) { } } - public String getFullServerUrl() { - if (TextUtils.isEmpty(fixedText) - || getText().toString().startsWith(AuthenticatorActivity.HTTP_PROTOCOL) - || getText().toString().startsWith(AuthenticatorActivity.HTTPS_PROTOCOL)) { - return getText().toString(); - } else if (isPrefixFixed) { - return getResources().getString(R.string.server_url) + "/" + getText().toString(); - } else { - return getText().toString() + "." + getResources().getString(R.string.server_url); - } - } - @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!TextUtils.isEmpty(fixedText)) { diff --git a/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 327381af44a2..130d613b1461 100644 --- a/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -129,6 +129,8 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * A Fragment that lists all files and folders in a given path. * TODO refactor to get rid of direct dependency on FileDisplayActivity @@ -796,7 +798,7 @@ public int onBrowseUp() { parentDir = storageManager.getFileByPath(parentPath); moveCount++; } else { - parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH); + parentDir = storageManager.getFileByPath(ROOT_PATH); } while (parentDir == null) { parentPath = new File(parentPath).getParent(); @@ -1140,7 +1142,7 @@ public void listDirectory(OCFile directory, boolean onlyOnDevice, boolean fromSe if (mFile != null) { directory = mFile; } else { - directory = storageManager.getFileByPath("/"); + directory = storageManager.getFileByPath(ROOT_PATH); if (directory == null) { return; // no files, wait for sync } diff --git a/src/main/java/com/owncloud/android/ui/trashbin/TrashbinPresenter.java b/src/main/java/com/owncloud/android/ui/trashbin/TrashbinPresenter.java index f642e7b0e5c3..391ca1f2844a 100644 --- a/src/main/java/com/owncloud/android/ui/trashbin/TrashbinPresenter.java +++ b/src/main/java/com/owncloud/android/ui/trashbin/TrashbinPresenter.java @@ -26,6 +26,8 @@ import java.io.File; import java.util.List; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + /** * Coordinates between model and view: querying model, updating view, react to UI input */ @@ -33,7 +35,7 @@ public class TrashbinPresenter implements TrashbinContract.Presenter { private TrashbinContract.View trashbinView; private TrashbinRepository trashbinRepository; - private String currentPath = "/"; + private String currentPath = ROOT_PATH; public TrashbinPresenter(TrashbinRepository trashbinRepository, TrashbinContract.View trashbinView) { this.trashbinRepository = trashbinRepository; @@ -48,12 +50,12 @@ public void enterFolder(String folder) { @Override public boolean isRoot() { - return !"/".equals(currentPath); + return !ROOT_PATH.equals(currentPath); } @Override public void navigateUp() { - if ("/".equals(currentPath)) { + if (ROOT_PATH.equals(currentPath)) { trashbinView.close(); } else { currentPath = new File(currentPath).getParent(); @@ -61,7 +63,7 @@ public void navigateUp() { loadFolder(); } - trashbinView.setDrawerIndicatorEnabled("/".equals(currentPath)); + trashbinView.setDrawerIndicatorEnabled(ROOT_PATH.equals(currentPath)); } @Override diff --git a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index b96fba57aac7..d57c72c9619e 100644 --- a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -68,6 +68,8 @@ import androidx.annotation.RequiresApi; +import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; + /** * Various utilities that make auto upload tick */ @@ -188,11 +190,10 @@ private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder) { String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DATE_MODIFIED}; String path = syncedFolder.getLocalPath(); - if (!path.endsWith("/")) { - path = path + "/%"; - } else { - path = path + "%"; + if (!path.endsWith(PATH_SEPARATOR)) { + path = path + PATH_SEPARATOR; } + path = path + "%"; String syncedFolderInitiatedKey = SYNCEDFOLDERINITIATED + syncedFolder.getId(); String dateInitiated = arbitraryDataProvider.getValue(GLOBAL, syncedFolderInitiatedKey); diff --git a/src/main/java/org/nextcloud/providers/cursors/RootCursor.java b/src/main/java/org/nextcloud/providers/cursors/RootCursor.java index 25be8f259343..8fc2ef0722bd 100644 --- a/src/main/java/org/nextcloud/providers/cursors/RootCursor.java +++ b/src/main/java/org/nextcloud/providers/cursors/RootCursor.java @@ -31,6 +31,8 @@ import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; +import static com.owncloud.android.datamodel.OCFile.ROOT_PATH; + @TargetApi(Build.VERSION_CODES.KITKAT) public class RootCursor extends MatrixCursor { @@ -47,7 +49,7 @@ public RootCursor(String... projection) { public void addRoot(Account account, Context context) { final FileDataStorageManager manager = new FileDataStorageManager(account, context.getContentResolver()); - final OCFile mainDir = manager.getFileByPath("/"); + final OCFile mainDir = manager.getFileByPath(ROOT_PATH); newRow().add(Root.COLUMN_ROOT_ID, account.name) .add(Root.COLUMN_DOCUMENT_ID, mainDir.getFileId())