From 623bd0b15a56b10b78766d15cae5775e174741fc Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 21 Sep 2022 15:34:00 +0200 Subject: [PATCH 01/20] When a file is removed from the phone. Put the remote one in the remote trash --- .../foundation/e/drive/FileObservers/FileEventListener.java | 5 +++-- app/src/main/java/foundation/e/drive/models/SyncWrapper.java | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java b/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java index 24191867..43266bee 100644 --- a/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java +++ b/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java @@ -8,6 +8,7 @@ package foundation.e.drive.FileObservers; +import static foundation.e.drive.models.SyncRequest.Type.REMOTE_DELETE; import static foundation.e.drive.models.SyncRequest.Type.UPLOAD; import android.content.Context; @@ -222,8 +223,8 @@ public class FileEventListener { //If already in DB if (fileState.getScannable() > 0) { - fileState.setScannable(0); - DbHelper.manageSyncedFileStateDB(fileState, "UPDATE", appContext); + SyncRequest deleteRequest = new SyncRequest(fileState, REMOTE_DELETE); + this.sendSyncRequestToSynchronizationService(deleteRequest); } } diff --git a/app/src/main/java/foundation/e/drive/models/SyncWrapper.java b/app/src/main/java/foundation/e/drive/models/SyncWrapper.java index a1984972..240352ea 100644 --- a/app/src/main/java/foundation/e/drive/models/SyncWrapper.java +++ b/app/src/main/java/foundation/e/drive/models/SyncWrapper.java @@ -16,6 +16,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import java.io.File; import foundation.e.drive.operations.DownloadFileOperation; +import foundation.e.drive.operations.RemoveFileOperation; import foundation.e.drive.operations.UploadFileOperation; /** @@ -66,7 +67,7 @@ public class SyncWrapper { final File file = new File(sfs.getLocalPath()); if (!file.exists()) { operation = null; - Log.w(TAG, "createRemoteOperation: local file doesn't exist for upload"); + Log.w(TAG, "createRemoteOperation: local file doesn't. Can't upload"); break; } operation = new UploadFileOperation(sfs, account, context); @@ -78,6 +79,8 @@ public class SyncWrapper { context); break; case REMOTE_DELETE: + operation = new RemoveFileOperation(request.getSyncedFileState()); + break; default: operation = null; break; -- GitLab From 28cce24cb18fb17607d7806628969e361ce138b7 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 26 Sep 2022 11:44:11 +0200 Subject: [PATCH 02/20] Add request to remove unscannable media from SyncedFileState databaase. bump version number to 1.2.4 Also, rewrite method name (add 's' at the end) for the method which remove hidden files from SyncedFileState database --- app/build.gradle | 2 +- .../java/foundation/e/drive/database/DbHelper.java | 5 +++-- .../e/drive/database/SyncedFileStateDAO.java | 13 +++++++++++-- .../foundation/e/drive/models/SyncedFileState.java | 8 -------- .../e/drive/receivers/BootCompletedReceiver.java | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index db4f90bc..648bfa2b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ plugins { def versionMajor = 1 def versionMinor = 2 -def versionPatch = 3 +def versionPatch = 4 diff --git a/app/src/main/java/foundation/e/drive/database/DbHelper.java b/app/src/main/java/foundation/e/drive/database/DbHelper.java index c0d2d9cb..54708046 100644 --- a/app/src/main/java/foundation/e/drive/database/DbHelper.java +++ b/app/src/main/java/foundation/e/drive/database/DbHelper.java @@ -366,9 +366,10 @@ public final class DbHelper extends SQLiteOpenHelper { * @param context * @throws SQLiteException if database can't be open */ - public static void removeHiddenSyncedFileState(Context context) throws SQLiteException { + public static void cleanSyncedFileStateTableAfterUpdate(Context context) throws SQLiteException { SyncedFileStateDAO dao = openSyncedFileStateDAO(context, true); - dao.deleteHiddenFileState(); + dao.deleteHiddenFileStates(); + dao.deleteUnscannableMediaFiles(); dao.close(); } } diff --git a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java index 9f93de59..c7522735 100644 --- a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java +++ b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java @@ -106,13 +106,22 @@ class SyncedFileStateDAO { /** - * Remove SyncedFileState for hidden file (starting with '.') + * Remove SyncedFileState for hidden files (starting with '.') * @return number of deleted input */ - public int deleteHiddenFileState() { + public int deleteHiddenFileStates() { return mDB.delete(TABLE_NAME, FILE_NAME + " LIKE ?", new String[]{".%"}); } + /** + * In previous version, when a synchronized file was removed, the DB value for scannable column + * was set to "0"; Now we consider those entries has to be removed + * @return number of deleted input + */ + public int deleteUnscannableMediaFiles() { + return mDB.delete(TABLE_NAME, IS_MEDIA_TYPE + " =1 AND "+SCANNABLE+" =0", null); + } + /** * Delete each syncedFileState which is bound to syncedFOlder with specified ID * @param folderId syncedFolder's id used as foreign key 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 7104feb8..38ee3331 100644 --- a/app/src/main/java/foundation/e/drive/models/SyncedFileState.java +++ b/app/src/main/java/foundation/e/drive/models/SyncedFileState.java @@ -176,14 +176,6 @@ public class SyncedFileState implements Parcelable { return scannable; } - /** - * Define in which context the file can be scan - * @param scannable 0: never. 1: on cloud only. 2: on device only. 3: in every context. - */ - public void setScannable(int scannable) { - this.scannable = scannable; - } - @Override public String toString(){ diff --git a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java index 6ec31479..779a3f6a 100644 --- a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java @@ -47,7 +47,7 @@ public class BootCompletedReceiver extends BroadcastReceiver { && BuildConfig.VERSION_CODE > pref.getInt(PREF_VERSION_CODE, 1002000)) { pref.edit().putInt(PREF_VERSION_CODE, BuildConfig.VERSION_CODE).apply(); try { - DbHelper.removeHiddenSyncedFileState(context); + DbHelper.cleanSyncedFileStateTableAfterUpdate(context); } catch (SQLiteException e) { Log.e(TAG, "Can't remove entry for hidden file in Database", e); } -- GitLab From 26c908ccc456f9c30c9b09eb969528dd88788ec9 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 28 Sep 2022 10:28:25 +0200 Subject: [PATCH 03/20] Add dependency to timber logging lib - Add dependency into build.gradle - Call Timber.plant(debugTree) in eDriveApplication and replace every call to Log.?(TAG,...) by Timber logging --- app/build.gradle | 1 + .../foundation/e/drive/EdriveApplication.java | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 648bfa2b..831e3cf8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -89,6 +89,7 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.13.1' implementation "androidx.work:work-runtime:2.7.1" implementation 'androidx.test:core:1.4.0' + implementation 'com.jakewharton.timber:timber:5.0.1' androidTestImplementation 'androidx.test:runner:1.4.0' androidTestImplementation 'androidx.test:rules:1.4.0' diff --git a/app/src/main/java/foundation/e/drive/EdriveApplication.java b/app/src/main/java/foundation/e/drive/EdriveApplication.java index 0e440fa8..493b027c 100644 --- a/app/src/main/java/foundation/e/drive/EdriveApplication.java +++ b/app/src/main/java/foundation/e/drive/EdriveApplication.java @@ -15,13 +15,14 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Environment; -import android.util.Log; import foundation.e.drive.FileObservers.FileEventListener; import foundation.e.drive.FileObservers.RecursiveFileObserver; import foundation.e.drive.services.SynchronizationService; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; +import static timber.log.Timber.DebugTree; /** * Class representing the eDrive application. @@ -30,15 +31,22 @@ import foundation.e.drive.utils.CommonUtils; * @author Vincent Bourgmayer */ public class EdriveApplication extends Application { - private static final String TAG = "EdriveApplication"; private RecursiveFileObserver mFileObserver = null; private FileEventListener fileEventListener; @Override public void onCreate() { super.onCreate(); + + if (BuildConfig.DEBUG) { + Timber.plant(new DebugTree()); + } else { + //Not handled yet + //Timber.plant(new ReleaseTree()); + } + Timber.tag("EdriveApplication"); + fileEventListener = new FileEventListener(getApplicationContext()); - Log.i(TAG, "Starting"); final String pathForObserver = Environment.getExternalStorageDirectory().getAbsolutePath(); mFileObserver = new RecursiveFileObserver(getApplicationContext(), pathForObserver, fileEventListener); @@ -47,15 +55,13 @@ public class EdriveApplication extends Application { CommonUtils.createNotificationChannel(getApplicationContext()); if (prefs.getString(AccountManager.KEY_ACCOUNT_NAME, null) != null) { - Log.d(TAG, "Account already registered"); startRecursiveFileObserver(); - resetTransferFailureCounter(); final Intent SynchronizationServiceIntent = new Intent(getApplicationContext(), SynchronizationService.class); startService(SynchronizationServiceIntent); - } else { + } else { //todo check utility of below code final Account mAccount = CommonUtils.getAccount(getString(R.string.eelo_account_type), AccountManager.get(this)); if (mAccount == null) { return; } @@ -75,16 +81,14 @@ public class EdriveApplication extends Application { if (!mFileObserver.isWatching()) { fileEventListener.bindToSynchronizationService(); mFileObserver.startWatching(); - Log.d(TAG, "Starting RecursiveFileObserver on root folder"); - } else { - Log.w(TAG, "RecursiveFileObserver (for media's root folder) was already running"); + Timber.d("Started RecursiveFileObserver on root folder"); } } public void stopRecursiveFileObserver() { mFileObserver.stopWatching(); fileEventListener.unbindFromSynchronizationService(); - Log.d(TAG, "RecursiveFileObserver on root folder stops watching "); + Timber.d("Stopped RecursiveFileObserver on root folder"); } @@ -101,6 +105,6 @@ public class EdriveApplication extends Application { @Override public void onLowMemory() { super.onLowMemory(); - Log.w(TAG, "System is low on memory. Application might get killed by the system."); + Timber.w("System is low on memory. Application might get killed by the system."); } } -- GitLab From 683ce733c268b7fd7b5049b64a246f5f58564981 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 28 Sep 2022 11:15:55 +0200 Subject: [PATCH 04/20] - Replace logging in ObserverService to use Timber - few refactoring, essentially to clean coding style - removed useless comments - removed useless import --- .../e/drive/services/ObserverService.java | 177 +++++++++--------- 1 file changed, 85 insertions(+), 92 deletions(-) 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 9756a22a..e863ba7a 100644 --- a/app/src/main/java/foundation/e/drive/services/ObserverService.java +++ b/app/src/main/java/foundation/e/drive/services/ObserverService.java @@ -21,7 +21,6 @@ import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.os.Handler; import android.os.IBinder; -import android.util.Log; import androidx.annotation.Nullable; @@ -54,10 +53,9 @@ import foundation.e.drive.receivers.DebugCmdReceiver; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; -import foundation.e.drive.utils.FileDiffUtils; -import foundation.e.drive.utils.FileDiffUtils.Action; import foundation.e.drive.utils.ServiceExceptionHandler; import foundation.e.drive.utils.SynchronizationServiceConnection; +import timber.log.Timber; /** * @author Vincent Bourgmayer @@ -66,7 +64,6 @@ import foundation.e.drive.utils.SynchronizationServiceConnection; * This service look for remote or looale file to synchronize */ 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. private List mSyncedFolders; //List of synced folder @@ -79,15 +76,22 @@ public class ObserverService extends Service implements OnRemoteOperationListene /* Lifecycle Methods */ @Override public void onDestroy(){ - Log.i(TAG, "onDestroy()"); + Timber.i("onDestroy()"); unbindService(synchronizationServiceConnection); super.onDestroy(); this.mSyncedFolders = null; } + + @Override + public void onCreate() { + super.onCreate(); + Timber.tag(ObserverService.class.getSimpleName()); + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.i(TAG, "onStartCommand("+startId+")"); + Timber.i("onStartCommand(%s)", startId); final Intent SynchronizationServiceIntent = new Intent(this, SynchronizationService.class); bindService(SynchronizationServiceIntent, synchronizationServiceConnection, Context.BIND_AUTO_CREATE); @@ -125,45 +129,45 @@ public class ObserverService extends Service implements OnRemoteOperationListene * @return false if at least one condition is false */ private boolean checkStartCondition(final SharedPreferences prefs, final boolean forcedSync) { - // Check Account not null + Timber.d("checkStartCondition()"); + if (mAccount == null) { - Log.e(TAG, "No account registered"); + Timber.w("No account registered"); return false; } - // Check that Media & Settings sync is enable - if (!CommonUtils.isMediaSyncEnabled(mAccount) && !CommonUtils.isSettingsSyncEnabled(mAccount) ){ - Log.w(TAG, "eDrive syncing has been disabled in /e/ account's settings"); + if (!CommonUtils.isMediaSyncEnabled(mAccount) && !CommonUtils.isSettingsSyncEnabled(mAccount)) { + Timber.w("Synchronization has been disabled in account's settings"); return false; } - // Check that Initialization has been done if (!prefs.getBoolean(INITIALIZATION_HAS_BEEN_DONE, false)) { - Log.w(TAG, "Initialization hasn't been done"); + Timber.w("Initialization hasn't been done"); Intent initializerIntent = new Intent(this, InitializerService.class); startService(initializerIntent); return false; } - // Check this service isn't already working - if (isWorking){ - Log.w(TAG, "ObserverService is already working"); + if (isWorking) { + Timber.w("ObserverService is already working"); return false; } // Check minimum delay since last call & not forced sync + /*@todo is it really usefull to check time beetween to start as it is started by WorkManager? + it matters only if we want to consider forced sync */ final long lastSyncTime = prefs.getLong(AppConstants.KEY_LAST_SYNC_TIME, 0L); final long currentTime = System.currentTimeMillis(); - if (!forcedSync && (currentTime - lastSyncTime ) < INTERSYNC_MINIMUM_DELAY ){ - Log.w(TAG, "Delay between now and last call is too short"); + if (!forcedSync && (currentTime - lastSyncTime ) < INTERSYNC_MINIMUM_DELAY ) { + Timber.w("Delay between now and last call is too short"); return false; } - // Check that network is available depending of metered network allowed or not + final boolean meteredNetworkAllowed = CommonUtils.isMeteredNetworkAllowed(mAccount); //check for the case where intent has been launched by initializerService if (!CommonUtils.haveNetworkConnection(this, meteredNetworkAllowed)) { - Log.w(TAG, "There is no allowed internet connexion."); + Timber.w("There is no allowed internet connexion."); return false; } return true; @@ -175,7 +179,6 @@ public class ObserverService extends Service implements OnRemoteOperationListene * Method to factorise code that is called from different place */ private void begin(){ - Log.i(TAG, "begin()"); this.isWorking = true; clearCachedFile(); deleteOldestCrashlogs(); @@ -187,52 +190,44 @@ public class ObserverService extends Service implements OnRemoteOperationListene * in external dir that are 10 days or more old. */ private void deleteOldestCrashlogs(){ - Log.i(TAG, "deleteOldestCrashLogs()"); - File externalFilesDir = getExternalFilesDir(ServiceExceptionHandler.CRASH_LOG_FOLDER); + Timber.i("deleteOldestCrashLogs()"); + final File externalFilesDir = getExternalFilesDir(ServiceExceptionHandler.CRASH_LOG_FOLDER); if (externalFilesDir == null) { - Log.e(TAG, "getExternalFilesDir() returned null. Returning to prevent a NPE"); + Timber.e("getExternalFilesDir() returned null. Preventing a NPE"); return; } - File[] fileToRemove = externalFilesDir.listFiles(new CrashlogsFileFilter()); + final File[] fileToRemove = externalFilesDir.listFiles(new CrashlogsFileFilter()); if (fileToRemove == null) { - Log.e(TAG, "getExternalFilesDir() returned null. Returning to prevent a NPE"); + Timber.e("getExternalFilesDir() returned null. Preventing a NPE"); return; } - int counter = 0; for (File file : fileToRemove) { try { file.delete(); - ++counter; - }catch (SecurityException e){ - e.printStackTrace(); + } catch (SecurityException exception) { + Timber.e(exception); } } - 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(){ - Log.i(TAG, "clearCachedFile()"); - //Load subfiles into external cache file - 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); - } + Timber.i("clearCachedFile()"); + final File[] fileToRemove = this.getApplicationContext().getExternalCacheDir().listFiles(new OnlyFileFilter() ); + if (fileToRemove == null) return; + + for (File file : fileToRemove) { + try { + file.delete(); + } catch (SecurityException exception) { + Timber.e(exception); } - } else { - Log.e(TAG+"_handleCachedFile()", "Array of cached file is null"); } } @@ -243,11 +238,11 @@ public class ObserverService extends Service implements OnRemoteOperationListene **/ private void startScan(boolean remote) { - Log.i(TAG, "startScan("+remote+")"); + Timber.i("startScan(%s)", remote); this.mSyncedFolders = loadSyncedFolders(); - if (mSyncedFolders.isEmpty() ){ - Log.w(TAG, "List of synced folders is empty"); + if (mSyncedFolders.isEmpty()) { + Timber.w("List of synced folders is empty"); this.stopSelf(); return; } @@ -255,15 +250,15 @@ public class ObserverService extends Service implements OnRemoteOperationListene if (remote) { final OwnCloudClient client = DavClientProvider.getInstance().getClientInstance(mAccount, getApplicationContext()); if (client == null) { - Log.w(TAG, "OwnCloudClient is null"); + Timber.w("OwnCloudClient is null"); return; } try { final ListFileRemoteOperation loadOperation = new ListFileRemoteOperation(this.mSyncedFolders, this, this.initialFolderCounter); loadOperation.execute(client, this, new Handler()); - } catch (IllegalArgumentException e){ - Log.e(TAG, "Can't execute ListFileRemoteOperation", e); + } catch (IllegalArgumentException exception) { + Timber.e(exception); } } else { scanLocalFiles(); @@ -275,14 +270,14 @@ public class ObserverService extends Service implements OnRemoteOperationListene * @return */ private List loadSyncedFolders(){ - boolean mediaSyncEnabled = CommonUtils.isMediaSyncEnabled(mAccount); - boolean settingsSyncedEnabled = CommonUtils.isSettingsSyncEnabled(mAccount); + final boolean mediaSyncEnabled = CommonUtils.isMediaSyncEnabled(mAccount); + final 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 { return new ArrayList(); @@ -295,38 +290,37 @@ public class ObserverService extends Service implements OnRemoteOperationListene * @param result The result of the remote Operation */ @Override - public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result ) { - Log.i( TAG, "onRemoteOperationFinish()" ); + public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { + Timber.i("onRemoteOperationFinish()"); if (!(operation instanceof ListFileRemoteOperation)) return; - if (result.isSuccess()) { + if (!result.isSuccess()) { + Timber.w("ListRemoteFileOperation failed. Http code: %s", result.getHttpCode()); + } - final List remoteFiles = ((RemoteOperationResult>)result).getResultData(); + final List remoteFiles = ((RemoteOperationResult>)result).getResultData(); - if (remoteFiles != null) { + if (remoteFiles != null) { - final ListFileRemoteOperation listFileOperation = (ListFileRemoteOperation) operation; - mSyncedFolders = listFileOperation.getSyncedFolderList(); //The list may have been reduced if some directory hasn't changed + final ListFileRemoteOperation listFileOperation = (ListFileRemoteOperation) operation; + mSyncedFolders = listFileOperation.getSyncedFolderList(); //The list may have been reduced if some directory hasn't changed - final List syncedFileStateList = DbHelper.getSyncedFileStatesByFolders(this, - getIdsFromFolderToScan()); + final List syncedFileStateList = DbHelper.getSyncedFileStatesByFolders(this, + getIdsFromFolderToScan()); - if (!remoteFiles.isEmpty() || !syncedFileStateList.isEmpty()) { - final RemoteContentScanner scanner = new RemoteContentScanner(getApplicationContext(), mAccount, mSyncedFolders); - syncRequests.putAll(scanner.scanContent(remoteFiles, syncedFileStateList)); - } + if (!remoteFiles.isEmpty() || !syncedFileStateList.isEmpty()) { + final RemoteContentScanner scanner = new RemoteContentScanner(getApplicationContext(), mAccount, mSyncedFolders); + syncRequests.putAll(scanner.scanContent(remoteFiles, syncedFileStateList)); } - } else { - Log.w(TAG, "ListRemoteFileOperation failed. Http code: " + result.getHttpCode()); } startScan(false); - Log.v(TAG, "syncRequests contains " + syncRequests.size()); if (!syncRequests.isEmpty()) { + Timber.d("syncRequests contains %s", syncRequests.size()); passSyncRequestsToSynchronizationService(); } else { - Log.w(TAG, "There is no file to sync."); + Timber.w("There is no file to sync."); getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) .edit() .putLong(AppConstants.KEY_LAST_SYNC_TIME, System.currentTimeMillis()) @@ -344,7 +338,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene synchronizationServiceConnection.getSynchronizationService().queueSyncRequests(syncRequests.values()); synchronizationServiceConnection.getSynchronizationService().startSynchronization(); } else { - Log.e(TAG, "ERROR: impossible to bind ObserverService to SynchronizationService"); + Timber.e("ERROR: impossible to bind ObserverService to SynchronizationService"); } } @@ -353,9 +347,9 @@ public class ObserverService extends Service implements OnRemoteOperationListene * @return List id of SyncedFolder to scan */ private List getIdsFromFolderToScan() { - List result = new ArrayList<>(); + final List result = new ArrayList<>(); for (int i = -1, size = this.mSyncedFolders.size(); ++i < size;) { - SyncedFolder syncedFolder = this.mSyncedFolders.get(i); + final SyncedFolder syncedFolder = this.mSyncedFolders.get(i); if (syncedFolder.isToSync() ){ result.add( (long) syncedFolder.getId() ); } @@ -371,31 +365,30 @@ public class ObserverService extends Service implements OnRemoteOperationListene * I.e : " com.android.my_example_package,7.1.2 " */ private void generateAppListFile() { - Log.i(TAG, "generateAppListFile()"); - List packagesInfo = getPackageManager().getInstalledPackages(0); + Timber.i("generateAppListFile()"); + final List packagesInfo = getPackageManager().getInstalledPackages(0); - StringBuilder fileContents = new StringBuilder(); - for( int i =-1, size = packagesInfo.size(); ++i < size; ){ + final StringBuilder fileContents = new StringBuilder(); + for(int i =-1, size = packagesInfo.size(); ++i < size;) { PackageInfo currentPackage = packagesInfo.get(i); fileContents.append( currentPackage.packageName).append(",").append(currentPackage.versionName).append("\n"); } try { - FileOutputStream tmp = openFileOutput(AppConstants.APPLICATIONS_LIST_FILE_NAME_TMP, Context.MODE_PRIVATE); + final 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); + final String filesdir = getFilesDir().getCanonicalPath()+PATH_SEPARATOR; + final File tmp_file = new File(filesdir+AppConstants.APPLICATIONS_LIST_FILE_NAME_TMP); + final File real_file = new File(filesdir+AppConstants.APPLICATIONS_LIST_FILE_NAME); - if ( tmp_file.length() != real_file.length() ) { - //only use tmp file if content has changed + if (tmp_file.length() != real_file.length()) { tmp_file.renameTo(real_file); } else { tmp_file.delete(); } - } catch (Exception e) { - Log.e(TAG, "Can't save file with package list: "+e.toString()); + } catch (Exception exception) { + Timber.w(exception); } } @@ -403,7 +396,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene * Prepare the list of files and SyncedFileState for synchronisation */ private void scanLocalFiles(){ - Log.i( TAG, "scanLocalFiles()" ); + Timber.i("scanLocalFiles()"); final List fileList = new ArrayList<>(); final List folderIdList= new ArrayList<>(); boolean contentToSyncFound = false; @@ -413,7 +406,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene while(iterator.hasNext()) { final SyncedFolder syncedFolder = iterator.next(); - Log.d(TAG, "SyncedFolder :"+syncedFolder.getLibelle()+", "+syncedFolder.getLocalFolder()+", "+syncedFolder.getLastModified()+", "+syncedFolder.isScanLocal()+", "+syncedFolder.getId() ); + Timber.v("SyncedFolder : %s, %s, %s, %s, %s", syncedFolder.getLibelle(), syncedFolder.getLocalFolder(), syncedFolder.getLastModified(), syncedFolder.isScanLocal(), syncedFolder.getId()); //Check it's not a hidden file final String fileName = CommonUtils.getFileNameFromPath(syncedFolder.getLocalFolder()); @@ -433,7 +426,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene final File localDirectory = new File(syncedFolder.getLocalFolder()); //Obtention du fichier local - Log.d(TAG, "Local Folder (last modified / exists): "+localDirectory.lastModified()+", "+localDirectory.exists() ); + Timber.v("Local Folder (last modified / exists): %s, %s", localDirectory.lastModified(),localDirectory.exists()); if (!localDirectory.exists()) { contentToSyncFound = true; @@ -459,7 +452,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene iterator.add(subSyncedFolder); iterator.previous(); } else if (contentToSyncFound) { - Log.v(TAG, "added subfile " + subFile.getAbsolutePath() + " into list of file to sync"); + Timber.v("added %s into list of file to scan", subFile.getAbsolutePath()); fileList.add(subFile); } } -- GitLab From f12e821966f17c430b44d587a4877ce01ceaeb86 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 28 Sep 2022 11:25:01 +0200 Subject: [PATCH 05/20] Replace Log in InitializerService to use Timber --- .../e/drive/services/InitializerService.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) 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 b53fc320..6b310f49 100644 --- a/app/src/main/java/foundation/e/drive/services/InitializerService.java +++ b/app/src/main/java/foundation/e/drive/services/InitializerService.java @@ -18,7 +18,6 @@ import android.content.SharedPreferences; import android.os.Build; import android.os.Environment; import android.os.IBinder; -import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; @@ -30,6 +29,7 @@ import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; +import timber.log.Timber; import static com.owncloud.android.lib.resources.files.FileUtils.PATH_SEPARATOR; import static foundation.e.drive.utils.AppConstants.MEDIA_SYNCABLE_CATEGORIES; @@ -44,27 +44,26 @@ import androidx.work.WorkManager; * @author Abhishek Aggarwal */ public class InitializerService extends Service { - private final String TAG = InitializerService.class.getSimpleName(); private List syncedFolders; private OwnCloudClient cloudClient; private Account account; @Override public void onCreate() { - Log.i(TAG, "onCreate()"); + Timber.tag(InitializerService.class.getSimpleName()); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.i(TAG, "onStartCommand(...)"); + Timber.i("onStartCommand()"); CommonUtils.setServiceUnCaughtExceptionHandler(this); //Get account SharedPreferences prefs = this.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); if (prefs.getBoolean(AppConstants.INITIALIZATION_HAS_BEEN_DONE, false)) { - Log.w(TAG, "Initializer has already been run"); + Timber.w("Initializer has already been done"); } else { String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); String accountType = prefs.getString(AccountManager.KEY_ACCOUNT_TYPE, ""); @@ -80,7 +79,7 @@ public class InitializerService extends Service { } if (accountName.isEmpty()) { - Log.w(TAG, "Account's name not found. Neither in shared prefs nor in intent's extras"); + Timber.w("Account's name not found"); stopSelf(); } else { this.account = CommonUtils.getAccount(accountName, accountType, AccountManager.get(this)); @@ -89,7 +88,7 @@ public class InitializerService extends Service { this.cloudClient = DavClientProvider.getInstance().getClientInstance(account, getApplicationContext()); start(); } else { - Log.w(TAG, "Got account is invalid."); + Timber.w("Got account is invalid"); stopSelf(); } } @@ -98,7 +97,7 @@ public class InitializerService extends Service { } public void start() { - Log.i(TAG, "start()"); + Timber.d("start()"); if (cloudClient == null) { stopSelf(); return; @@ -119,7 +118,7 @@ public class InitializerService extends Service { * @param categories categories indicating which syncedFolder to create */ private void getInitialSyncedFolders(List categories) { - Log.i(TAG, "getInitialSyncedFolders"); + Timber.d("getInitialSyncedFolders"); this.syncedFolders = new ArrayList<>(); @@ -166,7 +165,9 @@ public class InitializerService extends Service { false, CommonUtils.isSettingsSyncEnabled(account), false)); - } catch (Exception e) { Log.e(TAG, e.toString()); } + } catch (Exception exception) { + Timber.e(exception); + } break; } } -- GitLab From 91f02cd31b34d9fb95e2299e410601cd2bbe3e34 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 28 Sep 2022 11:33:41 +0200 Subject: [PATCH 06/20] Replace Log in ResetService to use Timber --- .../e/drive/services/ResetService.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/services/ResetService.java b/app/src/main/java/foundation/e/drive/services/ResetService.java index da07a532..77a4ca22 100644 --- a/app/src/main/java/foundation/e/drive/services/ResetService.java +++ b/app/src/main/java/foundation/e/drive/services/ResetService.java @@ -15,13 +15,13 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.IBinder; -import android.util.Log; import java.io.File; import foundation.e.drive.EdriveApplication; import foundation.e.drive.database.DbHelper; import foundation.e.drive.utils.AppConstants; +import timber.log.Timber; import static foundation.e.drive.utils.AppConstants.INITIALFOLDERS_NUMBER; import static foundation.e.drive.utils.AppConstants.INITIALIZATION_HAS_BEEN_DONE; @@ -34,11 +34,10 @@ import androidx.work.WorkManager; * Service which stop others, remove DB, clear sharedPrefs and unregister ScreenOffReceiver */ public class ResetService extends Service { - private static final String TAG = ResetService.class.getSimpleName(); @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.i(TAG, "onStartCommand()"); + Timber.tag(ResetService.class.getSimpleName()).i("onStartCommand()"); if ( intent.getExtras() != null ) { final String intent_accountName = intent.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME, ""); final String intent_accountType = intent.getExtras().getString(AccountManager.KEY_ACCOUNT_TYPE, ""); @@ -53,8 +52,8 @@ public class ResetService extends Service { stopAllServices(); - boolean result = deleteDatabase(DbHelper.DATABASE_NAME); - Log.d(TAG, "Remove Database: "+result); + final boolean result = deleteDatabase(DbHelper.DATABASE_NAME); + Timber.d("Remove Database: %s", result); cleanSharedPreferences(prefs); removeCachedFiles(); @@ -69,16 +68,16 @@ public class ResetService extends Service { private void stopAllServices() { Intent stopperIntent = new Intent(getApplicationContext(), ObserverService.class); boolean result = getApplicationContext().stopService( stopperIntent ); - Log.d(TAG, "stop ObserverService: "+result); + Timber.d("stop ObserverService: %s", result); stopperIntent = new Intent(getApplicationContext(), InitializerService.class); result = getApplicationContext().stopService( stopperIntent ); - Log.d(TAG, "stop InitializerService: "+result); + Timber.d("stop InitializerService: %s", result); stopperIntent = new Intent(getApplicationContext(), SynchronizationService.class); result = getApplicationContext().stopService( stopperIntent ); - Log.d(TAG, "stop SynchronizationService: "+result); + Timber.d("stop SynchronizationService: %s", result); } private void cleanSharedPreferences(SharedPreferences prefs) { @@ -97,9 +96,9 @@ public class ResetService extends Service { } private void removeCachedFiles() { - File[] cachedFiles = this.getApplicationContext().getExternalCacheDir().listFiles(); + final File[] cachedFiles = this.getApplicationContext().getExternalCacheDir().listFiles(); if (cachedFiles == null) { - Log.e(TAG, "listFiles() returned null. Returning to prevent a NPE"); + Timber.e("listFiles() returned null. preventing a NPE"); return; } -- GitLab From c082860d33defc4e2d00e0d3691c7afba450c71a Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 28 Sep 2022 11:48:44 +0200 Subject: [PATCH 07/20] Replace Log in SynchronizationService to use Timber --- .../services/SynchronizationService.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/services/SynchronizationService.java b/app/src/main/java/foundation/e/drive/services/SynchronizationService.java index 363e8167..e512ae82 100644 --- a/app/src/main/java/foundation/e/drive/services/SynchronizationService.java +++ b/app/src/main/java/foundation/e/drive/services/SynchronizationService.java @@ -18,7 +18,6 @@ import android.content.SharedPreferences; import android.os.Binder; import android.os.Handler; import android.os.IBinder; -import android.util.Log; import androidx.annotation.Nullable; @@ -42,12 +41,12 @@ import foundation.e.drive.operations.UploadFileOperation; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; +import timber.log.Timber; /** * @author Vincent Bourgmayer */ public class SynchronizationService extends Service implements OnRemoteOperationListener { - private final static String TAG = SynchronizationService.class.getSimpleName(); private final SynchronizationBinder binder = new SynchronizationBinder(); private final static int FAILURE_LIMIT = 3; private ConcurrentLinkedDeque syncRequestQueue; @@ -61,9 +60,15 @@ public class SynchronizationService extends Service implements OnRemoteOperation private NextcloudClient ncClient; private Handler handler; + @Override + public void onCreate() { + super.onCreate(); + Timber.tag(SynchronizationService.class.getSimpleName()); + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "onStartCommand()"); + Timber.i("onStartCommand()"); final SharedPreferences prefs = this.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); @@ -71,7 +76,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation account = CommonUtils.getAccount(accountName, accountType, AccountManager.get(this)); if (account == null) { - Log.w(TAG, "No account available. Stop SynchronizationService"); + Timber.w("No account available"); stopSelf(); return START_NOT_STICKY; } @@ -94,7 +99,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation @Override public void onLowMemory() { - Log.w(TAG, "System is low on memory. Service might get killed."); + Timber.w("System is low on memory. Service might get killed."); } @@ -143,7 +148,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation } public void startSynchronization(){ - Log.d(TAG, "startAllThreads"); + Timber.i("startAllThreads"); for(int i =-1; ++i < workerAmount;){ this.startWorker(i); } @@ -161,7 +166,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation if (operation != null) { if (CommonUtils.isThisSyncAllowed(account, request.getSyncedFileState().isMediaType())) { CommonUtils.createNotificationChannel(this); - Log.v(TAG, " starts " + request.getSyncedFileState().getName() + Timber.v(" starts " + request.getSyncedFileState().getName() + " " + request.getOperationType().name() + " on thread " + threadIndex); threadPool[threadIndex] = operation.execute(ocClient, this, handler); startedSync.put(threadIndex, syncWrapper); @@ -187,7 +192,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation @Override public void onRemoteOperationFinish(RemoteOperation callerOperation, RemoteOperationResult result) { - Log.d(TAG, "onRemoteOperationFinish()"); + Timber.i("onRemoteOperationFinish()"); SyncWrapper callerWrapper = null; for (Map.Entry keyValue : startedSync.entrySet()) { if (keyValue.getValue().getRemoteOperation().equals(callerOperation)) { @@ -211,42 +216,42 @@ public class SynchronizationService extends Service implements OnRemoteOperation final String operationClassName = callerOperation.getClass().getSimpleName(); switch (result.getCode()) { case OK: - Log.d(TAG, operationClassName + " Succeed"); + Timber.d("%s Succeed", operationClassName); break; case SYNC_CONFLICT: //Case specific to UploadFileOperation - Log.e(TAG, operationClassName+" : Sync_conflict : File is already up to date"); + Timber.e("%s : Sync_conflict : File is already up to date", operationClassName); break; case INVALID_OVERWRITE: - Log.e(TAG, operationClassName + " => invalid_overwrite :\n remote file and local file doesn't have the same size"); + Timber.e("%s => invalid_overwrite :\n remote file and local file doesn't have the same size", operationClassName); break; case UNKNOWN_ERROR: if (callerOperation instanceof UploadFileOperation) { final int rowAffected = DbHelper.forceFoldertoBeRescan(((UploadFileOperation) callerOperation).getSyncedState().getId(), getApplicationContext()); - Log.e(TAG, " Upload failed for unknown reason.\n Force folder to be rescan next time (row affected) :" + rowAffected); + Timber.e("Upload failed for unknown reason.\n Force folder to be rescan next time (row affected) : %s", rowAffected); } else if (callerOperation instanceof DownloadFileOperation) { - Log.e(TAG, " Download: Unknown_error : failed"); + Timber.e("Download: Unknown_error : failed"); } break; case FORBIDDEN: if (callerOperation instanceof UploadFileOperation) { final int rowAffected = DbHelper.forceFoldertoBeRescan(((UploadFileOperation) callerOperation).getSyncedState().getId(), getApplicationContext()); - Log.e(TAG, " Upload: Forbidden : Can't get syncedFileState, no remote path defined. Force folder to be rescan next time (row affected) :" + rowAffected); + Timber.e("Upload: Forbidden : Can't get syncedFileState, no remote path defined. Force folder to be rescan next time (row affected) : %s", rowAffected); } else if (callerOperation instanceof DownloadFileOperation) { - Log.e(TAG, "Download : Forbidden: Can't get syncedFileState, no local path defined"); + Timber.e("Download : Forbidden: Can't get syncedFileState, no local path defined"); } break; case QUOTA_EXCEEDED: //Case specific to UploadFileOperation - Log.w(TAG, "Quota_EXCEEDED"); + Timber.w("Quota_EXCEEDED"); break; case FILE_NOT_FOUND: //Case specific to DownloadFileOperation - Log.e(TAG, operationClassName+" : File_not_found: File not found after download"); + Timber.e("%s : File_not_found: File not found after download", operationClassName); break; case ETAG_UNCHANGED: //Case specific to DownloadFileOperation - Log.e(TAG, operationClassName+" : Sync_conflict: File is already up to date"); + Timber.e("%s : Sync_conflict: File is already up to date", operationClassName); break; } } -- GitLab From 475839c5b2b87e446a44a34ba3c83d2561b59726 Mon Sep 17 00:00:00 2001 From: Jonathan Klee Date: Thu, 29 Sep 2022 07:43:26 +0000 Subject: [PATCH 08/20] Apply 1 suggestion(s) to 1 file(s) --- .../java/foundation/e/drive/database/SyncedFileStateDAO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java index c7522735..a2433dcb 100644 --- a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java +++ b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java @@ -119,7 +119,7 @@ class SyncedFileStateDAO { * @return number of deleted input */ public int deleteUnscannableMediaFiles() { - return mDB.delete(TABLE_NAME, IS_MEDIA_TYPE + " =1 AND "+SCANNABLE+" =0", null); + return mDB.delete(TABLE_NAME, IS_MEDIA_TYPE + " =1 AND " + SCANNABLE + " =0", null); } /** -- GitLab From 1cd92a980013aeb66bd677f703e6b626985ac635 Mon Sep 17 00:00:00 2001 From: Vincent Bourgmayer Date: Mon, 3 Oct 2022 12:06:39 +0000 Subject: [PATCH 09/20] Replace android logging by Timber logging in packages: - fileObservers - database - ContentScanner --- .../FileObservers/FileEventListener.java | 28 ++-- .../contentScanner/LocalContentScanner.java | 15 +- .../contentScanner/RemoteContentScanner.java | 19 ++- .../foundation/e/drive/database/DbHelper.java | 128 +++++++++--------- .../e/drive/database/SyncedFileStateDAO.java | 38 ++---- .../e/drive/database/SyncedFolderDAO.java | 60 ++++---- 6 files changed, 124 insertions(+), 164 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java b/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java index 43266bee..b047c955 100644 --- a/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java +++ b/app/src/main/java/foundation/e/drive/FileObservers/FileEventListener.java @@ -14,7 +14,6 @@ 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; @@ -27,18 +26,19 @@ import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.services.SynchronizationService; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.SynchronizationServiceConnection; +import timber.log.Timber; /** * @author Narinder Rana * @author vincent Bourgmayer */ public class FileEventListener { - private static final String TAG = FileEventListener.class.getSimpleName(); private final Context appContext; private final SynchronizationServiceConnection serviceConnection = new SynchronizationServiceConnection(); public FileEventListener(Context applicationContext) { + Timber.tag(FileEventListener.class.getSimpleName()); this.appContext = applicationContext; } @@ -66,7 +66,7 @@ public class FileEventListener { handleFileDelete(file); break; case FileObserver.MOVE_SELF: //todo to be able to catch that, we probably need a buffer to catch a succession (MOVE_FROM, MOVE_TO, then MOVE_SELF). - Log.d(TAG, file.getAbsolutePath() + " has been moved. Not handled yet"); + Timber.d("%s has been moved. Not handled yet", file.getAbsolutePath()); break; default: break; @@ -90,7 +90,7 @@ public class FileEventListener { handleDirectoryDelete(dir); break; case FileObserver.MOVE_SELF: - Log.d(TAG, dir.getAbsolutePath() + " has been moved. Not handled yet"); + Timber.d("%s has been moved. Not handled yet", dir.getAbsolutePath()); break; default: break; @@ -102,12 +102,12 @@ public class FileEventListener { * @param request */ private void sendSyncRequestToSynchronizationService(SyncRequest request) { - Log.d(TAG, "Sending a SyncRequest for " + request.getSyncedFileState().getName()); + Timber.d("Sending a SyncRequest for %s", request.getSyncedFileState().getName()); if (serviceConnection.isBoundToSynchronizationService()) { serviceConnection.getSynchronizationService().queueSyncRequest(request); serviceConnection.getSynchronizationService().startSynchronization(); }else{ - Log.w(TAG, "Impossible to send SyncRequest. FileEventListener is not bound to SynchronizationService"); + Timber.d("Impossible to send SyncRequest. FileEventListener is not bound to SynchronizationService"); } } @@ -117,7 +117,7 @@ public class FileEventListener { * @param directory */ private void handleDirectoryCreate(File directory) { - Log.d(TAG, "handleDirectoryCreate(" + directory.getAbsolutePath() + ")"); + Timber.d("handleDirectoryCreate( %s )",directory.getAbsolutePath()); final String parentPath = CommonUtils.getLocalPath(directory.getParentFile()); final SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(parentPath, appContext); if (parentFolder != null) { @@ -133,7 +133,7 @@ public class FileEventListener { */ private void handleDirectoryCloseWrite(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); - Log.d(TAG, "handleDirectoryCloseWrite(" + fileLocalPath + ")"); + Timber.d("handleDirectoryCloseWrite( %s )",fileLocalPath ); final SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { handleDirectoryCreate(directory); //todo check if really relevant @@ -149,7 +149,7 @@ public class FileEventListener { */ private void handleDirectoryDelete(File directory) { final String fileLocalPath = CommonUtils.getLocalPath(directory); - Log.d(TAG, "handleDirectoryDelete("+fileLocalPath+")"); + Timber.d("handleDirectoryDelete( %s )", fileLocalPath); SyncedFolder folder = DbHelper.getSyncedFolderByLocalPath(fileLocalPath, appContext); if (folder == null) { //look for parent @@ -173,7 +173,7 @@ public class FileEventListener { */ private void handleFileCloseWrite(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); - Log.d(TAG, "handleFileCloseWrite("+fileLocalPath+")"); + Timber.d("handleFileCloseWrite( %s )", fileLocalPath); SyncRequest request = null; SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); @@ -181,7 +181,7 @@ public class FileEventListener { 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()); + Timber.w("Won't send sync request: no parent are known for new file: %s", file.getName()); return; } int scannableValue = 0; @@ -197,7 +197,7 @@ public class FileEventListener { fileState.setId(storedId); request = new SyncRequest(fileState, UPLOAD); } else { - Log.w(TAG, "New File " + file.getName() + " observed but impossible to insert it in DB"); + Timber.d("New File %s observed but impossible to insert it in DB", file.getName()); } } else { //File update if (fileState.getScannable() > 1) { @@ -215,7 +215,7 @@ public class FileEventListener { */ private void handleFileDelete(File file) { final String fileLocalPath = CommonUtils.getLocalPath(file); - Log.d(TAG, "handleFileDelete("+fileLocalPath+")"); + Timber.d("handleFileDelete( %s )",fileLocalPath); final SyncedFileState fileState = DbHelper.loadSyncedFile( appContext, fileLocalPath, true); if (fileState == null) { return; //Todo #1: should we call handleDirectoryDelete before to return ? @@ -232,7 +232,7 @@ public class FileEventListener { if (serviceConnection.isBoundToSynchronizationService()) appContext.unbindService(serviceConnection); else - Log.w(TAG, "Not bound to SynchronizationService: can't unbind."); + Timber.w("Not bound to SynchronizationService: can't unbind."); } public void bindToSynchronizationService(){ diff --git a/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java b/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java index 5864c980..23ac48db 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java +++ b/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java @@ -9,7 +9,6 @@ package foundation.e.drive.contentScanner; import android.accounts.Account; import android.content.Context; -import android.util.Log; import java.io.File; import java.util.List; @@ -20,6 +19,7 @@ import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.FileDiffUtils; +import timber.log.Timber; /** * Class to encapsulate function about scanning local file and @@ -27,10 +27,9 @@ import foundation.e.drive.utils.FileDiffUtils; */ public class LocalContentScanner extends AbstractContentScanner{ - private static final String TAG = LocalContentScanner.class.getSimpleName(); - public LocalContentScanner(Context context, Account account, List syncedFolders) { super(context, account, syncedFolders); + Timber.tag(LocalContentScanner.class.getSimpleName()); } @Override @@ -42,11 +41,11 @@ public class LocalContentScanner extends AbstractContentScanner{ final File file = new File(fileState.getLocalPath()); if (file.exists()) { - Log.w(TAG, "Expected " + file.getAbsolutePath() + "to be missing. but it still exists"); + Timber.d("Expected %s to be missing. but it still exists", file.getAbsolutePath()); return; } - Log.i(TAG, "Add remove SyncRequest for file " + file.getAbsolutePath()); + Timber.d("Add remove SyncRequest for file %s", file.getAbsolutePath()); syncRequests.put(fileState.getId(), new SyncRequest(fileState, SyncRequest.Type.REMOTE_DELETE)); } @@ -69,17 +68,17 @@ public class LocalContentScanner extends AbstractContentScanner{ int storedId = DbHelper.manageSyncedFileStateDB(newSyncedFileState, "INSERT", context); if (storedId > 0){ newSyncedFileState.setId( storedId ); - Log.i(TAG, "Add upload SyncRequest for new file " + filePath); + Timber.d("Add upload SyncRequest for new file %s", filePath); syncRequests.put(storedId, new SyncRequest(newSyncedFileState, SyncRequest.Type.UPLOAD)); } else { - Log.w(TAG, "Failed to insert (in DB) new SyncedFileState for " + filePath); + Timber.d("Failed to insert (in DB) new SyncedFileState for %s", filePath); } } @Override protected void onKnownFileFound(File file, SyncedFileState fileState) { if (FileDiffUtils.getActionForFileDiff(file, fileState) == FileDiffUtils.Action.Upload) { - Log.d(TAG, "Add upload SyncRequest for " + file.getAbsolutePath()); + Timber.d("Add upload SyncRequest for %s", file.getAbsolutePath()); syncRequests.put(fileState.getId(), new SyncRequest(fileState, SyncRequest.Type.UPLOAD)); } } diff --git a/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java b/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java index 4f424bb2..047bd8ff 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java +++ b/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java @@ -12,7 +12,6 @@ import static foundation.e.drive.utils.FileDiffUtils.getActionForFileDiff; import android.accounts.Account; import android.content.Context; import android.provider.MediaStore; -import android.util.Log; import com.owncloud.android.lib.resources.files.model.RemoteFile; @@ -25,13 +24,13 @@ import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.FileDiffUtils; +import timber.log.Timber; /** * Implementation of AbstractContentScanner for RemoteFile * @author vincent Bourgmayer */ public class RemoteContentScanner extends AbstractContentScanner { - private static final String TAG = RemoteContentScanner.class.getSimpleName(); /** * @param context Context used to access Database, etc. @@ -39,6 +38,7 @@ public class RemoteContentScanner extends AbstractContentScanner { */ public RemoteContentScanner(Context context, Account account, List syncedFolders) { super(context, account, syncedFolders); + Timber.tag(RemoteContentScanner.class.getSimpleName()); } @Override @@ -46,14 +46,14 @@ public class RemoteContentScanner extends AbstractContentScanner { final FileDiffUtils.Action action = getActionForFileDiff(file, fileState); if (action == FileDiffUtils.Action.Download) { - Log.d(TAG, "Add download SyncRequest for " + file.getRemotePath()); + Timber.d("Add download SyncRequest for %s", file.getRemotePath()); syncRequests.put(fileState.getId(), new DownloadRequest(file, fileState)); } else if (action == FileDiffUtils.Action.updateDB) { fileState.setLastETAG(file.getEtag()); final int affectedRows = DbHelper.manageSyncedFileStateDB(fileState, "UPDATE", context); - if (affectedRows == 0) Log.e(TAG, "Error while updating eTag in DB for: " + file.getRemotePath()); + if (affectedRows == 0) Timber.d("Error while updating eTag in DB for: %s", file.getRemotePath()); } } @@ -78,21 +78,20 @@ public class RemoteContentScanner extends AbstractContentScanner { final int storedId = DbHelper.manageSyncedFileStateDB(newFileState, "INSERT", context); if (storedId > 0) { newFileState.setId(storedId); - Log.d(TAG, "Add downloadSyncRequest for new remote file: " + remoteFilePath); + Timber.d("Add downloadSyncRequest for new remote file: %s", remoteFilePath); this.syncRequests.put(storedId, new DownloadRequest(file, newFileState)); } else { - Log.w(TAG, "Failed to insert (in DB) new SyncedFileState for remote file " + remoteFilePath); + Timber.d("Failed to insert (in DB) new SyncedFileState for remote file %s", remoteFilePath); } } @Override protected void onMissingRemoteFile(SyncedFileState fileState) { if (!CommonUtils.isThisSyncAllowed(account, fileState.isMediaType())) { - Log.d(TAG, "Sync of current file: " + fileState.getName() + " isn't allowed"); + Timber.d("Sync of current file: %s isn't allowed", fileState.getName()); return; } - //Check that file has already been synced fully if (!fileState.hasBeenSynchronizedOnce()) { return; } @@ -107,12 +106,12 @@ public class RemoteContentScanner extends AbstractContentScanner { new String[]{CommonUtils.getLocalPath(file)}); if (!file.delete()) { //May throw SecurityException or IOException - Log.w(TAG, "local file (" + file.getName() + ") removal failed."); + Timber.d("local file ( %s ) removal failed",file.getName()); return; } if (DbHelper.manageSyncedFileStateDB(fileState, "DELETE", context) <= 0) { - Log.e(TAG, "Failed to remove " + file.getName() + " from DB"); + Timber.e("Failed to remove %s from DB", file.getName()); } } diff --git a/app/src/main/java/foundation/e/drive/database/DbHelper.java b/app/src/main/java/foundation/e/drive/database/DbHelper.java index 54708046..ee94b9f9 100644 --- a/app/src/main/java/foundation/e/drive/database/DbHelper.java +++ b/app/src/main/java/foundation/e/drive/database/DbHelper.java @@ -13,7 +13,6 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; import java.io.File; import java.io.FileInputStream; @@ -27,6 +26,7 @@ import java.util.List; import foundation.e.drive.BuildConfig; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.models.SyncedFileState; +import timber.log.Timber; /** * @author Vincent Bourgmayer @@ -34,7 +34,7 @@ import foundation.e.drive.models.SyncedFileState; * https://vogella.developpez.com/tutoriels/android/utilisation-base-donnees-sqlite/ */ public final class DbHelper extends SQLiteOpenHelper { - final private static String TAG = DbHelper.class.getSimpleName(); //Tag for log + private static final int DATABASE_VERSION = 20; //16/03/2022 public static final String DATABASE_NAME = "eelo_drive.db"; @@ -43,6 +43,7 @@ public final class DbHelper extends SQLiteOpenHelper { */ public DbHelper(Context context){ super(context, DATABASE_NAME, null, DATABASE_VERSION); + Timber.tag(DbHelper.class.getSimpleName()); } /** @@ -63,7 +64,7 @@ public final class DbHelper extends SQLiteOpenHelper { */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.i(TAG, "onUpgrade(db, "+oldVersion+", "+newVersion+")"); + Timber.i("onUpgrade(db, %s, %s)",oldVersion, newVersion); try { if (oldVersion < 19) { db.execSQL(SyncedFolderContract.UPDATE_TABLE_TO_VERSION_19); @@ -78,29 +79,29 @@ public final class DbHelper extends SQLiteOpenHelper { db.execSQL(SyncedFileStateContract.UPDATE_MEDIA_DATA_TO_VERSION_20); db.execSQL(SyncedFileStateContract.UPDATE_SETTINGS_DATA_TO_VERSION_20); } - } catch(Exception e) { - Log.e(TAG, e.getMessage()); + } catch(Exception exception) { + Timber.e(exception); } } private static SyncedFileStateDAO openSyncedFileStateDAO(Context context, boolean writeMod){ - SyncedFileStateDAO dao = new SyncedFileStateDAO(context); - try{ + final SyncedFileStateDAO dao = new SyncedFileStateDAO(context); + try { dao.open(writeMod); - }catch (Exception e){ - Log.e(TAG, e.toString()); + } catch (Exception exception) { //todo catch SQLiteException instead or throw it and handle it in higher stack + Timber.e(exception); return null; } return dao; } private static SyncedFolderDAO openSyncedFolderDAO(Context context, boolean writeMod){ - SyncedFolderDAO dao = new SyncedFolderDAO(context); - try{ + final SyncedFolderDAO dao = new SyncedFolderDAO(context); + try { dao.open(writeMod); - }catch(Exception e){ - Log.e(TAG, e.toString() ); + } catch(Exception exception) { //todo catch SQLiteException instead or throw it and handle it in higher stack + Timber.e(exception); return null; } return dao; @@ -114,20 +115,17 @@ public final class DbHelper extends SQLiteOpenHelper { * but if it is an insert then it return the id of the inserted data. */ public static int manageSyncedFileStateDB(SyncedFileState syncedFileState, String action, Context context){ - Log.i(TAG, "manageSyncedFileStateDB()"); + Timber.d("manageSyncedFileStateDB( %s, %s )", syncedFileState.getName(), action); int result = -1; - SyncedFileStateDAO dao = openSyncedFileStateDAO(context, true); - if(dao != null){ - if(action.equals( "UPDATE") ) { - Log.d(TAG, "DB Update for "+syncedFileState.getName() ); + final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, true); + if (dao != null) { + if (action.equals( "UPDATE")) { result = dao.update(syncedFileState); - }else if(action.equals("INSERT") ){ - Log.d(TAG, "DB Insert for "+syncedFileState.getName() ); + } else if (action.equals("INSERT")) { result = (int) dao.insert( syncedFileState ); } - else if(action.equals("DELETE") ) { - Log.d(TAG, "DB Delete for "+syncedFileState.getName() ); - result = dao.delete( syncedFileState.getId() ); + else if (action.equals("DELETE")) { + result = dao.delete(syncedFileState.getId()); } dao.close(); } @@ -142,9 +140,9 @@ public final class DbHelper extends SQLiteOpenHelper { * @return instance of SyncedFileState or null if it can't open DB */ public static SyncedFileState loadSyncedFile(Context context, String Path, boolean useLocalPath) { - SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); + final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); - if(dao == null){ + if (dao == null) { return null; } SyncedFileState syncedFileState = dao.getByPath(Path, useLocalPath); @@ -160,11 +158,11 @@ public final class DbHelper extends SQLiteOpenHelper { * @return empty list if DB opening failed, either return the list of SyncedFileState */ public static List getSyncedFileStatesByFolders(Context context, List ids) {//Connect to DB - SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); - if(dao == null){ + final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); + if (dao == null) { return new ArrayList<>(); } - List result = dao.getBySyncedFolderID(ids); + final List result = dao.getBySyncedFolderID(ids); dao.close(); return result; } @@ -178,15 +176,15 @@ public final class DbHelper extends SQLiteOpenHelper { public static int updateSyncedFolders(List syncedFolders, Context context){ int result = -1; - //Connect to DB - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); - if(dao == null){ + + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + if (dao == null) { return result; } - //Execute queries - int SyncedFoldersSize = syncedFolders.size(); + + final int SyncedFoldersSize = syncedFolders.size(); for(int i = 0; i < SyncedFoldersSize; ++i ){ - result += dao.update( syncedFolders.get(i) ); + result += dao.update(syncedFolders.get(i)); } dao.close(); return result; @@ -195,12 +193,12 @@ public final class DbHelper extends SQLiteOpenHelper { public static int updateSyncedFolder(SyncedFolder syncedFolder, Context context) { int result = -1; - //Connect to DB - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); - if (dao == null){ + + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + if (dao == null) { return result; } - result = dao.update( syncedFolder ); + result = dao.update(syncedFolder); dao.close(); return result; } @@ -211,12 +209,11 @@ public final class DbHelper extends SQLiteOpenHelper { * @return List a list of SyncedFolder from DB */ public static List getAllSyncedFolders(Context context) { - SyncedFolderDAO dao = openSyncedFolderDAO(context, false); + final SyncedFolderDAO dao = openSyncedFolderDAO(context, false); List mSyncedFolder = new ArrayList(); - if(dao == null){ + if (dao == null) { return mSyncedFolder; - }else { - + } else { mSyncedFolder = dao.getSyncedFolderList(SyncedFolderContract.ENABLED+" = 1 ", null ); dao.close(); return mSyncedFolder; @@ -224,12 +221,11 @@ public final class DbHelper extends SQLiteOpenHelper { } public static List getSyncedFolderList(Context context, boolean isMediaType) { - SyncedFolderDAO dao = openSyncedFolderDAO(context, false); + final SyncedFolderDAO dao = openSyncedFolderDAO(context, false); List mSyncedFolder = new ArrayList<>(); - if(dao == null){ + if (dao == null) { return mSyncedFolder; - } - else { + } else { mSyncedFolder = dao.getSyncedFolderList(SyncedFolderContract.ENABLED+" = 1 AND " +SyncedFolderContract.IS_MEDIA_TYPE+" = ?", new String[] {(isMediaType)? "1":"0"} ); dao.close(); @@ -244,12 +240,11 @@ public final class DbHelper extends SQLiteOpenHelper { * @return the id of the Synced folder or -1 if it hasn't been inserted */ public static long insertSyncedFolder(SyncedFolder mSyncedFolder, Context context){ - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); - if(dao == null){ - Log.d(TAG+"_insertSyncedFolder", "dao is null"); + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + if (dao == null) { return -2; } - long id = dao.insert(mSyncedFolder); + final long id = dao.insert(mSyncedFolder); dao.close(); return id; } @@ -261,21 +256,21 @@ public final class DbHelper extends SQLiteOpenHelper { * @return int number of row affected */ public static int deleteSyncedFolder(long id, Context context){ - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); - if(dao == null){ + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + if (dao == null) { return -1; } - int result = dao.delete(id); + final int result = dao.delete(id); dao.close(); return result; } public static SyncedFolder getSyncedFolderByLocalPath(String localPath, Context context){ - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); if (dao == null) { return null; } - SyncedFolder syncedFolder = dao.getSyncedFolderByLocalPath(localPath); + final SyncedFolder syncedFolder = dao.getSyncedFolderByLocalPath(localPath); dao.close(); return syncedFolder; } @@ -288,12 +283,12 @@ public final class DbHelper extends SQLiteOpenHelper { * @return number of row affected */ public static int forceFoldertoBeRescan(int syncedFolderId, Context context){ - SyncedFolderDAO dao = openSyncedFolderDAO(context, true); - if(dao == null){ + final SyncedFolderDAO dao = openSyncedFolderDAO(context, true); + if (dao == null) { return -1; } - int result = dao.reduceLastModifiedValue(syncedFolderId); + final int result = dao.reduceLastModifiedValue(syncedFolderId); dao.close(); return result; } @@ -310,8 +305,8 @@ public final class DbHelper extends SQLiteOpenHelper { final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); result = dao.countFileWaitingForUploadForSyncedFolder(syncedFolderID) > 0; dao.close(); - } catch (SQLiteException e) { - Log.e(TAG, "SQlite error", e); + } catch (SQLiteException exception) { + Timber.e(exception); } return result; } @@ -328,8 +323,8 @@ public final class DbHelper extends SQLiteOpenHelper { final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, false); result = dao.countFileWaitingForDownloadForSyncedFolder(syncedFolderId) > 0; dao.close(); - } catch (SQLiteException e) { - Log.e(TAG, "SQLite error", e); + } catch (SQLiteException exception) { + Timber.e(exception); } return result; } @@ -352,13 +347,12 @@ public final class DbHelper extends SQLiteOpenHelper { while ((read = src.read(buffer)) != -1) { dst.write(buffer, 0, read); } - Log.i(TAG, "Database has been dump at "+ dbDump.getAbsolutePath()); + Timber.d("Database has been dump at %s", dbDump.getAbsolutePath()); return; - } catch (IOException e) { - Log.e(TAG, "IOException", e); + } catch (IOException exception) { + Timber.d(exception); } } - Log.e(TAG,"Failed to dump Database"); } /** @@ -367,7 +361,7 @@ public final class DbHelper extends SQLiteOpenHelper { * @throws SQLiteException if database can't be open */ public static void cleanSyncedFileStateTableAfterUpdate(Context context) throws SQLiteException { - SyncedFileStateDAO dao = openSyncedFileStateDAO(context, true); + final SyncedFileStateDAO dao = openSyncedFileStateDAO(context, true); dao.deleteHiddenFileStates(); dao.deleteUnscannableMediaFiles(); dao.close(); diff --git a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java index c7522735..8093770f 100644 --- a/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java +++ b/app/src/main/java/foundation/e/drive/database/SyncedFileStateDAO.java @@ -17,12 +17,12 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDoneException; import android.database.sqlite.SQLiteStatement; -import android.util.Log; import java.util.ArrayList; import java.util.List; import foundation.e.drive.models.SyncedFileState; +import timber.log.Timber; import static foundation.e.drive.database.SyncedFileStateContract.SCANNABLE; import static foundation.e.drive.database.SyncedFileStateContract.TABLE_NAME; @@ -34,19 +34,17 @@ import static foundation.e.drive.database.SyncedFileStateContract.LOCAL_PATH; import static foundation.e.drive.database.SyncedFileStateContract.REMOTE_PATH; import static foundation.e.drive.database.SyncedFileStateContract.SYNCEDFOLDER_ID; - /** * @author Vincent Bourgmayer * Offers Query to CRUD operation for SyncedFIleState Object */ class SyncedFileStateDAO { - final private static String TAG = SyncedFileStateDAO.class.getSimpleName(); //Tag for log - private SQLiteDatabase mDB; private final DbHelper mHelper; SyncedFileStateDAO(Context context){ this.mHelper = new DbHelper(context); + Timber.tag(SyncedFileStateDAO.class.getSimpleName()); } /** @@ -71,7 +69,7 @@ class SyncedFileStateDAO { * @return a ContentValues object */ private ContentValues toContentValues(SyncedFileState syncedFileState) { - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put( FILE_NAME, syncedFileState.getName() ); values.put( LOCAL_PATH, syncedFileState.getLocalPath() ); values.put( REMOTE_PATH, syncedFileState.getRemotePath() ); @@ -104,7 +102,6 @@ class SyncedFileStateDAO { + " = " + id, null); } - /** * Remove SyncedFileState for hidden files (starting with '.') * @return number of deleted input @@ -122,33 +119,16 @@ class SyncedFileStateDAO { return mDB.delete(TABLE_NAME, IS_MEDIA_TYPE + " =1 AND "+SCANNABLE+" =0", null); } - /** - * Delete each syncedFileState which is bound to syncedFOlder with specified ID - * @param folderId syncedFolder's id used as foreign key - * @return number of row affected - */ - public int deleteByFolder(long folderId) { - return mDB.delete(TABLE_NAME, SYNCEDFOLDER_ID - + " = " + folderId, null); - } - /** * Update a specific syncedFile * @param syncedFileState SyncedFileState to update * @return number of row affected */ int update(SyncedFileState syncedFileState){ - int result = 0; - try{ - result = mDB.update(TABLE_NAME, + return mDB.update(TABLE_NAME, toContentValues(syncedFileState), SyncedFileStateContract._ID+" = "+syncedFileState.getId(), null); - }catch(Exception e){ - Log.e(TAG, e.toString()); - } - - return result; } @@ -217,10 +197,10 @@ class SyncedFileStateDAO { } } } - Log.d(TAG+"_getBySyncedFolderID(...)", query); - Cursor cursor = mDB.rawQuery(query, null); + Timber.v("getBySyncedFolderID's query: %s", query); + final Cursor cursor = mDB.rawQuery(query, null); cursor.moveToFirst(); - List result = new ArrayList<>(); + final List result = new ArrayList<>(); while(!cursor.isAfterLast() ) { result.add( cursorToSyncedFileState(cursor) ); cursor.moveToNext(); @@ -254,10 +234,10 @@ class SyncedFileStateDAO { query +=" like \""+path+"\""; - Cursor cursor = mDB.rawQuery(query, null); + final Cursor cursor = mDB.rawQuery(query, null); cursor.moveToFirst(); SyncedFileState syncedFileState = null; - if ( !cursor.isAfterLast()) { + if (!cursor.isAfterLast()) { syncedFileState = cursorToSyncedFileState(cursor); } cursor.close(); diff --git a/app/src/main/java/foundation/e/drive/database/SyncedFolderDAO.java b/app/src/main/java/foundation/e/drive/database/SyncedFolderDAO.java index 4e63e002..ec5c818d 100644 --- a/app/src/main/java/foundation/e/drive/database/SyncedFolderDAO.java +++ b/app/src/main/java/foundation/e/drive/database/SyncedFolderDAO.java @@ -14,11 +14,12 @@ import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; -import android.util.Log; import java.util.ArrayList; import java.util.List; import foundation.e.drive.models.SyncedFolder; +import timber.log.Timber; + import static foundation.e.drive.database.SyncedFolderContract.CATEGORIE_LABEL; import static foundation.e.drive.database.SyncedFolderContract.ENABLED; import static foundation.e.drive.database.SyncedFolderContract.LAST_ETAG; @@ -34,10 +35,10 @@ import com.owncloud.android.lib.resources.files.FileUtils; /** * @author Vincent Bourgmayer + * //todo put consistency in method's visibility * Source: https://vogella.developpez.com/tutoriels/android/utilisation-base-donnees-sqlite/ */ class SyncedFolderDAO { - final private static String TAG = SyncedFolderDAO.class.getSimpleName(); //Tag for log private SQLiteDatabase mDB; private final DbHelper mHelper; private final String[] allColumns = { SyncedFolderContract._ID, @@ -53,6 +54,7 @@ class SyncedFolderDAO { }; SyncedFolderDAO(Context context){ + Timber.tag(SyncedFolderDAO.class.getSimpleName()); this.mHelper = new DbHelper(context); } @@ -78,7 +80,7 @@ class SyncedFolderDAO { * @return ContentValues object */ private ContentValues toContentValues(SyncedFolder syncedFolder){ - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put( CATEGORIE_LABEL, syncedFolder.getLibelle() ); values.put( LOCAL_PATH, syncedFolder.getLocalFolder() ); values.put( REMOTE_PATH, syncedFolder.getRemoteFolder() ); @@ -117,71 +119,58 @@ class SyncedFolderDAO { * @return Number of row affected */ public int update(SyncedFolder syncedFolder){ - int result = 0; - try{ - result = mDB.update(TABLE_NAME, - toContentValues(syncedFolder), - SyncedFolderContract._ID+" = "+ syncedFolder.getId(), - null); - }catch(Exception e){ - Log.e(TAG, e.toString()); - } - - return result; + return mDB.update(TABLE_NAME, + toContentValues(syncedFolder), + SyncedFolderContract._ID+" = "+ syncedFolder.getId(), + null); } /** * Get list of syncedFolder * @param selection if true, return all enabled syncedFolder, if false return all disabled syncedFolder + * todo rewrite this method and at least its description because it's not clear... * @return List of all syncedFolder */ List getSyncedFolderList(String selection, String[] args) { - Log.i(TAG, "getSyncedFolderList("+selection+", "+args+")"); - List syncedFolders = new ArrayList(); - - Cursor cursor = mDB.query(TABLE_NAME, allColumns, selection,args, null, null, + final List syncedFolders = new ArrayList(); + final Cursor cursor = mDB.query(TABLE_NAME, allColumns, selection,args, null, null, null); cursor.moveToFirst(); - while ( !cursor.isAfterLast() ) { - SyncedFolder syncedFolder = cursorToSyncedFolder(cursor); - if(syncedFolder == null ){ - Log.e(TAG, "getAllSyncedFolders : current Folder is null"); - }else { + while (!cursor.isAfterLast()) { + final SyncedFolder syncedFolder = cursorToSyncedFolder(cursor); + if (syncedFolder == null ) { + Timber.v("getSyncedFolderList : current Folder ( %s ) is null", syncedFolder.getLocalFolder()); + } else { syncedFolders.add(syncedFolder); } cursor.moveToNext(); } - // assurez-vous de la fermeture du curseur + cursor.close(); return syncedFolders; } /** * reduce to 1 the value stored in lastModified of this syncFolder . The goal is to allow app to resync this folder next time - * @param syncFolderID if true, return all enabled syncedFolder, if false return all disabled syncedFolder + * @param syncFolderID id of the synced folder to update * @return number of row affected */ int reduceLastModifiedValue(int syncFolderID) { - ContentValues values = new ContentValues(); + final ContentValues values = new ContentValues(); values.put( LOCAL_LAST_MODIFIED, 1 ); - int result = 0; - try{ - result = mDB.update(TABLE_NAME, values, + + return mDB.update(TABLE_NAME, values, SyncedFolderContract._ID+" = "+ syncFolderID, null); - }catch(Exception e){ - Log.e(TAG, e.toString()); - } - return result; } SyncedFolder getSyncedFolderByLocalPath(String localPath){ - Cursor cursor = mDB.query(TABLE_NAME, allColumns, LOCAL_PATH+" like \""+localPath+ FileUtils.PATH_SEPARATOR+"\"", new String[0], null, null, null); + final Cursor cursor = mDB.query(TABLE_NAME, allColumns, LOCAL_PATH + " like \"" + localPath + FileUtils.PATH_SEPARATOR + "\"", new String[0], null, null, null); cursor.moveToFirst(); SyncedFolder result = null; - if ( !cursor.isAfterLast() ) { + if (!cursor.isAfterLast()) { result = cursorToSyncedFolder(cursor); } cursor.close(); @@ -205,6 +194,5 @@ class SyncedFolderDAO { .setId(cursor.getInt(0) ) .setLastEtag(cursor.getString( 4 ) ) .setLastModified(cursor.getLong( 5 ) ); - } } -- GitLab From a0ae31899cc596026fa1a7564421896c0ccce65e Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 3 Oct 2022 17:33:53 +0200 Subject: [PATCH 10/20] Remove logging from foundation.e.drive.models package: - Remove logging from SyncWrapper class - Remove dead class: FileObserver --- .../e/drive/models/FileObserver.java | 33 ------------------- .../e/drive/models/SyncWrapper.java | 9 ----- 2 files changed, 42 deletions(-) delete mode 100644 app/src/main/java/foundation/e/drive/models/FileObserver.java diff --git a/app/src/main/java/foundation/e/drive/models/FileObserver.java b/app/src/main/java/foundation/e/drive/models/FileObserver.java deleted file mode 100644 index 1fe4ef23..00000000 --- a/app/src/main/java/foundation/e/drive/models/FileObserver.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright © ECORP SAS 2022. - * 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 - * http://www.gnu.org/licenses/gpl.html - */ - -package foundation.e.drive.models; - -import java.io.File; -import java.io.Serializable; -import java.util.List; - -/** - * @author Narinder Rana - */ -public class FileObserver implements Serializable { - - private List files; - public FileObserver(List files) { - this.files = files; - - } - - public List getFiles() { - return files; - } - - public void setFiles(List files) { - this.files = files; - } -} diff --git a/app/src/main/java/foundation/e/drive/models/SyncWrapper.java b/app/src/main/java/foundation/e/drive/models/SyncWrapper.java index 240352ea..40b3e3db 100644 --- a/app/src/main/java/foundation/e/drive/models/SyncWrapper.java +++ b/app/src/main/java/foundation/e/drive/models/SyncWrapper.java @@ -9,11 +9,9 @@ package foundation.e.drive.models; import android.accounts.Account; import android.content.Context; -import android.util.Log; import com.owncloud.android.lib.common.operations.RemoteOperation; -import java.io.File; import foundation.e.drive.operations.DownloadFileOperation; import foundation.e.drive.operations.RemoveFileOperation; @@ -25,7 +23,6 @@ import foundation.e.drive.operations.UploadFileOperation; * @author Vincent Bourgmayer */ public class SyncWrapper { - private final static String TAG = SyncWrapper.class.getSimpleName(); private final SyncRequest request; private final RemoteOperation remoteOperation; private boolean isRunning; @@ -64,12 +61,6 @@ public class SyncWrapper { switch (request.getOperationType()) { case UPLOAD: final SyncedFileState sfs = request.getSyncedFileState(); - final File file = new File(sfs.getLocalPath()); - if (!file.exists()) { - operation = null; - Log.w(TAG, "createRemoteOperation: local file doesn't. Can't upload"); - break; - } operation = new UploadFileOperation(sfs, account, context); break; case DOWNLOAD: -- GitLab From b4f3e63e0d44402b004484752f52552d060114c1 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 3 Oct 2022 18:11:49 +0200 Subject: [PATCH 11/20] operations pacakage: Replace android logging by Timber logging --- .../operations/DownloadFileOperation.java | 28 ++++++++--------- .../e/drive/operations/GetAliasOperation.java | 6 ++-- .../operations/ListFileRemoteOperation.java | 16 +++++----- .../drive/operations/UploadFileOperation.java | 30 +++++++------------ 4 files changed, 34 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/operations/DownloadFileOperation.java b/app/src/main/java/foundation/e/drive/operations/DownloadFileOperation.java index cc4115ee..9fe4a53c 100644 --- a/app/src/main/java/foundation/e/drive/operations/DownloadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/DownloadFileOperation.java @@ -10,17 +10,16 @@ package foundation.e.drive.operations; import android.content.Context; -import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.resources.files.DownloadFileRemoteOperation; -import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.files.model.RemoteFile; import java.io.File; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** * @author Vincent Bourgmayer @@ -28,7 +27,6 @@ import foundation.e.drive.utils.CommonUtils; * /!\ Doesn't require NextcloudClient yet */ public class DownloadFileOperation extends RemoteOperation { - private final static String TAG = DownloadFileOperation.class.getSimpleName(); private final RemoteFile remoteFile; private final Context context; @@ -38,11 +36,12 @@ public class DownloadFileOperation extends RemoteOperation { private final String previousEtag; /** - * COnstructor of download operation where syncedFileState is already known + * Constructor of download operation where syncedFileState is already known * @param remoteFile remote file to Download * @param syncedFileState SyncedFileState corresponding to remote file */ public DownloadFileOperation(RemoteFile remoteFile, SyncedFileState syncedFileState, Context context) { + Timber.tag(DownloadFileOperation.class.getSimpleName()); this.remoteFile = remoteFile; this.syncedFileState = syncedFileState; this.previousEtag = syncedFileState.getLastETAG(); @@ -52,15 +51,14 @@ public class DownloadFileOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient ownCloudClient) { - Log.i(TAG, "run(client) for "+remoteFile.getRemotePath()); + Timber.v( "run() for %s", remoteFile.getRemotePath()); if (syncedFileState.getId() == -1) { this.syncedFileState.setId(DbHelper.manageSyncedFileStateDB(this.syncedFileState, "INSERT", context)); } if (syncedFileState.getLastETAG().equals(remoteFile.getEtag()) && syncedFileState.getLocalLastModified() > 0L) { - //file is up to date - Log.w(TAG, "File already up-to-date"); + Timber.v( "%s already up-to-date", remoteFile.getRemotePath()); return new RemoteOperationResult(RemoteOperationResult.ResultCode.ETAG_UNCHANGED); } @@ -78,11 +76,11 @@ public class DownloadFileOperation extends RemoteOperation { final File tmpFile = new File(tmpFilePath); if (!tmpFile.exists()) { - Log.e(TAG, "Downloaded file doesn't exist or is null"); + Timber.d( "Missing downloaded temporary file for %s", remoteFile.getRemotePath()); resultCode = RemoteOperationResult.ResultCode.FILE_NOT_FOUND; } else if (tmpFile.length() != remoteFile.getLength()) { - Log.e(TAG, "Local and remote file doesn't have the same size"); + Timber.d( "Local and remote version of %s doesn't match", remoteFile.getRemotePath()); resultCode = RemoteOperationResult.ResultCode.INVALID_OVERWRITE; tmpFile.delete(); } else { //file has been correctly download. @@ -95,10 +93,10 @@ public class DownloadFileOperation extends RemoteOperation { } if (!tmpFile.renameTo(localFile)) { - Log.d(TAG, "failed to move " + tmpFile.getAbsolutePath() + " to " + targetPath); + Timber.d("failed to move %s to %s", tmpFile.getAbsolutePath(), targetPath); return new RemoteOperationResult(RemoteOperationResult.ResultCode.FORBIDDEN); } - Log.d(TAG, "File moved to: "+localFile.getAbsolutePath()); + syncedFileState.setLocalLastModified(localFile.lastModified()) .setLastETAG(remoteFile.getEtag()); @@ -108,13 +106,12 @@ public class DownloadFileOperation extends RemoteOperation { CommonUtils.doActionMediaScannerConnexionScanFile(context, syncedFileState.getLocalPath()); } } else { //If download failed - Log.e(TAG, "Download failed: "+downloadResult.getLogMessage()); + Timber.d("Download failed: %s, %s", downloadResult.getCode(), downloadResult.getLogMessage()); resultCode = RemoteOperationResult.ResultCode.UNKNOWN_ERROR; } if (mustRestart) { - Log.w(TAG, restartCounter+" unsuccessfull trial.s of downloading" - + remoteFile.getRemotePath()); + Timber.v("%s unsuccessfull trial.s of downloading %s", restartCounter, remoteFile.getRemotePath()); syncedFileState.setLastETAG(this.previousEtag); if (this.restartCounter < 3) { this.restartCounter += 1; @@ -125,8 +122,7 @@ public class DownloadFileOperation extends RemoteOperation { } //So now, we can update instance of SyncedState and save it to DB if (DbHelper.manageSyncedFileStateDB(syncedFileState, "UPDATE", context) <= 0) { - Log.e(TAG, "DB update failed: 0 affected row"); - //@TODO : do smtg + //todo : define what to do in this case. Is this test even relevant ? } return new RemoteOperationResult(resultCode); } diff --git a/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java b/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java index c73473d0..253127e8 100644 --- a/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java @@ -11,7 +11,6 @@ package foundation.e.drive.operations; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.common.utils.Log_OC; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.NameValuePair; @@ -22,6 +21,8 @@ import org.json.JSONObject; import java.util.ArrayList; +import timber.log.Timber; + /** * @author TheScarastic * /!\ Doesn't require NextcloudClient yet @@ -29,7 +30,6 @@ import java.util.ArrayList; public class GetAliasOperation extends RemoteOperation { - private static final String TAG = GetAliasOperation.class.getSimpleName(); private static final String ALIAS_PATH = "/ocs/v1.php/cloud/hide-my-email/"; // JSON Node names @@ -78,7 +78,7 @@ public class GetAliasOperation extends RemoteOperation { } catch (Exception e) { e.printStackTrace(); result = new RemoteOperationResult<>(e); - Log_OC.e(TAG, "Fetching aliases failed"); + Timber.tag(GetAliasOperation.class.getSimpleName()).d("Fetching aliases failed"); } finally { if (get != null) get.releaseConnection(); diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index 4867176e..0ab10daa 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -10,7 +10,6 @@ package foundation.e.drive.operations; import android.content.Context; -import android.util.Log; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -23,6 +22,7 @@ import java.util.ListIterator; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** @@ -30,7 +30,6 @@ import foundation.e.drive.utils.CommonUtils; * @author Vincent Bourgmayer */ public class ListFileRemoteOperation extends RemoteOperation> { - private final String TAG = ListFileRemoteOperation.class.getSimpleName(); private static final int HTTP_404 = 404; private final List syncedFolders; @@ -39,6 +38,7 @@ public class ListFileRemoteOperation extends RemoteOperation remoteFiles; public ListFileRemoteOperation(List syncedFolders, Context context, int initialFolderNumber) { + Timber.tag(ListFileRemoteOperation.class.getSimpleName()); this.syncedFolders = syncedFolders; this.context = context; this.initialFolderNumber = initialFolderNumber; @@ -60,8 +60,8 @@ public class ListFileRemoteOperation extends RemoteOperation Ignored"); + Timber.d("ReadFolderRemoteOperation failed : http %s, %s => ignored", result.getHttpCode(), result.getLogMessage()); } } finalResult = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK); @@ -130,7 +130,7 @@ public class ListFileRemoteOperation extends RemoteOperation uploadResult; if (file.length() >= FILE_SIZE_FLOOR_FOR_CHUNKED) { - Log.d(TAG, "upload " + file.getName() + " as chunked file"); + Timber.d("Upload %s as chunked file", file.getName()); uploadResult = uploadChunkedFile(file, client); } else { uploadResult = uploadFile(file, client); @@ -107,7 +107,7 @@ public class UploadFileOperation extends RemoteOperation { private ResultCode onUploadFailure(final ResultCode uploadResult, final String fileName) { if (uploadResult != ResultCode.CONFLICT && uploadResult != ResultCode.QUOTA_EXCEEDED) { - Log.e(TAG, "UploadFileRemoteOperation for : " + fileName + " failed => code: " + uploadResult); + Timber.d("Upload for %s failed : %s", fileName, uploadResult); return ResultCode.UNKNOWN_ERROR; } return uploadResult; @@ -125,21 +125,21 @@ public class UploadFileOperation extends RemoteOperation { */ private ResultCode checkCondition(final File file, final OwnCloudClient client) { if (file == null || !file.exists()) { - Log.w(TAG, "Can't get the file. It might have been deleted"); + Timber.d("Can't get the file. It might have been deleted"); return ResultCode.FORBIDDEN; } //If file already up-to-date & synced if (syncedState.isLastEtagStored() && syncedState.getLocalLastModified() == file.lastModified()) { - Log.d(TAG, "syncedState last modified: "+ syncedState.getLocalLastModified()+" <=> file last modified: "+file.lastModified() +": So return sync_conflict"); + Timber.d("Synchronization conflict because: last modified from DB(%s) and from file (%s) are different ", syncedState.getLocalLastModified(), file.lastModified()); return ResultCode.SYNC_CONFLICT; } final NextcloudClient ncClient = DavClientProvider.getInstance().getNcClientInstance(account, context); final RemoteOperationResult checkQuotaResult = checkAvailableSpace(ncClient, file.length()); if (checkQuotaResult.getCode() != ResultCode.OK) { - Log.e(TAG, "Impossible to check quota. Upload of " + syncedState.getLocalPath() + "cancelled"); + Timber.d("Impossible to check quota. Cancels upload of %s", syncedState.getLocalPath()); return checkQuotaResult.getCode(); } @@ -242,7 +242,7 @@ public class UploadFileOperation extends RemoteOperation { * Upload a file * note: this has been extracted from run(...) for * testing purpose - * @param client client to run the method. @TODO will be replaced by NextcloudClient in future. + * @param client client to run the method. TODO will be replaced by NextcloudClient in future. * @return RemoteOperationResult the instance must contains etag in resultData if successful. */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @@ -259,23 +259,15 @@ public class UploadFileOperation extends RemoteOperation { /** * Create remote parent folder of the file if missing * @param targetPath Path of remote directory to create or check for existence - * @param client Client to perform the request. @TODO will be replaced by NextcloudClient in future. + * @param client Client to perform the request. TODO will be replaced by NextcloudClient in future. * @return true if the parent directory has been created, false either */ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public boolean createRemoteFolder(String targetPath, OwnCloudClient client) { final String remoteFolderPath = targetPath.substring(0, targetPath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); final CreateFolderRemoteOperation createFolderOperation = new CreateFolderRemoteOperation(remoteFolderPath, true); - try{ - final RemoteOperationResult createFolderResult = createFolderOperation.execute(client); - if (createFolderResult.isSuccess() || createFolderResult.getCode() == ResultCode.FOLDER_ALREADY_EXISTS) { - return true; - } - Log.e(TAG, createFolderResult.getLogMessage()); - } catch(Exception e) { - Log.e(TAG, e.toString()); - } - return false; + final RemoteOperationResult createFolderResult = createFolderOperation.execute(client); + return createFolderResult.isSuccess() || createFolderResult.getCode() == ResultCode.FOLDER_ALREADY_EXISTS; } public SyncedFileState getSyncedState() { -- GitLab From b2c3e6af7e6c07e0577f418f80c77ffc28f7d15d Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 3 Oct 2022 18:16:56 +0200 Subject: [PATCH 12/20] receivers package: Replace android logging by Timber logging --- .../e/drive/receivers/BootCompletedReceiver.java | 9 ++++----- .../foundation/e/drive/receivers/DebugCmdReceiver.java | 7 ++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java index 779a3f6a..094cfeef 100644 --- a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java @@ -13,25 +13,24 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.sqlite.SQLiteException; -import android.util.Log; import foundation.e.drive.BuildConfig; import foundation.e.drive.database.DbHelper; import foundation.e.drive.services.InitializerService; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** * @author Abhishek Aggarwal */ public class BootCompletedReceiver extends BroadcastReceiver { - public static final String TAG = BootCompletedReceiver.class.getSimpleName(); private static final String DATE_SYSTEM_PROPERTY = "ro.build.date"; private static final String PREF_VERSION_CODE = "VERSION_CODE"; @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - Log.i(TAG, "onReceive(...)"); + Timber.tag(BootCompletedReceiver.class.getSimpleName()).v("onReceive(...)"); final SharedPreferences pref = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { if (!CommonUtils.getProp(DATE_SYSTEM_PROPERTY).equals(pref.getString(DATE_SYSTEM_PROPERTY, ""))) { @@ -48,8 +47,8 @@ public class BootCompletedReceiver extends BroadcastReceiver { pref.edit().putInt(PREF_VERSION_CODE, BuildConfig.VERSION_CODE).apply(); try { DbHelper.cleanSyncedFileStateTableAfterUpdate(context); - } catch (SQLiteException e) { - Log.e(TAG, "Can't remove entry for hidden file in Database", e); + } catch (SQLiteException exception) { + Timber.e(exception); } } } diff --git a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java index 79809dd2..afb752cc 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -14,6 +14,7 @@ import android.util.Log; import foundation.e.drive.database.DbHelper; import foundation.e.drive.services.ObserverService; +import timber.log.Timber; /** * @author Jonathan Klee @@ -23,17 +24,17 @@ public class DebugCmdReceiver extends BroadcastReceiver { public static final String ACTION_FORCE_SYNC = "foundation.e.drive.action.FORCE_SYNC"; public static final String ACTION_DUMP_DATABASE = "foundation.e.drive.action.DUMP_DATABASE"; - public static final String TAG = "DebugCmdReceiver"; @Override public void onReceive(Context context, Intent intent) { - Log.d(TAG, "onReceive"); + Timber.tag(DebugCmdReceiver.class.getSimpleName()).v("onReceive"); switch (intent.getAction()) { case ACTION_FORCE_SYNC: - Log.i(TAG, "Force Sync intent received"); + Timber.d("Force Sync intent received"); context.startService(new Intent(ACTION_FORCE_SYNC, null, context, ObserverService.class)); break; case ACTION_DUMP_DATABASE: + Timber.d("Dump database intent received"); DbHelper.dumpDatabase(context); break; default: -- GitLab From e2c8c2fc94a44f96169c501d96a72e9235e7843b Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 3 Oct 2022 18:47:24 +0200 Subject: [PATCH 13/20] utils package: replace Android logging by Timber logging --- .../foundation/e/drive/utils/CommonUtils.java | 69 ++++++------------- .../e/drive/utils/DavClientProvider.java | 21 +++--- .../drive/utils/ServiceExceptionHandler.java | 54 ++++++--------- .../SynchronizationServiceConnection.java | 9 +-- 4 files changed, 58 insertions(+), 95 deletions(-) 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 946e5c46..9542f79b 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -7,7 +7,6 @@ * http://www.gnu.org/licenses/gpl.html */ - package foundation.e.drive.utils; import android.accounts.Account; @@ -26,13 +25,13 @@ import android.net.NetworkCapabilities; import android.net.Uri; import android.os.Build; -import android.util.Log; import android.webkit.MimeTypeMap; import android.widget.Toast; import com.owncloud.android.lib.resources.files.FileUtils; import java.io.File; +import java.io.IOException; import java.lang.reflect.Method; import java.text.CharacterIterator; import java.text.StringCharacterIterator; @@ -45,6 +44,7 @@ import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.work.AccountUserInfoWorker; import foundation.e.drive.work.FullScanWorker; import foundation.e.drive.work.WorkRequestFactory; +import timber.log.Timber; import static foundation.e.drive.utils.AppConstants.MEDIASYNC_PROVIDER_AUTHORITY; import static foundation.e.drive.utils.AppConstants.METERED_NETWORK_ALLOWED_AUTHORITY; @@ -69,14 +69,12 @@ public abstract class CommonUtils { /** * Set ServiceUncaughtExceptionHandler to be the MainThread Exception Handler * Or update the service which use it - * + * todo: check if the ServiceExceptionHandler could be remove * @param service current service */ public static void setServiceUnCaughtExceptionHandler(Service service) { - Thread.UncaughtExceptionHandler defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); if (defaultUEH != null && ServiceExceptionHandler.class.getSimpleName().equals(defaultUEH.getClass().getSimpleName())) { - Log.d("ObserverService", "ServiceExceptionHandler already set!"); ((ServiceExceptionHandler) defaultUEH).setService(service); } else { Thread.setDefaultUncaughtExceptionHandler(new ServiceExceptionHandler(service)); @@ -170,13 +168,9 @@ public abstract class CommonUtils { * @return String, the last part after separator of path or null if invalid path has been provided */ public static String getFileNameFromPath(String path) { - try { - String[] splittedString = path.split(FileUtils.PATH_SEPARATOR); - return splittedString[splittedString.length - 1]; - } catch (Exception e) { - Log.e(TAG, e.toString()); - return null; - } + final String[] splittedString = path.split(FileUtils.PATH_SEPARATOR); + if (splittedString.length <= 0) return null; + return splittedString[splittedString.length - 1]; } /** @@ -187,7 +181,7 @@ public abstract class CommonUtils { * @return True if there is connection, false either */ public static boolean haveNetworkConnection(Context context, boolean meteredNetworkAllowed) { - Log.i(TAG, "haveNetworkConnection()"); + Timber.tag(TAG).v(TAG, "haveNetworkConnection()"); final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); final NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork()); @@ -210,10 +204,9 @@ public abstract class CommonUtils { * @return String containing mimeType of the file */ public static String getMimeType(File file) { - Log.i(TAG, "getMimeType()"); - String mimetype = MimeTypeMap.getSingleton().getMimeTypeFromExtension( - MimeTypeMap.getFileExtensionFromUrl( - Uri.fromFile(file).toString()).toLowerCase()); + final String mimetype = MimeTypeMap.getSingleton() + .getMimeTypeFromExtension( + MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()).toLowerCase()); if (mimetype == null) { return "*/*"; } @@ -227,15 +220,17 @@ public abstract class CommonUtils { * @param filePath String containing path the file to update by mediaScanner */ public static void doActionMediaScannerConnexionScanFile(Context context, final String filePath) { - Log.i(TAG, "doActionMediaScannerConnexionScanFile(" + filePath + ")"); + Timber.v(TAG, "doActionMediaScannerConnexionScanFile( %s )", filePath); + final String[] filePathArray = new String[] { filePath }; + final String[] mimeType = new String[] {getMimeType(new File(filePath))}; MediaScannerConnection.scanFile(context, - new String[]{filePath}, - new String[]{getMimeType(new File(filePath))}, + filePathArray, + mimeType, new MediaScannerConnection.OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { - Log.v("MediaScanWork", "file " + path - + " was scanned successfully: " + uri); + Timber.tag("MediaScannerConnection") + .v("file %s was scanned with success: %s ", path, uri); } }); } @@ -250,35 +245,13 @@ public abstract class CommonUtils { String result; try { result = file.getCanonicalPath(); - } catch (Exception e) { - Log.e(TAG, e.toString()); - result = file.getAbsolutePath(); + } catch (SecurityException | IOException exception ) { + Timber.v(exception); + result = file.getAbsolutePath(); //todo why not simply always use getAbsolutePath? } return result; } - /** - * Used for debug - * - * @param f File to debug - * @return String showing value of file's properties - * @dev-only - */ - public static String debugFile(File f) { - return "File name: " + f.getName() - + "\n File exist?: " + f.exists() - + "\n File absolute path: " + f.getAbsolutePath() - + "\n File path: " + f.getPath() - + "\n File length: " + f.length() - + "\n File last modif: " + f.lastModified() - + "\n File readable?: " + f.canRead() - + "\n File writable?: " + f.canWrite() - + "\n File is file?: " + f.isFile() - + "\n File is Dir?: " + f.isDirectory() - + "\n File can be read?: " + f.canRead() - + "\n File can be written?: " + f.canWrite(); - } - /** * Formatter class is not used since bytes passed by server are in SI unit aka 1kb = 1024byte * https://stackoverflow.com/questions/3758606/how-can-i-convert-byte-size-into-a-human-readable-format-in-java/3758880#3758880 @@ -330,7 +303,7 @@ public abstract class CommonUtils { */ public static void registerInitializationWorkers(List syncedFolders, WorkManager workManager) { if (syncedFolders == null || syncedFolders.isEmpty()) { - Log.e(TAG, "Can't create remote folders. List is empty"); + Timber.tag(TAG).d("registerInitializationWorkers: Can't create remote folders. List is empty"); return; } diff --git a/app/src/main/java/foundation/e/drive/utils/DavClientProvider.java b/app/src/main/java/foundation/e/drive/utils/DavClientProvider.java index 4ca2ce5d..6c88038f 100644 --- a/app/src/main/java/foundation/e/drive/utils/DavClientProvider.java +++ b/app/src/main/java/foundation/e/drive/utils/DavClientProvider.java @@ -13,7 +13,6 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.net.Uri; -import android.util.Log; import com.nextcloud.common.NextcloudClient; import com.nextcloud.common.OkHttpCredentialsUtil; @@ -23,12 +22,16 @@ import com.owncloud.android.lib.common.OwnCloudClientFactory; import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; import com.owncloud.android.lib.common.accounts.AccountUtils; +import timber.log.Timber; + /** * @author Vincent Bourgmayer */ public class DavClientProvider { - private static final String TAG = DavClientProvider.class.getSimpleName(); - private DavClientProvider (){} + private DavClientProvider (){ + Timber.tag(DavClientProvider.class.getSimpleName()); + } + @Deprecated private OwnCloudClient ocClientInstance; private NextcloudClient ncClientInstance; @@ -44,11 +47,11 @@ public class DavClientProvider { ocClientInstance = OwnCloudClientFactory.createOwnCloudClient(serverUri, ctx, true); final String pwd = getAcountPwd(account, ctx); - Log.d(TAG, "name: "+account.name+"\n"+AccountManager.get(ctx).getUserData(account, AccountUtils.Constants.KEY_USER_ID)); + Timber.v("name: %s \n%s", account.name, AccountManager.get(ctx).getUserData(account, AccountUtils.Constants.KEY_USER_ID)); ocClientInstance.setCredentials(new OwnCloudBasicCredentials(account.name, pwd)); - } catch (AccountUtils.AccountNotFoundException e) { - Log.e(TAG, "Can't parse serverPath to Uri : " + e.toString()); + } catch (AccountUtils.AccountNotFoundException exception) { + Timber.e(exception); return null; } } @@ -63,15 +66,15 @@ public class DavClientProvider { public NextcloudClient getNcClientInstance(final Account account, final Context ctx) { - Log.i(TAG, "getNcClientInstance()"); + Timber.v("getNcClientInstance()"); if (ncClientInstance == null) { try { final Uri serverUri = Uri.parse(AccountUtils.getBaseUrlForAccount(ctx, account)); final String credentials = OkHttpCredentialsUtil.basic(account.name, getAcountPwd(account, ctx)); ncClientInstance = OwnCloudClientFactory.createNextcloudClient(serverUri, account.name, credentials, ctx, true); - } catch (AccountUtils.AccountNotFoundException e) { - Log.e(TAG, "Can't get server URI for account: "+account.name+"\n"+e.getMessage()); + } catch (AccountUtils.AccountNotFoundException exception) { + Timber.e("Can't get server URI for account: %s\n%s", account.name,exception.getMessage()); return null; } ncClientInstance.setUserId(account.name); diff --git a/app/src/main/java/foundation/e/drive/utils/ServiceExceptionHandler.java b/app/src/main/java/foundation/e/drive/utils/ServiceExceptionHandler.java index fc5c69be..24074649 100644 --- a/app/src/main/java/foundation/e/drive/utils/ServiceExceptionHandler.java +++ b/app/src/main/java/foundation/e/drive/utils/ServiceExceptionHandler.java @@ -9,7 +9,6 @@ package foundation.e.drive.utils; import android.app.Service; import android.os.Environment; -import android.util.Log; import java.io.File; import java.io.FileOutputStream; @@ -19,10 +18,10 @@ import java.io.StringWriter; import java.lang.Thread.UncaughtExceptionHandler; /** + * todo: check if still usefull or if it can be remove * @author Vincent Bourgmayer */ public class ServiceExceptionHandler implements UncaughtExceptionHandler{ - private final static String TAG = ServiceExceptionHandler.class.getSimpleName(); public final static String CRASH_LOG_FOLDER = "crash-logs"; public final static String LOG_FILE_NAME_PREFIX = "eDrive-crash-"; public final static String LOG_FILE_EXTENSION = ".log"; @@ -44,66 +43,53 @@ public class ServiceExceptionHandler implements UncaughtExceptionHandler{ } @Override - public void uncaughtException(Thread t, Throwable e) { - Log.d(TAG, "Service class: "+service.getClass().getSimpleName()); + public void uncaughtException(Thread t, Throwable exception) { if(isExternalStorageAvailable() && !isExternalStorageReadOnly()){ - //Get TimeStamp - Long timestamp = System.currentTimeMillis(); - //Create a new file that user can sent to us - String fileName = LOG_FILE_NAME_PREFIX+timestamp+LOG_FILE_EXTENSION; + final Long timestamp = System.currentTimeMillis(); - File downloadDir = service.getApplication().getExternalFilesDir(CRASH_LOG_FOLDER); - File logFile = new File(downloadDir, fileName); - try { + final String fileName = LOG_FILE_NAME_PREFIX+timestamp+LOG_FILE_EXTENSION; - FileOutputStream fos = new FileOutputStream(logFile); + final File downloadDir = service.getApplication().getExternalFilesDir(CRASH_LOG_FOLDER); + final File logFile = new File(downloadDir, fileName); + try (FileOutputStream fos = new FileOutputStream(logFile)) { fos.write(service.getClass().getSimpleName().getBytes()); - fos.write(getStackTraceAsString(e).getBytes()); - fos.close(); + fos.write(getStackTraceAsString(exception).getBytes()); logFile.setReadable(true, false); - - } catch (IOException exception) { - exception.printStackTrace(); + } catch (IOException ioException) { + ioException.printStackTrace(); } } //source: https://stackoverflow.com/questions/9050962/rethrow-uncaughtexceptionhandler-exception-after-logging-it/9050990#9050990 if(defaultUEH != null){ - defaultUEH.uncaughtException(t, e); + defaultUEH.uncaughtException(t, exception); }else{ - Log.d(TAG, "/e/ Drive has crashed and there is no ExceptionHandler"); System.exit(1); //Kill /e/ Drive... } } //source: https://www.journaldev.com/9400/android-external-storage-read-write-save-file private static boolean isExternalStorageAvailable() { - String extStorageState = Environment.getExternalStorageState(); - if (Environment.MEDIA_MOUNTED.equals(extStorageState)) { - return true; - } - return false; + final String extStorageState = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(extStorageState); } //source: https://www.journaldev.com/9400/android-external-storage-read-write-save-file private static boolean isExternalStorageReadOnly() { - String extStorageState = Environment.getExternalStorageState(); - if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) { - return true; - } - return false; + final String extStorageState = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState); } /** * Return the stackTrace of the exception as a String - * @param e the exception + * @param exception the exception * @return the Stacktrace as a string */ - private String getStackTraceAsString(Throwable e){ - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - e.printStackTrace(pw); + private String getStackTraceAsString(Throwable exception){ + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw); + exception.printStackTrace(pw); return sw.toString(); } } \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/utils/SynchronizationServiceConnection.java b/app/src/main/java/foundation/e/drive/utils/SynchronizationServiceConnection.java index 8820dc2a..5a11626c 100644 --- a/app/src/main/java/foundation/e/drive/utils/SynchronizationServiceConnection.java +++ b/app/src/main/java/foundation/e/drive/utils/SynchronizationServiceConnection.java @@ -11,22 +11,22 @@ package foundation.e.drive.utils; import android.content.ComponentName; import android.content.ServiceConnection; import android.os.IBinder; -import android.util.Log; import foundation.e.drive.services.SynchronizationService; +import timber.log.Timber; /** * @author Vincent Bourgmayer */ public class SynchronizationServiceConnection implements ServiceConnection { - private final static String TAG = SynchronizationServiceConnection.class.getSimpleName(); private SynchronizationService synchronizationService; private boolean boundToSynchronizationService = false; @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - Log.i(TAG, "onServiceConnected: binding to SynchronizationService"); + Timber.tag(SynchronizationServiceConnection.class.getSimpleName()) + .v("binding to SynchronizationService"); SynchronizationService.SynchronizationBinder binder = (SynchronizationService.SynchronizationBinder) iBinder; synchronizationService = binder.getService(); boundToSynchronizationService = true; @@ -34,7 +34,8 @@ public class SynchronizationServiceConnection implements ServiceConnection { @Override public void onServiceDisconnected(ComponentName componentName) { - Log.i(TAG, "onServiceDisconnected: unbinding from SynchronizationService"); + Timber.tag(SynchronizationServiceConnection.class.getSimpleName()) + .v("Unbinding from SynchronizationService"); boundToSynchronizationService = false; } -- GitLab From 0bcd4715b2d60648217e3de2ab91fdc339bedb64 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 3 Oct 2022 18:53:49 +0200 Subject: [PATCH 14/20] widgets package: replace android logging by Timber logging --- .../e/drive/widgets/EDriveWidget.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java index 25d870f7..3eedd267 100644 --- a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java +++ b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java @@ -28,7 +28,6 @@ import android.net.Network; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; -import android.util.Log; import android.view.View; import android.widget.RemoteViews; @@ -38,13 +37,13 @@ import java.util.Locale; import foundation.e.drive.R; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** * @author TheScarastic * Implementation of App Widget functionality. */ public class EDriveWidget extends AppWidgetProvider { - private static final String TAG = EDriveWidget.class.getSimpleName(); public static final String WEBPAGE = "https://esolutions.shop/ecloud-subscriptions/?username=%s&token=placeholder¤t-quota=%s&from=wp"; @@ -72,8 +71,8 @@ public class EDriveWidget extends AppWidgetProvider { long convertedBytes = 0; try { convertedBytes = Long.parseLong(bytes); - } catch (NumberFormatException e) { - Log.i(TAG, "Invalid bytes " + bytes); + } catch (NumberFormatException exception) { + Timber.tag(EDriveWidget.class.getSimpleName()).i("Invalid bytes %s", bytes); } final String space = CommonUtils.humanReadableByteCountBin(convertedBytes); final String[] split = space.split(" "); @@ -224,13 +223,16 @@ public class EDriveWidget extends AppWidgetProvider { String totalShownQuota = "?"; String usedShownQuota = "?"; + + Timber.tag(EDriveWidget.class.getSimpleName()); + //todo extract following duplicated code into a dedicated function try { final long totalQuotaLong = Long.parseLong(totalQuota); if (totalQuotaLong >= 0) { totalShownQuota = CommonUtils.humanReadableByteCountBin(totalQuotaLong); } } catch (NumberFormatException ignored) { - Log.i(TAG, "Bad totalQuotaLong " + totalQuota); + Timber.d("Bad totalQuotaLong %s", totalQuota); } try { @@ -239,12 +241,12 @@ public class EDriveWidget extends AppWidgetProvider { usedShownQuota = CommonUtils.humanReadableByteCountBin(usedQuotaLong); } } catch (NumberFormatException ignore) { - Log.i(TAG, "Bad usedQuotaLong " + usedQuota); + Timber.d("Bad usedQuotaLong %s", usedQuota); } views.setTextViewText(R.id.planName, context.getString(R.string.free_plan, totalShownQuota)); - String[] groups = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS).split(","); + final String[] groups = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS).split(","); for (String group : groups) { if (group.contains("premium-")) { views.setTextViewText(R.id.planName, context.getString(R.string.premium_plan, @@ -259,7 +261,7 @@ public class EDriveWidget extends AppWidgetProvider { views.setTextViewText(R.id.sync, context.getString(R.string.last_synced, sdf.format(calender.getTime()))); - String aliases = accountManager.getUserData(account, ACCOUNT_DATA_ALIAS_KEY); + final String aliases = accountManager.getUserData(account, ACCOUNT_DATA_ALIAS_KEY); if (aliases == null || aliases.isEmpty()) { views.setViewVisibility(R.id.show_alias, View.GONE); views.setViewVisibility(R.id.alias1_container, View.GONE); @@ -304,7 +306,7 @@ public class EDriveWidget extends AppWidgetProvider { } private void registerConnectivityCallback(final Context context) { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService( + final ConnectivityManager cm = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE); cm.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() { @Override -- GitLab From 7caa4a287fa7604166e5fc2cee814184e83a7d80 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 4 Oct 2022 11:34:17 +0200 Subject: [PATCH 15/20] work package: use Timber for loggin --- .../e/drive/work/AccountUserInfoWorker.java | 12 ++++++------ .../e/drive/work/CreateRemoteFolderWorker.java | 16 +++++++--------- .../e/drive/work/FirstStartWorker.java | 6 +++--- .../foundation/e/drive/work/FullScanWorker.java | 8 ++++---- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java b/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java index 957d5eeb..6fcc83c5 100644 --- a/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java +++ b/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java @@ -23,7 +23,6 @@ import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.util.Log; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; @@ -48,13 +47,13 @@ import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import foundation.e.drive.widgets.EDriveWidget; +import timber.log.Timber; /** * @author vincent Bourgmayer * @author TheScarastic */ public class AccountUserInfoWorker extends Worker { - private static final String TAG = AccountUserInfoWorker.class.getSimpleName(); public static final String UNIQUE_WORK_NAME = "AccountUserInfoWorker"; private final AccountManager accountManager; private final GetUserInfoRemoteOperation GetUserInfoRemoteOperation = new GetUserInfoRemoteOperation(); @@ -64,6 +63,7 @@ public class AccountUserInfoWorker extends Worker { public AccountUserInfoWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); + Timber.tag(AccountUserInfoWorker.class.getSimpleName()); mContext = context; accountManager = AccountManager.get(context); } @@ -100,7 +100,7 @@ public class AccountUserInfoWorker extends Worker { final String userId = userInfo.getId(); client.setUserId(userId); AccountManager.get(mContext).setUserData(account, ACCOUNT_USER_ID_KEY, userId); - Log.v(TAG, "UserId "+ userId +" saved for account"); + Timber.v("UserId %s saved for account", userId); } final Quota userQuota = userInfo.getQuota(); final double relativeQuota = userQuota.getRelative(); @@ -117,10 +117,10 @@ public class AccountUserInfoWorker extends Worker { accountManager.setUserData(account, ACCOUNT_DATA_USED_QUOTA_KEY, "" + userQuota.getUsed()); addNotifAboutQuota(relativeQuota); - Log.d(TAG+"fetchUserInfo()", "Success"); + Timber.d("fetchUserInfo(): success"); return true; } - Log.d(TAG+"fetchUserInfo()", "Failure"); + Timber.d("fetchUserInfo(): failure"); return false; } @@ -196,7 +196,7 @@ public class AccountUserInfoWorker extends Worker { } } accountManager.setUserData(account, ACCOUNT_DATA_ALIAS_KEY, aliases); - Log.d(TAG+"fetchAliases()", "Success"); + Timber.d("fetchAliases(): success"); return true; } diff --git a/app/src/main/java/foundation/e/drive/work/CreateRemoteFolderWorker.java b/app/src/main/java/foundation/e/drive/work/CreateRemoteFolderWorker.java index 2d995c64..28005199 100644 --- a/app/src/main/java/foundation/e/drive/work/CreateRemoteFolderWorker.java +++ b/app/src/main/java/foundation/e/drive/work/CreateRemoteFolderWorker.java @@ -12,7 +12,6 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; import androidx.annotation.NonNull; import androidx.work.Data; @@ -31,6 +30,7 @@ import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; +import timber.log.Timber; /** * /!\ Doesn't require NextcloudClient yet @@ -38,7 +38,6 @@ import foundation.e.drive.utils.DavClientProvider; * @author Vincent Bourgmayer */ public class CreateRemoteFolderWorker extends Worker { - private static final String TAG = CreateRemoteFolderWorker.class.getSimpleName(); public static final String DATA_KEY_ID="id"; public static final String DATA_KEY_LIBELLE="libelle"; public static final String DATA_KEY_LOCAL_PATH="localPath"; @@ -52,6 +51,7 @@ public class CreateRemoteFolderWorker extends Worker { public CreateRemoteFolderWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); + Timber.tag(CreateRemoteFolderWorker.class.getSimpleName()); } @NonNull @@ -60,18 +60,18 @@ public class CreateRemoteFolderWorker extends Worker { final Context context = getApplicationContext(); final Account account = getAccount(); if (account == null) { - Log.e(TAG, "Can't get valid account: stop everything"); + Timber.e("doWork(): Can't get valid account"); return Result.failure(); } final boolean meteredNetworkAllowed = CommonUtils.isMeteredNetworkAllowed(account); if (!CommonUtils.haveNetworkConnection(context, meteredNetworkAllowed)) { - Log.e(TAG, "Can't create remote folder because there is no usable connection"); + Timber.d("doWork(): no usable connection"); return Result.retry(); } final SyncedFolder syncedFolder = getSyncedFolderFromData(); - Log.d(TAG, "doWork() for :"+syncedFolder.getLocalFolder()); + Timber.v("doWork() for : %s", syncedFolder.getLocalFolder()); final File folder = new File(syncedFolder.getLocalFolder() ); if (!folder.exists()) { folder.mkdirs(); @@ -81,7 +81,7 @@ public class CreateRemoteFolderWorker extends Worker { //final NextcloudClient client = DavClientProvider.getInstance().getNcClientInstance(account, context); final OwnCloudClient client = DavClientProvider.getInstance().getClientInstance(account, context); if (client == null) { - Log.e(TAG, "Can't get OwnCloudClient."); + Timber.d("doWork(): Can't get OwnCloudClient"); return Result.retry(); } @@ -90,9 +90,7 @@ public class CreateRemoteFolderWorker extends Worker { final RemoteOperationResult result = mkcolRequest.execute(client); if (result.isSuccess() || result.getCode() == RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS) { - if(DbHelper.insertSyncedFolder(syncedFolder, context) >= 0 ) { - Log.d(TAG, "Insertion in DB succeed"); - } + DbHelper.insertSyncedFolder(syncedFolder, context); return Result.success(); } diff --git a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java b/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java index c112d36e..4898f79b 100644 --- a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java +++ b/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java @@ -12,7 +12,6 @@ import static foundation.e.drive.utils.AppConstants.INITIALFOLDERS_NUMBER; import android.content.Context; import android.content.Intent; -import android.util.Log; import androidx.annotation.NonNull; import androidx.work.WorkManager; @@ -22,6 +21,7 @@ import androidx.work.WorkerParameters; import foundation.e.drive.EdriveApplication; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** * This class start eDrive work after initialization. @@ -30,15 +30,15 @@ import foundation.e.drive.utils.CommonUtils; * @author Vincent Bourgmayer */ public class FirstStartWorker extends Worker { - private static final String TAG = FirstStartWorker.class.getSimpleName(); public FirstStartWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); + Timber.tag(FirstStartWorker.class.getSimpleName()); } @NonNull @Override public Result doWork() { - Log.d(TAG, "doWork()"); + Timber.v("doWork()"); final Context appContext = getApplicationContext(); appContext.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) diff --git a/app/src/main/java/foundation/e/drive/work/FullScanWorker.java b/app/src/main/java/foundation/e/drive/work/FullScanWorker.java index bc895434..2dd503bf 100644 --- a/app/src/main/java/foundation/e/drive/work/FullScanWorker.java +++ b/app/src/main/java/foundation/e/drive/work/FullScanWorker.java @@ -13,7 +13,6 @@ import android.accounts.AccountManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.util.Log; import androidx.annotation.NonNull; import androidx.work.Worker; @@ -22,6 +21,7 @@ import androidx.work.WorkerParameters; import foundation.e.drive.services.ObserverService; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import timber.log.Timber; /** * As a first step, this class must replace foundation.e.drive.jobs.ScannerJob @@ -33,17 +33,17 @@ import foundation.e.drive.utils.CommonUtils; * @author Vincent Bourgmayer */ public class FullScanWorker extends Worker { - private final static String TAG = FullScanWorker.class.getSimpleName(); public final static String UNIQUE_WORK_NAME = "FullScan"; public FullScanWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); + Timber.tag(FullScanWorker.class.getSimpleName()); } @NonNull @Override public Result doWork() { - Log.d(TAG, "doWork(): going to send intent to ObserverService"); + Timber.v("doWork(): going to send intent to ObserverService"); final SharedPreferences prefs = getApplicationContext().getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); @@ -55,7 +55,7 @@ public class FullScanWorker extends Worker { final Intent observerServiceIntent = new Intent(this.getApplicationContext(), ObserverService.class); this.getApplicationContext().startService(observerServiceIntent); } else { - Log.w(TAG, "Intent for ObserverService not send : account is null or \"settings sync\" & \"media sync\" settings are disabled"); + Timber.d("Intent for ObserverService not send : account is null or \"settings sync\" & \"media sync\" settings are disabled"); } return Result.success(); -- GitLab From 265c147f9e5a932c9b12feae5b4e5d20aaedc924 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 4 Oct 2022 11:37:19 +0200 Subject: [PATCH 16/20] activity package: use Timber for loggin --- .../foundation/e/drive/activity/AccountsActivity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java index 109936ae..7acb1ea8 100644 --- a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java +++ b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java @@ -24,7 +24,6 @@ import android.content.ComponentName; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.View; import androidx.appcompat.app.AppCompatActivity; @@ -38,9 +37,9 @@ import foundation.e.drive.databinding.ActivityAccountsBinding; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import foundation.e.drive.widgets.EDriveWidget; +import timber.log.Timber; public class AccountsActivity extends AppCompatActivity { - private static final String TAG = AccountsActivity.class.getSimpleName(); public static final String NON_OFFICIAL_AVATAR_PATH = "/index.php/avatar/"; private static final String ACCOUNT_SETTINGS = @@ -51,6 +50,7 @@ public class AccountsActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Timber.tag(AccountsActivity.class.getSimpleName()); binding = ActivityAccountsBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); @@ -98,7 +98,7 @@ public class AccountsActivity extends AppCompatActivity { totalShownQuota = CommonUtils.humanReadableByteCountBin(totalQuotaLong); } } catch (NumberFormatException ignored) { - Log.i(TAG, "Bad totalQuotaLong " + totalQuota); + Timber.i("Bad totalQuotaLong " + totalQuota); } try { @@ -107,7 +107,7 @@ public class AccountsActivity extends AppCompatActivity { usedShownQuota = CommonUtils.humanReadableByteCountBin(usedQuotaLong); } } catch (NumberFormatException ignore) { - Log.i(TAG, "Bad usedQuotaLong " + usedQuota); + Timber.i("Bad usedQuotaLong " + usedQuota); } binding.plan.setText(getString(R.string.free_plan, totalShownQuota)); -- GitLab From 9f7deafb6a65480c70da10639673e80505477599 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 4 Oct 2022 12:12:06 +0200 Subject: [PATCH 17/20] Timber: add a ReleaseTree implementation --- app/src/main/AndroidManifest.xml | 1 + .../foundation/e/drive/EdriveApplication.java | 3 +- .../e/drive/receivers/DebugCmdReceiver.java | 9 +++- .../foundation/e/drive/utils/ReleaseTree.java | 43 +++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/foundation/e/drive/utils/ReleaseTree.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 41f9436c..2e436255 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -109,6 +109,7 @@ + diff --git a/app/src/main/java/foundation/e/drive/EdriveApplication.java b/app/src/main/java/foundation/e/drive/EdriveApplication.java index 493b027c..069c0509 100644 --- a/app/src/main/java/foundation/e/drive/EdriveApplication.java +++ b/app/src/main/java/foundation/e/drive/EdriveApplication.java @@ -21,6 +21,7 @@ import foundation.e.drive.FileObservers.RecursiveFileObserver; import foundation.e.drive.services.SynchronizationService; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import foundation.e.drive.utils.ReleaseTree; import timber.log.Timber; import static timber.log.Timber.DebugTree; @@ -42,7 +43,7 @@ public class EdriveApplication extends Application { Timber.plant(new DebugTree()); } else { //Not handled yet - //Timber.plant(new ReleaseTree()); + Timber.plant(new ReleaseTree()); } Timber.tag("EdriveApplication"); diff --git a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java index afb752cc..90a088bd 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -14,6 +14,7 @@ import android.util.Log; import foundation.e.drive.database.DbHelper; import foundation.e.drive.services.ObserverService; +import foundation.e.drive.utils.ReleaseTree; import timber.log.Timber; /** @@ -24,7 +25,8 @@ public class DebugCmdReceiver extends BroadcastReceiver { public static final String ACTION_FORCE_SYNC = "foundation.e.drive.action.FORCE_SYNC"; public static final String ACTION_DUMP_DATABASE = "foundation.e.drive.action.DUMP_DATABASE"; - + public static final String ACTION_FULL_LOG_ON_PROD ="foundation.e.drive.action.FULL_LOG_ON_PROD"; + private static final String FULL_LOG_ENABLE_KEY = "full_log_enable"; @Override public void onReceive(Context context, Intent intent) { Timber.tag(DebugCmdReceiver.class.getSimpleName()).v("onReceive"); @@ -37,6 +39,11 @@ public class DebugCmdReceiver extends BroadcastReceiver { Timber.d("Dump database intent received"); DbHelper.dumpDatabase(context); break; + case ACTION_FULL_LOG_ON_PROD: + final boolean allow_full_log = intent.getBooleanExtra(FULL_LOG_ENABLE_KEY, false); + ReleaseTree.allowDebugLogOnProd(allow_full_log); + Timber.d("Allow full log on prod: %s", allow_full_log); + break; default: break; } diff --git a/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java new file mode 100644 index 00000000..b1b2fbb6 --- /dev/null +++ b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java @@ -0,0 +1,43 @@ +package foundation.e.drive.utils; + +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import timber.log.Timber; + +public class ReleaseTree extends Timber.Tree{ + private static boolean debugEnable = false; + + public static void allowDebugLogOnProd(boolean allow) { + debugEnable = allow; + } + + @Override + protected void log(int priority, @Nullable String tag, @NonNull String message, @Nullable Throwable throwable) { + if (!debugEnable && priority < Log.INFO ) { + return; + } + switch (priority) { + case Log.VERBOSE: + Log.v(tag, message, throwable); + break; + case Log.DEBUG: + Log.d(tag, message, throwable); + break; + case Log.INFO: + Log.i(tag, message, throwable); + break; + case Log.WARN: + Log.w(tag, message, throwable); + break; + case Log.ERROR: + Log.w(tag, message, throwable); + break; + case Log.ASSERT: + Log.wtf(tag, message, throwable); + break; + } + } +} -- GitLab From d7fd62a78c8d22af9863f29ce84371dd5e077a16 Mon Sep 17 00:00:00 2001 From: Jonathan Klee Date: Tue, 4 Oct 2022 13:36:33 +0000 Subject: [PATCH 18/20] Apply 1 suggestion(s) to 1 file(s) --- app/src/main/java/foundation/e/drive/utils/ReleaseTree.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java index b1b2fbb6..26b62d75 100644 --- a/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java +++ b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java @@ -7,7 +7,7 @@ import androidx.annotation.Nullable; import timber.log.Timber; -public class ReleaseTree extends Timber.Tree{ +public class ReleaseTree extends Timber.Tree { private static boolean debugEnable = false; public static void allowDebugLogOnProd(boolean allow) { -- GitLab From e37fba809edc98cb7f7396532be2e5f76d3173b3 Mon Sep 17 00:00:00 2001 From: Jonathan Klee Date: Tue, 4 Oct 2022 13:36:45 +0000 Subject: [PATCH 19/20] Apply 1 suggestion(s) to 1 file(s) --- .../java/foundation/e/drive/receivers/DebugCmdReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java index 90a088bd..9e0e10b4 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -25,7 +25,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { public static final String ACTION_FORCE_SYNC = "foundation.e.drive.action.FORCE_SYNC"; public static final String ACTION_DUMP_DATABASE = "foundation.e.drive.action.DUMP_DATABASE"; - public static final String ACTION_FULL_LOG_ON_PROD ="foundation.e.drive.action.FULL_LOG_ON_PROD"; + public static final String ACTION_FULL_LOG_ON_PROD = "foundation.e.drive.action.FULL_LOG_ON_PROD"; private static final String FULL_LOG_ENABLE_KEY = "full_log_enable"; @Override public void onReceive(Context context, Intent intent) { -- GitLab From 462e67e91a54b1e499358751cf79c0a14310e117 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 5 Oct 2022 10:43:36 +0200 Subject: [PATCH 20/20] Fix missing tag in log --- .../e/drive/services/ObserverService.java | 6 ++--- .../foundation/e/drive/utils/ReleaseTree.java | 23 ++----------------- 2 files changed, 5 insertions(+), 24 deletions(-) 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 e863ba7a..99b718a3 100644 --- a/app/src/main/java/foundation/e/drive/services/ObserverService.java +++ b/app/src/main/java/foundation/e/drive/services/ObserverService.java @@ -76,7 +76,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene /* Lifecycle Methods */ @Override public void onDestroy(){ - Timber.i("onDestroy()"); + Timber.v("onDestroy()"); unbindService(synchronizationServiceConnection); super.onDestroy(); this.mSyncedFolders = null; @@ -291,7 +291,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene */ @Override public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { - Timber.i("onRemoteOperationFinish()"); + Timber.d("onRemoteOperationFinish()"); if (!(operation instanceof ListFileRemoteOperation)) return; if (!result.isSuccess()) { @@ -365,7 +365,7 @@ public class ObserverService extends Service implements OnRemoteOperationListene * I.e : " com.android.my_example_package,7.1.2 " */ private void generateAppListFile() { - Timber.i("generateAppListFile()"); + Timber.d("generateAppListFile()"); final List packagesInfo = getPackageManager().getInstalledPackages(0); final StringBuilder fileContents = new StringBuilder(); diff --git a/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java index 26b62d75..aff51444 100644 --- a/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java +++ b/app/src/main/java/foundation/e/drive/utils/ReleaseTree.java @@ -7,7 +7,7 @@ import androidx.annotation.Nullable; import timber.log.Timber; -public class ReleaseTree extends Timber.Tree { +public class ReleaseTree extends Timber.DebugTree{ private static boolean debugEnable = false; public static void allowDebugLogOnProd(boolean allow) { @@ -19,25 +19,6 @@ public class ReleaseTree extends Timber.Tree { if (!debugEnable && priority < Log.INFO ) { return; } - switch (priority) { - case Log.VERBOSE: - Log.v(tag, message, throwable); - break; - case Log.DEBUG: - Log.d(tag, message, throwable); - break; - case Log.INFO: - Log.i(tag, message, throwable); - break; - case Log.WARN: - Log.w(tag, message, throwable); - break; - case Log.ERROR: - Log.w(tag, message, throwable); - break; - case Log.ASSERT: - Log.wtf(tag, message, throwable); - break; - } + super.log(priority, tag, message, throwable); } } -- GitLab