X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/23c9be24a22ac4cfa78510ae3e58e5f0044a57ad..10f99ceb9ca7a65b2d59f30a7ddfbfa7ffc60a7a:/src/com/owncloud/android/syncadapter/FileSyncAdapter.java?ds=inline diff --git a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java index 4b40ff49..349f1370 100644 --- a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java +++ b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java @@ -26,19 +26,22 @@ import java.util.Map; import org.apache.jackrabbit.webdav.DavException; -import com.owncloud.android.Log_OC; import com.owncloud.android.R; -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.RemoteOperationResult; +import com.owncloud.android.lib.common.accounts.AccountUtils.Constants; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UpdateOCVersionOperation; -import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity; +import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.Log_OC; + import android.accounts.Account; +import android.accounts.AccountManager; import android.accounts.AccountsException; import android.app.Notification; import android.app.NotificationManager; @@ -50,6 +53,7 @@ import android.content.Context; import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; +//import android.support.v4.content.LocalBroadcastManager; /** * Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing @@ -68,6 +72,16 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { private static final int MAX_FAILED_RESULTS = 3; + public static final String EVENT_FULL_SYNC_START = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_START"; + public static final String EVENT_FULL_SYNC_END = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_END"; + public static final String EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED"; + public static final String EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED"; + + public static final String EXTRA_ACCOUNT_NAME = FileSyncAdapter.class.getName() + ".EXTRA_ACCOUNT_NAME"; + public static final String EXTRA_FOLDER_PATH = FileSyncAdapter.class.getName() + ".EXTRA_FOLDER_PATH"; + public static final String EXTRA_RESULT = FileSyncAdapter.class.getName() + ".EXTRA_RESULT"; + + /** Time stamp for the current synchronization process, used to distinguish fresh data */ private long mCurrentSyncTime; @@ -94,10 +108,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { /** {@link SyncResult} instance to return to the system when the synchronization finish */ private SyncResult mSyncResult; + + /** 'True' means that the server supports the share API */ + private boolean mIsShareSupported; /** - * Creates an {@link FileSyncAdapter} + * Creates a {@link FileSyncAdapter} * * {@inheritDoc} */ @@ -107,11 +124,21 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { /** + * Creates a {@link FileSyncAdapter} + * + * {@inheritDoc} + */ + public FileSyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) { + super(context, autoInitialize, allowParallelSyncs); + } + + + /** * {@inheritDoc} */ @Override public synchronized void onPerformSync(Account account, Bundle extras, - String authority, ContentProviderClient provider, + String authority, ContentProviderClient providerClient, SyncResult syncResult) { mCancellation = false; @@ -126,8 +153,9 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { mSyncResult.delayUntil = 60*60*24; // avoid too many automatic synchronizations this.setAccount(account); - this.setContentProvider(provider); - this.setStorageManager(new FileDataStorageManager(account, provider)); + this.setContentProviderClient(providerClient); + this.setStorageManager(new FileDataStorageManager(account, providerClient)); + try { this.initClientForCurrentAccount(); } catch (IOException e) { @@ -143,13 +171,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { } Log_OC.d(TAG, "Synchronization of ownCloud account " + account.name + " starting"); - sendStickyBroadcast(true, null, null); // message to signal the start of the synchronization to the UI + sendLocalBroadcast(EVENT_FULL_SYNC_START, null, null); // message to signal the start of the synchronization to the UI try { updateOCVersion(); mCurrentSyncTime = System.currentTimeMillis(); if (!mCancellation) { - synchronizeFolder(getStorageManager().getFileByPath(OCFile.PATH_SEPARATOR), true); + synchronizeFolder(getStorageManager().getFileByPath(OCFile.ROOT_PATH)); } else { Log_OC.d(TAG, "Leaving synchronization before synchronizing the root folder because cancelation request"); @@ -173,7 +201,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { if (mForgottenLocalFiles.size() > 0) { notifyForgottenLocalFiles(); } - sendStickyBroadcast(false, null, mLastFailedResult); // message to signal the end to the UI + sendLocalBroadcast(EVENT_FULL_SYNC_END, null, mLastFailedResult); // message to signal the end to the UI } } @@ -204,6 +232,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { RemoteOperationResult result = update.execute(getClient()); if (!result.isSuccess()) { mLastFailedResult = result; + } else { + mIsShareSupported = update.getOCVersion().isSharedSupported(); } } @@ -218,9 +248,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * depth first strategy. * * @param folder Folder to synchronize. - * @param updateFolderProperties When 'true', updates also the properties of the of the target folder. */ - private void synchronizeFolder(OCFile folder, boolean updateFolderProperties) { + private void synchronizeFolder(OCFile folder) { if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult)) return; @@ -233,14 +262,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { DataStorageManager dataStorageManager, Account account, Context context ) { - } */ // folder synchronization SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( folder, mCurrentSyncTime, - updateFolderProperties, true, + mIsShareSupported, getStorageManager(), getAccount(), getContext() @@ -249,7 +277,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { // synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess - sendStickyBroadcast(true, folder.getRemotePath(), null); + sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED, folder.getRemotePath(), result); // check the result of synchronizing the folder if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) { @@ -261,19 +289,18 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { if (synchFolderOp.getForgottenLocalFiles().size() > 0) { mForgottenLocalFiles.putAll(synchFolderOp.getForgottenLocalFiles()); } - // synchronize children folders - List children = synchFolderOp.getChildren(); - fetchChildren(children); // beware of the 'hidden' recursion here! - - // update folder size again after recursive synchronization - getStorageManager().calculateFolderSize(folder.getFileId()); - sendStickyBroadcast(true, folder.getRemotePath(), null); // notify again + if (result.isSuccess()) { + // synchronize children folders + List children = synchFolderOp.getChildren(); + fetchChildren(folder, children, synchFolderOp.getRemoteFolderChanged()); // beware of the 'hidden' recursion here! + } } else { // 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()))) { + ( result.isIdPRedirection() && + getClient().getCredentials() == null )) { + //MainApp.getAuthTokenTypeSamlSessionCookie().equals(getClient().getAuthTokenType()))) { mSyncResult.stats.numAuthExceptions++; } else if (result.getException() instanceof DavException) { @@ -311,12 +338,21 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * * @param files Files to recursively synchronize. */ - private void fetchChildren(List files) { + private void fetchChildren(OCFile parent, List files, boolean parentEtagChanged) { int i; + OCFile newFile = null; + //String etag = null; + //boolean syncDown = false; for (i=0; i < files.size() && !mCancellation; i++) { - OCFile newFile = files.get(i); - if (newFile.isDirectory()) { - synchronizeFolder(newFile, false); + newFile = files.get(i); + if (newFile.isFolder()) { + /* + etag = newFile.getEtag(); + syncDown = (parentEtagChanged || etag == null || etag.length() == 0); + if(syncDown) { */ + synchronizeFolder(newFile); + sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED, parent.getRemotePath(), null); + //} } } @@ -327,20 +363,22 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { /** * 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 dirRemotePath Remote path of a folder that was just synchronized (with or without success) + * @param event Event in the process of synchronization to be notified. + * @param dirRemotePath Remote path of the folder target of the event occurred. + * @param result Result of an individual {@ SynchronizeFolderOperation}, if completed; may be null. */ - private void sendStickyBroadcast(boolean inProgress, String dirRemotePath, RemoteOperationResult result) { - Intent i = new Intent(FileSyncService.SYNC_MESSAGE); - i.putExtra(FileSyncService.IN_PROGRESS, inProgress); - i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name); + private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) { + Log_OC.d(TAG, "Send broadcast " + event); + Intent intent = new Intent(event); + intent.putExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME, getAccount().name); if (dirRemotePath != null) { - i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath); + intent.putExtra(FileSyncAdapter.EXTRA_FOLDER_PATH, dirRemotePath); } if (result != null) { - i.putExtra(FileSyncService.SYNC_RESULT, result); + intent.putExtra(FileSyncAdapter.EXTRA_RESULT, result); } - getContext().sendStickyBroadcast(i); + getContext().sendStickyBroadcast(intent); + //LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } @@ -349,13 +387,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * Notifies the user about a failed synchronization through the status notification bar */ private void notifyFailedSynchronization() { - Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis()); + Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; 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())) + getClient().getCredentials() == null ) + //MainApp.getAuthTokenTypeSamlSessionCookie().equals(getClient().getAuthTokenType())) ) ); // TODO put something smart in the contentIntent below for all the possible errors @@ -391,7 +429,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { */ private void notifyFailsInFavourites() { if (mFailedResultsCounter > 0) { - Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_fail_in_favourites_ticker), System.currentTimeMillis()); + Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_fail_in_favourites_ticker), System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; // TODO put something smart in the contentIntent below notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); @@ -402,7 +440,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_in_favourites_ticker, notification); } else { - Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_conflicts_in_favourites_ticker), System.currentTimeMillis()); + Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_conflicts_in_favourites_ticker), System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; // TODO put something smart in the contentIntent below notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); @@ -424,7 +462,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * We won't consider a synchronization as failed when foreign files can not be copied to the ownCloud local directory. */ private void notifyForgottenLocalFiles() { - Notification notification = new Notification(R.drawable.icon, getContext().getString(R.string.sync_foreign_files_forgotten_ticker), System.currentTimeMillis()); + Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_foreign_files_forgotten_ticker), System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; /// includes a pending intent in the notification showing a more detailed explanation