Merge branch 'develop' into pinEnhancement
authorDavid A. Velasco <dvelasco@solidgear.es>
Tue, 28 Apr 2015 12:20:17 +0000 (14:20 +0200)
committerDavid A. Velasco <dvelasco@solidgear.es>
Tue, 28 Apr 2015 12:20:17 +0000 (14:20 +0200)
Conflicts SOLVED:
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/Uploader.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

1  2 
res/values/strings.xml
res/xml/preferences.xml
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/activity/PinCodeActivity.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/Uploader.java
src/com/owncloud/android/ui/preview/PreviewImageActivity.java

diff --combined res/values/strings.xml
@@@ -24,7 -24,8 +24,7 @@@
      <string name="prefs_category_more">More</string>
      <string name="prefs_accounts">Accounts</string>
      <string name="prefs_manage_accounts">Manage Accounts</string>
 -    <string name="prefs_pincode">App PIN</string>
 -    <string name="prefs_pincode_summary">Protect your client</string>
 +    <string name="prefs_pincode">Passcode lock</string>
      <string name="prefs_instant_upload">Instant picture uploads</string>
      <string name="prefs_instant_upload_summary">Instantly upload pictures taken by camera</string>
      <string name="prefs_instant_video_upload">Instant video uploads</string>
@@@ -52,6 -53,7 +52,7 @@@
      <string name="sync_string_files">Files</string>
      <string name="setup_btn_connect">Connect</string>
      <string name="uploader_btn_upload_text">Upload</string>
+     <string name="uploader_btn_new_folder_text">New folder</string>
      <string name="uploader_top_message">Choose upload folder:</string>
      <string name="uploader_wrn_no_account_title">No account found</string>
      <string name="uploader_wrn_no_account_text">There are no %1$s accounts on your device. Please setup an account first.</string>
        <string name="auth_no_net_conn_title">No network connection</string>
        <string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
        <string name="auth_connection_established">Connection established</string>
-       <string name="auth_testing_connection">Testing connection&#8230;</string>
+       <string name="auth_testing_connection">Testing connection</string>
        <string name="auth_not_configured_title">Malformed server configuration</string>
        <string name="auth_account_not_new">An account for the same user and server already exists in the device</string>
        <string name="auth_account_not_the_same">The entered user does not match the user of this account</string>
        <string name="auth_fail_get_user_name">Your server is not returning a correct user id, please contact an administrator
        </string>
        <string name="auth_can_not_auth_against_server">Cannot authenticate against this server</string>
+     <string name="auth_account_does_not_exist">Account does not exist in the device yet</string>
      
      <string name="fd_keep_in_sync">Keep file up to date</string>
      <string name="common_rename">Rename</string>
        <string name="share_link_file_error">An error occurred while trying to share this file or folder</string>
        <string name="unshare_link_file_no_exist">Unable to unshare. Please check whether the file exists</string>
        <string name="unshare_link_file_error">An error occurred while trying to unshare this file or folder</string>
+     <string name="share_link_password_title">Enter a password</string>
+     <string name="share_link_empty_password">You must enter a password</string>
  
        <string name="activity_chooser_send_file_title">Send</string>
  
        <string name="prefs_category_security">Security</string>
  
        <string name="prefs_instant_video_upload_path_title">Upload Video Path</string>
+     <string name="download_folder_failed_content">Download of %1$s folder could not be completed</string>
+       <string name="subject_token">%1$s shared \"%2$s\" with you</string>
+     <string name="auth_refresh_button">Refresh connection</string>
+     <string name="auth_host_address">Server address</string>
  
  </resources>
diff --combined res/xml/preferences.xml
@@@ -3,7 -3,7 +3,7 @@@
    ownCloud Android client application
  
    Copyright (C) 2012  Bartek Przybylski
-   Copyright (C) 2012-2013 ownCloud Inc.
+   Copyright (C) 2015 ownCloud Inc.
  
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2,
                android:title="@string/prefs_select_oc_account"
                android:summary="@string/prefs_summary_select_oc_account"
                / -->
 -          <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:title="@string/prefs_pincode" android:key="set_pincode" 
 -                        android:summary="@string/prefs_pincode_summary"/>
 +          <android.preference.CheckBoxPreference android:title="@string/prefs_pincode" android:key="set_pincode" />
        </PreferenceCategory>
  
-     <PreferenceCategory android:title="@string/prefs_category_instant_uploading">
-         <com.owncloud.android.ui.PreferenceWithLongSummary
-                                                       android:title="@string/prefs_instant_upload_path_title"
-                                                       android:key="instant_upload_path" />
-           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_uploading"
+     <PreferenceCategory android:title="@string/prefs_category_instant_uploading" android:key="instant_uploading_category">
+          <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_uploading"
                                android:title="@string/prefs_instant_upload"
                                android:summary="@string/prefs_instant_upload_summary"/>
-           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:dependency="instant_uploading"
-                                               android:disableDependentsState="true"
+          <com.owncloud.android.ui.PreferenceWithLongSummary
+                                                       android:title="@string/prefs_instant_upload_path_title"
+                                                       android:key="instant_upload_path" />
+           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
                                                android:title="@string/instant_upload_on_wifi"
                                                android:key="instant_upload_on_wifi"/>
+           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_video_uploading"
+                               android:title="@string/prefs_instant_video_upload"
+                               android:summary="@string/prefs_instant_video_upload_summary" />
            <com.owncloud.android.ui.PreferenceWithLongSummary
                                                        android:title="@string/prefs_instant_video_upload_path_title"
                                                        android:key="instant_video_upload_path" />
-           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_video_uploading"
-                               android:title="@string/prefs_instant_video_upload"
-                               android:summary="@string/prefs_instant_video_upload_summary"/>
-           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:dependency="instant_video_uploading"
-                                               android:disableDependentsState="true"
+           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
                                                android:title="@string/instant_video_upload_on_wifi"
                                                android:key="instant_video_upload_on_wifi"/>
            <!-- DISABLED FOR RELEASE UNTIL FIXED
@@@ -1,6 -1,10 +1,10 @@@
- /* ownCloud Android client application
+ /**
+  *   ownCloud Android client application
+  *
+  *   @author Bartek Przybylski
+  *   @author David A. Velasco
   *   Copyright (C) 2011  Bartek Przybylski
-  *   Copyright (C) 2012-2014 ownCloud Inc.
+  *   Copyright (C) 2015 ownCloud Inc.
   *
   *   This program is free software: you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License version 2,
  package com.owncloud.android.ui.activity;
  
  import java.io.File;
- import java.io.IOException;
  
  import android.accounts.Account;
  import android.accounts.AccountManager;
  import android.accounts.AuthenticatorException;
- import android.accounts.OperationCanceledException;
  import android.annotation.TargetApi;
  import android.app.AlertDialog;
- import android.app.Dialog;
- import android.app.ProgressDialog;
  import android.content.BroadcastReceiver;
  import android.content.ComponentName;
  import android.content.ContentResolver;
- import android.content.ContentUris;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.Intent;
@@@ -45,16 -44,12 +44,12 @@@ import android.database.Cursor
  import android.net.Uri;
  import android.os.Build;
  import android.os.Bundle;
- import android.os.Environment;
  import android.os.IBinder;
  import android.preference.PreferenceManager;
- import android.provider.DocumentsContract;
- import android.provider.MediaStore;
  import android.provider.OpenableColumns;
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentManager;
  import android.support.v4.app.FragmentTransaction;
- import android.util.Log;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ArrayAdapter;
@@@ -70,7 -65,6 +65,7 @@@ import com.actionbarsherlock.view.Windo
  import com.owncloud.android.BuildConfig;
  import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
 +import com.owncloud.android.authentication.PinCheck;
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.files.services.FileDownloader;
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
@@@ -92,14 -86,15 +87,15 @@@ import com.owncloud.android.operations.
  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.RefreshFolderOperation;
  import com.owncloud.android.operations.UnshareLinkOperation;
  import com.owncloud.android.services.observer.FileObserverService;
  import com.owncloud.android.syncadapter.FileSyncAdapter;
- import com.owncloud.android.ui.adapter.FileListListAdapter;
+ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
  import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
  import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
  import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
+ import com.owncloud.android.ui.dialog.UploadSourceDialogFragment;
  import com.owncloud.android.ui.fragment.FileDetailFragment;
  import com.owncloud.android.ui.fragment.FileFragment;
  import com.owncloud.android.ui.fragment.OCFileListFragment;
@@@ -109,14 -104,12 +105,12 @@@ import com.owncloud.android.ui.preview.
  import com.owncloud.android.ui.preview.PreviewVideoActivity;
  import com.owncloud.android.utils.DisplayUtils;
  import com.owncloud.android.utils.ErrorMessageAdapter;
+ import com.owncloud.android.utils.FileStorageUtils;
  import com.owncloud.android.utils.UriUtils;
  
  
  /**
   * Displays, what files the user has available in his ownCloud.
-  * 
-  * @author Bartek Przybylski
-  * @author David A. Velasco
   */
  
  public class FileDisplayActivity extends HookActivity implements
@@@ -138,14 -131,10 +132,10 @@@ OnSslUntrustedCertListener, OnEnforceab
      private static final String KEY_SYNC_IN_PROGRESS = "SYNC_IN_PROGRESS";
      private static final String KEY_WAITING_TO_SEND = "WAITING_TO_SEND";
  
-     public static final int DIALOG_SHORT_WAIT = 0;
-     private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 1;
-     private static final int DIALOG_CERT_NOT_SAVED = 2;
-     
      public static final String ACTION_DETAILS = "com.owncloud.android.ui.activity.action.DETAILS";
  
-     private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
-     private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
+     public static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
+     public static final int ACTION_SELECT_MULTIPLE_FILES = 2;
      public static final int ACTION_MOVE_FILES = 3;
  
      private static final String TAG = FileDisplayActivity.class.getSimpleName();
      
      private boolean mSyncInProgress = false;
  
-     private String DIALOG_UNTRUSTED_CERT;
-     
+     private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT";
+     private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
+     private static String DIALOG_UPLOAD_SOURCE = "DIALOG_UPLOAD_SOURCE";
+     private static String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED";
      private OCFile mWaitingToSend;
 +    
 +    private Boolean mUnlocked = false;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
  
          super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account is valid
  
 -        // PIN CODE request ;  best location is to decide, let's try this first
 -        if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
 -            requestPinCode();
 -        } else if (getIntent().getAction() == null && savedInstanceState == null) {
 -            requestPinCode();
 +        
 +        if (PinCheck.checkIfPinEntry()){
 +            Intent i = new Intent(MainApp.getAppContext(), PinCodeActivity.class);
 +            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
 +            startActivity(i);
          }
  
 -        /// grant that FileObserverService is watching favourite files
 +        /// grant that FileObserverService is watching favorite files
          if (savedInstanceState == null) {
              Intent initObserversIntent = FileObserverService.makeInitIntent(this);
              startService(initObserversIntent);
      
      @Override
      protected void onStart() {
+         Log_OC.d(TAG, "onStart() start");
          super.onStart();
          getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
+         Log_OC.d(TAG, "onStart() end");
      }
  
      @Override
      protected void onDestroy() {
+         Log_OC.d(TAG, "onDestroy() start");
          super.onDestroy();
+         Log_OC.d(TAG, "onDestroy() end");
      }
  
      /**
              setNavigationListWithFolder(file);
              
              if (!stateWasRecovered) {
-                 Log_OC.e(TAG, "Initializing Fragments in onAccountChanged..");
+                 Log_OC.d(TAG, "Initializing Fragments in onAccountChanged..");
                  initFragmentsWithFile();
                  if (file.isFolder()) {
                      startSyncFolderOperation(file, false);
          boolean retval = true;
          switch (item.getItemId()) {
          case R.id.action_create_dir: {
-             CreateFolderDialogFragment dialog = 
-                     CreateFolderDialogFragment.newInstance(getCurrentDir());
-             dialog.show(getSupportFragmentManager(), "createdirdialog");
+             CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(getCurrentDir());
+             dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
              break;
          }
          case R.id.action_sync_account: {
              break;
          }
          case R.id.action_upload: {
-             showDialog(DIALOG_CHOOSE_UPLOAD_SOURCE);
+             UploadSourceDialogFragment dialog = UploadSourceDialogFragment.newInstance(getAccount());
+             dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE);
              break;
          }
          case R.id.action_settings: {
              
              // Read sorting order, default to sort by name ascending
              Integer sortOrder = appPreferences
-                     .getInt("sortOrder", FileListListAdapter.SORT_NAME);
+                     .getInt("sortOrder", FileStorageUtils.SORT_NAME);
              
              AlertDialog.Builder builder = new AlertDialog.Builder(this);
              builder.setTitle(R.string.actionbar_sort_title)
      }
  
      private void startSynchronization() {
-         Log_OC.e(TAG, "Got to start sync");
+         Log_OC.d(TAG, "Got to start sync");
          if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
-             Log_OC.e(TAG, "Canceling all syncs for " + MainApp.getAuthority());
+             Log_OC.d(TAG, "Canceling all syncs for " + MainApp.getAuthority());
              ContentResolver.cancelSync(null, MainApp.getAuthority());   // cancel the current synchronizations of any ownCloud account
              Bundle bundle = new Bundle();
              bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
              bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
-             Log_OC.e(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority());
+             Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority());
              ContentResolver.requestSync(
                      getAccount(),
                      MainApp.getAuthority(), bundle);
          } else {
-             Log_OC.e(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority() + " with new API");
+             Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority() + " with new API");
              SyncRequest.Builder builder = new SyncRequest.Builder();
              builder.setSyncAdapter(getAccount(), MainApp.getAuthority());
              builder.setExpedited(true);
       *
       */
      @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+     @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-         super.onActivityResult(requestCode, resultCode, data);
  
          if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
              //getClipData is only supported on api level 16+, Jelly Bean
                  }, 
                  DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
              );
+         } else {
+             super.onActivityResult(requestCode, resultCode, data);
          }
      }
  
      private void requestMultipleUpload(Intent data, int resultCode) {
          if (filePaths != null) {
              String[] remotePaths = new String[filePaths.length];
              String remotePathBase = "";
              for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
                  remotePathBase += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
              }
  
  
      private void requestSimpleUpload(Intent data, int resultCode) {
-         String filepath = null;
+         String filePath = null;
          String mimeType = null;
  
          Uri selectedImageUri = data.getData();
          try {
              mimeType = getContentResolver().getType(selectedImageUri);
  
-             String filemanagerstring = selectedImageUri.getPath();
-             String selectedImagePath = getPath(selectedImageUri);
+             String fileManagerString = selectedImageUri.getPath();
+             String selectedImagePath = UriUtils.getLocalPath(selectedImageUri, this);
  
              if (selectedImagePath != null)
-                 filepath = selectedImagePath;
+                 filePath = selectedImagePath;
              else
-                 filepath = filemanagerstring;
+                 filePath = fileManagerString;
  
          } catch (Exception e) {
              Log_OC.e(TAG, "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
-             e.printStackTrace();
  
          } finally {
-             if (filepath == null) {
-                 Log_OC.e(TAG, "Couldnt resolve path to file");
-                 Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
+             if (filePath == null) {
+                 Log_OC.e(TAG, "Couldn't resolve path to file");
+                 Toast t = Toast.makeText(
+                         this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG
+                 );
                  t.show();
                  return;
              }
          }
  
          Intent i = new Intent(this, FileUploader.class);
-         i.putExtra(FileUploader.KEY_ACCOUNT,
-                 getAccount());
-         String remotepath = new String();
-         for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-             remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
-         }
-         if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
-             remotepath += OCFile.PATH_SEPARATOR;
-         if (filepath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
-             Cursor cursor = MainApp.getAppContext().getContentResolver()
-                     .query(Uri.parse(filepath), null, null, null, null, null);
+         i.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
+         OCFile currentDir = getCurrentDir();
+         String remotePath =  (currentDir != null) ? currentDir.getRemotePath() : OCFile.ROOT_PATH;
  
+         if (filePath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
+             Cursor cursor = getContentResolver().query(Uri.parse(filePath), null, null, null, null);
              try {
                  if (cursor != null && cursor.moveToFirst()) {
-                     String displayName = cursor.getString(
-                             cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
-                     Log.i(TAG, "Display Name: " + displayName + "; mimeType: " + mimeType);
+                     String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
+                     Log_OC.v(TAG, "Display Name: " + displayName );
  
                      displayName.replace(File.separatorChar, '_');
                      displayName.replace(File.pathSeparatorChar, '_');
-                     remotepath += displayName + DisplayUtils.getComposedFileExtension(filepath);
+                     remotePath += displayName + DisplayUtils.getComposedFileExtension(filePath);
  
                  }
+                 // and what happens in case of error?; wrong target name for the upload
              } finally {
                  cursor.close();
              }
  
          } else {
-             remotepath += new File(filepath).getName();
+             remotePath += new File(filePath).getName();
          }
  
-         i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
-         i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
+         i.putExtra(FileUploader.KEY_LOCAL_FILE, filePath);
+         i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePath);
          i.putExtra(FileUploader.KEY_MIME_TYPE, mimeType);
          i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
          if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
-             i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
+         i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
          startService(i);
      }
  
      @Override
      protected void onSaveInstanceState(Bundle outState) {
          // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
-         Log_OC.e(TAG, "onSaveInstanceState() start");
+         Log_OC.d(TAG, "onSaveInstanceState() start");
          super.onSaveInstanceState(outState);
          outState.putParcelable(FileDisplayActivity.KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
          outState.putBoolean(FileDisplayActivity.KEY_SYNC_IN_PROGRESS, mSyncInProgress);
  
      @Override
      protected void onResume() {
+         Log_OC.d(TAG, "onResume() start");
          super.onResume();
-         Log_OC.e(TAG, "onResume() start");
-         
 +        if (PinCheck.checkIfPinEntry()){
 +            Intent i = new Intent(MainApp.getAppContext(), PinCodeActivity.class);
 +            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
 +            startActivity(i);
 +        }
 +    
          // refresh list of files
          refreshListOfFilesFragment();
  
          IntentFilter syncIntentFilter = new IntentFilter(FileSyncAdapter.EVENT_FULL_SYNC_START);
          syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_END);
          syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED);
-         syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
-         syncIntentFilter.addAction(SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
+         syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED);
+         syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
          mSyncBroadcastReceiver = new SyncBroadcastReceiver();
          registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
          //LocalBroadcastManager.getInstance(this).registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
  
      @Override
      protected void onPause() {
-         Log_OC.e(TAG, "onPause() start");
+         Log_OC.d(TAG, "onPause() start");
          if (mSyncBroadcastReceiver != null) {
              unregisterReceiver(mSyncBroadcastReceiver);
              //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver);
              mDownloadFinishReceiver = null;
          }
          
 -        
 +        PinCheck.setUnlockTimestamp();
-         Log_OC.d(TAG, "onPause() end");
-         super.onPause();
-     }
-     @Override
-     protected Dialog onCreateDialog(int id) {
-         Dialog dialog = null;
-         AlertDialog.Builder builder;
-         switch (id) {
-         case DIALOG_SHORT_WAIT: {
-             ProgressDialog working_dialog = new ProgressDialog(this);
-             working_dialog.setMessage(getResources().getString(
-                     R.string.wait_a_moment));
-             working_dialog.setIndeterminate(true);
-             working_dialog.setCancelable(false);
-             dialog = working_dialog;
-             break;
-         }
-         case DIALOG_CHOOSE_UPLOAD_SOURCE: {
-             String[] allTheItems = { getString(R.string.actionbar_upload_files),
-                     getString(R.string.actionbar_upload_from_apps) };
-             builder = new AlertDialog.Builder(this);
-             builder.setTitle(R.string.actionbar_upload);
-             builder.setItems(allTheItems, new DialogInterface.OnClickListener() {
-                 public void onClick(DialogInterface dialog, int item) {
-                     if (item == 0) {
-                         // if (!mDualPane) {
-                             Intent action = new Intent(FileDisplayActivity.this, UploadFilesActivity.class);
-                             action.putExtra(UploadFilesActivity.EXTRA_ACCOUNT, FileDisplayActivity.this.getAccount());
-                             startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
-                             // } else {
-                             // TODO create and handle new fragment
-                             // LocalFileListFragment
-                             // }
-                     } else if (item == 1) {
-                         Intent action = new Intent(Intent.ACTION_GET_CONTENT);
-                         action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
-                         //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
-                         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-                             action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
-                         }
-                         startActivityForResult(Intent.createChooser(action, getString(R.string.upload_chooser_title)),
-                                 ACTION_SELECT_CONTENT_FROM_APPS);
-                     }
-                 }
-             });
-             dialog = builder.create();
-             break;
-         }
-         case DIALOG_CERT_NOT_SAVED: {
-             builder = new AlertDialog.Builder(this);
-             builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
-             builder.setCancelable(false);
-             builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
-                 @Override
-                 public void onClick(DialogInterface dialog, int which) {
-                     dialog.dismiss();
-                 };
-             });
-             dialog = builder.create();
-             break;
-         }
-         default:
-             dialog = null;
-         }
 +
-         return dialog;
-     }
-     /**
-      * Translates a content URI of an content to a physical path on the disk
-      * 
-      * @param uri The URI to resolve
-      * @return The path to the content or null if it could not be found
-      */
-     public String getPath(Uri uri) {
-         final boolean isKitKatOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
-         // DocumentProvider
-         if (isKitKatOrLater && DocumentsContract.isDocumentUri(getApplicationContext(), uri)) {
-             // ExternalStorageProvider
-             if (UriUtils.isExternalStorageDocument(uri)) {
-                 final String docId = DocumentsContract.getDocumentId(uri);
-                 final String[] split = docId.split(":");
-                 final String type = split[0];
-                 if ("primary".equalsIgnoreCase(type)) {
-                     return Environment.getExternalStorageDirectory() + "/" + split[1];
-                 }
-             }
-             // DownloadsProvider
-             else if (UriUtils.isDownloadsDocument(uri)) {
-                 final String id = DocumentsContract.getDocumentId(uri);
-                 final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
-                         Long.valueOf(id));
-                 return UriUtils.getDataColumn(getApplicationContext(), contentUri, null, null);
-             }
-             // MediaProvider
-             else if (UriUtils.isMediaDocument(uri)) {
-                 final String docId = DocumentsContract.getDocumentId(uri);
-                 final String[] split = docId.split(":");
-                 final String type = split[0];
-                 Uri contentUri = null;
-                 if ("image".equals(type)) {
-                     contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-                 } else if ("video".equals(type)) {
-                     contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-                 } else if ("audio".equals(type)) {
-                     contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-                 }
-                 final String selection = "_id=?";
-                 final String[] selectionArgs = new String[] { split[1] };
-                 return UriUtils.getDataColumn(getApplicationContext(), contentUri, selection, selectionArgs);
-             }
-             // Documents providers returned as content://...
-             else if (UriUtils.isContentDocument(uri)) {
-                 return uri.toString();
-             }
-         }
-         // MediaStore (and general)
-         else if ("content".equalsIgnoreCase(uri.getScheme())) {
-             // Return the remote address
-             if (UriUtils.isGooglePhotosUri(uri))
-                 return uri.getLastPathSegment();
-             return UriUtils.getDataColumn(getApplicationContext(), uri, null, null);
-         }
-         // File
-         else if ("file".equalsIgnoreCase(uri.getScheme())) {
-             return uri.getPath();
-         }
-         return null;
+         super.onPause();
+         Log_OC.d(TAG, "onPause() end");
      }
  
      /**
                              setFile(currentFile);
                          }
                          
-                         mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
+                         mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
                                  
-                         if (SynchronizeFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
+                         if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
                                      equals(event) &&
                                  /// TODO refactor and make common
                                  synchResult != null && !synchResult.isSuccess() &&  
                                      (synchResult.isException() && synchResult.getException() 
                                              instanceof AuthenticatorException))) {
  
-                             OwnCloudClient client = null;
                              try {
-                                 OwnCloudAccount ocAccount = 
+                                 OwnCloudClient client;
+                                 OwnCloudAccount ocAccount =
                                          new OwnCloudAccount(getAccount(), context);
                                  client = (OwnCloudClientManagerFactory.getDefaultSingleton().
                                          removeClientFor(ocAccount));
-                                 // TODO get rid of these exceptions
-                             } catch (AccountNotFoundException e) {
-                                 e.printStackTrace();
-                             } catch (AuthenticatorException e) {
-                                 e.printStackTrace();
-                             } catch (OperationCanceledException e) {
-                                 e.printStackTrace();
-                             } catch (IOException e) {
-                                 e.printStackTrace();
-                             }
-                             
-                             if (client != null) {
-                                 OwnCloudCredentials cred = client.getCredentials();
-                                 if (cred != null) {
-                                     AccountManager am = AccountManager.get(context);
-                                     if (cred.authTokenExpires()) {
-                                         am.invalidateAuthToken(
-                                                 getAccount().type, 
-                                                 cred.getAuthToken()
-                                         );
-                                     } else {
-                                         am.clearPassword(getAccount());
+                                 if (client != null) {
+                                     OwnCloudCredentials cred = client.getCredentials();
+                                     if (cred != null) {
+                                         AccountManager am = AccountManager.get(context);
+                                         if (cred.authTokenExpires()) {
+                                             am.invalidateAuthToken(
+                                                     getAccount().type,
+                                                     cred.getAuthToken()
+                                             );
+                                         } else {
+                                             am.clearPassword(getAccount());
+                                         }
                                      }
                                  }
+                                 requestCredentialsUpdate();
+                             } catch (AccountNotFoundException e) {
+                                 Log_OC.e(TAG, "Account " + getAccount() + " was removed!", e);
                              }
-                             
-                             requestCredentialsUpdate();
-                             
                          }
                      }
                      removeStickyBroadcast(intent);
  
  
      /**
-      * Class waiting for broadcast events from the {@link FielDownloader} service.
+      * Class waiting for broadcast events from the {@link FileDownloader} service.
       * 
       * Updates the UI when a download is started or finished, provided that it is relevant for the
       * current folder.
       */
      private class DownloadFinishReceiver extends BroadcastReceiver {
+         //int refreshCounter = 0;
          @Override
          public void onReceive(Context context, Intent intent) {
              try {
                  boolean sameAccount = isSameAccount(context, intent);
                  String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
                  boolean isDescendant = isDescendant(downloadedRemotePath);
-     
                  if (sameAccount && isDescendant) {
-                     refreshListOfFilesFragment();
-                     refreshSecondFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
+                     String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
+                     if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
+                         //Log_OC.v(TAG, "refresh #" + ++refreshCounter);
+                         refreshListOfFilesFragment();
+                     }
+                     refreshSecondFragment(
+                             intent.getAction(),
+                             downloadedRemotePath,
+                             intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
+                     );
                  }
      
                  if (mWaitingToSend != null) {
-                     mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
+                     mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
                      if (mWaitingToSend.isDown()) { 
                          sendDownloadedFile();
                      }
  
          private boolean isDescendant(String downloadedRemotePath) {
              OCFile currentDir = getCurrentDir();
-             return (currentDir != null && downloadedRemotePath != null && downloadedRemotePath.startsWith(currentDir.getRemotePath()));
+             return (
+                 currentDir != null &&
+                 downloadedRemotePath != null &&
+                 downloadedRemotePath.startsWith(currentDir.getRemotePath())
+             );
+         }
+         private boolean isAscendant(String linkedToRemotePath) {
+             OCFile currentDir = getCurrentDir();
+             return (
+                 currentDir != null &&
+                 currentDir.getRemotePath().startsWith(linkedToRemotePath)
+             );
          }
  
          private boolean isSameAccount(Context context, Intent intent) {
       * TODO
       */
      private void updateNavigationElementsInActionBar(OCFile chosenFile) {
-         ActionBar actionBar = getSupportActionBar(); 
+         ActionBar actionBar = getSupportActionBar();
+         // For adding content description tag to a title field in the action bar
+         int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
          if (chosenFile == null || mDualPane) {
              // only list of files - set for browsing through folders
              OCFile currentDir = getCurrentDir();
              actionBar.setDisplayShowTitleEnabled(!noRoot); 
              if (!noRoot) {
                  actionBar.setTitle(getString(R.string.default_display_name_for_root_folder));
+                 View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+                 if (actionBarTitleView != null) {    // it's null in Android 2.x
+                     actionBarTitleView.setContentDescription(getString(R.string.default_display_name_for_root_folder));
+                 }
              }
              actionBar.setNavigationMode(!noRoot ? ActionBar.NAVIGATION_MODE_STANDARD : ActionBar.NAVIGATION_MODE_LIST);
              actionBar.setListNavigationCallbacks(mDirectories, this);   // assuming mDirectories is updated
              actionBar.setDisplayShowTitleEnabled(true);
              actionBar.setTitle(chosenFile.getFileName());
              actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+             View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+             if (actionBarTitleView != null) {    // it's null in Android 2.x
+                 getWindow().getDecorView().findViewById(actionBarTitleId).
+                         setContentDescription(chosenFile.getFileName());
+             }
          }
      }
  
          }
      };    
  
 -
 -
 -    /**
 -     * Launch an intent to request the PIN code to the user before letting him use the app
 -     */
 -    private void requestPinCode() {
 -        boolean pinStart = false;
 -        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
 -        pinStart = appPrefs.getBoolean("set_pincode", false);
 -        if (pinStart) {
 -            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
 -            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
 -            startActivity(i);
 -        }
 -    }
 -
 -
      @Override
      public void onSavedCertificate() {
          startSyncFolderOperation(getCurrentDir(), false);
  
      @Override
      public void onFailedSavingCertificate() {
-         showDialog(DIALOG_CERT_NOT_SAVED);
+         ConfirmationDialogFragment dialog = ConfirmationDialogFragment.newInstance(
+                 R.string.ssl_validator_not_saved, new String[]{}, R.string.common_ok, -1, -1
+         );
+         dialog.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED);
      }
  
      @Override
  
      private void requestForDownload() {
          Account account = getAccount();
+         //if (!mWaitingToPreview.isDownloading()) {
          if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
              Intent i = new Intent(this, FileDownloader.class);
              i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
              if (file.isFolder()) {
                  return file;
              } else if (getStorageManager() != null) {
-                 String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
+                 String parentPath = file.getRemotePath().substring(0,
+                         file.getRemotePath().lastIndexOf(file.getFileName()));
                  return getStorageManager().getFileByPath(parentPath);
              }
          }
          mSyncInProgress = true;
                  
          // perform folder synchronization
-         RemoteOperation synchFolderOp = new SynchronizeFolderOperation( folder,  
+         RemoteOperation synchFolderOp = new RefreshFolderOperation( folder,
                                                                          currentSyncTime, 
                                                                          false,
                                                                          getFileOperationsHelper().isSharedSupported(),
                                                                          getAccount(), 
                                                                          getApplicationContext()
                                                                        );
-         synchFolderOp.execute(getAccount(), this, null, null);
+         synchFolderOp.execute(getAccount(), MainApp.getAppContext(), this, null, null);
          
          setSupportProgressBarIndeterminateVisibility(true);
  
       */
      public void showUntrustedCertDialog(RemoteOperationResult result) {
          // Show a dialog with the certificate info
-         SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException());
+         SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError(
+                 (CertificateCombinedException)result.getException());
          FragmentManager fm = getSupportFragmentManager();
          FragmentTransaction ft = fm.beginTransaction();
          dialog.show(ft, DIALOG_UNTRUSTED_CERT);
      
      private void requestForDownload(OCFile file) {
          Account account = getAccount();
-         if (!mDownloaderBinder.isDownloading(account, file)) {
+         if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
              Intent i = new Intent(this, FileDownloader.class);
              i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
              i.putExtra(FileDownloader.EXTRA_FILE, file);
      private void sortByName(boolean ascending){
          getListOfFilesFragment().sortByName(ascending);
      }
  }
@@@ -1,5 -1,8 +1,8 @@@
- /* ownCloud Android client application
+ /**
+  *   ownCloud Android client application
+  *
   *   Copyright (C) 2011 Bartek Przybylski
+  *   Copyright (C) 2015 ownCloud Inc.
   *
   *   This program is free software: you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License version 2,
@@@ -18,6 -21,13 +21,6 @@@ package com.owncloud.android.ui.activit
  
  import java.util.Arrays;
  
 -import com.actionbarsherlock.app.ActionBar;
 -import com.actionbarsherlock.app.SherlockFragmentActivity;
 -import com.owncloud.android.R;
 -import com.owncloud.android.utils.DisplayUtils;
 -
 -import android.app.AlertDialog;
 -import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.SharedPreferences;
  import android.os.Bundle;
@@@ -32,13 -42,6 +35,13 @@@ import android.view.View.OnKeyListener
  import android.widget.Button;
  import android.widget.EditText;
  import android.widget.TextView;
 +import android.widget.Toast;
 +
 +import com.actionbarsherlock.app.ActionBar;
 +import com.actionbarsherlock.app.SherlockFragmentActivity;
 +import com.owncloud.android.R;
 +import com.owncloud.android.authentication.PinCheck;
 +import com.owncloud.android.utils.DisplayUtils;
  
  public class PinCodeActivity extends SherlockFragmentActivity {
  
                      }
                      
                      if (mPinCodeChecked && 
 -                            ( mActivity.equals("FileDisplayActivity") || mActivity.equals("PreviewImageActivity") ) ){
 +                       (mActivity.equals("FileDisplayActivity") || mActivity.equals("PreviewImageActivity") || mActivity.equals("ownCloudUploader"))){
 +                        PinCheck.setUnlockTimestamp();
                          finish();
                      } else if (mPinCodeChecked){
 +                        PinCheck.setUnlockTimestamp();
                          
                          Intent intent = getIntent();
                          String newState = intent.getStringExtra(EXTRA_NEW_STATE);
          
          }else {
              Arrays.fill(mTempText, null);
 -            AlertDialog aDialog = new AlertDialog.Builder(this).create();
              CharSequence errorSeq = getString(R.string.common_error);
 -            aDialog.setTitle(errorSeq);
 -            CharSequence cseq = getString(R.string.pincode_wrong);
 -            aDialog.setMessage(cseq);
 -            CharSequence okSeq = getString(R.string.common_ok);
 -            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
 -
 -                @Override
 -                public void onClick(DialogInterface dialog, int which) {
 -                   return; 
 -                }
 -                
 -            });
 -            aDialog.show();
 +            Toast.makeText(this, errorSeq, Toast.LENGTH_LONG).show();
 +            
              clearBoxes(); 
              mPinHdr.setText(R.string.pincode_enter_pin_code);
              mPinHdrExplanation.setVisibility(View.INVISIBLE);
              savePincodeAndExit();
              
          } else {
 -            
              Arrays.fill(mTempText, null);
 -            AlertDialog aDialog = new AlertDialog.Builder(this).create();
 -            CharSequence errorSeq = getString(R.string.common_error);
 -            aDialog.setTitle(errorSeq);
              CharSequence cseq = getString(R.string.pincode_mismatch);
 -            aDialog.setMessage(cseq);
 -            CharSequence okSeq = getString(R.string.common_ok);
 -            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
 -
 -                @Override
 -                public void onClick(DialogInterface dialog, int which) {
 -                   return; 
 -                }
 -                
 -            });
 -            aDialog.show();
 +            Toast.makeText(this, cseq, Toast.LENGTH_LONG).show();
 +            
              mPinHdr.setText(R.string.pincode_configure_your_pin);
              mPinHdrExplanation.setVisibility(View.VISIBLE);
              clearBoxes();
     
      
      protected void pinCodeEnd(boolean state){
 -        AlertDialog aDialog = new AlertDialog.Builder(this).create();
 -        
 +        CharSequence cseq;
          if (state){
 -            CharSequence saveSeq = getString(R.string.common_save_exit);
 -            aDialog.setTitle(saveSeq);
 -            CharSequence cseq = getString(R.string.pincode_stored);
 -            aDialog.setMessage(cseq);
 -            
 +           cseq = getString(R.string.pincode_stored);
          }else{
 -            CharSequence saveSeq = getString(R.string.common_save_exit);
 -            aDialog.setTitle(saveSeq);
 -            CharSequence cseq = getString(R.string.pincode_removed);
 -            aDialog.setMessage(cseq);
 -            
 +             cseq = getString(R.string.pincode_removed);
          }
 -        CharSequence okSeq = getString(R.string.common_ok);
 -        aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
 -
 -            @Override
 -            public void onClick(DialogInterface dialog, int which) {
 -                finish();
 -                return; 
 -            }
 -            
 -        });
 -        aDialog.show(); 
 +        
 +        Toast.makeText(this, cseq, Toast.LENGTH_LONG).show();
 +        finish();
      }
      
      protected void savePincodeAndExit(){
          appPrefs.commit();
          
          pinCodeEnd(true);
 -        
 -        
 -        
      }
      
      
      protected void clearBoxes(){
 -        
          mText1.setText("");
          mText2.setText("");
          mText3.setText("");
      @Override
      public boolean onKeyDown(int keyCode, KeyEvent event){
          if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
 -            
              if (mActivity.equals("preferences")){
                  SharedPreferences.Editor appPrefsE = PreferenceManager
              
                  finish();
              }
              return true; 
 -            
          }
 -        
          return super.onKeyDown(keyCode, event);
 -    }
 -    
 -   
 -
 -    
 -            
 +    }     
  }
@@@ -1,6 -1,10 +1,10 @@@
- /* ownCloud Android client application
+ /**
+  *   ownCloud Android client application
+  *
+  *   @author Bartek Przybylski
+  *   @author David A. Velasco
   *   Copyright (C) 2011  Bartek Przybylski
-  *   Copyright (C) 2012-2013 ownCloud Inc.
+  *   Copyright (C) 2015 ownCloud Inc.
   *
   *   This program is free software: you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License version 2,
@@@ -21,13 -25,17 +25,17 @@@ import android.accounts.Account
  import android.accounts.AccountManager;
  import android.accounts.AccountManagerCallback;
  import android.accounts.AccountManagerFuture;
+ import android.content.ComponentName;
+ import android.content.Context;
  import android.content.Intent;
+ import android.content.ServiceConnection;
  import android.content.SharedPreferences;
  import android.content.pm.PackageInfo;
  import android.content.pm.PackageManager.NameNotFoundException;
  import android.net.Uri;
  import android.os.Bundle;
  import android.os.Handler;
+ import android.os.IBinder;
  import android.preference.CheckBoxPreference;
  import android.preference.Preference;
  import android.preference.Preference.OnPreferenceChangeListener;
@@@ -50,21 -58,25 +58,24 @@@ import com.owncloud.android.MainApp
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountUtils;
  import com.owncloud.android.authentication.AuthenticatorActivity;
 +import com.owncloud.android.authentication.PinCheck;
+ import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.db.DbHandler;
+ import com.owncloud.android.files.FileOperationsHelper;
+ import com.owncloud.android.files.services.FileDownloader;
+ import com.owncloud.android.files.services.FileUploader;
  import com.owncloud.android.lib.common.utils.Log_OC;
+ import com.owncloud.android.services.OperationsService;
  import com.owncloud.android.ui.RadioButtonPreference;
  import com.owncloud.android.utils.DisplayUtils;
  
 -import java.io.File;
 -
  
  /**
   * An Activity that allows the user to change the application's settings.
-  * 
-  * @author Bartek Przybylski
-  * @author David A. Velasco
   */
- public class Preferences extends SherlockPreferenceActivity implements AccountManagerCallback<Boolean> {
+ public class Preferences extends SherlockPreferenceActivity
+         implements AccountManagerCallback<Boolean>, ComponentsGetter {
      
      private static final String TAG = "OwnCloudPreferences";
  
      private String mAccountName;
      private boolean mShowContextMenu = false;
      private String mUploadPath;
+     private PreferenceCategory mPrefInstantUploadCategory;
+     private Preference mPrefInstantUpload;
      private Preference mPrefInstantUploadPath;
+     private Preference mPrefInstantUploadPathWiFi;
+     private Preference mPrefInstantVideoUpload;
      private Preference mPrefInstantVideoUploadPath;
+     private Preference mPrefInstantVideoUploadPathWiFi;
      private String mUploadVideoPath;
  
+     protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
+     protected FileUploader.FileUploaderBinder mUploaderBinder = null;
+     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
  
      @SuppressWarnings("deprecation")
      @Override
          actionBar.setDisplayHomeAsUpEnabled(true);
          actionBar.setTitle(R.string.actionbar_settings);
  
+         // For adding content description tag to a title field in the action bar
+         int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
+         View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+         if (actionBarTitleView != null) {    // it's null in Android 2.x
+             getWindow().getDecorView().findViewById(actionBarTitleId).
+                     setContentDescription(getString(R.string.actionbar_settings));
+         }
          // Load the accounts category for adding the list of accounts
          mAccountsPrefCategory = (PreferenceCategory) findPreference("accounts_category");
  
                          String username = currentAccount.name.substring(0, currentAccount.name.lastIndexOf('@'));
                          
                          String recommendSubject = String.format(getString(R.string.recommend_subject), appName);
-                         String recommendText = String.format(getString(R.string.recommend_text), appName, downloadUrl, username);
+                         String recommendText = String.format(getString(R.string.recommend_text),
+                                 appName, downloadUrl, username);
                          
                          intent.putExtra(Intent.EXTRA_SUBJECT, recommendSubject);
                          intent.putExtra(Intent.EXTRA_TEXT, recommendText);
                          startActivity(intent);
  
                          return(true);
  
                      }
                      }
                  });
          }
+         
+         mPrefInstantUploadCategory = (PreferenceCategory) findPreference("instant_uploading_category");
+         
+         mPrefInstantUploadPathWiFi =  findPreference("instant_upload_on_wifi");
+         mPrefInstantUpload = findPreference("instant_uploading");
+         
+         toggleInstantPictureOptions(((CheckBoxPreference) mPrefInstantUpload).isChecked());
+         
+         mPrefInstantUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+             
+             @Override
+             public boolean onPreferenceChange(Preference preference, Object newValue) {
+                 toggleInstantPictureOptions((Boolean) newValue);
+                 return true;
+             }
+         });
+        
          mPrefInstantVideoUploadPath =  findPreference("instant_video_upload_path");
          if (mPrefInstantVideoUploadPath != null){
  
                      }
                  });
          }
+         
+         mPrefInstantVideoUploadPathWiFi =  findPreference("instant_video_upload_on_wifi");
+         mPrefInstantVideoUpload = findPreference("instant_video_uploading");
+         toggleInstantVideoOptions(((CheckBoxPreference) mPrefInstantVideoUpload).isChecked());
+         
+         mPrefInstantVideoUpload.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+             
+             @Override
+             public boolean onPreferenceChange(Preference preference, Object newValue) {
+                 toggleInstantVideoOptions((Boolean) newValue);
+                 return true;
+             }
+         });
              
          /* About App */
         pAboutApp = (Preference) findPreference("about_app");
         loadInstantUploadPath();
         loadInstantUploadVideoPath();
  
+         /* ComponentsGetter */
+         mDownloadServiceConnection = newTransferenceServiceConnection();
+         if (mDownloadServiceConnection != null) {
+             bindService(new Intent(this, FileDownloader.class), mDownloadServiceConnection,
+                     Context.BIND_AUTO_CREATE);
+         }
+         mUploadServiceConnection = newTransferenceServiceConnection();
+         if (mUploadServiceConnection != null) {
+             bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
+                     Context.BIND_AUTO_CREATE);
+         }
+     }
+     
+     private void toggleInstantPictureOptions(Boolean value){
+         if (value){
+             mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPathWiFi);
+             mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPath);
+         } else {
+             mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPathWiFi);
+             mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPath);
+         }
+     }
+     
+     private void toggleInstantVideoOptions(Boolean value){
+         if (value){
+             mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPathWiFi);
+             mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPath);
+         } else {
+             mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPathWiFi);
+             mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPath);
+         }
      }
  
      @Override
      protected void onPause() {
          super.onPause();
 +        
 +        PinCheck.setUnlockTimestamp();
      }
  
      @Override
  
                      // Remove account
                      am.removeAccount(a, this, mHandler);
+                     Log_OC.d(TAG, "Remove an account " + a.name);
                  }
              }
          }
      @Override
      public void run(AccountManagerFuture<Boolean> future) {
          if (future.isDone()) {
+             // after remove account
+             Account account = new Account(mAccountName, MainApp.getAccountType());
+             if (!AccountUtils.exists(account, MainApp.getAppContext())) {
+                 // Cancel tranfers
+                 if (mUploaderBinder != null) {
+                     mUploaderBinder.cancel(account);
+                 }
+                 if (mDownloaderBinder != null) {
+                     mDownloaderBinder.cancel(account);
+                 }
+             }
              Account a = AccountUtils.getCurrentOwnCloudAccount(this);
              String accountName = "";
              if (a == null) {
      @Override
      protected void onDestroy() {
          mDbHandler.close();
+         if (mDownloadServiceConnection != null) {
+             unbindService(mDownloadServiceConnection);
+             mDownloadServiceConnection = null;
+         }
+         if (mUploadServiceConnection != null) {
+             unbindService(mUploadServiceConnection);
+             mUploadServiceConnection = null;
+         }
          super.onDestroy();
      }
  
                                              FileDisplayActivity.class
                                      );
                                      i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                                     i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                                      startActivity(i);
                                  } else {
                                      finish();
          editor.putString("instant_video_upload_path", mUploadVideoPath);
          editor.commit();
      }
+     // Methods for ComponetsGetter
+     @Override
+     public FileDownloader.FileDownloaderBinder getFileDownloaderBinder() {
+         return mDownloaderBinder;
+     }
+     @Override
+     public FileUploader.FileUploaderBinder getFileUploaderBinder() {
+         return mUploaderBinder;
+     }
+     @Override
+     public OperationsService.OperationsServiceBinder getOperationsServiceBinder() {
+         return null;
+     }
+     @Override
+     public FileDataStorageManager getStorageManager() {
+         return null;
+     }
+     @Override
+     public FileOperationsHelper getFileOperationsHelper() {
+         return null;
+     }
+     protected ServiceConnection newTransferenceServiceConnection() {
+         return new PreferencesServiceConnection();
+     }
+     /** Defines callbacks for service binding, passed to bindService() */
+     private class PreferencesServiceConnection implements ServiceConnection {
+         @Override
+         public void onServiceConnected(ComponentName component, IBinder service) {
+             if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
+                 mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
+             } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
+                 Log_OC.d(TAG, "Upload service connected");
+                 mUploaderBinder = (FileUploader.FileUploaderBinder) service;
+             } else {
+                 return;
+             }
+         }
+         @Override
+         public void onServiceDisconnected(ComponentName component) {
+             if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
+                 Log_OC.d(TAG, "Download service suddenly disconnected");
+                 mDownloaderBinder = null;
+             } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
+                 Log_OC.d(TAG, "Upload service suddenly disconnected");
+                 mUploaderBinder = null;
+             }
+         }
+     };
  }
@@@ -1,6 -1,9 +1,9 @@@
- /* ownCloud Android client application
+ /**
+  *   ownCloud Android client application
+  *
+  *   @author Bartek Przybylski
   *   Copyright (C) 2012  Bartek Przybylski
-  *   Copyright (C) 2012-2013 ownCloud Inc.
+  *   Copyright (C) 2015 ownCloud Inc.
   *
   *   This program is free software: you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License version 2,
@@@ -38,6 -41,7 +41,7 @@@ import android.content.DialogInterface.
  import android.content.DialogInterface.OnClickListener;
  import android.content.Intent;
  import android.content.SharedPreferences;
+ import android.content.res.Resources.NotFoundException;
  import android.database.Cursor;
  import android.net.Uri;
  import android.os.Bundle;
@@@ -51,40 -55,42 +55,44 @@@ import android.widget.AdapterView
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.Button;
  import android.widget.EditText;
+ import android.widget.ListView;
  import android.widget.SimpleAdapter;
  import android.widget.Toast;
  
  import com.actionbarsherlock.app.ActionBar;
- import com.actionbarsherlock.app.SherlockListActivity;
  import com.actionbarsherlock.view.MenuItem;
  import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountAuthenticator;
 +import com.owncloud.android.authentication.PinCheck;
 +import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.files.services.FileUploader;
+ import com.owncloud.android.lib.common.operations.RemoteOperation;
+ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  import com.owncloud.android.lib.common.utils.Log_OC;
+ import com.owncloud.android.operations.CreateFolderOperation;
+ import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
  import com.owncloud.android.utils.DisplayUtils;
+ import com.owncloud.android.utils.ErrorMessageAdapter;
  
  /**
   * This can be used to upload things to an ownCloud instance.
-  * 
-  * @author Bartek Przybylski
-  * 
   */
- public class Uploader extends SherlockListActivity implements OnItemClickListener, android.view.View.OnClickListener {
-     private static final String TAG = "ownCloudUploader";
+ public class Uploader extends FileActivity
+         implements OnItemClickListener, android.view.View.OnClickListener {
+     private static final String TAG = Uploader.class.getSimpleName();
  
-     private Account mAccount;
      private AccountManager mAccountManager;
      private Stack<String> mParents;
      private ArrayList<Parcelable> mStreamsToUpload;
      private boolean mCreateDir;
      private String mUploadPath;
-     private FileDataStorageManager mStorageManager;
      private OCFile mFile;
+     private boolean mAccountSelected;
+     
      private final static int DIALOG_NO_ACCOUNT = 0;
      private final static int DIALOG_WAITING = 1;
      private final static int DIALOG_NO_STREAM = 2;
  
      private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
  
+     private final static String KEY_PARENTS = "PARENTS";
+     private final static String KEY_FILE = "FILE";
+     private final static String KEY_ACCOUNT_SELECTED = "ACCOUNT_SELECTED";
      @Override
      protected void onCreate(Bundle savedInstanceState) {
+         prepareStreamsToUpload();
+         if (savedInstanceState == null) {
+             mParents = new Stack<String>();
+             mAccountSelected = false;
+         } else {
+             mParents = (Stack<String>) savedInstanceState.getSerializable(KEY_PARENTS);
+             mFile = savedInstanceState.getParcelable(KEY_FILE);
+             mAccountSelected = savedInstanceState.getBoolean(KEY_ACCOUNT_SELECTED);
+         }
          super.onCreate(savedInstanceState);
-         mParents = new Stack<String>();
-         
 +        // Check Pin entry
 +        if (PinCheck.checkIfPinEntry()){
 +            Intent i = new Intent(MainApp.getAppContext(), PinCodeActivity.class);
 +            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "ownCloudUploader");
 +            startActivity(i);
 +        }
 +        
          ActionBar actionBar = getSupportActionBar();
          actionBar.setIcon(DisplayUtils.getSeasonalIconId());
  
-         if (prepareStreamsToUpload()) {
+     }
+     @Override
+     protected void setAccount(Account account, boolean savedAccount) {
+         if (somethingToUpload()) {
              mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
              Account[] accounts = mAccountManager.getAccountsByType(MainApp.getAccountType());
              if (accounts.length == 0) {
                  Log_OC.i(TAG, "No ownCloud account is available");
                  showDialog(DIALOG_NO_ACCOUNT);
-             } else if (accounts.length > 1) {
-                 Log_OC.i(TAG, "More then one ownCloud is available");
+             } else if (accounts.length > 1 && !mAccountSelected) {
+                 Log_OC.i(TAG, "More than one ownCloud is available");
                  showDialog(DIALOG_MULTIPLE_ACCOUNT);
              } else {
-                 mAccount = accounts[0];
-                 mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
-                 initTargetFolder();
-                 populateDirectoryList();
-                 
+                 if (!savedAccount) {
+                     setAccount(accounts[0]);
+                 }
              }
-             
          } else {
              showDialog(DIALOG_NO_STREAM);
          }
+         super.setAccount(account, savedAccount);
      }
-     
+     @Override
+     protected void onAccountSet(boolean stateWasRecovered) {
+         super.onAccountSet(mAccountWasRestored);
+         initTargetFolder();
+         populateDirectoryList();
+     }
+     @Override
+     protected void onSaveInstanceState(Bundle outState) {
+          Log_OC.d(TAG, "onSaveInstanceState() start");
+         super.onSaveInstanceState(outState);
+         outState.putSerializable(KEY_PARENTS, mParents);
+         //outState.putParcelable(KEY_ACCOUNT, mAccount);
+         outState.putParcelable(KEY_FILE, mFile);
+         outState.putBoolean(KEY_ACCOUNT_SELECTED, mAccountSelected);
+         Log_OC.d(TAG, "onSaveInstanceState() end");
+     }
      @Override
      protected Dialog onCreateDialog(final int id) {
          final AlertDialog.Builder builder = new Builder(this);
          case DIALOG_NO_ACCOUNT:
              builder.setIcon(android.R.drawable.ic_dialog_alert);
              builder.setTitle(R.string.uploader_wrn_no_account_title);
-             builder.setMessage(String.format(getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
+             builder.setMessage(String.format(
+                     getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
              builder.setCancelable(false);
              builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
                  @Override
              });
              return builder.create();
          case DIALOG_MULTIPLE_ACCOUNT:
-             CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(MainApp.getAccountType()).length];
+             CharSequence ac[] = new CharSequence[
+                     mAccountManager.getAccountsByType(MainApp.getAccountType()).length];
              for (int i = 0; i < ac.length; ++i) {
-                 ac[i] = DisplayUtils.convertIdn(mAccountManager.getAccountsByType(MainApp.getAccountType())[i].name, false);
+                 ac[i] = DisplayUtils.convertIdn(
+                         mAccountManager.getAccountsByType(MainApp.getAccountType())[i].name, false);
              }
              builder.setTitle(R.string.common_choose_account);
              builder.setItems(ac, new OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
-                     mAccount = mAccountManager.getAccountsByType(MainApp.getAccountType())[which];
-                     mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
-                     initTargetFolder();
-                     populateDirectoryList();
+                     setAccount(mAccountManager.getAccountsByType(MainApp.getAccountType())[which]);
+                     onAccountSet(mAccountWasRestored);
+                     dialog.dismiss();
+                     mAccountSelected = true;
                  }
              });
              builder.setCancelable(true);
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
          // click on folder in the list
          Log_OC.d(TAG, "on item click");
-         Vector<OCFile> tmpfiles = mStorageManager.getFolderContent(mFile);
+         Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile);
          if (tmpfiles.size() <= 0) return;
          // filter on dirtype
          Vector<OCFile> files = new Vector<OCFile>();
          // click on button
          switch (v.getId()) {
          case R.id.uploader_choose_folder:
-             mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
+             mUploadPath = "";   // first element in mParents is root dir, represented by "";
+                                 // init mUploadPath with "/" results in a "//" prefix
              for (String p : mParents)
                  mUploadPath += p + OCFile.PATH_SEPARATOR;
              Log_OC.d(TAG, "Uploading file to dir " + mUploadPath);
              uploadFiles();
  
              break;
+             
+         case R.id.uploader_new_folder:
+             CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile);
+             dialog.show(getSupportFragmentManager(), "createdirdialog");
+             break;
+             
+             
          default:
              throw new IllegalArgumentException("Wrong element clicked");
          }
                  // there is no need for checking for is there more then one
                  // account at this point
                  // since account setup can set only one account at time
-                 mAccount = accounts[0];
+                 setAccount(accounts[0]);
                  populateDirectoryList();
              }
          }
  
      private void populateDirectoryList() {
          setContentView(R.layout.uploader_layout);
+         
+         ListView mListView = (ListView) findViewById(android.R.id.list);
  
          String current_dir = mParents.peek();
          if(current_dir.equals("")){
          
          Log_OC.d(TAG, "Populating view with content of : " + full_path);
  
-         mFile = mStorageManager.getFileByPath(full_path);
+         mFile = getStorageManager().getFileByPath(full_path);
          if (mFile != null) {
-             Vector<OCFile> files = mStorageManager.getFolderContent(mFile);
+             Vector<OCFile> files = getStorageManager().getFolderContent(mFile);
              List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
              for (OCFile f : files) {
                  HashMap<String, Object> h = new HashMap<String, Object>();
                                                  R.layout.uploader_list_item_layout,
                                                  new String[] {"dirname"},
                                                  new int[] {R.id.textView1});
-             setListAdapter(sa);
-             Button btn = (Button) findViewById(R.id.uploader_choose_folder);
-             btn.setOnClickListener(this);
-             getListView().setOnItemClickListener(this);
+             
+             mListView.setAdapter(sa);
+             Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
+             btnChooseFolder.setOnClickListener(this);
+             
+             Button btnNewFolder = (Button) findViewById(R.id.uploader_new_folder);
+             btnNewFolder.setOnClickListener(this);
+             
+             mListView.setOnItemClickListener(this);
          }
      }
  
          return full_path;
      }
  
-     private boolean prepareStreamsToUpload() {
+     private void prepareStreamsToUpload() {
          if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
              mStreamsToUpload = new ArrayList<Parcelable>();
              mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
          } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
              mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
          }
+     }
+     private boolean somethingToUpload() {
          return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null);
      }
  
                         String mimeType = getContentResolver().getType(uri);
                         
                         if (mimeType.contains("image")) {
-                            String[] CONTENT_PROJECTION = { Images.Media.DATA, Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE, Images.Media.SIZE};
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                            String[] CONTENT_PROJECTION = { Images.Media.DATA,
+                                    Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE,
+                                    Images.Media.SIZE};
+                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                    null, null);
                             c.moveToFirst();
                             int index = c.getColumnIndex(Images.Media.DATA);
                             String data = c.getString(index);
                             local.add(data);
-                            remote.add(mUploadPath + c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
+                            remote.add(mUploadPath +
+                                    c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
                         
                         }
                         else if (mimeType.contains("video")) {
-                            String[] CONTENT_PROJECTION = { Video.Media.DATA, Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE, Video.Media.SIZE, Video.Media.DATE_MODIFIED };
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                            String[] CONTENT_PROJECTION = { Video.Media.DATA,
+                                    Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
+                                    Video.Media.SIZE, Video.Media.DATE_MODIFIED };
+                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                    null, null);
                             c.moveToFirst();
                             int index = c.getColumnIndex(Video.Media.DATA);
                             String data = c.getString(index);
                             local.add(data);
-                            remote.add(mUploadPath + c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
+                            remote.add(mUploadPath +
+                                    c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
                            
                         }
                         else if (mimeType.contains("audio")) {
-                            String[] CONTENT_PROJECTION = { Audio.Media.DATA, Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE, Audio.Media.SIZE };
-                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                            String[] CONTENT_PROJECTION = { Audio.Media.DATA,
+                                    Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE,
+                                    Audio.Media.SIZE };
+                            Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                    null, null);
                             c.moveToFirst();
                             int index = c.getColumnIndex(Audio.Media.DATA);
                             String data = c.getString(index);
                             local.add(data);
-                            remote.add(mUploadPath + c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
+                            remote.add(mUploadPath +
+                                    c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
                          
                         }
                         else {
-                            String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
-                            // cut everything whats before mnt. It occured to me that sometimes apps send their name into the URI
+                            String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
+                                    "://", "");
+                            // cut everything whats before mnt. It occurred to me that sometimes
+                            // apps send their name into the URI
                             if (filePath.contains("mnt")) {
                                String splitedFilePath[] = filePath.split("/mnt");
                                filePath = splitedFilePath[1];
                         }
                          
                      } else if (uri.getScheme().equals("file")) {
-                         String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
+                         String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
+                                 "://", "");
                          if (filePath.contains("mnt")) {
                             String splitedFilePath[] = filePath.split("/mnt");
                             filePath = splitedFilePath[1];
              Intent intent = new Intent(getApplicationContext(), FileUploader.class);
              intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
              intent.putExtra(FileUploader.KEY_LOCAL_FILE, local.toArray(new String[local.size()]));
-             intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote.toArray(new String[remote.size()]));
-             intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
+             intent.putExtra(FileUploader.KEY_REMOTE_FILE,
+                     remote.toArray(new String[remote.size()]));
+             intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
              startService(intent);
  
              //Save the path to shared preferences
              }
              
          } catch (SecurityException e) {
-             String message = String.format(getString(R.string.uploader_error_forbidden_content), getString(R.string.app_name));
+             String message = String.format(getString(R.string.uploader_error_forbidden_content),
+                     getString(R.string.app_name));
              Toast.makeText(this, message, Toast.LENGTH_LONG).show();            
          }
      }
      
+     @Override
+     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+         super.onRemoteOperationFinish(operation, result);
+         
+       
+         if (operation instanceof CreateFolderOperation) {
+             onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
+         }
+         
+     }
+     
+     /**
+      * Updates the view associated to the activity after the finish of an operation
+      * trying create a new folder
+      * 
+      * @param operation     Creation operation performed.
+      * @param result        Result of the creation.
+      */
+     private void onCreateFolderOperationFinish(CreateFolderOperation operation,
+                                                RemoteOperationResult result) {
+         if (result.isSuccess()) {
+             dismissLoadingDialog();
+             populateDirectoryList();
+         } else {
+             dismissLoadingDialog();
+             try {
+                 Toast msg = Toast.makeText(this, 
+                         ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
+                         Toast.LENGTH_LONG); 
+                 msg.show();
+             } catch (NotFoundException e) {
+                 Log_OC.e(TAG, "Error while trying to show fail message " , e);
+             }
+         }
+     }
+     
+     
      /**
       *  Loads the target folder initialize shown to the user.
       * 
       *  The target account has to be chosen before this method is called. 
       */
      private void initTargetFolder() {
-         if (mStorageManager == null) {
-             throw new IllegalStateException("Do not call this method before initializing mStorageManager");
+         if (getStorageManager() == null) {
+             throw new IllegalStateException("Do not call this method before " +
+                     "initializing mStorageManager");
          }
          
          SharedPreferences appPreferences = PreferenceManager
                  mParents.add(dir);
          }
          //Make sure that path still exists, if it doesn't pop the stack and try the previous path
-             while(!mStorageManager.fileExists(generatePath(mParents)) && mParents.size() > 1){
+             while(!getStorageManager().fileExists(generatePath(mParents)) && mParents.size() > 1){
                  mParents.pop();
              }
      }
@@@ -1,5 -1,8 +1,8 @@@
- /* ownCloud Android client application
-  *   Copyright (C) 2012-2013  ownCloud Inc.
+ /**
+  *   ownCloud Android client application
+  *
+  *   @author David A. Velasco
+  *   Copyright (C) 2015  ownCloud Inc.
   *
   *   This program is free software: you can redistribute it and/or modify
   *   it under the terms of the GNU General Public License version 2,
@@@ -23,11 -26,13 +26,11 @@@ import android.content.Context
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.content.ServiceConnection;
 -import android.content.SharedPreferences;
  import android.os.Build;
  import android.os.Bundle;
  import android.os.Handler;
  import android.os.IBinder;
  import android.os.Message;
 -import android.preference.PreferenceManager;
  import android.support.v4.view.ViewPager;
  import android.view.View;
  
@@@ -35,10 -40,8 +38,10 @@@ import com.actionbarsherlock.app.Action
  import com.actionbarsherlock.view.MenuItem;
  import com.actionbarsherlock.view.Window;
  import com.ortiz.touch.ExtendedViewPager;
 +import com.owncloud.android.MainApp;
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountUtils;
 +import com.owncloud.android.authentication.PinCheck;
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.files.services.FileDownloader;
@@@ -62,8 -65,6 +65,6 @@@ import com.owncloud.android.utils.Displ
  
  /**
   *  Holds a swiping galley where image files contained in an ownCloud directory are shown
-  *  
-  *  @author David A. Velasco
   */
  public class PreviewImageActivity extends FileActivity implements 
   FileFragment.ContainerActivity,
@@@ -89,8 -90,6 +90,8 @@@ ViewPager.OnPageChangeListener, OnRemot
      
      private View mFullScreenAnchorView;
      
 +    private Boolean mUnlocked = false;
 +    
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          actionBar.hide();
          
          // PIN CODE request
 -        if (getIntent().getExtras() != null && savedInstanceState == null && fromNotification()) {
 -            requestPinCode();
 +        if (PinCheck.checkIfPinEntry()){
 +            Intent i = new Intent(MainApp.getAppContext(), PinCodeActivity.class);
 +            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "PreviewImageActivity");
 +            startActivity(i);
          }
  
          // Make sure we're running on Honeycomb or higher to use FullScreen and
      @Override
      protected void onResume() {
          super.onResume();
 +        
 +        if (PinCheck.checkIfPinEntry()){
 +            Intent i = new Intent(MainApp.getAppContext(), PinCodeActivity.class);
 +            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "PreviewImageActivity");
 +            startActivity(i);
 +        }
 +        
          //Log_OC.e(TAG, "ACTIVITY, ONRESUME");
          mDownloadFinishReceiver = new DownloadFinishReceiver();
          
      
      @Override
      public void onPause() {
 -        unregisterReceiver(mDownloadFinishReceiver);
 -        mDownloadFinishReceiver = null;
 +        if (mDownloadFinishReceiver != null){
 +            unregisterReceiver(mDownloadFinishReceiver);
 +            mDownloadFinishReceiver = null;
 +        }
 +        
 +        PinCheck.setUnlockTimestamp();
          super.onPause();
      }
      
      
  
      /**
-      * Class waiting for broadcast events from the {@link FielDownloader} service.
+      * Class waiting for broadcast events from the {@link FileDownloader} service.
       * 
       * Updates the UI when a download is started or finished, provided that it is relevant for the
       * folder displayed in the gallery.
              }
          }
      }
 -    
 -    
 -    /**
 -     * Launch an intent to request the PIN code to the user before letting him use the app
 -     */
 -    private void requestPinCode() {
 -        boolean pinStart = false;
 -        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
 -        pinStart = appPrefs.getBoolean("set_pincode", false);
 -        if (pinStart) {
 -            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
 -            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "PreviewImageActivity");
 -            startActivity(i);
 -        }
 -    }
  
      @Override
      public void onBrowsedDownTo(OCFile folder) {
          }
          return false;
      }
 -
  }