X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/5b9935c849edbbfbaea563f95373f7f7dbe0fc59..a8fade7369bc8d1752dc4ba5fe07935cac84e96f:/src/com/owncloud/android/files/services/FileUploader.java diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index a3c76ebc..a02e74a5 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -19,6 +19,7 @@ package com.owncloud.android.files.services; import java.io.File; +import java.io.IOException; import java.util.AbstractList; import java.util.HashMap; import java.util.Iterator; @@ -31,8 +32,27 @@ import org.apache.http.HttpStatus; import org.apache.jackrabbit.webdav.MultiStatus; import org.apache.jackrabbit.webdav.client.methods.PropFindMethod; +import com.owncloud.android.authentication.AccountAuthenticator; +import com.owncloud.android.authentication.AuthenticatorActivity; +import com.owncloud.android.datamodel.FileDataStorageManager; +import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.operations.ChunkedUploadFileOperation; +import com.owncloud.android.operations.CreateFolderOperation; +import com.owncloud.android.operations.RemoteOperation; +import com.owncloud.android.operations.RemoteOperationResult; +import com.owncloud.android.operations.UploadFileOperation; +import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.utils.OwnCloudVersion; + +import eu.alefzero.webdav.OnDatatransferProgressListener; +import eu.alefzero.webdav.WebdavEntry; +import eu.alefzero.webdav.WebdavUtils; + +import com.owncloud.android.network.OwnCloudClientUtils; + import android.accounts.Account; import android.accounts.AccountManager; +import android.accounts.AccountsException; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -47,32 +67,19 @@ import android.os.Message; import android.os.Process; import android.webkit.MimeTypeMap; import android.widget.RemoteViews; -import android.widget.Toast; import com.owncloud.android.Log_OC; import com.owncloud.android.R; -import com.owncloud.android.authenticator.AccountAuthenticator; -import com.owncloud.android.datamodel.FileDataStorageManager; -import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.db.DbHandler; -import com.owncloud.android.network.OwnCloudClientUtils; -import com.owncloud.android.operations.ChunkedUploadFileOperation; -import com.owncloud.android.operations.RemoteOperationResult; -import com.owncloud.android.operations.RemoteOperationResult.ResultCode; -import com.owncloud.android.operations.UploadFileOperation; import com.owncloud.android.ui.activity.FailedUploadActivity; -import com.owncloud.android.ui.activity.FileDetailActivity; +import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.ui.activity.FileDisplayActivity; import com.owncloud.android.ui.activity.InstantUploadActivity; -import com.owncloud.android.ui.fragment.FileDetailFragment; import com.owncloud.android.ui.preview.PreviewImageActivity; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.utils.FileStorageUtils; -import com.owncloud.android.utils.OwnCloudVersion; -import eu.alefzero.webdav.OnDatatransferProgressListener; import eu.alefzero.webdav.WebdavClient; -import eu.alefzero.webdav.WebdavEntry; -import eu.alefzero.webdav.WebdavUtils; public class FileUploader extends Service implements OnDatatransferProgressListener { @@ -490,37 +497,48 @@ public class FileUploader extends Service implements OnDatatransferProgressListe notifyUploadStart(mCurrentUpload); - // / prepare client object to send requests to the ownCloud server - if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) { - mLastAccount = mCurrentUpload.getAccount(); - mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver()); - mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext()); - } - - // / create remote folder for instant uploads - if (mCurrentUpload.isRemoteFolderToBeCreated()) { - mUploadClient.createDirectory(FileStorageUtils.getInstantUploadFilePath(this, "")); - // ignoring result fail could just mean that it already exists, - // but local database is not synchronized the upload will be - // tried anyway - } - - // / perform the upload RemoteOperationResult uploadResult = null; + try { + /// prepare client object to send requests to the ownCloud server + if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) { + mLastAccount = mCurrentUpload.getAccount(); + mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver()); + mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext()); + } + + /// create remote folder for instant uploads + if (mCurrentUpload.isRemoteFolderToBeCreated()) { + RemoteOperation operation = new CreateFolderOperation( FileStorageUtils.getInstantUploadFilePath(this, ""), + mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR).getFileId(), // TODO generalize this : INSTANT_UPLOAD_DIR could not be a child of root + mStorageManager); + operation.execute(mUploadClient); // ignoring result; fail could just mean that it already exists, but local database is not synchronized; the upload will be tried anyway + } + + + /// perform the upload uploadResult = mCurrentUpload.execute(mUploadClient); if (uploadResult.isSuccess()) { saveUploadedFile(); } - + + } catch (AccountsException e) { + Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e); + uploadResult = new RemoteOperationResult(e); + + } catch (IOException e) { + Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e); + uploadResult = new RemoteOperationResult(e); + } finally { synchronized (mPendingUploads) { mPendingUploads.remove(uploadKey); Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map."); } } - - // notify result + + /// notify result + notifyUploadResult(uploadResult, mCurrentUpload); sendFinalBroadcast(mCurrentUpload, uploadResult); @@ -561,7 +579,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream()); } - result = new RemoteOperationResult(isMultiStatus, status); + result = new RemoteOperationResult(isMultiStatus, status, propfind.getResponseHeaders()); Log_OC.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage()); @@ -685,11 +703,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe if (PreviewImageFragment.canBePreviewed(upload.getFile())) { showDetailsIntent = new Intent(this, PreviewImageActivity.class); } else { - showDetailsIntent = new Intent(this, FileDetailActivity.class); - showDetailsIntent.putExtra(FileDetailActivity.EXTRA_MODE, FileDetailActivity.MODE_DETAILS); + showDetailsIntent = new Intent(this, FileDisplayActivity.class); } - showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, upload.getFile()); - showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, upload.getAccount()); + showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile()); + showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount()); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int) System.currentTimeMillis(), showDetailsIntent, 0); @@ -748,11 +765,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe if (PreviewImageFragment.canBePreviewed(upload.getFile())) { showDetailsIntent = new Intent(this, PreviewImageActivity.class); } else { - showDetailsIntent = new Intent(this, FileDetailActivity.class); - showDetailsIntent.putExtra(FileDetailActivity.EXTRA_MODE, FileDetailActivity.MODE_DETAILS); + showDetailsIntent = new Intent(this, FileDisplayActivity.class); } - showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, upload.getFile()); - showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, upload.getAccount()); + showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile()); + showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount()); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int) System.currentTimeMillis(), showDetailsIntent, 0); @@ -775,57 +791,81 @@ public class FileUploader extends Service implements OnDatatransferProgressListe Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis()); finalNotification.flags |= Notification.FLAG_AUTO_CANCEL; - String content = null; - if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL - || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) { - // TODO we need a class to provide error messages for the users - // from a RemoteOperationResult and a RemoteOperation - content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(), - getString(R.string.app_name)); - } else if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) { - content = getString(R.string.failed_upload_quota_exceeded_text); + + boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED || + //(uploadResult.isTemporalRedirection() && uploadResult.isIdPRedirection() && + (uploadResult.isIdPRedirection() && + AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(mUploadClient.getAuthTokenType()))); + if (needsToUpdateCredentials) { + // let the user update credentials with one click + Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class); + updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount()); + updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ENFORCED_UPDATE, true); + updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN); + updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND); + finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT); + content = String.format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName()); + finalNotification.setLatestEventInfo(getApplicationContext(), + getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent); + mUploadClient = null; // grant that future retries on the same account will get the fresh credentials } else { - content = String - .format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName()); - } + // TODO put something smart in the contentIntent below + // finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); + //} + + if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL + || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) { + // TODO we need a class to provide error messages for the users + // from a RemoteOperationResult and a RemoteOperation + content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(), + getString(R.string.app_name)); + } else if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) { + content = getString(R.string.failed_upload_quota_exceeded_text); + } else { + content = String + .format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName()); + } - // we add only for instant-uploads the InstantUploadActivity and the - // db entry - Intent detailUploadIntent = null; - if (upload.isInstant() && InstantUploadActivity.IS_ENABLED) { - detailUploadIntent = new Intent(this, InstantUploadActivity.class); - detailUploadIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount()); - } else { - detailUploadIntent = new Intent(this, FailedUploadActivity.class); - detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content); - } - finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), - (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT - | PendingIntent.FLAG_ONE_SHOT); - - if (upload.isInstant()) { - DbHandler db = null; - try { - db = new DbHandler(this.getBaseContext()); - String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode(); - Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode()); - if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) { - message = getString(R.string.failed_upload_quota_exceeded_text); - } - if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED, - message) == 0) { - db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message); - } - } finally { - if (db != null) { - db.close(); + // we add only for instant-uploads the InstantUploadActivity and the + // db entry + Intent detailUploadIntent = null; + if (upload.isInstant() && InstantUploadActivity.IS_ENABLED) { + detailUploadIntent = new Intent(this, InstantUploadActivity.class); + detailUploadIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount()); + } else { + detailUploadIntent = new Intent(this, FailedUploadActivity.class); + detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content); + } + finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), + (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT + | PendingIntent.FLAG_ONE_SHOT); + + if (upload.isInstant()) { + DbHandler db = null; + try { + db = new DbHandler(this.getBaseContext()); + String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode(); + Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode()); + if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) { + message = getString(R.string.failed_upload_quota_exceeded_text); + } + if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED, + message) == 0) { + db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message); + } + } finally { + if (db != null) { + db.close(); + } } } } finalNotification.setLatestEventInfo(getApplicationContext(), getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent); - + mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification); }