From 7f4db3fdd0708fad386069cc068ebd211aa89d27 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Sun, 3 Nov 2019 00:48:23 +0100 Subject: [PATCH 1/4] Make synced folder init/enable date persistent Signed-off-by: Alice Gaudon --- .../android/datamodel/SyncedFolder.java | 50 ++++++++---- .../datamodel/SyncedFolderDisplayItem.java | 11 ++- .../datamodel/SyncedFolderProvider.java | 12 ++- .../com/owncloud/android/db/ProviderMeta.java | 3 +- .../android/jobs/AccountRemovalJob.java | 7 +- .../providers/FileContentProvider.java | 30 ++++++++ .../ui/activity/SyncedFoldersActivity.java | 34 +++----- .../ui/adapter/SyncedFolderAdapter.java | 9 ++- .../android/utils/FilesSyncHelper.java | 77 ++++++------------- .../activity/SyncedFoldersActivityTest.java | 1 + 10 files changed, 127 insertions(+), 107 deletions(-) diff --git a/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java b/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java index 24aaa1f3f7..91b42b8134 100644 --- a/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java +++ b/src/main/java/com/owncloud/android/datamodel/SyncedFolder.java @@ -30,23 +30,23 @@ import lombok.Setter; /** * Synced folder entity containing all information per synced folder. */ -@Getter -@Setter @AllArgsConstructor public class SyncedFolder implements Serializable, Cloneable { public static final long UNPERSISTED_ID = Long.MIN_VALUE; + public static final long EMPTY_ENABLED_TIMESTAMP_MS = -1; private static final long serialVersionUID = -793476118299906429L; - private long id = UNPERSISTED_ID; - private String localPath; - private String remotePath; - private Boolean wifiOnly; - private Boolean chargingOnly; - private Boolean subfolderByDate; - private String account; - private Integer uploadAction; - private boolean enabled; - private MediaFolderType type; + @Getter @Setter private long id; + @Getter @Setter private String localPath; + @Getter @Setter private String remotePath; + @Getter @Setter private Boolean wifiOnly; + @Getter @Setter private Boolean chargingOnly; + @Getter @Setter private Boolean subfolderByDate; + @Getter @Setter private String account; + @Getter @Setter private Integer uploadAction; + @Getter private boolean enabled; + @Getter private long enabledTimestampMs; + @Getter @Setter private MediaFolderType type; /** * constructor for new, to be persisted entity. @@ -59,11 +59,25 @@ public class SyncedFolder implements Serializable, Cloneable { * @param account the account owning the synced folder * @param uploadAction the action to be done after the upload * @param enabled flag if synced folder config is active + * @param timestampMs the current timestamp in milliseconds * @param type the type of the folder */ public SyncedFolder(String localPath, String remotePath, Boolean wifiOnly, Boolean chargingOnly, Boolean subfolderByDate, String account, Integer uploadAction, Boolean enabled, - MediaFolderType type) { + long timestampMs, MediaFolderType type) { + this(UNPERSISTED_ID, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, + enabled, timestampMs, type); + } + + /** + * constructor for wrapping existing folders. + * + * @param id id + */ + protected SyncedFolder(long id, String localPath, String remotePath, Boolean wifiOnly, Boolean chargingOnly, + Boolean subfolderByDate, String account, Integer uploadAction, Boolean enabled, + long timestampMs, MediaFolderType type) { + this.id = id; this.localPath = localPath; this.remotePath = remotePath; this.wifiOnly = wifiOnly; @@ -71,10 +85,18 @@ public class SyncedFolder implements Serializable, Cloneable { this.subfolderByDate = subfolderByDate; this.account = account; this.uploadAction = uploadAction; - this.enabled = enabled; + this.setEnabled(enabled, timestampMs); this.type = type; } + /** + * @param timestampMs the current timestamp in milliseconds + */ + public void setEnabled(boolean enabled, long timestampMs) { + this.enabled = enabled; + this.enabledTimestampMs = enabled ? timestampMs : EMPTY_ENABLED_TIMESTAMP_MS; + } + public Object clone() { try { return super.clone(); diff --git a/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java b/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java index cac3df7a14..7420b18892 100644 --- a/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java +++ b/src/main/java/com/owncloud/android/datamodel/SyncedFolderDisplayItem.java @@ -56,9 +56,11 @@ public class SyncedFolderDisplayItem extends SyncedFolder { */ public SyncedFolderDisplayItem(long id, String localPath, String remotePath, Boolean wifiOnly, Boolean chargingOnly, Boolean subfolderByDate, String account, Integer uploadAction, Boolean enabled, - List filePaths, String folderName, long numberOfFiles, MediaFolderType type) + long timestampMs, List filePaths, String folderName, long numberOfFiles, + MediaFolderType type) { - super(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, enabled, type); + super(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, enabled, + timestampMs, type); this.filePaths = filePaths; this.folderName = folderName; this.numberOfFiles = numberOfFiles; @@ -66,8 +68,9 @@ public class SyncedFolderDisplayItem extends SyncedFolder { public SyncedFolderDisplayItem(long id, String localPath, String remotePath, Boolean wifiOnly, Boolean chargingOnly, Boolean subfolderByDate, String account, Integer uploadAction, Boolean enabled, - String folderName, MediaFolderType type) { - super(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, enabled, type); + long timestampMs, String folderName, MediaFolderType type) { + super(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, account, uploadAction, enabled, + timestampMs, type); this.folderName = folderName; } } diff --git a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java index 07712a9e34..b7dd75d967 100644 --- a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java +++ b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java @@ -27,6 +27,7 @@ import android.content.Context; import android.database.Cursor; import android.net.Uri; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.client.preferences.AppPreferencesImpl; import com.owncloud.android.db.ProviderMeta; @@ -37,6 +38,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Observable; +import javax.inject.Inject; + import androidx.annotation.NonNull; import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; @@ -50,6 +53,8 @@ public class SyncedFolderProvider extends Observable { private ContentResolver mContentResolver; private AppPreferences preferences; + @Inject protected Clock clock; + /** * constructor. * @@ -162,7 +167,7 @@ public class SyncedFolderProvider extends Observable { // read sync folder object and update SyncedFolder syncedFolder = createSyncedFolderFromCursor(cursor); - syncedFolder.setEnabled(enabled); + syncedFolder.setEnabled(enabled, clock.getCurrentTime()); // update sync folder object in db result = updateSyncFolder(syncedFolder); @@ -347,11 +352,13 @@ public class SyncedFolderProvider extends Observable { ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION)); Boolean enabled = cursor.getInt(cursor.getColumnIndex( ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED)) == 1; + long enabledTimestampMs = cursor.getLong(cursor.getColumnIndex( + ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED_TIMESTAMP_MS)); MediaFolderType type = MediaFolderType.getById(cursor.getInt(cursor.getColumnIndex( ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE))); syncedFolder = new SyncedFolder(id, localPath, remotePath, wifiOnly, chargingOnly, subfolderByDate, - accountName, uploadAction, enabled, type); + accountName, uploadAction, enabled, enabledTimestampMs, type); } return syncedFolder; } @@ -370,6 +377,7 @@ public class SyncedFolderProvider extends Observable { cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_WIFI_ONLY, syncedFolder.getWifiOnly()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_CHARGING_ONLY, syncedFolder.getChargingOnly()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED, syncedFolder.isEnabled()); + cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ENABLED_TIMESTAMP_MS, syncedFolder.getEnabledTimestampMs()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_BY_DATE, syncedFolder.getSubfolderByDate()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_ACCOUNT, syncedFolder.getAccount()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_UPLOAD_ACTION, syncedFolder.getUploadAction()); diff --git a/src/main/java/com/owncloud/android/db/ProviderMeta.java b/src/main/java/com/owncloud/android/db/ProviderMeta.java index 093d36b9f2..8bbe982b15 100644 --- a/src/main/java/com/owncloud/android/db/ProviderMeta.java +++ b/src/main/java/com/owncloud/android/db/ProviderMeta.java @@ -31,7 +31,7 @@ import com.owncloud.android.MainApp; */ public class ProviderMeta { public static final String DB_NAME = "filelist"; - public static final int DB_VERSION = 49; + public static final int DB_VERSION = 50; private ProviderMeta() { // No instance @@ -220,6 +220,7 @@ public class ProviderMeta { public static final String SYNCED_FOLDER_WIFI_ONLY = "wifi_only"; public static final String SYNCED_FOLDER_CHARGING_ONLY = "charging_only"; public static final String SYNCED_FOLDER_ENABLED = "enabled"; + public static final String SYNCED_FOLDER_ENABLED_TIMESTAMP_MS = "enabled_timestamp_ms"; public static final String SYNCED_FOLDER_TYPE = "type"; public static final String SYNCED_FOLDER_SUBFOLDER_BY_DATE = "subfolder_by_date"; public static final String SYNCED_FOLDER_ACCOUNT = "account"; diff --git a/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java b/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java index b87d3e99de..9065d9a0b6 100644 --- a/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java +++ b/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java @@ -57,7 +57,6 @@ import com.owncloud.android.ui.activity.ContactsPreferenceActivity; import com.owncloud.android.ui.events.AccountRemovedEvent; import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.FileStorageUtils; -import com.owncloud.android.utils.FilesSyncHelper; import com.owncloud.android.utils.PushUtils; import org.greenrobot.eventbus.EventBus; @@ -129,7 +128,7 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback syncedFolders = syncedFolderProvider.getSyncedFolders(); @@ -183,8 +182,6 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback= 50) { + Log_OC.i(SQL, "Entering in the #50 add persistent enable date to synced_folders table"); + db.beginTransaction(); + try { + db.execSQL(ALTER_TABLE + ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME + + ADD_COLUMN + ProviderTableMeta.SYNCED_FOLDER_ENABLED_TIMESTAMP_MS + " INTEGER "); + + db.execSQL("UPDATE " + ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME + " SET " + + ProviderTableMeta.SYNCED_FOLDER_ENABLED_TIMESTAMP_MS + " = CASE " + + " WHEN enabled = 0 THEN " + SyncedFolder.EMPTY_ENABLED_TIMESTAMP_MS + " " + + " ELSE " + clock.getCurrentTime() + + " END "); + + upgraded = true; + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + + if (!upgraded) { + Log_OC.i(SQL, String.format(Locale.ENGLISH, UPGRADE_VERSION_MSG, oldVersion, newVersion)); + } } @Override diff --git a/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java b/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java index 78ae762868..07ec55dc45 100644 --- a/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java @@ -41,13 +41,13 @@ import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.di.Injectable; import com.nextcloud.client.preferences.AppPreferences; import com.owncloud.android.BuildConfig; import com.owncloud.android.MainApp; import com.owncloud.android.R; -import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.MediaFolder; import com.owncloud.android.datamodel.MediaFolderType; import com.owncloud.android.datamodel.MediaProvider; @@ -113,6 +113,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA private int type; @Inject AppPreferences preferences; @Inject PowerManagementService powerManagementService; + @Inject Clock clock; @Override protected void onCreate(Bundle savedInstanceState) { @@ -223,7 +224,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA final int gridWidth = getResources().getInteger(R.integer.media_grid_width); boolean lightVersion = getResources().getBoolean(R.bool.syncedFolder_light); - mAdapter = new SyncedFolderAdapter(this, gridWidth, this, lightVersion); + mAdapter = new SyncedFolderAdapter(this, clock, gridWidth, this, lightVersion); mSyncedFolderProvider = new SyncedFolderProvider(getContentResolver(), preferences); final GridLayoutManager lm = new GridLayoutManager(this, gridWidth); @@ -386,6 +387,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA syncedFolder.getAccount(), syncedFolder.getUploadAction(), syncedFolder.isEnabled(), + clock.getCurrentTime(), filePaths, localFolder.getName(), files.length, @@ -411,6 +413,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA syncedFolder.getAccount(), syncedFolder.getUploadAction(), syncedFolder.isEnabled(), + clock.getCurrentTime(), mediaFolder.filePaths, mediaFolder.folderName, mediaFolder.numberOfFiles, @@ -432,9 +435,10 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA true, false, false, - getAccount().name, + getAccount().name, FileUploader.LOCAL_BEHAVIOUR_FORGET, false, + clock.getCurrentTime(), mediaFolder.filePaths, mediaFolder.folderName, mediaFolder.numberOfFiles, @@ -519,7 +523,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA SyncedFolderDisplayItem emptyCustomFolder = new SyncedFolderDisplayItem( SyncedFolder.UNPERSISTED_ID, null, null, true, false, false, getAccount().name, - FileUploader.LOCAL_BEHAVIOUR_FORGET, false, null, MediaFolderType.CUSTOM); + FileUploader.LOCAL_BEHAVIOUR_FORGET, false, clock.getCurrentTime(), null, MediaFolderType.CUSTOM); onSyncFolderSettingsClick(0, emptyCustomFolder); } @@ -548,9 +552,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA @Override public void onSyncStatusToggleClick(int section, SyncedFolderDisplayItem syncedFolderDisplayItem) { - ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext(). - getContentResolver()); - if (syncedFolderDisplayItem.getId() > UNPERSISTED_ID) { mSyncedFolderProvider.updateSyncedFolderEnabled(syncedFolderDisplayItem.getId(), syncedFolderDisplayItem.isEnabled()); @@ -565,9 +566,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA FilesSyncHelper.insertAllDBEntriesForSyncedFolder(syncedFolderDisplayItem); showBatteryOptimizationInfo(); - } else { - String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + syncedFolderDisplayItem.getId(); - arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey); } } @@ -600,9 +598,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA @Override public void onSaveSyncedFolderPreference(SyncedFolderParcelable syncedFolder) { - ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext(). - getContentResolver()); - // custom folders newly created aren't in the list already, // so triggering a refresh if (MediaFolderType.CUSTOM == syncedFolder.getType() && syncedFolder.getId() == UNPERSISTED_ID) { @@ -610,15 +605,12 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA SyncedFolder.UNPERSISTED_ID, syncedFolder.getLocalPath(), syncedFolder.getRemotePath(), syncedFolder.getWifiOnly(), syncedFolder.getChargingOnly(), syncedFolder.getSubfolderByDate(), syncedFolder.getAccount(), syncedFolder.getUploadAction(), syncedFolder.getEnabled(), - new File(syncedFolder.getLocalPath()).getName(), syncedFolder.getType()); + clock.getCurrentTime(), new File(syncedFolder.getLocalPath()).getName(), syncedFolder.getType()); long storedId = mSyncedFolderProvider.storeSyncedFolder(newCustomFolder); if (storedId != -1) { newCustomFolder.setId(storedId); if (newCustomFolder.isEnabled()) { FilesSyncHelper.insertAllDBEntriesForSyncedFolder(newCustomFolder); - } else { - String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + newCustomFolder.getId(); - arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey); } } mAdapter.addSyncFolderItem(newCustomFolder); @@ -635,9 +627,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA item.setId(storedId); if (item.isEnabled()) { FilesSyncHelper.insertAllDBEntriesForSyncedFolder(item); - } else { - String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + item.getId(); - arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey); } } } else { @@ -645,9 +634,6 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA mSyncedFolderProvider.updateSyncFolder(item); if (item.isEnabled()) { FilesSyncHelper.insertAllDBEntriesForSyncedFolder(item); - } else { - String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + item.getId(); - arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey); } } @@ -699,7 +685,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA item.setChargingOnly(chargingOnly); item.setSubfolderByDate(subfolderByDate); item.setUploadAction(uploadAction); - item.setEnabled(enabled); + item.setEnabled(enabled, clock.getCurrentTime()); return item; } diff --git a/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java index 8a8176e54e..7588b323da 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java @@ -33,6 +33,7 @@ import android.widget.TextView; import com.afollestad.sectionedrecyclerview.SectionedRecyclerViewAdapter; import com.afollestad.sectionedrecyclerview.SectionedViewHolder; +import com.nextcloud.client.core.Clock; import com.owncloud.android.R; import com.owncloud.android.datamodel.MediaFolderType; import com.owncloud.android.datamodel.SyncedFolderDisplayItem; @@ -54,14 +55,16 @@ import butterknife.ButterKnife; public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter { private final Context mContext; + private final Clock clock; private final int mGridWidth; private final int mGridTotal; private final ClickListener mListener; private final List mSyncFolderItems; private final boolean mLight; - public SyncedFolderAdapter(Context context, int gridWidth, ClickListener listener, boolean light) { + public SyncedFolderAdapter(Context context, Clock clock, int gridWidth, ClickListener listener, boolean light) { mContext = context; + this.clock = clock; mGridWidth = gridWidth; mGridTotal = gridWidth * 2; mListener = listener; @@ -148,7 +151,7 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter { - mSyncFolderItems.get(section).setEnabled(!mSyncFolderItems.get(section).isEnabled()); + mSyncFolderItems.get(section).setEnabled(!mSyncFolderItems.get(section).isEnabled(), clock.getCurrentTime()); setSyncButtonActiveIcon(holder.syncStatusButton, mSyncFolderItems.get(section).isEnabled()); mListener.onSyncStatusToggleClick(section, mSyncFolderItems.get(section)); }); @@ -157,7 +160,7 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter { - mSyncFolderItems.get(section).setEnabled(!mSyncFolderItems.get(section).isEnabled()); + mSyncFolderItems.get(section).setEnabled(!mSyncFolderItems.get(section).isEnabled(), clock.getCurrentTime()); setSyncButtonActiveIcon(holder.syncStatusButton, mSyncFolderItems.get(section).isEnabled()); mListener.onSyncStatusToggleClick(section, mSyncFolderItems.get(section)); }); diff --git a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index 9116a3d570..351abe46b2 100644 --- a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -30,7 +30,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; -import android.text.TextUtils; import android.util.Log; import com.evernote.android.job.JobManager; @@ -41,7 +40,6 @@ import com.nextcloud.client.jobs.BackgroundJobManager; import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.preferences.AppPreferences; import com.owncloud.android.MainApp; -import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.FilesystemDataProvider; import com.owncloud.android.datamodel.MediaFolderType; import com.owncloud.android.datamodel.SyncedFolder; @@ -73,7 +71,6 @@ public final class FilesSyncHelper { public static final String TAG = "FileSyncHelper"; public static final String GLOBAL = "global"; - public static final String SYNCEDFOLDERINITIATED = "syncedFolderIntitiated_"; public static final int ContentSyncJobId = 315; @@ -84,59 +81,34 @@ public final class FilesSyncHelper { public static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) { final Context context = MainApp.getAppContext(); final ContentResolver contentResolver = context.getContentResolver(); - ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(contentResolver); - Long currentTime = System.currentTimeMillis(); - double currentTimeInSeconds = currentTime / 1000.0; - String currentTimeString = Long.toString((long) currentTimeInSeconds); + final long enabledTimestampMs = syncedFolder.getEnabledTimestampMs(); - String syncedFolderInitiatedKey = SYNCEDFOLDERINITIATED + syncedFolder.getId(); - boolean dryRun = TextUtils.isEmpty(arbitraryDataProvider.getValue - (GLOBAL, syncedFolderInitiatedKey)); - - if (MediaFolderType.IMAGE == syncedFolder.getType()) { - if (dryRun) { - arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, - currentTimeString); - } else { - FilesSyncHelper.insertContentIntoDB(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI - , syncedFolder); + if (syncedFolder.isEnabled() && enabledTimestampMs >= 0) { + MediaFolderType mediaType = syncedFolder.getType(); + if (mediaType == MediaFolderType.IMAGE) { + FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI + , syncedFolder); FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, - syncedFolder); - } - - } else if (MediaFolderType.VIDEO == syncedFolder.getType()) { - - if (dryRun) { - arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, - currentTimeString); - } else { - FilesSyncHelper.insertContentIntoDB(android.provider.MediaStore.Video.Media.INTERNAL_CONTENT_URI, - syncedFolder); + syncedFolder); + } else if (mediaType == MediaFolderType.VIDEO) { + FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.INTERNAL_CONTENT_URI, + syncedFolder); FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, - syncedFolder); - } - - } else { - try { - if (dryRun) { - arbitraryDataProvider.storeOrUpdateKeyValue(GLOBAL, syncedFolderInitiatedKey, - currentTimeString); - } else { + syncedFolder); + } else { + try { FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver); Path path = Paths.get(syncedFolder.getLocalPath()); - String dateInitiated = arbitraryDataProvider.getValue(GLOBAL, - syncedFolderInitiatedKey); - Files.walkFileTree(path, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { - File file = path.toFile(); - if (attrs.lastModifiedTime().toMillis() >= Long.parseLong(dateInitiated) * 1000) { + if (attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) { filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(), - attrs.lastModifiedTime().toMillis(), file.isDirectory(), syncedFolder); + attrs.lastModifiedTime().toMillis(), + file.isDirectory(), syncedFolder); } return FileVisitResult.CONTINUE; @@ -147,11 +119,9 @@ public final class FilesSyncHelper { return FileVisitResult.CONTINUE; } }); - + } catch (IOException e) { + Log.e(TAG, "Something went wrong while indexing files for auto upload " + e.getLocalizedMessage()); } - - } catch (IOException e) { - Log.e(TAG, "Something went wrong while indexing files for auto upload " + e.getLocalizedMessage()); } } } @@ -172,7 +142,6 @@ public final class FilesSyncHelper { private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder) { final Context context = MainApp.getAppContext(); final ContentResolver contentResolver = context.getContentResolver(); - ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(contentResolver); Cursor cursor; int column_index_data; @@ -191,11 +160,10 @@ public final class FilesSyncHelper { } path = path + "%"; - String syncedFolderInitiatedKey = SYNCEDFOLDERINITIATED + syncedFolder.getId(); - String dateInitiated = arbitraryDataProvider.getValue(GLOBAL, syncedFolderInitiatedKey); + long enabledTimestampMs = syncedFolder.getEnabledTimestampMs(); cursor = context.getContentResolver().query(uri, projection, MediaStore.MediaColumns.DATA + " LIKE ?", - new String[]{path}, null); + new String[]{path}, null); if (cursor != null) { column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); @@ -203,9 +171,10 @@ public final class FilesSyncHelper { while (cursor.moveToNext()) { contentPath = cursor.getString(column_index_data); isFolder = new File(contentPath).isDirectory(); - if (cursor.getLong(column_index_date_modified) >= Long.parseLong(dateInitiated)) { + if (cursor.getLong(column_index_date_modified) >= enabledTimestampMs / 1000.0) { filesystemDataProvider.storeOrUpdateFileValue(contentPath, - cursor.getLong(column_index_date_modified), isFolder, syncedFolder); + cursor.getLong(column_index_date_modified), isFolder, + syncedFolder); } } cursor.close(); diff --git a/src/test/java/com/owncloud/android/ui/activity/SyncedFoldersActivityTest.java b/src/test/java/com/owncloud/android/ui/activity/SyncedFoldersActivityTest.java index b29b06c6bc..2861b3e3c0 100644 --- a/src/test/java/com/owncloud/android/ui/activity/SyncedFoldersActivityTest.java +++ b/src/test/java/com/owncloud/android/ui/activity/SyncedFoldersActivityTest.java @@ -177,6 +177,7 @@ public class SyncedFoldersActivityTest { "test@nextcloud.com", 1, enabled, + System.currentTimeMillis(), new ArrayList(), folderName, 2, From c2ea4de8020eb11506922b56b4b7c79e5a348b31 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 6 Nov 2019 01:44:41 +0100 Subject: [PATCH 2/4] FileContentProvider: add dagger injection Signed-off-by: Alice Gaudon --- src/main/java/com/nextcloud/client/di/ComponentsModule.java | 2 ++ .../com/owncloud/android/providers/FileContentProvider.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/com/nextcloud/client/di/ComponentsModule.java b/src/main/java/com/nextcloud/client/di/ComponentsModule.java index a8eadc3641..558ef0afa9 100644 --- a/src/main/java/com/nextcloud/client/di/ComponentsModule.java +++ b/src/main/java/com/nextcloud/client/di/ComponentsModule.java @@ -32,6 +32,7 @@ import com.owncloud.android.files.services.FileDownloader; import com.owncloud.android.files.services.FileUploader; import com.owncloud.android.jobs.NotificationJob; import com.owncloud.android.providers.DiskLruImageCacheFileProvider; +import com.owncloud.android.providers.FileContentProvider; import com.owncloud.android.providers.UsersAndGroupsSearchProvider; import com.owncloud.android.services.AccountManagerService; import com.owncloud.android.services.OperationsService; @@ -148,6 +149,7 @@ abstract class ComponentsModule { @ContributesAndroidInjector abstract BootupBroadcastReceiver bootupBroadcastReceiver(); @ContributesAndroidInjector abstract NotificationJob.NotificationReceiver notificationJobBroadcastReceiver(); + @ContributesAndroidInjector abstract FileContentProvider fileContentProvider(); @ContributesAndroidInjector abstract UsersAndGroupsSearchProvider usersAndGroupsSearchProvider(); @ContributesAndroidInjector abstract DiskLruImageCacheFileProvider diskLruImageCacheFileProvider(); diff --git a/src/main/java/com/owncloud/android/providers/FileContentProvider.java b/src/main/java/com/owncloud/android/providers/FileContentProvider.java index b82789ce98..78824925e4 100644 --- a/src/main/java/com/owncloud/android/providers/FileContentProvider.java +++ b/src/main/java/com/owncloud/android/providers/FileContentProvider.java @@ -63,6 +63,7 @@ import java.util.Locale; import javax.inject.Inject; import androidx.annotation.NonNull; +import dagger.android.AndroidInjection; /** * The ContentProvider for the ownCloud App. @@ -419,6 +420,7 @@ public class FileContentProvider extends ContentProvider { @Override public boolean onCreate() { + AndroidInjection.inject(this); mDbHelper = new DataBaseHelper(getContext()); mContext = getContext(); From 2e13212752c3a94b8c06195f179d81db35f75c00 Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Wed, 6 Nov 2019 01:50:40 +0100 Subject: [PATCH 3/4] SyncedFolderProvider: pass Clock dependency via constructor instead of dagger Signed-off-by: Alice Gaudon --- .../client/jobs/BackgroundJobFactory.kt | 9 +++-- .../java/com/owncloud/android/MainApp.java | 37 +++++++++++-------- .../datamodel/SyncedFolderProvider.java | 12 +++--- .../files/BootupBroadcastReceiver.java | 5 ++- .../android/jobs/AccountRemovalJob.java | 16 +++++--- .../owncloud/android/jobs/FilesSyncJob.java | 21 ++++++----- .../jobs/MediaFoldersDetectionJob.java | 12 ++++-- .../owncloud/android/jobs/NCJobCreator.java | 13 +++++-- .../ui/activity/SyncedFoldersActivity.java | 2 +- .../android/utils/FilesSyncHelper.java | 6 +-- .../client/jobs/BackgroundJobFactoryTest.kt | 5 +++ 11 files changed, 85 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt b/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt index 3ddd997114..38a6a57c81 100644 --- a/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt +++ b/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt @@ -26,6 +26,7 @@ import androidx.annotation.RequiresApi import androidx.work.ListenableWorker import androidx.work.WorkerFactory import androidx.work.WorkerParameters +import com.nextcloud.client.core.Clock import com.nextcloud.client.device.DeviceInfo import com.nextcloud.client.device.PowerManagementService import com.nextcloud.client.preferences.AppPreferences @@ -40,6 +41,7 @@ import javax.inject.Provider class BackgroundJobFactory @Inject constructor( private val preferences: AppPreferences, private val contentResolver: ContentResolver, + private val clock: Clock, private val powerManagerService: PowerManagementService, private val backgroundJobManager: Provider, private val deviceInfo: DeviceInfo @@ -58,13 +60,14 @@ class BackgroundJobFactory @Inject constructor( } return when (workerClass) { - ContentObserverWork::class -> createContentObserverJob(context, workerParameters) + ContentObserverWork::class -> createContentObserverJob(context, workerParameters, clock) else -> null // falls back to default factory } } - private fun createContentObserverJob(context: Context, workerParameters: WorkerParameters): ListenableWorker? { - val folderResolver = SyncedFolderProvider(contentResolver, preferences) + private fun createContentObserverJob(context: Context, workerParameters: WorkerParameters, clock: Clock): + ListenableWorker? { + val folderResolver = SyncedFolderProvider(contentResolver, preferences, clock) @RequiresApi(Build.VERSION_CODES.N) if (deviceInfo.apiLevel >= Build.VERSION_CODES.N) { return ContentObserverWork( diff --git a/src/main/java/com/owncloud/android/MainApp.java b/src/main/java/com/owncloud/android/MainApp.java index 05c90f3cae..3b7f088efe 100644 --- a/src/main/java/com/owncloud/android/MainApp.java +++ b/src/main/java/com/owncloud/android/MainApp.java @@ -45,6 +45,7 @@ import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; import com.nextcloud.client.account.UserAccountManager; import com.nextcloud.client.appinfo.AppInfo; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.di.ActivityInjector; import com.nextcloud.client.di.DaggerAppComponent; @@ -161,6 +162,9 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { @Inject BackgroundJobManager backgroundJobManager; + @Inject + Clock clock; + private PassCodeManager passCodeManager; @SuppressWarnings("unused") @@ -268,7 +272,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { preferences, uploadsStorageManager, connectivityService, - powerManagementService + powerManagementService, + clock ) ); @@ -304,7 +309,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { accountManager, connectivityService, powerManagementService, - backgroundJobManager); + backgroundJobManager, + clock); initContactsBackup(accountManager); notificationChannels(); @@ -462,23 +468,24 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { final UserAccountManager accountManager, final ConnectivityService connectivityService, final PowerManagementService powerManagementService, - final BackgroundJobManager jobManager + final BackgroundJobManager jobManager, + final Clock clock ) { updateToAutoUpload(); - cleanOldEntries(); - updateAutoUploadEntries(); + cleanOldEntries(clock); + updateAutoUploadEntries(clock); if (getAppContext() != null) { if (PermissionUtil.checkSelfPermission(getAppContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) { - splitOutAutoUploadEntries(); + splitOutAutoUploadEntries(clock); } else { AppPreferences preferences = AppPreferencesImpl.fromContext(getAppContext()); preferences.setAutoUploadSplitEntriesEnabled(true); } } - initiateExistingAutoUploadEntries(); + initiateExistingAutoUploadEntries(clock); FilesSyncHelper.scheduleFilesSyncIfNeeded(mContext, jobManager); FilesSyncHelper.restartJobsIfNeeded( @@ -685,18 +692,18 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { } } - private static void updateAutoUploadEntries() { + private static void updateAutoUploadEntries(Clock clock) { // updates entries to reflect their true paths Context context = getAppContext(); AppPreferences preferences = AppPreferencesImpl.fromContext(context); if (!preferences.isAutoUploadPathsUpdateEnabled()) { SyncedFolderProvider syncedFolderProvider = - new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences); + new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences, clock); syncedFolderProvider.updateAutoUploadPaths(mContext); } } - private static void splitOutAutoUploadEntries() { + private static void splitOutAutoUploadEntries(Clock clock) { Context context = getAppContext(); AppPreferences preferences = AppPreferencesImpl.fromContext(context); if (!preferences.isAutoUploadSplitEntriesEnabled()) { @@ -705,7 +712,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { Log_OC.i(TAG, "Migrate synced_folders records for image/video split"); ContentResolver contentResolver = context.getContentResolver(); - SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, preferences); + SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, preferences, clock); final List imageMediaFolders = MediaProvider.getImageFolders(contentResolver, 1, null, true); final List videoMediaFolders = MediaProvider.getVideoFolders(contentResolver, 1, null, true); @@ -751,12 +758,12 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { } } - private static void initiateExistingAutoUploadEntries() { + private static void initiateExistingAutoUploadEntries(Clock clock) { new Thread(() -> { AppPreferences preferences = AppPreferencesImpl.fromContext(getAppContext()); if (!preferences.isAutoUploadInitialized()) { SyncedFolderProvider syncedFolderProvider = - new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences); + new SyncedFolderProvider(MainApp.getAppContext().getContentResolver(), preferences, clock); for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) { if (syncedFolder.isEnabled()) { @@ -770,7 +777,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { }).start(); } - private static void cleanOldEntries() { + private static void cleanOldEntries(Clock clock) { // previous versions of application created broken entries in the SyncedFolderProvider // database, and this cleans all that and leaves 1 (newest) entry per synced folder @@ -779,7 +786,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector { if (!preferences.isLegacyClean()) { SyncedFolderProvider syncedFolderProvider = - new SyncedFolderProvider(context.getContentResolver(), preferences); + new SyncedFolderProvider(context.getContentResolver(), preferences, clock); List syncedFolderList = syncedFolderProvider.getSyncedFolders(); Map, Long> syncedFolders = new HashMap<>(); diff --git a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java index b7dd75d967..8a66a4058a 100644 --- a/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java +++ b/src/main/java/com/owncloud/android/datamodel/SyncedFolderProvider.java @@ -38,8 +38,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Observable; -import javax.inject.Inject; - import androidx.annotation.NonNull; import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; @@ -50,22 +48,22 @@ import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; public class SyncedFolderProvider extends Observable { static private final String TAG = SyncedFolderProvider.class.getSimpleName(); - private ContentResolver mContentResolver; - private AppPreferences preferences; - - @Inject protected Clock clock; + private final ContentResolver mContentResolver; + private final AppPreferences preferences; + private final Clock clock; /** * constructor. * * @param contentResolver the ContentResolver to work with. */ - public SyncedFolderProvider(ContentResolver contentResolver, AppPreferences preferences) { + public SyncedFolderProvider(ContentResolver contentResolver, AppPreferences preferences, Clock clock) { if (contentResolver == null) { throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver"); } mContentResolver = contentResolver; this.preferences = preferences; + this.clock = clock; } /** diff --git a/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java b/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java index 77f1535f07..311d45240a 100644 --- a/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java +++ b/src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.Intent; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.jobs.BackgroundJobManager; import com.nextcloud.client.network.ConnectivityService; @@ -53,6 +54,7 @@ public class BootupBroadcastReceiver extends BroadcastReceiver { @Inject ConnectivityService connectivityService; @Inject PowerManagementService powerManagementService; @Inject BackgroundJobManager backgroundJobManager; + @Inject Clock clock; /** * Receives broadcast intent reporting that the system was just boot up. @@ -69,7 +71,8 @@ public class BootupBroadcastReceiver extends BroadcastReceiver { accountManager, connectivityService, powerManagementService, - backgroundJobManager); + backgroundJobManager, + clock); MainApp.initContactsBackup(accountManager); } else { Log_OC.d(TAG, "Getting wrong intent: " + intent.getAction()); diff --git a/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java b/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java index 9065d9a0b6..a63793d129 100644 --- a/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java +++ b/src/main/java/com/owncloud/android/jobs/AccountRemovalJob.java @@ -38,6 +38,7 @@ import com.evernote.android.job.Job; import com.evernote.android.job.util.support.PersistableBundleCompat; import com.google.gson.Gson; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.preferences.AppPreferencesImpl; import com.owncloud.android.MainApp; import com.owncloud.android.R; @@ -80,12 +81,14 @@ public class AccountRemovalJob extends Job implements AccountManagerCallback syncedFolders = syncedFolderProvider.getSyncedFolders(); List syncedFolderIds = new ArrayList<>(); diff --git a/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java b/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java index 0a254580a0..5c7a9771aa 100644 --- a/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java +++ b/src/main/java/com/owncloud/android/jobs/FilesSyncJob.java @@ -34,6 +34,7 @@ import android.text.TextUtils; import com.evernote.android.job.Job; import com.evernote.android.job.util.support.PersistableBundleCompat; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.preferences.AppPreferences; @@ -76,22 +77,25 @@ public class FilesSyncJob extends Job { public static final String OVERRIDE_POWER_SAVING = "overridePowerSaving"; private static final String WAKELOCK_TAG_SEPARATION = ":"; - private UserAccountManager userAccountManager; - private AppPreferences preferences; - private UploadsStorageManager uploadsStorageManager; - private ConnectivityService connectivityService; - private PowerManagementService powerManagementService; + private final UserAccountManager userAccountManager; + private final AppPreferences preferences; + private final UploadsStorageManager uploadsStorageManager; + private final ConnectivityService connectivityService; + private final PowerManagementService powerManagementService; + private final Clock clock; FilesSyncJob(final UserAccountManager userAccountManager, final AppPreferences preferences, final UploadsStorageManager uploadsStorageManager, final ConnectivityService connectivityService, - final PowerManagementService powerManagementService) { + final PowerManagementService powerManagementService, + final Clock clock) { this.userAccountManager = userAccountManager; this.preferences = preferences; this.uploadsStorageManager = uploadsStorageManager; this.connectivityService = connectivityService; this.powerManagementService = powerManagementService; + this.clock = clock; } @NonNull @@ -126,13 +130,12 @@ public class FilesSyncJob extends Job { userAccountManager, connectivityService, powerManagementService); - FilesSyncHelper.insertAllDBEntries(preferences, skipCustom); + FilesSyncHelper.insertAllDBEntries(preferences, clock, skipCustom); // Create all the providers we'll need final ContentResolver contentResolver = context.getContentResolver(); final FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver); - SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, - preferences); + SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, preferences, clock); Locale currentLocale = context.getResources().getConfiguration().locale; SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale); diff --git a/src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java b/src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java index 43e0736088..e421b9365a 100644 --- a/src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java +++ b/src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java @@ -39,6 +39,7 @@ import android.text.TextUtils; import com.evernote.android.job.Job; import com.google.gson.Gson; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.client.preferences.AppPreferencesImpl; import com.owncloud.android.R; @@ -74,11 +75,13 @@ public class MediaFoldersDetectionJob extends Job { private static final String DISABLE_DETECTION_CLICK = "DISABLE_DETECTION_CLICK"; - private UserAccountManager userAccountManager; - private Random randomId = new Random(); + private final UserAccountManager userAccountManager; + private final Clock clock; + private final Random randomId = new Random(); - MediaFoldersDetectionJob(UserAccountManager accountManager) { + MediaFoldersDetectionJob(UserAccountManager accountManager, Clock clock) { this.userAccountManager = accountManager; + this.clock = clock; } @NonNull @@ -88,7 +91,8 @@ public class MediaFoldersDetectionJob extends Job { ContentResolver contentResolver = context.getContentResolver(); ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(contentResolver); SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, - AppPreferencesImpl.fromContext(context)); + AppPreferencesImpl.fromContext(context), + clock); Gson gson = new Gson(); String arbitraryDataString; MediaFoldersModel mediaFoldersModel; diff --git a/src/main/java/com/owncloud/android/jobs/NCJobCreator.java b/src/main/java/com/owncloud/android/jobs/NCJobCreator.java index c0894a59e1..010ae26689 100644 --- a/src/main/java/com/owncloud/android/jobs/NCJobCreator.java +++ b/src/main/java/com/owncloud/android/jobs/NCJobCreator.java @@ -29,6 +29,7 @@ import android.content.Context; import com.evernote.android.job.Job; import com.evernote.android.job.JobCreator; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.preferences.AppPreferences; @@ -48,6 +49,7 @@ public class NCJobCreator implements JobCreator { private final UploadsStorageManager uploadsStorageManager; private final ConnectivityService connectivityService; private final PowerManagementService powerManagementService; + private final Clock clock; public NCJobCreator( Context context, @@ -55,7 +57,8 @@ public class NCJobCreator implements JobCreator { AppPreferences preferences, UploadsStorageManager uploadsStorageManager, ConnectivityService connectivityServices, - PowerManagementService powerManagementService + PowerManagementService powerManagementService, + Clock clock ) { this.context = context; this.accountManager = accountManager; @@ -63,6 +66,7 @@ public class NCJobCreator implements JobCreator { this.uploadsStorageManager = uploadsStorageManager; this.connectivityService = connectivityServices; this.powerManagementService = powerManagementService; + this.clock = clock; } @Override @@ -73,19 +77,20 @@ public class NCJobCreator implements JobCreator { case ContactsImportJob.TAG: return new ContactsImportJob(); case AccountRemovalJob.TAG: - return new AccountRemovalJob(uploadsStorageManager, accountManager); + return new AccountRemovalJob(uploadsStorageManager, accountManager, clock); case FilesSyncJob.TAG: return new FilesSyncJob(accountManager, preferences, uploadsStorageManager, connectivityService, - powerManagementService); + powerManagementService, + clock); case OfflineSyncJob.TAG: return new OfflineSyncJob(accountManager, connectivityService, powerManagementService); case NotificationJob.TAG: return new NotificationJob(context, accountManager); case MediaFoldersDetectionJob.TAG: - return new MediaFoldersDetectionJob(accountManager); + return new MediaFoldersDetectionJob(accountManager, clock); default: return null; } diff --git a/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java b/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java index 07ec55dc45..16724bf664 100644 --- a/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java +++ b/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.java @@ -225,7 +225,7 @@ public class SyncedFoldersActivity extends FileActivity implements SyncedFolderA final int gridWidth = getResources().getInteger(R.integer.media_grid_width); boolean lightVersion = getResources().getBoolean(R.bool.syncedFolder_light); mAdapter = new SyncedFolderAdapter(this, clock, gridWidth, this, lightVersion); - mSyncedFolderProvider = new SyncedFolderProvider(getContentResolver(), preferences); + mSyncedFolderProvider = new SyncedFolderProvider(getContentResolver(), preferences, clock); final GridLayoutManager lm = new GridLayoutManager(this, gridWidth); mAdapter.setLayoutManager(lm); diff --git a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index 351abe46b2..a729eebf9a 100644 --- a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -35,6 +35,7 @@ import android.util.Log; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; import com.nextcloud.client.account.UserAccountManager; +import com.nextcloud.client.core.Clock; import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.jobs.BackgroundJobManager; import com.nextcloud.client.network.ConnectivityService; @@ -126,11 +127,10 @@ public final class FilesSyncHelper { } } - public static void insertAllDBEntries(AppPreferences preferences, boolean skipCustom) { + public static void insertAllDBEntries(AppPreferences preferences, Clock clock, boolean skipCustom) { final Context context = MainApp.getAppContext(); final ContentResolver contentResolver = context.getContentResolver(); - SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, - preferences); + SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver, preferences, clock); for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) { if (syncedFolder.isEnabled() && (MediaFolderType.CUSTOM != syncedFolder.getType() || !skipCustom)) { diff --git a/src/test/java/com/nextcloud/client/jobs/BackgroundJobFactoryTest.kt b/src/test/java/com/nextcloud/client/jobs/BackgroundJobFactoryTest.kt index 826d5a8621..23a5f88eed 100644 --- a/src/test/java/com/nextcloud/client/jobs/BackgroundJobFactoryTest.kt +++ b/src/test/java/com/nextcloud/client/jobs/BackgroundJobFactoryTest.kt @@ -24,6 +24,7 @@ import android.content.ContentResolver import android.content.Context import android.os.Build import androidx.work.WorkerParameters +import com.nextcloud.client.core.Clock import com.nextcloud.client.device.DeviceInfo import com.nextcloud.client.device.PowerManagementService import com.nextcloud.client.preferences.AppPreferences @@ -59,6 +60,9 @@ class BackgroundJobFactoryTest { @Mock private lateinit var deviceInfo: DeviceInfo + @Mock + private lateinit var clock: Clock + private lateinit var factory: BackgroundJobFactory @Before @@ -67,6 +71,7 @@ class BackgroundJobFactoryTest { factory = BackgroundJobFactory( preferences, contentResolver, + clock, powerManagementService, Provider { backgroundJobManager }, deviceInfo From 65da616f812760362ecc0b0e02b288188babe8cc Mon Sep 17 00:00:00 2001 From: Alice Gaudon Date: Fri, 15 Nov 2019 07:56:07 +0100 Subject: [PATCH 4/4] FilesSyncHelper: use our own logging framework Signed-off-by: Alice Gaudon --- src/main/java/com/owncloud/android/utils/FilesSyncHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index a729eebf9a..e2074b3139 100644 --- a/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -30,7 +30,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; -import android.util.Log; import com.evernote.android.job.JobManager; import com.evernote.android.job.JobRequest; @@ -50,6 +49,7 @@ import com.owncloud.android.db.OCUpload; import com.owncloud.android.files.services.FileUploader; import com.owncloud.android.jobs.FilesSyncJob; import com.owncloud.android.jobs.OfflineSyncJob; +import com.owncloud.android.lib.common.utils.Log_OC; import org.lukhnos.nnio.file.FileVisitResult; import org.lukhnos.nnio.file.Files; @@ -121,7 +121,7 @@ public final class FilesSyncHelper { } }); } catch (IOException e) { - Log.e(TAG, "Something went wrong while indexing files for auto upload " + e.getLocalizedMessage()); + Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e); } } }