diff --git a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java index c909dc6dc79b200e126181498f7ae583a6e5d84e..946e5c46b05e35176ce7c8e11dc650c684cbed7a 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -39,35 +39,19 @@ import java.text.StringCharacterIterator; import java.util.Locale; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; import foundation.e.drive.R; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.work.AccountUserInfoWorker; -import foundation.e.drive.work.CreateRemoteFolderWorker; -import foundation.e.drive.work.FirstStartWorker; import foundation.e.drive.work.FullScanWorker; +import foundation.e.drive.work.WorkRequestFactory; import static foundation.e.drive.utils.AppConstants.MEDIASYNC_PROVIDER_AUTHORITY; import static foundation.e.drive.utils.AppConstants.METERED_NETWORK_ALLOWED_AUTHORITY; import static foundation.e.drive.utils.AppConstants.SETTINGSYNC_PROVIDER_AUTHORITY; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_ENABLE; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_ID; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LAST_ETAG; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LAST_MODIFIED; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LIBELLE; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LOCAL_PATH; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_MEDIATYPE; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_REMOTE_PATH; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_SCAN_LOCAL; -import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_SCAN_REMOTE; import androidx.annotation.NonNull; -import androidx.work.BackoffPolicy; -import androidx.work.Constraints; -import androidx.work.Data; import androidx.work.ExistingPeriodicWorkPolicy; -import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; import androidx.work.PeriodicWorkRequest; import androidx.work.WorkManager; @@ -323,20 +307,9 @@ public abstract class CommonUtils { * @param workManager the instance of workManager */ public static void registerPeriodicFullScanWorker(WorkManager workManager) { - final Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) - .setRequiresBatteryNotLow(true) - .build(); - - final PeriodicWorkRequest periodicFullScanRequest = - new PeriodicWorkRequest.Builder(FullScanWorker.class, - 31, TimeUnit.MINUTES, - 5, TimeUnit.MINUTES) - .setConstraints(constraints) - .addTag(AppConstants.WORK_GENERIC_TAG) - .build(); - - workManager.enqueueUniquePeriodicWork(FullScanWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.KEEP, periodicFullScanRequest); + workManager.enqueueUniquePeriodicWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingPeriodicWorkPolicy.KEEP, + WorkRequestFactory.getPeriodicWorkRequest(WorkRequestFactory.WorkType.FULL_SCAN)); } @@ -360,39 +333,16 @@ public abstract class CommonUtils { Log.e(TAG, "Can't create remote folders. List is empty"); return; } - - final Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) - .setRequiresBatteryNotLow(true) - .build(); - - final OneTimeWorkRequest getUserInfoRequest = new OneTimeWorkRequest.Builder(AccountUserInfoWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) - .setConstraints(constraints) - .build(); + + final OneTimeWorkRequest getUserInfoRequest = WorkRequestFactory.getOneTimeWorkRequest(WorkRequestFactory.WorkType.ONE_TIME_USER_INFO, null); final List workRequests = new ArrayList<>(); - for (SyncedFolder folder : syncedFolders) { - final OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder( - CreateRemoteFolderWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .setInputData(createDataFromSyncedFolder(folder)) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) - .setConstraints(constraints) - .build(); - - workRequests.add(oneTimeWorkRequest); + final OneTimeWorkRequest createRemoteFolderWorkRequest = WorkRequestFactory.getOneTimeWorkRequest(WorkRequestFactory.WorkType.CREATE_REMOTE_DIR, folder); + workRequests.add(createRemoteFolderWorkRequest); } - final OneTimeWorkRequest firstStartRequest = new OneTimeWorkRequest.Builder(FirstStartWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) - .build(); + final OneTimeWorkRequest firstStartRequest = WorkRequestFactory.getOneTimeWorkRequest(WorkRequestFactory.WorkType.FIRST_START, null); workManager.beginWith(getUserInfoRequest) .then(workRequests) @@ -401,21 +351,6 @@ public abstract class CommonUtils { } - private static Data createDataFromSyncedFolder(SyncedFolder folder) { - return new Data.Builder() - .putInt(DATA_KEY_ID, folder.getId()) - .putString(DATA_KEY_LIBELLE, folder.getLibelle()) - .putString(DATA_KEY_LOCAL_PATH, folder.getLocalFolder()) - .putString(DATA_KEY_REMOTE_PATH, folder.getRemoteFolder()) - .putString(DATA_KEY_LAST_ETAG, folder.getLastEtag()) - .putLong(DATA_KEY_LAST_MODIFIED, folder.getLastModified()) - .putBoolean(DATA_KEY_SCAN_LOCAL, folder.isScanLocal()) - .putBoolean(DATA_KEY_SCAN_REMOTE, folder.isScanRemote()) - .putBoolean(DATA_KEY_ENABLE, folder.isEnabled()) - .putBoolean(DATA_KEY_MEDIATYPE, folder.isMediaType()) - .build(); - } - public static void createNotificationChannel(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { final CharSequence name = context.getString(R.string.notif_channel_name); @@ -446,18 +381,8 @@ public abstract class CommonUtils { * @param workManager */ public static void registerPeriodicUserInfoChecking(WorkManager workManager) { - final Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - final PeriodicWorkRequest periodicUserInfoScanRequest = - new PeriodicWorkRequest.Builder(AccountUserInfoWorker.class, - 30, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .setConstraints(constraints) - .build(); - - workManager.enqueueUniquePeriodicWork(AccountUserInfoWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, periodicUserInfoScanRequest); + final PeriodicWorkRequest workRequest = WorkRequestFactory.getPeriodicWorkRequest(WorkRequestFactory.WorkType.PERIODIC_USER_INFO); + workManager.enqueueUniquePeriodicWork(AccountUserInfoWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.REPLACE, workRequest); } /** diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e3daf5166b02341e8b35c5735b2656e45c5aeb38 --- /dev/null +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -0,0 +1,196 @@ +package foundation.e.drive.work; + +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_ENABLE; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_ID; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LAST_ETAG; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LAST_MODIFIED; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LIBELLE; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_LOCAL_PATH; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_MEDIATYPE; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_REMOTE_PATH; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_SCAN_LOCAL; +import static foundation.e.drive.work.CreateRemoteFolderWorker.DATA_KEY_SCAN_REMOTE; + +import androidx.annotation.Nullable; +import androidx.work.BackoffPolicy; +import androidx.work.Constraints; +import androidx.work.Data; +import androidx.work.NetworkType; +import androidx.work.OneTimeWorkRequest; +import androidx.work.PeriodicWorkRequest; + +import java.security.InvalidParameterException; +import java.util.concurrent.TimeUnit; + +import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.utils.AppConstants; + +public class WorkRequestFactory { + public enum WorkType { + FULL_SCAN, + PERIODIC_USER_INFO, + ONE_TIME_USER_INFO, + CREATE_REMOTE_DIR, + FIRST_START + } + + /** + * Build an instance of PeriodicWorkRequest depending of the work type specified + * @param type WorkType. Should be FULL_SCAN or PERIODIC_USER_INFO. + * If not, it will throw an InvalidParameterException + * @return Periodic WorkRequest + */ + public static PeriodicWorkRequest getPeriodicWorkRequest(WorkType type) { + switch (type) { + case FULL_SCAN: + return createPeriodicFullScanWorkRequest(); + case PERIODIC_USER_INFO: + return createPeriodicGetUserInfoWorkRequest(); + default: + throw new InvalidParameterException("Unsupported Work Type: " + type); + } + } + + /** + * Build an instance of OneTimeWorkRequest depending of the work type specified. + * @param type Should be ONE_TIME_USER_INFO, or FIRST_START, or CREATE_REMOTE_DIR + * or it will throw InvalidParameterException + * @param syncedFolder this parameter is required for CREATE_REMOTE_DIR work type. If null it will throw an NPE. + * @return OneTimeWorkRequest's instance. + */ + public static OneTimeWorkRequest getOneTimeWorkRequest(WorkType type, @Nullable SyncedFolder syncedFolder) { + switch (type) { + case ONE_TIME_USER_INFO: + return createOneTimeGetUserInfoWorkRequest(); + case FIRST_START: + return createOneTimeFirstStartWorkRequest(); + case CREATE_REMOTE_DIR: + if (syncedFolder == null) throw new NullPointerException("Synced folder is null"); + return createOneTimeCreateRemoteFolderWorkRequest(syncedFolder); + default: + throw new InvalidParameterException("Unsupported Work Type: " + type); + } + } + + + /** + * Create a PeridocWorkRequest instance for + * a Full scan with constraints on network (should + * be unmetered) and battery (shouldn't be low) + * @return instance of PeriodicWorkRequest + */ + private static PeriodicWorkRequest createPeriodicFullScanWorkRequest() { + final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); + + final PeriodicWorkRequest workRequest = + new PeriodicWorkRequest.Builder(FullScanWorker.class, + 31, TimeUnit.MINUTES, + 5, TimeUnit.MINUTES) + .setConstraints(constraints) + .addTag(AppConstants.WORK_GENERIC_TAG) + .build(); + return workRequest; + } + + /** + * Create a periodic work request to get userInfo + * @return instance of PeriodicWorkRequest + */ + private static PeriodicWorkRequest createPeriodicGetUserInfoWorkRequest() { + final Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + final PeriodicWorkRequest workRequest = + new PeriodicWorkRequest.Builder(AccountUserInfoWorker.class, + 30, TimeUnit.MINUTES) + .addTag(AppConstants.WORK_GENERIC_TAG) + .setConstraints(constraints) + .build(); + return workRequest; + } + + /** + * Instanciate a OneTimeWorkRequest to retrieve user info + * @return instance of OneTimeWorkRequest + */ + private static OneTimeWorkRequest createOneTimeGetUserInfoWorkRequest() { + final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); + + final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(AccountUserInfoWorker.class) + .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .setConstraints(constraints) + .build(); + return workRequest; + } + + /** + * Create a OneTime workRequest to create a remote folder + * With constraints on network (unmetered) and battery (not low) + * @param syncedFolder SyncedFolder instance with data about folder to create + * @return Instance OneTimeWorkRequest + */ + private static OneTimeWorkRequest createOneTimeCreateRemoteFolderWorkRequest(SyncedFolder syncedFolder) { + final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); + + final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder( + CreateRemoteFolderWorker.class) + .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .setInputData(createDataFromSyncedFolder(syncedFolder)) + .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .setConstraints(constraints) + .build(); + return workRequest; + } + + /** + * Create a OneTime WorkRequest which start eDrive + * after initialization + * @return Instance of OneTimeWorkRequest + */ + private static OneTimeWorkRequest createOneTimeFirstStartWorkRequest() { + final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(FirstStartWorker.class) + .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .build(); + return workRequest; + } + + /** + * Create Constraints for unmetered network + * and battery not low + * @return instance of Constraints + */ + private static Constraints createUnmeteredNetworkAndHighBatteryConstraints() { + final Constraints constraint = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.UNMETERED) + .setRequiresBatteryNotLow(true) + .build(); + return constraint; + } + + + /** + * Parse SyncedFolder instance in Data, used as data for WorkRequest + * @param folder SyncedFolder instance + * @return Data instance + */ + private static Data createDataFromSyncedFolder(SyncedFolder folder) { + return new Data.Builder() + .putInt(DATA_KEY_ID, folder.getId()) + .putString(DATA_KEY_LIBELLE, folder.getLibelle()) + .putString(DATA_KEY_LOCAL_PATH, folder.getLocalFolder()) + .putString(DATA_KEY_REMOTE_PATH, folder.getRemoteFolder()) + .putString(DATA_KEY_LAST_ETAG, folder.getLastEtag()) + .putLong(DATA_KEY_LAST_MODIFIED, folder.getLastModified()) + .putBoolean(DATA_KEY_SCAN_LOCAL, folder.isScanLocal()) + .putBoolean(DATA_KEY_SCAN_REMOTE, folder.isScanRemote()) + .putBoolean(DATA_KEY_ENABLE, folder.isEnabled()) + .putBoolean(DATA_KEY_MEDIATYPE, folder.isMediaType()) + .build(); + } +}