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:
commit
39e3ddaa07
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user