From cdeff1696b84236d764f81da3d4df978b8fbc410 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sat, 26 Nov 2022 21:20:38 +0100 Subject: [PATCH 01/28] Use Room/DAO for getFolderContent Signed-off-by: Dariusz Olszewski --- .../client/database/DatabaseModule.kt | 6 + .../client/database/NextcloudDatabase.kt | 2 + .../nextcloud/client/database/dao/FileDao.kt | 33 +++++ .../datamodel/FileDataStorageManager.java | 127 +++++++++++++----- 4 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt diff --git a/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt b/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt index 822c0380c9..92aff3f3f2 100644 --- a/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt +++ b/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt @@ -25,6 +25,7 @@ package com.nextcloud.client.database import android.content.Context import com.nextcloud.client.core.Clock import com.nextcloud.client.database.dao.ArbitraryDataDao +import com.nextcloud.client.database.dao.FileDao import dagger.Module import dagger.Provides import javax.inject.Singleton @@ -42,4 +43,9 @@ class DatabaseModule { fun arbitraryDataDao(nextcloudDatabase: NextcloudDatabase): ArbitraryDataDao { return nextcloudDatabase.arbitraryDataDao() } + + @Provides + fun fileDao(nextcloudDatabase: NextcloudDatabase): FileDao { + return nextcloudDatabase.fileDao() + } } diff --git a/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt index 62b7045a59..64b19a55a8 100644 --- a/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt +++ b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt @@ -30,6 +30,7 @@ import androidx.room.RoomDatabase import com.nextcloud.client.core.Clock import com.nextcloud.client.core.ClockImpl import com.nextcloud.client.database.dao.ArbitraryDataDao +import com.nextcloud.client.database.dao.FileDao import com.nextcloud.client.database.entity.ArbitraryDataEntity import com.nextcloud.client.database.entity.CapabilityEntity import com.nextcloud.client.database.entity.ExternalLinkEntity @@ -65,6 +66,7 @@ import com.owncloud.android.db.ProviderMeta abstract class NextcloudDatabase : RoomDatabase() { abstract fun arbitraryDataDao(): ArbitraryDataDao + abstract fun fileDao(): FileDao companion object { const val FIRST_ROOM_DB_VERSION = 65 diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt new file mode 100644 index 0000000000..a2bb2588f8 --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -0,0 +1,33 @@ +/* + * Nextcloud Android client application + * + * @author Dariusz Olszewski + * Copyright (C) 2022 Dariusz Olszewski + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see . + * + */ + +package com.nextcloud.client.database.dao + +import androidx.room.Dao +import androidx.room.Query +import com.nextcloud.client.database.entity.FileEntity + +@Dao +interface FileDao { + @Query("SELECT * FROM filelist WHERE parent = :parentId") + fun getFolderContent(parentId: Long): List +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index b3eab7a91c..14275f96cd 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -41,6 +41,9 @@ import android.text.TextUtils; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.nextcloud.client.account.User; +import com.nextcloud.client.database.NextcloudDatabase; +import com.nextcloud.client.database.dao.FileDao; +import com.nextcloud.client.database.entity.FileEntity; import com.owncloud.android.MainApp; import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; import com.owncloud.android.lib.common.network.WebdavEntry; @@ -91,6 +94,9 @@ public class FileDataStorageManager { private final ContentProviderClient contentProviderClient; private final User user; + private final FileDao fileDao = NextcloudDatabase.getInstance(MainApp.getAppContext()).fileDao(); + private final Gson gson = new Gson(); + public FileDataStorageManager(User user, ContentResolver contentResolver) { this.contentProviderClient = null; this.contentResolver = contentResolver; @@ -861,46 +867,18 @@ public class FileDataStorageManager { } private List getFolderContent(long parentId, boolean onlyOnDevice) { + Log_OC.d(TAG, "getFolderContent - start"); List folderContent = new ArrayList<>(); - Uri requestURI = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, String.valueOf(parentId)); - Cursor cursor; - - if (getContentProviderClient() != null) { - try { - cursor = getContentProviderClient().query( - requestURI, - null, - ProviderTableMeta.FILE_PARENT + "=?", - new String[]{String.valueOf(parentId)}, - null - ); - } catch (RemoteException e) { - Log_OC.e(TAG, e.getMessage(), e); - return folderContent; + List files = fileDao.getFolderContent(parentId); + for (FileEntity fileEntity: files) { + OCFile child = createFileInstance(fileEntity); + if (!onlyOnDevice || child.existsOnDevice()) { + folderContent.add(child); } - } else { - cursor = getContentResolver().query( - requestURI, - null, - ProviderTableMeta.FILE_PARENT + "=?", - new String[]{String.valueOf(parentId)}, - null - ); - } - - if (cursor != null) { - if (cursor.moveToFirst()) { - do { - OCFile child = createFileInstance(cursor); - if (!onlyOnDevice || child.existsOnDevice()) { - folderContent.add(child); - } - } while (cursor.moveToNext()); - } - cursor.close(); } + Log_OC.d(TAG, "getFolderContent - finished"); return folderContent; } @@ -1046,6 +1024,85 @@ public class FileDataStorageManager { return ocFile; } + private OCFile createFileInstance(FileEntity fileEntity) { + OCFile ocFile = new OCFile(fileEntity.getPath()); + ocFile.setDecryptedRemotePath(fileEntity.getPathDecrypted()); + ocFile.setFileId(fileEntity.getId()); + ocFile.setParentId(fileEntity.getParent()); + ocFile.setMimeType(fileEntity.getContentType()); + ocFile.setStoragePath(fileEntity.getStoragePath()); + if (ocFile.getStoragePath() == null) { + // try to find existing file and bind it with current account; + // with the current update of SynchronizeFolderOperation, this won't be + // necessary anymore after a full synchronization of the account + File file = new File(FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), ocFile)); + if (file.exists()) { + ocFile.setStoragePath(file.getAbsolutePath()); + ocFile.setLastSyncDateForData(file.lastModified()); + } + } + ocFile.setFileLength(fileEntity.getContentLength()); + ocFile.setCreationTimestamp(fileEntity.getCreation()); + ocFile.setModificationTimestamp(fileEntity.getModified()); + ocFile.setModificationTimestampAtLastSyncForData(fileEntity.getModifiedAtLastSyncForData()); + ocFile.setLastSyncDateForProperties(fileEntity.getLastSyncDate()); + ocFile.setLastSyncDateForData(fileEntity.getLastSyncDateForData()); + ocFile.setEtag(fileEntity.getEtag()); + ocFile.setEtagOnServer(fileEntity.getEtagOnServer()); + ocFile.setSharedViaLink(fileEntity.getSharedViaLink() == 1); + ocFile.setSharedWithSharee(fileEntity.getSharedWithSharee() == 1); + ocFile.setPermissions(fileEntity.getPermissions()); + ocFile.setRemoteId(fileEntity.getRemoteId()); + ocFile.setUpdateThumbnailNeeded(fileEntity.getUpdateThumbnail() == 1); + ocFile.setDownloading(fileEntity.isDownloading() == 1); + ocFile.setEtagInConflict(fileEntity.getEtagInConflict()); + ocFile.setFavorite(fileEntity.getFavorite() == 1); + ocFile.setEncrypted(fileEntity.isEncrypted() == 1); +// if (ocFile.isEncrypted()) { +// ocFile.setFileName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_NAME))); +// } + Integer mountType = fileEntity.getMountType(); + if (mountType != null) { + ocFile.setMountType(WebdavEntry.MountType.values()[mountType]); + } + ocFile.setPreviewAvailable(fileEntity.getHasPreview() == 1); + ocFile.setUnreadCommentsCount(fileEntity.getUnreadCommentsCount()); + ocFile.setOwnerId(fileEntity.getOwnerId()); + ocFile.setOwnerDisplayName(fileEntity.getOwnerDisplayName()); + ocFile.setNote(fileEntity.getNote()); + ocFile.setRichWorkspace(fileEntity.getRichWorkspace()); + ocFile.setLocked(fileEntity.getLocked() == 1); + final int lockTypeInt = fileEntity.getLockType(); + ocFile.setLockType(lockTypeInt != -1 ? FileLockType.fromValue(lockTypeInt) : null); + ocFile.setLockOwnerId(fileEntity.getLockOwner()); + ocFile.setLockOwnerDisplayName(fileEntity.getLockOwnerDisplayName()); + ocFile.setLockOwnerEditor(fileEntity.getLockOwnerEditor()); + ocFile.setLockTimestamp(fileEntity.getLockTimestamp()); + ocFile.setLockTimeout(fileEntity.getLockTimeout()); + ocFile.setLockToken(fileEntity.getLockToken()); + + String sharees = fileEntity.getSharees(); + if (sharees == null || NULL_STRING.equals(sharees) || sharees.isEmpty()) { + ocFile.setSharees(new ArrayList<>()); + } else { + try { + ShareeUser[] shareesArray = gson.fromJson(sharees, ShareeUser[].class); + ocFile.setSharees(new ArrayList<>(Arrays.asList(shareesArray))); + } catch (JsonSyntaxException e) { + // ignore saved value due to api change + ocFile.setSharees(new ArrayList<>()); + } + } + + String metadataSize = fileEntity.getMetadataSize(); + ImageDimension imageDimension = gson.fromJson(metadataSize, ImageDimension.class); + if (imageDimension != null) { + ocFile.setImageDimension(imageDimension); + } + + return ocFile; + } + public boolean saveShare(OCShare share) { boolean overridden = false; From 092a3051dfc9f2629e1c1143a61a54f9e778a201 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sat, 26 Nov 2022 21:52:10 +0100 Subject: [PATCH 02/28] Missing newline (detekt) Signed-off-by: Dariusz Olszewski --- app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index a2bb2588f8..cbd85e2775 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -30,4 +30,4 @@ import com.nextcloud.client.database.entity.FileEntity interface FileDao { @Query("SELECT * FROM filelist WHERE parent = :parentId") fun getFolderContent(parentId: Long): List -} \ No newline at end of file +} From 1d44674d836af0cf3ce1607084afce2bc570bd43 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sat, 26 Nov 2022 23:16:47 +0100 Subject: [PATCH 03/28] Seems that timestamps need Long rather than Int Signed-off-by: Dariusz Olszewski --- .../nextcloud/client/database/entity/FileEntity.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt index e05bd6fd63..f90a0ff9fd 100644 --- a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt +++ b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt @@ -43,9 +43,9 @@ data class FileEntity( @ColumnInfo(name = ProviderTableMeta.FILE_PARENT) val parent: Int?, @ColumnInfo(name = ProviderTableMeta.FILE_CREATION) - val creation: Int?, + val creation: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_MODIFIED) - val modified: Int?, + val modified: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_TYPE) val contentType: String?, @ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_LENGTH) @@ -55,11 +55,11 @@ data class FileEntity( @ColumnInfo(name = ProviderTableMeta.FILE_ACCOUNT_OWNER) val accountOwner: String?, @ColumnInfo(name = ProviderTableMeta.FILE_LAST_SYNC_DATE) - val lastSyncDate: Int?, + val lastSyncDate: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA) - val lastSyncDateForData: Int?, + val lastSyncDateForData: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA) - val modifiedAtLastSyncForData: Int?, + val modifiedAtLastSyncForData: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_ETAG) val etag: String?, @ColumnInfo(name = ProviderTableMeta.FILE_ETAG_ON_SERVER) @@ -111,7 +111,7 @@ data class FileEntity( @ColumnInfo(name = ProviderTableMeta.FILE_LOCK_OWNER_EDITOR) val lockOwnerEditor: String?, @ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TIMESTAMP) - val lockTimestamp: Int?, + val lockTimestamp: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TIMEOUT) val lockTimeout: Int?, @ColumnInfo(name = ProviderTableMeta.FILE_LOCK_TOKEN) From 45b9006068e72637faedf56a68306acc11d22ac5 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sat, 26 Nov 2022 23:18:07 +0100 Subject: [PATCH 04/28] Convert NULL values for integer/long columns to 0 (SpotBugs) Signed-off-by: Dariusz Olszewski --- .../datamodel/FileDataStorageManager.java | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 14275f96cd..8fe07c9687 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -1024,11 +1024,19 @@ public class FileDataStorageManager { return ocFile; } + private int nullToZero(Integer i) { + return (i == null) ? 0 : i; + } + + private long nullToZero(Long i) { + return (i == null) ? 0 : i; + } + private OCFile createFileInstance(FileEntity fileEntity) { OCFile ocFile = new OCFile(fileEntity.getPath()); ocFile.setDecryptedRemotePath(fileEntity.getPathDecrypted()); - ocFile.setFileId(fileEntity.getId()); - ocFile.setParentId(fileEntity.getParent()); + ocFile.setFileId(nullToZero(fileEntity.getId())); + ocFile.setParentId(nullToZero(fileEntity.getParent())); ocFile.setMimeType(fileEntity.getContentType()); ocFile.setStoragePath(fileEntity.getStoragePath()); if (ocFile.getStoragePath() == null) { @@ -1041,44 +1049,44 @@ public class FileDataStorageManager { ocFile.setLastSyncDateForData(file.lastModified()); } } - ocFile.setFileLength(fileEntity.getContentLength()); - ocFile.setCreationTimestamp(fileEntity.getCreation()); - ocFile.setModificationTimestamp(fileEntity.getModified()); - ocFile.setModificationTimestampAtLastSyncForData(fileEntity.getModifiedAtLastSyncForData()); - ocFile.setLastSyncDateForProperties(fileEntity.getLastSyncDate()); - ocFile.setLastSyncDateForData(fileEntity.getLastSyncDateForData()); + ocFile.setFileLength(nullToZero(fileEntity.getContentLength())); + ocFile.setCreationTimestamp(nullToZero(fileEntity.getCreation())); + ocFile.setModificationTimestamp(nullToZero(fileEntity.getModified())); + ocFile.setModificationTimestampAtLastSyncForData(nullToZero(fileEntity.getModifiedAtLastSyncForData())); + ocFile.setLastSyncDateForProperties(nullToZero(fileEntity.getLastSyncDate())); + ocFile.setLastSyncDateForData(nullToZero(fileEntity.getLastSyncDateForData())); ocFile.setEtag(fileEntity.getEtag()); ocFile.setEtagOnServer(fileEntity.getEtagOnServer()); - ocFile.setSharedViaLink(fileEntity.getSharedViaLink() == 1); - ocFile.setSharedWithSharee(fileEntity.getSharedWithSharee() == 1); + ocFile.setSharedViaLink(nullToZero(fileEntity.getSharedViaLink()) == 1); + ocFile.setSharedWithSharee(nullToZero(fileEntity.getSharedWithSharee()) == 1); ocFile.setPermissions(fileEntity.getPermissions()); ocFile.setRemoteId(fileEntity.getRemoteId()); - ocFile.setUpdateThumbnailNeeded(fileEntity.getUpdateThumbnail() == 1); - ocFile.setDownloading(fileEntity.isDownloading() == 1); + ocFile.setUpdateThumbnailNeeded(nullToZero(fileEntity.getUpdateThumbnail()) == 1); + ocFile.setDownloading(nullToZero(fileEntity.isDownloading()) == 1); ocFile.setEtagInConflict(fileEntity.getEtagInConflict()); - ocFile.setFavorite(fileEntity.getFavorite() == 1); - ocFile.setEncrypted(fileEntity.isEncrypted() == 1); + ocFile.setFavorite(nullToZero(fileEntity.getFavorite()) == 1); + ocFile.setEncrypted(nullToZero(fileEntity.isEncrypted()) == 1); // if (ocFile.isEncrypted()) { // ocFile.setFileName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_NAME))); // } - Integer mountType = fileEntity.getMountType(); + Integer mountType = fileEntity.getMountType(); // TODO - any default when NULL returned? if (mountType != null) { ocFile.setMountType(WebdavEntry.MountType.values()[mountType]); } - ocFile.setPreviewAvailable(fileEntity.getHasPreview() == 1); - ocFile.setUnreadCommentsCount(fileEntity.getUnreadCommentsCount()); + ocFile.setPreviewAvailable(nullToZero(fileEntity.getHasPreview()) == 1); + ocFile.setUnreadCommentsCount(nullToZero(fileEntity.getUnreadCommentsCount())); ocFile.setOwnerId(fileEntity.getOwnerId()); ocFile.setOwnerDisplayName(fileEntity.getOwnerDisplayName()); ocFile.setNote(fileEntity.getNote()); ocFile.setRichWorkspace(fileEntity.getRichWorkspace()); - ocFile.setLocked(fileEntity.getLocked() == 1); - final int lockTypeInt = fileEntity.getLockType(); + ocFile.setLocked(nullToZero(fileEntity.getLocked()) == 1); + final int lockTypeInt = nullToZero(fileEntity.getLockType()); // TODO - what value should be used for NULL??? ocFile.setLockType(lockTypeInt != -1 ? FileLockType.fromValue(lockTypeInt) : null); ocFile.setLockOwnerId(fileEntity.getLockOwner()); ocFile.setLockOwnerDisplayName(fileEntity.getLockOwnerDisplayName()); ocFile.setLockOwnerEditor(fileEntity.getLockOwnerEditor()); - ocFile.setLockTimestamp(fileEntity.getLockTimestamp()); - ocFile.setLockTimeout(fileEntity.getLockTimeout()); + ocFile.setLockTimestamp(nullToZero(fileEntity.getLockTimestamp())); + ocFile.setLockTimeout(nullToZero(fileEntity.getLockTimeout())); ocFile.setLockToken(fileEntity.getLockToken()); String sharees = fileEntity.getSharees(); From 32a712061050a13982a7ca84fc2670644bace990 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 27 Nov 2022 00:23:23 +0100 Subject: [PATCH 05/28] Old implementation of getFolderContent ordered results by file name Signed-off-by: Dariusz Olszewski --- app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index cbd85e2775..028a599fd4 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -25,9 +25,10 @@ package com.nextcloud.client.database.dao import androidx.room.Dao import androidx.room.Query import com.nextcloud.client.database.entity.FileEntity +import com.owncloud.android.db.ProviderMeta.ProviderTableMeta @Dao interface FileDao { - @Query("SELECT * FROM filelist WHERE parent = :parentId") + @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getFolderContent(parentId: Long): List } From 71180412f9c037a6695ba8d0953a7443719757f8 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 27 Nov 2022 22:19:33 +0100 Subject: [PATCH 06/28] Use Room/DAO for getFileById Signed-off-by: Dariusz Olszewski --- .../main/java/com/nextcloud/client/database/dao/FileDao.kt | 3 +++ .../com/nextcloud/client/database/entity/FileEntity.kt | 2 +- .../owncloud/android/datamodel/FileDataStorageManager.java | 7 +++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 028a599fd4..41639b8220 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -29,6 +29,9 @@ import com.owncloud.android.db.ProviderMeta.ProviderTableMeta @Dao interface FileDao { + @Query("SELECT * FROM filelist WHERE _id = :id LIMIT 1") + fun getFileById(id: Long): FileEntity? + @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getFolderContent(parentId: Long): List } diff --git a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt index f90a0ff9fd..3c89ee77f1 100644 --- a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt +++ b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt @@ -31,7 +31,7 @@ import com.owncloud.android.db.ProviderMeta.ProviderTableMeta data class FileEntity( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = ProviderTableMeta._ID) - val id: Int?, + val id: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_NAME) val name: String?, @ColumnInfo(name = ProviderTableMeta.FILE_ENCRYPTED_NAME) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 8fe07c9687..b8e93cd41b 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -144,13 +144,12 @@ public class FileDataStorageManager { public @Nullable OCFile getFileById(long id) { - Cursor cursor = getFileCursorForValue(ProviderTableMeta._ID, String.valueOf(id)); OCFile ocFile = null; - if (cursor.moveToFirst()) { - ocFile = createFileInstance(cursor); + FileEntity fileEntity = fileDao.getFileById(id); + if (fileEntity != null) { + ocFile = createFileInstance(fileEntity); } - cursor.close(); return ocFile; } From dd8a70262e01958b63532f30e2938c7280357159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Mon, 28 Nov 2022 09:47:23 +0100 Subject: [PATCH 07/28] FileEntity: fix parent and contentLength types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../java/com/nextcloud/client/database/entity/FileEntity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt index 3c89ee77f1..f02a06af2a 100644 --- a/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt +++ b/app/src/main/java/com/nextcloud/client/database/entity/FileEntity.kt @@ -41,7 +41,7 @@ data class FileEntity( @ColumnInfo(name = ProviderTableMeta.FILE_PATH_DECRYPTED) val pathDecrypted: String?, @ColumnInfo(name = ProviderTableMeta.FILE_PARENT) - val parent: Int?, + val parent: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_CREATION) val creation: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_MODIFIED) @@ -49,7 +49,7 @@ data class FileEntity( @ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_TYPE) val contentType: String?, @ColumnInfo(name = ProviderTableMeta.FILE_CONTENT_LENGTH) - val contentLength: Int?, + val contentLength: Long?, @ColumnInfo(name = ProviderTableMeta.FILE_STORAGE_PATH) val storagePath: String?, @ColumnInfo(name = ProviderTableMeta.FILE_ACCOUNT_OWNER) From 5d8bb3e8f55271a041d5ea73cfc74f8ecc05de0f Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Mon, 28 Nov 2022 22:32:38 +0100 Subject: [PATCH 08/28] Simplify getFileById - as suggested in review comment Signed-off-by: Dariusz Olszewski --- .../owncloud/android/datamodel/FileDataStorageManager.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index b8e93cd41b..38e72029d5 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -144,14 +144,11 @@ public class FileDataStorageManager { public @Nullable OCFile getFileById(long id) { - OCFile ocFile = null; - FileEntity fileEntity = fileDao.getFileById(id); if (fileEntity != null) { - ocFile = createFileInstance(fileEntity); + return createFileInstance(fileEntity); } - - return ocFile; + return null; } public @Nullable From 8272facf41db3702668151000abb4597291934ac Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Wed, 30 Nov 2022 21:39:04 +0100 Subject: [PATCH 09/28] Use Room/DAO for other getFileByX and fileExists Signed-off-by: Dariusz Olszewski --- .../nextcloud/client/database/dao/FileDao.kt | 16 ++++ .../datamodel/FileDataStorageManager.java | 91 +++++-------------- 2 files changed, 37 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 41639b8220..0dbda22397 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -32,6 +32,22 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE _id = :id LIMIT 1") fun getFileById(id: Long): FileEntity? + // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? + @Query("SELECT * FROM filelist WHERE path = :path and file_owner = :fileOwner LIMIT 1") + fun getFileByEncryptedRemotePath(path: String, fileOwner: String): FileEntity? + + // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? + @Query("SELECT * FROM filelist WHERE path_decrypted = :path and file_owner = :fileOwner LIMIT 1") + fun getFileByDecryptedRemotePath(path: String, fileOwner: String): FileEntity? + + // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? + @Query("SELECT * FROM filelist WHERE media_path = :path and file_owner = :fileOwner LIMIT 1") + fun getFileByLocalPath(path: String, fileOwner: String): FileEntity? + + // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? + @Query("SELECT * FROM filelist WHERE remote_id = :remoteId and file_owner = :fileOwner LIMIT 1") + fun getFileByRemoteId(remoteId: String, fileOwner: String): FileEntity? + @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getFolderContent(parentId: Long): List } diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 38e72029d5..1322c53670 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -117,7 +117,8 @@ public class FileDataStorageManager { return getFileByEncryptedRemotePath(path); } - public OCFile getFileByEncryptedRemotePath(String path) { + public @Nullable + OCFile getFileByEncryptedRemotePath(String path) { return getFileByPath(ProviderTableMeta.FILE_PATH, path); } @@ -128,18 +129,19 @@ public class FileDataStorageManager { private @Nullable OCFile getFileByPath(String type, String path) { - Cursor cursor = getFileCursorForValue(type, path); - OCFile ocFile = null; - if (cursor.moveToFirst()) { - ocFile = createFileInstance(cursor); - } - cursor.close(); + FileEntity fileEntity = ProviderTableMeta.FILE_PATH.equals(type) ? + fileDao.getFileByEncryptedRemotePath(path, user.getAccountName()) : + fileDao.getFileByDecryptedRemotePath(path, user.getAccountName()); - if (ocFile == null && OCFile.ROOT_PATH.equals(path)) { + if (fileEntity != null) { + return createFileInstance(fileEntity); + } + + if (OCFile.ROOT_PATH.equals(path)) { return createRootDir(); // root should always exist } - return ocFile; + return null; } public @Nullable @@ -153,36 +155,26 @@ public class FileDataStorageManager { public @Nullable OCFile getFileByLocalPath(String path) { - Cursor cursor = getFileCursorForValue(ProviderTableMeta.FILE_STORAGE_PATH, path); - OCFile ocFile = null; - - if (cursor.moveToFirst()) { - ocFile = createFileInstance(cursor); + FileEntity fileEntity = fileDao.getFileByLocalPath(path, user.getAccountName()); + if (fileEntity != null) { + return createFileInstance(fileEntity); } - cursor.close(); - - return ocFile; + return null; } public @Nullable OCFile getFileByRemoteId(String remoteId) { - Cursor cursor = getFileCursorForValue(ProviderTableMeta.FILE_REMOTE_ID, remoteId); - OCFile ocFile = null; - - if (cursor.moveToFirst()) { - ocFile = createFileInstance(cursor); + FileEntity fileEntity = fileDao.getFileByRemoteId(remoteId, user.getAccountName()); + if (fileEntity != null) { + return createFileInstance(fileEntity); } - cursor.close(); - - return ocFile; + return null; } - public boolean fileExists(long id) { - return fileExists(ProviderTableMeta._ID, String.valueOf(id)); - } + public boolean fileExists(long id) { return fileDao.getFileById(id) != null; } public boolean fileExists(String path) { - return fileExists(ProviderTableMeta.FILE_PATH, path); + return fileDao.getFileByEncryptedRemotePath(path, user.getAccountName()) != null; } @@ -888,47 +880,6 @@ public class FileDataStorageManager { return ocFile; } - // TODO write test - private boolean fileExists(String key, String value) { - Cursor cursor = getFileCursorForValue(key, value); - boolean isExists = false; - - if (cursor == null) { - Log_OC.e(TAG, "Couldn't determine file existance, assuming non existance"); - } else { - isExists = cursor.moveToFirst(); - cursor.close(); - } - - return isExists; - } - - private Cursor getFileCursorForValue(String key, String value) { - Cursor cursor; - if (getContentResolver() != null) { - cursor = getContentResolver() - .query(ProviderTableMeta.CONTENT_URI, - null, - key + AND - + ProviderTableMeta.FILE_ACCOUNT_OWNER - + "=?", - new String[]{value, user.getAccountName()}, null); - } else { - try { - cursor = getContentProviderClient().query( - ProviderTableMeta.CONTENT_URI, - null, - key + AND + ProviderTableMeta.FILE_ACCOUNT_OWNER - + "=?", new String[]{value, user.getAccountName()}, - null); - } catch (RemoteException e) { - Log_OC.e(TAG, "Could not get file details: " + e.getMessage(), e); - cursor = null; - } - } - return cursor; - } - @Nullable private OCFile createFileInstanceFromVirtual(Cursor cursor) { long fileId = cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.VIRTUAL_OCFILE_ID)); From e76201d59f3c34abc0b883858575222422a3dff1 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 4 Dec 2022 16:41:24 +0100 Subject: [PATCH 10/28] Use Room/DAO for getGalleryItems and getAllFiles Signed-off-by: Dariusz Olszewski --- .../nextcloud/client/database/dao/FileDao.kt | 16 +++- .../datamodel/FileDataStorageManager.java | 87 +++---------------- 2 files changed, 22 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 0dbda22397..871d73fe18 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -33,21 +33,29 @@ interface FileDao { fun getFileById(id: Long): FileEntity? // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? - @Query("SELECT * FROM filelist WHERE path = :path and file_owner = :fileOwner LIMIT 1") + @Query("SELECT * FROM filelist WHERE path = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByEncryptedRemotePath(path: String, fileOwner: String): FileEntity? // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? - @Query("SELECT * FROM filelist WHERE path_decrypted = :path and file_owner = :fileOwner LIMIT 1") + @Query("SELECT * FROM filelist WHERE path_decrypted = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByDecryptedRemotePath(path: String, fileOwner: String): FileEntity? // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? - @Query("SELECT * FROM filelist WHERE media_path = :path and file_owner = :fileOwner LIMIT 1") + @Query("SELECT * FROM filelist WHERE media_path = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByLocalPath(path: String, fileOwner: String): FileEntity? // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? - @Query("SELECT * FROM filelist WHERE remote_id = :remoteId and file_owner = :fileOwner LIMIT 1") + @Query("SELECT * FROM filelist WHERE remote_id = :remoteId AND file_owner = :fileOwner LIMIT 1") fun getFileByRemoteId(remoteId: String, fileOwner: String): FileEntity? @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getFolderContent(parentId: Long): List + + @Query("SELECT * FROM filelist WHERE modified >= :startDate AND modified < :endDate AND " + + "(content_type LIKE 'image/%' OR content_type LIKE 'video/%') AND file_owner = :fileOwner " + + "ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) + fun getGalleryItems(startDate: Long, endDate: Long, fileOwner: String): List + + @Query("SELECT * FROM filelist WHERE file_owner = :fileOwner ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) + fun getAllFiles(fileOwner: String): List } diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 1322c53670..105c84a5b7 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -2205,64 +2205,17 @@ public class FileDataStorageManager { } public List getGalleryItems(long startDate, long endDate) { + Log_OC.d(TAG, "getGalleryItems - start: " + startDate + ", " + endDate); List files = new ArrayList<>(); - Uri requestURI = ProviderTableMeta.CONTENT_URI; - Cursor cursor; + List fileEntities = fileDao.getGalleryItems(startDate, endDate, user.getAccountName()); + Log_OC.d(TAG, "getGalleryItems - query complete, list size: " + fileEntities.size()); - if (getContentProviderClient() != null) { - try { - cursor = getContentProviderClient().query( - requestURI, - null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + - ProviderTableMeta.FILE_MODIFIED + ">=? AND " + - ProviderTableMeta.FILE_MODIFIED + "=? AND " + - ProviderTableMeta.FILE_MODIFIED + " getAllFiles() { - String selection = ProviderTableMeta.FILE_ACCOUNT_OWNER + "= ? "; - String[] selectionArgs = new String[]{user.getAccountName()}; - + // TODO - Apparently this method is used only by tests List folderContent = new ArrayList<>(); + List fileEntities = fileDao.getAllFiles(user.getAccountName()); - Uri requestURI = ProviderTableMeta.CONTENT_URI_DIR; - Cursor cursor; - - if (getContentProviderClient() != null) { - try { - cursor = getContentProviderClient().query(requestURI, null, selection, selectionArgs, null); - } catch (RemoteException e) { - Log_OC.e(TAG, e.getMessage(), e); - return folderContent; - } - } else { - cursor = getContentResolver().query(requestURI, null, selection, selectionArgs, null); - } - - if (cursor != null) { - if (cursor.moveToFirst()) { - do { - folderContent.add(createFileInstance(cursor)); - } while (cursor.moveToNext()); - } - cursor.close(); + for (FileEntity fileEntity: fileEntities) { + folderContent.add(createFileInstance(fileEntity)); } return folderContent; From 8ec6e3a0af0a4bb826464740940995b794f6ae68 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 4 Dec 2022 19:48:25 +0100 Subject: [PATCH 11/28] Use Room/DAO for getFolderWithDescendants (used by moveLocalFile) and finally remove createFileInstance(cursor) - no longer needed Signed-off-by: Dariusz Olszewski --- .../nextcloud/client/database/dao/FileDao.kt | 3 + .../datamodel/FileDataStorageManager.java | 178 ++++-------------- 2 files changed, 38 insertions(+), 143 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 871d73fe18..28c903c2ad 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -58,4 +58,7 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE file_owner = :fileOwner ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getAllFiles(fileOwner: String): List + + @Query("SELECT * FROM filelist WHERE path LIKE :pathPattern AND file_owner = :fileOwner ORDER BY path ASC") + fun getFolderWithDescendants(pathPattern: String, fileOwner: String): List } diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index 105c84a5b7..bf44a9d99d 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -657,81 +657,57 @@ public class FileDataStorageManager { } /// 1. get all the descendants of the moved element in a single QUERY - Cursor cursor = null; - if (getContentProviderClient() != null) { - try { - cursor = getContentProviderClient().query( - ProviderTableMeta.CONTENT_URI, - null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + " LIKE ? ", - new String[]{user.getAccountName(), ocFile.getRemotePath() + "%"}, - ProviderTableMeta.FILE_PATH + " ASC " - ); - } catch (RemoteException e) { - Log_OC.e(TAG, e.getMessage(), e); - } - - } else { - cursor = getContentResolver().query( - ProviderTableMeta.CONTENT_URI, - null, - ProviderTableMeta.FILE_ACCOUNT_OWNER + AND + ProviderTableMeta.FILE_PATH + " LIKE ? ", - new String[]{user.getAccountName(), ocFile.getRemotePath() + "%"}, - ProviderTableMeta.FILE_PATH + " ASC " - ); - } + List fileEntities = + fileDao.getFolderWithDescendants(ocFile.getRemotePath() + "%", user.getAccountName()); /// 2. prepare a batch of update operations to change all the descendants - ArrayList operations = new ArrayList<>(cursor.getCount()); + ArrayList operations = new ArrayList<>(fileEntities.size()); String defaultSavePath = FileStorageUtils.getSavePath(user.getAccountName()); List originalPathsToTriggerMediaScan = new ArrayList<>(); List newPathsToTriggerMediaScan = new ArrayList<>(); - if (cursor.moveToFirst()) { - int lengthOfOldPath = ocFile.getRemotePath().length(); - int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath; - do { - ContentValues contentValues = new ContentValues(); // keep construction in the loop - OCFile childFile = createFileInstance(cursor); + int lengthOfOldPath = ocFile.getRemotePath().length(); + int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath; + for (FileEntity fileEntity: fileEntities) { + ContentValues contentValues = new ContentValues(); // keep construction in the loop + OCFile childFile = createFileInstance(fileEntity); + contentValues.put( + ProviderTableMeta.FILE_PATH, + targetPath + childFile.getRemotePath().substring(lengthOfOldPath) + ); + + if (!childFile.isEncrypted()) { contentValues.put( - ProviderTableMeta.FILE_PATH, + ProviderTableMeta.FILE_PATH_DECRYPTED, targetPath + childFile.getRemotePath().substring(lengthOfOldPath) ); + } - if (!childFile.isEncrypted()) { - contentValues.put( - ProviderTableMeta.FILE_PATH_DECRYPTED, - targetPath + childFile.getRemotePath().substring(lengthOfOldPath) - ); + if (childFile.getStoragePath() != null && childFile.getStoragePath().startsWith(defaultSavePath)) { + // update link to downloaded content - but local move is not done here! + String targetLocalPath = defaultSavePath + targetPath + + childFile.getStoragePath().substring(lengthOfOldStoragePath); + + contentValues.put(ProviderTableMeta.FILE_STORAGE_PATH, targetLocalPath); + + if (MimeTypeUtil.isMedia(childFile.getMimeType())) { + originalPathsToTriggerMediaScan.add(childFile.getStoragePath()); + newPathsToTriggerMediaScan.add(targetLocalPath); } - if (childFile.getStoragePath() != null && childFile.getStoragePath().startsWith(defaultSavePath)) { - // update link to downloaded content - but local move is not done here! - String targetLocalPath = defaultSavePath + targetPath + - childFile.getStoragePath().substring(lengthOfOldStoragePath); + } - contentValues.put(ProviderTableMeta.FILE_STORAGE_PATH, targetLocalPath); + if (childFile.getRemotePath().equals(ocFile.getRemotePath())) { + contentValues.put(ProviderTableMeta.FILE_PARENT, targetParent.getFileId()); + } - if (MimeTypeUtil.isMedia(childFile.getMimeType())) { - originalPathsToTriggerMediaScan.add(childFile.getStoragePath()); - newPathsToTriggerMediaScan.add(targetLocalPath); - } + operations.add( + ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI) + .withValues(contentValues) + .withSelection(ProviderTableMeta._ID + " = ?", new String[]{String.valueOf(childFile.getFileId())}) + .build()); - } - - if (childFile.getRemotePath().equals(ocFile.getRemotePath())) { - contentValues.put(ProviderTableMeta.FILE_PARENT, targetParent.getFileId()); - } - - operations.add( - ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI) - .withValues(contentValues) - .withSelection(ProviderTableMeta._ID + " = ?", new String[]{String.valueOf(childFile.getFileId())}) - .build()); - - } while (cursor.moveToNext()); } - cursor.close(); /// 3. apply updates in batch try { @@ -887,90 +863,6 @@ public class FileDataStorageManager { return getFileById(fileId); } - private OCFile createFileInstance(Cursor cursor) { - OCFile ocFile = null; - if (cursor != null) { - ocFile = new OCFile(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_PATH))); - ocFile.setDecryptedRemotePath(getString(cursor, ProviderTableMeta.FILE_PATH_DECRYPTED)); - ocFile.setFileId(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta._ID))); - ocFile.setParentId(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_PARENT))); - ocFile.setMimeType(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_CONTENT_TYPE))); - ocFile.setStoragePath(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_STORAGE_PATH))); - if (ocFile.getStoragePath() == null) { - // try to find existing file and bind it with current account; - // with the current update of SynchronizeFolderOperation, this won't be - // necessary anymore after a full synchronization of the account - File file = new File(FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), ocFile)); - if (file.exists()) { - ocFile.setStoragePath(file.getAbsolutePath()); - ocFile.setLastSyncDateForData(file.lastModified()); - } - } - ocFile.setFileLength(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_CONTENT_LENGTH))); - ocFile.setCreationTimestamp(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_CREATION))); - ocFile.setModificationTimestamp(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_MODIFIED))); - ocFile.setModificationTimestampAtLastSyncForData(cursor.getLong( - cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA))); - ocFile.setLastSyncDateForProperties(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LAST_SYNC_DATE))); - ocFile.setLastSyncDateForData(cursor.getLong(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA))); - ocFile.setEtag(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_ETAG))); - ocFile.setEtagOnServer(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_ETAG_ON_SERVER))); - ocFile.setSharedViaLink(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_SHARED_VIA_LINK)) == 1); - ocFile.setSharedWithSharee(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_SHARED_WITH_SHAREE)) == 1); - ocFile.setPermissions(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_PERMISSIONS))); - ocFile.setRemoteId(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_REMOTE_ID))); - ocFile.setUpdateThumbnailNeeded(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1); - ocFile.setDownloading(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1); - ocFile.setEtagInConflict(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_ETAG_IN_CONFLICT))); - ocFile.setFavorite(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_FAVORITE)) == 1); - ocFile.setEncrypted(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_IS_ENCRYPTED)) == 1); -// if (ocFile.isEncrypted()) { -// ocFile.setFileName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_NAME))); -// } - ocFile.setMountType(WebdavEntry.MountType.values()[cursor.getInt( - cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_MOUNT_TYPE))]); - ocFile.setPreviewAvailable(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_HAS_PREVIEW)) == 1); - ocFile.setUnreadCommentsCount(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_UNREAD_COMMENTS_COUNT))); - ocFile.setOwnerId(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_OWNER_ID))); - ocFile.setOwnerDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_OWNER_DISPLAY_NAME))); - ocFile.setNote(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_NOTE))); - ocFile.setRichWorkspace(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_RICH_WORKSPACE))); - ocFile.setLocked(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCKED)) == 1); - final int lockTypeInt = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TYPE)); - ocFile.setLockType(lockTypeInt != -1 ? FileLockType.fromValue(lockTypeInt) : null); - ocFile.setLockOwnerId(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER))); - ocFile.setLockOwnerDisplayName(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER_DISPLAY_NAME))); - ocFile.setLockOwnerEditor(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_OWNER_EDITOR))); - ocFile.setLockTimestamp(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TIMESTAMP))); - ocFile.setLockTimeout(cursor.getInt(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TIMEOUT))); - ocFile.setLockToken(cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_LOCK_TOKEN))); - - - String sharees = cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_SHAREES)); - - if (sharees == null || NULL_STRING.equals(sharees) || sharees.isEmpty()) { - ocFile.setSharees(new ArrayList<>()); - } else { - try { - ShareeUser[] shareesArray = new Gson().fromJson(sharees, ShareeUser[].class); - - ocFile.setSharees(new ArrayList<>(Arrays.asList(shareesArray))); - } catch (JsonSyntaxException e) { - // ignore saved value due to api change - ocFile.setSharees(new ArrayList<>()); - } - } - String metadataSize = cursor.getString(cursor.getColumnIndexOrThrow(ProviderTableMeta.FILE_METADATA_SIZE)); - ImageDimension imageDimension = new Gson().fromJson(metadataSize, ImageDimension.class); - - if (imageDimension != null) { - ocFile.setImageDimension(imageDimension); - } - } - - return ocFile; - } - private int nullToZero(Integer i) { return (i == null) ? 0 : i; } From 9cbaa007247a9b02365ddafb7f3cdf11c4ad21dc Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 4 Dec 2022 20:34:26 +0100 Subject: [PATCH 12/28] SpotBugs Signed-off-by: Dariusz Olszewski --- .../android/datamodel/FileDataStorageManager.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index bf44a9d99d..fdbbdc974c 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -656,9 +656,11 @@ public class FileDataStorageManager { throw new IllegalStateException("Parent folder of the target path does not exist!!"); } + String oldPath = ocFile.getRemotePath(); + /// 1. get all the descendants of the moved element in a single QUERY List fileEntities = - fileDao.getFolderWithDescendants(ocFile.getRemotePath() + "%", user.getAccountName()); + fileDao.getFolderWithDescendants(oldPath + "%", user.getAccountName()); /// 2. prepare a batch of update operations to change all the descendants ArrayList operations = new ArrayList<>(fileEntities.size()); @@ -666,7 +668,7 @@ public class FileDataStorageManager { List originalPathsToTriggerMediaScan = new ArrayList<>(); List newPathsToTriggerMediaScan = new ArrayList<>(); - int lengthOfOldPath = ocFile.getRemotePath().length(); + int lengthOfOldPath = oldPath.length(); int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath; for (FileEntity fileEntity: fileEntities) { ContentValues contentValues = new ContentValues(); // keep construction in the loop @@ -2098,11 +2100,11 @@ public class FileDataStorageManager { public List getGalleryItems(long startDate, long endDate) { Log_OC.d(TAG, "getGalleryItems - start: " + startDate + ", " + endDate); - List files = new ArrayList<>(); List fileEntities = fileDao.getGalleryItems(startDate, endDate, user.getAccountName()); Log_OC.d(TAG, "getGalleryItems - query complete, list size: " + fileEntities.size()); + List files = new ArrayList<>(fileEntities.size()); for (FileEntity fileEntity: fileEntities) { files.add(createFileInstance(fileEntity)); } @@ -2196,8 +2198,8 @@ public class FileDataStorageManager { public List getAllFiles() { // TODO - Apparently this method is used only by tests - List folderContent = new ArrayList<>(); List fileEntities = fileDao.getAllFiles(user.getAccountName()); + List folderContent = new ArrayList<>(fileEntities.size()); for (FileEntity fileEntity: fileEntities) { folderContent.add(createFileInstance(fileEntity)); From 4df8946b5e0d536a1d37273cb230933eb248f3ad Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 4 Dec 2022 21:01:25 +0100 Subject: [PATCH 13/28] spotlessKotlinCheck Signed-off-by: Dariusz Olszewski --- .../java/com/nextcloud/client/database/dao/FileDao.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 28c903c2ad..2d648170c8 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -51,9 +51,11 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) fun getFolderContent(parentId: Long): List - @Query("SELECT * FROM filelist WHERE modified >= :startDate AND modified < :endDate AND " + - "(content_type LIKE 'image/%' OR content_type LIKE 'video/%') AND file_owner = :fileOwner " + - "ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) + @Query( + "SELECT * FROM filelist WHERE modified >= :startDate AND modified < :endDate AND " + + "(content_type LIKE 'image/%' OR content_type LIKE 'video/%') AND file_owner = :fileOwner " + + "ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER + ) fun getGalleryItems(startDate: Long, endDate: Long, fileOwner: String): List @Query("SELECT * FROM filelist WHERE file_owner = :fileOwner ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) From 0fb3c924957454c454be62b4fd2010410b090cd8 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Sun, 4 Dec 2022 21:06:12 +0100 Subject: [PATCH 14/28] Fix compilation of tests (revert marking getFileByEncryptedRemotePath as @Nullable) Signed-off-by: Dariusz Olszewski --- .../com/owncloud/android/datamodel/FileDataStorageManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index fdbbdc974c..d5aaabc62f 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -117,8 +117,7 @@ public class FileDataStorageManager { return getFileByEncryptedRemotePath(path); } - public @Nullable - OCFile getFileByEncryptedRemotePath(String path) { + public OCFile getFileByEncryptedRemotePath(String path) { return getFileByPath(ProviderTableMeta.FILE_PATH, path); } From 1a669e4eb697ab5b702c122be9c564be59928c29 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski <8277636+starypatyk@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:19:16 +0100 Subject: [PATCH 15/28] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Álvaro Brey Signed-off-by: Dariusz Olszewski <8277636+starypatyk@users.noreply.github.com> --- .../com/nextcloud/client/database/dao/FileDao.kt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 2d648170c8..105d8fb2d4 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -48,17 +48,19 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE remote_id = :remoteId AND file_owner = :fileOwner LIMIT 1") fun getFileByRemoteId(remoteId: String, fileOwner: String): FileEntity? - @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) + @Query("SELECT * FROM filelist WHERE parent = :parentId ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER}") fun getFolderContent(parentId: Long): List @Query( - "SELECT * FROM filelist WHERE modified >= :startDate AND modified < :endDate AND " + - "(content_type LIKE 'image/%' OR content_type LIKE 'video/%') AND file_owner = :fileOwner " + - "ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER + "SELECT * FROM filelist WHERE modified >= :startDate" + + " AND modified < :endDate" + + " AND (content_type LIKE 'image/%' OR content_type LIKE 'video/%')" + + " AND file_owner = :fileOwner" + + " ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER}" ) fun getGalleryItems(startDate: Long, endDate: Long, fileOwner: String): List - @Query("SELECT * FROM filelist WHERE file_owner = :fileOwner ORDER BY " + ProviderTableMeta.FILE_DEFAULT_SORT_ORDER) + @Query("SELECT * FROM filelist WHERE file_owner = :fileOwner ORDER BY ${ProviderTableMeta.FILE_DEFAULT_SORT_ORDER}") fun getAllFiles(fileOwner: String): List @Query("SELECT * FROM filelist WHERE path LIKE :pathPattern AND file_owner = :fileOwner ORDER BY path ASC") From 07f61fcfa29e46cecdabfdbd04cfdc9ed70fefa9 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski <8277636+starypatyk@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:23:09 +0100 Subject: [PATCH 16/28] Apply suggestion from code review - FileDataStorageManager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Álvaro Brey Signed-off-by: Dariusz Olszewski <8277636+starypatyk@users.noreply.github.com> --- .../com/owncloud/android/datamodel/FileDataStorageManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java index d5aaabc62f..4321696775 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -128,7 +128,8 @@ public class FileDataStorageManager { private @Nullable OCFile getFileByPath(String type, String path) { - FileEntity fileEntity = ProviderTableMeta.FILE_PATH.equals(type) ? + final boolean shouldUseEncryptedPath = ProviderTableMeta.FILE_PATH.equals(type); + FileEntity fileEntity = shouldUseEncryptedPath ? fileDao.getFileByEncryptedRemotePath(path, user.getAccountName()) : fileDao.getFileByDecryptedRemotePath(path, user.getAccountName()); From 69344bd8fb15ea5a6d631fd2d5ce4966d04efa75 Mon Sep 17 00:00:00 2001 From: Dariusz Olszewski Date: Tue, 13 Dec 2022 23:25:37 +0100 Subject: [PATCH 17/28] Remove TODOs as discussed Signed-off-by: Dariusz Olszewski --- .../main/java/com/nextcloud/client/database/dao/FileDao.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt index 105d8fb2d4..21a7e34d70 100644 --- a/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt +++ b/app/src/main/java/com/nextcloud/client/database/dao/FileDao.kt @@ -32,19 +32,15 @@ interface FileDao { @Query("SELECT * FROM filelist WHERE _id = :id LIMIT 1") fun getFileById(id: Long): FileEntity? - // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? @Query("SELECT * FROM filelist WHERE path = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByEncryptedRemotePath(path: String, fileOwner: String): FileEntity? - // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? @Query("SELECT * FROM filelist WHERE path_decrypted = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByDecryptedRemotePath(path: String, fileOwner: String): FileEntity? - // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? @Query("SELECT * FROM filelist WHERE media_path = :path AND file_owner = :fileOwner LIMIT 1") fun getFileByLocalPath(path: String, fileOwner: String): FileEntity? - // TODO - there should be only one entry - does it make sense to add order by to preserve previous behaviour? @Query("SELECT * FROM filelist WHERE remote_id = :remoteId AND file_owner = :fileOwner LIMIT 1") fun getFileByRemoteId(remoteId: String, fileOwner: String): FileEntity? From 3cfd729b3c5bf7fbd81d978a4590bb064c208f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 25 Nov 2022 17:29:13 +0100 Subject: [PATCH 18/28] FolderPickerActivity: disable copy/move to the same folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a no-op anyways, right now, and causes bad UX Signed-off-by: Álvaro Brey --- .../ui/activity/FolderPickerActivity.kt | 48 +++++++++++++++---- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt index 56f2e9458e..5972a78c8d 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt @@ -74,6 +74,9 @@ open class FolderPickerActivity : private var mChooseBtn: MaterialButton? = null private var caption: String? = null + private var mAction: String? = null + private var mTargetFilePaths: ArrayList? = null + @Inject lateinit var localBroadcastManager: LocalBroadcastManager @@ -95,8 +98,9 @@ open class FolderPickerActivity : View.VISIBLE findViewById(R.id.switch_grid_view_button).visibility = View.GONE - if (intent.getStringExtra(EXTRA_ACTION) != null) { - when (intent.getStringExtra(EXTRA_ACTION)) { + mAction = intent.getStringExtra(EXTRA_ACTION) + if (mAction != null) { + when (mAction) { MOVE -> { caption = resources.getText(R.string.move_to).toString() mSearchOnlyFolders = true @@ -118,6 +122,7 @@ open class FolderPickerActivity : } else { caption = themeUtils.getDefaultDisplayNameForRootFolder(this) } + mTargetFilePaths = intent.getStringArrayListExtra(EXTRA_FILE_PATHS) if (intent.getParcelableExtra(EXTRA_CURRENT_FOLDER) != null) { file = intent.getParcelableExtra(EXTRA_CURRENT_FOLDER) } @@ -146,7 +151,7 @@ open class FolderPickerActivity : val listOfFolders = listOfFilesFragment listOfFolders!!.listDirectory(folder, false, false) startSyncFolderOperation(folder, false) - updateNavigationElementsInActionBar() + updateUiElements() } } @@ -205,7 +210,7 @@ open class FolderPickerActivity : */ override fun onBrowsedDownTo(directory: OCFile) { file = directory - updateNavigationElementsInActionBar() + updateUiElements() // Sync Folder startSyncFolderOperation(directory, false) } @@ -241,6 +246,8 @@ open class FolderPickerActivity : // refresh list of files refreshListOfFilesFragment(false) + updateUiElements() + // Listen for sync messages val syncIntentFilter = IntentFilter(FileSyncAdapter.EVENT_FULL_SYNC_START) syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_END) @@ -317,7 +324,7 @@ open class FolderPickerActivity : val root = storageManager.getFileByPath(OCFile.ROOT_PATH) listOfFiles.listDirectory(root, false, false) file = listOfFiles.currentFile - updateNavigationElementsInActionBar() + updateUiElements() startSyncFolderOperation(root, false) } } @@ -331,10 +338,34 @@ open class FolderPickerActivity : return } file = listOfFiles.currentFile - updateNavigationElementsInActionBar() + updateUiElements() } } + private fun updateUiElements() { + toggleChooseEnabled() + updateNavigationElementsInActionBar() + } + + private fun toggleChooseEnabled() { + mChooseBtn?.isEnabled = checkFolderSelectable() + } + + // for copy and move, disable selecting parent folder of target files + private fun checkFolderSelectable(): Boolean { + return when { + mAction != COPY && mAction != MOVE -> true + mTargetFilePaths.isNullOrEmpty() -> true + file?.isFolder != true -> true + // only disable if ALL target files are in selected folder + else -> mTargetFilePaths!!.any { !isParentFolder(file.remotePath, it) } + } + } + + private fun isParentFolder(folderPath: String, filePath: String): Boolean { + return folderPath == File(filePath).parent + } + private fun updateNavigationElementsInActionBar() { val currentDir = currentFolder val actionBar = supportActionBar @@ -378,9 +409,8 @@ open class FolderPickerActivity : if (targetFiles != null) { resultData.putParcelableArrayListExtra(EXTRA_FILES, targetFiles) } - val targetFilePaths = i.getStringArrayListExtra(EXTRA_FILE_PATHS) - if (targetFilePaths != null) { - resultData.putStringArrayListExtra(EXTRA_FILE_PATHS, targetFilePaths) + mTargetFilePaths.let { + resultData.putStringArrayListExtra(EXTRA_FILE_PATHS, it) } setResult(RESULT_OK, resultData) finish() From a824d9a7b504303d1eb2b9ba8a238bd2b7324575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 30 Nov 2022 13:06:15 +0100 Subject: [PATCH 19/28] FolderPickerActivity: properly compare subfolders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Need to use File as well, otherwise trailing slashes are different Signed-off-by: Álvaro Brey --- .../com/owncloud/android/ui/activity/FolderPickerActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt index 5972a78c8d..7ef9a2c323 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt @@ -363,7 +363,7 @@ open class FolderPickerActivity : } private fun isParentFolder(folderPath: String, filePath: String): Boolean { - return folderPath == File(filePath).parent + return File(folderPath).path == File(filePath).parent } private fun updateNavigationElementsInActionBar() { From 04ffe37d251b565be2f6c30d18e4103262fd8ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Wed, 30 Nov 2022 13:14:17 +0100 Subject: [PATCH 20/28] FolderPickerActivity: remove EXTRA_CURRENT_FOLDER argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was unused (as it never reached the OCFileListFragment, which always starts at /) but was mistakenly pre-populating the `file` variable with a wrong folder Signed-off-by: Álvaro Brey --- .../owncloud/android/ui/activity/FolderPickerActivity.kt | 8 ++------ .../owncloud/android/ui/fragment/OCFileListFragment.java | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt index 7ef9a2c323..830dec76ca 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt @@ -123,9 +123,7 @@ open class FolderPickerActivity : caption = themeUtils.getDefaultDisplayNameForRootFolder(this) } mTargetFilePaths = intent.getStringArrayListExtra(EXTRA_FILE_PATHS) - if (intent.getParcelableExtra(EXTRA_CURRENT_FOLDER) != null) { - file = intent.getParcelableExtra(EXTRA_CURRENT_FOLDER) - } + if (savedInstanceState == null) { createFragments() } @@ -246,6 +244,7 @@ open class FolderPickerActivity : // refresh list of files refreshListOfFilesFragment(false) + file = listOfFilesFragment?.currentFile updateUiElements() // Listen for sync messages @@ -590,9 +589,6 @@ open class FolderPickerActivity : @JvmField val EXTRA_ACTION = FolderPickerActivity::class.java.canonicalName?.plus(".EXTRA_ACTION") - @JvmField - val EXTRA_CURRENT_FOLDER = FolderPickerActivity::class.java.canonicalName?.plus(".EXTRA_CURRENT_FOLDER") - const val MOVE = "MOVE" const val COPY = "COPY" const val CHOOSE_LOCATION = "CHOOSE_LOCATION" diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 438027b82d..42d3a4d450 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -1227,7 +1227,6 @@ public class OCFileListFragment extends ExtendedListFragment implements paths.add(file.getRemotePath()); } action.putStringArrayListExtra(FolderPickerActivity.EXTRA_FILE_PATHS, paths); - action.putExtra(FolderPickerActivity.EXTRA_CURRENT_FOLDER, mFile); action.putExtra(FolderPickerActivity.EXTRA_ACTION, extraAction); getActivity().startActivityForResult(action, requestCode); } From 6d4a65b45ccf67801dba90d7da1c8856c5968c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Thu, 15 Dec 2022 17:22:11 +0100 Subject: [PATCH 21/28] FolderPickerActivity: also disable action when trying to move or copy a folder to a descendant of itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- .../ui/activity/FolderPickerActivity.kt | 12 +- .../com/owncloud/android/utils/PathUtils.kt | 49 ++++++++ .../owncloud/android/utils/PathUtilsTest.kt | 114 ++++++++++++++++++ 3 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/owncloud/android/utils/PathUtils.kt create mode 100644 app/src/test/java/com/owncloud/android/utils/PathUtilsTest.kt diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt index 830dec76ca..b9b7f11ef3 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt @@ -53,6 +53,7 @@ import com.owncloud.android.utils.DataHolderUtil import com.owncloud.android.utils.DisplayUtils import com.owncloud.android.utils.ErrorMessageAdapter import com.owncloud.android.utils.FileSortOrder +import com.owncloud.android.utils.PathUtils import java.io.File import javax.inject.Inject @@ -356,15 +357,14 @@ open class FolderPickerActivity : mAction != COPY && mAction != MOVE -> true mTargetFilePaths.isNullOrEmpty() -> true file?.isFolder != true -> true - // only disable if ALL target files are in selected folder - else -> mTargetFilePaths!!.any { !isParentFolder(file.remotePath, it) } + // all of the target files are already in the selected directory + mTargetFilePaths!!.all { PathUtils.isDirectParent(file.remotePath, it) } -> false + // some of the target files are parents of the selected folder + mTargetFilePaths!!.any { PathUtils.isAncestor(it, file.remotePath) } -> false + else -> true } } - private fun isParentFolder(folderPath: String, filePath: String): Boolean { - return File(folderPath).path == File(filePath).parent - } - private fun updateNavigationElementsInActionBar() { val currentDir = currentFolder val actionBar = supportActionBar diff --git a/app/src/main/java/com/owncloud/android/utils/PathUtils.kt b/app/src/main/java/com/owncloud/android/utils/PathUtils.kt new file mode 100644 index 0000000000..342d893abb --- /dev/null +++ b/app/src/main/java/com/owncloud/android/utils/PathUtils.kt @@ -0,0 +1,49 @@ +/* + * Nextcloud Android client application + * + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see . + * + */ + +package com.owncloud.android.utils + +import com.owncloud.android.datamodel.OCFile +import java.io.File + +object PathUtils { + /** + * Returns `true` if [folderPath] is a direct parent of [filePath], `false` otherwise + */ + fun isDirectParent(folderPath: String, filePath: String): Boolean { + return File(folderPath).path == File(filePath).parent + } + + /** + * Returns `true` if [folderPath] is an ancestor of [filePath], `false` otherwise + * + * If [isDirectParent] is `true` for the same arguments, this function should return `true` as well + */ + fun isAncestor(folderPath: String, filePath: String): Boolean { + if (folderPath.isEmpty() || filePath.isEmpty()) { + return false + } + val folderPathWithSlash = + if (folderPath.endsWith(OCFile.PATH_SEPARATOR)) folderPath else folderPath + OCFile.PATH_SEPARATOR + return filePath.startsWith(folderPathWithSlash) + } +} diff --git a/app/src/test/java/com/owncloud/android/utils/PathUtilsTest.kt b/app/src/test/java/com/owncloud/android/utils/PathUtilsTest.kt new file mode 100644 index 0000000000..f83eaadc42 --- /dev/null +++ b/app/src/test/java/com/owncloud/android/utils/PathUtilsTest.kt @@ -0,0 +1,114 @@ +/* + * Nextcloud Android client application + * + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see . + * + */ + +package com.owncloud.android.utils + +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Suite + +private val directParents: Array> = arrayOf( + arrayOf("/bar", "/bar/foo.tgz", true), + arrayOf("/bar/", "/bar/foo.tgz", true), + arrayOf("/bar/", "/bar/foo/", true), + arrayOf("/bar/", "/bar/foo", true), + arrayOf("/", "/bar/", true), + arrayOf("/bar/", "/foo/bar", false) +) + +private val nonAncestors: Array> = arrayOf( + arrayOf("/bar/", "/", false), + arrayOf("/bar/", "", false), + arrayOf("/", "", false), + arrayOf("", "", false), + arrayOf("", "/", false) +) + +/** + * These should return `false` for [PathUtils.isDirectParent] but `true` for [PathUtils.isAncestor] + */ +private val indirectAncestors: List> = listOf( + Pair("/bar", "/bar/foo/baz.tgz"), + Pair("/bar/", "/bar/foo/baz.tgz"), + Pair("/bar/", "/bar/foo/baz/"), + Pair("/bar/", "/bar/foo/baz") +) + +@RunWith(Suite::class) +@Suite.SuiteClasses( + PathUtilsTest.IsDirectParent::class, + PathUtilsTest.IsAncestor::class +) +class PathUtilsTest { + + @RunWith(Parameterized::class) + internal class IsDirectParent( + private val folderPath: String, + private val filePath: String, + private val isParent: Boolean + ) { + + @Test + fun testIsParent() { + assertEquals("Wrong isParentPath result", isParent, PathUtils.isDirectParent(folderPath, filePath)) + } + + companion object { + @Parameterized.Parameters(name = "{0}, {1} => {2}") + @JvmStatic + fun urls(): Array> { + val otherAncestors: Array> = indirectAncestors.map { + @Suppress("UNCHECKED_CAST") + arrayOf(it.first, it.second, false) as Array + }.toTypedArray() + return directParents + nonAncestors + otherAncestors + } + } + } + + @RunWith(Parameterized::class) + internal class IsAncestor( + private val folderPath: String, + private val filePath: String, + private val isAscendant: Boolean + ) { + + @Test + fun testIsAncestor() { + assertEquals("Wrong isParentPath result", isAscendant, PathUtils.isAncestor(folderPath, filePath)) + } + + companion object { + @Parameterized.Parameters(name = "{0}, {1} => {2}") + @JvmStatic + fun urls(): Array> { + val otherAncestors: Array> = indirectAncestors.map { + @Suppress("UNCHECKED_CAST") + arrayOf(it.first, it.second, true) as Array + }.toTypedArray() + return directParents + nonAncestors + otherAncestors + } + } + } +} From bff4adbb5f340d5cec19fc1388b2a062d7cffac7 Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Fri, 16 Dec 2022 08:57:01 +0000 Subject: [PATCH 22/28] =?UTF-8?q?=F0=9F=94=84=20Synced=20local=20'.github/?= =?UTF-8?q?workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/codeql.yml | 44 ++++++++++++------------ .github/workflows/detectNewJavaFiles.yml | 39 ++++++++++----------- .github/workflows/stale.yml | 2 +- 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fb9b2f62a8..c68c81b46f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,27 +23,27 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'java' ] + language: [ 'java' ] steps: - - name: Checkout repository - uses: actions/checkout@v3 - - name: Set Swap Space - uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c #v1.0 - with: + - name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 + - name: Set Swap Space + uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 + with: swap-size-gb: 10 - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - - name: Set up JDK - uses: actions/setup-java@v3 - with: - distribution: "temurin" - java-version: 11 - - name: Assemble - run: | - mkdir -p "$HOME/.gradle" - echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" - ./gradlew assembleDebug - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Initialize CodeQL + uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2 + with: + languages: ${{ matrix.language }} + - name: Set up JDK + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 + with: + distribution: "temurin" + java-version: 11 + - name: Assemble + run: | + mkdir -p "$HOME/.gradle" + echo "org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" + ./gradlew assembleDebug + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2 diff --git a/.github/workflows/detectNewJavaFiles.yml b/.github/workflows/detectNewJavaFiles.yml index 7107619e4e..10df722b9e 100644 --- a/.github/workflows/detectNewJavaFiles.yml +++ b/.github/workflows/detectNewJavaFiles.yml @@ -10,23 +10,22 @@ jobs: detectNewJavaFiles: runs-on: ubuntu-latest steps: - - id: file_changes - uses: trilom/file-changes-action@v1.2.4 - with: - output: ',' - - name: Detect new java files - run: | - if [ -z '${{ steps.file_changes.outputs.files_added }}' ]; then - echo "No new files added" - exit 0 - fi - new_java=$(echo '${{ steps.file_changes.outputs.files_added }}' | tr ',' '\n' | grep '\.java$' | cat) - if [ -n "$new_java" ]; then - # shellcheck disable=SC2016 - printf 'New java files detected:\n```\n%s\n```\n' "$new_java" | tee "$GITHUB_STEP_SUMMARY" - exit 1 - else - echo "No new java files detected" - exit 0 - fi - + - id: file_changes + uses: trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b # v1.2.4 + with: + output: ',' + - name: Detect new java files + run: | + if [ -z '${{ steps.file_changes.outputs.files_added }}' ]; then + echo "No new files added" + exit 0 + fi + new_java=$(echo '${{ steps.file_changes.outputs.files_added }}' | tr ',' '\n' | grep '\.java$' | cat) + if [ -n "$new_java" ]; then + # shellcheck disable=SC2016 + printf 'New java files detected:\n```\n%s\n```\n' "$new_java" | tee "$GITHUB_STEP_SUMMARY" + exit 1 + else + echo "No new java files detected" + exit 0 + fi diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index e2124ec9f3..fe49e91162 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@v6 + - uses: actions/stale@5ebf00ea0e4c1561e9b43a292ed34424fb1d4578 # v6 with: days-before-stale: 28 days-before-close: 14 From 56df7ad1033c309e833f37b0124c7b4e853362b2 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Fri, 16 Dec 2022 10:18:51 +0100 Subject: [PATCH 23/28] Pin versions Signed-off-by: tobiasKaminsky --- .github/workflows/analysis.yml | 4 ++-- .github/workflows/assembleFlavors.yml | 4 ++-- .github/workflows/autoApproveDependabot.yml | 2 +- .github/workflows/check.yml | 4 ++-- .github/workflows/detectSnapshot.yml | 2 +- .github/workflows/gradle-wrapper-validation.yml | 4 ++-- .github/workflows/qa.yml | 4 ++-- .github/workflows/screenShotTest.yml | 17 ++++++++--------- .github/workflows/unit-tests.yml | 13 ++++++------- 9 files changed, 26 insertions(+), 28 deletions(-) diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index 6a3ce2ebc4..1f99e39fed 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -28,12 +28,12 @@ jobs: echo "::set-output name=pr::${{ github.event.pull_request.number }}" echo "::set-output name=repo::${{ github.event.pull_request.head.repo.full_name }}" fi - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 with: repository: ${{ steps.get-vars.outputs.repo }} ref: ${{ steps.get-vars.outputs.branch }} - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 with: distribution: "temurin" java-version: 11 diff --git a/.github/workflows/assembleFlavors.yml b/.github/workflows/assembleFlavors.yml index 8979c1442f..6bec7e9545 100644 --- a/.github/workflows/assembleFlavors.yml +++ b/.github/workflows/assembleFlavors.yml @@ -15,9 +15,9 @@ jobs: matrix: flavor: [ Generic, Gplay, Huawei ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 - name: set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 with: distribution: "temurin" java-version: 11 diff --git a/.github/workflows/autoApproveDependabot.yml b/.github/workflows/autoApproveDependabot.yml index 1946010fd3..8deb91bf16 100644 --- a/.github/workflows/autoApproveDependabot.yml +++ b/.github/workflows/autoApproveDependabot.yml @@ -10,7 +10,7 @@ jobs: auto-approve: runs-on: ubuntu-latest steps: - - uses: hmarr/auto-approve-action@v3.1.0 + - uses: hmarr/auto-approve-action@de8ae18c173c131e182d4adf2c874d8d2308a85b # v3.1.0 if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 0c38dfa7c3..63f970d6ca 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -15,9 +15,9 @@ jobs: matrix: task: [ detekt, spotlessKotlinCheck ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 with: distribution: "temurin" java-version: 11 diff --git a/.github/workflows/detectSnapshot.yml b/.github/workflows/detectSnapshot.yml index c529840486..d1c3c754ed 100644 --- a/.github/workflows/detectSnapshot.yml +++ b/.github/workflows/detectSnapshot.yml @@ -12,6 +12,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 - name: Detect SNAPSHOT run: scripts/analysis/detectSNAPSHOT.sh diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index d0d8f814e2..0e649b2e9e 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -12,5 +12,5 @@ jobs: name: "Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: gradle/wrapper-validation-action@v1 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 + - uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1 diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 59c3b803ab..7c228a5d0a 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -15,10 +15,10 @@ jobs: - name: Check if secrets are available run: echo "::set-output name=ok::${{ secrets.KS_PASS != '' }}" id: check-secrets - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 if: ${{ steps.check-secrets.outputs.ok == 'true' }} - name: set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 if: ${{ steps.check-secrets.outputs.ok == 'true' }} with: distribution: "temurin" diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index ac36160e9c..74b646102b 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -18,17 +18,17 @@ jobs: color: [ blue ] api-level: [ 27 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 - name: Gradle cache - uses: actions/cache@v3 + uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} - name: AVD cache - uses: actions/cache@v3 + uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3 id: avd-cache with: path: | @@ -36,14 +36,14 @@ jobs: ~/.android/adb* key: avd-${{ matrix.api-level }} - - uses: actions/setup-java@v3 + - uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 with: distribution: "temurin" java-version: 11 - name: create AVD and generate snapshot for caching if: steps.avd-cache.outputs.cache-hit != 'true' - uses: reactivecircus/android-emulator-runner@v2 + uses: reactivecircus/android-emulator-runner@50986b1464923454c95e261820bc626f38490ec0 # v2 with: api-level: ${{ matrix.api-level }} force-avd-creation: false @@ -64,12 +64,12 @@ jobs: - name: Delete old comments env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} if: ${{ always() }} run: scripts/deleteOldComments.sh "${{ matrix.color }}-${{ matrix.scheme }}" "Screenshot" ${{github.event.number}} - name: Run screenshot tests - uses: reactivecircus/android-emulator-runner@v2 + uses: reactivecircus/android-emulator-runner@50986b1464923454c95e261820bc626f38490ec0 # v2 with: api-level: ${{ matrix.api-level }} force-avd-creation: false @@ -82,8 +82,7 @@ jobs: if: ${{ failure() }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: - scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "${{ matrix.color }}-${{ matrix.scheme }}" "Screenshot" ${{github.event.number}} + run: scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "${{ matrix.color }}-${{ matrix.scheme }}" "Screenshot" ${{github.event.number}} - name: Archive Espresso results uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb if: ${{ always() }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a64c5f69ef..f3e3baf73e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -14,29 +14,28 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 - name: Set up JDK 11 - uses: actions/setup-java@v3 + uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3 with: distribution: "temurin" java-version: 11 - name: Delete old comments env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} if: ${{ always() }} run: scripts/deleteOldComments.sh "test" "Unit" ${{github.event.number}} - name: Run unit tests with coverage - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef # v2 with: arguments: jacocoTestGplayDebugUnitTest - name: Upload failing results if: ${{ failure() }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: - scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "test" "Unit" ${{github.event.number}} + run: scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "test" "Unit" ${{github.event.number}} - name: Upload coverage to codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unit From 3e0d9d5cb955fd9d408d301f5587a8f4d15174df Mon Sep 17 00:00:00 2001 From: nextcloud-android-bot Date: Fri, 16 Dec 2022 09:37:14 +0000 Subject: [PATCH 24/28] =?UTF-8?q?=F0=9F=94=84=20Synced=20local=20'.github/?= =?UTF-8?q?workflows/'=20with=20remote=20'config/workflows/'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nextcloud-android-bot --- .github/workflows/detectNewJavaFiles.yml | 1 + .github/workflows/stale.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/detectNewJavaFiles.yml b/.github/workflows/detectNewJavaFiles.yml index 10df722b9e..b64964cef7 100644 --- a/.github/workflows/detectNewJavaFiles.yml +++ b/.github/workflows/detectNewJavaFiles.yml @@ -1,3 +1,4 @@ +# synced from @nextcloud/android-config name: "Detect new java files" on: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index fe49e91162..09cb471f10 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,4 +1,4 @@ ---- +# synced from @nextcloud/android-config name: 'Close stale issues' on: schedule: From 283c02426e0c8b60cb3591de70dbd1dee72f75ad Mon Sep 17 00:00:00 2001 From: ge78fug Date: Thu, 15 Dec 2022 11:36:27 +0100 Subject: [PATCH 25/28] Changed the community_testing_version_text Signed-off-by: ge78fug --- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 7ec930609d..ff160d6cbd 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -145,7 +145,7 @@ Fehler gefunden? Komisches Verhalten? Helfen Sie durch Testen Fehlerbericht auf GitHub erstellen - Möchten Sie uns beim Testen der nächsten Version unterstützen? + Helfen Sie uns beim Testen der nächsten Version! Konfigurieren Lokale Verschlüsselung entfernen Wollen Sie %1$s wirklich löschen? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 840f042967..b5f63830bb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -523,7 +523,7 @@ Help by testing Found a bug? Oddments? Report an issue on GitHub - Interested in helping out by testing what will be the next version? + Help us test the next version! Test the dev version This includes all upcoming features and it is on the very bleeding edge. Bugs/errors can occur, if and when they do, please report of your findings. Release candidate From e75687c748391062c9987aa128a3e940a6c997e2 Mon Sep 17 00:00:00 2001 From: ge78fug Date: Fri, 16 Dec 2022 08:27:47 +0100 Subject: [PATCH 26/28] Removed the community_testing_version_text Signed-off-by: ge78fug --- app/src/main/res/layout/community_layout.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/src/main/res/layout/community_layout.xml b/app/src/main/res/layout/community_layout.xml index 880adb62aa..9e1ab9bcda 100755 --- a/app/src/main/res/layout/community_layout.xml +++ b/app/src/main/res/layout/community_layout.xml @@ -69,15 +69,6 @@ android:theme="@style/Button.Primary" app:cornerRadius="@dimen/button_corner_radius" /> - - Date: Fri, 16 Dec 2022 11:45:08 +0100 Subject: [PATCH 27/28] Deleted the english community_testing_version_text Signed-off-by: Marius Wagner --- app/src/main/res/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b5f63830bb..e4ad6665ca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -523,7 +523,6 @@ Help by testing Found a bug? Oddments? Report an issue on GitHub - Help us test the next version! Test the dev version This includes all upcoming features and it is on the very bleeding edge. Bugs/errors can occur, if and when they do, please report of your findings. Release candidate From b694ece33210dffc2c50bff84446613a07ff8092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Brey?= Date: Fri, 16 Dec 2022 13:50:21 +0100 Subject: [PATCH 28/28] Update community activity screenshot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Álvaro Brey --- ...tcloud.client.CommunityActivityIT_open.png | Bin 82360 -> 76660 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/app/screenshots/gplay/debug/com.nextcloud.client.CommunityActivityIT_open.png b/app/screenshots/gplay/debug/com.nextcloud.client.CommunityActivityIT_open.png index 6160fc40056edf8c3d685df5f97fecf78232d661..c70bcfaee7d3d6c79e0569596aae93f79c2f3029 100644 GIT binary patch literal 76660 zcmdp-Wn7fs-{(~Xq)R}$1Qh9%20^;JJBL!bh7dszkdp3(p}R}zpgGrA0=+Pq_c{yo~M~@z#KYD~B z`3wzsLZYH%{peB9BY9~_E$@YcWmKc@S2XB_GG0oO!CczAfQinO#ewmb0LB8TYz$A<(cng7EunWJQ5sLj{6l;8TEzoHiN ze`;&XyfKtO>H&hin=RMB!H6g}Y;v~jEr~19u478$xBu~kjvf*FL^QwH_7m&&*l7B( z)%MlFa%3kGQL3gIM~}*FJ@R?lR>cw-7Ja=rXUgSyZddO(`6)ZzyV-k}zR__Ra!(~V zQ8>aTSv;1xwz?W5SZ9-~usK}a*eK)e{q|ne{TT`x zPHz(m8m(rL(ksnYUh&r?@ux=ZALv}I#?9RyrmPifoRMgb@Y+OR5x?u9AdO+=a4l)+ zr(rRa!O0w^7PC=gEdJ;5Ov;ca{?`-ccJLa8fOOu7U}`+q4_dkYJ|s^G2po1?YCHqB zuyJVw^FFn@7Ai1hGnjwpcOs{J>y5v%vLcr)*0IJVE-qefP>05>k|Cj{h7SxkoJAXw zV-boe7ymM1($z}T@A5z$JTw%qZ+Vdh0|rfaaB!do(URwNT6%hUdD;ANok^$CAmWUa zy?b)=wwdi&uKpv=H60q9bA7 zgBPBM3x%_XM@QefbjrJTr;A~yz;8uuDW}uF)DuNTu372FfrS!x0lPKvI8Swx_6O` zz#fprJ)hpQZ2)QKqgLmd#WViIW|PYj!QjM%0DqgSnar`ez8)#! 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 DB!m7` literal 82360 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 (dNr{c4!Y<_tJK}Dub7N*2Qjb04rcv zncz?g`fX#-$i2t#X>=*zRC8IG?o&S(_KuH}vm4|FyS7j@wFNjiLceD~^cY z-LX|7ULv8_dI)y{qxko9o-#ZWDJyx8I=-Ra>~C?byXldFKA1SlYlOW$hE494p11b} z{3lLO`?s(d!r@67X85@6@uK&%xFenDDYQ$9xJ&olzQJBo%~z6D=A5~h&)dzV`_ z9gyvEM!cbakZ!N{x{tW$P)coQ(ZgBdV}Z@Q=r*IfFh8gyq)KtVeK65*{=-u3B`Y*d z3lvl3MLq%wGL`gsSC_^Bh3H1_ zx8!}nzN%K!WU=D{XCj@Xisy}tx*3(%wlIXgtpo@}7hkb*e$caW!mV!o(5Wk^35;!u zc!RQ!9932HOipux`%t?^n9L$jeo@t9Ce6 z37=fArghUHekWK|x*4zQD8zLWL%J;uFDuLvCmH}PDG9o}^Y#-DvDPxl%&3^3Li?8x z#jdv^>pqUxsf5t4wcpR6(h@$wSyLdxE8&}VRztrycF;fFX`zB}m9`m;i<=Q1nam;o z<-~I`&`n)sr_FA?nh@OSa)&P}l&kzmOd4NAz~i_`Z)EcDUFM{JdJ?);zlo7zc3}IM>(y$t0n_g{Q{}l8cP?s?#%DHuMqKSEvhHrP! zy{!x6J&|5I{doK1CthgrcSMyTy9D}trB*qey^Nes=jov%FfjBI@8_c1R%^5r1?bYB zT;Q_A<}Q2sf~}ukysmG?@8ag|`FwqdRgt?F-9%?Tb^@#N0qw^bIqdhxDJCNGnJJEf z`|KFUNt#rc-lR`4!2)BBG%8_Vb6T&{-$bxAf`Gg8y1tX6{ zFJ@cB-493BrLjR%Mn$-eZ>w@-hFY+)1U$J2PA^&Yrpw{AZ|8p$aHEIJ^RQOGJN6tL z_VD&yra!1b_FDHI?pNSP;^TKl5YEJLmhC@}3>Q2MMA?w`D<{61E*?F_`S$g+;a8|+ z&8jy+t=avli<|jArRGkBOI)tK2~7E=0*6U93np-WL!Dm} z&i*U)&2Nfx2G{cS!ywis-NbO_aPk1wN9t8t zy7T@!2Aw>X__9?WEi{WdxPZ+cjB-tZ4@s

5Pdo@>MJP=F1HgdAzPsE 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 +$ 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