Skip to content

Commit e6c1454

Browse files
committed
Persist conflicts in local database and show with an icon in the list of files
1 parent 5f41bb1 commit e6c1454

9 files changed

Lines changed: 130 additions & 60 deletions

File tree

2.58 KB
Loading

src/com/owncloud/android/datamodel/FileDataStorageManager.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ public boolean saveFile(OCFile file) {
204204
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
205205
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
206206
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
207-
207+
cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
208+
208209
boolean sameRemotePath = fileExists(file.getRemotePath());
209210
if (sameRemotePath || fileExists(file.getFileId())) { // for renamed files; no more delete and create
210211

@@ -313,6 +314,7 @@ public void saveFolder(
313314
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
314315
cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail());
315316
cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading());
317+
cv.put(ProviderTableMeta.FILE_IN_CONFLICT, file.isInConflict());
316318

317319
boolean existsByPath = fileExists(file.getRemotePath());
318320
if (existsByPath || fileExists(file.getFileId())) {
@@ -942,7 +944,9 @@ private OCFile createFileInstance(Cursor c) {
942944
c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false);
943945
file.setDownloading(c.getInt(
944946
c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false);
945-
947+
file.setInConflict(c.getInt(
948+
c.getColumnIndex(ProviderTableMeta.FILE_IN_CONFLICT)) == 1 ? true : false);
949+
946950
}
947951
return file;
948952
}
@@ -1310,6 +1314,10 @@ public void updateSharedFiles(Collection<OCFile> sharedFiles) {
13101314
ProviderTableMeta.FILE_IS_DOWNLOADING,
13111315
file.isDownloading() ? 1 : 0
13121316
);
1317+
cv.put(
1318+
ProviderTableMeta.FILE_IN_CONFLICT,
1319+
file.isInConflict() ? 1 : 0
1320+
);
13131321

13141322
boolean existsByPath = fileExists(file.getRemotePath());
13151323
if (existsByPath || fileExists(file.getFileId())) {
@@ -1578,4 +1586,27 @@ public void deleteFileInMediaScan(String path) {
15781586

15791587
}
15801588

1589+
public void saveConflict(long fileId, boolean inConflict) {
1590+
ContentValues cv = new ContentValues();
1591+
cv.put(ProviderTableMeta.FILE_IN_CONFLICT, inConflict);
1592+
if (getContentResolver() != null) {
1593+
getContentResolver().update(
1594+
ProviderTableMeta.CONTENT_URI_FILE,
1595+
cv,
1596+
ProviderTableMeta._ID + "=?",
1597+
new String[] { String.valueOf(fileId)}
1598+
);
1599+
} else {
1600+
try {
1601+
getContentProviderClient().update(
1602+
ProviderTableMeta.CONTENT_URI_FILE,
1603+
cv,
1604+
ProviderTableMeta._ID + "=?",
1605+
new String[]{String.valueOf(fileId)}
1606+
);
1607+
} catch (RemoteException e) {
1608+
Log_OC.e(TAG, "Failed saving conflict in database " + e.getMessage());
1609+
}
1610+
}
1611+
}
15811612
}

src/com/owncloud/android/datamodel/OCFile.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public OCFile[] newArray(int size) {
7474

7575
private boolean mIsDownloading;
7676

77+
private boolean mInConflict;
78+
7779

7880
/**
7981
* Create new {@link OCFile} with given path.
@@ -115,8 +117,9 @@ private OCFile(Parcel source) {
115117
mPublicLink = source.readString();
116118
mPermissions = source.readString();
117119
mRemoteId = source.readString();
118-
mNeedsUpdateThumbnail = source.readInt() == 0;
119-
mIsDownloading = source.readInt() == 0;
120+
mNeedsUpdateThumbnail = source.readInt() == 1;
121+
mIsDownloading = source.readInt() == 1;
122+
mInConflict = source.readInt() == 1;
120123

121124
}
122125

@@ -142,6 +145,7 @@ public void writeToParcel(Parcel dest, int flags) {
142145
dest.writeString(mRemoteId);
143146
dest.writeInt(mNeedsUpdateThumbnail ? 1 : 0);
144147
dest.writeInt(mIsDownloading ? 1 : 0);
148+
dest.writeInt(mInConflict ? 1 : 0);
145149
}
146150

147151
/**
@@ -357,6 +361,7 @@ private void resetData() {
357361
mRemoteId = null;
358362
mNeedsUpdateThumbnail = false;
359363
mIsDownloading = false;
364+
mInConflict = false;
360365
}
361366

362367
/**
@@ -597,9 +602,11 @@ public void setDownloading(boolean isDownloading) {
597602
this.mIsDownloading = isDownloading;
598603
}
599604

600-
public boolean isSynchronizing() {
601-
// TODO real implementation
602-
return false;
605+
public boolean isInConflict() {
606+
return mInConflict;
603607
}
604608

609+
public void setInConflict(boolean inConflict) {
610+
mInConflict = inConflict;
611+
}
605612
}

src/com/owncloud/android/db/ProviderMeta.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
public class ProviderMeta {
3232

3333
public static final String DB_NAME = "filelist";
34-
public static final int DB_VERSION = 10;
34+
public static final int DB_VERSION = 11;
3535

3636
private ProviderMeta() {
3737
}
@@ -72,6 +72,7 @@ static public class ProviderTableMeta implements BaseColumns {
7272
public static final String FILE_REMOTE_ID = "remote_id";
7373
public static final String FILE_UPDATE_THUMBNAIL = "update_thumbnail";
7474
public static final String FILE_IS_DOWNLOADING= "is_downloading";
75+
public static final String FILE_IN_CONFLICT = "in_conflict";
7576

7677
public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME
7778
+ " collate nocase asc";
@@ -94,7 +95,7 @@ static public class ProviderTableMeta implements BaseColumns {
9495

9596
public static final String OCSHARES_DEFAULT_SORT_ORDER = OCSHARES_FILE_SOURCE
9697
+ " collate nocase asc";
97-
98+
9899

99100
}
100101
}

src/com/owncloud/android/operations/RefreshFolderOperation.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -354,50 +354,55 @@ private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient cl
354354
}
355355

356356
// loop to update every child
357-
OCFile remoteFile = null, localFile = null;
357+
OCFile remoteFile = null, localFile = null, updatedFile = null;
358+
RemoteFile r;
358359
for (int i=1; i<folderAndFiles.size(); i++) {
359360
/// new OCFile instance with the data from the server
360-
remoteFile = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(i));
361-
remoteFile.setParentId(mLocalFolder.getFileId());
361+
r = (RemoteFile) folderAndFiles.get(i);
362+
remoteFile = FileStorageUtils.fillOCFile(r);
363+
364+
/// new OCFile instance to merge fresh data from server with local state
365+
updatedFile = FileStorageUtils.fillOCFile(r);
366+
updatedFile.setParentId(mLocalFolder.getFileId());
362367

363368
/// retrieve local data for the read file
364369
// localFile = mStorageManager.getFileByPath(remoteFile.getRemotePath());
365370
localFile = localFilesMap.remove(remoteFile.getRemotePath());
366371

367-
/// add to the remoteFile (the new one) data about LOCAL STATE (not existing in server)
368-
remoteFile.setLastSyncDateForProperties(mCurrentSyncTime);
372+
/// add to updatedFile data about LOCAL STATE (not existing in server)
373+
updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
369374
if (localFile != null) {
370-
// some properties of local state are kept unmodified
371-
remoteFile.setFileId(localFile.getFileId());
372-
remoteFile.setFavorite(localFile.isFavorite());
373-
remoteFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
374-
remoteFile.setModificationTimestampAtLastSyncForData(
375+
updatedFile.setFileId(localFile.getFileId());
376+
updatedFile.setFavorite(localFile.isFavorite());
377+
updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
378+
updatedFile.setModificationTimestampAtLastSyncForData(
375379
localFile.getModificationTimestampAtLastSyncForData()
376380
);
377-
remoteFile.setStoragePath(localFile.getStoragePath());
381+
updatedFile.setStoragePath(localFile.getStoragePath());
378382
// eTag will not be updated unless file CONTENTS are synchronized
379-
remoteFile.setEtag(localFile.getEtag());
380-
if (remoteFile.isFolder()) {
381-
remoteFile.setFileLength(localFile.getFileLength());
383+
updatedFile.setEtag(localFile.getEtag());
384+
if (updatedFile.isFolder()) {
385+
updatedFile.setFileLength(localFile.getFileLength());
382386
// TODO move operations about size of folders to FileContentProvider
383387
} else if (mRemoteFolderChanged && remoteFile.isImage() &&
384388
remoteFile.getModificationTimestamp() !=
385389
localFile.getModificationTimestamp()) {
386-
remoteFile.setNeedsUpdateThumbnail(true);
390+
updatedFile.setNeedsUpdateThumbnail(true);
387391
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
388392
}
389-
remoteFile.setPublicLink(localFile.getPublicLink());
390-
remoteFile.setShareByLink(localFile.isShareByLink());
393+
updatedFile.setPublicLink(localFile.getPublicLink());
394+
updatedFile.setShareByLink(localFile.isShareByLink());
395+
updatedFile.setInConflict(localFile.isInConflict());
391396
} else {
392397
// remote eTag will not be updated unless file CONTENTS are synchronized
393-
remoteFile.setEtag("");
398+
updatedFile.setEtag("");
394399
}
395400

396401
/// check and fix, if needed, local storage path
397-
FileStorageUtils.searchForLocalFileInDefaultPath(remoteFile, mAccount);
402+
FileStorageUtils.searchForLocalFileInDefaultPath(updatedFile, mAccount);
398403

399404
/// prepare content synchronization for kept-in-sync files
400-
if (remoteFile.isFavorite()) {
405+
if (updatedFile.isFavorite()) {
401406
SynchronizeFileOperation operation = new SynchronizeFileOperation( localFile,
402407
remoteFile,
403408
mAccount,
@@ -408,7 +413,7 @@ private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient cl
408413
mFilesToSyncContents.add(operation);
409414
}
410415

411-
updatedFiles.add(remoteFile);
416+
updatedFiles.add(updatedFile);
412417
}
413418

414419
// save updated contents in local database

src/com/owncloud/android/operations/SynchronizeFileOperation.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,16 +218,11 @@ protected RemoteOperationResult run(OwnCloudClient client) {
218218
mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()
219219
);
220220

221-
Log_OC.d(TAG, "TOKENs checked to SYNC " + mRemotePath );
222-
Log_OC.d(TAG, " server#modificationTimestamp " + mServerFile.getModificationTimestamp());
223-
Log_OC.d(TAG, " local#modificationTimestampAtLastSyncForData " + mServerFile.getModificationTimestampAtLastSyncForData());
224-
Log_OC.d(TAG, " local#modificationTimestamp " + mLocalFile.getLocalModificationTimestamp());
225-
Log_OC.d(TAG, " local#lastSyncDateForData " + mLocalFile.getLastSyncDateForData());
226-
227221
/// decide action to perform depending upon changes
228222
//if (!mLocalFile.getEtag().isEmpty() && localChanged && serverChanged) {
229223
if (localChanged && serverChanged) {
230224
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
225+
getStorageManager().saveConflict(mLocalFile.getFileId(), true);
231226

232227
} else if (localChanged) {
233228
if (mSyncFileContents && mAllowUploads) {
@@ -257,6 +252,7 @@ protected RemoteOperationResult run(OwnCloudClient client) {
257252
mServerFile.setLastSyncDateForData(mLocalFile.getLastSyncDateForData());
258253
mServerFile.setStoragePath(mLocalFile.getStoragePath());
259254
mServerFile.setParentId(mLocalFile.getParentId());
255+
mServerFile.setEtag(mLocalFile.getEtag());
260256
getStorageManager().saveFile(mServerFile);
261257

262258
}

src/com/owncloud/android/operations/SynchronizeFolderOperation.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -302,47 +302,52 @@ private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient cl
302302
}
303303

304304
// loop to synchronize every child
305-
OCFile remoteFile = null, localFile = null;
305+
OCFile remoteFile = null, localFile = null, updatedFile = null;
306+
RemoteFile r;
306307
for (int i=1; i<folderAndFiles.size(); i++) {
307308
/// new OCFile instance with the data from the server
308-
remoteFile = FileStorageUtils.fillOCFile((RemoteFile)folderAndFiles.get(i));
309-
remoteFile.setParentId(mLocalFolder.getFileId());
309+
r = (RemoteFile) folderAndFiles.get(i);
310+
remoteFile = FileStorageUtils.fillOCFile(r);
311+
312+
/// new OCFile instance to merge fresh data from server with local state
313+
updatedFile = FileStorageUtils.fillOCFile(r);
314+
updatedFile.setParentId(mLocalFolder.getFileId());
310315

311316
/// retrieve local data for the read file
312317
// localFile = mStorageManager.getFileByPath(remoteFile.getRemotePath());
313318
localFile = localFilesMap.remove(remoteFile.getRemotePath());
314319

315-
/// add to the remoteFile (the new one) data about LOCAL STATE (not existing in server)
316-
remoteFile.setLastSyncDateForProperties(mCurrentSyncTime);
320+
/// add to updatedFile data about LOCAL STATE (not existing in server)
321+
updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
317322
if (localFile != null) {
318-
// some properties of local state are kept unmodified
319-
remoteFile.setFileId(localFile.getFileId());
320-
remoteFile.setFavorite(localFile.isFavorite());
321-
remoteFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
322-
remoteFile.setModificationTimestampAtLastSyncForData(
323+
updatedFile.setFileId(localFile.getFileId());
324+
updatedFile.setFavorite(localFile.isFavorite());
325+
updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
326+
updatedFile.setModificationTimestampAtLastSyncForData(
323327
localFile.getModificationTimestampAtLastSyncForData()
324328
);
325-
remoteFile.setStoragePath(localFile.getStoragePath());
326-
// eTag will not be updated unless contents are synchronized
327-
remoteFile.setEtag(localFile.getEtag());
328-
if (remoteFile.isFolder()) {
329-
remoteFile.setFileLength(localFile.getFileLength());
329+
updatedFile.setStoragePath(localFile.getStoragePath());
330+
// eTag will not be updated unless file CONTENTS are synchronized
331+
updatedFile.setEtag(localFile.getEtag());
332+
if (updatedFile.isFolder()) {
333+
updatedFile.setFileLength(localFile.getFileLength());
330334
// TODO move operations about size of folders to FileContentProvider
331335
} else if (mRemoteFolderChanged && remoteFile.isImage() &&
332336
remoteFile.getModificationTimestamp() !=
333337
localFile.getModificationTimestamp()) {
334-
remoteFile.setNeedsUpdateThumbnail(true);
338+
updatedFile.setNeedsUpdateThumbnail(true);
335339
Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
336340
}
337-
remoteFile.setPublicLink(localFile.getPublicLink());
338-
remoteFile.setShareByLink(localFile.isShareByLink());
341+
updatedFile.setPublicLink(localFile.getPublicLink());
342+
updatedFile.setShareByLink(localFile.isShareByLink());
343+
updatedFile.setInConflict(localFile.isInConflict());
339344
} else {
340-
// remote eTag will not be updated unless contents are synchronized
341-
remoteFile.setEtag("");
345+
// remote eTag will not be updated unless file CONTENTS are synchronized
346+
updatedFile.setEtag("");
342347
}
343348

344349
/// check and fix, if needed, local storage path
345-
searchForLocalFileInDefaultPath(remoteFile);
350+
searchForLocalFileInDefaultPath(updatedFile);
346351

347352
/// classify file to sync/download contents later
348353
if (remoteFile.isFolder()) {
@@ -367,7 +372,7 @@ private void synchronizeData(ArrayList<Object> folderAndFiles, OwnCloudClient cl
367372

368373
}
369374

370-
updatedFiles.add(remoteFile);
375+
updatedFiles.add(updatedFile);
371376
}
372377

373378
// save updated contents in local database
@@ -399,7 +404,7 @@ private void prepareOpsFromLocalKnowledge() throws OperationCancelledException {
399404
/// this should result in direct upload of files that were locally modified
400405
SynchronizeFileOperation operation = new SynchronizeFileOperation(
401406
child,
402-
child, // cheating with the remote file to get an upadte to server; to refactor
407+
(child.isInConflict() ? null : child),
403408
mAccount,
404409
true,
405410
mContext

src/com/owncloud/android/providers/FileContentProvider.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ public class FileContentProvider extends ContentProvider {
107107
ProviderTableMeta.FILE_UPDATE_THUMBNAIL);
108108
mFileProjectionMap.put(ProviderTableMeta.FILE_IS_DOWNLOADING,
109109
ProviderTableMeta.FILE_IS_DOWNLOADING);
110+
mFileProjectionMap.put(ProviderTableMeta.FILE_IN_CONFLICT,
111+
ProviderTableMeta.FILE_IN_CONFLICT);
110112
}
111113

112114
private static final int SINGLE_FILE = 1;
@@ -634,7 +636,8 @@ public void onCreate(SQLiteDatabase db) {
634636
+ ProviderTableMeta.FILE_PERMISSIONS + " TEXT null,"
635637
+ ProviderTableMeta.FILE_REMOTE_ID + " TEXT null,"
636638
+ ProviderTableMeta.FILE_UPDATE_THUMBNAIL + " INTEGER," //boolean
637-
+ ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER);" //boolean
639+
+ ProviderTableMeta.FILE_IS_DOWNLOADING + " INTEGER," //boolean
640+
+ ProviderTableMeta.FILE_IN_CONFLICT + " INTEGER);" //boolean
638641
);
639642

640643
// Create table ocshares
@@ -834,6 +837,24 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
834837
if (!upgraded)
835838
Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
836839
", newVersion == " + newVersion);
840+
841+
if (oldVersion < 11 && newVersion >= 11) {
842+
Log_OC.i("SQL", "Entering in the #11 ADD in onUpgrade");
843+
db.beginTransaction();
844+
try {
845+
db .execSQL("ALTER TABLE " + ProviderTableMeta.FILE_TABLE_NAME +
846+
" ADD COLUMN " + ProviderTableMeta.FILE_IN_CONFLICT + " INTEGER " +
847+
" DEFAULT 0");
848+
upgraded = true;
849+
db.setTransactionSuccessful();
850+
} finally {
851+
db.endTransaction();
852+
}
853+
}
854+
if (!upgraded)
855+
Log_OC.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion +
856+
", newVersion == " + newVersion);
857+
837858
}
838859
}
839860

0 commit comments

Comments
 (0)