Updating synchronization for providing SSL warning when necessary; STEP 2: added SSL warning dialog in FileDisplayActivity

This commit is contained in:
David A. Velasco 2012-10-23 15:35:47 +02:00
parent 6e469559c5
commit 808d2a74ab
2 changed files with 107 additions and 22 deletions

View file

@ -57,10 +57,16 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
private final static String TAG = "FileSyncAdapter"; private final static String TAG = "FileSyncAdapter";
/**
* Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation
*/
private static final int MAX_FAILED_RESULTS = 3;
private long mCurrentSyncTime; private long mCurrentSyncTime;
private boolean mCancellation; private boolean mCancellation;
private boolean mIsManualSync; private boolean mIsManualSync;
private boolean mRightSync; private int mFailedResultsCounter;
private RemoteOperationResult mLastFailedResult;
public FileSyncAdapter(Context context, boolean autoInitialize) { public FileSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize); super(context, autoInitialize);
@ -73,7 +79,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
mCancellation = false; mCancellation = false;
mIsManualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); mIsManualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
mRightSync = true; mFailedResultsCounter = 0;
mLastFailedResult = null;
this.setAccount(account); this.setAccount(account);
this.setContentProvider(provider); this.setContentProvider(provider);
@ -81,7 +88,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
Log.d(TAG, "syncing owncloud account " + account.name); Log.d(TAG, "syncing owncloud account " + account.name);
sendStickyBroadcast(true, null); // message to signal the start to the UI sendStickyBroadcast(true, null, null); // message to signal the start of the synchronization to the UI
try { try {
updateOCVersion(); updateOCVersion();
@ -96,8 +103,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
} finally { } finally {
// it's important making this although very unexpected errors occur; that's the reason for the finally // it's important making this although very unexpected errors occur; that's the reason for the finally
mRightSync &= (syncResult.stats.numIoExceptions == 0 && syncResult.stats.numAuthExceptions == 0 && syncResult.stats.numParseExceptions == 0); if (mFailedResultsCounter > 0 && mIsManualSync) {
if (!mRightSync && mIsManualSync) {
/// don't let the system synchronization manager retries MANUAL synchronizations /// don't let the system synchronization manager retries MANUAL synchronizations
// (be careful: "MANUAL" currently includes the synchronization requested when a new account is created and when the user changes the current account) // (be careful: "MANUAL" currently includes the synchronization requested when a new account is created and when the user changes the current account)
syncResult.tooManyRetries = true; syncResult.tooManyRetries = true;
@ -105,7 +111,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
/// notify the user about the failure of MANUAL synchronization /// notify the user about the failure of MANUAL synchronization
notifyFailedSynchronization(); notifyFailedSynchronization();
} }
sendStickyBroadcast(false, null); // message to signal the end to the UI sendStickyBroadcast(false, null, mLastFailedResult); // message to signal the end to the UI
} }
} }
@ -169,6 +175,9 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
*/ */
private void fetchData(String remotePath, SyncResult syncResult, long parentId) { private void fetchData(String remotePath, SyncResult syncResult, long parentId) {
if (mFailedResultsCounter > MAX_FAILED_RESULTS && isFinisher(mLastFailedResult))
return;
// get client object to connect to the remote ownCloud server // get client object to connect to the remote ownCloud server
WebdavClient client = null; WebdavClient client = null;
try { try {
@ -191,7 +200,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
// synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess // synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess
sendStickyBroadcast(true, remotePath); sendStickyBroadcast(true, remotePath, null);
if (result.isSuccess()) { if (result.isSuccess()) {
// synchronize children folders // synchronize children folders
@ -208,14 +217,31 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
} else if (result.getException() instanceof IOException) { } else if (result.getException() instanceof IOException) {
syncResult.stats.numIoExceptions++; syncResult.stats.numIoExceptions++;
} else if (result.getException() != null) {
// TODO maybe something smarter with syncResult
mRightSync = false;
} }
mFailedResultsCounter++;
mLastFailedResult = result;
} }
} }
/**
* Checks if a failed result should terminate the synchronization process immediately, according to
* OUR OWN POLICY
*
* @param failedResult Remote operation result to check.
* @return 'True' if the result should immediately finish the synchronization
*/
private boolean isFinisher(RemoteOperationResult failedResult) {
if (failedResult != null) {
RemoteOperationResult.ResultCode code = failedResult.getCode();
return (code.equals(RemoteOperationResult.ResultCode.SSL_ERROR) ||
code.equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) ||
code.equals(RemoteOperationResult.ResultCode.BAD_OC_VERSION) ||
code.equals(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED));
}
return false;
}
/** /**
* Synchronize data of folders in the list of received files * Synchronize data of folders in the list of received files
* *
@ -235,21 +261,21 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
/** /**
* Sends a message to any app component interested in the progress of the synchronization. * Sends a message to any application component interested in the progress of the synchronization.
* *
* @param inProgress 'True' when the synchronization progress is not finished. * @param inProgress 'True' when the synchronization progress is not finished.
* @param dirRemotePath Remote path of a folder that was just synchronized (with or without success) * @param dirRemotePath Remote path of a folder that was just synchronized (with or without success)
*/ */
private void sendStickyBroadcast(boolean inProgress, String dirRemotePath/*, RemoteOperationResult result*/) { private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) {
Intent i = new Intent(FileSyncService.SYNC_MESSAGE); Intent i = new Intent(FileSyncService.SYNC_MESSAGE);
i.putExtra(FileSyncService.IN_PROGRESS, inProgress); i.putExtra(FileSyncService.IN_PROGRESS, inProgress);
i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name); i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);
if (dirRemotePath != null) { if (dirRemotePath != null) {
i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath); i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);
} }
/*if (result != null) { if (result != null) {
i.putExtra(FileSyncService.SYNC_RESULT, result); i.putExtra(FileSyncService.SYNC_RESULT, result);
}*/ }
getContext().sendStickyBroadcast(i); getContext().sendStickyBroadcast(i);
} }

View file

@ -71,7 +71,10 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader; import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.network.OwnCloudClientUtils; import com.owncloud.android.network.OwnCloudClientUtils;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.syncadapter.FileSyncService; import com.owncloud.android.syncadapter.FileSyncService;
import com.owncloud.android.ui.dialog.SslValidatorDialog;
import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
import com.owncloud.android.ui.fragment.FileDetailFragment; import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.OCFileListFragment; import com.owncloud.android.ui.fragment.OCFileListFragment;
@ -86,7 +89,7 @@ import eu.alefzero.webdav.WebdavClient;
*/ */
public class FileDisplayActivity extends SherlockFragmentActivity implements public class FileDisplayActivity extends SherlockFragmentActivity implements
OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener { OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener {
private ArrayAdapter<String> mDirectories; private ArrayAdapter<String> mDirectories;
private OCFile mCurrentDir = null; private OCFile mCurrentDir = null;
@ -99,6 +102,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
private FileDownloaderBinder mDownloaderBinder = null; private FileDownloaderBinder mDownloaderBinder = null;
private FileUploaderBinder mUploaderBinder = null; private FileUploaderBinder mUploaderBinder = null;
private ServiceConnection mDownloadConnection = null, mUploadConnection = null; private ServiceConnection mDownloadConnection = null, mUploadConnection = null;
private RemoteOperationResult mLastSslUntrustedServerResult = null;
private OCFileListFragment mFileList; private OCFileListFragment mFileList;
@ -109,6 +113,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
private static final int DIALOG_ABOUT_APP = 2; private static final int DIALOG_ABOUT_APP = 2;
public static final int DIALOG_SHORT_WAIT = 3; public static final int DIALOG_SHORT_WAIT = 3;
private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4; private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4;
private static final int DIALOG_SSL_VALIDATOR = 5;
private static final int DIALOG_CERT_NOT_SAVED = 6;
private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1; private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
private static final int ACTION_SELECT_MULTIPLE_FILES = 2; private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
@ -274,12 +281,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
break; break;
} }
case R.id.startSync: { case R.id.startSync: {
ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE); // cancel the current synchronizations of any ownCloud account startSynchronization();
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(
AccountUtils.getCurrentOwnCloudAccount(this),
AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
break; break;
} }
case R.id.action_upload: { case R.id.action_upload: {
@ -307,6 +309,16 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
return retval; return retval;
} }
private void startSynchronization() {
ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE); // cancel the current synchronizations of any ownCloud account
Bundle bundle = new Bundle();
bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(
AccountUtils.getCurrentOwnCloudAccount(this),
AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
}
@Override @Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) { public boolean onNavigationItemSelected(int itemPosition, long itemId) {
int i = itemPosition; int i = itemPosition;
@ -520,6 +532,15 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
Log.d(getClass().toString(), "onPause() end"); Log.d(getClass().toString(), "onPause() end");
} }
@Override
protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
if (id == DIALOG_SSL_VALIDATOR && mLastSslUntrustedServerResult != null) {
((SslValidatorDialog)dialog).updateResult(mLastSslUntrustedServerResult);
}
}
@Override @Override
protected Dialog onCreateDialog(int id) { protected Dialog onCreateDialog(int id) {
Dialog dialog = null; Dialog dialog = null;
@ -645,6 +666,23 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
dialog = builder.create(); dialog = builder.create();
break; break;
} }
case DIALOG_SSL_VALIDATOR: {
dialog = SslValidatorDialog.newInstance(this, mLastSslUntrustedServerResult, this);
break;
}
case DIALOG_CERT_NOT_SAVED: {
builder = new AlertDialog.Builder(this);
builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
builder.setCancelable(false);
builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
};
});
dialog = builder.create();
break;
}
default: default:
dialog = null; dialog = null;
} }
@ -772,6 +810,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
} }
private class SyncBroadcastReceiver extends BroadcastReceiver { private class SyncBroadcastReceiver extends BroadcastReceiver {
/** /**
* {@link BroadcastReceiver} to enable syncing feedback in UI * {@link BroadcastReceiver} to enable syncing feedback in UI
*/ */
@ -809,6 +848,14 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
setSupportProgressBarIndeterminateVisibility(inProgress); setSupportProgressBarIndeterminateVisibility(inProgress);
} }
RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncService.SYNC_RESULT);
if (synchResult != null) {
if (synchResult.getCode().equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
mLastSslUntrustedServerResult = synchResult;
showDialog(DIALOG_SSL_VALIDATOR);
}
}
} }
} }
@ -1009,4 +1056,16 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
} }
@Override
public void onSavedCertificate() {
startSynchronization();
}
@Override
public void onFailedSavingCertificate() {
showDialog(DIALOG_CERT_NOT_SAVED);
}
} }