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

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

E1 clean download file operation

parent d4b39f93
Loading
Loading
Loading
Loading
+53 −93
Original line number Diff line number Diff line
@@ -9,8 +9,6 @@
package foundation.e.drive.operations;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -26,109 +24,76 @@ import foundation.e.drive.utils.CommonUtils;
 * @author Vincent Bourgmayer
 * Encapsulate a global download process for a file
 */
public class DownloadFileOperation extends RemoteOperation implements  Parcelable {
public class DownloadFileOperation extends RemoteOperation {
    private final static String TAG = DownloadFileOperation.class.getSimpleName();

    private final RemoteFile mRFile;
    private Context mContext;
    private String mTargetPath;
    private final RemoteFile remoteFile;
    private Context context;
    private String targetPath;
    private int restartCounter =0;
    private SyncedFileState mSyncedState;
    private SyncedFileState syncedFileState;
    private String previousEtag;


    /**
     * 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){        this.mRFile = remoteFile;
        this.mSyncedState = syncedFileState;
        this.previousEtag = mSyncedState.getLastETAG();
        this.mTargetPath = this.mSyncedState.getLocalPath();
    }

    protected DownloadFileOperation(Parcel in) {
        mRFile = in.readParcelable(RemoteFile.class.getClassLoader());
        mTargetPath = in.readString();
        restartCounter = in.readInt();
        mSyncedState = in.readParcelable(SyncedFileState.class.getClassLoader());
        previousEtag = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mRFile, flags);
        dest.writeString(mTargetPath);
        dest.writeInt(restartCounter);
        dest.writeParcelable(mSyncedState, flags);
        dest.writeString(previousEtag);
    }


    public static final Creator<DownloadFileOperation> CREATOR = new Creator<DownloadFileOperation>() {
        @Override
        public DownloadFileOperation createFromParcel(Parcel in) {
            return new DownloadFileOperation(in);
    public DownloadFileOperation(RemoteFile remoteFile, SyncedFileState syncedFileState, Context context) {
        this.remoteFile = remoteFile;
        this.syncedFileState = syncedFileState;
        this.previousEtag = syncedFileState.getLastETAG();
        this.targetPath = syncedFileState.getLocalPath();
        this.context = context;
    }

        @Override
        public DownloadFileOperation[] newArray(int size) {
            return new DownloadFileOperation[size];
        }
    };

    public void setContext(Context context){
            this.mContext = context;
    }


    @Override
    protected RemoteOperationResult run(OwnCloudClient ownCloudClient) {
        Log.i(TAG, "run(ownCloudClient)");

        //get or build synced file equivalent of this.mFile
        if(mSyncedState == null || mTargetPath == null || mTargetPath.isEmpty()) {
            Log.e(TAG, "mSyncedState or mTargetPath is empty or null. Can't Download in those conditions");
        if (syncedFileState == null || targetPath == null || targetPath.isEmpty()) {
            Log.e(TAG, "syncedFileState or targetPath is empty or null. Can't Download in those conditions");
            return new RemoteOperationResult(RemoteOperationResult.ResultCode.FORBIDDEN);
        }else if(mSyncedState.getId() == -1){
            this.mSyncedState.setId( DbHelper.manageSyncedFileStateDB(this.mSyncedState, "INSERT", mContext) );
        } else if (syncedFileState.getId() == -1) {
            this.syncedFileState.setId(DbHelper.manageSyncedFileStateDB(this.syncedFileState, "INSERT", context));
        }

        if(mSyncedState.getLastETAG().equals( mRFile.getEtag() ) && mSyncedState.getLocalLastModified() > 0L){
        if (syncedFileState.getLastETAG().equals(remoteFile.getEtag()) && syncedFileState.getLocalLastModified() > 0L) {
            //Same etag and localLastModified  not null mean the file is up to date
            Log.w(TAG, "File already up-to-date");
            return new RemoteOperationResult(RemoteOperationResult.ResultCode.ETAG_UNCHANGED);
        }
        String tmpTargetPath = mContext.getExternalCacheDir()+ FileUtils.PATH_SEPARATOR+mSyncedState.getName();
        DownloadFileRemoteOperation downloadOperation = new DownloadFileRemoteOperation(mRFile.getRemotePath(),
        
        final String tmpTargetPath = context.getExternalCacheDir()+ FileUtils.PATH_SEPARATOR+ syncedFileState.getName();
        final DownloadFileRemoteOperation downloadOperation = new DownloadFileRemoteOperation(remoteFile.getRemotePath(),
                tmpTargetPath);

        RemoteOperationResult downloadResult = downloadOperation.execute( ownCloudClient );
        RemoteOperationResult.ResultCode mResultCode;
        final RemoteOperationResult downloadResult = downloadOperation.execute(ownCloudClient);
        RemoteOperationResult.ResultCode resultCode;

        boolean mustRestart = true;
        if (downloadResult.isSuccess()) {
            File tmpLocalFile = new File(tmpTargetPath);
            final File tmpLocalFile = new File(tmpTargetPath);
            if (!tmpLocalFile.exists()) {
                Log.e(TAG, "Downloaded file doesn't exist or is null");
                mResultCode = RemoteOperationResult.ResultCode.FILE_NOT_FOUND;
                resultCode = RemoteOperationResult.ResultCode.FILE_NOT_FOUND;

            }else if(tmpLocalFile.length() != mRFile.getLength() ){
            } else if (tmpLocalFile.length() != remoteFile.getLength()) {

                Log.e(TAG, "Local and remote file doesn't have the same size.");
                mResultCode = RemoteOperationResult.ResultCode.INVALID_OVERWRITE;
                resultCode = RemoteOperationResult.ResultCode.INVALID_OVERWRITE;
                tmpLocalFile.delete();

            } else {
                //file has been correctly download.
                File localFile = new File(mTargetPath);
                final File localFile = new File(targetPath);
                if (localFile.exists()) {
                    localFile.delete();
                }
                //Check parentFolder existence and create if needed
                String parentFoldersPath = localFile.getParent();
                File localParentFile = new File(parentFoldersPath);
                final String parentFoldersPath = localFile.getParent();
                final File localParentFile = new File(parentFoldersPath);
                if (!localParentFile.exists()) {
                    if (localParentFile.mkdirs())
                        Log.d(TAG, "Created folders: "+parentFoldersPath);
@@ -139,40 +104,35 @@ public class DownloadFileOperation extends RemoteOperation implements Parcelabl
                boolean renameResult = tmpLocalFile.renameTo(localFile);
                if (!renameResult)
                    Log.d(TAG, "File hasn't been successfully moved at its place");
                mSyncedState.setLocalLastModified( localFile.lastModified() )
                        .setLastETAG( mRFile.getEtag() );
                syncedFileState.setLocalLastModified(localFile.lastModified())
                        .setLastETAG(remoteFile.getEtag());
                mustRestart = false;
                mResultCode = RemoteOperationResult.ResultCode.OK;
                resultCode = RemoteOperationResult.ResultCode.OK;
                //needed to make Gallery show new image
                CommonUtils.doActionMediaScannerConnexionScanFile(mContext, mSyncedState.getLocalPath() );
                CommonUtils.doActionMediaScannerConnexionScanFile(context, syncedFileState.getLocalPath());
            }
        } else {
            //If download failed
            Log.e(TAG, "Download failed: "+downloadResult.getLogMessage());
            mResultCode = RemoteOperationResult.ResultCode.UNKNOWN_ERROR;
            resultCode = RemoteOperationResult.ResultCode.UNKNOWN_ERROR;
        }

        if (mustRestart) {
            Log.w(TAG, restartCounter+" unsuccessfull trial.s of downloading file "
                    +mRFile.getRemotePath() );
            mSyncedState.setLastETAG(this.previousEtag);
                    + remoteFile.getRemotePath());
            syncedFileState.setLastETAG(this.previousEtag);
            if (this.restartCounter < 3) {
                this.restartCounter += 1;
                return this.run(ownCloudClient);
            } else {
                mResultCode = RemoteOperationResult.ResultCode.INVALID_OVERWRITE;
                resultCode = RemoteOperationResult.ResultCode.INVALID_OVERWRITE;
            }
        }
        //So now, we can update instance of SyncedState and save it to DB
        if( DbHelper.manageSyncedFileStateDB( mSyncedState, "UPDATE", mContext ) <= 0 ){
        if (DbHelper.manageSyncedFileStateDB(syncedFileState, "UPDATE", context) <= 0) {
            Log.e(TAG, "DB update failed: 0 affected row");
            //@TODO : do smtg
        }
        return new RemoteOperationResult( mResultCode );
    }

    @Override
    public int describeContents() {
        return 0;
        return new RemoteOperationResult(resultCode);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ public class SynchronizationService extends Service implements OnRemoteOperation
                break;
            case DOWNLOAD:
                final DownloadRequest downloadRequest = (DownloadRequest) request;
                operation = new DownloadFileOperation(downloadRequest.getRemoteFile(), downloadRequest.getSyncedFileState());
                operation = new DownloadFileOperation(downloadRequest.getRemoteFile(), downloadRequest.getSyncedFileState(), getApplicationContext());
                break;
            case REMOTE_DELETE:
            default: