OC-1380: Fix Start Synchroniztion fails
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / FileDisplayActivity.java
index 125fd9e..26b1df5 100644 (file)
 package com.owncloud.android.ui.activity;
 
 import java.io.File;
+import java.io.IOException;
 
 import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.app.Dialog;
@@ -59,6 +62,8 @@ import com.actionbarsherlock.view.Window;
 import com.owncloud.android.Log_OC;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.authentication.AccountUtils.AccountNotFoundException;
 import com.owncloud.android.datamodel.DataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -67,6 +72,7 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileObserverService;
 import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
+import com.owncloud.android.network.OwnCloudClientUtils;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.OnRemoteOperationListener;
 import com.owncloud.android.operations.RemoteOperation;
@@ -74,6 +80,7 @@ import com.owncloud.android.operations.RemoteOperationResult;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
+import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.syncadapter.FileSyncService;
 import com.owncloud.android.ui.dialog.EditNameDialog;
@@ -87,6 +94,8 @@ import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
 import com.owncloud.android.ui.preview.PreviewVideoActivity;
 
+import eu.alefzero.webdav.WebdavClient;
+
 /**
  * Displays, what files the user has available in his ownCloud.
  * 
@@ -176,27 +185,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         mRightFragmentContainer = findViewById(R.id.right_fragment_container);
         if (savedInstanceState == null) {
             createMinFragments();
-            if (!isRedirectingToSetupAccount()) {
-                initFragmentsWithFile();
-            }
         }
 
         // Action bar setup
         mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
-        OCFile currFile = getFile();
-        if (mStorageManager != null) {
-            while(currFile != null && currFile.getFileName() != OCFile.PATH_SEPARATOR) {
-                if (currFile.isDirectory()) {
-                    mDirectories.add(currFile.getFileName());
-                }
-                currFile = mStorageManager.getFileById(currFile.getParentId());
-            }
-        }
-        mDirectories.add(OCFile.PATH_SEPARATOR);
-        ActionBar actionBar = getSupportActionBar();
-        actionBar.setHomeButtonEnabled(true);   // mandatory since Android ICS, according to the official documentation
-        setSupportProgressBarIndeterminateVisibility(false);        // always AFTER setContentView(...) ; to workaround bug in its implementation
-
+        getSupportActionBar().setHomeButtonEnabled(true);       // mandatory since Android ICS, according to the official documentation
+        setSupportProgressBarIndeterminateVisibility(false);    // always AFTER setContentView(...) ; to work around bug in its implementation
+        
         Log_OC.d(TAG, "onCreate() end");
     }
 
@@ -233,17 +228,28 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             }
             if (file == null) {
                 // fall back to root folder
-                file = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);  // never should return null
+                file = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);  // never returns null
             }
             setFile(file);
-
-            if (findViewById(android.R.id.content) != null && !stateWasRecovered) {
+            mDirectories.clear();
+            OCFile fileIt = file;
+            while(fileIt != null && fileIt.getFileName() != OCFile.PATH_SEPARATOR) {
+                if (fileIt.isDirectory()) {
+                    mDirectories.add(fileIt.getFileName());
+                }
+                fileIt = mStorageManager.getFileById(fileIt.getParentId());
+            }
+            mDirectories.add(OCFile.PATH_SEPARATOR);
+            if (!stateWasRecovered) {
                 Log_OC.e(TAG, "Initializing Fragments in onAccountChanged..");
                 initFragmentsWithFile();
+                
             } else {
-                Log_OC.e(TAG, "Fragment initializacion ignored in onAccountChanged due to lack of CONTENT VIEW");
+                updateFragmentsVisibility(!file.isDirectory());
+                updateNavigationElementsInActionBar(file.isDirectory() ? null : file);
             }
-
+            
+            
         } else {
             Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
         }
@@ -259,11 +265,24 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
     private void initFragmentsWithFile() {
         if (getAccount() != null && getFile() != null) {
+            /// First fragment
+            OCFileListFragment listOfFiles = getListOfFilesFragment(); 
+            if (listOfFiles != null) {
+                listOfFiles.listDirectory(getCurrentDir());   
+            } else {
+                Log.e(TAG, "Still have a chance to lose the initializacion of list fragment >(");
+            }
+            
             /// Second fragment
             OCFile file = getFile(); 
             Fragment secondFragment = chooseInitialSecondFragment(file);
             if (secondFragment != null) {
                 setSecondFragment(secondFragment);
+                updateFragmentsVisibility(true);
+                updateNavigationElementsInActionBar(file);
+                
+            } else {
+                cleanSecondFragment();
             }
 
         } else {
@@ -361,8 +380,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             FragmentTransaction tr = getSupportFragmentManager().beginTransaction();
             tr.remove(second);
             tr.commit();
-            updateFragmentsVisibility(false);
         }
+        updateFragmentsVisibility(false);
+        updateNavigationElementsInActionBar(null);
     }
 
     protected void refeshListOfFilesFragment() {
@@ -443,8 +463,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             FileFragment second = getSecondFragment();
             OCFile currentDir = getCurrentDir();
             if((currentDir != null && currentDir.getParentId() != 0) || 
-                    (second != null && second.getFile() != null)) {
+                    (second != null && second.getFile() != null)) {                
                 onBackPressed(); 
+                
             }
             break;
         }
@@ -587,7 +608,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
             setFile(listOfFiles.getCurrentFile());
         }
         cleanSecondFragment();
-        updateNavigationElementsInActionBar(null);
     }
 
     @Override
@@ -600,14 +620,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     }
 
     @Override
-    protected void onStart() {
-        super.onStart();
-        FileFragment second = getSecondFragment();
-        updateFragmentsVisibility(second != null);
-        updateNavigationElementsInActionBar((second == null) ? null : second.getFile());
-    }
-
-    @Override
     protected void onResume() {
         super.onResume();
         Log_OC.e(TAG, "onResume() start");
@@ -627,13 +639,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         downloadIntentFilter.addAction(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
         mDownloadFinishReceiver = new DownloadFinishReceiver();
         registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
-
-        // List current directory
-        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
-        if (listOfFiles != null) {
-            listOfFiles.listDirectory(getCurrentDir());   // TODO we should find the way to avoid the need of this (maybe it's not necessary yet; to check)
-        }
-
+    
         Log_OC.d(TAG, "onResume() end");
     }
 
@@ -844,19 +850,14 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
                         || fillBlankRoot ) {
                     if (!fillBlankRoot) 
                         currentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
-//                    OCFileListFragment fileListFragment = getListOfFilesFragment();
-//                    if (fileListFragment != null) {
-//                        fileListFragment.listDirectory(currentDir);
-//                    }
-                }
-
-                OCFileListFragment fileListFragment = getListOfFilesFragment();
-                if (fileListFragment != null) {
-                    fileListFragment.listDirectory(currentDir);
+                    OCFileListFragment fileListFragment = getListOfFilesFragment();
+                    if (fileListFragment != null) {
+                        fileListFragment.listDirectory(currentDir);
+                    }
+                    if (getSecondFragment() == null)
+                        setFile(currentDir);
                 }
-
-                setFile(currentDir);
-
+                
                 setSupportProgressBarIndeterminateVisibility(inProgress);
                 removeStickyBroadcast(intent);
 
@@ -945,7 +946,12 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     public void onBrowsedDownTo(OCFile directory) {
         pushDirname(directory);
         cleanSecondFragment();
-        updateNavigationElementsInActionBar(null);
+        
+        // Sync Folder
+        startSyncFolderOperation(directory.getRemotePath(), directory.getFileId());
+//        // Update folder size on DB
+//        getStorageManager().calculateFolderSize(directory.getParentId());
+        
     }
 
     /**
@@ -1015,9 +1021,9 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
     /**
      * TODO
      */
-    private void updateNavigationElementsInActionBar(OCFile currentFile) {
+    private void updateNavigationElementsInActionBar(OCFile chosenFile) {
         ActionBar actionBar = getSupportActionBar(); 
-        if (currentFile == null || mDualPane) {
+        if (chosenFile == null || mDualPane) {
             // only list of files - set for browsing through folders
             OCFile currentDir = getCurrentDir();
             actionBar.setDisplayHomeAsUpEnabled(currentDir != null && currentDir.getParentId() != 0);
@@ -1028,7 +1034,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         } else {
             actionBar.setDisplayHomeAsUpEnabled(true);
             actionBar.setDisplayShowTitleEnabled(true);
-            actionBar.setTitle(currentFile.getFileName());
+            actionBar.setTitle(chosenFile.getFileName());
             actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
         }
     }
@@ -1038,15 +1044,6 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
      * {@inheritDoc}
      */
     @Override
-    public OCFile getInitialDirectory() {
-        return getCurrentDir();
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
     public void onFileStateChanged() {
         refeshListOfFilesFragment();
         updateNavigationElementsInActionBar(getSecondFragment().getFile());
@@ -1163,6 +1160,52 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
         } else if (operation instanceof CreateFolderOperation) {
             onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
+            
+        } else if (operation instanceof SynchronizeFolderOperation) {
+            onSynchronizeFolderOperationFinish((SynchronizeFolderOperation)operation, result);
+        }
+    }
+
+
+    /**
+     * Updates the view associated to the activity after the finish of an operation trying to synchronize a folder. 
+     * 
+     * @param operation     Synchronize operation performed.
+     * @param result        Result of the synchronization.
+     */
+    private void onSynchronizeFolderOperationFinish(SynchronizeFolderOperation operation, RemoteOperationResult result) {
+        
+        OCFileListFragment list = getListOfFilesFragment();
+        enableDisableViewGroup(list.getListView(), true);
+        
+        setSupportProgressBarIndeterminateVisibility(false);
+        if (result.isSuccess()) {
+            if (result.getCode() != ResultCode.OK_NO_CHANGES_ON_DIR) {
+                DataStorageManager storageManager = getStorageManager();
+                OCFile parentDir = storageManager.getFileByPath(operation.getRemotePath());
+
+                // Update folder size on DB
+                getStorageManager().calculateFolderSize(parentDir.getFileId());
+
+                // Refrest List
+                refreshListOfFilesFragment(parentDir);
+            }
+        } else {
+            try {
+                Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.sync_file_fail_msg, Toast.LENGTH_LONG); 
+                msg.show();
+
+            } catch (NotFoundException e) {
+                Log_OC.e(TAG, "Error while trying to show fail message " , e);
+            }
+        }
+    }
+
+
+    private void refreshListOfFilesFragment(OCFile parentDir) {
+        OCFileListFragment fileListFragment = getListOfFilesFragment();
+        if (fileListFragment != null) { 
+            fileListFragment.listDirectory(parentDir);
         }
     }
 
@@ -1345,12 +1388,42 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
         if (file != null) {
             if (file.isDirectory()) {
                 return file;
-            } else {
+            } else if (mStorageManager != null) {
                 return mStorageManager.getFileById(file.getParentId());
             }
-        } else {
-            return null;
         }
+        return null;
+    }
+    
+    public void startSyncFolderOperation(String remotePath, long parentId) {
+        long currentSyncTime = System.currentTimeMillis(); 
+        
+        OCFileListFragment list = getListOfFilesFragment();
+        enableDisableViewGroup(list.getListView(), false);
+        
+       // perform folder synchronization
+        RemoteOperation synchFolderOp = new SynchronizeFolderOperation(  remotePath, 
+                                                                                    currentSyncTime, 
+                                                                                    parentId, 
+                                                                                    getStorageManager(), 
+                                                                                    getAccount(), 
+                                                                                    getApplicationContext()
+                                                                                  );
+        synchFolderOp.execute(getAccount(), this, this, mHandler, this);
+        
+        setSupportProgressBarIndeterminateVisibility(true);
     }
 
+    
+    public void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
+        int childCount = viewGroup.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+          View view = viewGroup.getChildAt(i);
+          view.setEnabled(enabled);
+          view.setClickable(!enabled);
+          if (view instanceof ViewGroup) {
+            enableDisableViewGroup((ViewGroup) view, enabled);
+          }
+        }
+      }
 }