2 * ownCloud Android client application
4 * Copyright (C) 2012 Bartek Przybylski
5 * Copyright (C) 2015 ownCloud Inc.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 package com
.owncloud
.android
.datamodel
;
23 import android
.accounts
.Account
;
24 import android
.content
.ContentProviderClient
;
25 import android
.content
.ContentProviderOperation
;
26 import android
.content
.ContentProviderResult
;
27 import android
.content
.ContentResolver
;
28 import android
.content
.ContentUris
;
29 import android
.content
.ContentValues
;
30 import android
.content
.Intent
;
31 import android
.content
.OperationApplicationException
;
32 import android
.database
.Cursor
;
33 import android
.net
.Uri
;
34 import android
.os
.RemoteException
;
35 import android
.provider
.MediaStore
;
37 import com
.owncloud
.android
.MainApp
;
38 import com
.owncloud
.android
.db
.ProviderMeta
.ProviderTableMeta
;
39 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
;
40 import com
.owncloud
.android
.lib
.resources
.shares
.OCShare
;
41 import com
.owncloud
.android
.lib
.resources
.shares
.ShareType
;
42 import com
.owncloud
.android
.lib
.resources
.status
.CapabilityBooleanType
;
43 import com
.owncloud
.android
.lib
.resources
.status
.OCCapability
;
44 import com
.owncloud
.android
.utils
.FileStorageUtils
;
47 import java
.io
.FileInputStream
;
48 import java
.io
.FileOutputStream
;
49 import java
.io
.IOException
;
50 import java
.io
.InputStream
;
51 import java
.io
.OutputStream
;
52 import java
.util
.ArrayList
;
53 import java
.util
.Collection
;
54 import java
.util
.Collections
;
55 import java
.util
.HashSet
;
56 import java
.util
.Iterator
;
57 import java
.util
.List
;
59 import java
.util
.Vector
;
61 public class FileDataStorageManager
{
63 public static final int ROOT_PARENT_ID
= 0;
65 private ContentResolver mContentResolver
;
66 private ContentProviderClient mContentProviderClient
;
67 private Account mAccount
;
69 private static String TAG
= FileDataStorageManager
.class.getSimpleName();
72 public FileDataStorageManager(Account account
, ContentResolver cr
) {
73 mContentProviderClient
= null
;
74 mContentResolver
= cr
;
78 public FileDataStorageManager(Account account
, ContentProviderClient cp
) {
79 mContentProviderClient
= cp
;
80 mContentResolver
= null
;
85 public void setAccount(Account account
) {
89 public Account
getAccount() {
93 public ContentResolver
getContentResolver() {
94 return mContentResolver
;
97 public ContentProviderClient
getContentProviderClient() {
98 return mContentProviderClient
;
102 public OCFile
getFileByPath(String path
) {
103 Cursor c
= getCursorForValue(ProviderTableMeta
.FILE_PATH
, path
);
105 if (c
.moveToFirst()) {
106 file
= createFileInstance(c
);
109 if (file
== null
&& OCFile
.ROOT_PATH
.equals(path
)) {
110 return createRootDir(); // root should always exist
116 public OCFile
getFileById(long id
) {
117 Cursor c
= getCursorForValue(ProviderTableMeta
._ID
, String
.valueOf(id
));
119 if (c
.moveToFirst()) {
120 file
= createFileInstance(c
);
126 public OCFile
getFileByLocalPath(String path
) {
127 Cursor c
= getCursorForValue(ProviderTableMeta
.FILE_STORAGE_PATH
, path
);
129 if (c
.moveToFirst()) {
130 file
= createFileInstance(c
);
136 public boolean fileExists(long id
) {
137 return fileExists(ProviderTableMeta
._ID
, String
.valueOf(id
));
140 public boolean fileExists(String path
) {
141 return fileExists(ProviderTableMeta
.FILE_PATH
, path
);
145 public Vector
<OCFile
> getFolderContent(OCFile f
, boolean onlyOnDevice
) {
146 if (f
!= null
&& f
.isFolder() && f
.getFileId() != -1) {
147 return getFolderContent(f
.getFileId(), onlyOnDevice
);
150 return new Vector
<OCFile
>();
155 public Vector
<OCFile
> getFolderImages(OCFile folder
, boolean onlyOnDevice
) {
156 Vector
<OCFile
> ret
= new Vector
<OCFile
>();
157 if (folder
!= null
) {
158 // TODO better implementation, filtering in the access to database instead of here
159 Vector
<OCFile
> tmp
= getFolderContent(folder
, onlyOnDevice
);
160 OCFile current
= null
;
161 for (int i
=0; i
<tmp
.size(); i
++) {
162 current
= tmp
.get(i
);
163 if (current
.isImage()) {
171 public boolean saveFile(OCFile file
) {
172 boolean overriden
= false
;
173 ContentValues cv
= new ContentValues();
174 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, file
.getModificationTimestamp());
176 ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
,
177 file
.getModificationTimestampAtLastSyncForData()
179 cv
.put(ProviderTableMeta
.FILE_CREATION
, file
.getCreationTimestamp());
180 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, file
.getFileLength());
181 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, file
.getMimetype());
182 cv
.put(ProviderTableMeta
.FILE_NAME
, file
.getFileName());
183 cv
.put(ProviderTableMeta
.FILE_PARENT
, file
.getParentId());
184 cv
.put(ProviderTableMeta
.FILE_PATH
, file
.getRemotePath());
185 if (!file
.isFolder())
186 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
187 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
188 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, file
.getLastSyncDateForProperties());
189 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, file
.getLastSyncDateForData());
190 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, file
.isFavorite() ?
1 : 0);
191 cv
.put(ProviderTableMeta
.FILE_ETAG
, file
.getEtag());
192 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, file
.isSharedViaLink() ?
1 : 0);
193 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, file
.isSharedWithSharee() ?
1 : 0);
194 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, file
.getPublicLink());
195 cv
.put(ProviderTableMeta
.FILE_PERMISSIONS
, file
.getPermissions());
196 cv
.put(ProviderTableMeta
.FILE_REMOTE_ID
, file
.getRemoteId());
197 cv
.put(ProviderTableMeta
.FILE_UPDATE_THUMBNAIL
, file
.needsUpdateThumbnail());
198 cv
.put(ProviderTableMeta
.FILE_IS_DOWNLOADING
, file
.isDownloading());
199 cv
.put(ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
, file
.getEtagInConflict());
201 boolean sameRemotePath
= fileExists(file
.getRemotePath());
202 if (sameRemotePath
||
203 fileExists(file
.getFileId())) { // for renamed files; no more delete and create
206 if (sameRemotePath
) {
207 oldFile
= getFileByPath(file
.getRemotePath());
208 file
.setFileId(oldFile
.getFileId());
210 oldFile
= getFileById(file
.getFileId());
214 if (getContentResolver() != null
) {
215 getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
,
216 ProviderTableMeta
._ID
+ "=?",
217 new String
[]{String
.valueOf(file
.getFileId())});
220 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
,
221 cv
, ProviderTableMeta
._ID
+ "=?",
222 new String
[]{String
.valueOf(file
.getFileId())});
223 } catch (RemoteException e
) {
225 "Fail to insert insert file to database "
230 Uri result_uri
= null
;
231 if (getContentResolver() != null
) {
232 result_uri
= getContentResolver().insert(
233 ProviderTableMeta
.CONTENT_URI_FILE
, cv
);
236 result_uri
= getContentProviderClient().insert(
237 ProviderTableMeta
.CONTENT_URI_FILE
, cv
);
238 } catch (RemoteException e
) {
240 "Fail to insert insert file to database "
244 if (result_uri
!= null
) {
245 long new_id
= Long
.parseLong(result_uri
.getPathSegments()
247 file
.setFileId(new_id
);
256 * Inserts or updates the list of files contained in a given folder.
258 * CALLER IS THE RESPONSIBLE FOR GRANTING RIGHT UPDATE OF INFORMATION, NOT THIS METHOD.
259 * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED
262 * @param updatedFiles
263 * @param filesToRemove
265 public void saveFolder(
266 OCFile folder
, Collection
<OCFile
> updatedFiles
, Collection
<OCFile
> filesToRemove
269 Log_OC
.d(TAG
, "Saving folder " + folder
.getRemotePath() + " with " + updatedFiles
.size()
270 + " children and " + filesToRemove
.size() + " files to remove");
272 ArrayList
<ContentProviderOperation
> operations
=
273 new ArrayList
<ContentProviderOperation
>(updatedFiles
.size());
275 // prepare operations to insert or update files to save in the given folder
276 for (OCFile file
: updatedFiles
) {
277 ContentValues cv
= new ContentValues();
278 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, file
.getModificationTimestamp());
280 ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
,
281 file
.getModificationTimestampAtLastSyncForData()
283 cv
.put(ProviderTableMeta
.FILE_CREATION
, file
.getCreationTimestamp());
284 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, file
.getFileLength());
285 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, file
.getMimetype());
286 cv
.put(ProviderTableMeta
.FILE_NAME
, file
.getFileName());
287 //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
288 cv
.put(ProviderTableMeta
.FILE_PARENT
, folder
.getFileId());
289 cv
.put(ProviderTableMeta
.FILE_PATH
, file
.getRemotePath());
290 if (!file
.isFolder()) {
291 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
293 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
294 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, file
.getLastSyncDateForProperties());
295 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, file
.getLastSyncDateForData());
296 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, file
.isFavorite() ?
1 : 0);
297 cv
.put(ProviderTableMeta
.FILE_ETAG
, file
.getEtag());
298 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, file
.isSharedViaLink() ?
1 : 0);
299 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, file
.isSharedWithSharee() ?
1 : 0);
300 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, file
.getPublicLink());
301 cv
.put(ProviderTableMeta
.FILE_PERMISSIONS
, file
.getPermissions());
302 cv
.put(ProviderTableMeta
.FILE_REMOTE_ID
, file
.getRemoteId());
303 cv
.put(ProviderTableMeta
.FILE_UPDATE_THUMBNAIL
, file
.needsUpdateThumbnail());
304 cv
.put(ProviderTableMeta
.FILE_IS_DOWNLOADING
, file
.isDownloading());
305 cv
.put(ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
, file
.getEtagInConflict());
307 boolean existsByPath
= fileExists(file
.getRemotePath());
308 if (existsByPath
|| fileExists(file
.getFileId())) {
309 // updating an existing file
310 operations
.add(ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
312 withSelection(ProviderTableMeta
._ID
+ "=?",
313 new String
[]{String
.valueOf(file
.getFileId())})
318 operations
.add(ContentProviderOperation
.newInsert(ProviderTableMeta
.CONTENT_URI
).
319 withValues(cv
).build());
323 // prepare operations to remove files in the given folder
324 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?" + " AND " +
325 ProviderTableMeta
.FILE_PATH
+ "=?";
326 String
[] whereArgs
= null
;
327 for (OCFile file
: filesToRemove
) {
328 if (file
.getParentId() == folder
.getFileId()) {
329 whereArgs
= new String
[]{mAccount
.name
, file
.getRemotePath()};
330 if (file
.isFolder()) {
331 operations
.add(ContentProviderOperation
.newDelete(
332 ContentUris
.withAppendedId(
333 ProviderTableMeta
.CONTENT_URI_DIR
, file
.getFileId()
335 ).withSelection(where
, whereArgs
).build());
338 new File(FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
));
339 if (localFolder
.exists()) {
340 removeLocalFolder(localFolder
);
343 operations
.add(ContentProviderOperation
.newDelete(
344 ContentUris
.withAppendedId(
345 ProviderTableMeta
.CONTENT_URI_FILE
, file
.getFileId()
347 ).withSelection(where
, whereArgs
).build());
350 String path
= file
.getStoragePath();
351 new File(path
).delete();
352 triggerMediaScan(path
); // notify MediaScanner about removed file
358 // update metadata of folder
359 ContentValues cv
= new ContentValues();
360 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, folder
.getModificationTimestamp());
362 ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
,
363 folder
.getModificationTimestampAtLastSyncForData()
365 cv
.put(ProviderTableMeta
.FILE_CREATION
, folder
.getCreationTimestamp());
366 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, 0);
367 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, folder
.getMimetype());
368 cv
.put(ProviderTableMeta
.FILE_NAME
, folder
.getFileName());
369 cv
.put(ProviderTableMeta
.FILE_PARENT
, folder
.getParentId());
370 cv
.put(ProviderTableMeta
.FILE_PATH
, folder
.getRemotePath());
371 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
372 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, folder
.getLastSyncDateForProperties());
373 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
, folder
.getLastSyncDateForData());
374 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, folder
.isFavorite() ?
1 : 0);
375 cv
.put(ProviderTableMeta
.FILE_ETAG
, folder
.getEtag());
376 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, folder
.isSharedViaLink() ?
1 : 0);
377 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, folder
.isSharedWithSharee() ?
1 : 0);
378 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, folder
.getPublicLink());
379 cv
.put(ProviderTableMeta
.FILE_PERMISSIONS
, folder
.getPermissions());
380 cv
.put(ProviderTableMeta
.FILE_REMOTE_ID
, folder
.getRemoteId());
382 operations
.add(ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
384 withSelection(ProviderTableMeta
._ID
+ "=?",
385 new String
[]{String
.valueOf(folder
.getFileId())})
388 // apply operations in batch
389 ContentProviderResult
[] results
= null
;
390 Log_OC
.d(TAG
, "Sending " + operations
.size() + " operations to FileContentProvider");
392 if (getContentResolver() != null
) {
393 results
= getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
396 results
= getContentProviderClient().applyBatch(operations
);
399 } catch (OperationApplicationException e
) {
400 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
402 } catch (RemoteException e
) {
403 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
406 // update new id in file objects for insertions
407 if (results
!= null
) {
409 Iterator
<OCFile
> filesIt
= updatedFiles
.iterator();
411 for (int i
= 0; i
< results
.length
; i
++) {
412 if (filesIt
.hasNext()) {
413 file
= filesIt
.next();
417 if (results
[i
].uri
!= null
) {
418 newId
= Long
.parseLong(results
[i
].uri
.getPathSegments().get(1));
419 //updatedFiles.get(i).setFileId(newId);
421 file
.setFileId(newId
);
430 public boolean removeFile(OCFile file
, boolean removeDBData
, boolean removeLocalCopy
) {
431 boolean success
= true
;
433 if (file
.isFolder()) {
434 success
= removeFolder(file
, removeDBData
, removeLocalCopy
);
438 //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE,
439 // ""+file.getFileId());
440 Uri file_uri
= ContentUris
.withAppendedId(ProviderTableMeta
.CONTENT_URI_FILE
,
442 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?" + " AND " +
443 ProviderTableMeta
.FILE_PATH
+ "=?";
444 String
[] whereArgs
= new String
[]{mAccount
.name
, file
.getRemotePath()};
446 if (getContentProviderClient() != null
) {
448 deleted
= getContentProviderClient().delete(file_uri
, where
, whereArgs
);
449 } catch (RemoteException e
) {
453 deleted
= getContentResolver().delete(file_uri
, where
, whereArgs
);
455 success
&= (deleted
> 0);
457 String localPath
= file
.getStoragePath();
458 if (removeLocalCopy
&& file
.isDown() && localPath
!= null
&& success
) {
459 success
= new File(localPath
).delete();
461 deleteFileInMediaScan(localPath
);
463 if (!removeDBData
&& success
) {
464 // maybe unnecessary, but should be checked TODO remove if unnecessary
465 file
.setStoragePath(null
);
467 saveConflict(file
, null
);
476 public boolean removeFolder(OCFile folder
, boolean removeDBData
, boolean removeLocalContent
) {
477 boolean success
= true
;
478 if (folder
!= null
&& folder
.isFolder()) {
479 if (removeDBData
&& folder
.getFileId() != -1) {
480 success
= removeFolderInDb(folder
);
482 if (removeLocalContent
&& success
) {
483 success
= removeLocalFolder(folder
);
489 private boolean removeFolderInDb(OCFile folder
) {
490 Uri folder_uri
= Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, "" +
491 folder
.getFileId()); // URI for recursive deletion
492 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?" + " AND " +
493 ProviderTableMeta
.FILE_PATH
+ "=?";
494 String
[] whereArgs
= new String
[]{mAccount
.name
, folder
.getRemotePath()};
496 if (getContentProviderClient() != null
) {
498 deleted
= getContentProviderClient().delete(folder_uri
, where
, whereArgs
);
499 } catch (RemoteException e
) {
503 deleted
= getContentResolver().delete(folder_uri
, where
, whereArgs
);
508 private boolean removeLocalFolder(OCFile folder
) {
509 boolean success
= true
;
510 String localFolderPath
= FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, folder
);
511 File localFolder
= new File(localFolderPath
);
512 if (localFolder
.exists()) {
513 // stage 1: remove the local files already registered in the files database
514 Vector
<OCFile
> files
= getFolderContent(folder
.getFileId(), false
);
516 for (OCFile file
: files
) {
517 if (file
.isFolder()) {
518 success
&= removeLocalFolder(file
);
521 File localFile
= new File(file
.getStoragePath());
522 success
&= localFile
.delete();
524 // notify MediaScanner about removed file
525 deleteFileInMediaScan(file
.getStoragePath());
526 file
.setStoragePath(null
);
534 // stage 2: remove the folder itself and any local file inside out of sync;
535 // for instance, after clearing the app cache or reinstalling
536 success
&= removeLocalFolder(localFolder
);
541 private boolean removeLocalFolder(File localFolder
) {
542 boolean success
= true
;
543 File
[] localFiles
= localFolder
.listFiles();
544 if (localFiles
!= null
) {
545 for (File localFile
: localFiles
) {
546 if (localFile
.isDirectory()) {
547 success
&= removeLocalFolder(localFile
);
549 String path
= localFile
.getAbsolutePath();
550 success
&= localFile
.delete();
554 success
&= localFolder
.delete();
560 * Updates database and file system for a file or folder that was moved to a different location.
562 * TODO explore better (faster) implementations
563 * TODO throw exceptions up !
565 public void moveLocalFile(OCFile file
, String targetPath
, String targetParentPath
) {
567 if (file
!= null
&& file
.fileExists() && !OCFile
.ROOT_PATH
.equals(file
.getFileName())) {
569 OCFile targetParent
= getFileByPath(targetParentPath
);
570 if (targetParent
== null
) {
571 throw new IllegalStateException(
572 "Parent folder of the target path does not exist!!");
575 /// 1. get all the descendants of the moved element in a single QUERY
577 if (getContentProviderClient() != null
) {
579 c
= getContentProviderClient().query(
580 ProviderTableMeta
.CONTENT_URI
,
582 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
583 ProviderTableMeta
.FILE_PATH
+ " LIKE ? ",
586 file
.getRemotePath() + "%"
588 ProviderTableMeta
.FILE_PATH
+ " ASC "
590 } catch (RemoteException e
) {
591 Log_OC
.e(TAG
, e
.getMessage());
595 c
= getContentResolver().query(
596 ProviderTableMeta
.CONTENT_URI
,
598 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
599 ProviderTableMeta
.FILE_PATH
+ " LIKE ? ",
602 file
.getRemotePath() + "%"
604 ProviderTableMeta
.FILE_PATH
+ " ASC "
608 /// 2. prepare a batch of update operations to change all the descendants
609 ArrayList
<ContentProviderOperation
> operations
=
610 new ArrayList
<ContentProviderOperation
>(c
.getCount());
611 String defaultSavePath
= FileStorageUtils
.getSavePath(mAccount
.name
);
612 List
<String
> originalPathsToTriggerMediaScan
= new ArrayList
<String
>();
613 List
<String
> newPathsToTriggerMediaScan
= new ArrayList
<String
>();
614 if (c
.moveToFirst()) {
615 int lengthOfOldPath
= file
.getRemotePath().length();
616 int lengthOfOldStoragePath
= defaultSavePath
.length() + lengthOfOldPath
;
618 ContentValues cv
= new ContentValues(); // keep construction in the loop
619 OCFile child
= createFileInstance(c
);
621 ProviderTableMeta
.FILE_PATH
,
622 targetPath
+ child
.getRemotePath().substring(lengthOfOldPath
)
624 if (child
.getStoragePath() != null
&&
625 child
.getStoragePath().startsWith(defaultSavePath
)) {
626 // update link to downloaded content - but local move is not done here!
627 String targetLocalPath
= defaultSavePath
+ targetPath
+
628 child
.getStoragePath().substring(lengthOfOldStoragePath
);
630 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, targetLocalPath
);
632 originalPathsToTriggerMediaScan
.add(child
.getStoragePath());
633 newPathsToTriggerMediaScan
.add(targetLocalPath
);
636 if (child
.getRemotePath().equals(file
.getRemotePath())) {
638 ProviderTableMeta
.FILE_PARENT
,
639 targetParent
.getFileId()
643 ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
646 ProviderTableMeta
._ID
+ "=?",
647 new String
[]{String
.valueOf(child
.getFileId())}
651 } while (c
.moveToNext());
655 /// 3. apply updates in batch
657 if (getContentResolver() != null
) {
658 getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
661 getContentProviderClient().applyBatch(operations
);
664 } catch (Exception e
) {
665 Log_OC
.e(TAG
, "Fail to update " + file
.getFileId() + " and descendants in database",
669 /// 4. move in local file system
670 String originalLocalPath
= FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
);
671 String targetLocalPath
= defaultSavePath
+ targetPath
;
672 File localFile
= new File(originalLocalPath
);
673 boolean renamed
= false
;
674 if (localFile
.exists()) {
675 File targetFile
= new File(targetLocalPath
);
676 File targetFolder
= targetFile
.getParentFile();
677 if (!targetFolder
.exists()) {
678 targetFolder
.mkdirs();
680 renamed
= localFile
.renameTo(targetFile
);
684 Iterator
<String
> it
= originalPathsToTriggerMediaScan
.iterator();
685 while (it
.hasNext()) {
686 // Notify MediaScanner about removed file
687 deleteFileInMediaScan(it
.next());
689 it
= newPathsToTriggerMediaScan
.iterator();
690 while (it
.hasNext()) {
691 // Notify MediaScanner about new file/folder
692 triggerMediaScan(it
.next());
699 public void copyLocalFile(OCFile file
, String targetPath
) {
701 if (file
!= null
&& file
.fileExists() && !OCFile
.ROOT_PATH
.equals(file
.getFileName())) {
702 String localPath
= FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
);
703 File localFile
= new File(localPath
);
704 boolean copied
= false
;
705 String defaultSavePath
= FileStorageUtils
.getSavePath(mAccount
.name
);
706 if (localFile
.exists()) {
707 File targetFile
= new File(defaultSavePath
+ targetPath
);
708 File targetFolder
= targetFile
.getParentFile();
709 if (!targetFolder
.exists()) {
710 targetFolder
.mkdirs();
712 copied
= FileStorageUtils
.copyFile(localFile
, targetFile
);
714 Log_OC
.d(TAG
, "Local file COPIED : " + copied
);
718 public void migrateStoredFiles(String srcPath
, String dstPath
) throws Exception
{
720 if (getContentResolver() != null
) {
721 c
= getContentResolver().query(ProviderTableMeta
.CONTENT_URI_FILE
,
723 ProviderTableMeta
.FILE_STORAGE_PATH
+ " IS NOT NULL",
729 c
= getContentProviderClient().query(ProviderTableMeta
.CONTENT_URI_FILE
,
730 new String
[]{ProviderTableMeta
._ID
, ProviderTableMeta
.FILE_STORAGE_PATH
},
731 ProviderTableMeta
.FILE_STORAGE_PATH
+ " IS NOT NULL",
734 } catch (RemoteException e
) {
735 Log_OC
.e(TAG
, e
.getMessage());
740 ArrayList
<ContentProviderOperation
> operations
=
741 new ArrayList
<ContentProviderOperation
>(c
.getCount());
742 if (c
.moveToFirst()) {
744 ContentValues cv
= new ContentValues();
745 long fileId
= c
.getLong(c
.getColumnIndex(ProviderTableMeta
._ID
));
746 String oldFileStoragePath
= c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_STORAGE_PATH
));
748 if (oldFileStoragePath
.startsWith(srcPath
)) {
751 ProviderTableMeta
.FILE_STORAGE_PATH
,
752 oldFileStoragePath
.replaceFirst(srcPath
, dstPath
));
755 ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
758 ProviderTableMeta
._ID
+ "=?",
759 new String
[]{String
.valueOf(fileId
)}
764 } while (c
.moveToNext());
768 /// 3. apply updates in batch
770 if (getContentResolver() != null
) {
771 getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
774 getContentProviderClient().applyBatch(operations
);
777 } catch (Exception e
) {
783 private Vector
<OCFile
> getFolderContent(long parentId
, boolean onlyOnDevice
) {
785 Vector
<OCFile
> ret
= new Vector
<OCFile
>();
787 Uri req_uri
= Uri
.withAppendedPath(
788 ProviderTableMeta
.CONTENT_URI_DIR
,
789 String
.valueOf(parentId
));
792 if (getContentProviderClient() != null
) {
794 c
= getContentProviderClient().query(req_uri
, null
,
795 ProviderTableMeta
.FILE_PARENT
+ "=?",
796 new String
[]{String
.valueOf(parentId
)}, null
);
797 } catch (RemoteException e
) {
798 Log_OC
.e(TAG
, e
.getMessage());
802 c
= getContentResolver().query(req_uri
, null
,
803 ProviderTableMeta
.FILE_PARENT
+ "=?",
804 new String
[]{String
.valueOf(parentId
)}, null
);
807 if (c
.moveToFirst()) {
809 OCFile child
= createFileInstance(c
);
810 if (child
.isFolder() || !onlyOnDevice
|| onlyOnDevice
&& child
.isDown()){
813 } while (c
.moveToNext());
818 Collections
.sort(ret
);
824 private OCFile
createRootDir() {
825 OCFile file
= new OCFile(OCFile
.ROOT_PATH
);
826 file
.setMimetype("DIR");
827 file
.setParentId(FileDataStorageManager
.ROOT_PARENT_ID
);
832 private boolean fileExists(String cmp_key
, String value
) {
834 if (getContentResolver() != null
) {
835 c
= getContentResolver()
836 .query(ProviderTableMeta
.CONTENT_URI
,
839 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
841 new String
[]{value
, mAccount
.name
}, null
);
844 c
= getContentProviderClient().query(
845 ProviderTableMeta
.CONTENT_URI
,
848 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?",
849 new String
[]{value
, mAccount
.name
}, null
);
850 } catch (RemoteException e
) {
852 "Couldn't determine file existance, assuming non existance: "
857 boolean retval
= c
.moveToFirst();
862 private Cursor
getCursorForValue(String key
, String value
) {
864 if (getContentResolver() != null
) {
865 c
= getContentResolver()
866 .query(ProviderTableMeta
.CONTENT_URI
,
869 + ProviderTableMeta
.FILE_ACCOUNT_OWNER
871 new String
[]{value
, mAccount
.name
}, null
);
874 c
= getContentProviderClient().query(
875 ProviderTableMeta
.CONTENT_URI
,
877 key
+ "=? AND " + ProviderTableMeta
.FILE_ACCOUNT_OWNER
878 + "=?", new String
[]{value
, mAccount
.name
},
880 } catch (RemoteException e
) {
881 Log_OC
.e(TAG
, "Could not get file details: " + e
.getMessage());
889 private OCFile
createFileInstance(Cursor c
) {
892 file
= new OCFile(c
.getString(c
893 .getColumnIndex(ProviderTableMeta
.FILE_PATH
)));
894 file
.setFileId(c
.getLong(c
.getColumnIndex(ProviderTableMeta
._ID
)));
895 file
.setParentId(c
.getLong(c
896 .getColumnIndex(ProviderTableMeta
.FILE_PARENT
)));
897 file
.setMimetype(c
.getString(c
898 .getColumnIndex(ProviderTableMeta
.FILE_CONTENT_TYPE
)));
899 if (!file
.isFolder()) {
900 file
.setStoragePath(c
.getString(c
901 .getColumnIndex(ProviderTableMeta
.FILE_STORAGE_PATH
)));
902 if (file
.getStoragePath() == null
) {
903 // try to find existing file and bind it with current account;
904 // with the current update of SynchronizeFolderOperation, this won't be
905 // necessary anymore after a full synchronization of the account
906 File f
= new File(FileStorageUtils
.getDefaultSavePathFor(mAccount
.name
, file
));
908 file
.setStoragePath(f
.getAbsolutePath());
909 file
.setLastSyncDateForData(f
.lastModified());
913 file
.setFileLength(c
.getLong(c
914 .getColumnIndex(ProviderTableMeta
.FILE_CONTENT_LENGTH
)));
915 file
.setCreationTimestamp(c
.getLong(c
916 .getColumnIndex(ProviderTableMeta
.FILE_CREATION
)));
917 file
.setModificationTimestamp(c
.getLong(c
918 .getColumnIndex(ProviderTableMeta
.FILE_MODIFIED
)));
919 file
.setModificationTimestampAtLastSyncForData(c
.getLong(c
920 .getColumnIndex(ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
)));
921 file
.setLastSyncDateForProperties(c
.getLong(c
922 .getColumnIndex(ProviderTableMeta
.FILE_LAST_SYNC_DATE
)));
923 file
.setLastSyncDateForData(c
.getLong(c
.
924 getColumnIndex(ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
)));
925 file
.setFavorite(c
.getInt(
926 c
.getColumnIndex(ProviderTableMeta
.FILE_KEEP_IN_SYNC
)) == 1 ? true
: false
);
927 file
.setEtag(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_ETAG
)));
928 file
.setShareViaLink(c
.getInt(
929 c
.getColumnIndex(ProviderTableMeta
.FILE_SHARED_VIA_LINK
)) == 1 ? true
: false
);
930 file
.setShareWithSharee(c
.getInt(
931 c
.getColumnIndex(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
)) == 1 ? true
: false
);
932 file
.setPublicLink(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_PUBLIC_LINK
)));
933 file
.setPermissions(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_PERMISSIONS
)));
934 file
.setRemoteId(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_REMOTE_ID
)));
935 file
.setNeedsUpdateThumbnail(c
.getInt(
936 c
.getColumnIndex(ProviderTableMeta
.FILE_UPDATE_THUMBNAIL
)) == 1 ? true
: false
);
937 file
.setDownloading(c
.getInt(
938 c
.getColumnIndex(ProviderTableMeta
.FILE_IS_DOWNLOADING
)) == 1 ? true
: false
);
939 file
.setEtagInConflict(c
.getString(c
.getColumnIndex(ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
)));
945 // Methods for Shares
946 public boolean saveShare(OCShare share
) {
947 boolean overriden
= false
;
948 ContentValues cv
= new ContentValues();
949 cv
.put(ProviderTableMeta
.OCSHARES_FILE_SOURCE
, share
.getFileSource());
950 cv
.put(ProviderTableMeta
.OCSHARES_ITEM_SOURCE
, share
.getItemSource());
951 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_TYPE
, share
.getShareType().getValue());
952 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_WITH
, share
.getShareWith());
953 cv
.put(ProviderTableMeta
.OCSHARES_PATH
, share
.getPath());
954 cv
.put(ProviderTableMeta
.OCSHARES_PERMISSIONS
, share
.getPermissions());
955 cv
.put(ProviderTableMeta
.OCSHARES_SHARED_DATE
, share
.getSharedDate());
956 cv
.put(ProviderTableMeta
.OCSHARES_EXPIRATION_DATE
, share
.getExpirationDate());
957 cv
.put(ProviderTableMeta
.OCSHARES_TOKEN
, share
.getToken());
959 ProviderTableMeta
.OCSHARES_SHARE_WITH_DISPLAY_NAME
,
960 share
.getSharedWithDisplayName()
962 cv
.put(ProviderTableMeta
.OCSHARES_IS_DIRECTORY
, share
.isFolder() ?
1 : 0);
963 cv
.put(ProviderTableMeta
.OCSHARES_USER_ID
, share
.getUserId());
964 cv
.put(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
, share
.getRemoteId());
965 cv
.put(ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
, mAccount
.name
);
967 if (shareExists(share
.getRemoteId())) {// for renamed files; no more delete and create
969 if (getContentResolver() != null
) {
970 getContentResolver().update(ProviderTableMeta
.CONTENT_URI_SHARE
, cv
,
971 ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
+ "=?",
972 new String
[]{String
.valueOf(share
.getRemoteId())});
975 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI_SHARE
,
976 cv
, ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
+ "=?",
977 new String
[]{String
.valueOf(share
.getRemoteId())});
978 } catch (RemoteException e
) {
980 "Fail to insert insert file to database "
985 Uri result_uri
= null
;
986 if (getContentResolver() != null
) {
987 result_uri
= getContentResolver().insert(
988 ProviderTableMeta
.CONTENT_URI_SHARE
, cv
);
991 result_uri
= getContentProviderClient().insert(
992 ProviderTableMeta
.CONTENT_URI_SHARE
, cv
);
993 } catch (RemoteException e
) {
995 "Fail to insert insert file to database "
999 if (result_uri
!= null
) {
1000 long new_id
= Long
.parseLong(result_uri
.getPathSegments()
1002 share
.setId(new_id
);
1011 * Get first share bound to a file with a known path and given {@link ShareType}.
1013 * @param path Path of the file.
1014 * @param type Type of the share to get
1015 * @param shareWith Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK}
1016 * @return First {@OCShare} instance found in DB bound to the file in 'path'
1018 public OCShare
getFirstShareByPathAndType(String path
, ShareType type
, String shareWith
) {
1020 if (shareWith
== null
) {
1024 String selection
= ProviderTableMeta
.OCSHARES_PATH
+ "=? AND "
1025 + ProviderTableMeta
.OCSHARES_SHARE_TYPE
+ "=? AND "
1026 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?" ;
1027 if (!ShareType
.PUBLIC_LINK
.equals(type
)) {
1028 selection
+= " AND " + ProviderTableMeta
.OCSHARES_SHARE_WITH
+ "=?";
1031 String
[] selectionArgs
;
1032 if (ShareType
.PUBLIC_LINK
.equals(type
)) {
1033 selectionArgs
= new String
[]{
1035 Integer
.toString(type
.getValue()),
1039 selectionArgs
= new String
[]{
1041 Integer
.toString(type
.getValue()),
1047 if (getContentResolver() != null
) {
1048 c
= getContentResolver().query(
1049 ProviderTableMeta
.CONTENT_URI_SHARE
,
1051 selection
, selectionArgs
,
1055 c
= getContentProviderClient().query(
1056 ProviderTableMeta
.CONTENT_URI_SHARE
,
1058 selection
, selectionArgs
,
1061 } catch (RemoteException e
) {
1062 Log_OC
.e(TAG
, "Could not get file details: " + e
.getMessage());
1066 OCShare share
= null
;
1067 if (c
.moveToFirst()) {
1068 share
= createShareInstance(c
);
1074 private OCShare
createShareInstance(Cursor c
) {
1075 OCShare share
= null
;
1077 share
= new OCShare(c
.getString(c
1078 .getColumnIndex(ProviderTableMeta
.OCSHARES_PATH
)));
1079 share
.setId(c
.getLong(c
.getColumnIndex(ProviderTableMeta
._ID
)));
1080 share
.setFileSource(c
.getLong(c
1081 .getColumnIndex(ProviderTableMeta
.OCSHARES_ITEM_SOURCE
)));
1082 share
.setShareType(ShareType
.fromValue(c
.getInt(c
1083 .getColumnIndex(ProviderTableMeta
.OCSHARES_SHARE_TYPE
))));
1084 share
.setShareWith(c
.getString(c
1085 .getColumnIndex(ProviderTableMeta
.OCSHARES_SHARE_WITH
)));
1086 share
.setPermissions(c
.getInt(c
1087 .getColumnIndex(ProviderTableMeta
.OCSHARES_PERMISSIONS
)));
1088 share
.setSharedDate(c
.getLong(c
1089 .getColumnIndex(ProviderTableMeta
.OCSHARES_SHARED_DATE
)));
1090 share
.setExpirationDate(c
.getLong(c
1091 .getColumnIndex(ProviderTableMeta
.OCSHARES_EXPIRATION_DATE
)));
1092 share
.setToken(c
.getString(c
1093 .getColumnIndex(ProviderTableMeta
.OCSHARES_TOKEN
)));
1094 share
.setSharedWithDisplayName(c
.getString(c
1095 .getColumnIndex(ProviderTableMeta
.OCSHARES_SHARE_WITH_DISPLAY_NAME
)));
1096 share
.setIsFolder(c
.getInt(
1097 c
.getColumnIndex(ProviderTableMeta
.OCSHARES_IS_DIRECTORY
)) == 1);
1098 share
.setUserId(c
.getLong(c
.getColumnIndex(ProviderTableMeta
.OCSHARES_USER_ID
)));
1099 share
.setIdRemoteShared(c
.getLong(
1100 c
.getColumnIndex(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
)));
1105 private boolean shareExists(String cmp_key
, String value
) {
1107 if (getContentResolver() != null
) {
1108 c
= getContentResolver()
1109 .query(ProviderTableMeta
.CONTENT_URI_SHARE
,
1112 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
1114 new String
[]{value
, mAccount
.name
}, null
);
1117 c
= getContentProviderClient().query(
1118 ProviderTableMeta
.CONTENT_URI_SHARE
,
1121 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?",
1122 new String
[]{value
, mAccount
.name
}, null
);
1123 } catch (RemoteException e
) {
1125 "Couldn't determine file existance, assuming non existance: "
1130 boolean retval
= c
.moveToFirst();
1135 private boolean shareExists(long remoteId
) {
1136 return shareExists(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
, String
.valueOf(remoteId
));
1139 private void resetShareFlagsInAllFiles() {
1140 ContentValues cv
= new ContentValues();
1141 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, false
);
1142 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, false
);
1143 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, "");
1144 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?";
1145 String
[] whereArgs
= new String
[]{mAccount
.name
};
1147 if (getContentResolver() != null
) {
1148 getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
, whereArgs
);
1152 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
,
1154 } catch (RemoteException e
) {
1155 Log_OC
.e(TAG
, "Exception in resetShareFlagsInAllFiles" + e
.getMessage());
1160 private void resetShareFlagsInFolder(OCFile folder
) {
1161 ContentValues cv
= new ContentValues();
1162 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, false
);
1163 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, false
);
1164 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, "");
1165 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
1166 ProviderTableMeta
.FILE_PARENT
+ "=?";
1167 String
[] whereArgs
= new String
[] { mAccount
.name
, String
.valueOf(folder
.getFileId()) };
1169 if (getContentResolver() != null
) {
1170 getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
, whereArgs
);
1174 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
,
1176 } catch (RemoteException e
) {
1177 Log_OC
.e(TAG
, "Exception in resetShareFlagsInFolder " + e
.getMessage());
1182 private void resetShareFlagInAFile(String filePath
){
1183 ContentValues cv
= new ContentValues();
1184 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, false
);
1185 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, false
);
1186 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, "");
1187 String where
= ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
1188 ProviderTableMeta
.FILE_PATH
+ "=?";
1189 String
[] whereArgs
= new String
[] { mAccount
.name
, filePath
};
1191 if (getContentResolver() != null
) {
1192 getContentResolver().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
, whereArgs
);
1196 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI
, cv
, where
,
1198 } catch (RemoteException e
) {
1199 Log_OC
.e(TAG
, "Exception in resetShareFlagsInFolder " + e
.getMessage());
1204 private void cleanShares() {
1205 String where
= ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?";
1206 String
[] whereArgs
= new String
[]{mAccount
.name
};
1208 if (getContentResolver() != null
) {
1209 getContentResolver().delete(ProviderTableMeta
.CONTENT_URI_SHARE
, where
, whereArgs
);
1213 getContentProviderClient().delete(ProviderTableMeta
.CONTENT_URI_SHARE
, where
,
1215 } catch (RemoteException e
) {
1216 Log_OC
.e(TAG
, "Exception in cleanShares" + e
.getMessage());
1221 public void saveShares(Collection
<OCShare
> shares
) {
1223 if (shares
!= null
) {
1224 ArrayList
<ContentProviderOperation
> operations
=
1225 new ArrayList
<ContentProviderOperation
>(shares
.size());
1227 // prepare operations to insert or update files to save in the given folder
1228 for (OCShare share
: shares
) {
1229 ContentValues cv
= new ContentValues();
1230 cv
.put(ProviderTableMeta
.OCSHARES_FILE_SOURCE
, share
.getFileSource());
1231 cv
.put(ProviderTableMeta
.OCSHARES_ITEM_SOURCE
, share
.getItemSource());
1232 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_TYPE
, share
.getShareType().getValue());
1233 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_WITH
, share
.getShareWith());
1234 cv
.put(ProviderTableMeta
.OCSHARES_PATH
, share
.getPath());
1235 cv
.put(ProviderTableMeta
.OCSHARES_PERMISSIONS
, share
.getPermissions());
1236 cv
.put(ProviderTableMeta
.OCSHARES_SHARED_DATE
, share
.getSharedDate());
1237 cv
.put(ProviderTableMeta
.OCSHARES_EXPIRATION_DATE
, share
.getExpirationDate());
1238 cv
.put(ProviderTableMeta
.OCSHARES_TOKEN
, share
.getToken());
1240 ProviderTableMeta
.OCSHARES_SHARE_WITH_DISPLAY_NAME
,
1241 share
.getSharedWithDisplayName()
1243 cv
.put(ProviderTableMeta
.OCSHARES_IS_DIRECTORY
, share
.isFolder() ?
1 : 0);
1244 cv
.put(ProviderTableMeta
.OCSHARES_USER_ID
, share
.getUserId());
1245 cv
.put(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
, share
.getRemoteId());
1246 cv
.put(ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
, mAccount
.name
);
1248 if (shareExists(share
.getRemoteId())) {
1249 // updating an existing file
1251 ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI_SHARE
).
1253 withSelection(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
+ "=?",
1254 new String
[]{String
.valueOf(share
.getRemoteId())})
1257 // adding a new file
1259 ContentProviderOperation
.newInsert(ProviderTableMeta
.CONTENT_URI_SHARE
).
1266 // apply operations in batch
1267 if (operations
.size() > 0) {
1268 @SuppressWarnings("unused")
1269 ContentProviderResult
[] results
= null
;
1270 Log_OC
.d(TAG
, "Sending " + operations
.size() +
1271 " operations to FileContentProvider");
1273 if (getContentResolver() != null
) {
1274 results
= getContentResolver().applyBatch(MainApp
.getAuthority(),
1277 results
= getContentProviderClient().applyBatch(operations
);
1280 } catch (OperationApplicationException e
) {
1281 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1283 } catch (RemoteException e
) {
1284 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1291 public void updateSharedFiles(Collection
<OCFile
> sharedFiles
) {
1292 resetShareFlagsInAllFiles();
1294 if (sharedFiles
!= null
) {
1295 ArrayList
<ContentProviderOperation
> operations
=
1296 new ArrayList
<ContentProviderOperation
>(sharedFiles
.size());
1298 // prepare operations to insert or update files to save in the given folder
1299 for (OCFile file
: sharedFiles
) {
1300 ContentValues cv
= new ContentValues();
1301 cv
.put(ProviderTableMeta
.FILE_MODIFIED
, file
.getModificationTimestamp());
1303 ProviderTableMeta
.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA
,
1304 file
.getModificationTimestampAtLastSyncForData()
1306 cv
.put(ProviderTableMeta
.FILE_CREATION
, file
.getCreationTimestamp());
1307 cv
.put(ProviderTableMeta
.FILE_CONTENT_LENGTH
, file
.getFileLength());
1308 cv
.put(ProviderTableMeta
.FILE_CONTENT_TYPE
, file
.getMimetype());
1309 cv
.put(ProviderTableMeta
.FILE_NAME
, file
.getFileName());
1310 cv
.put(ProviderTableMeta
.FILE_PARENT
, file
.getParentId());
1311 cv
.put(ProviderTableMeta
.FILE_PATH
, file
.getRemotePath());
1312 if (!file
.isFolder()) {
1313 cv
.put(ProviderTableMeta
.FILE_STORAGE_PATH
, file
.getStoragePath());
1315 cv
.put(ProviderTableMeta
.FILE_ACCOUNT_OWNER
, mAccount
.name
);
1316 cv
.put(ProviderTableMeta
.FILE_LAST_SYNC_DATE
, file
.getLastSyncDateForProperties());
1318 ProviderTableMeta
.FILE_LAST_SYNC_DATE_FOR_DATA
,
1319 file
.getLastSyncDateForData()
1321 cv
.put(ProviderTableMeta
.FILE_KEEP_IN_SYNC
, file
.isFavorite() ?
1 : 0);
1322 cv
.put(ProviderTableMeta
.FILE_ETAG
, file
.getEtag());
1323 cv
.put(ProviderTableMeta
.FILE_SHARED_VIA_LINK
, file
.isSharedViaLink() ?
1 : 0);
1324 cv
.put(ProviderTableMeta
.FILE_SHARED_WITH_SHAREE
, file
.isSharedWithSharee() ?
1 : 0);
1325 cv
.put(ProviderTableMeta
.FILE_PUBLIC_LINK
, file
.getPublicLink());
1326 cv
.put(ProviderTableMeta
.FILE_PERMISSIONS
, file
.getPermissions());
1327 cv
.put(ProviderTableMeta
.FILE_REMOTE_ID
, file
.getRemoteId());
1329 ProviderTableMeta
.FILE_UPDATE_THUMBNAIL
,
1330 file
.needsUpdateThumbnail() ?
1 : 0
1333 ProviderTableMeta
.FILE_IS_DOWNLOADING
,
1334 file
.isDownloading() ?
1 : 0
1336 cv
.put(ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
, file
.getEtagInConflict());
1338 boolean existsByPath
= fileExists(file
.getRemotePath());
1339 if (existsByPath
|| fileExists(file
.getFileId())) {
1340 // updating an existing file
1342 ContentProviderOperation
.newUpdate(ProviderTableMeta
.CONTENT_URI
).
1344 withSelection(ProviderTableMeta
._ID
+ "=?",
1345 new String
[]{String
.valueOf(file
.getFileId())})
1349 // adding a new file
1351 ContentProviderOperation
.newInsert(ProviderTableMeta
.CONTENT_URI
).
1358 // apply operations in batch
1359 if (operations
.size() > 0) {
1360 @SuppressWarnings("unused")
1361 ContentProviderResult
[] results
= null
;
1362 Log_OC
.d(TAG
, "Sending " + operations
.size() +
1363 " operations to FileContentProvider");
1365 if (getContentResolver() != null
) {
1366 results
= getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
1368 results
= getContentProviderClient().applyBatch(operations
);
1371 } catch (OperationApplicationException e
) {
1372 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1374 } catch (RemoteException e
) {
1375 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1382 public void removeShare(OCShare share
) {
1383 Uri share_uri
= ProviderTableMeta
.CONTENT_URI_SHARE
;
1384 String where
= ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?" + " AND " +
1385 ProviderTableMeta
._ID
+ "=?";
1386 String
[] whereArgs
= new String
[]{mAccount
.name
, Long
.toString(share
.getId())};
1387 if (getContentProviderClient() != null
) {
1389 getContentProviderClient().delete(share_uri
, where
, whereArgs
);
1390 } catch (RemoteException e
) {
1391 e
.printStackTrace();
1394 getContentResolver().delete(share_uri
, where
, whereArgs
);
1398 public void saveSharesDB(ArrayList
<OCShare
> shares
) {
1399 ArrayList
<ContentProviderOperation
> operations
= new ArrayList
<ContentProviderOperation
>();
1401 // Reset flags & Remove shares for this files
1402 String filePath
= "";
1403 for (OCShare share
: shares
) {
1404 if (filePath
!= share
.getPath()){
1405 filePath
= share
.getPath();
1406 resetShareFlagInAFile(filePath
);
1407 operations
= prepareRemoveSharesInFile(filePath
, operations
);
1411 // Add operations to insert shares
1412 operations
= prepareInsertShares(shares
, operations
);
1414 // apply operations in batch
1415 if (operations
.size() > 0) {
1416 Log_OC
.d(TAG
, "Sending " + operations
.size() + " operations to FileContentProvider");
1418 if (getContentResolver() != null
) {
1419 getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
1422 getContentProviderClient().applyBatch(operations
);
1425 } catch (OperationApplicationException e
) {
1426 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1428 } catch (RemoteException e
) {
1429 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1433 // // TODO: review if it is needed
1434 // // Update shared files
1435 // ArrayList<OCFile> sharedFiles = new ArrayList<OCFile>();
1437 // for (OCShare share : shares) {
1439 // String path = share.getPath();
1440 // if (share.isFolder()) {
1441 // path = path + FileUtils.PATH_SEPARATOR;
1444 // // Update OCFile with data from share: ShareByLink, publicLink and
1445 // OCFile file = getFileByPath(path);
1446 // if (file != null) {
1447 // if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
1448 // file.setShareViaLink(true);
1449 // sharedFiles.add(file);
1455 // updateSharedFiles(sharedFiles);
1458 public void removeSharesForFile(String remotePath
) {
1459 resetShareFlagInAFile(remotePath
);
1460 ArrayList
<ContentProviderOperation
> operations
= new ArrayList
<ContentProviderOperation
>();
1461 operations
= prepareRemoveSharesInFile(remotePath
, operations
);
1462 // apply operations in batch
1463 if (operations
.size() > 0) {
1464 Log_OC
.d(TAG
, "Sending " + operations
.size() + " operations to FileContentProvider");
1466 if (getContentResolver() != null
) {
1467 getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
1470 getContentProviderClient().applyBatch(operations
);
1473 } catch (OperationApplicationException e
) {
1474 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1476 } catch (RemoteException e
) {
1477 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1483 public void saveSharesInFolder(ArrayList
<OCShare
> shares
, OCFile folder
) {
1484 resetShareFlagsInFolder(folder
);
1485 ArrayList
<ContentProviderOperation
> operations
= new ArrayList
<ContentProviderOperation
>();
1486 operations
= prepareRemoveSharesInFolder(folder
, operations
);
1488 if (shares
!= null
) {
1489 // prepare operations to insert or update files to save in the given folder
1490 operations
= prepareInsertShares(shares
, operations
);
1493 // apply operations in batch
1494 if (operations
.size() > 0) {
1495 Log_OC
.d(TAG
, "Sending " + operations
.size() + " operations to FileContentProvider");
1497 if (getContentResolver() != null
) {
1498 getContentResolver().applyBatch(MainApp
.getAuthority(), operations
);
1501 getContentProviderClient().applyBatch(operations
);
1504 } catch (OperationApplicationException e
) {
1505 Log_OC
.e(TAG
, "Exception in batch of operations " + e
.getMessage());
1507 } catch (RemoteException e
) {
1515 * Prepare operations to insert or update files to save in the given folder
1516 * @param shares List of shares to insert
1517 * @param operations List of operations
1520 private ArrayList
<ContentProviderOperation
> prepareInsertShares(
1521 ArrayList
<OCShare
> shares
, ArrayList
<ContentProviderOperation
> operations
) {
1523 if (shares
!= null
) {
1524 // prepare operations to insert or update files to save in the given folder
1525 for (OCShare share
: shares
) {
1526 ContentValues cv
= new ContentValues();
1527 cv
.put(ProviderTableMeta
.OCSHARES_FILE_SOURCE
, share
.getFileSource());
1528 cv
.put(ProviderTableMeta
.OCSHARES_ITEM_SOURCE
, share
.getItemSource());
1529 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_TYPE
, share
.getShareType().getValue());
1530 cv
.put(ProviderTableMeta
.OCSHARES_SHARE_WITH
, share
.getShareWith());
1531 cv
.put(ProviderTableMeta
.OCSHARES_PATH
, share
.getPath());
1532 cv
.put(ProviderTableMeta
.OCSHARES_PERMISSIONS
, share
.getPermissions());
1533 cv
.put(ProviderTableMeta
.OCSHARES_SHARED_DATE
, share
.getSharedDate());
1534 cv
.put(ProviderTableMeta
.OCSHARES_EXPIRATION_DATE
, share
.getExpirationDate());
1535 cv
.put(ProviderTableMeta
.OCSHARES_TOKEN
, share
.getToken());
1537 ProviderTableMeta
.OCSHARES_SHARE_WITH_DISPLAY_NAME
,
1538 share
.getSharedWithDisplayName()
1540 cv
.put(ProviderTableMeta
.OCSHARES_IS_DIRECTORY
, share
.isFolder() ?
1 : 0);
1541 cv
.put(ProviderTableMeta
.OCSHARES_USER_ID
, share
.getUserId());
1542 cv
.put(ProviderTableMeta
.OCSHARES_ID_REMOTE_SHARED
, share
.getRemoteId());
1543 cv
.put(ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
, mAccount
.name
);
1545 // adding a new share resource
1547 ContentProviderOperation
.newInsert(ProviderTableMeta
.CONTENT_URI_SHARE
).
1556 private ArrayList
<ContentProviderOperation
> prepareRemoveSharesInFolder(
1557 OCFile folder
, ArrayList
<ContentProviderOperation
> preparedOperations
) {
1558 if (folder
!= null
) {
1559 String where
= ProviderTableMeta
.OCSHARES_PATH
+ "=?" + " AND "
1560 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?";
1561 String
[] whereArgs
= new String
[]{ "", mAccount
.name
};
1563 Vector
<OCFile
> files
= getFolderContent(folder
, false
);
1565 for (OCFile file
: files
) {
1566 whereArgs
[0] = file
.getRemotePath();
1567 preparedOperations
.add(
1568 ContentProviderOperation
.newDelete(ProviderTableMeta
.CONTENT_URI_SHARE
).
1569 withSelection(where
, whereArgs
).
1574 return preparedOperations
;
1578 private ArrayList
<ContentProviderOperation
> prepareRemoveSharesInFile(
1579 String filePath
, ArrayList
<ContentProviderOperation
> preparedOperations
) {
1581 String where
= ProviderTableMeta
.OCSHARES_PATH
+ "=?" + " AND "
1582 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?";
1583 String
[] whereArgs
= new String
[]{filePath
, mAccount
.name
};
1585 preparedOperations
.add(
1586 ContentProviderOperation
.newDelete(ProviderTableMeta
.CONTENT_URI_SHARE
).
1587 withSelection(where
, whereArgs
).
1591 return preparedOperations
;
1595 public ArrayList
<OCShare
> getSharesWithForAFile(String filePath
, String accountName
){
1597 String where
= ProviderTableMeta
.OCSHARES_PATH
+ "=?" + " AND "
1598 + ProviderTableMeta
.OCSHARES_ACCOUNT_OWNER
+ "=?"+ "AND"
1599 + " (" + ProviderTableMeta
.OCSHARES_SHARE_TYPE
+ "=? OR "
1600 + ProviderTableMeta
.OCSHARES_SHARE_TYPE
+ "=? ) ";
1601 String
[] whereArgs
= new String
[]{ filePath
, accountName
,
1602 Integer
.toString(ShareType
.USER
.getValue()),
1603 Integer
.toString(ShareType
.GROUP
.getValue()) };
1606 if (getContentResolver() != null
) {
1607 c
= getContentResolver().query(
1608 ProviderTableMeta
.CONTENT_URI_SHARE
,
1609 null
, where
, whereArgs
, null
);
1612 c
= getContentProviderClient().query(
1613 ProviderTableMeta
.CONTENT_URI_SHARE
,
1614 null
, where
, whereArgs
, null
);
1616 } catch (RemoteException e
) {
1617 Log_OC
.e(TAG
, "Could not get list of shares with: " + e
.getMessage());
1621 ArrayList
<OCShare
> shares
= new ArrayList
<OCShare
>();
1622 OCShare share
= null
;
1623 if (c
.moveToFirst()) {
1625 share
= createShareInstance(c
);
1628 } while (c
.moveToNext());
1635 public static void triggerMediaScan(String path
) {
1637 Intent intent
= new Intent(Intent
.ACTION_MEDIA_SCANNER_SCAN_FILE
);
1638 intent
.setData(Uri
.fromFile(new File(path
)));
1639 MainApp
.getAppContext().sendBroadcast(intent
);
1643 public void deleteFileInMediaScan(String path
) {
1645 String mimetypeString
= FileStorageUtils
.getMimeTypeFromName(path
);
1646 ContentResolver contentResolver
= getContentResolver();
1648 if (contentResolver
!= null
) {
1649 if (mimetypeString
.startsWith("image/")) {
1651 contentResolver
.delete(MediaStore
.Images
.Media
.EXTERNAL_CONTENT_URI
,
1652 MediaStore
.Images
.Media
.DATA
+ "=?", new String
[]{path
});
1653 } else if (mimetypeString
.startsWith("audio/")) {
1655 contentResolver
.delete(MediaStore
.Audio
.Media
.EXTERNAL_CONTENT_URI
,
1656 MediaStore
.Audio
.Media
.DATA
+ "=?", new String
[]{path
});
1657 } else if (mimetypeString
.startsWith("video/")) {
1659 contentResolver
.delete(MediaStore
.Video
.Media
.EXTERNAL_CONTENT_URI
,
1660 MediaStore
.Video
.Media
.DATA
+ "=?", new String
[]{path
});
1663 ContentProviderClient contentProviderClient
= getContentProviderClient();
1665 if (mimetypeString
.startsWith("image/")) {
1667 contentProviderClient
.delete(MediaStore
.Images
.Media
.EXTERNAL_CONTENT_URI
,
1668 MediaStore
.Images
.Media
.DATA
+ "=?", new String
[]{path
});
1669 } else if (mimetypeString
.startsWith("audio/")) {
1671 contentProviderClient
.delete(MediaStore
.Audio
.Media
.EXTERNAL_CONTENT_URI
,
1672 MediaStore
.Audio
.Media
.DATA
+ "=?", new String
[]{path
});
1673 } else if (mimetypeString
.startsWith("video/")) {
1675 contentProviderClient
.delete(MediaStore
.Video
.Media
.EXTERNAL_CONTENT_URI
,
1676 MediaStore
.Video
.Media
.DATA
+ "=?", new String
[]{path
});
1678 } catch (RemoteException e
) {
1679 Log_OC
.e(TAG
, "Exception deleting media file in MediaStore " + e
.getMessage());
1685 public void saveConflict(OCFile file
, String etagInConflict
) {
1686 if (!file
.isDown()) {
1687 etagInConflict
= null
;
1689 ContentValues cv
= new ContentValues();
1690 cv
.put(ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
, etagInConflict
);
1692 if (getContentResolver() != null
) {
1693 updated
= getContentResolver().update(
1694 ProviderTableMeta
.CONTENT_URI_FILE
,
1696 ProviderTableMeta
._ID
+ "=?",
1697 new String
[] { String
.valueOf(file
.getFileId())}
1701 updated
= getContentProviderClient().update(
1702 ProviderTableMeta
.CONTENT_URI_FILE
,
1704 ProviderTableMeta
._ID
+ "=?",
1705 new String
[]{String
.valueOf(file
.getFileId())}
1707 } catch (RemoteException e
) {
1708 Log_OC
.e(TAG
, "Failed saving conflict in database " + e
.getMessage());
1712 Log_OC
.d(TAG
, "Number of files updated with CONFLICT: " + updated
);
1715 if (etagInConflict
!= null
) {
1716 /// set conflict in all ancestor folders
1718 long parentId
= file
.getParentId();
1719 Set
<String
> ancestorIds
= new HashSet
<String
>();
1720 while (parentId
!= FileDataStorageManager
.ROOT_PARENT_ID
) {
1721 ancestorIds
.add(Long
.toString(parentId
));
1722 parentId
= getFileById(parentId
).getParentId();
1725 if (ancestorIds
.size() > 0) {
1726 StringBuffer whereBuffer
= new StringBuffer();
1727 whereBuffer
.append(ProviderTableMeta
._ID
).append(" IN (");
1728 for (int i
= 0; i
< ancestorIds
.size() - 1; i
++) {
1729 whereBuffer
.append("?,");
1731 whereBuffer
.append("?");
1732 whereBuffer
.append(")");
1734 if (getContentResolver() != null
) {
1735 updated
= getContentResolver().update(
1736 ProviderTableMeta
.CONTENT_URI_FILE
,
1738 whereBuffer
.toString(),
1739 ancestorIds
.toArray(new String
[]{})
1743 updated
= getContentProviderClient().update(
1744 ProviderTableMeta
.CONTENT_URI_FILE
,
1746 whereBuffer
.toString(),
1747 ancestorIds
.toArray(new String
[]{})
1749 } catch (RemoteException e
) {
1750 Log_OC
.e(TAG
, "Failed saving conflict in database " + e
.getMessage());
1753 } // else file is ROOT folder, no parent to set in conflict
1756 /// update conflict in ancestor folders
1757 // (not directly unset; maybe there are more conflicts below them)
1758 String parentPath
= file
.getRemotePath();
1759 if (parentPath
.endsWith(OCFile
.PATH_SEPARATOR
)) {
1760 parentPath
= parentPath
.substring(0, parentPath
.length() - 1);
1762 parentPath
= parentPath
.substring(0, parentPath
.lastIndexOf(OCFile
.PATH_SEPARATOR
) + 1);
1764 Log_OC
.d(TAG
, "checking parents to remove conflict; STARTING with " + parentPath
);
1765 while (parentPath
.length() > 0) {
1768 ProviderTableMeta
.FILE_ETAG_IN_CONFLICT
+ " IS NOT NULL AND " +
1769 ProviderTableMeta
.FILE_CONTENT_TYPE
+ " != 'DIR' AND " +
1770 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ " = ? AND " +
1771 ProviderTableMeta
.FILE_PATH
+ " LIKE ?";
1772 Cursor descendentsInConflict
= getContentResolver().query(
1773 ProviderTableMeta
.CONTENT_URI_FILE
,
1774 new String
[]{ProviderTableMeta
._ID
},
1776 new String
[]{mAccount
.name
, parentPath
+ "%"},
1779 if (descendentsInConflict
== null
|| descendentsInConflict
.getCount() == 0) {
1780 Log_OC
.d(TAG
, "NO MORE conflicts in " + parentPath
);
1781 if (getContentResolver() != null
) {
1782 updated
= getContentResolver().update(
1783 ProviderTableMeta
.CONTENT_URI_FILE
,
1785 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
1786 ProviderTableMeta
.FILE_PATH
+ "=?",
1787 new String
[]{mAccount
.name
, parentPath
}
1791 updated
= getContentProviderClient().update(
1792 ProviderTableMeta
.CONTENT_URI_FILE
,
1794 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=? AND " +
1795 ProviderTableMeta
.FILE_PATH
+ "=?"
1796 , new String
[]{mAccount
.name
, parentPath
}
1798 } catch (RemoteException e
) {
1799 Log_OC
.e(TAG
, "Failed saving conflict in database " + e
.getMessage());
1804 Log_OC
.d(TAG
, "STILL " + descendentsInConflict
.getCount() + " in " + parentPath
);
1807 if (descendentsInConflict
!= null
) {
1808 descendentsInConflict
.close();
1811 parentPath
= parentPath
.substring(0, parentPath
.length() - 1); // trim last /
1812 parentPath
= parentPath
.substring(0, parentPath
.lastIndexOf(OCFile
.PATH_SEPARATOR
) + 1);
1813 Log_OC
.d(TAG
, "checking parents to remove conflict; NEXT " + parentPath
);
1820 public OCCapability
saveCapabilities(OCCapability capability
){
1822 // Prepare capabilities data
1823 ContentValues cv
= new ContentValues();
1824 cv
.put(ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
, mAccount
.name
);
1825 cv
.put(ProviderTableMeta
.CAPABILITIES_VERSION_MAYOR
, capability
.getVersionMayor());
1826 cv
.put(ProviderTableMeta
.CAPABILITIES_VERSION_MINOR
, capability
.getVersionMinor());
1827 cv
.put(ProviderTableMeta
.CAPABILITIES_VERSION_MICRO
, capability
.getVersionMicro());
1828 cv
.put(ProviderTableMeta
.CAPABILITIES_VERSION_STRING
, capability
.getVersionString());
1829 cv
.put(ProviderTableMeta
.CAPABILITIES_VERSION_EDITION
, capability
.getVersionEdition());
1830 cv
.put(ProviderTableMeta
.CAPABILITIES_CORE_POLLINTERVAL
, capability
.getCorePollinterval());
1831 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_API_ENABLED
, capability
.getFilesSharingApiEnabled().getValue());
1832 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_ENABLED
,
1833 capability
.getFilesSharingPublicEnabled().getValue());
1834 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED
,
1835 capability
.getFilesSharingPublicPasswordEnforced().getValue());
1836 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED
,
1837 capability
.getFilesSharingPublicExpireDateEnabled().getValue());
1838 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS
,
1839 capability
.getFilesSharingPublicExpireDateDays());
1840 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED
,
1841 capability
.getFilesSharingPublicExpireDateEnforced().getValue());
1842 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL
,
1843 capability
.getFilesSharingPublicSendMail().getValue());
1844 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_UPLOAD
,
1845 capability
.getFilesSharingPublicUpload().getValue());
1846 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_USER_SEND_MAIL
,
1847 capability
.getFilesSharingUserSendMail().getValue());
1848 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_RESHARING
, capability
.getFilesSharingResharing().getValue());
1849 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_FEDERATION_OUTGOING
,
1850 capability
.getFilesSharingFederationOutgoing().getValue());
1851 cv
.put(ProviderTableMeta
.CAPABILITIES_SHARING_FEDERATION_INCOMING
,
1852 capability
.getFilesSharingFederationIncoming().getValue());
1853 cv
.put(ProviderTableMeta
.CAPABILITIES_FILES_BIGFILECHUNKING
, capability
.getFilesBigFileChuncking().getValue());
1854 cv
.put(ProviderTableMeta
.CAPABILITIES_FILES_UNDELETE
, capability
.getFilesUndelete().getValue());
1855 cv
.put(ProviderTableMeta
.CAPABILITIES_FILES_VERSIONING
, capability
.getFilesVersioning().getValue());
1857 if (capabilityExists(mAccount
.name
)) {
1858 if (getContentResolver() != null
) {
1859 getContentResolver().update(ProviderTableMeta
.CONTENT_URI_CAPABILITIES
, cv
,
1860 ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
+ "=?",
1861 new String
[]{mAccount
.name
});
1864 getContentProviderClient().update(ProviderTableMeta
.CONTENT_URI_CAPABILITIES
,
1865 cv
, ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
+ "=?",
1866 new String
[]{mAccount
.name
});
1867 } catch (RemoteException e
) {
1869 "Fail to insert insert file to database "
1874 Uri result_uri
= null
;
1875 if (getContentResolver() != null
) {
1876 result_uri
= getContentResolver().insert(
1877 ProviderTableMeta
.CONTENT_URI_CAPABILITIES
, cv
);
1880 result_uri
= getContentProviderClient().insert(
1881 ProviderTableMeta
.CONTENT_URI_CAPABILITIES
, cv
);
1882 } catch (RemoteException e
) {
1884 "Fail to insert insert capability to database "
1888 if (result_uri
!= null
) {
1889 long new_id
= Long
.parseLong(result_uri
.getPathSegments()
1891 capability
.setId(new_id
);
1892 capability
.setAccountName(mAccount
.name
);
1899 private boolean capabilityExists(String accountName
) {
1900 Cursor c
= getCapabilityCursorForAccount(accountName
);
1901 boolean exists
= false
;
1903 exists
= c
.moveToFirst();
1909 private Cursor
getCapabilityCursorForAccount(String accountName
){
1911 if (getContentResolver() != null
) {
1912 c
= getContentResolver()
1913 .query(ProviderTableMeta
.CONTENT_URI_CAPABILITIES
,
1915 ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
+ "=? ",
1916 new String
[]{accountName
}, null
);
1919 c
= getContentProviderClient().query(
1920 ProviderTableMeta
.CONTENT_URI_CAPABILITIES
,
1922 ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
+ "=? ",
1923 new String
[]{accountName
}, null
);
1924 } catch (RemoteException e
) {
1926 "Couldn't determine capability existance, assuming non existance: "
1934 public OCCapability
getCapability(String accountName
){
1935 OCCapability capability
= null
;
1936 Cursor c
= getCapabilityCursorForAccount(accountName
);
1938 if (c
.moveToFirst()) {
1939 capability
= createCapabilityInstance(c
);
1941 capability
= new OCCapability(); // return default with all UNKNOWN
1947 private OCCapability
createCapabilityInstance(Cursor c
) {
1948 OCCapability capability
= null
;
1950 capability
= new OCCapability();
1951 capability
.setId(c
.getLong(c
.getColumnIndex(ProviderTableMeta
._ID
)));
1952 capability
.setAccountName(c
.getString(c
1953 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_ACCOUNT_NAME
)));
1954 capability
.setVersionMayor(c
.getInt(c
1955 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_VERSION_MAYOR
)));
1956 capability
.setVersionMinor(c
.getInt(c
1957 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_VERSION_MINOR
)));
1958 capability
.setVersionMicro(c
.getInt(c
1959 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_VERSION_MICRO
)));
1960 capability
.setVersionString(c
.getString(c
1961 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_VERSION_STRING
)));
1962 capability
.setVersionEdition(c
.getString(c
1963 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_VERSION_EDITION
)));
1964 capability
.setCorePollinterval(c
.getInt(c
1965 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_CORE_POLLINTERVAL
)));
1966 capability
.setFilesSharingApiEnabled(CapabilityBooleanType
.fromValue(c
.getInt(c
1967 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_API_ENABLED
))));
1968 capability
.setFilesSharingPublicEnabled(CapabilityBooleanType
.fromValue(c
.getInt(c
1969 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_ENABLED
))));
1970 capability
.setFilesSharingPublicPasswordEnforced(CapabilityBooleanType
.fromValue(c
.getInt(c
1971 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_PASSWORD_ENFORCED
))));
1972 capability
.setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType
.fromValue(c
.getInt(c
1973 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENABLED
))));
1974 capability
.setFilesSharingPublicExpireDateDays(c
.getInt(c
1975 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_DAYS
)));
1976 capability
.setFilesSharingPublicExpireDateEnforced(CapabilityBooleanType
.fromValue(c
.getInt(c
1977 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_EXPIRE_DATE_ENFORCED
))));
1978 capability
.setFilesSharingPublicSendMail(CapabilityBooleanType
.fromValue(c
.getInt(c
1979 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_SEND_MAIL
))));
1980 capability
.setFilesSharingPublicUpload(CapabilityBooleanType
.fromValue(c
.getInt(c
1981 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_PUBLIC_UPLOAD
))));
1982 capability
.setFilesSharingUserSendMail(CapabilityBooleanType
.fromValue(c
.getInt(c
1983 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_USER_SEND_MAIL
))));
1984 capability
.setFilesSharingResharing(CapabilityBooleanType
.fromValue(c
.getInt(c
1985 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_RESHARING
))));
1986 capability
.setFilesSharingFederationOutgoing(CapabilityBooleanType
.fromValue(c
.getInt(c
1987 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_FEDERATION_OUTGOING
))));
1988 capability
.setFilesSharingFederationIncoming(CapabilityBooleanType
.fromValue(c
.getInt(c
1989 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_SHARING_FEDERATION_INCOMING
))));
1990 capability
.setFilesBigFileChuncking(CapabilityBooleanType
.fromValue(c
.getInt(c
1991 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_FILES_BIGFILECHUNKING
))));
1992 capability
.setFilesUndelete(CapabilityBooleanType
.fromValue(c
.getInt(c
1993 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_FILES_UNDELETE
))));
1994 capability
.setFilesVersioning(CapabilityBooleanType
.fromValue(c
.getInt(c
1995 .getColumnIndex(ProviderTableMeta
.CAPABILITIES_FILES_VERSIONING
))));