From: masensio Date: Wed, 16 Oct 2013 12:26:02 +0000 (-0700) Subject: Merge pull request #268 from owncloud/fix_fails_in_uploads_after_fall_and_rise_of_net... X-Git-Tag: oc-android-1.4.6~3 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/db1ea015619a1cc5a3886ea90dc20f910fc6dd9e?hp=b5d86aa9defd685d97459dfc6224d820be4ceb7a Merge pull request #268 from owncloud/fix_fails_in_uploads_after_fall_and_rise_of_network_connection Fix fails in uploads after fall and rise of network connection --- diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png index e388c7be..8a2fe193 100644 Binary files a/res/drawable-hdpi/icon.png and b/res/drawable-hdpi/icon.png differ diff --git a/res/drawable-hdpi/logo.png b/res/drawable-hdpi/logo.png index ecea3b0e..a920912c 100644 Binary files a/res/drawable-hdpi/logo.png and b/res/drawable-hdpi/logo.png differ diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png index 11cf0ab1..f8f54b73 100644 Binary files a/res/drawable-ldpi/icon.png and b/res/drawable-ldpi/icon.png differ diff --git a/res/drawable-ldpi/logo.png b/res/drawable-ldpi/logo.png index 62dff255..7de7cb84 100644 Binary files a/res/drawable-ldpi/logo.png and b/res/drawable-ldpi/logo.png differ diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png index 6997c7e4..42bbaad0 100644 Binary files a/res/drawable-mdpi/icon.png and b/res/drawable-mdpi/icon.png differ diff --git a/res/drawable-mdpi/logo.png b/res/drawable-mdpi/logo.png index ecea3b0e..a920912c 100644 Binary files a/res/drawable-mdpi/logo.png and b/res/drawable-mdpi/logo.png differ diff --git a/res/layout/media_control.xml b/res/layout/media_control.xml index 489c9973..f308edca 100644 --- a/res/layout/media_control.xml +++ b/res/layout/media_control.xml @@ -27,7 +27,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:paddingTop="4dip" + android:paddingTop="4dp" android:orientation="horizontal" > @@ -58,33 +58,33 @@ android:id="@+id/currentTimeText" android:textSize="14sp" android:textStyle="bold" - android:paddingTop="4dip" - android:paddingStart="4dip" + android:paddingTop="4dp" + android:paddingStart="4dp" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingEnd="4dip" + android:paddingEnd="4dp" android:text="@string/placeholder_media_time" /> diff --git a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java index 6eb6ec7b..fa8662f3 100644 --- a/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java +++ b/src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java @@ -54,8 +54,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver { Log_OC.d(TAG, "Received: " + intent.getAction()); if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) { handleConnectivityAction(context, intent); - } else if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH && - intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) { + }else if (intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) { handleNewPhotoAction(context, intent); Log_OC.d(TAG, "UNOFFICIAL processed: com.android.camera.NEW_PICTURE"); } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) { diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 06d834fd..aa7925d1 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -271,7 +271,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe if (isInstant) { newUpload.setRemoteFolderToBeCreated(); } - mPendingUploads.putIfAbsent(uploadKey, newUpload); + mPendingUploads.putIfAbsent(uploadKey, newUpload); // Grants that the file only upload once time + newUpload.addDatatransferProgressListener(this); newUpload.addDatatransferProgressListener((FileUploaderBinder)mBinder); requestedUploads.add(uploadKey); @@ -721,12 +722,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon); /// includes a pending intent in the notification showing the details view of the file - Intent showDetailsIntent = null; - if (PreviewImageFragment.canBePreviewed(upload.getFile())) { - showDetailsIntent = new Intent(this, PreviewImageActivity.class); - } else { - showDetailsIntent = new Intent(this, FileDisplayActivity.class); - } + Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class); showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile()); showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount()); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); diff --git a/src/com/owncloud/android/operations/ExistenceCheckOperation.java b/src/com/owncloud/android/operations/ExistenceCheckOperation.java index e404a6f8..136fe224 100644 --- a/src/com/owncloud/android/operations/ExistenceCheckOperation.java +++ b/src/com/owncloud/android/operations/ExistenceCheckOperation.java @@ -23,6 +23,7 @@ import org.apache.commons.httpclient.methods.HeadMethod; import com.owncloud.android.Log_OC; import eu.alefzero.webdav.WebdavClient; +import eu.alefzero.webdav.WebdavUtils; import android.content.Context; import android.net.ConnectivityManager; @@ -65,16 +66,16 @@ public class ExistenceCheckOperation extends RemoteOperation { RemoteOperationResult result = null; HeadMethod head = null; try { - head = new HeadMethod(client.getBaseUri() + mPath); + head = new HeadMethod(client.getBaseUri() + WebdavUtils.encodePath(mPath)); int status = client.executeMethod(head, TIMEOUT, TIMEOUT); client.exhaustResponse(head.getResponseBodyAsStream()); boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); result = new RemoteOperationResult(success, status, head.getResponseHeaders()); - Log_OC.d(TAG, "Existence check for " + client.getBaseUri() + mPath + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); + Log_OC.d(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); } catch (Exception e) { result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Existence check for " + client.getBaseUri() + mPath + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); + Log_OC.e(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); } finally { if (head != null) diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index db47d465..284ece2d 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -86,6 +86,7 @@ import com.owncloud.android.ui.fragment.FileDetailFragment; import com.owncloud.android.ui.fragment.FileFragment; import com.owncloud.android.ui.fragment.OCFileListFragment; import com.owncloud.android.ui.preview.PreviewImageActivity; +import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; import com.owncloud.android.ui.preview.PreviewVideoActivity; @@ -211,12 +212,15 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account OCFile file = getFile(); + // get parent from path + String parentPath = ""; if (file != null) { if (file.isDown() && file.getLastSyncDateForProperties() == 0) { // upload in progress - right now, files are not inserted in the local cache until the upload is successful - if (mStorageManager.getFileById(file.getParentId()) == null) { - file = null; // not able to know the directory where the file is uploading - } + // get parent from path + parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName())); + if (mStorageManager.getFileByPath(parentPath) == null) + file = null; // not able to know the directory where the file is uploading } else { file = mStorageManager.getFileByPath(file.getRemotePath()); // currentDir = null if not in the current Account } @@ -232,7 +236,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (fileIt.isDirectory()) { mDirectories.add(fileIt.getFileName()); } - fileIt = mStorageManager.getFileById(fileIt.getParentId()); + // get parent from path + parentPath = fileIt.getRemotePath().substring(0, fileIt.getRemotePath().lastIndexOf(fileIt.getFileName())); + fileIt = mStorageManager.getFileByPath(parentPath); } mDirectories.add(OCFile.PATH_SEPARATOR); if (!stateWasRecovered) { @@ -855,7 +861,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa Log_OC.d(TAG, "sync of account " + accountName + " is in_progress: " + inProgress); - if (getAccount() != null && accountName.equals(getAccount().name)) { + if (getAccount() != null && accountName.equals(getAccount().name) + && mStorageManager != null + ) { String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH); @@ -869,7 +877,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if ((synchFolderRemotePath != null && currentDir != null && (currentDir.getRemotePath().equals(synchFolderRemotePath))) || fillBlankRoot ) { if (!fillBlankRoot) - currentDir = getStorageManager().getFileByPath(synchFolderRemotePath); + currentDir = mStorageManager.getFileByPath(synchFolderRemotePath); OCFileListFragment fileListFragment = getListOfFilesFragment(); if (fileListFragment != null) { fileListFragment.listDirectory(currentDir); @@ -1358,7 +1366,8 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa if (file.isDirectory()) { return file; } else if (mStorageManager != null) { - return mStorageManager.getFileById(file.getParentId()); + String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName())); + return mStorageManager.getFileByPath(parentPath); } } return null; diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java index 5380a883..d1269f58 100644 --- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java +++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java @@ -64,6 +64,7 @@ import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.dialog.EditNameDialog; import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener; +import com.owncloud.android.ui.preview.PreviewImageFragment; import eu.alefzero.webdav.OnDatatransferProgressListener; @@ -741,7 +742,13 @@ public class FileDetailFragment extends FileFragment implements msg.show(); } getSherlockActivity().removeStickyBroadcast(intent); // not the best place to do this; a small refactorization of BroadcastReceivers should be done + updateFileDetails(false, false); // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server + + // Force the preview if the file is an image + if (uploadWasFine && PreviewImageFragment.canBePreviewed(getFile())) { + ((FileDisplayActivity) mContainerActivity).startImagePreview(getFile()); + } } } } diff --git a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java index ef1e977c..50cab7ee 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@ -16,8 +16,6 @@ */ package com.owncloud.android.ui.preview; -import android.app.Dialog; -import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -105,7 +103,10 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C } private void initViewPager() { - OCFile parentFolder = mStorageManager.getFileById(getFile().getParentId()); + // get parent from path + String parentPath = getFile().getRemotePath().substring(0, getFile().getRemotePath().lastIndexOf(getFile().getFileName())); + OCFile parentFolder = mStorageManager.getFileByPath(parentPath); + //OCFile parentFolder = mStorageManager.getFileById(getFile().getParentId()); if (parentFolder == null) { // should not be necessary parentFolder = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR); @@ -153,7 +154,7 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C Log_OC.d(TAG, "Simulating reselection of current page after connection of download binder"); onPageSelected(mViewPager.getCurrentItem()); } - + } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) { Log_OC.d(TAG, "Upload service connected"); mUploaderBinder = (FileUploaderBinder) service; @@ -430,8 +431,12 @@ public class PreviewImageActivity extends FileActivity implements FileFragment.C if (!file.isImage()) { throw new IllegalArgumentException("Non-image file passed as argument"); } - mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); - file = mStorageManager.getFileById(file.getFileId()); + mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver()); + + // Update file according to DB file, if it is possible + if (file.getFileId() > DataStorageManager.ROOT_PARENT_ID) + file = mStorageManager.getFileById(file.getFileId()); + if (file != null) { /// Refresh the activity according to the Account and OCFile set setFile(file); // reset after getting it fresh from mStorageManager diff --git a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java index 291bd4a0..578c56e8 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -56,7 +56,6 @@ import com.owncloud.android.operations.OnRemoteOperationListener; import com.owncloud.android.operations.RemoteOperation; import com.owncloud.android.operations.RemoteOperationResult; import com.owncloud.android.operations.RemoveFileOperation; -import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.fragment.ConfirmationDialogFragment; import com.owncloud.android.ui.fragment.FileFragment; diff --git a/src/eu/alefzero/webdav/ChunkFromFileChannelRequestEntity.java b/src/eu/alefzero/webdav/ChunkFromFileChannelRequestEntity.java index 3f453968..103cd04a 100644 --- a/src/eu/alefzero/webdav/ChunkFromFileChannelRequestEntity.java +++ b/src/eu/alefzero/webdav/ChunkFromFileChannelRequestEntity.java @@ -120,11 +120,14 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres mChannel.position(mOffset); long size = mFile.length(); if (size == 0) size = -1; - while (mChannel.position() < mOffset + mChunkSize && mChannel.position() < mChannel.size()) { + long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); + while (mChannel.position() < maxCount) { readCount = mChannel.read(mBuffer); out.write(mBuffer.array(), 0, readCount); mBuffer.clear(); - mTransferred += readCount; + if (mTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks + mTransferred += readCount; + } synchronized (mDataTransferListeners) { it = mDataTransferListeners.iterator(); while (it.hasNext()) { diff --git a/src/eu/alefzero/webdav/WebdavClient.java b/src/eu/alefzero/webdav/WebdavClient.java index cedf9267..f25e3906 100644 --- a/src/eu/alefzero/webdav/WebdavClient.java +++ b/src/eu/alefzero/webdav/WebdavClient.java @@ -24,12 +24,14 @@ import java.util.ArrayList; import java.util.List; import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpConnectionManager; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthPolicy; import org.apache.commons.httpclient.auth.AuthScope; @@ -48,6 +50,8 @@ import com.owncloud.android.network.BearerCredentials; import android.net.Uri; public class WebdavClient extends HttpClient { + private static final int MAX_REDIRECTIONS_COUNT = 3; + private Uri mUri; private Credentials mCredentials; private boolean mFollowRedirects; @@ -160,15 +164,39 @@ public class WebdavClient extends HttpClient { @Override public int executeMethod(HttpMethod method) throws IOException, HttpException { + boolean customRedirectionNeeded = false; try { method.setFollowRedirects(mFollowRedirects); } catch (Exception e) { - + if (mFollowRedirects) Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName() + " method, custom redirection will be used"); + customRedirectionNeeded = mFollowRedirects; } if (mSsoSessionCookie != null && mSsoSessionCookie.length() > 0) { method.setRequestHeader("Cookie", mSsoSessionCookie); } - return super.executeMethod(method); + int status = super.executeMethod(method); + int redirectionsCount = 0; + while (customRedirectionNeeded && + redirectionsCount < MAX_REDIRECTIONS_COUNT && + ( status == HttpStatus.SC_MOVED_PERMANENTLY || + status == HttpStatus.SC_MOVED_TEMPORARILY || + status == HttpStatus.SC_TEMPORARY_REDIRECT) + ) { + + Header location = method.getResponseHeader("Location"); + if (location != null) { + Log_OC.d(TAG, "Location to redirect: " + location.getValue()); + method.setURI(new URI(location.getValue(), true)); + status = super.executeMethod(method); + redirectionsCount++; + + } else { + Log_OC.d(TAG, "No location to redirect!"); + status = HttpStatus.SC_NOT_FOUND; + } + } + + return status; }