1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Merge pull request #112 from owncloud/reliable_uploads_actions_uploads_view

Update to support changes for uploads view in OC app
This commit is contained in:
David A. Velasco 2016-03-30 13:45:23 +02:00
commit 39e3ddaa07
6 changed files with 101 additions and 25 deletions

View File

@ -25,6 +25,7 @@
package com.owncloud.android.lib.common.network;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
@ -58,7 +59,9 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
private ByteBuffer mBuffer = ByteBuffer.allocate(4096);
public ChunkFromFileChannelRequestEntity(final FileChannel channel, final String contentType, long chunkSize, final File file) {
public ChunkFromFileChannelRequestEntity(
final FileChannel channel, final String contentType, long chunkSize, final File file
) {
super();
if (channel == null) {
throw new IllegalArgumentException("File may not be null");
@ -120,14 +123,19 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
int readCount = 0;
Iterator<OnDatatransferProgressListener> it = null;
try {
try {
mChannel.position(mOffset);
long size = mFile.length();
if (size == 0) size = -1;
long maxCount = Math.min(mOffset + mChunkSize, mChannel.size());
while (mChannel.position() < maxCount) {
readCount = mChannel.read(mBuffer);
out.write(mBuffer.array(), 0, readCount);
try {
out.write(mBuffer.array(), 0, readCount);
} catch (IOException io) {
// work-around try catch to filter exception in writing
throw new FileRequestEntity.WriteException(io);
}
mBuffer.clear();
if (mTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks
mTransferred += readCount;
@ -141,10 +149,19 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
}
} catch (IOException io) {
Log_OC.e(TAG, io.getMessage());
throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);
// any read problem will be handled as if the file is not there
if (io instanceof FileNotFoundException) {
throw io;
} else {
FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
fnf.initCause(io);
throw fnf;
}
} catch (FileRequestEntity.WriteException we) {
throw we.getWrapped();
}
}
}

View File

@ -26,6 +26,7 @@
package com.owncloud.android.lib.common.network;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
@ -100,12 +101,9 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
@Override
public void writeRequest(final OutputStream out) throws IOException {
//byte[] tmp = new byte[4096];
ByteBuffer tmp = ByteBuffer.allocate(4096);
int readResult = 0;
// TODO(bprzybylski): each mem allocation can throw OutOfMemoryError we need to handle it
// globally in some fashionable manner
RandomAccessFile raf = new RandomAccessFile(mFile, "r");
FileChannel channel = raf.getChannel();
Iterator<OnDatatransferProgressListener> it = null;
@ -114,7 +112,12 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
if (size == 0) size = -1;
try {
while ((readResult = channel.read(tmp)) >= 0) {
out.write(tmp.array(), 0, readResult);
try {
out.write(tmp.array(), 0, readResult);
} catch (IOException io) {
// work-around try catch to filter exception in writing
throw new WriteException(io);
}
tmp.clear();
transferred += readResult;
synchronized (mDataTransferListeners) {
@ -126,12 +129,37 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
}
} catch (IOException io) {
Log_OC.e("FileRequestException", io.getMessage());
throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);
// any read problem will be handled as if the file is not there
if (io instanceof FileNotFoundException) {
throw io;
} else {
FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
fnf.initCause(io);
throw fnf;
}
} catch (WriteException we) {
throw we.getWrapped();
} finally {
channel.close();
raf.close();
try {
channel.close();
raf.close();
} catch (IOException io) {
// ignore failures closing source file
}
}
}
protected static class WriteException extends Exception {
IOException mWrapped;
WriteException(IOException wrapped) {
mWrapped = wrapped;
}
public IOException getWrapped() {
return mWrapped;
}
}

View File

@ -307,7 +307,8 @@ public abstract class RemoteOperation implements Runnable {
* to trigger authentication update */
if (mCallerActivity != null && mAccount != null && mContext != null &&
!result.isSuccess() &&
(result.getCode() == ResultCode.UNAUTHORIZED || result.isIdPRedirection())) {
ResultCode.UNAUTHORIZED.equals(result.getCode())
) {
/// possible fail due to lack of authorization
// in an operation performed in foreground
OwnCloudCredentials cred = mClient.getCredentials();

View File

@ -25,6 +25,7 @@
package com.owncloud.android.lib.common.operations;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@ -108,7 +109,10 @@ public class RemoteOperationResult implements Serializable {
PARTIAL_MOVE_DONE,
PARTIAL_COPY_DONE,
SHARE_WRONG_PARAMETER,
WRONG_SERVER_RESPONSE, INVALID_CHARACTER_DETECT_IN_SERVER
WRONG_SERVER_RESPONSE,
INVALID_CHARACTER_DETECT_IN_SERVER,
DELAYED_FOR_WIFI,
LOCAL_FILE_NOT_FOUND
}
private boolean mSuccess = false;
@ -180,6 +184,9 @@ public class RemoteOperationResult implements Serializable {
}
}
}
if (isIdPRedirection()) {
mCode = ResultCode.UNAUTHORIZED; // overrides default ResultCode.UNKNOWN
}
}
public RemoteOperationResult(boolean success, String bodyResponse, int httpCode) {
@ -254,6 +261,9 @@ public class RemoteOperationResult implements Serializable {
mCode = ResultCode.SSL_ERROR;
}
} else if (e instanceof FileNotFoundException) {
mCode = ResultCode.LOCAL_FILE_NOT_FOUND;
} else {
mCode = ResultCode.UNKNOWN_ERROR;
}

View File

@ -32,9 +32,11 @@ import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.FileRequestEntity;
@ -87,8 +89,16 @@ public class UploadRemoteFileOperation extends RemoteOperation {
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
DefaultHttpMethodRetryHandler oldRetryHandler =
(DefaultHttpMethodRetryHandler) client.getParams().getParameter(HttpMethodParams.RETRY_HANDLER);
try {
// prevent that uploads are retried automatically by network library
client.getParams().setParameter(
HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(0, false)
);
mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
if (mCancellationRequested.get()) {
@ -114,6 +124,12 @@ public class UploadRemoteFileOperation extends RemoteOperation {
} else {
result = new RemoteOperationResult(e);
}
} finally {
// reset previous retry handler
client.getParams().setParameter(
HttpMethodParams.RETRY_HANDLER,
oldRetryHandler
);
}
return result;
}

View File

@ -37,6 +37,8 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
public static final OwnCloudVersion owncloud_v4_5 = new OwnCloudVersion(
0x04050000);
public static final int MINIMUN_VERSION_FOR_CHUNKED_UPLOADS = 0x04050000; // 4.5
public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27
public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1
@ -127,6 +129,10 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
}
public boolean isChunkedUploadSupported() {
return (mVersion >= MINIMUN_VERSION_FOR_CHUNKED_UPLOADS);
}
public boolean isSharedSupported() {
return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API);
}
@ -150,6 +156,4 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
public boolean isVersionWithCapabilitiesAPI(){
return (mVersion>= MINIMUM_VERSION_CAPABILITIES_API);
}
}