Skip to content

Commit 5f5b9b3

Browse files
committed
fix(anr): is auto upload
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent ffaf934 commit 5f5b9b3

File tree

8 files changed

+70
-51
lines changed

8 files changed

+70
-51
lines changed

app/src/main/java/com/nextcloud/client/database/dao/SyncedFolderDao.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.room.Dao
1111
import androidx.room.Query
1212
import com.nextcloud.client.database.entity.SyncedFolderEntity
1313
import com.owncloud.android.db.ProviderMeta
14+
import kotlinx.coroutines.flow.Flow
1415

1516
@Dao
1617
interface SyncedFolderDao {
@@ -23,4 +24,7 @@ interface SyncedFolderDao {
2324
"""
2425
)
2526
fun findByLocalPathAndAccount(localPath: String, account: String): SyncedFolderEntity?
27+
28+
@Query("SELECT * FROM ${ProviderMeta.ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME}")
29+
fun getAllAsFlow(): Flow<List<SyncedFolderEntity>>
2630
}

app/src/main/java/com/nextcloud/utils/ShortcutUtil.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import androidx.core.graphics.drawable.toDrawable
2424
import com.nextcloud.client.account.User
2525
import com.owncloud.android.R
2626
import com.owncloud.android.datamodel.OCFile
27+
import com.owncloud.android.datamodel.SyncedFolderObserver
2728
import com.owncloud.android.datamodel.SyncedFolderProvider
2829
import com.owncloud.android.datamodel.ThumbnailsCacheManager
2930
import com.owncloud.android.ui.activity.FileActivity
@@ -91,7 +92,7 @@ class ShortcutUtil @Inject constructor(private val mContext: Context) {
9192
thumbnail != null -> IconCompat.createWithAdaptiveBitmap(bitmapToAdaptiveBitmap(thumbnail))
9293

9394
file.isFolder -> {
94-
val isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user)
95+
val isAutoUploadFolder = SyncedFolderObserver.isAutoUploadFolder(file, user)
9596
val isDarkModeActive = syncedFolderProvider.preferences.isDarkModeEnabled
9697
val overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder)
9798
val drawable = MimeTypeUtil.getFolderIcon(isDarkModeActive, overlayIconId, mContext, viewThemeUtils)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Nextcloud - Android Client
3+
*
4+
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
package com.owncloud.android.datamodel
9+
10+
import com.nextcloud.client.account.User
11+
import com.nextcloud.client.database.dao.SyncedFolderDao
12+
import com.nextcloud.client.database.entity.SyncedFolderEntity
13+
import com.owncloud.android.lib.resources.files.model.ServerFileInterface
14+
import kotlinx.coroutines.CoroutineScope
15+
import kotlinx.coroutines.Dispatchers
16+
import kotlinx.coroutines.Job
17+
import kotlinx.coroutines.SupervisorJob
18+
import kotlinx.coroutines.flow.distinctUntilChanged
19+
import kotlinx.coroutines.launch
20+
import java.util.concurrent.CopyOnWriteArraySet
21+
22+
object SyncedFolderObserver {
23+
24+
private val entities = CopyOnWriteArraySet<SyncedFolderEntity>()
25+
private var job: Job? = null
26+
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
27+
28+
fun start(dao: SyncedFolderDao) {
29+
if (job?.isActive == true) return
30+
31+
job = scope.launch {
32+
dao.getAllAsFlow()
33+
.distinctUntilChanged()
34+
.collect { updatedEntities ->
35+
entities.clear()
36+
entities.addAll(updatedEntities)
37+
}
38+
}
39+
}
40+
41+
fun isAutoUploadFolder(file: ServerFileInterface, user: User): Boolean {
42+
val normalizedRemotePath = file.remotePath
43+
.trimEnd('/')
44+
45+
return entities
46+
.stream()
47+
.filter { it.account == user.accountName }
48+
.filter { it.remotePath != null }
49+
.anyMatch { entity ->
50+
val entityRemotePath = entity.remotePath?.trimEnd('/') ?: return@anyMatch false
51+
normalizedRemotePath.contains(entityRemotePath)
52+
}
53+
}
54+
}

app/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.owncloud.android.MainApp;
2626
import com.owncloud.android.db.ProviderMeta;
2727
import com.owncloud.android.lib.common.utils.Log_OC;
28-
import com.owncloud.android.lib.resources.files.model.ServerFileInterface;
2928

3029
import java.io.File;
3130
import java.util.ArrayList;
@@ -61,6 +60,7 @@ public SyncedFolderProvider(ContentResolver contentResolver, AppPreferences pref
6160
mContentResolver = contentResolver;
6261
this.preferences = preferences;
6362
this.clock = clock;
63+
SyncedFolderObserver.INSTANCE.start(dao);
6464
}
6565

6666
/**
@@ -84,10 +84,6 @@ public long storeSyncedFolder(SyncedFolder syncedFolder) {
8484
}
8585
}
8686

87-
public static boolean isAutoUploadFolder(SyncedFolderProvider syncedFolderProvider, ServerFileInterface file, User user) {
88-
return syncedFolderProvider != null && syncedFolderProvider.findByRemotePathAndAccount(file.getRemotePath(), user);
89-
}
90-
9187
public int countEnabledSyncedFolders() {
9288
int count = 0;
9389
Cursor cursor = mContentResolver.query(
@@ -423,44 +419,4 @@ private ContentValues createContentValuesFromSyncedFolder(SyncedFolder syncedFol
423419
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS, syncedFolder.getLastScanTimestampMs());
424420
return cv;
425421
}
426-
427-
/**
428-
* method to check if sync folder for the remote path exist in table or not
429-
*
430-
* @param remotePath to be check
431-
* @param user for which we are looking
432-
* @return <code>true</code> if exist, <code>false</code> otherwise
433-
*/
434-
public boolean findByRemotePathAndAccount(String remotePath, User user) {
435-
boolean result = false;
436-
437-
//if path ends with / then remove the last / to work the query right way
438-
//because the sub folders of synced folders will not have the slash at the end
439-
if (remotePath.endsWith("/")) {
440-
remotePath = remotePath.substring(0, remotePath.length() - 1);
441-
}
442-
443-
Cursor cursor = mContentResolver.query(
444-
ProviderMeta.ProviderTableMeta.CONTENT_URI_SYNCED_FOLDERS,
445-
null,
446-
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_REMOTE_PATH + " LIKE ? AND " +
447-
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ACCOUNT + " =? ",
448-
new String[]{"%" + remotePath + "%", user.getAccountName()},
449-
null);
450-
451-
if (cursor != null && cursor.getCount() >= 1) {
452-
result = true;
453-
} else {
454-
if (cursor == null) {
455-
Log_OC.e(TAG, "Sync folder db cursor for remote path = " + remotePath + " in NULL.");
456-
}
457-
}
458-
459-
if (cursor != null) {
460-
cursor.close();
461-
}
462-
463-
return result;
464-
465-
}
466422
}

app/src/main/java/com/owncloud/android/ui/activity/EditorWebView.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.owncloud.android.R;
3232
import com.owncloud.android.databinding.RichdocumentsWebviewBinding;
3333
import com.owncloud.android.datamodel.OCFile;
34+
import com.owncloud.android.datamodel.SyncedFolderObserver;
3435
import com.owncloud.android.datamodel.SyncedFolderProvider;
3536
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
3637
import com.owncloud.android.ui.asynctasks.TextEditorLoadUrlTask;
@@ -251,7 +252,7 @@ protected void setThumbnailView(final User user) {
251252
// Todo minimize: only icon by mimetype
252253
OCFile file = getFile();
253254
if (file.isFolder()) {
254-
boolean isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user);
255+
boolean isAutoUploadFolder = SyncedFolderObserver.INSTANCE.isAutoUploadFolder(file, user);
255256

256257
Integer overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder);
257258
LayerDrawable drawable = MimeTypeUtil.getFolderIcon(preferences.isDarkModeEnabled(), overlayIconId, this, viewThemeUtils);

app/src/main/java/com/owncloud/android/ui/activity/ShareActivity.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.owncloud.android.R;
2222
import com.owncloud.android.databinding.ShareActivityBinding;
2323
import com.owncloud.android.datamodel.OCFile;
24+
import com.owncloud.android.datamodel.SyncedFolderObserver;
2425
import com.owncloud.android.datamodel.SyncedFolderProvider;
2526
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
2627
import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -63,14 +64,14 @@ protected void onCreate(Bundle savedInstanceState) {
6364

6465
OCFile file = getFile();
6566
Optional<User> optionalUser = getUser();
66-
if (!optionalUser.isPresent()) {
67+
if (optionalUser.isEmpty()) {
6768
finish();
6869
return;
6970
}
7071

7172
// Icon
7273
if (file.isFolder()) {
73-
boolean isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, optionalUser.get());
74+
boolean isAutoUploadFolder = SyncedFolderObserver.INSTANCE.isAutoUploadFolder(file, optionalUser.get());
7475

7576
Integer overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder);
7677
LayerDrawable drawable = MimeTypeUtil.getFolderIcon(preferences.isDarkModeEnabled(), overlayIconId, this, viewThemeUtils);

app/src/main/java/com/owncloud/android/ui/adapter/ReceiveExternalFilesAdapter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.nextcloud.client.account.User
1818
import com.owncloud.android.databinding.UploaderListItemLayoutBinding
1919
import com.owncloud.android.datamodel.FileDataStorageManager
2020
import com.owncloud.android.datamodel.OCFile
21+
import com.owncloud.android.datamodel.SyncedFolderObserver
2122
import com.owncloud.android.datamodel.SyncedFolderProvider
2223
import com.owncloud.android.datamodel.ThumbnailsCacheManager
2324
import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncThumbnailDrawable
@@ -112,7 +113,7 @@ class ReceiveExternalFilesAdapter(
112113
}
113114

114115
private fun setupThumbnailForFolder(thumbnailImageView: ImageView, file: OCFile) {
115-
val isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user)
116+
val isAutoUploadFolder = SyncedFolderObserver.isAutoUploadFolder(file, user)
116117
val isDarkModeActive = syncedFolderProvider.preferences.isDarkModeEnabled
117118
val overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder)
118119
val icon = MimeTypeUtil.getFolderIcon(isDarkModeActive, overlayIconId, context, viewThemeUtils)

app/src/main/java/com/owncloud/android/utils/DisplayUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
5858
import com.owncloud.android.datamodel.FileDataStorageManager;
5959
import com.owncloud.android.datamodel.OCFile;
60+
import com.owncloud.android.datamodel.SyncedFolderObserver;
6061
import com.owncloud.android.datamodel.SyncedFolderProvider;
6162
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
6263
import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -902,7 +903,7 @@ private static void setThumbnailForOfflineOperation(OCFile file, ImageView thumb
902903
private static void setThumbnailForFolder(OCFile file, ImageView thumbnailView, LoaderImageView shimmerThumbnail, User user, SyncedFolderProvider syncedFolderProvider, AppPreferences preferences, Context context, ViewThemeUtils viewThemeUtils) {
903904
stopShimmer(shimmerThumbnail, thumbnailView);
904905

905-
boolean isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user);
906+
boolean isAutoUploadFolder = SyncedFolderObserver.INSTANCE.isAutoUploadFolder(file, user);
906907
boolean isDarkModeActive = preferences.isDarkModeEnabled();
907908

908909
final var overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder);

0 commit comments

Comments
 (0)