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

Commit 64ad39b0 authored by Vincent Bourgmayer's avatar Vincent Bourgmayer
Browse files

Replace locale file deletion task, by file sync disabling task.

parent e9f28b02
Loading
Loading
Loading
Loading
+12 −10
Original line number Diff line number Diff line
@@ -8,11 +8,13 @@

package foundation.e.drive.FileObservers;

import static foundation.e.drive.models.SyncRequest.Type.REMOTE_DELETE;
import static foundation.e.drive.models.SyncRequest.Type.DISABLE_SYNCING;
import static foundation.e.drive.models.SyncRequest.Type.UPLOAD;
import static foundation.e.drive.models.SyncedFileState.DEVICE_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.ECLOUD_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.NOT_SCANNABLE;

import android.content.Context;
import android.content.Intent;
import android.os.FileObserver;

import androidx.annotation.NonNull;
@@ -25,7 +27,6 @@ import foundation.e.drive.database.DbHelper;
import foundation.e.drive.models.SyncRequest;
import foundation.e.drive.models.SyncedFileState;
import foundation.e.drive.models.SyncedFolder;
import foundation.e.drive.services.SynchronizationService;
import foundation.e.drive.utils.CommonUtils;
import foundation.e.drive.utils.SynchronizationServiceConnection;
import timber.log.Timber;
@@ -192,10 +193,10 @@ public class FileEventListener {
                Timber.d("Won't send sync request: no parent are known for new file: %s", file.getName());
                return;
            }
            int scannableValue = 0;
            int scannableValue = NOT_SCANNABLE;
            if (parentFolder.isEnabled()) {
                if (parentFolder.isScanRemote()) scannableValue++;
                if (parentFolder.isScanLocal()) scannableValue += 2;
                if (parentFolder.isScanRemote()) scannableValue = ECLOUD_SCANNABLE;
                if (parentFolder.isScanLocal()) scannableValue += DEVICE_SCANNABLE;
            }

            final String remotePath = parentFolder.getRemoteFolder()+file.getName();
@@ -209,7 +210,7 @@ public class FileEventListener {
            }
        } else { //File update
            final boolean isWaitingForDownload = fileState.isLastEtagStored() && fileState.getLocalLastModified() == 0L;
            if (fileState.getScannable() > 1 && !isWaitingForDownload) {
            if (fileState.getScannable() > ECLOUD_SCANNABLE && !isWaitingForDownload) {
                request = new SyncRequest(fileState, UPLOAD);
            }
        }
@@ -231,9 +232,10 @@ public class FileEventListener {
        }

        //If already in DB
        if (fileState.getScannable() > 0) {
            SyncRequest deleteRequest = new SyncRequest(fileState, REMOTE_DELETE);
            this.sendSyncRequestToSynchronizationService(deleteRequest);
        if (fileState.getScannable() > NOT_SCANNABLE) {
            //todo: if file is already sync disabled, we should probably remove file from DB
            final SyncRequest disableSyncingRequest = new SyncRequest(fileState, DISABLE_SYNCING);
            this.sendSyncRequestToSynchronizationService(disableSyncingRequest);
        }
    }

+0 −86
Original line number Diff line number Diff line
/*
 * Copyright © MURENA SAS 2023.
 * 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
 */

@file:JvmName("RecycleBin")

package foundation.e.drive

import foundation.e.drive.utils.AppConstants
import timber.log.Timber
import java.io.File
import java.io.IOException
import java.nio.file.Files
import kotlin.io.path.Path
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration

/**
 * This class contains method for trashing file & cleaning the trash
 */
object RecycleBin {
    private val DELAY_FOR_DELETION = 30.toDuration(DurationUnit.DAYS)
    private val BIN_PATH = AppConstants.RECYCLE_BIN_PATH //TMP only, Need to find a way to get context

    /**
     * Remove files which are in recycle bin
     * for more than DELAY_FOR_DELETION
     * @return false as soon as some files that should be removed is not removed
     */
    fun clearOldestFiles(): Boolean {
        val binDir = File(BIN_PATH)

        if (!binDir.exists()) return true

        try {
            val filesToRemove = binDir.listFiles { file ->
                computeTimeInBin(file.lastModified()) > DELAY_FOR_DELETION
            }

            filesToRemove?.forEach { file -> file?.delete() }
        } catch (exception: IOException) {
            //Note that some files might have already been removed
            Timber.e(exception, "Caught exception when clearing oldest file in bin")
            return false
        }
        return true
    }

    /**
     * Compute time from which file is in Bin
     * and return it as a Duration in days
     */
    private fun computeTimeInBin(fileLastModified: Long): Duration {
        return (System.currentTimeMillis() - fileLastModified).toDuration(DurationUnit.DAYS)
    }

    /**
     * put a file into the bin
     */
    fun trashFile(file: File): Boolean {
        File(BIN_PATH).mkdirs() //Assert that recycle bin exist

        if (file.exists()) {
            val targetPath = File(BIN_PATH, file.name).absolutePath
            try {
                val moveResult = Files.move(file.toPath(), Path(targetPath))
                if (moveResult.toFile().exists()) {
                    return true
                }
            } catch (exception: IOException) {
                Timber.e(exception)
            } catch (exception: SecurityException) {
                Timber.e(exception)
            } catch (exception: NullPointerException) {
                Timber.e(exception)
            }
        }
        Timber.d("Can't move %s to trashbin", file.absolutePath)
        return false
    }
}
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
@@ -68,6 +68,9 @@ public abstract class AbstractContentScanner<T> {
        }
        
        for (SyncedFileState remainingFileState : fileStates) {
            if (remainingFileState.getScannable() == SyncedFileState.NOT_SCANNABLE) {
                continue;
            }
            onMissingFile(remainingFileState);
        }
        return syncRequests;
+11 −5
Original line number Diff line number Diff line
@@ -7,6 +7,10 @@
 */
package foundation.e.drive.contentScanner;

import static foundation.e.drive.models.SyncedFileState.DEVICE_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.ECLOUD_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.NOT_SCANNABLE;

import android.content.Context;

import androidx.annotation.NonNull;
@@ -44,9 +48,9 @@ public class LocalContentScanner extends AbstractContentScanner<File>{
            Timber.d("Expected %s to be missing. but it still exists", file.getAbsolutePath());
            return;
        }

        //todo: should we check if already sync disabled, and then remove it from DB ?
        Timber.d("Add remove SyncRequest for file %s", file.getAbsolutePath());
        syncRequests.put(fileState.getId(), new SyncRequest(fileState, SyncRequest.Type.REMOTE_DELETE));
        syncRequests.put(fileState.getId(), new SyncRequest(fileState, SyncRequest.Type.DISABLE_SYNCING));
    }

    @Override
@@ -55,10 +59,10 @@ public class LocalContentScanner extends AbstractContentScanner<File>{
        final SyncedFolder parentDir = getParentSyncedFolder(filePath);
        if (parentDir == null) return;

        int scannableValue = 0;
        int scannableValue = NOT_SCANNABLE;
        if (parentDir.isEnabled()) {
            if (parentDir.isScanRemote()) scannableValue++;
            if (parentDir.isScanLocal()) scannableValue += 2;
            if (parentDir.isScanRemote()) scannableValue += ECLOUD_SCANNABLE;
            if (parentDir.isScanLocal()) scannableValue += DEVICE_SCANNABLE;
        }

        final SyncedFileState newSyncedFileState = new SyncedFileState(-1, file.getName(), filePath, parentDir.getRemoteFolder() + file.getName(), "", 0, parentDir.getId(), parentDir.isMediaType(),scannableValue);
@@ -73,6 +77,8 @@ public class LocalContentScanner extends AbstractContentScanner<File>{

    @Override
    protected void onKnownFileFound(@NonNull File file, @NonNull SyncedFileState fileState) {
        if (fileState.getScannable() == NOT_SCANNABLE) return;
        
        if (FileDiffUtils.getActionForFileDiff(file, fileState) == FileDiffUtils.Action.Upload) {
            Timber.d("Add upload SyncRequest for %s", file.getAbsolutePath());
            syncRequests.put(fileState.getId(), new SyncRequest(fileState, SyncRequest.Type.UPLOAD));
+11 −6
Original line number Diff line number Diff line
@@ -7,7 +7,10 @@
 */
package foundation.e.drive.contentScanner;

import static foundation.e.drive.models.SyncRequest.Type.LOCAL_DELETE;
import static foundation.e.drive.models.SyncRequest.Type.DISABLE_SYNCING;
import static foundation.e.drive.models.SyncedFileState.DEVICE_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.ECLOUD_SCANNABLE;
import static foundation.e.drive.models.SyncedFileState.NOT_SCANNABLE;
import static foundation.e.drive.utils.FileDiffUtils.getActionForFileDiff;

import android.content.Context;
@@ -43,6 +46,8 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {

    @Override
    protected void onKnownFileFound(@NonNull RemoteFile file, @NonNull SyncedFileState fileState) {
        if (fileState.getScannable() == NOT_SCANNABLE) return;

        final FileDiffUtils.Action action = getActionForFileDiff(file, fileState);
        if (action == FileDiffUtils.Action.Download) {

@@ -66,10 +71,10 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {

        final String fileName = CommonUtils.getFileNameFromPath(remoteFilePath);

        int scannableValue = 0;
        int scannableValue = NOT_SCANNABLE;
        if (parentDir.isEnabled()) {
            if (parentDir.isScanRemote()) scannableValue++;
            if (parentDir.isScanLocal()) scannableValue += 2;
            if (parentDir.isScanRemote()) scannableValue += ECLOUD_SCANNABLE;
            if (parentDir.isScanLocal()) scannableValue += DEVICE_SCANNABLE;
        }

        final SyncedFileState newFileState = new SyncedFileState(-1, fileName, parentDir.getLocalFolder() + fileName, remoteFilePath, file.getEtag(), 0, parentDir.getId(), parentDir.isMediaType(), scannableValue);
@@ -88,8 +93,8 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {
            return;
        }

        Timber.d("Add local deletion request for file: %s", fileState.getLocalPath());
        this.syncRequests.put(fileState.getId(), new SyncRequest(fileState, LOCAL_DELETE));
        Timber.d("Add Disable syncing request for file: %s", fileState.getLocalPath());
        this.syncRequests.put(fileState.getId(), new SyncRequest(fileState, DISABLE_SYNCING));
    }

    @Override
Loading