Loading app/src/main/java/foundation/e/drive/EdriveApplication.java +7 −5 Original line number Diff line number Diff line Loading @@ -31,17 +31,17 @@ public class EdriveApplication extends Application { private static final String TAG = "EdriveApplication"; private RecursiveFileObserver mFileObserver = null; private FileEventListener fileEventListener; @Override public void onCreate() { super.onCreate(); fileEventListener = new FileEventListener(getApplicationContext()); Log.i(TAG, "Starting"); resetOperationManagerSetting(); final String pathForObserver = Environment.getExternalStorageDirectory().getAbsolutePath(); mFileObserver = new RecursiveFileObserver(getApplicationContext(), pathForObserver, new FileEventListener()); mFileObserver = new RecursiveFileObserver(getApplicationContext(), pathForObserver, fileEventListener); SharedPreferences prefs = getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); Loading Loading @@ -77,8 +77,9 @@ public class EdriveApplication extends Application { */ public void startRecursiveFileObserver(){ if (!mFileObserver.isWatching()) { fileEventListener.bindToSynchronizationService(); mFileObserver.startWatching(); Log.d(TAG, "Starting RecursiveFileObserver on media's root folder"); Log.d(TAG, "Starting RecursiveFileObserver on root folder"); } else { Log.w(TAG, "RecursiveFileObserver (for media's root folder) was already running"); Loading @@ -87,7 +88,8 @@ public class EdriveApplication extends Application { public void stopRecursiveFileObserver(){ mFileObserver.stopWatching(); Log.d(TAG, "RecursiveFileObserver on media's root folder stops watching "); fileEventListener.unbindFromSynchronizationService(); Log.d(TAG, "RecursiveFileObserver on root folder stops watching "); } @Override Loading app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java +153 −5 Original line number Diff line number Diff line /* * Copyright © Narinder Rana (/e/ foundation). * Copyright © Vincent Bourgmayer (/e/ foundation). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at Loading @@ -8,23 +9,170 @@ package foundation.e.drive.FileObservers; import static foundation.e.drive.models.SyncRequest.Type.UPLOAD; import android.content.Context; import android.content.Intent; import android.os.FileObserver; import android.util.Log; import com.owncloud.android.lib.resources.files.FileUtils; import java.io.File; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncRequest; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.services.SynchronizationService; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.SynchronizationServiceConnection; /** * @author Narinder Rana * @author vincent Bourgmayer */ public class FileEventListener { private final static String TAG = FileEventListener.class.getSimpleName(); private static final String TAG = FileEventListener.class.getSimpleName(); private final Context appContext; private final SynchronizationServiceConnection serviceConnection = new SynchronizationServiceConnection(); public FileEventListener(Context applicationContext) { this.appContext = applicationContext; } public void onEvent(int event, File file) { if (event == FileObserver.CLOSE_WRITE) { //Event triggered after modification/creation Log.d(TAG, "CLOSE_WRITE event for :" + file.getName()); } else if (event == FileObserver.DELETE) { Log.d(TAG, "DELETE event for :" + file.getName()); if (event == FileObserver.DELETE) { if (file.isDirectory()) { handleDirectoryDelete(file); } else { handleFileDelete(file); } } else if (event == FileObserver.CLOSE_WRITE) { if (file.isDirectory()) { handleDirectoryCloseWrite(file); } else { handleFileCloseWrite(file); } } else if (event == FileObserver.MOVE_SELF){ Log.d(TAG, file.getAbsolutePath() + " has been moved. Not handled yet"); } } private void sendSyncRequestToSynchronizationService(SyncRequest request) { Log.d(TAG, "Sending a SyncRequest for " + request.getSyncedFileState().getName()); if (serviceConnection.isBoundToSynchronizationService()) { serviceConnection.getSynchronizationService().queueOperation(request); serviceConnection.getSynchronizationService().startSynchronization(); }else{ Log.w(TAG, "Impossible to send SyncRequest. FileEventListener is not bound to SynchronizationService"); } } private void handleDirectoryCloseWrite(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); Log.d(TAG, "handleDirectoryCloseWrite(" + fileLocalPath + ")"); SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { //it's a directory creation final String parentPath = CommonUtils.getLocalPath(directory.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder != null) { //if parent is in the DB folder = new SyncedFolder(parentFolder, directory.getName() + FileUtils.PATH_SEPARATOR, directory.lastModified(), ""); DbHelper.insertSyncedFolder(folder, appContext); } } else { //It's a directory update folder.setLastModified(directory.lastModified()); DbHelper.updateSyncedFolder(folder, appContext); } } private void handleDirectoryDelete(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); Log.d(TAG, "handleDirectoryDelete("+fileLocalPath+")"); SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { //look for parent final String parentPath = CommonUtils.getLocalPath(directory.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder != null ) { //if parent is in the DB folder = new SyncedFolder(parentFolder, directory.getName()+ FileUtils.PATH_SEPARATOR, directory.lastModified(), ""); folder.setEnabled(false); DbHelper.insertSyncedFolder(folder, appContext); } } else { //If already in DB if (folder.isEnabled()) { folder.setEnabled(false); DbHelper.updateSyncedFolder(folder, appContext); } } } private void handleFileCloseWrite(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); Log.d(TAG, "handleFileCloseWrite("+fileLocalPath+")"); SyncRequest request = null; SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); if (fileState == null) { //New file discovered final String parentPath = CommonUtils.getLocalPath(file.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder == null || !parentFolder.isEnabled()) { Log.w(TAG, "Won't send sync request: no parent are known for new file: "+file.getName()); return; } int scannableValue = 0; if (parentFolder.isEnabled()) { if (parentFolder.isScanRemote()) scannableValue++; if (parentFolder.isScanLocal()) scannableValue += 2; } final String remotePath = parentFolder.getRemoteFolder()+file.getName(); fileState = new SyncedFileState(-1, file.getName(), CommonUtils.getLocalPath(file), remotePath, "", 0L, parentFolder.getId(), parentFolder.isMediaType(), scannableValue); int storedId = DbHelper.manageSyncedFileStateDB(fileState, "INSERT", appContext); if (storedId > 0) { fileState.setId(storedId); request = new SyncRequest(fileState, UPLOAD); } else { Log.w(TAG, "New File " + file.getName() + " observed but impossible to insert it in DB"); } } else { //File update if (fileState.getScannable() > 1) { request = new SyncRequest(fileState, UPLOAD); } } if (request != null) { sendSyncRequestToSynchronizationService(request); } } private void handleFileDelete(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); Log.d(TAG, "handleFileDelete("+fileLocalPath+")"); SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); if (fileState == null) { Log.d(TAG, "Ignore event because file is not already in database"); return; } //If already in DB if (fileState.getScannable() > 0) { fileState.setScannable(0); DbHelper.manageSyncedFileStateDB(fileState, "UPDATE", appContext); } } public void unbindFromSynchronizationService(){ if(serviceConnection.isBoundToSynchronizationService()) appContext.unbindService(serviceConnection); else Log.w(TAG, "Not bound to SynchronizationService: can't unbind."); } public void bindToSynchronizationService(){ Log.d(TAG, "bindToSynchronizationService()"); final Intent SynchronizationServiceIntent = new Intent(appContext, SynchronizationService.class); appContext.bindService(SynchronizationServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE); } } app/src/main/java/foundation/e/drive/database/DbHelper.java +33 −7 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ import foundation.e.drive.models.SyncedFileState; */ public final class DbHelper extends SQLiteOpenHelper { final private static String TAG = DbHelper.class.getSimpleName(); //Tag for log private static final int DATABASE_VERSION = 19; //20/09/2018 private static final int DATABASE_VERSION = 20; //16/03/2022 public static final String DATABASE_NAME = "eelo_drive.db"; /** Loading Loading @@ -53,20 +53,24 @@ public final class DbHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i(TAG, "onUpgrade(db, "+oldVersion+", "+newVersion+")"); if(oldVersion < 19){ try { if (oldVersion < 19) { db.execSQL(SyncedFolderContract.UPDATE_TABLE_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_TABLE_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_MEDIA_DATA_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_SETTINGS_DATA_TO_VERSION_19); db.execSQL(SyncedFolderContract.UPDATE_MEDIA_DATA_TO_VERSION_19); db.execSQL(SyncedFolderContract.UPDATE_SETTINGS_DATA_TO_VERSION_19); } if (oldVersion < 20) { db.execSQL(SyncedFileStateContract.UPDATE_TABLE_TO_VERSION_20); db.execSQL(SyncedFileStateContract.UPDATE_MEDIA_DATA_TO_VERSION_20); db.execSQL(SyncedFileStateContract.UPDATE_SETTINGS_DATA_TO_VERSION_20); } } catch(Exception e) { Log.e(TAG, toString()); } } } private static SyncedFileStateDAO openSyncedFileStateDAO(Context context, boolean writeMod){ Loading Loading @@ -116,7 +120,6 @@ public final class DbHelper extends SQLiteOpenHelper { } dao.close(); } return result; } Loading Loading @@ -178,6 +181,19 @@ public final class DbHelper extends SQLiteOpenHelper { return result; } public static int updateSyncedFolder(SyncedFolder syncedFolder, Context context) { int result = -1; //Connect to DB SyncedFolderDAO dao = openSyncedFolderDAO(context, true); if (dao == null){ return result; } result = dao.update( syncedFolder ); dao.close(); return result; } /** * Load SyncedFolder's from DB * @param context app or service activity Loading Loading @@ -243,6 +259,16 @@ public final class DbHelper extends SQLiteOpenHelper { return result; } public static SyncedFolder getSyncedFolderByLocalPath(String localPath, Context context){ SyncedFolderDAO dao = openSyncedFolderDAO(context, true); if (dao == null) { return null; } SyncedFolder syncedFolder = dao.getSyncedFolderByLocalPath(localPath); dao.close(); return syncedFolder; } /** * Set the lastModified value of SyncedFolder to 1. * The goal is to force to rescan it next time. Loading app/src/main/java/foundation/e/drive/database/SyncedFileStateContract.java +10 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ class SyncedFileStateContract implements BaseColumns{ static final String LOCAL_LAST_MODIFIED = "local_last_modified"; static final String SYNCEDFOLDER_ID = "synced_folder_id"; static final String IS_MEDIA_TYPE = "is_media_type"; static final String SCANNABLE = "scannable"; static final String SQL_CREATE_TABLE_SYNCEDFILESTATE = "CREATE TABLE "+TABLE_NAME+" ( " Loading @@ -36,6 +37,7 @@ class SyncedFileStateContract implements BaseColumns{ +LOCAL_LAST_MODIFIED+" INTEGER, " + SYNCEDFOLDER_ID +" INTEGER, " +IS_MEDIA_TYPE+" BOOLEAN," +SCANNABLE+" INTEGER, " +"CONSTRAINT synced_unicity_constraint UNIQUE (" +FILE_NAME+", " +LOCAL_PATH+", " Loading @@ -45,8 +47,8 @@ class SyncedFileStateContract implements BaseColumns{ static final String SQL_DELETE_TABLE_SYNCEDFILESTATE = " DROP TABLE IF EXISTS " + TABLE_NAME; //Update for version 18 and lower static final String UPDATE_TABLE_TO_VERSION_19 = "ALTER TABLE "+TABLE_NAME+" ADD COLUMN "+IS_MEDIA_TYPE+" BOOLEAN;"; static final String UPDATE_MEDIA_DATA_TO_VERSION_19 = "UPDATE "+TABLE_NAME+ " SET "+IS_MEDIA_TYPE+" = 1 WHERE "+ REMOTE_PATH+" LIKE \"/Photos/%\" OR "+ Loading @@ -60,4 +62,11 @@ class SyncedFileStateContract implements BaseColumns{ static final String UPDATE_SETTINGS_DATA_TO_VERSION_19 = "UPDATE "+TABLE_NAME+ " SET "+IS_MEDIA_TYPE+" = 0 WHERE "+REMOTE_PATH+" LIKE \"/Devices/%\";"; //update for version 19 and lower static final String UPDATE_TABLE_TO_VERSION_20 = "ALTER TABLE "+TABLE_NAME+" ADD COLUMN "+SCANNABLE+" INTEGER;"; static final String UPDATE_MEDIA_DATA_TO_VERSION_20 = "UPDATE "+TABLE_NAME+" SET "+SCANNABLE+" = 3 WHERE" + IS_MEDIA_TYPE+" = 1 ;" ; static final String UPDATE_SETTINGS_DATA_TO_VERSION_20 = "UPDATE "+TABLE_NAME+" SET "+SCANNABLE+" = 2 WHERE" + IS_MEDIA_TYPE+" = 0 ;" ; } app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java +16 −20 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.List; import foundation.e.drive.models.SyncedFileState; import static foundation.e.drive.database.SyncedFileStateContract.SCANNABLE; import static foundation.e.drive.database.SyncedFileStateContract.TABLE_NAME; import static foundation.e.drive.database.SyncedFileStateContract.FILE_NAME; import static foundation.e.drive.database.SyncedFileStateContract.IS_MEDIA_TYPE; Loading @@ -39,16 +41,6 @@ class SyncedFileStateDAO { private SQLiteDatabase mDB; private final DbHelper mHelper; /*private final String[] allColumns = { SyncedFileStateContract._ID, SyncedFileStateContract.FILE_NAME, SyncedFileStateContract.LOCAL_PATH, SyncedFileStateContract.REMOTE_PATH, SyncedFileStateContract.LAST_ETAG, SyncedFileStateContract.LOCAL_LAST_MODIFIED, SyncedFileStateContract.SYNCEDFOLDER_ID, SyncedFileStateContract.IS_MEDIA_TYPE };*/ SyncedFileStateDAO(Context context){ this.mHelper = new DbHelper(context); Loading Loading @@ -84,6 +76,7 @@ class SyncedFileStateDAO { values.put( LOCAL_LAST_MODIFIED, syncedFileState.getLocalLastModified() ); values.put( SYNCEDFOLDER_ID, syncedFileState.getSyncedFolderId() ); values.put( IS_MEDIA_TYPE, syncedFileState.isMediaType() ? 1 : 0 ); values.put( SCANNABLE, syncedFileState.getScannable()); return values; } Loading Loading @@ -151,7 +144,8 @@ class SyncedFileStateDAO { +LAST_ETAG+", " +LOCAL_LAST_MODIFIED+", " + SYNCEDFOLDER_ID+", " + IS_MEDIA_TYPE + IS_MEDIA_TYPE+", " + SCANNABLE +" FROM " +TABLE_NAME; if (syncedFolderids.size() > 0) { Loading Loading @@ -190,7 +184,8 @@ class SyncedFileStateDAO { +LAST_ETAG+", " +LOCAL_LAST_MODIFIED+", " + SYNCEDFOLDER_ID+", " + IS_MEDIA_TYPE+ + IS_MEDIA_TYPE+", " + SCANNABLE+ " FROM " +TABLE_NAME+" WHERE "; if (isLocalPath) Loading Loading @@ -224,7 +219,8 @@ class SyncedFileStateDAO { cursor.getString(4 ),// last Etag cursor.getLong(5 ),//Local last modified cursor.getLong(6 ), //SyncedFolderID (cursor.getInt(7) == 1 ) //is Media Type (cursor.getInt(7) == 1), //is Media Type cursor.getInt(8) //scannable ); } } Loading
app/src/main/java/foundation/e/drive/EdriveApplication.java +7 −5 Original line number Diff line number Diff line Loading @@ -31,17 +31,17 @@ public class EdriveApplication extends Application { private static final String TAG = "EdriveApplication"; private RecursiveFileObserver mFileObserver = null; private FileEventListener fileEventListener; @Override public void onCreate() { super.onCreate(); fileEventListener = new FileEventListener(getApplicationContext()); Log.i(TAG, "Starting"); resetOperationManagerSetting(); final String pathForObserver = Environment.getExternalStorageDirectory().getAbsolutePath(); mFileObserver = new RecursiveFileObserver(getApplicationContext(), pathForObserver, new FileEventListener()); mFileObserver = new RecursiveFileObserver(getApplicationContext(), pathForObserver, fileEventListener); SharedPreferences prefs = getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); Loading Loading @@ -77,8 +77,9 @@ public class EdriveApplication extends Application { */ public void startRecursiveFileObserver(){ if (!mFileObserver.isWatching()) { fileEventListener.bindToSynchronizationService(); mFileObserver.startWatching(); Log.d(TAG, "Starting RecursiveFileObserver on media's root folder"); Log.d(TAG, "Starting RecursiveFileObserver on root folder"); } else { Log.w(TAG, "RecursiveFileObserver (for media's root folder) was already running"); Loading @@ -87,7 +88,8 @@ public class EdriveApplication extends Application { public void stopRecursiveFileObserver(){ mFileObserver.stopWatching(); Log.d(TAG, "RecursiveFileObserver on media's root folder stops watching "); fileEventListener.unbindFromSynchronizationService(); Log.d(TAG, "RecursiveFileObserver on root folder stops watching "); } @Override Loading
app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java +153 −5 Original line number Diff line number Diff line /* * Copyright © Narinder Rana (/e/ foundation). * Copyright © Vincent Bourgmayer (/e/ foundation). * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at Loading @@ -8,23 +9,170 @@ package foundation.e.drive.FileObservers; import static foundation.e.drive.models.SyncRequest.Type.UPLOAD; import android.content.Context; import android.content.Intent; import android.os.FileObserver; import android.util.Log; import com.owncloud.android.lib.resources.files.FileUtils; import java.io.File; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncRequest; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.services.SynchronizationService; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.SynchronizationServiceConnection; /** * @author Narinder Rana * @author vincent Bourgmayer */ public class FileEventListener { private final static String TAG = FileEventListener.class.getSimpleName(); private static final String TAG = FileEventListener.class.getSimpleName(); private final Context appContext; private final SynchronizationServiceConnection serviceConnection = new SynchronizationServiceConnection(); public FileEventListener(Context applicationContext) { this.appContext = applicationContext; } public void onEvent(int event, File file) { if (event == FileObserver.CLOSE_WRITE) { //Event triggered after modification/creation Log.d(TAG, "CLOSE_WRITE event for :" + file.getName()); } else if (event == FileObserver.DELETE) { Log.d(TAG, "DELETE event for :" + file.getName()); if (event == FileObserver.DELETE) { if (file.isDirectory()) { handleDirectoryDelete(file); } else { handleFileDelete(file); } } else if (event == FileObserver.CLOSE_WRITE) { if (file.isDirectory()) { handleDirectoryCloseWrite(file); } else { handleFileCloseWrite(file); } } else if (event == FileObserver.MOVE_SELF){ Log.d(TAG, file.getAbsolutePath() + " has been moved. Not handled yet"); } } private void sendSyncRequestToSynchronizationService(SyncRequest request) { Log.d(TAG, "Sending a SyncRequest for " + request.getSyncedFileState().getName()); if (serviceConnection.isBoundToSynchronizationService()) { serviceConnection.getSynchronizationService().queueOperation(request); serviceConnection.getSynchronizationService().startSynchronization(); }else{ Log.w(TAG, "Impossible to send SyncRequest. FileEventListener is not bound to SynchronizationService"); } } private void handleDirectoryCloseWrite(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); Log.d(TAG, "handleDirectoryCloseWrite(" + fileLocalPath + ")"); SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { //it's a directory creation final String parentPath = CommonUtils.getLocalPath(directory.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder != null) { //if parent is in the DB folder = new SyncedFolder(parentFolder, directory.getName() + FileUtils.PATH_SEPARATOR, directory.lastModified(), ""); DbHelper.insertSyncedFolder(folder, appContext); } } else { //It's a directory update folder.setLastModified(directory.lastModified()); DbHelper.updateSyncedFolder(folder, appContext); } } private void handleDirectoryDelete(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); Log.d(TAG, "handleDirectoryDelete("+fileLocalPath+")"); SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { //look for parent final String parentPath = CommonUtils.getLocalPath(directory.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder != null ) { //if parent is in the DB folder = new SyncedFolder(parentFolder, directory.getName()+ FileUtils.PATH_SEPARATOR, directory.lastModified(), ""); folder.setEnabled(false); DbHelper.insertSyncedFolder(folder, appContext); } } else { //If already in DB if (folder.isEnabled()) { folder.setEnabled(false); DbHelper.updateSyncedFolder(folder, appContext); } } } private void handleFileCloseWrite(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); Log.d(TAG, "handleFileCloseWrite("+fileLocalPath+")"); SyncRequest request = null; SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); if (fileState == null) { //New file discovered final String parentPath = CommonUtils.getLocalPath(file.getParentFile()); SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder == null || !parentFolder.isEnabled()) { Log.w(TAG, "Won't send sync request: no parent are known for new file: "+file.getName()); return; } int scannableValue = 0; if (parentFolder.isEnabled()) { if (parentFolder.isScanRemote()) scannableValue++; if (parentFolder.isScanLocal()) scannableValue += 2; } final String remotePath = parentFolder.getRemoteFolder()+file.getName(); fileState = new SyncedFileState(-1, file.getName(), CommonUtils.getLocalPath(file), remotePath, "", 0L, parentFolder.getId(), parentFolder.isMediaType(), scannableValue); int storedId = DbHelper.manageSyncedFileStateDB(fileState, "INSERT", appContext); if (storedId > 0) { fileState.setId(storedId); request = new SyncRequest(fileState, UPLOAD); } else { Log.w(TAG, "New File " + file.getName() + " observed but impossible to insert it in DB"); } } else { //File update if (fileState.getScannable() > 1) { request = new SyncRequest(fileState, UPLOAD); } } if (request != null) { sendSyncRequestToSynchronizationService(request); } } private void handleFileDelete(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); Log.d(TAG, "handleFileDelete("+fileLocalPath+")"); SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); if (fileState == null) { Log.d(TAG, "Ignore event because file is not already in database"); return; } //If already in DB if (fileState.getScannable() > 0) { fileState.setScannable(0); DbHelper.manageSyncedFileStateDB(fileState, "UPDATE", appContext); } } public void unbindFromSynchronizationService(){ if(serviceConnection.isBoundToSynchronizationService()) appContext.unbindService(serviceConnection); else Log.w(TAG, "Not bound to SynchronizationService: can't unbind."); } public void bindToSynchronizationService(){ Log.d(TAG, "bindToSynchronizationService()"); final Intent SynchronizationServiceIntent = new Intent(appContext, SynchronizationService.class); appContext.bindService(SynchronizationServiceIntent, serviceConnection, Context.BIND_AUTO_CREATE); } }
app/src/main/java/foundation/e/drive/database/DbHelper.java +33 −7 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ import foundation.e.drive.models.SyncedFileState; */ public final class DbHelper extends SQLiteOpenHelper { final private static String TAG = DbHelper.class.getSimpleName(); //Tag for log private static final int DATABASE_VERSION = 19; //20/09/2018 private static final int DATABASE_VERSION = 20; //16/03/2022 public static final String DATABASE_NAME = "eelo_drive.db"; /** Loading Loading @@ -53,20 +53,24 @@ public final class DbHelper extends SQLiteOpenHelper { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i(TAG, "onUpgrade(db, "+oldVersion+", "+newVersion+")"); if(oldVersion < 19){ try { if (oldVersion < 19) { db.execSQL(SyncedFolderContract.UPDATE_TABLE_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_TABLE_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_MEDIA_DATA_TO_VERSION_19); db.execSQL(SyncedFileStateContract.UPDATE_SETTINGS_DATA_TO_VERSION_19); db.execSQL(SyncedFolderContract.UPDATE_MEDIA_DATA_TO_VERSION_19); db.execSQL(SyncedFolderContract.UPDATE_SETTINGS_DATA_TO_VERSION_19); } if (oldVersion < 20) { db.execSQL(SyncedFileStateContract.UPDATE_TABLE_TO_VERSION_20); db.execSQL(SyncedFileStateContract.UPDATE_MEDIA_DATA_TO_VERSION_20); db.execSQL(SyncedFileStateContract.UPDATE_SETTINGS_DATA_TO_VERSION_20); } } catch(Exception e) { Log.e(TAG, toString()); } } } private static SyncedFileStateDAO openSyncedFileStateDAO(Context context, boolean writeMod){ Loading Loading @@ -116,7 +120,6 @@ public final class DbHelper extends SQLiteOpenHelper { } dao.close(); } return result; } Loading Loading @@ -178,6 +181,19 @@ public final class DbHelper extends SQLiteOpenHelper { return result; } public static int updateSyncedFolder(SyncedFolder syncedFolder, Context context) { int result = -1; //Connect to DB SyncedFolderDAO dao = openSyncedFolderDAO(context, true); if (dao == null){ return result; } result = dao.update( syncedFolder ); dao.close(); return result; } /** * Load SyncedFolder's from DB * @param context app or service activity Loading Loading @@ -243,6 +259,16 @@ public final class DbHelper extends SQLiteOpenHelper { return result; } public static SyncedFolder getSyncedFolderByLocalPath(String localPath, Context context){ SyncedFolderDAO dao = openSyncedFolderDAO(context, true); if (dao == null) { return null; } SyncedFolder syncedFolder = dao.getSyncedFolderByLocalPath(localPath); dao.close(); return syncedFolder; } /** * Set the lastModified value of SyncedFolder to 1. * The goal is to force to rescan it next time. Loading
app/src/main/java/foundation/e/drive/database/SyncedFileStateContract.java +10 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ class SyncedFileStateContract implements BaseColumns{ static final String LOCAL_LAST_MODIFIED = "local_last_modified"; static final String SYNCEDFOLDER_ID = "synced_folder_id"; static final String IS_MEDIA_TYPE = "is_media_type"; static final String SCANNABLE = "scannable"; static final String SQL_CREATE_TABLE_SYNCEDFILESTATE = "CREATE TABLE "+TABLE_NAME+" ( " Loading @@ -36,6 +37,7 @@ class SyncedFileStateContract implements BaseColumns{ +LOCAL_LAST_MODIFIED+" INTEGER, " + SYNCEDFOLDER_ID +" INTEGER, " +IS_MEDIA_TYPE+" BOOLEAN," +SCANNABLE+" INTEGER, " +"CONSTRAINT synced_unicity_constraint UNIQUE (" +FILE_NAME+", " +LOCAL_PATH+", " Loading @@ -45,8 +47,8 @@ class SyncedFileStateContract implements BaseColumns{ static final String SQL_DELETE_TABLE_SYNCEDFILESTATE = " DROP TABLE IF EXISTS " + TABLE_NAME; //Update for version 18 and lower static final String UPDATE_TABLE_TO_VERSION_19 = "ALTER TABLE "+TABLE_NAME+" ADD COLUMN "+IS_MEDIA_TYPE+" BOOLEAN;"; static final String UPDATE_MEDIA_DATA_TO_VERSION_19 = "UPDATE "+TABLE_NAME+ " SET "+IS_MEDIA_TYPE+" = 1 WHERE "+ REMOTE_PATH+" LIKE \"/Photos/%\" OR "+ Loading @@ -60,4 +62,11 @@ class SyncedFileStateContract implements BaseColumns{ static final String UPDATE_SETTINGS_DATA_TO_VERSION_19 = "UPDATE "+TABLE_NAME+ " SET "+IS_MEDIA_TYPE+" = 0 WHERE "+REMOTE_PATH+" LIKE \"/Devices/%\";"; //update for version 19 and lower static final String UPDATE_TABLE_TO_VERSION_20 = "ALTER TABLE "+TABLE_NAME+" ADD COLUMN "+SCANNABLE+" INTEGER;"; static final String UPDATE_MEDIA_DATA_TO_VERSION_20 = "UPDATE "+TABLE_NAME+" SET "+SCANNABLE+" = 3 WHERE" + IS_MEDIA_TYPE+" = 1 ;" ; static final String UPDATE_SETTINGS_DATA_TO_VERSION_20 = "UPDATE "+TABLE_NAME+" SET "+SCANNABLE+" = 2 WHERE" + IS_MEDIA_TYPE+" = 0 ;" ; }
app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java +16 −20 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.List; import foundation.e.drive.models.SyncedFileState; import static foundation.e.drive.database.SyncedFileStateContract.SCANNABLE; import static foundation.e.drive.database.SyncedFileStateContract.TABLE_NAME; import static foundation.e.drive.database.SyncedFileStateContract.FILE_NAME; import static foundation.e.drive.database.SyncedFileStateContract.IS_MEDIA_TYPE; Loading @@ -39,16 +41,6 @@ class SyncedFileStateDAO { private SQLiteDatabase mDB; private final DbHelper mHelper; /*private final String[] allColumns = { SyncedFileStateContract._ID, SyncedFileStateContract.FILE_NAME, SyncedFileStateContract.LOCAL_PATH, SyncedFileStateContract.REMOTE_PATH, SyncedFileStateContract.LAST_ETAG, SyncedFileStateContract.LOCAL_LAST_MODIFIED, SyncedFileStateContract.SYNCEDFOLDER_ID, SyncedFileStateContract.IS_MEDIA_TYPE };*/ SyncedFileStateDAO(Context context){ this.mHelper = new DbHelper(context); Loading Loading @@ -84,6 +76,7 @@ class SyncedFileStateDAO { values.put( LOCAL_LAST_MODIFIED, syncedFileState.getLocalLastModified() ); values.put( SYNCEDFOLDER_ID, syncedFileState.getSyncedFolderId() ); values.put( IS_MEDIA_TYPE, syncedFileState.isMediaType() ? 1 : 0 ); values.put( SCANNABLE, syncedFileState.getScannable()); return values; } Loading Loading @@ -151,7 +144,8 @@ class SyncedFileStateDAO { +LAST_ETAG+", " +LOCAL_LAST_MODIFIED+", " + SYNCEDFOLDER_ID+", " + IS_MEDIA_TYPE + IS_MEDIA_TYPE+", " + SCANNABLE +" FROM " +TABLE_NAME; if (syncedFolderids.size() > 0) { Loading Loading @@ -190,7 +184,8 @@ class SyncedFileStateDAO { +LAST_ETAG+", " +LOCAL_LAST_MODIFIED+", " + SYNCEDFOLDER_ID+", " + IS_MEDIA_TYPE+ + IS_MEDIA_TYPE+", " + SCANNABLE+ " FROM " +TABLE_NAME+" WHERE "; if (isLocalPath) Loading Loading @@ -224,7 +219,8 @@ class SyncedFileStateDAO { cursor.getString(4 ),// last Etag cursor.getLong(5 ),//Local last modified cursor.getLong(6 ), //SyncedFolderID (cursor.getInt(7) == 1 ) //is Media Type (cursor.getInt(7) == 1), //is Media Type cursor.getInt(8) //scannable ); } }