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

Commit ca5dd59d authored by Vincent Bourgmayer's avatar Vincent Bourgmayer
Browse files

Merge branch '762-workOnContentScanner' into 'v1-oreo'

Work ContentScanner package to add tests

See merge request !179
parents e4bf0a7d 67b42590
Loading
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@
 */
package foundation.e.drive.contentScanner;

import android.accounts.Account;
import android.content.Context;

import com.owncloud.android.lib.resources.files.FileUtils;
@@ -27,18 +26,16 @@ import foundation.e.drive.models.SyncedFolder;
 */
public abstract class AbstractContentScanner<T> {
    protected final Context context;
    protected final Account account;
    protected final HashMap<Integer, SyncRequest> syncRequests;
    protected final List<SyncedFolder> syncedFolders;

    /**
     * @param context Context used to access Database, etc.
     * @param account Account used to checked if user has change some synchronization's settings
     * @param syncedFolders List of SyncedFolders
     */
    protected AbstractContentScanner(Context context, Account account, List<SyncedFolder> syncedFolders) {
    protected AbstractContentScanner(Context context, List<SyncedFolder> syncedFolders) {
        syncRequests = new HashMap<>();
        this.context = context;
        this.account = account;
        this.syncedFolders = syncedFolders;
    }

@@ -67,7 +64,7 @@ public abstract class AbstractContentScanner<T> {
        }
        
        for (SyncedFileState remainingFileState : fileStates) {
            onMissingRemoteFile(remainingFileState);
            onMissingFile(remainingFileState);
        }
        return syncRequests;
    };
@@ -93,7 +90,7 @@ public abstract class AbstractContentScanner<T> {
     * When a file doesn't exist anymore we remove it from device/cloud (depending of implementation) & from Database
     * @param fileState SyncedFileState for which we lack remote file
     */
    protected abstract void onMissingRemoteFile(SyncedFileState fileState);
    protected abstract void onMissingFile(SyncedFileState fileState);

    /**
     * A new file has been found
+7 −9
Original line number Diff line number Diff line
/*
 * Copyright © ECORP SAS 2022.
 * Copyright © MURENA 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
@@ -7,7 +7,6 @@
 */
package foundation.e.drive.contentScanner;

import android.accounts.Account;
import android.content.Context;

import java.io.File;
@@ -24,16 +23,17 @@ import timber.log.Timber;
/**
 * Class to encapsulate function about scanning local file and
 * create syncRequest when needed
 * @author vincent Bourgmayer
 */
public class LocalContentScanner extends AbstractContentScanner<File>{

    public LocalContentScanner(Context context, Account account, List<SyncedFolder> syncedFolders) {
        super(context, account, syncedFolders);
    public LocalContentScanner(Context context, List<SyncedFolder> syncedFolders) {
        super(context, syncedFolders);
        Timber.tag(LocalContentScanner.class.getSimpleName());
    }

    @Override
    protected void onMissingRemoteFile(SyncedFileState fileState) {
    protected void onMissingFile(SyncedFileState fileState) {
        if (!fileState.hasBeenSynchronizedOnce()) {
            return;
        }
@@ -61,11 +61,9 @@ public class LocalContentScanner extends AbstractContentScanner<File>{
            if (parentDir.isScanLocal()) scannableValue += 2;
        }

        //create the syncedFile State
        final SyncedFileState newSyncedFileState = new SyncedFileState(-1, file.getName(), filePath, parentDir.getRemoteFolder() + file.getName(), "", 0, parentDir.getId(), parentDir.isMediaType(),scannableValue);

        //Store it in DB
        int storedId = DbHelper.manageSyncedFileStateDB(newSyncedFileState, "INSERT", context);
        final int storedId = DbHelper.manageSyncedFileStateDB(newSyncedFileState, "INSERT", context);
        if (storedId > 0) {
            newSyncedFileState.setId( storedId );
            Timber.d("Add upload SyncRequest for new file %s", filePath);
+7 −35
Original line number Diff line number Diff line
/*
 * Copyright © ECORP SAS 2022.
 * Copyright © MURENA 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
@@ -7,19 +7,18 @@
 */
package foundation.e.drive.contentScanner;

import static foundation.e.drive.models.SyncRequest.Type.LOCAL_DELETE;
import static foundation.e.drive.utils.FileDiffUtils.getActionForFileDiff;

import android.accounts.Account;
import android.content.Context;
import android.provider.MediaStore;

import com.owncloud.android.lib.resources.files.model.RemoteFile;

import java.io.File;
import java.util.List;

import foundation.e.drive.database.DbHelper;
import foundation.e.drive.models.DownloadRequest;
import foundation.e.drive.models.SyncRequest;
import foundation.e.drive.models.SyncedFileState;
import foundation.e.drive.models.SyncedFolder;
import foundation.e.drive.utils.CommonUtils;
@@ -34,10 +33,9 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {

    /**
     * @param context Context used to access Database, etc.
     * @param account Account used to checked if user has change some synchronization's settings
     */
    public RemoteContentScanner(Context context, Account account, List<SyncedFolder> syncedFolders) {
        super(context, account, syncedFolders);
    public RemoteContentScanner(Context context, List<SyncedFolder> syncedFolders) {
        super(context, syncedFolders);
        Timber.tag(RemoteContentScanner.class.getSimpleName());
    }

@@ -74,7 +72,6 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {

        final SyncedFileState newFileState = new SyncedFileState(-1, fileName, parentDir.getLocalFolder() + fileName, remoteFilePath, file.getEtag(), 0, parentDir.getId(), parentDir.isMediaType(), scannableValue);

        //Store it in DB
        final int storedId = DbHelper.manageSyncedFileStateDB(newFileState, "INSERT", context);
        if (storedId > 0) {
            newFileState.setId(storedId);
@@ -84,33 +81,8 @@ public class RemoteContentScanner extends AbstractContentScanner<RemoteFile> {
    }

    @Override
    protected void onMissingRemoteFile(SyncedFileState fileState) {
        if (!CommonUtils.isThisSyncAllowed(account, fileState.isMediaType())) {
            Timber.d("Sync of current file: %s isn't allowed", fileState.getName());
            return;
        }

        if (!fileState.hasBeenSynchronizedOnce()) {
            return;
        }

        final File file = new File(fileState.getLocalPath());
        if (!file.exists()) {
            return;
        }

        context.getContentResolver().delete(MediaStore.Files.getContentUri("external"),
                MediaStore.Files.FileColumns.DATA + "=?",
                new String[]{CommonUtils.getLocalPath(file)});

        if (!file.delete()) { //May throw SecurityException or IOException
            Timber.d("local file ( %s ) removal failed",file.getName());
            return;
        }

        if (DbHelper.manageSyncedFileStateDB(fileState, "DELETE", context) <= 0) {
            Timber.e("Failed to remove %s from DB", file.getName());
        }
    protected void onMissingFile(SyncedFileState fileState) {
        this.syncRequests.put(fileState.getId(), new SyncRequest(fileState, LOCAL_DELETE));
    }

    @Override
+18 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteStatement;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import foundation.e.drive.models.SyncedFileState;
@@ -195,15 +196,26 @@ import static foundation.e.drive.database.SyncedFileStateContract.SYNCEDFOLDER_I
    /* package */ List<SyncedFileState> getBySyncedFolderIds(List<Long> syncedFolderIds) {
        final List<SyncedFileState> result = new ArrayList<>();
        if (syncedFolderIds == null || syncedFolderIds.isEmpty()) {
            Timber.d("getBySyncedFolderIds(): SyncedFOlderIds is empty or null");
            return result;
        }
        final String whereClause = SYNCEDFOLDER_ID + " IN (?)";
        final String[] whereValue = new String[] {
             syncedFolderIds.toString()

        final List<String> matcherList = new ArrayList<>(); //list of "?" to be replaced by value by SQliteDatabase.query() call

        final String[] whereValue = new String[syncedFolderIds.size()];
        for (int i = 0; i < syncedFolderIds.size(); i++) {
            matcherList.add("?");
            whereValue[i] = syncedFolderIds.get(i).toString();
        }

        final StringBuilder whereClause = new StringBuilder();
        whereClause.append(SYNCEDFOLDER_ID)
                .append(" IN ")
                .append(matcherList.toString()
                        .replace("[", "(")
                .replace("]", ")") };
                        .replace("]", ")"));

        final Cursor cursor = mDB.query(TABLE_NAME, allColumns, whereClause, whereValue, null, null, null);
        final Cursor cursor = mDB.query(TABLE_NAME, allColumns, whereClause.toString(), whereValue, null, null, null);
        cursor.moveToFirst();
        while(!cursor.isAfterLast() ) {
            result.add( cursorToSyncedFileState(cursor) );
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ package foundation.e.drive.models;
import androidx.annotation.Nullable;

public class SyncRequest {
    public enum Type { UPLOAD, DOWNLOAD, REMOTE_DELETE};
    public enum Type { UPLOAD, DOWNLOAD, REMOTE_DELETE, LOCAL_DELETE};

    private final SyncedFileState syncedFileState;

Loading