Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 683ce733 authored by Vincent Bourgmayer's avatar Vincent Bourgmayer
Browse files

- Replace logging in ObserverService to use Timber

- few refactoring, essentially to clean coding style
- removed useless comments
- removed useless import
parent 26c908cc
Loading
Loading
Loading
Loading
+85 −92
Original line number Diff line number Diff line
@@ -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<SyncedFolder> 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");
            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");
            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");
            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");
            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,8 +270,8 @@ public class ObserverService extends Service implements OnRemoteOperationListene
     * @return
     */
   private List<SyncedFolder> 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) {
            return DbHelper.getAllSyncedFolders(this);
@@ -296,10 +291,12 @@ public class ObserverService extends Service implements OnRemoteOperationListene
     */
    @Override
    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
        Log.i( TAG, "onRemoteOperationFinish()" );
        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<RemoteFile> remoteFiles = ((RemoteOperationResult<ArrayList<RemoteFile>>)result).getResultData();

@@ -316,17 +313,14 @@ public class ObserverService extends Service implements OnRemoteOperationListene
                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<Long> id of SyncedFolder to scan
     */
    private List<Long> getIdsFromFolderToScan() {
        List<Long> result = new ArrayList<>();
        final List<Long> 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<PackageInfo> packagesInfo = getPackageManager().getInstalledPackages(0);
        Timber.i("generateAppListFile()");
        final List<PackageInfo> packagesInfo = getPackageManager().getInstalledPackages(0);

        StringBuilder fileContents = new StringBuilder();
        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
                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<File> fileList = new ArrayList<>();
        final List<Long> 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);
                }
            }