import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.UpdateOCVersionOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import com.owncloud.android.operations.UpdateOCVersionOperation;
import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity;
import android.accounts.Account;
import android.accounts.AccountsException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.accounts.Account;
import android.accounts.AccountsException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
- * SyncAdapter implementation for syncing sample SyncAdapter contacts to the
- * platform ContactOperations provider.
+ * Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing
+ * ownCloud files.
+ *
+ * Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}.
*
* @author Bartek Przybylski
* @author David A. Velasco
*/
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
*
* @author Bartek Przybylski
* @author David A. Velasco
*/
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
public FileSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
public FileSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
mForgottenLocalFiles = new HashMap<String, String>();
mSyncResult = syncResult;
mSyncResult.fullSyncRequested = false;
mForgottenLocalFiles = new HashMap<String, String>();
mSyncResult = syncResult;
mSyncResult.fullSyncRequested = false;
mSyncResult.tooManyRetries = true;
notifyFailedSynchronization();
return;
} catch (AccountsException e) {
mSyncResult.tooManyRetries = true;
notifyFailedSynchronization();
return;
} catch (AccountsException e) {
}
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
notifyFailsInFavourites();
}
if (mForgottenLocalFiles.size() > 0) {
notifyForgottenLocalFiles();
}
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
notifyFailsInFavourites();
}
if (mForgottenLocalFiles.size() > 0) {
notifyForgottenLocalFiles();
- * Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
- * fetched will be still saved in the database. See onPerformSync implementation.
+ * Sets the mCancellation flag to 'true'. THe synchronization will be stopped later,
+ * before a new folder is fetched. Data of the last folder synchronized will be still
+ * locally saved.
+ *
+ * See {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}
+ * and {@link #synchronizeFolder(String, long)}.
- * Synchronize the properties of files and folders contained in a remote folder given by remotePath.
+ * Synchronizes the list of files contained in a folder identified with its remote path.
+ *
+ * Fetches the list and properties of the files contained in the given folder, including their
+ * properties, and updates the local database with them.
+ *
+ * Enters in the child folders to synchronize their contents also, following a recursive
+ * depth first strategy.
- * @param remotePath Remote path to the folder to synchronize.
- * @param parentId Database Id of the folder to synchronize.
+ * @param folder Folder to synchronize.
+ * @param updateFolderProperties When 'true', updates also the properties of the of the target folder.
- // perform folder synchronization
- SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( remotePath,
+ /*
+ OCFile folder,
+ long currentSyncTime,
+ boolean updateFolderProperties,
+ boolean syncFullAccount,
+ DataStorageManager dataStorageManager,
+ Account account,
+ Context context ) {
+
+ }
+ */
+ // folder synchronization
+ SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( folder,
if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) {
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) {
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
List<OCFile> children = synchFolderOp.getChildren();
fetchChildren(children); // beware of the 'hidden' recursion here!
List<OCFile> children = synchFolderOp.getChildren();
fetchChildren(children); // beware of the 'hidden' recursion here!
- if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED) {
+ // in failures, the statistics for the global result are updated
+ if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED ||
+ ( result.isIdPRedirection() &&
+ AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(getClient().getAuthTokenType()))) {
*/
private void fetchChildren(List<OCFile> files) {
int i;
for (i=0; i < files.size() && !mCancellation; i++) {
OCFile newFile = files.get(i);
if (newFile.isDirectory()) {
*/
private void fetchChildren(List<OCFile> files) {
int i;
for (i=0; i < files.size() && !mCancellation; i++) {
OCFile newFile = files.get(i);
if (newFile.isDirectory()) {
- fetchData(newFile.getRemotePath(), newFile.getFileId());
-
- // Update folder size on DB
- FileDataStorageManager storageManager = new FileDataStorageManager(getAccount(), getContext().getContentResolver());
- storageManager.saveFolderSize(newFile.getFileId());
+ synchronizeFolder(newFile, false);
private void notifyFailedSynchronization() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
private void notifyFailedSynchronization() {
Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
- boolean needsToUpdateCredentials = (mLastFailedResult != null && mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED);
+ boolean needsToUpdateCredentials = (mLastFailedResult != null &&
+ ( mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED ||
+ // (mLastFailedResult.isTemporalRedirection() && mLastFailedResult.isIdPRedirection() &&
+ ( mLastFailedResult.isIdPRedirection() &&
+ AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(getClient().getAuthTokenType()))
+ )
+ );
// TODO put something smart in the contentIntent below for all the possible errors
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
if (needsToUpdateCredentials) {
// let the user update credentials with one click
Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class);
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount());
// TODO put something smart in the contentIntent below for all the possible errors
notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
if (needsToUpdateCredentials) {
// let the user update credentials with one click
Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class);
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount());
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.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_TOKEN);
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);