use of com.owncloud.android.lib.common.operations.RemoteOperationResult in project android by nextcloud.
the class UpdateShareViaLinkOperation method run.
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
OCShare publicShare = getStorageManager().getShareById(shareId);
UpdateShareRemoteOperation updateOp = new UpdateShareRemoteOperation(publicShare.getRemoteId());
updateOp.setPassword(password);
updateOp.setExpirationDate(expirationDateInMillis);
updateOp.setHideFileDownload(hideFileDownload);
updateOp.setLabel(label);
RemoteOperationResult result = updateOp.execute(client);
if (result.isSuccess()) {
// Retrieve updated share / save directly with password? -> no; the password is not to be saved
RemoteOperation getShareOp = new GetShareRemoteOperation(publicShare.getRemoteId());
result = getShareOp.execute(client);
if (result.isSuccess()) {
OCShare share = (OCShare) result.getData().get(0);
getStorageManager().saveShare(share);
}
}
return result;
}
use of com.owncloud.android.lib.common.operations.RemoteOperationResult in project android by nextcloud.
the class UploadFileOperation method saveUploadedFile.
/**
* Saves a OC File after a successful upload.
* <p>
* A PROPFIND is necessary to keep the props in the local database
* synchronized with the server, specially the modification time and Etag
* (where available)
*/
private void saveUploadedFile(OwnCloudClient client) {
OCFile file = mFile;
if (file.fileExists()) {
file = getStorageManager().getFileById(file.getFileId());
}
if (file == null) {
// this can happen e.g. when the file gets deleted during upload
return;
}
long syncDate = System.currentTimeMillis();
file.setLastSyncDateForData(syncDate);
// new PROPFIND to keep data consistent with server
// in theory, should return the same we already have
// TODO from the appropriate OC server version, get data from last PUT response headers, instead
// TODO of a new PROPFIND; the latter may fail, specially for chunked uploads
String path;
if (encryptedAncestor) {
path = file.getParentRemotePath() + mFile.getEncryptedFileName();
} else {
path = getRemotePath();
}
ReadFileRemoteOperation operation = new ReadFileRemoteOperation(path);
RemoteOperationResult result = operation.execute(client);
if (result.isSuccess()) {
updateOCFile(file, (RemoteFile) result.getData().get(0));
file.setLastSyncDateForProperties(syncDate);
} else {
Log_OC.e(TAG, "Error reading properties of file after successful upload; this is gonna hurt...");
}
if (mWasRenamed) {
OCFile oldFile = getStorageManager().getFileByPath(mOldFile.getRemotePath());
if (oldFile != null) {
oldFile.setStoragePath(null);
getStorageManager().saveFile(oldFile);
getStorageManager().saveConflict(oldFile, null);
}
// else: it was just an automatic renaming due to a name
// coincidence; nothing else is needed, the storagePath is right
// in the instance returned by mCurrentUpload.getFile()
}
file.setUpdateThumbnailNeeded(true);
getStorageManager().saveFile(file);
getStorageManager().saveConflict(file, null);
if (MimeTypeUtil.isMedia(file.getMimeType())) {
FileDataStorageManager.triggerMediaScan(file.getStoragePath(), file);
}
// generate new Thumbnail
final ThumbnailsCacheManager.ThumbnailGenerationTask task = new ThumbnailsCacheManager.ThumbnailGenerationTask(getStorageManager(), user);
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, file.getRemoteId()));
}
use of com.owncloud.android.lib.common.operations.RemoteOperationResult in project android by nextcloud.
the class UploadFileOperation method checkConditions.
private RemoteOperationResult checkConditions(File originalFile) {
RemoteOperationResult remoteOperationResult = null;
// check that connectivity conditions are met and delays the upload otherwise
Connectivity connectivity = connectivityService.getConnectivity();
if (mOnWifiOnly && (!connectivity.isWifi() || connectivity.isMetered())) {
Log_OC.d(TAG, "Upload delayed until WiFi is available: " + getRemotePath());
remoteOperationResult = new RemoteOperationResult(ResultCode.DELAYED_FOR_WIFI);
}
// check if charging conditions are met and delays the upload otherwise
final BatteryStatus battery = powerManagementService.getBattery();
if (mWhileChargingOnly && !battery.isCharging()) {
Log_OC.d(TAG, "Upload delayed until the device is charging: " + getRemotePath());
remoteOperationResult = new RemoteOperationResult(ResultCode.DELAYED_FOR_CHARGING);
}
// check that device is not in power save mode
if (!mIgnoringPowerSaveMode && powerManagementService.isPowerSavingEnabled()) {
Log_OC.d(TAG, "Upload delayed because device is in power save mode: " + getRemotePath());
remoteOperationResult = new RemoteOperationResult(ResultCode.DELAYED_IN_POWER_SAVE_MODE);
}
// check if the file continues existing before schedule the operation
if (!originalFile.exists()) {
Log_OC.d(TAG, mOriginalStoragePath + " not exists anymore");
remoteOperationResult = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
}
// check that internet is not behind walled garden
if (!connectivityService.getConnectivity().isConnected() || connectivityService.isInternetWalled()) {
remoteOperationResult = new RemoteOperationResult(ResultCode.NO_NETWORK_CONNECTION);
}
return remoteOperationResult;
}
use of com.owncloud.android.lib.common.operations.RemoteOperationResult in project android by nextcloud.
the class UploadFileOperation method encryptedUpload.
// gson cannot handle sparse arrays easily, therefore use hashmap
@SuppressLint("AndroidLintUseSparseArrays")
private RemoteOperationResult encryptedUpload(OwnCloudClient client, OCFile parentFile) {
RemoteOperationResult result = null;
File temporalFile = null;
File originalFile = new File(mOriginalStoragePath);
File expectedFile = null;
FileLock fileLock = null;
long size;
boolean metadataExists = false;
String token = null;
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
String privateKey = arbitraryDataProvider.getValue(getAccount().name, EncryptionUtils.PRIVATE_KEY);
String publicKey = arbitraryDataProvider.getValue(getAccount().name, EncryptionUtils.PUBLIC_KEY);
try {
// check conditions
result = checkConditions(originalFile);
if (result != null) {
return result;
}
/**
*** E2E ****
*/
token = EncryptionUtils.lockFolder(parentFile, client);
// immediately store it
mUpload.setFolderUnlockToken(token);
uploadsStorageManager.updateUpload(mUpload);
// Update metadata
Pair<Boolean, DecryptedFolderMetadata> metadataPair = EncryptionUtils.retrieveMetadata(parentFile, client, privateKey, publicKey);
metadataExists = metadataPair.first;
DecryptedFolderMetadata metadata = metadataPair.second;
/**
** E2E ****
*/
// check name collision
RemoteOperationResult collisionResult = checkNameCollision(client, metadata, parentFile.isEncrypted());
if (collisionResult != null) {
result = collisionResult;
return collisionResult;
}
mFile.setDecryptedRemotePath(parentFile.getDecryptedRemotePath() + originalFile.getName());
String expectedPath = FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), mFile);
expectedFile = new File(expectedPath);
result = copyFile(originalFile, expectedPath);
if (!result.isSuccess()) {
return result;
}
// Get the last modification date of the file from the file system
String lastModifiedTimestamp = Long.toString(originalFile.lastModified() / 1000);
Long creationTimestamp = FileUtil.getCreationTimestamp(originalFile);
/**
*** E2E ****
*/
// Key, always generate new one
byte[] key = EncryptionUtils.generateKey();
// IV, always generate new one
byte[] iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength);
EncryptionUtils.EncryptedFile encryptedFile = EncryptionUtils.encryptFile(mFile, key, iv);
// new random file name, check if it exists in metadata
String encryptedFileName = UUID.randomUUID().toString().replaceAll("-", "");
while (metadata.getFiles().get(encryptedFileName) != null) {
encryptedFileName = UUID.randomUUID().toString().replaceAll("-", "");
}
File encryptedTempFile = File.createTempFile("encFile", encryptedFileName);
FileOutputStream fileOutputStream = new FileOutputStream(encryptedTempFile);
fileOutputStream.write(encryptedFile.encryptedBytes);
fileOutputStream.close();
/**
*** E2E ****
*/
FileChannel channel = null;
try {
channel = new RandomAccessFile(mFile.getStoragePath(), "rw").getChannel();
fileLock = channel.tryLock();
} catch (FileNotFoundException e) {
// this basically means that the file is on SD card
// try to copy file to temporary dir if it doesn't exist
String temporalPath = FileStorageUtils.getInternalTemporalPath(user.getAccountName(), mContext) + mFile.getRemotePath();
mFile.setStoragePath(temporalPath);
temporalFile = new File(temporalPath);
Files.deleteIfExists(Paths.get(temporalPath));
result = copy(originalFile, temporalFile);
if (result.isSuccess()) {
if (temporalFile.length() == originalFile.length()) {
channel = new RandomAccessFile(temporalFile.getAbsolutePath(), "rw").getChannel();
fileLock = channel.tryLock();
} else {
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
}
}
}
try {
size = channel.size();
} catch (IOException e1) {
size = new File(mFile.getStoragePath()).length();
}
for (OCUpload ocUpload : uploadsStorageManager.getAllStoredUploads()) {
if (ocUpload.getUploadId() == getOCUploadId()) {
ocUpload.setFileSize(size);
uploadsStorageManager.updateUpload(ocUpload);
break;
}
}
// / perform the upload
if (size > ChunkedFileUploadRemoteOperation.CHUNK_SIZE_MOBILE) {
boolean onWifiConnection = connectivityService.getConnectivity().isWifi();
mUploadOperation = new ChunkedFileUploadRemoteOperation(encryptedTempFile.getAbsolutePath(), mFile.getParentRemotePath() + encryptedFileName, mFile.getMimeType(), mFile.getEtagInConflict(), lastModifiedTimestamp, onWifiConnection, token, creationTimestamp, mDisableRetries);
} else {
mUploadOperation = new UploadFileRemoteOperation(encryptedTempFile.getAbsolutePath(), mFile.getParentRemotePath() + encryptedFileName, mFile.getMimeType(), mFile.getEtagInConflict(), lastModifiedTimestamp, creationTimestamp, token, mDisableRetries);
}
for (OnDatatransferProgressListener mDataTransferListener : mDataTransferListeners) {
mUploadOperation.addDataTransferProgressListener(mDataTransferListener);
}
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
result = mUploadOperation.execute(client);
// location in the Nextcloud local folder
if (!result.isSuccess() && result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED) {
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
}
if (result.isSuccess()) {
mFile.setDecryptedRemotePath(parentFile.getDecryptedRemotePath() + originalFile.getName());
mFile.setRemotePath(parentFile.getRemotePath() + encryptedFileName);
// update metadata
DecryptedFolderMetadata.DecryptedFile decryptedFile = new DecryptedFolderMetadata.DecryptedFile();
DecryptedFolderMetadata.Data data = new DecryptedFolderMetadata.Data();
data.setFilename(mFile.getDecryptedFileName());
data.setMimetype(mFile.getMimeType());
data.setKey(EncryptionUtils.encodeBytesToBase64String(key));
decryptedFile.setEncrypted(data);
decryptedFile.setInitializationVector(EncryptionUtils.encodeBytesToBase64String(iv));
decryptedFile.setAuthenticationTag(encryptedFile.authenticationTag);
metadata.getFiles().put(encryptedFileName, decryptedFile);
EncryptedFolderMetadata encryptedFolderMetadata = EncryptionUtils.encryptFolderMetadata(metadata, privateKey);
String serializedFolderMetadata = EncryptionUtils.serializeJSON(encryptedFolderMetadata);
// upload metadata
EncryptionUtils.uploadMetadata(parentFile, serializedFolderMetadata, token, client, metadataExists);
// unlock
result = EncryptionUtils.unlockFolder(parentFile, client, token);
if (result.isSuccess()) {
token = null;
}
}
} catch (FileNotFoundException e) {
Log_OC.d(TAG, mFile.getStoragePath() + " not exists anymore");
result = new RemoteOperationResult(ResultCode.LOCAL_FILE_NOT_FOUND);
} catch (OverlappingFileLockException e) {
Log_OC.d(TAG, "Overlapping file lock exception");
result = new RemoteOperationResult(ResultCode.LOCK_FAILED);
} catch (Exception e) {
result = new RemoteOperationResult(e);
} finally {
mUploadStarted.set(false);
if (fileLock != null) {
try {
fileLock.release();
} catch (IOException e) {
Log_OC.e(TAG, "Failed to unlock file with path " + mFile.getStoragePath());
}
}
if (temporalFile != null && !originalFile.equals(temporalFile)) {
temporalFile.delete();
}
if (result == null) {
result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
}
logResult(result, mFile.getStoragePath(), mFile.getRemotePath());
}
if (result.isSuccess()) {
handleSuccessfulUpload(temporalFile, expectedFile, originalFile, client);
} else if (result.getCode() == ResultCode.SYNC_CONFLICT) {
getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
}
// unlock must be done always
if (token != null) {
RemoteOperationResult unlockFolderResult = EncryptionUtils.unlockFolder(parentFile, client, token);
if (!unlockFolderResult.isSuccess()) {
return unlockFolderResult;
}
}
// delete temporal file
if (temporalFile != null && temporalFile.exists() && !temporalFile.delete()) {
Log_OC.e(TAG, "Could not delete temporal file " + temporalFile.getAbsolutePath());
}
return result;
}
use of com.owncloud.android.lib.common.operations.RemoteOperationResult in project android by nextcloud.
the class UploadFileOperation method copyFile.
private RemoteOperationResult copyFile(File originalFile, String expectedPath) throws OperationCancelledException, IOException {
if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY && !mOriginalStoragePath.equals(expectedPath)) {
String temporalPath = FileStorageUtils.getInternalTemporalPath(user.getAccountName(), mContext) + mFile.getRemotePath();
mFile.setStoragePath(temporalPath);
File temporalFile = new File(temporalPath);
return copy(originalFile, temporalFile);
}
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
return new RemoteOperationResult(ResultCode.OK);
}
Aggregations