ソースを参照

Fixed update of size in folders when browsing down and up through new folders in servers

David A. Velasco 11 年 前
コミット
8bd6f85e22

+ 28 - 37
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -182,7 +182,6 @@ public class FileDataStorageManager {
         cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
 
         boolean sameRemotePath = fileExists(file.getRemotePath());
-        boolean changesSizeOfAncestors = false;
         if (sameRemotePath ||
                 fileExists(file.getFileId())        ) {           // for renamed files; no more delete and create
 
@@ -193,7 +192,6 @@ public class FileDataStorageManager {
             } else {
                 oldFile = getFileById(file.getFileId());
             }
-            changesSizeOfAncestors = (oldFile.getFileLength() != file.getFileLength());
 
             overriden = true;
             if (getContentResolver() != null) {
@@ -212,7 +210,6 @@ public class FileDataStorageManager {
                 }
             }
         } else {
-            changesSizeOfAncestors = true;
             Uri result_uri = null;
             if (getContentResolver() != null) {
                 result_uri = getContentResolver().insert(
@@ -235,17 +232,13 @@ public class FileDataStorageManager {
         }
 
         if (file.isFolder()) {
-            calculateFolderSize(file.getFileId());
+            updateFolderSize(file.getFileId());
             if (file.needsUpdatingWhileSaving()) {
                 for (OCFile f : getFolderContent(file))
                     saveFile(f);
             }
         }
         
-        if (changesSizeOfAncestors || file.isFolder()) {
-            updateSizesToTheRoot(file.getParentId());
-        }
-        
         return overriden;
     }
 
@@ -262,6 +255,7 @@ public class FileDataStorageManager {
         Log_OC.d(TAG,  "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
 
         ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(updatedFiles.size());
+        long folderSize = 0;
 
         // prepare operations to insert or update files to save in the given folder
         for (OCFile file : updatedFiles) {
@@ -270,6 +264,7 @@ public class FileDataStorageManager {
             cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
             cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
             cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+            folderSize += file.getFileLength();
             cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
             cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
             //cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
@@ -350,19 +345,16 @@ public class FileDataStorageManager {
             }
         }
         
-        // update metadata of folder --> TODO  MOVE UPDATE OF SIZE TO CONTENTPROVIDER
+        // update metadata of folder
         ContentValues cv = new ContentValues();
         cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
         cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
         cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, folder.getFileLength());
+        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, folderSize);
         cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
         cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
         cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
         cv.put(ProviderTableMeta.FILE_PATH, folder.getRemotePath());
-        if (!folder.isFolder()) {
-            cv.put(ProviderTableMeta.FILE_STORAGE_PATH, folder.getStoragePath());
-        }
         cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, folder.getLastSyncDateForProperties());
         cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, folder.getLastSyncDateForData());
@@ -417,23 +409,27 @@ public class FileDataStorageManager {
 
 
     /**
-     * Calculate and save the folderSize on DB
+     * 
      * @param id
      */
-    public void calculateFolderSize(long id) {
-        long folderSize = 0;
-        
-        Vector<OCFile> files = getFolderContent(id);
-        
-        for (OCFile f: files)
-        {
-            folderSize = folderSize + f.getFileLength();
+    public void updateFolderSize(long id) {
+        if (getContentResolver() != null) {
+            getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR, null,
+                    ProviderTableMeta._ID + "=?",
+                    new String[] { String.valueOf(id) });
+        } else {
+            try {
+                getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR, null,
+                    ProviderTableMeta._ID + "=?",
+                    new String[] { String.valueOf(id) });
+                
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
+            }
         }
-        
-        updateSize(id, folderSize);
     }
     
-    
+
     public void removeFile(OCFile file, boolean removeDBData, boolean removeLocalCopy) {
         if (file != null) {
             if (file.isFolder()) {
@@ -454,9 +450,6 @@ public class FileDataStorageManager {
                     } else {
                         getContentResolver().delete(file_uri, where, whereArgs);
                     }
-                    if (file.getFileLength() > 0) {
-                        updateSizesToTheRoot(file.getParentId());   // TODO move to content provider
-                    }
                 }
                 if (removeLocalCopy && file.isDown()) {
                     boolean success = new File(file.getStoragePath()).delete();
@@ -496,9 +489,6 @@ public class FileDataStorageManager {
         } else {
             getContentResolver().delete(folder_uri, where, whereArgs); 
         }
-        if (folder.getFileLength() > 0) {
-            updateSizesToTheRoot(folder.getParentId()); // TODO move to FileContentProvider
-        }
     }
 
     private void removeLocalFolder(File folder) {
@@ -732,9 +722,9 @@ public class FileDataStorageManager {
         return file;
     }
 
-    /**
+    /*
      * Update the size value of an OCFile in DB
-     */
+     *
     private int updateSize(long id, long size) {
         ContentValues cv = new ContentValues();
         cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
@@ -752,11 +742,12 @@ public class FileDataStorageManager {
         }
         return result;
     }
+    */
 
-    /** 
+    /* 
      * Update the size of a subtree of folder from a file to the root
      * @param parentId: parent of the file
-     */
+     *
     private void updateSizesToTheRoot(long parentId) {
         
         OCFile file; 
@@ -764,14 +755,14 @@ public class FileDataStorageManager {
         while (parentId != FileDataStorageManager.ROOT_PARENT_ID) {
             
             // Update the size of the parent
-            calculateFolderSize(parentId);
+            updateFolderSize(parentId);
             
             // search the next parent
             file = getFileById(parentId);            
             parentId = file.getParentId();
             
         }              
-        
     }
+    */
     
 }

+ 47 - 7
src/com/owncloud/android/providers/FileContentProvider.java

@@ -41,7 +41,6 @@ import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.text.TextUtils;
-import android.util.Log;
 
 /**
  * The ContentProvider for the ownCloud App.
@@ -88,16 +87,19 @@ public class FileContentProvider extends ContentProvider {
                 ProviderTableMeta.FILE_ETAG);
     }
 
-    private static final String TAG = FileContentProvider.class.getSimpleName(); 
     private static final int SINGLE_FILE = 1;
     private static final int DIRECTORY = 2;
     private static final int ROOT_DIRECTORY = 3;
     private static final UriMatcher mUriMatcher;
+
+    public static final String METHOD_UPDATE_FOLDER_SIZE = "updateFolderSize";
+    
     static {
         mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
         mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, null, ROOT_DIRECTORY);
         mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
         mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
+        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/", DIRECTORY);
         mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
     }
 
@@ -155,11 +157,11 @@ public class FileContentProvider extends ContentProvider {
             if (children != null && children.moveToFirst())  {
                 long childId;
                 boolean isDir; 
-                String remotePath; 
+                //String remotePath; 
                 while (!children.isAfterLast()) {
                     childId = children.getLong(children.getColumnIndex(ProviderTableMeta._ID));
                     isDir = "DIR".equals(children.getString(children.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
-                    remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
+                    //remotePath = children.getString(children.getColumnIndex(ProviderTableMeta.FILE_PATH));
                     if (isDir) {
                         count += delete(db, ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, childId), null, null);
                     } else {
@@ -275,8 +277,9 @@ public class FileContentProvider extends ContentProvider {
         case ROOT_DIRECTORY:
             break;
         case DIRECTORY:
+            String folderId = uri.getPathSegments().get(1);
             sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="
-                    + uri.getPathSegments().get(1));
+                    + folderId);
             break;
         case SINGLE_FILE:
             if (uri.getPathSegments().size() > 1) {
@@ -298,6 +301,16 @@ public class FileContentProvider extends ContentProvider {
         // DB case_sensitive
         db.execSQL("PRAGMA case_sensitive_like = true");
         Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
+        if (mUriMatcher.match(uri) == DIRECTORY && c != null && c.moveToFirst()) {
+            long size = 0;
+            while (!c.isAfterLast()) {
+                size += c.getLong(c.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
+                c.moveToNext();
+            }
+            ContentValues cv = new ContentValues();
+            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
+            db.update(ProviderTableMeta.DB_NAME, cv, ProviderTableMeta._ID + "=?", new String[] {uri.getPathSegments().get(1)});
+        }
 
         c.setNotificationUri(getContext().getContentResolver(), uri);
         return c;
@@ -322,10 +335,37 @@ public class FileContentProvider extends ContentProvider {
     
     
     private int update(SQLiteDatabase db, Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        return db.update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
+        switch (mUriMatcher.match(uri)) {
+            case DIRECTORY:
+                return updateFolderSize(db, selectionArgs[0]);
+            default:
+                return db.update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
+        }
     }    
 
     
+    private int updateFolderSize(SQLiteDatabase db, String folderId) {
+        int count = 0;
+        Uri selectUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, folderId);
+        String[] selectProjection = new String[] { ProviderTableMeta.FILE_CONTENT_LENGTH };
+        String selectWhere = ProviderTableMeta.FILE_PARENT + "=?";
+        String updateWhere = ProviderTableMeta._ID + "=?";
+        String [] whereArgs = new String[] { folderId };
+        Cursor childrenLengths = query(db, selectUri, selectProjection, selectWhere, whereArgs, null);
+        if (childrenLengths != null && childrenLengths.moveToFirst()) {
+            long size = 0;
+            while (!childrenLengths.isAfterLast()) {
+                size += childrenLengths.getLong(childrenLengths.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH));
+                childrenLengths.moveToNext();
+            }
+            ContentValues cv = new ContentValues();
+            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, size);
+            count = db.update(ProviderTableMeta.DB_NAME, cv, updateWhere, whereArgs);
+        }
+        return count;
+    }
+
+    
     @Override
     public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
         //Log.d(TAG, "applying batch in provider " + this + " (temporary: " + isTemporary() + ")" );
@@ -347,7 +387,7 @@ public class FileContentProvider extends ContentProvider {
         return results;
     }
 
-    
+
     class DataBaseHelper extends SQLiteOpenHelper {
 
         public DataBaseHelper(Context context) {

+ 5 - 6
src/com/owncloud/android/syncadapter/FileSyncAdapter.java

@@ -263,11 +263,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             }
             // synchronize children folders 
             List<OCFile> 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
+            fetchChildren(folder, children);    // beware of the 'hidden' recursion here!
             
         } else {
             // in failures, the statistics for the global result are updated
@@ -311,12 +307,15 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
      * 
      * @param files         Files to recursively synchronize.
      */
-    private void fetchChildren(List<OCFile> files) {
+    private void fetchChildren(OCFile parent, List<OCFile> files) {
         int i;
         for (i=0; i < files.size() && !mCancellation; i++) {
             OCFile newFile = files.get(i);
             if (newFile.isFolder()) {
                 synchronizeFolder(newFile, false);
+                // update the size of the parent folder again after recursive synchronization 
+                getStorageManager().updateFolderSize(parent.getFileId());  
+                sendStickyBroadcast(true, parent.getRemotePath(), null);        // notify again to refresh size in UI
             }
         }