package com.owncloud.android.ui.activity;
import java.io.File;
-import org.apache.commons.httpclient.Credentials;
+import java.io.IOException;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
-//import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
+import com.owncloud.android.BuildConfig;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileObserverService;
-import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
+import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.operations.CreateFolderOperation;
-
+import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
-import com.owncloud.android.lib.common.OwnCloudClientMap;
-import com.owncloud.android.lib.common.network.BearerCredentials;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
import com.owncloud.android.lib.common.network.CertificateCombinedException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.operations.CreateShareOperation;
+import com.owncloud.android.operations.MoveFileOperation;
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.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.CreateFolderDialogFragment;
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
import com.owncloud.android.ui.preview.PreviewVideoActivity;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ErrorMessageAdapter;
-import com.owncloud.android.utils.Log_OC;
/**
*/
public class FileDisplayActivity extends HookActivity implements
-FileFragment.ContainerActivity, OnNavigationListener, OnSslUntrustedCertListener {
-
+FileFragment.ContainerActivity, OnNavigationListener,
+OnSslUntrustedCertListener, OnEnforceableRefreshListener {
+
private ArrayAdapter<String> mDirectories;
private SyncBroadcastReceiver mSyncBroadcastReceiver;
private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
private 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 String DIALOG_UNTRUSTED_CERT;
private OCFile mWaitingToSend;
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
Log_OC.d(TAG, "onCreate() start");
requestPinCode();
}
- /// file observer
- Intent observer_intent = new Intent(this, FileObserverService.class);
- observer_intent.putExtra(FileObserverService.KEY_FILE_CMD, FileObserverService.CMD_INIT_OBSERVED_LIST);
- startService(observer_intent);
-
+ /// grant that FileObserverService is watching favourite files
+ if (savedInstanceState == null) {
+ Intent initObserversIntent = FileObserverService.makeInitIntent(this);
+ startService(initObserversIntent);
+ }
+
/// Load of saved instance state
if(savedInstanceState != null) {
mWaitingToPreview = (OCFile) savedInstanceState.getParcelable(FileDisplayActivity.KEY_WAITING_TO_PREVIEW);
getSupportActionBar().setHomeButtonEnabled(true); // mandatory since Android ICS, according to the official documentation
setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/); // always AFTER setContentView(...) ; to work around bug in its implementation
+ setBackgroundText();
+
Log_OC.d(TAG, "onCreate() end");
}
Log_OC.e(TAG, "Initializing Fragments in onAccountChanged..");
initFragmentsWithFile();
if (file.isFolder()) {
- startSyncFolderOperation(file);
+ startSyncFolderOperation(file, false);
}
} else {
if (listOfFiles != null) {
listOfFiles.listDirectory(getCurrentDir());
} else {
- Log.e(TAG, "Still have a chance to lose the initializacion of list fragment >(");
+ Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >(");
}
/// Second fragment
}
} else {
- Log.wtf(TAG, "initFragments() called with invalid NULLs!");
+ Log_OC.wtf(TAG, "initFragments() called with invalid NULLs!");
if (getAccount() == null) {
- Log.wtf(TAG, "\t account is NULL");
+ Log_OC.wtf(TAG, "\t account is NULL");
}
if (getFile() == null) {
- Log.wtf(TAG, "\t file is NULL");
+ Log_OC.wtf(TAG, "\t file is NULL");
}
}
}
}
@Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ if (BuildConfig.DEBUG) {
+ menu.findItem(R.id.action_logger).setVisible(true);
+ } else {
+ menu.findItem(R.id.action_logger).setVisible(false);
+ }
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSherlock().getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
startActivity(settingsIntent);
break;
}
+ case R.id.action_logger: {
+ Intent loggerIntent = new Intent(getApplicationContext(),LogHistoryActivity.class);
+ startActivity(loggerIntent);
+ break;
+ }
case android.R.id.home: {
FileFragment second = getSecondFragment();
OCFile currentDir = getCurrentDir();
}
break;
}
+ case R.id.action_sort: {
+ SharedPreferences appPreferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+
+ // Read sorting order, default to sort by name ascending
+ Integer sortOrder = appPreferences
+ .getInt("sortOrder", FileListListAdapter.SORT_NAME);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.actionbar_sort_title)
+ .setSingleChoiceItems(R.array.actionbar_sortby, sortOrder , new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+
+ switch (which){
+ case 0:
+ sortByName(true);
+ break;
+ case 1:
+ sortByDate(false);
+ break;
+
+// TODO re-enable when server-side folder size calculation is available
+// case 2:
+// sortBySize(false);
+// break;
+ }
+
+ dialog.dismiss();
+
+ }
+ });
+ builder.create().show();
+ break;
+ }
default:
retval = super.onOptionsItemSelected(item);
}
} else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
requestMultipleUpload(data, resultCode);
+ } else if (requestCode == ACTION_MOVE_FILES && (resultCode == RESULT_OK ||
+ resultCode == MoveActivity.RESULT_OK_AND_MOVE)){
+
+ final Intent fData = data;
+ final int fResultCode = resultCode;
+ getHandler().postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ requestMoveOperation(fData, fResultCode);
+ }
+ },
+ DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
+ );
}
}
startService(i);
}
+ /**
+ * Request the operation for moving the file/folder from one path to another
+ *
+ * @param data Intent received
+ * @param resultCode Result code received
+ */
+ private void requestMoveOperation(Intent data, int resultCode) {
+ OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(MoveActivity.EXTRA_CURRENT_FOLDER);
+ OCFile targetFile = (OCFile) data.getParcelableExtra(MoveActivity.EXTRA_TARGET_FILE);
+ getFileOperationsHelper().moveFile(folderToMoveAt, targetFile);
+ }
+
@Override
public void onBackPressed() {
OCFileListFragment listOfFiles = getListOfFilesFragment();
}
case DIALOG_CHOOSE_UPLOAD_SOURCE: {
- String[] items = null;
String[] allTheItems = { getString(R.string.actionbar_upload_files),
- getString(R.string.actionbar_upload_from_apps),
- getString(R.string.actionbar_failed_instant_upload) };
-
- String[] commonItems = { getString(R.string.actionbar_upload_files),
getString(R.string.actionbar_upload_from_apps) };
- if (InstantUploadActivity.IS_ENABLED)
- items = allTheItems;
- else
- items = commonItems;
-
builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.actionbar_upload);
- builder.setItems(items, new DialogInterface.OnClickListener() {
+ builder.setItems(allTheItems, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
// if (!mDualPane) {
action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(action, getString(R.string.upload_chooser_title)),
ACTION_SELECT_CONTENT_FROM_APPS);
- } else if (item == 2 && InstantUploadActivity.IS_ENABLED) {
- Intent action = new Intent(FileDisplayActivity.this, InstantUploadActivity.class);
- action.putExtra(FileUploader.KEY_ACCOUNT, FileDisplayActivity.this.getAccount());
- startActivity(action);
}
}
});
synchResult.isIdPRedirection() ||
(synchResult.isException() && synchResult.getException()
instanceof AuthenticatorException))) {
-
- OwnCloudClient client = OwnCloudClientMap.removeClientFor(getAccount());
+ OwnCloudClient client = null;
+ try {
+ 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) {
- Credentials cred = client.getCredentials();
- String ssoSessionCookie = client.getSsoSessionCookie();
- if (cred != null || ssoSessionCookie != null) {
- boolean bearerAuthorization = (cred != null && cred instanceof BearerCredentials);
- boolean samlBasedSsoAuthorization = (cred == null && ssoSessionCookie != null);
+ OwnCloudCredentials cred = client.getCredentials();
+ if (cred != null) {
AccountManager am = AccountManager.get(context);
-
- if (bearerAuthorization) {
- am.invalidateAuthToken(getAccount().type,
- ((BearerCredentials)cred).getAccessToken());
-
- } else if (samlBasedSsoAuthorization ) {
- am.invalidateAuthToken(getAccount().type, ssoSessionCookie);
-
+ if (cred.authTokenExpires()) {
+ am.invalidateAuthToken(
+ getAccount().type,
+ cred.getAuthToken()
+ );
} else {
am.clearPassword(getAccount());
}
removeStickyBroadcast(intent);
Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);
+
+ setBackgroundText();
}
}
}
+ /**
+ * Show a text message on screen view for notifying user if content is
+ * loading or folder is empty
+ */
+ private void setBackgroundText() {
+ OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+ if (ocFileListFragment != null) {
+ int message = R.string.file_list_loading;
+ if (!mSyncInProgress) {
+ // In case file list is empty
+ message = R.string.file_list_empty;
+ }
+ ocFileListFragment.setMessageForEmptyList(getString(message));
+ } else {
+ Log_OC.e(TAG, "OCFileListFragment is null");
+ }
+ }
/**
* Once the file upload has finished -> update view
*/
@Override
public void onReceive(Context context, Intent intent) {
- String uploadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
- String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
- boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name);
- OCFile currentDir = getCurrentDir();
- boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) &&
- (uploadedRemotePath.startsWith(currentDir.getRemotePath()));
-
- if (sameAccount && isDescendant) {
- refreshListOfFilesFragment();
- }
-
- boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
- boolean renamedInUpload = getFile().getRemotePath().
- equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH));
- boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) ||
- renamedInUpload;
- FileFragment details = getSecondFragment();
- boolean detailFragmentIsShown = (details != null &&
- details instanceof FileDetailFragment);
-
- if (sameAccount && sameFile && detailFragmentIsShown) {
- if (uploadWasFine) {
- setFile(getStorageManager().getFileByPath(uploadedRemotePath));
- }
- if (renamedInUpload) {
- String newName = (new File(uploadedRemotePath)).getName();
- Toast msg = Toast.makeText(
- context,
- String.format(
- getString(R.string.filedetails_renamed_in_upload_msg),
- newName),
- Toast.LENGTH_LONG);
- msg.show();
+ try {
+ String uploadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+ String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
+ boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name);
+ OCFile currentDir = getCurrentDir();
+ boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) &&
+ (uploadedRemotePath.startsWith(currentDir.getRemotePath()));
+
+ if (sameAccount && isDescendant) {
+ refreshListOfFilesFragment();
}
- if (uploadWasFine || getFile().fileExists()) {
- ((FileDetailFragment)details).updateFileDetails(false, true);
- } else {
- cleanSecondFragment();
+
+ boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
+ boolean renamedInUpload = getFile().getRemotePath().
+ equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH));
+ boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) ||
+ renamedInUpload;
+ FileFragment details = getSecondFragment();
+ boolean detailFragmentIsShown = (details != null &&
+ details instanceof FileDetailFragment);
+
+ if (sameAccount && sameFile && detailFragmentIsShown) {
+ if (uploadWasFine) {
+ setFile(getStorageManager().getFileByPath(uploadedRemotePath));
+ }
+ if (renamedInUpload) {
+ String newName = (new File(uploadedRemotePath)).getName();
+ Toast msg = Toast.makeText(
+ context,
+ String.format(
+ getString(R.string.filedetails_renamed_in_upload_msg),
+ newName),
+ Toast.LENGTH_LONG);
+ msg.show();
+ }
+ if (uploadWasFine || getFile().fileExists()) {
+ ((FileDetailFragment)details).updateFileDetails(false, true);
+ } else {
+ cleanSecondFragment();
+ }
+
+ // Force the preview if the file is an image
+ if (uploadWasFine && PreviewImageFragment.canBePreviewed(getFile())) {
+ startImagePreview(getFile());
+ } // TODO what about other kind of previews?
}
- // Force the preview if the file is an image
- if (uploadWasFine && PreviewImageFragment.canBePreviewed(getFile())) {
- startImagePreview(getFile());
- } // TODO what about other kind of previews?
+ } finally {
+ if (intent != null) {
+ removeStickyBroadcast(intent);
+ }
}
-
- removeStickyBroadcast(intent);
}
private class DownloadFinishReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- 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));
- }
-
- if (mWaitingToSend != null) {
- mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
- if (mWaitingToSend.isDown()) {
- sendDownloadedFile();
+ 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));
+ }
+
+ if (mWaitingToSend != null) {
+ mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
+ if (mWaitingToSend.isDown()) {
+ sendDownloadedFile();
+ }
}
- }
- removeStickyBroadcast(intent);
+ } finally {
+ if (intent != null) {
+ removeStickyBroadcast(intent);
+ }
+ }
}
private boolean isDescendant(String downloadedRemotePath) {
OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
listOfFiles.listDirectory(root);
setFile(listOfFiles.getCurrentFile());
- startSyncFolderOperation(root);
+ startSyncFolderOperation(root, false);
}
cleanSecondFragment();
}
setNavigationListWithFolder(folder);
listOfFiles.listDirectory(folder);
setFile(listOfFiles.getCurrentFile());
- startSyncFolderOperation(folder);
+ startSyncFolderOperation(folder, false);
} else {
Log_OC.e(TAG, "Unexpected null when accessing list fragment");
}
cleanSecondFragment();
// Sync Folder
- startSyncFolderOperation(directory);
+ startSyncFolderOperation(directory, false);
}
@Override
public void onSavedCertificate() {
- startSyncFolderOperation(getCurrentDir());
+ startSyncFolderOperation(getCurrentDir(), false);
}
} else if (operation instanceof UnshareLinkOperation) {
onUnshareLinkOperationFinish((UnshareLinkOperation)operation, result);
- }
+ } else if (operation instanceof MoveFileOperation) {
+ onMoveFileOperationFinish((MoveFileOperation)operation, result);
+ }
}
/**
- * Updates the view associated to the activity after the finish of an operation trying create a new folder
+ * Updates the view associated to the activity after the finish of an operation trying to move a
+ * file.
*
- * @param operation Creation operation performed.
- * @param result Result of the creation.
+ * @param operation Move operation performed.
+ * @param result Result of the move operation.
*/
- private void onCreateFolderOperationFinish(CreateFolderOperation operation, RemoteOperationResult result) {
+ private void onMoveFileOperationFinish(MoveFileOperation operation, RemoteOperationResult result) {
if (result.isSuccess()) {
dismissLoadingDialog();
refreshListOfFilesFragment();
}
}
+ /**
+ * 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();
+ refreshListOfFilesFragment();
+ } else {
+ dismissLoadingDialog();
+ try {
+ Toast msg = Toast.makeText(FileDisplayActivity.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);
+ }
+ }
+ }
+
/**
* {@inheritDoc}
return null;
}
- public void startSyncFolderOperation(OCFile folder) {
+ public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) {
long currentSyncTime = System.currentTimeMillis();
mSyncInProgress = true;
currentSyncTime,
false,
getFileOperationsHelper().isSharedSupported(),
+ ignoreETag,
getStorageManager(),
getAccount(),
getApplicationContext()
synchFolderOp.execute(getAccount(), this, null, null);
setSupportProgressBarIndeterminateVisibility(true);
+
+ setBackgroundText();
}
/**
}
onTransferStateChanged(file, false, false);
}
-
+
+ @Override
+ public void onRefresh(boolean ignoreETag) {
+ refreshList(ignoreETag);
+ }
+
+ @Override
+ public void onRefresh() {
+ refreshList(true);
+ }
+
+ private void refreshList(boolean ignoreETag) {
+ OCFileListFragment listOfFiles = getListOfFilesFragment();
+ if (listOfFiles != null) {
+ OCFile folder = listOfFiles.getCurrentFile();
+ if (folder != null) {
+ /*mFile = mContainerActivity.getStorageManager().getFileById(mFile.getFileId());
+ listDirectory(mFile);*/
+ startSyncFolderOperation(folder, ignoreETag);
+ }
+ }
+ }
+
+ private void sortByDate(boolean ascending){
+ getListOfFilesFragment().sortByDate(ascending);
+ }
+
+ private void sortBySize(boolean ascending){
+ getListOfFilesFragment().sortBySize(ascending);
+ }
+
+ private void sortByName(boolean ascending){
+ getListOfFilesFragment().sortByName(ascending);
+ }
}