<string name="uploader_upload_succeeded_content_single">%1$s was successfully uploaded</string>
<string name="uploader_upload_failed_ticker">Upload failed</string>
<string name="uploader_upload_failed_content_single">Upload of %1$s could not be completed</string>
+ <string name="uploader_upload_failed_credentials_error">Upload failed, you need to relogin</string>
<string name="downloader_download_in_progress_ticker">Downloading …</string>
<string name="downloader_download_in_progress_content">%1$d%% Downloading %2$s</string>
<string name="downloader_download_succeeded_ticker">Download succeeded</string>
<string name="downloader_download_failed_ticker">Download failed</string>
<string name="downloader_download_failed_content">Download of %1$s could not be completed</string>
<string name="downloader_not_downloaded_yet">Not downloaded yet</string>
+ <string name="downloader_download_failed_credentials_error">Download failed, you need to relogin</string>
<string name="common_choose_account">Choose account</string>
<string name="sync_fail_ticker">Synchronization failed</string>
<string name="sync_fail_content">Synchronization of %1$s could not be completed</string>
<string name="clipboard_text_copied">Copied to clipboard</string>
<string name="error_cant_bind_to_operations_service">Critical error: cannot perform operations</string>
+
+ <string name="network_error_socket_exception">An error occurred while connecting with the server.</string>
+ <string name="network_error_socket_timeout_exception">An error occurred while waiting for the server, the operation couldn\'t have been done</string>
+ <string name="network_error_connect_timeout_exception">An error occurred while waiting for the server, the operation couldn\'t have been done</string>
+ <string name="network_host_not_available">The operation couldn\'t be completed, server is unavaliable</string>
+
</resources>
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
+import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.Log_OC;
import com.owncloud.android.utils.NotificationBuilderWithProgressBar;
private void notifyDownloadResult(DownloadFileOperation download, RemoteOperationResult downloadResult) {
mNotificationManager.cancel(R.string.downloader_download_in_progress_ticker);
if (!downloadResult.isCancelled()) {
- int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;
- int contentId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;
- mNotificationBuilder
- .setTicker(getString(tickerId))
- .setContentTitle(getString(tickerId))
- .setAutoCancel(true)
- .setOngoing(false)
- .setProgress(0, 0, false);
+ int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker :
+ R.string.downloader_download_failed_ticker;
+
boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED ||
- // (downloadResult.isTemporalRedirection() && downloadResult.isIdPRedirection()
(downloadResult.isIdPRedirection()
&& mDownloadClient.getCredentials() == null));
- //&& MainApp.getAuthTokenTypeSamlSessionCookie().equals(mDownloadClient.getAuthTokenType())));
+ tickerId = (needsToUpdateCredentials) ?
+ R.string.downloader_download_failed_credentials_error : tickerId;
+
+ mNotificationBuilder
+ .setTicker(getString(tickerId))
+ .setContentTitle(getString(tickerId))
+ .setAutoCancel(true)
+ .setOngoing(false)
+ .setProgress(0, 0, false);
+
if (needsToUpdateCredentials) {
+
// let the user update credentials with one click
Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, download.getAccount());
updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
mNotificationBuilder
.setContentIntent(PendingIntent.getActivity(
- this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT
- ))
- .setContentText(String.format(getString(contentId), new File(download.getSavePath()).getName()));
+ this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT));
+
mDownloadClient = null; // grant that future retries on the same account will get the fresh credentials
} else {
}
mNotificationBuilder
.setContentIntent(PendingIntent.getActivity(
- this, (int) System.currentTimeMillis(), showDetailsIntent, 0
- ))
- .setContentText(String.format(getString(contentId), new File(download.getSavePath()).getName()));
+ this, (int) System.currentTimeMillis(), showDetailsIntent, 0));
}
+
+ mNotificationBuilder.setContentText(ErrorMessageAdapter.getErrorCauseMessage(downloadResult, download, getResources()));
+
mNotificationManager.notify(tickerId, mNotificationBuilder.build());
}
}
import com.owncloud.android.ui.activity.InstantUploadActivity;
import com.owncloud.android.ui.preview.PreviewImageActivity;
import com.owncloud.android.ui.preview.PreviewImageFragment;
+import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.Log_OC;
import com.owncloud.android.utils.NotificationBuilderWithProgressBar;
))
.setTicker(getString(R.string.uploader_upload_succeeded_ticker))
.setContentTitle(getString(R.string.uploader_upload_succeeded_ticker))
- .setContentText(
- String.format(getString(R.string.uploader_upload_succeeded_content_single),
- upload.getFileName())
- );
+ .setContentText(ErrorMessageAdapter.getErrorCauseMessage(uploadResult, upload, getResources()));
mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build()); // NOT
// AN
} else {
// / fail -> explicit failure notification
- mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
+ mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
+
NotificationCompat.Builder errorBuilder = new NotificationCompat.Builder(this);
- errorBuilder
- .setSmallIcon(R.drawable.notification_icon)
- .setTicker(getString(R.string.uploader_upload_failed_ticker))
- .setContentTitle(getString(R.string.uploader_upload_failed_ticker))
- .setAutoCancel(true);
- String content = null;
- boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
- //(uploadResult.isTemporalRedirection() && uploadResult.isIdPRedirection() &&
+ String content = null;
+
+ // check credentials error
+ boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
(uploadResult.isIdPRedirection() &&
mUploadClient.getCredentials() == null));
- //MainApp.getAuthTokenTypeSamlSessionCookie().equals(mUploadClient.getAuthTokenType())));
+ int tickerId = (needsToUpdateCredentials) ?
+ R.string.uploader_upload_failed_credentials_error : R.string.uploader_upload_failed_ticker;
+
+ errorBuilder
+ .setSmallIcon(R.drawable.notification_icon)
+ .setTicker(getString(tickerId))
+ .setContentTitle(getString(tickerId))
+ .setAutoCancel(true);
+
+ content = ErrorMessageAdapter.getErrorCauseMessage(uploadResult, upload, getResources());
+
if (needsToUpdateCredentials) {
// let the user update credentials with one click
Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
errorBuilder.setContentIntent(PendingIntent.getActivity(
this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT
));
- content = String.format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
+
mUploadClient = null; // grant that future retries on the same account will get the fresh credentials
} else {
// TODO put something smart in the contentIntent below
-
- 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
}
errorBuilder.setContentText(content);
- mNotificationManager.notify(R.string.uploader_upload_failed_ticker, errorBuilder.build());
+ mNotificationManager.notify(tickerId, errorBuilder.build());
}
}
import com.owncloud.android.services.OperationsService;
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.dialog.LoadingDialog;
+import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.Log_OC;
Intent sendIntent = operation.getSendIntent();
startActivity(sendIntent);
- } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND
- Toast t = Toast.makeText(this, getString(R.string.share_link_file_no_exist), Toast.LENGTH_LONG);
- t.show();
- } else { // Generic error
- // Show a Message, operation finished without success
- Toast t = Toast.makeText(this, getString(R.string.share_link_file_error), Toast.LENGTH_LONG);
+ } else {
+ Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
t.show();
- }
+ }
}
if (result.isSuccess()){
updateFileFromDB();
- } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND
- Toast t = Toast.makeText(this, getString(R.string.unshare_link_file_no_exist), Toast.LENGTH_LONG);
- t.show();
- } else { // Generic error
- // Show a Message, operation finished without success
- Toast t = Toast.makeText(this, getString(R.string.unshare_link_file_error), Toast.LENGTH_LONG);
+ } else {
+ Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
t.show();
- }
-
+ }
}
import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.ui.preview.PreviewVideoActivity;
import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.Log_OC;
*/
private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) {
dismissLoadingDialog();
+
+ Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
+ msg.show();
+
if (result.isSuccess()) {
- Toast msg = Toast.makeText(this, R.string.remove_success_msg, Toast.LENGTH_LONG);
- msg.show();
OCFile removedFile = operation.getFile();
FileFragment second = getSecondFragment();
if (second != null && removedFile.equals(second.getFile())) {
}
invalidateOptionsMenu();
} else {
- Toast msg = Toast.makeText(this, R.string.remove_fail_msg, Toast.LENGTH_LONG);
- msg.show();
if (result.isSslRecoverableException()) {
mLastSslUntrustedServerResult = result;
showUntrustedCertDialog(mLastSslUntrustedServerResult);
refreshListOfFilesFragment();
} else {
dismissLoadingDialog();
- if (result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME) {
- Toast.makeText(FileDisplayActivity.this, R.string.filename_forbidden_characters, Toast.LENGTH_LONG).show();
- } else {
try {
- Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG);
+ Toast msg = Toast.makeText(FileDisplayActivity.this,
+ ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
msg.show();
} catch (NotFoundException e) {
Log_OC.e(TAG, "Error while trying to show fail message " , e);
}
- }
}
}
}
} else {
- if (result.getCode().equals(ResultCode.INVALID_LOCAL_FILE_NAME)) {
- Toast msg = Toast.makeText(this, R.string.rename_local_fail_msg, Toast.LENGTH_LONG);
- msg.show();
- // TODO throw again the new rename dialog
- } if (result.getCode().equals(ResultCode.INVALID_CHARACTER_IN_NAME)) {
- Toast msg = Toast.makeText(this, R.string.filename_forbidden_characters, Toast.LENGTH_LONG);
- msg.show();
- } else {
- Toast msg = Toast.makeText(this, R.string.rename_server_fail_msg, Toast.LENGTH_LONG);
- msg.show();
- if (result.isSslRecoverableException()) {
- mLastSslUntrustedServerResult = result;
- showUntrustedCertDialog(mLastSslUntrustedServerResult);
- }
+ Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
+ msg.show();
+
+ if (result.isSslRecoverableException()) {
+ mLastSslUntrustedServerResult = result;
+ showUntrustedCertDialog(mLastSslUntrustedServerResult);
}
}
}
onTransferStateChanged(syncedFile, true, true);
} else {
- Toast msg = Toast.makeText(this, R.string.sync_file_nothing_to_do_msg, Toast.LENGTH_LONG);
+ Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+ Toast.LENGTH_LONG);
msg.show();
}
}
--- /dev/null
+/* ownCloud Android client application
+ * Copyright (C) 2014 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+package com.owncloud.android.utils;
+
+import java.io.File;
+import java.net.SocketTimeoutException;
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import android.content.res.Resources;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.operations.CreateShareOperation;
+import com.owncloud.android.operations.DownloadFileOperation;
+import com.owncloud.android.operations.RemoveFileOperation;
+import com.owncloud.android.operations.RenameFileOperation;
+import com.owncloud.android.operations.SynchronizeFileOperation;
+import com.owncloud.android.operations.UnshareLinkOperation;
+import com.owncloud.android.operations.UploadFileOperation;
+
+/**
+ * Class to choose proper error messages to show to the user depending on the results of operations, always following the same policy
+ *
+ * @author masensio
+ *
+ */
+
+public class ErrorMessageAdapter {
+
+ public ErrorMessageAdapter() {
+
+ }
+
+ public static String getErrorCauseMessage(RemoteOperationResult result, RemoteOperation operation, Resources res) {
+
+ String message = null;
+
+ if (operation instanceof UploadFileOperation) {
+
+ if (result.isSuccess()) {
+ message = String.format(res.getString(R.string.uploader_upload_succeeded_content_single),
+ ((UploadFileOperation) operation).getFileName());
+ } else {
+ if (result.getCode() == ResultCode.LOCAL_STORAGE_FULL
+ || result.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
+ message = String.format(res.getString(R.string.error__upload__local_file_not_copied),
+ ((UploadFileOperation) operation).getFileName());
+
+ } else if (result.getCode() == ResultCode.QUOTA_EXCEEDED) {
+ message = res.getString(R.string.failed_upload_quota_exceeded_text);
+
+ } else {
+ message = String.format(res.getString(R.string.uploader_upload_failed_content_single),
+ ((UploadFileOperation) operation).getFileName());
+ }
+ }
+
+ } else if (operation instanceof DownloadFileOperation) {
+
+ if (result.isSuccess()) {
+ message = String.format(res.getString(R.string.downloader_download_succeeded_content),
+ new File(((DownloadFileOperation) operation).getSavePath()).getName());
+
+ } else {
+ message = String.format(res.getString(R.string.downloader_download_failed_content),
+ new File(((DownloadFileOperation) operation).getSavePath()).getName());
+ }
+
+ } else if (operation instanceof RemoveFileOperation) {
+ if (result.isSuccess()) {
+ message = res.getString(R.string.remove_success_msg);
+
+ } else {
+ if (isNetworkError(result.getCode())) {
+ message = getErrorMessage(result, res);
+
+ } else {
+ message = res.getString(R.string.remove_fail_msg);
+ }
+ }
+
+ } else if (operation instanceof RenameFileOperation) {
+ if (result.getCode().equals(ResultCode.INVALID_LOCAL_FILE_NAME)) {
+ message = res.getString(R.string.rename_local_fail_msg);
+
+ } if (result.getCode().equals(ResultCode.INVALID_CHARACTER_IN_NAME)) {
+ message = res.getString(R.string.filename_forbidden_characters);
+
+ } else if (isNetworkError(result.getCode())) {
+ message = getErrorMessage(result, res);
+
+ } else {
+ message = res.getString(R.string.rename_server_fail_msg);
+ }
+
+ } else if (operation instanceof SynchronizeFileOperation) {
+ if (!((SynchronizeFileOperation) operation).transferWasRequested()) {
+ message = res.getString(R.string.sync_file_nothing_to_do_msg);
+ }
+
+ } else if (operation instanceof CreateFolderOperation) {
+ if (result.getCode() == ResultCode.INVALID_CHARACTER_IN_NAME) {
+ message = res.getString(R.string.filename_forbidden_characters);
+
+ } else if (isNetworkError(result.getCode())) {
+ message = getErrorMessage(result, res);
+
+ } else {
+ message = res.getString(R.string.create_dir_fail_msg);
+ }
+ } else if (operation instanceof CreateShareOperation) {
+ if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND
+ message = res.getString(R.string.share_link_file_no_exist);
+
+ } else if (isNetworkError(result.getCode())) {
+ message = getErrorMessage(result, res);
+
+ } else { // Generic error
+ // Show a Message, operation finished without success
+ message = res.getString(R.string.share_link_file_error);
+ }
+
+ } else if (operation instanceof UnshareLinkOperation) {
+
+ if (result.getCode() == ResultCode.SHARE_NOT_FOUND) { // Error --> SHARE_NOT_FOUND
+ message = res.getString(R.string.unshare_link_file_no_exist);
+
+ } else if (isNetworkError(result.getCode())) {
+ message = getErrorMessage(result, res);
+
+ } else { // Generic error
+ // Show a Message, operation finished without success
+ message = res.getString(R.string.unshare_link_file_error);
+ }
+ }
+
+ return message;
+ }
+
+ private static String getErrorMessage(RemoteOperationResult result , Resources res) {
+
+ String message = null;
+
+ if (!result.isSuccess()) {
+
+ if (result.getCode() == ResultCode.WRONG_CONNECTION) {
+ message = res.getString(R.string.network_error_socket_exception);
+
+ } else if (result.getCode() == ResultCode.TIMEOUT) {
+ message = res.getString(R.string.network_error_socket_exception);
+
+ if (result.getException() instanceof SocketTimeoutException) {
+ message = res.getString(R.string.network_error_socket_timeout_exception);
+ } else if(result.getException() instanceof ConnectTimeoutException) {
+ message = res.getString(R.string.network_error_connect_timeout_exception);
+ }
+
+ } else if (result.getCode() == ResultCode.HOST_NOT_AVAILABLE) {
+ message = res.getString(R.string.network_host_not_available);
+ }
+ }
+
+ return message;
+ }
+
+ private static boolean isNetworkError(RemoteOperationResult.ResultCode code) {
+ if (code == ResultCode.WRONG_CONNECTION ||
+ code == ResultCode.TIMEOUT ||
+ code == ResultCode.HOST_NOT_AVAILABLE) {
+ return true;
+ }
+ else
+ return false;
+ }
+}