diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6ba265a284592e3672280c4bdf7c0aa14a25109d..23340a40daf3f2dd49bb207dbe0b5aebb97d7a0f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: "registry.gitlab.e.foundation:5000/e/apps/docker-android-apps-cicd:latest" +image: "registry.gitlab.e.foundation:5000/e/apps/docker-android-apps-cicd:legacy" stages: - build @@ -22,4 +22,3 @@ build: paths: - app/build/outputs/apk/ expire_in: 4 weeks - diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fafd9d3fcf85537caa4988171b05acac3cedff14..52b93ca7a249cabe791b246acb8778ead1717483 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -24,9 +24,11 @@ http://www.gnu.org/licenses/gpl.html android:protectionLevel="signature" /> files; + + //private List syncedFileStatesList; + + public FileObserver(List files) { + this.files = files; + + } + + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + +// public List getSyncedFileStatesList() { +// return syncedFileStatesList; +// } +// +// public void setSyncedFileStatesList(List syncedFileStatesList) { +// this.syncedFileStatesList = syncedFileStatesList; +// } +} diff --git a/app/src/main/java/foundation/e/drive/models/SyncedFileState.java b/app/src/main/java/foundation/e/drive/models/SyncedFileState.java index 42c76a102482a4681845082e752f1edf57211f3d..3b9255be143e3b637c1686beff0ce6d5b7d4ee8e 100644 --- a/app/src/main/java/foundation/e/drive/models/SyncedFileState.java +++ b/app/src/main/java/foundation/e/drive/models/SyncedFileState.java @@ -11,12 +11,14 @@ package foundation.e.drive.models; import android.os.Parcel; import android.os.Parcelable; +import java.io.Serializable; + /** * @author Vincent Bourgmayer * Describe a file state which will be Synchronized (= Synced) or which has already been synced one times */ -public class SyncedFileState implements Parcelable { +public class SyncedFileState implements Parcelable, Serializable { protected SyncedFileState(){}; //@ToRemove. Test Only. It's to allow to make a mock SyncedFileState Class in test. diff --git a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java index 88276a6b9703b773b4bdaf40e115b3b11e4e59e0..258cf9785e05c7dcca5be7ae7a548f415f70f535 100644 --- a/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/UploadFileOperation.java @@ -24,7 +24,10 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo import java.io.File; import java.util.ArrayList; import foundation.e.drive.database.DbHelper; +import foundation.e.drive.models.FileObserver; import foundation.e.drive.models.SyncedFileState; +import foundation.e.drive.services.FileObserverService; +import foundation.e.drive.services.InitializerService; import foundation.e.drive.utils.CommonUtils; /** @@ -136,6 +139,9 @@ public class UploadFileOperation extends RemoteOperation implements ComparableOp //if upload is a success if( uploadResult.isSuccess() ){ + + FileObserverService.files.remove(file); + Object data = uploadResult.getSingleData(); if(data != null){ mSyncedState.setLastETAG((String) data); diff --git a/app/src/main/java/foundation/e/drive/receivers/ConnectivityReceiver.java b/app/src/main/java/foundation/e/drive/receivers/ConnectivityReceiver.java index 066582a49dd363e5d4c5a2b323b8eb64690d9c93..ec0dba30b91f10f141b4adade765b666afa90949 100644 --- a/app/src/main/java/foundation/e/drive/receivers/ConnectivityReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/ConnectivityReceiver.java @@ -5,46 +5,76 @@ import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Bundle; +import android.os.Handler; import android.util.Log; import java.io.IOException; +import foundation.e.drive.services.FileObserverService; +import foundation.e.drive.services.InitializerService; +import foundation.e.drive.services.MyApplication; + public class ConnectivityReceiver extends BroadcastReceiver { public static ConnectivityReceiverListener connectivityReceiverListener; + public boolean isConnected; public ConnectivityReceiver() { super(); } - public boolean isConnected(Context context) { -// String command = "ping -c 1 e.foundation"; -// return (Runtime.getRuntime().exec(command).waitFor() == 0); - try { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo netInfo = cm.getActiveNetworkInfo(); - //should check null because in airplane mode it will be null - return (netInfo != null && netInfo.isConnected()); - } catch (NullPointerException e) { - e.printStackTrace(); - return false; - } + public static boolean isConnected() { + ConnectivityManager + cm = (ConnectivityManager) MyApplication.getInstance().getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + return activeNetwork != null + && activeNetwork.isConnectedOrConnecting(); } + @Override - public void onReceive(Context context, Intent arg1) { + public void onReceive(final Context context, Intent arg1) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + final NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); + + + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + isConnected = activeNetwork != null + && activeNetwork.isConnectedOrConnecting(); + + if (connectivityReceiverListener != null) { + Log.e("TAG", "connectivityReceiverListener...." + isConnected); + connectivityReceiverListener.onNetworkConnectionChanged(isConnected); + } + + if (isConnected) { + Intent observersServiceIntent = new Intent(context, foundation.e.drive.services.ObserverService.class); + if (InitializerService.schedulerFlag) { + + context.startService(observersServiceIntent); + + } else if (InitializerService.fileObserverFlag) { + // + Bundle mBundle = new Bundle(); + mBundle.putBoolean("isFileObserverService", true); + observersServiceIntent.putExtras(mBundle); + context.startService(observersServiceIntent); + } + + InitializerService.schedulerFlag = false; + InitializerService.fileObserverFlag = false; + } + } + }, 20000); - boolean isConnected = activeNetwork != null - && activeNetwork.isConnectedOrConnecting(); - //if (connectivityReceiverListener != null) { - Log.e("TAG", "ConnectivityReceiver onNetworkConnectionChanged...." + isConnected); - //connectivityReceiverListener.onNetworkConnectionChanged(isConnected); - //} } public interface ConnectivityReceiverListener { diff --git a/app/src/main/java/foundation/e/drive/receivers/ScreenOffReceiver.java b/app/src/main/java/foundation/e/drive/receivers/ScreenOffReceiver.java index 519cd481759489e01f45d782a0ee694720672f9a..e8d29f5ee213899dd1fc5bac895a52cce4a5c6ef 100644 --- a/app/src/main/java/foundation/e/drive/receivers/ScreenOffReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/ScreenOffReceiver.java @@ -11,7 +11,11 @@ package foundation.e.drive.receivers; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.util.Log; + +import foundation.e.drive.services.FileObserverService; +import foundation.e.drive.services.InitializerService; import foundation.e.drive.services.ObserverService; import foundation.e.drive.utils.CommonUtils; @@ -38,7 +42,19 @@ public class ScreenOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "onReceive"); - // i will use this code for check file sync list + + if(FileObserverService.files.size()!=0){ + try { + Intent observersServiceIntent = new Intent(context, foundation.e.drive.services.ObserverService.class); + Bundle mBundle = new Bundle(); + mBundle.putBoolean("isFileObserverService", true); + observersServiceIntent.putExtras(mBundle); + context.startService(observersServiceIntent); + }catch (Exception exception){ + exception.printStackTrace(); + } + } + /*String intentAction = intent.getAction(); if(intentAction == null){ diff --git a/app/src/main/java/foundation/e/drive/services/FileObserverService.java b/app/src/main/java/foundation/e/drive/services/FileObserverService.java index 964fe206b7cd220036261c42b8bd0d8b04887164..ea3cc29b8596110e7ceff1f3588fd0aef69429cd 100644 --- a/app/src/main/java/foundation/e/drive/services/FileObserverService.java +++ b/app/src/main/java/foundation/e/drive/services/FileObserverService.java @@ -5,6 +5,7 @@ import android.app.Service; import android.content.Intent; import android.os.AsyncTask; import android.os.Build; +import android.os.Bundle; import android.os.Environment; import android.os.FileObserver; @@ -16,14 +17,21 @@ import android.support.annotation.Nullable; import android.util.Log; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import foundation.e.drive.receivers.ConnectivityReceiver; +import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.RecursiveFileObserver; -public class FileObserverService extends Service { +public class FileObserverService extends Service { + + private final static String TAG = FileObserverService.class.getSimpleName(); RecursiveFileObserver mFileObserver = null; private int observerFlag=-1; + public static List files=new ArrayList<>(); @Override @@ -53,18 +61,33 @@ public class FileObserverService extends Service { //Modify =2, create =256, delete =512, movedTo =128 if(event== FileObserver.CREATE || event==FileObserver.MODIFY || event== FileObserver.DELETE || event ==FileObserver.MOVED_TO){ - Log.d("OnEvent", "...Event ..." + event+"...file ..." + file); + Log.i(TAG, "...Event ..." + event+"...file ..." + file); + + Log.e("TAG", "file.isDirectory() ...."+file+"......"+file.isDirectory()); + + if(!file.isDirectory()){ + if(!files.contains(file)){ - try - { - if(observerFlag == -1){ - new AsyncTaskRunner().execute(""); + files.add(file); + } + if(!ConnectivityReceiver.isConnected()){ + InitializerService.fileObserverFlag=true; + } + try + { + if(observerFlag == -1){ + new AsyncTaskRunner().execute(""); + } + } + catch (Exception e) + { + e.printStackTrace(); } } - catch (Exception e) - { - e.printStackTrace(); - } + + + + } } @@ -90,7 +113,7 @@ public class FileObserverService extends Service { @Override public void onTaskRemoved(Intent rootIntent) { - Log.d("TAG", "............onTaskRemoved"); + Log.d(TAG, "............onTaskRemoved"); super.onTaskRemoved(rootIntent); Intent intent = new Intent(this, InitializerService.class); this.startActivity(intent); @@ -108,23 +131,27 @@ public class FileObserverService extends Service { @Override protected void onPostExecute(String s) { super.onPostExecute(s); - // Log.d("onPostExecute", "...ObserverService Intent...post Execute " ); - - final Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - @Override - public void run() { - // Log.e("onPostExecute", "...ObserverService Intent..." ); - // Do something after 20s = 20000ms - Intent observersServiceIntent = new Intent(getApplicationContext(), foundation.e.drive.services.ObserverService.class); - startService(observersServiceIntent); - - observerFlag=-1; + try { + Log.e("Tag", "onPostExecute.........."); + + for(File f:files){ + Log.e("TAG", "...........file name in post execute.."+f.getAbsolutePath()); } - }, 20000); + + Intent observersServiceIntent = new Intent(getApplicationContext(), foundation.e.drive.services.ObserverService.class); + Bundle mBundle = new Bundle(); + mBundle.putBoolean("isFileObserverService", true); + mBundle.putByteArray("fileObserverObject", CommonUtils.convertToBytes(new foundation.e.drive.models.FileObserver(files))); + observersServiceIntent.putExtras(mBundle); + startService(observersServiceIntent); + }catch (Exception exception){ + exception.printStackTrace(); + } + observerFlag=-1; } + } diff --git a/app/src/main/java/foundation/e/drive/services/InitializerService.java b/app/src/main/java/foundation/e/drive/services/InitializerService.java index ad556cea4a7b16a8c9aef74026eba249ed2ae874..05fe20e9cbd8dbf31ec9f548ab9393262073cd2c 100644 --- a/app/src/main/java/foundation/e/drive/services/InitializerService.java +++ b/app/src/main/java/foundation/e/drive/services/InitializerService.java @@ -28,6 +28,7 @@ import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -61,6 +62,10 @@ public class InitializerService extends Service private int restartFolderCreationCounter =0; private ConnectivityReceiver connectivityReceiver; + // public static List files=new ArrayList<>(); + public static boolean schedulerFlag=false; + public static boolean fileObserverFlag=false; + @Override public void onCreate() { Log.i(TAG, "onCreate()"); @@ -296,8 +301,8 @@ public class InitializerService extends Service .apply(); //all folder have been created - //JobUtils.stopScheduledJob(appContext, JobUtils.InitializerJobId); - // JobUtils.scheduleScannerJob(appContext); + JobUtils.stopScheduledJob(appContext, JobUtils.InitializerJobId); + JobUtils.scheduleScannerJob(appContext); Log.d(TAG, "RegisterReceiver: screenOffReceiver"); IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); @@ -305,8 +310,8 @@ public class InitializerService extends Service getApplicationContext().registerReceiver(ScreenOffReceiver.getInstance(), filter); //Immediatly start ObserverService to not have to wait 30 minutes. -// Intent observersServiceIntent = new Intent(getApplicationContext(), foundation.e.drive.services.ObserverService.class); -// startService(observersServiceIntent); + Intent observersServiceIntent = new Intent(getApplicationContext(), foundation.e.drive.services.ObserverService.class); + startService(observersServiceIntent); //start FileObserverService startService(new Intent(this, FileObserverService.class)); diff --git a/app/src/main/java/foundation/e/drive/services/MyApplication.java b/app/src/main/java/foundation/e/drive/services/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..79ae6d83d3d151f591cdc38464ac92dec0636d5a --- /dev/null +++ b/app/src/main/java/foundation/e/drive/services/MyApplication.java @@ -0,0 +1,25 @@ +package foundation.e.drive.services; + +import android.app.Application; + +import foundation.e.drive.receivers.ConnectivityReceiver; + +public class MyApplication extends Application { + + private static MyApplication mInstance; + + @Override + public void onCreate() { + super.onCreate(); + + mInstance = this; + } + + public static synchronized MyApplication getInstance() { + return mInstance; + } + + public void setConnectivityListener(ConnectivityReceiver.ConnectivityReceiverListener listener) { + ConnectivityReceiver.connectivityReceiverListener = listener; + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/services/ObserverService.java b/app/src/main/java/foundation/e/drive/services/ObserverService.java index dfd2873ebef992f461c2e242e31883bf3dd283f5..59ac358239e455db3b9d9eaf59e01bb9387da14e 100644 --- a/app/src/main/java/foundation/e/drive/services/ObserverService.java +++ b/app/src/main/java/foundation/e/drive/services/ObserverService.java @@ -15,18 +15,21 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Parcelable; import android.provider.MediaStore; import android.support.annotation.Nullable; import android.util.Log; + import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.files.model.RemoteFile; + import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; @@ -40,6 +43,7 @@ import foundation.e.drive.database.DbHelper; import foundation.e.drive.fileFilters.CrashlogsFileFilter; import foundation.e.drive.fileFilters.FileFilterFactory; import foundation.e.drive.fileFilters.OnlyFileFilter; +import foundation.e.drive.models.FileObserver; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.operations.DownloadFileOperation; @@ -60,7 +64,7 @@ import static foundation.e.drive.utils.AppConstants.INITIALIZATION_HAS_BEEN_DONE * @author Vincent Bourgmayer * This service look for remote or looale file to synchronize */ -public class ObserverService extends Service implements OnRemoteOperationListener{ +public class ObserverService extends Service implements OnRemoteOperationListener { private final static String TAG = ObserverService.class.getSimpleName(); private final static int INTERSYNC_MINIMUM_DELAY = 900000; // min delay between two sync in ms. @@ -69,18 +73,31 @@ public class ObserverService extends Service implements OnRemoteOperationListene private int initialFolderCounter; private Account mAccount; private HashMap operationsForIntent; + private Boolean isFileObserverService = false; + private FileObserver fileObserverObject; + // private foundation.e.drive.models.FileObserver fileObserverObject; /* Lifecycle Methods */ @Override - public void onDestroy(){ + public void onDestroy() { Log.i(TAG, "onDestroy()"); super.onDestroy(); this.mSyncedFolders = null; } - + @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.i(TAG, "onStartCommand("+startId+")"); + Log.i(TAG, "onStartCommand(" + startId + ")"); + + try { + Bundle bundle = intent.getExtras(); + if (null != bundle) { + isFileObserverService = bundle.getBoolean("isFileObserverService"); + fileObserverObject = (foundation.e.drive.models.FileObserver) CommonUtils.convertFromBytes(bundle.getByteArray("fileObserverObject")); + } + } catch (Exception ex) { + ex.printStackTrace(); + } CommonUtils.setServiceUnCaughtExceptionHandler(this); @@ -91,14 +108,14 @@ public class ObserverService extends Service implements OnRemoteOperationListene initialFolderCounter = prefs.getInt(AppConstants.INITIALFOLDERS_NUMBER, 0); // Check if account is invalid - if(this.mAccount == null){ + if (this.mAccount == null) { Log.w(TAG, "No account registered"); JobUtils.stopScheduledJob(this, JobUtils.ScannerJobId); //If no account return super.onStartCommand(intent, flags, startId); } //check if user have disable eDrive's sync in account's settings - if(!CommonUtils.isMediaSyncEnabled(mAccount) && !CommonUtils.isSettingsSyncEnabled(mAccount) ){ + if (!CommonUtils.isMediaSyncEnabled(mAccount) && !CommonUtils.isSettingsSyncEnabled(mAccount)) { Log.w(TAG, "eDrive syncing has been disabled in /e/ account's settings"); return super.onStartCommand(intent, flags, startId); } @@ -108,19 +125,19 @@ public class ObserverService extends Service implements OnRemoteOperationListene Log.w(TAG, "Initialization hasn't been done"); Intent initializerIntent = new Intent(this, InitializerService.class); startService(initializerIntent); - return super.onStartCommand( intent, flags, startId ); + return super.onStartCommand(intent, flags, startId); } //Check this service isn't already working - if(isWorking){ + if (isWorking) { Log.w(TAG, "ObserverService is already working"); - return super.onStartCommand(intent,flags,startId); + return super.onStartCommand(intent, flags, startId); } //check OperationManagerService isn't working - if(prefs.getBoolean(AppConstants.KEY_OMS_IS_WORKING, false)){ + if (prefs.getBoolean(AppConstants.KEY_OMS_IS_WORKING, false)) { Log.w(TAG, "OperationManagerService is still performing some operation"); - return super.onStartCommand(intent,flags, startId); + return super.onStartCommand(intent, flags, startId); } //Check a minimum delay has been respected between two start. @@ -136,19 +153,20 @@ public class ObserverService extends Service implements OnRemoteOperationListene //check for the case where intent has been launched by initializerService if (!CommonUtils.haveNetworkConnexion(this)) { Log.w(TAG, "There is no Internet connexion."); - return super.onStartCommand( intent, flags, startId ); + return super.onStartCommand(intent, flags, startId); } this.operationsForIntent = new HashMap<>(); begin(); - return super.onStartCommand( intent, flags, startId ); + return super.onStartCommand(intent, flags, startId); } /* Common methods */ + /** * Start to bind this service to OperationManagerService or start scan if binding is already set. * Method to factorise code that is called from different place */ - private void begin(){ + private void begin() { Log.i(TAG, "begin()"); this.isWorking = true; clearCachedFile(); @@ -160,7 +178,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene * This method remove all the crash-logs file * in external dir that are 10 days or more old. */ - private void deleteOldestCrashlogs(){ + private void deleteOldestCrashlogs() { Log.i(TAG, "deleteOldestCrashLogs()"); File[] fileToRemove = getExternalFilesDir(ServiceExceptionHandler.CRASH_LOG_FOLDER) .listFiles(new CrashlogsFileFilter()); @@ -170,48 +188,50 @@ public class ObserverService extends Service implements OnRemoteOperationListene try { file.delete(); ++counter; - }catch (SecurityException e){ + } catch (SecurityException e) { e.printStackTrace(); } } - Log.d(TAG, counter+" old crashlogs file.s deleted"); + Log.d(TAG, counter + " old crashlogs file.s deleted"); } /** * Clear cached file unused: * remove each cached file which isn't in OperationManagerService.lockedSyncedFileState(); + * * @TODO rewrite this method! */ - private void clearCachedFile(){ + private void clearCachedFile() { Log.i(TAG, "clearCachedFile()"); //Load subfiles into external cache file - File[] fileArray = this.getApplicationContext().getExternalCacheDir().listFiles(new OnlyFileFilter() ); - if(fileArray != null) { + File[] fileArray = this.getApplicationContext().getExternalCacheDir().listFiles(new OnlyFileFilter()); + if (fileArray != null) { boolean toRemove; for (int i = -1, size = fileArray.length; ++i < size; ) { toRemove = true; if (toRemove) { boolean deleteResult = fileArray[i].delete(); - Log.v(TAG+"_handleCachedFile()", "Deletion of cached file: " + deleteResult); + Log.v(TAG + "_handleCachedFile()", "Deletion of cached file: " + deleteResult); } } - }else{ - Log.e(TAG+"_handleCachedFile()", "Array of cached file is null"); + } else { + Log.e(TAG + "_handleCachedFile()", "Array of cached file is null"); } } /** * Start scanning job * Load operation from DB + * * @param remote if true looks for remote change. If false, look for local change. **/ private void startScan(boolean remote) { - Log.i(TAG, "startScan("+remote+")"); + Log.i(TAG, "startScan(" + remote + ")"); this.mSyncedFolders = loadSyncedFolders(); - if(mSyncedFolders.isEmpty() ){ + if (mSyncedFolders.isEmpty()) { Log.w(TAG, "List of synced folders is empty"); this.stopSelf(); return; @@ -219,7 +239,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene //Display content of SyncedFolderList StringBuilder logFolderList = new StringBuilder("SyncedFolder: libelle, localFolder, lastmodified, scanLocal, id :"); - for(SyncedFolder sf : mSyncedFolders){ + for (SyncedFolder sf : mSyncedFolders) { logFolderList.append("\n").append(sf.getLibelle()).append(", ").append(sf.getLocalFolder()).append(", ").append(sf.getLastModified()).append(", ").append(sf.isScanLocal()).append(", ").append(sf.getId()); } Log.d(TAG, logFolderList.toString()); @@ -231,52 +251,68 @@ public class ObserverService extends Service implements OnRemoteOperationListene Log.d(TAG, "Going to scan remote files"); ListFileRemoteOperation loadOperation = new ListFileRemoteOperation(this.mSyncedFolders, this, this.initialFolderCounter); loadOperation.execute(client, this, new Handler()); - } catch (IllegalArgumentException e){ - Log.e(TAG, e.toString() ); + } catch (IllegalArgumentException e) { + Log.e(TAG, e.toString()); } - }else{ + } else { Log.w(TAG, "OwnCloudClient is null"); return; } } else { - scanLocalFiles(); + if (isFileObserverService && null != fileObserverObject) { + + Log.e("TAG", "ObserverService..isFileObserverService...." + isFileObserverService); + + // List files = fileObserverObject.getFiles(); + DbHelper.updateSyncedFolders(mSyncedFolders, this); //@ToDo: maybe do this when all contents will be synced. + + List syncedFileStates = DbHelper.getSyncedFileStatesByFolders(this, + getIdsFromFolderToScan()); + + if (!syncedFileStates.isEmpty() || !fileObserverObject.getFiles().isEmpty()) { + handleLocalFiles(fileObserverObject.getFiles(), syncedFileStates); + } + // handleLocalFiles(fileObserverObject.getFiles(), fileObserverObject.getSyncedFileStatesList()); + + } else { + scanLocalFiles(); + } + } } /** * Get list of synced folder depending of if media and setting sync are enabled. + * * @return */ - private List loadSyncedFolders(){ + private List loadSyncedFolders() { boolean mediaSyncEnabled = CommonUtils.isMediaSyncEnabled(mAccount); boolean settingsSyncedEnabled = CommonUtils.isSettingsSyncEnabled(mAccount); - if(mediaSyncEnabled && settingsSyncedEnabled){ + if (mediaSyncEnabled && settingsSyncedEnabled) { return DbHelper.getAllSyncedFolders(this); - }else if(mediaSyncEnabled){ + } else if (mediaSyncEnabled) { return DbHelper.getSyncedFolderList(this, true); - }else if(settingsSyncedEnabled){ + } else if (settingsSyncedEnabled) { return DbHelper.getSyncedFolderList(this, false); - }else{ + } else { return new ArrayList(); } - } - - - - + } /** * Handle end of remote Operation + * * @param operation The RemoteOperation which ends and call this methods - * @param result The result of the remote Operation + * @param result The result of the remote Operation */ @Override - public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result ) { - Log.i( TAG, "onRemoteOperationFinish()" ); - if( operation instanceof ListFileRemoteOperation) { + public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { + Log.i(TAG, "onRemoteOperationFinish()"); + if (operation instanceof ListFileRemoteOperation) { if (result.isSuccess()) { List resultDatas = result.getData(); if (resultDatas != null) { @@ -296,18 +332,18 @@ public class ObserverService extends Service implements OnRemoteOperationListene } this.startScan(false); - Log.v(TAG, "operationsForIntent contains "+ operationsForIntent.size() ); + Log.v(TAG, "operationsForIntent contains " + operationsForIntent.size()); //After everything has been scanned. Send Intent to OperationmanagerService with data in bundle - if(operationsForIntent != null && !operationsForIntent.isEmpty()) { + if (operationsForIntent != null && !operationsForIntent.isEmpty()) { Intent OMSIntent = new Intent(this, OperationManagerService.class); - for(Map.Entry entry: operationsForIntent.entrySet()){ - OMSIntent.putExtra(entry.getKey()+"", entry.getValue()); + for (Map.Entry entry : operationsForIntent.entrySet()) { + OMSIntent.putExtra(entry.getKey() + "", entry.getValue()); } OMSIntent.putExtra("account", mAccount); startService(OMSIntent); - }else{ + } else { Log.w(TAG, "There is no file to sync."); getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) .edit() @@ -323,14 +359,15 @@ public class ObserverService extends Service implements OnRemoteOperationListene /** * Method to get Id of SyncedFolder to scan + * * @return List id of SyncedFolder to scan */ - private List getIdsFromFolderToScan(){ + private List getIdsFromFolderToScan() { List result = new ArrayList<>(); - for(int i = -1, size = this.mSyncedFolders.size(); ++i < size;){ + for (int i = -1, size = this.mSyncedFolders.size(); ++i < size; ) { SyncedFolder syncedFolder = this.mSyncedFolders.get(i); - if(syncedFolder.isToSync() ){ - result.add( (long) syncedFolder.getId() ); + if (syncedFolder.isToSync()) { + result.add((long) syncedFolder.getId()); } } return result; @@ -340,15 +377,16 @@ public class ObserverService extends Service implements OnRemoteOperationListene /** * decide what to do with remote files and decide - * @param remoteFiles Remote Files to inspect + * + * @param remoteFiles Remote Files to inspect * @param syncedFileStates SyncedFileState to inspect */ - private void handleRemoteFiles(List remoteFiles, List syncedFileStates ){ + private void handleRemoteFiles(List remoteFiles, List syncedFileStates) { Log.i(TAG, "handleRemoteFiles()"); Log.d(TAG, "start to loop through remoteFiles"); ListIterator syncedFileListIterator; - for( int i =-1, size = remoteFiles.size(); ++i < size; ){ + for (int i = -1, size = remoteFiles.size(); ++i < size; ) { final RemoteFile remoteFile = (RemoteFile) remoteFiles.get(i); final String remoteFilePath = remoteFile.getRemotePath(); @@ -357,29 +395,29 @@ public class ObserverService extends Service implements OnRemoteOperationListene boolean correspondant_found = false; syncedFileListIterator = syncedFileStates.listIterator(); //reset listiterator - Log.d( TAG, "start to loop through syncedFileList for: "+remoteFilePath); + Log.d(TAG, "start to loop through syncedFileList for: " + remoteFilePath); - while( syncedFileListIterator.hasNext() ){ + while (syncedFileListIterator.hasNext()) { SyncedFileState syncedFileState = syncedFileListIterator.next(); //ignore hidden file from db - if(syncedFileState.isMediaType() && syncedFileState.getName().startsWith(".")){ + if (syncedFileState.isMediaType() && syncedFileState.getName().startsWith(".")) { syncedFileListIterator.remove(); continue; } - Log.v(TAG, "syncedFileState.getRemotePath() :"+syncedFileState.getRemotePath() ); + Log.v(TAG, "syncedFileState.getRemotePath() :" + syncedFileState.getRemotePath()); //If syncedFileState match the remote file if (remoteFilePath.equals(syncedFileState.getRemotePath())) { - Log.d(TAG, "correspondant found for "+remoteFilePath ); + Log.d(TAG, "correspondant found for " + remoteFilePath); correspondant_found = true; if (syncedFileState.isLastEtagStored() //there is an etag stored - && (!remoteFile.getEtag().equals(syncedFileState.getLastETAG()) //If etag has changed - || syncedFileState.getLocalLastModified() == 0L)) { //File hasn't been downloaded + && (!remoteFile.getEtag().equals(syncedFileState.getLastETAG()) //If etag has changed + || syncedFileState.getLocalLastModified() == 0L)) { //File hasn't been downloaded - Log.v(TAG, "etag and localLastModified are valids for "+remoteFilePath ); + Log.v(TAG, "etag and localLastModified are valids for " + remoteFilePath); //compare size with local file if (remoteFile.getLength() == new File(syncedFileState.getLocalPath()).length()) { //length is 0 is file doesn't exist @@ -388,8 +426,8 @@ public class ObserverService extends Service implements OnRemoteOperationListene syncedFileState.setLastETAG(remoteFile.getEtag()); int affectedRows = DbHelper.manageSyncedFileStateDB(syncedFileState, "UPDATE", this); Log.v(TAG, affectedRows + " syncedFileState.s row in DB has been updated."); - }else { - Log.i(TAG, "Add download operation for file "+syncedFileState.getId()); + } else { + Log.i(TAG, "Add download operation for file " + syncedFileState.getId()); DownloadFileOperation downloadFileOperation = new DownloadFileOperation(remoteFile, syncedFileState); this.operationsForIntent.put(syncedFileState.getId(), downloadFileOperation); } @@ -399,7 +437,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene } } - if( correspondant_found )continue; + if (correspondant_found) continue; //If we get here, RemoteFile is a new file to download Log.v(TAG, "SyncedFileState corresponding to remoteFile not found."); @@ -408,8 +446,8 @@ public class ObserverService extends Service implements OnRemoteOperationListene final String parentOfKnownPath = remoteFilePath.substring(0, remoteFilePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); //look for parent folder in SyncedFolders - for (int j = -1, mSyncedFolderSize = this.mSyncedFolders.size(); ++j < mSyncedFolderSize;) { - if ( mSyncedFolders.get(j).getRemoteFolder().equals( parentOfKnownPath ) ) { //We have found the parent folder + for (int j = -1, mSyncedFolderSize = this.mSyncedFolders.size(); ++j < mSyncedFolderSize; ) { + if (mSyncedFolders.get(j).getRemoteFolder().equals(parentOfKnownPath)) { //We have found the parent folder final SyncedFolder parentFolder = mSyncedFolders.get(j); String fileName = CommonUtils.getFileNameFromPath(remoteFilePath); //get remote file's name @@ -422,7 +460,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene int storedId = DbHelper.manageSyncedFileStateDB(newRemoteFile, "INSERT", this); if (storedId > 0) { newRemoteFile.setId(storedId); - Log.i(TAG, "Add download operation for new file "+storedId); + Log.i(TAG, "Add download operation for new file " + storedId); //Create Download operation and add it into Bundle this.operationsForIntent.put(storedId, new DownloadFileOperation(remoteFile, newRemoteFile)); @@ -439,52 +477,53 @@ public class ObserverService extends Service implements OnRemoteOperationListene } //At this step, we finished to handle each remote file and we may still have synced file but without remote equivalent. // In most cases, we consider those files as remotly removed files. So we start to delete those local file. - Log.v( TAG, "Start to handle remotly missing file" ); - handleRemoteRemainingSyncedFileState( syncedFileStates ); + Log.v(TAG, "Start to handle remotly missing file"); + handleRemoteRemainingSyncedFileState(syncedFileStates); } /** * Handle the list of syncedFileState which don't have remoteFile anymore. + * * @param syncedFileStates SyncedFileState for which no remote equivalent has been found */ - private void handleRemoteRemainingSyncedFileState(List syncedFileStates){ + private void handleRemoteRemainingSyncedFileState(List syncedFileStates) { - Log.i( TAG, "handleRemoteRemainingSyncedFileState()" ); + Log.i(TAG, "handleRemoteRemainingSyncedFileState()"); //Loop through remaining file state - for(int i = -1, size = syncedFileStates.size(); ++i < size; ){ + for (int i = -1, size = syncedFileStates.size(); ++i < size; ) { SyncedFileState syncedFileState = syncedFileStates.get(i); - if( !CommonUtils.isThisSyncAllowed( mAccount, syncedFileState.isMediaType() ) ){ - Log.d(TAG, "Sync of current file: "+syncedFileState.getName()+" isn't allowed"); + if (!CommonUtils.isThisSyncAllowed(mAccount, syncedFileState.isMediaType())) { + Log.d(TAG, "Sync of current file: " + syncedFileState.getName() + " isn't allowed"); continue; } //Check that file has already been synced fully - if( syncedFileState.isLastEtagStored() && syncedFileState.getLocalLastModified() > 0L) { + if (syncedFileState.isLastEtagStored() && syncedFileState.getLocalLastModified() > 0L) { //Get local file - File file = new File( syncedFileStates.get(i).getLocalPath() ); + File file = new File(syncedFileStates.get(i).getLocalPath()); //Try to remove local file boolean fileExists = file.exists(); - if( fileExists) { - Log.d(TAG, file.getName()+" exists *1"); + if (fileExists) { + Log.d(TAG, file.getName() + " exists *1"); //delete file int rowAffected = getContentResolver().delete(MediaStore.Files.getContentUri("external"), MediaStore.Files.FileColumns.DATA + "=?", new String[]{CommonUtils.getLocalPath(file)}); - Log.d(TAG, "deleted rows by mediastore : "+rowAffected); + Log.d(TAG, "deleted rows by mediastore : " + rowAffected); //sometimes (it seems to be relative to file's type) mediastore don't remove local file from storage fileExists = !file.delete(); } //if it succeed, remove syncedFileState in DB - if(! fileExists ) { + if (!fileExists) { //It means that file has been correctly deleted from device. So update DB. if (DbHelper.manageSyncedFileStateDB(syncedFileState, "DELETE", this) <= 0) Log.e(TAG, "SyncedFileState row hasn't been deleted from DB"); - }else - Log.w(TAG, "local file:"+file.getName()+" still exist and can't be remove"); + } else + Log.w(TAG, "local file:" + file.getName() + " still exist and can't be remove"); } } } @@ -496,74 +535,74 @@ public class ObserverService extends Service implements OnRemoteOperationListene * Generate a .txt file containing list of all installed packages with their version name * I.e : " com.android.my_example_package,7.1.2 " */ - private void generateAppListFile(){ + private void generateAppListFile() { Log.i(TAG, "generateAppListFile()"); List packagesInfo = getPackageManager().getInstalledPackages(0); StringBuilder fileContents = new StringBuilder(); - for( int i =-1, size = packagesInfo.size(); ++i < size; ){ + for (int i = -1, size = packagesInfo.size(); ++i < size; ) { PackageInfo currentPackage = packagesInfo.get(i); - fileContents.append( currentPackage.packageName).append(",").append(currentPackage.versionName).append("\n"); + fileContents.append(currentPackage.packageName).append(",").append(currentPackage.versionName).append("\n"); } try { FileOutputStream tmp = openFileOutput(AppConstants.APPLICATIONS_LIST_FILE_NAME_TMP, Context.MODE_PRIVATE); tmp.write(fileContents.toString().getBytes()); tmp.close(); - String filesdir = getFilesDir().getCanonicalPath()+PATH_SEPARATOR; - File tmp_file = new File(filesdir+AppConstants.APPLICATIONS_LIST_FILE_NAME_TMP); - File real_file = new File(filesdir+AppConstants.APPLICATIONS_LIST_FILE_NAME); + String filesdir = getFilesDir().getCanonicalPath() + PATH_SEPARATOR; + File tmp_file = new File(filesdir + AppConstants.APPLICATIONS_LIST_FILE_NAME_TMP); + File real_file = new File(filesdir + AppConstants.APPLICATIONS_LIST_FILE_NAME); - if ( tmp_file.length() != real_file.length() ) { + if (tmp_file.length() != real_file.length()) { //only use tmp file if content has changed tmp_file.renameTo(real_file); } else { tmp_file.delete(); } } catch (Exception e) { - Log.e(TAG, "Can't save file with package list: "+e.toString()); + Log.e(TAG, "Can't save file with package list: " + e.toString()); } } /** * Prepare the list of files and SyncedFileState for synchronisation */ - private void scanLocalFiles(){ - Log.i( TAG, "scanLocalFiles()" ); + private void scanLocalFiles() { + List fileList = new ArrayList<>(); - List folderIdList= new ArrayList<>(); + List folderIdList = new ArrayList<>(); boolean contentToSyncFound = false; //Regenere list of application's package - if(CommonUtils.isSettingsSyncEnabled(mAccount)) generateAppListFile(); + if (CommonUtils.isSettingsSyncEnabled(mAccount)) generateAppListFile(); - ListIterator iterator = mSyncedFolders.listIterator() ; + ListIterator iterator = mSyncedFolders.listIterator(); //Loop through folders - while(iterator.hasNext() ){ + while (iterator.hasNext()) { SyncedFolder syncedFolder = iterator.next(); - Log.d(TAG, "SyncedFolder :"+syncedFolder.getLibelle()+", "+syncedFolder.getLocalFolder()+", "+syncedFolder.getLastModified()+", "+syncedFolder.isScanLocal()+", "+syncedFolder.getId() ); + Log.d(TAG, "SyncedFolder :" + syncedFolder.getLibelle() + ", " + syncedFolder.getLocalFolder() + ", " + syncedFolder.getLastModified() + ", " + syncedFolder.isScanLocal() + ", " + syncedFolder.getId()); //Check it's not a hidden file - if(syncedFolder.isMediaType() && CommonUtils.getFileNameFromPath(syncedFolder.getLocalFolder()).startsWith(".")){ + if (syncedFolder.isMediaType() && CommonUtils.getFileNameFromPath(syncedFolder.getLocalFolder()).startsWith(".")) { iterator.remove(); continue; } //Check it can be scann from local - if(!syncedFolder.isScanLocal()){ + if (!syncedFolder.isScanLocal()) { iterator.remove(); continue; } //Check if it's a new folder - if ( syncedFolder.getId() == -1) { + if (syncedFolder.getId() == -1) { Log.v(TAG, "This is a new folder, we must register it"); //persist new syncedFolder int syncedFolder_id = (int) DbHelper.insertSyncedFolder(syncedFolder, this); //It will return -1 if there is an error, like an already existing folder with same value if (syncedFolder_id > 0) { Log.v(TAG, "Folder has been registered in DB"); syncedFolder.setId(syncedFolder_id); - }else { + } else { Log.w(TAG, "syncedFolder " + syncedFolder.getLocalFolder() + " remove iterator because it hasn't been registered in DB or already stored"); iterator.remove(); continue; @@ -571,38 +610,38 @@ public class ObserverService extends Service implements OnRemoteOperationListene } //Get local folder corresponding File localFolder = new File(syncedFolder.getLocalFolder()); //Obtention du fichier local - Log.d(TAG, "Local Folder (last modified / exists): "+localFolder.lastModified()+", "+localFolder.exists() ); + Log.d(TAG, "Local Folder (last modified / exists): " + localFolder.lastModified() + ", " + localFolder.exists()); //Check if local folder exists - if(!localFolder.exists()){ + if (!localFolder.exists()) { Log.v(TAG, "local folder doesn't exist anymore . So content has change"); contentToSyncFound = true; - folderIdList.add( (long) syncedFolder.getId() ); + folderIdList.add((long) syncedFolder.getId()); continue; } boolean folderHasChange = false; //consider by default that file hadn't change //Check if folder had change - if(localFolder.lastModified() > syncedFolder.getLastModified() ) { //compare last modified date + if (localFolder.lastModified() > syncedFolder.getLastModified()) { //compare last modified date Log.v(TAG, "local folder has changed"); - syncedFolder.setLastModified( localFolder.lastModified() ); //@Todo: it would be better to set it after all it's content has been synced + syncedFolder.setLastModified(localFolder.lastModified()); //@Todo: it would be better to set it after all it's content has been synced contentToSyncFound = true; //at least one dir has changed folderHasChange = true; //The folder has change - folderIdList.add( (long) syncedFolder.getId() ); //add id into list of modified folder + folderIdList.add((long) syncedFolder.getId()); //add id into list of modified folder } //Get sub files - final FileFilter filter = FileFilterFactory.getFileFilter( (syncedFolder.isMediaType()) ? "media" : syncedFolder.getLibelle() ); + final FileFilter filter = FileFilterFactory.getFileFilter((syncedFolder.isMediaType()) ? "media" : syncedFolder.getLibelle()); File[] subElements = localFolder.listFiles(filter); //hiden media files are being ignored Log.v(TAG, "loop through subfiles"); - for (int i = -1, subEltSize = (subElements != null)? subElements.length: 0; ++i < subEltSize; ) { + for (int i = -1, subEltSize = (subElements != null) ? subElements.length : 0; ++i < subEltSize; ) { File subElt = subElements[i]; - if(subElt == null) continue; + if (subElt == null) continue; if (subElt.isDirectory()) { //if its a subfolder add it to syncedFolder list //if a subfolder is found, add it to syncedFolder list - Log.v(TAG, "subfile "+subElt.getAbsolutePath()+" is a directory."); + Log.v(TAG, "subfile " + subElt.getAbsolutePath() + " is a directory."); SyncedFolder subSyncedFolder = new SyncedFolder(syncedFolder, subElt.getName() + FileUtils.PATH_SEPARATOR, 0L, "");//Need to put 0 into to be handled on next iterati iterator.add(subSyncedFolder); iterator.previous(); @@ -617,12 +656,13 @@ public class ObserverService extends Service implements OnRemoteOperationListene } //end of iterator loop - if(contentToSyncFound) { + if (contentToSyncFound) { DbHelper.updateSyncedFolders(mSyncedFolders, this); //@ToDo: maybe do this when all contents will be synced. + List syncedFileStates = DbHelper.getSyncedFileStatesByFolders(this, folderIdList); - if(!syncedFileStates.isEmpty() || !fileList.isEmpty() ) { + if (!syncedFileStates.isEmpty() || !fileList.isEmpty()) { handleLocalFiles(fileList, syncedFileStates); } } @@ -633,49 +673,50 @@ public class ObserverService extends Service implements OnRemoteOperationListene * If file has already be synced and modified since last synced then update (= upload) * if file has never been synced then upload * if file has already be on server once(=> SyncedFIleState.etag is valid) and not local file exist then remove syncedFile - * @param localFileList list of local file to scan + * + * @param localFileList list of local file to scan * @param syncedFileStates List of SyncedFileState to scan */ - private void handleLocalFiles(List localFileList, List syncedFileStates ){ - Log.i(TAG, "handleLocalFiles()"); + private void handleLocalFiles(List localFileList, List syncedFileStates) { Log.d(TAG, "Loop through local file list"); Log.v(TAG, "format: filePath, exist, lastModified) :"); + Log.e("TAG", "ObserverService..handleLocalFiles...."); //Loop through local files - for(int i =-1, localFilesSize = localFileList.size(); ++i < localFilesSize;){ + for (int i = -1, localFilesSize = localFileList.size(); ++i < localFilesSize; ) { File localFile = localFileList.get(i); - String filePath = CommonUtils.getLocalPath( localFile ); + String filePath = CommonUtils.getLocalPath(localFile); boolean correspondant_found = false; - Log.v(TAG, "Current file is "+filePath+", "+localFile.exists()+", "+localFile.lastModified() ); + Log.v(TAG, "Current file is " + filePath + ", " + localFile.exists() + ", " + localFile.lastModified()); ListIterator syncedFileListIterator = syncedFileStates.listIterator(); Log.d(TAG, "Loop through syncedFileStates "); Log.v(TAG, "format: (Path, Id, last Modified)"); - while( syncedFileListIterator.hasNext() ) { + while (syncedFileListIterator.hasNext()) { SyncedFileState syncedFileState = syncedFileListIterator.next(); //Ignore hidden media file store in DB - if(syncedFileState.isMediaType() && syncedFileState.getName().startsWith(".")){ + if (syncedFileState.isMediaType() && syncedFileState.getName().startsWith(".")) { syncedFileListIterator.remove(); continue; } - Log.v(TAG, syncedFileState.getLocalPath()+", "+syncedFileState.getId()+", "+syncedFileState.getLocalLastModified()); + Log.v(TAG, syncedFileState.getLocalPath() + ", " + syncedFileState.getId() + ", " + syncedFileState.getLocalLastModified()); //if syncedFileState correspond to local file - if( syncedFileState.getLocalPath().equals( filePath ) ){ + if (syncedFileState.getLocalPath().equals(filePath)) { correspondant_found = true; //If no etag is stored in sfs, the file hasn't been sync up to server. then do upload - if( syncedFileState.getLocalLastModified() < localFile.lastModified() || !syncedFileState.isLastEtagStored()){ - Log.d(TAG+"_handleLocalFiles()", syncedFileState.getName()+" file has been modified or never sync" ); + if (syncedFileState.getLocalLastModified() < localFile.lastModified() || !syncedFileState.isLastEtagStored()) { + Log.d(TAG + "_handleLocalFiles()", syncedFileState.getName() + " file has been modified or never sync"); boolean checkEtag = false; //Look for folder to know if the folder can be scan remotly. - for(int folderIndex =-1, size = mSyncedFolders.size();++folderIndex < size;) { + for (int folderIndex = -1, size = mSyncedFolders.size(); ++folderIndex < size; ) { final SyncedFolder syncedFolder = mSyncedFolders.get(folderIndex); if (syncedFolder.getId() == syncedFileState.getSyncedFolderId()) { @@ -684,8 +725,8 @@ public class ObserverService extends Service implements OnRemoteOperationListene break; } } - Log.i(TAG, "Add upload operation for file "+syncedFileState.getId()); - UploadFileOperation uploadFileOperation = new UploadFileOperation(syncedFileState, checkEtag ); + Log.i(TAG, "Add upload operation for file " + syncedFileState.getId()); + UploadFileOperation uploadFileOperation = new UploadFileOperation(syncedFileState, checkEtag); this.operationsForIntent.put(syncedFileState.getId(), uploadFileOperation); } // No need to reloop on it. @@ -693,7 +734,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene break; } } - if( correspondant_found ) continue; + if (correspondant_found) continue; //if no correspondance, then it is a new file Log.v(TAG, "this is a new file to sync"); @@ -702,20 +743,20 @@ public class ObserverService extends Service implements OnRemoteOperationListene final String parentPath = filePath.substring(0, filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); //look into synced folders if folder path exist - for(SyncedFolder syncedFolder : mSyncedFolders){ - if(syncedFolder.getLocalFolder().equals(parentPath)){ + for (SyncedFolder syncedFolder : mSyncedFolders) { + if (syncedFolder.getLocalFolder().equals(parentPath)) { //create the syncedFile State SyncedFileState newSyncedFileState = new SyncedFileState(-1, localFile.getName(), filePath, syncedFolder.getRemoteFolder() + localFile.getName(), "", 0, syncedFolder.getId(), syncedFolder.isMediaType()); //Store it in DB int storedId = DbHelper.manageSyncedFileStateDB(newSyncedFileState, "INSERT", this); - if(storedId > 0){ - newSyncedFileState.setId( storedId ); - Log.i(TAG, "Add upload operation for new file "+storedId); + if (storedId > 0) { + newSyncedFileState.setId(storedId); + Log.i(TAG, "Add upload operation for new file " + storedId); //create UploadOperation and add it into bundle UploadFileOperation uploadOperation = new UploadFileOperation(newSyncedFileState, syncedFolder.isScanRemote()); this.operationsForIntent.put(storedId, uploadOperation); - }else{ + } else { Log.w(TAG, "The new file to synced cannot be store in DB. Ignore it"); } break; @@ -723,25 +764,26 @@ public class ObserverService extends Service implements OnRemoteOperationListene }//end of loop over folder }//end of loop over local files //Handle remaining file - handleLocalRemainingSyncedFileState( syncedFileStates ); + handleLocalRemainingSyncedFileState(syncedFileStates); } /** * manage rest of the list of syncedFilesState to look for remote file to delete + * * @param syncedFileStates List of SyncedFileState for which no local equivalent has been found */ - private void handleLocalRemainingSyncedFileState(List syncedFileStates){ + private void handleLocalRemainingSyncedFileState(List syncedFileStates) { Log.i(TAG, "handleLocalRemainingSyncedFileState(...)"); //Loop through remaining SyncedFileState - for(SyncedFileState fileState : syncedFileStates){ - if(fileState.isLastEtagStored() && fileState.getLocalLastModified() > 0L){ + for (SyncedFileState fileState : syncedFileStates) { + if (fileState.isLastEtagStored() && fileState.getLocalLastModified() > 0L) { //try to get File File file = new File(fileState.getLocalPath()); - Log.v(TAG, "File : "+file.getAbsolutePath()+","+file.exists()); - if(file.exists()){ + Log.v(TAG, "File : " + file.getAbsolutePath() + "," + file.exists()); + if (file.exists()) { Log.w(TAG, "The file still exist. There is a problem!"); - }else{ - Log.i(TAG, "Add remove operation for file "+fileState.getId()); + } else { + Log.i(TAG, "Add remove operation for file " + fileState.getId()); RemoveFileOperation removeOperation = new RemoveFileOperation(fileState); this.operationsForIntent.put(fileState.getId(), removeOperation); } 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 2d1c16e2075583f573ec17e3d5845d66938b3a93..98a9841bc5c894ba87c2e51e23e9297a9ee1a805 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -30,7 +30,12 @@ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.resources.files.FileUtils; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import foundation.e.drive.receivers.ScreenOffReceiver; @@ -291,4 +296,26 @@ public abstract class CommonUtils { + "\n File can be read?: " + f.canRead() + "\n File can be written?: " + f.canWrite(); } + + /* + this function convert object to bytes + */ + public static byte[] convertToBytes(Object object) throws IOException { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos)) { + out.writeObject(object); + return bos.toByteArray(); + } + } + + /* + this function convert bytes to Object + */ + public static Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException { + try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream in = new ObjectInputStream(bis)) { + return in.readObject(); + } + } + } \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/utils/JobUtils.java b/app/src/main/java/foundation/e/drive/utils/JobUtils.java index 213b1e9ff70b78edde1c947021ebc21c79e94211..a83aedb8a515625c16fa300da0562751a3c45241 100644 --- a/app/src/main/java/foundation/e/drive/utils/JobUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/JobUtils.java @@ -24,7 +24,7 @@ import foundation.e.drive.jobs.ScannerJob; public abstract class JobUtils { final private static String TAG = JobUtils.class.getSimpleName(); //Tag for log public final static int ScannerJobId = 3310; - //public final static int InitializerJobId = 3311; + public final static int InitializerJobId = 3311; /** * Start the scheduledJob for observing remote's folder @@ -32,23 +32,23 @@ public abstract class JobUtils { */ public static void scheduleScannerJob(Context context){ Log.i(TAG, "scheduleJob"); - Log.i(TAG, "scheduleJob task off"); + /* I. Start periodic checkup */ -// ComponentName jobService = new ComponentName( context, ScannerJob.class ); -// -// JobInfo job = new JobInfo.Builder(ScannerJobId, jobService ) -// .setPeriodic(1860000, 30000) //31git minutes and 30 secondes -// .setPersisted(true) -// .setRequiredNetworkType( JobInfo.NETWORK_TYPE_ANY ) -// .build(); -// -// JobScheduler jobScheduler = context.getSystemService( JobScheduler.class ); -// -// if ( jobScheduler.schedule( job ) == JobScheduler.RESULT_SUCCESS ) { -// Log.d(TAG, "Scheduled job created"); -// } else { -// Log.e(TAG, "Scheduled job not created"); -// } + ComponentName jobService = new ComponentName( context, ScannerJob.class ); + + JobInfo job = new JobInfo.Builder(ScannerJobId, jobService ) + .setPeriodic(7200000 , 30000) //2 hr + .setPersisted(true) + .setRequiredNetworkType( JobInfo.NETWORK_TYPE_ANY ) + .build(); + + JobScheduler jobScheduler = context.getSystemService( JobScheduler.class ); + + if ( jobScheduler.schedule( job ) == JobScheduler.RESULT_SUCCESS ) { + Log.d(TAG, "Scheduled job created"); + } else { + Log.e(TAG, "Scheduled job not created"); + } } /**