import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
+import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.lib.common.OwnCloudClientFactory;
+import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
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.lib.resources.files.ExistenceCheckRemoteOperation;
import com.owncloud.android.lib.resources.shares.ShareType;
import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;
import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.operations.CreateShareOperation;
import com.owncloud.android.operations.GetServerInfoOperation;
+import com.owncloud.android.operations.MoveFileOperation;
import com.owncloud.android.operations.OAuth2GetAccessToken;
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.utils.Log_OC;
import android.accounts.Account;
import android.accounts.AccountsException;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
public static final String EXTRA_ACCOUNT = "ACCOUNT";
public static final String EXTRA_SERVER_URL = "SERVER_URL";
- public static final String EXTRA_AUTH_TOKEN_TYPE = "AUTH_TOKEN_TYPE";
public static final String EXTRA_OAUTH2_QUERY_PARAMETERS = "OAUTH2_QUERY_PARAMETERS";
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
public static final String EXTRA_SEND_INTENT = "SEND_INTENT";
public static final String EXTRA_CREATE_FULL_PATH = "CREATE_FULL_PATH";
public static final String EXTRA_SYNC_FILE_CONTENTS = "SYNC_FILE_CONTENTS";
public static final String EXTRA_RESULT = "RESULT";
+ public static final String EXTRA_NEW_PARENT_PATH = "NEW_PARENT_PATH";
// TODO review if ALL OF THEM are necessary
- public static final String EXTRA_WEBDAV_PATH = "WEBDAV_PATH";
public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT";
public static final String EXTRA_USERNAME = "USERNAME";
public static final String EXTRA_PASSWORD = "PASSWORD";
public static final String EXTRA_AUTH_TOKEN = "AUTH_TOKEN";
- public static final String EXTRA_FOLLOW_REDIRECTS = "FOLLOW_REDIRECTS";
public static final String EXTRA_COOKIE = "COOKIE";
public static final String ACTION_CREATE_SHARE = "CREATE_SHARE";
public static final String ACTION_REMOVE = "REMOVE";
public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
public static final String ACTION_SYNC_FILE = "SYNC_FILE";
+ public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER"; // for the moment, just to download
+ public static final String ACTION_MOVE_FILE = "MOVE_FILE";
public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED";
public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED";
+
private ConcurrentLinkedQueue<Pair<Target, RemoteOperation>> mPendingOperations =
new ConcurrentLinkedQueue<Pair<Target, RemoteOperation>>();
private static class Target {
public Uri mServerUrl = null;
public Account mAccount = null;
- public String mWebDavUrl = null;
public String mUsername = null;
public String mPassword = null;
public String mAuthToken = null;
- public boolean mFollowRedirects = true;
public String mCookie = null;
- public Target(Account account, Uri serverUrl, String webdavUrl, String username, String password, String authToken,
- boolean followRedirects, String cookie) {
+ public Target(Account account, Uri serverUrl, String username, String password, String authToken,
+ String cookie) {
mAccount = account;
mServerUrl = serverUrl;
- mWebDavUrl = webdavUrl;
mUsername = username;
mPassword = password;
mAuthToken = authToken;
- mFollowRedirects = followRedirects;
mCookie = cookie;
}
}
*
* New operations are added calling to startService(), resulting in a call to this method.
* This ensures the service will keep on working although the caller activity goes away.
- *
- * IMPORTANT: the only operations performed here right now is {@link GetSharedFilesOperation}. The class
- * is taking advantage of it due to time constraints.
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- //Log_OC.wtf(TAG, "onStartCommand init" );
+ if (ACTION_SYNC_FOLDER.equals(intent.getAction())) {
+ // WIP: for the moment, only SYNC_FOLDER is expected here; the rest of the operations are requested through
+ // the Binder
+ Pair<Target, RemoteOperation> itemToQueue = newOperation(intent);
+ if (itemToQueue != null) {
+ mPendingOperations.add(itemToQueue);
+ }
+ }
+
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
- //Log_OC.wtf(TAG, "onStartCommand end" );
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
//Log_OC.wtf(TAG, "onDestroy init" );
+ // Saving cookies
+ try {
+ OwnCloudClientManagerFactory.getDefaultSingleton().
+ saveAllClients(this, MainApp.getAccountType());
+
+ // 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();
+ }
+
//Log_OC.wtf(TAG, "Clear mUndispatchedFinisiedOperations" );
mUndispatchedFinishedOperations.clear();
+
//Log_OC.wtf(TAG, "onDestroy end" );
super.onDestroy();
}
/**
- * Creates and adds to the queue a new operation, as described by operationIntent
+ * Creates and adds to the queue a new operation, as described by operationIntent.
+ *
+ * Calls startService to make the operation is processed by the ServiceHandler.
*
* @param operationIntent Intent describing a new operation to queue and execute.
* @return Identifier of the operation created, or null if failed.
*/
- public long newOperation(Intent operationIntent) {
- RemoteOperation operation = null;
- Target target = null;
- try {
- if (!operationIntent.hasExtra(EXTRA_ACCOUNT) &&
- !operationIntent.hasExtra(EXTRA_SERVER_URL)) {
- Log_OC.e(TAG, "Not enough information provided in intent");
-
- } else {
- Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT);
- String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL);
- String webDavPath = operationIntent.getStringExtra(EXTRA_WEBDAV_PATH);
- String webDavUrl = serverUrl + webDavPath;
- String username = operationIntent.getStringExtra(EXTRA_USERNAME);
- String password = operationIntent.getStringExtra(EXTRA_PASSWORD);
- String authToken = operationIntent.getStringExtra(EXTRA_AUTH_TOKEN);
- boolean followRedirects = operationIntent.getBooleanExtra(EXTRA_FOLLOW_REDIRECTS, true);
- String cookie = operationIntent.getStringExtra(EXTRA_COOKIE);
- target = new Target(
- account,
- (serverUrl == null) ? null : Uri.parse(serverUrl),
- ((webDavPath == null) || (serverUrl == null)) ? null : webDavUrl,
- username,
- password,
- authToken,
- followRedirects,
- cookie
- );
-
- String action = operationIntent.getAction();
- if (action.equals(ACTION_CREATE_SHARE)) { // Create Share
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- Intent sendIntent = operationIntent.getParcelableExtra(EXTRA_SEND_INTENT);
- if (remotePath.length() > 0) {
- operation = new CreateShareOperation(remotePath, ShareType.PUBLIC_LINK,
- "", false, "", 1, sendIntent);
- }
-
- } else if (action.equals(ACTION_UNSHARE)) { // Unshare file
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- if (remotePath.length() > 0) {
- operation = new UnshareLinkOperation(
- remotePath,
- OperationsService.this);
- }
-
- } else if (action.equals(ACTION_GET_SERVER_INFO)) {
- // check OC server and get basic information from it
- String authTokenType =
- operationIntent.getStringExtra(EXTRA_AUTH_TOKEN_TYPE);
- operation = new GetServerInfoOperation(
- serverUrl, authTokenType, OperationsService.this);
-
- } else if (action.equals(ACTION_OAUTH2_GET_ACCESS_TOKEN)) {
- /// GET ACCESS TOKEN to the OAuth server
- String oauth2QueryParameters =
- operationIntent.getStringExtra(EXTRA_OAUTH2_QUERY_PARAMETERS);
- operation = new OAuth2GetAccessToken(
- getString(R.string.oauth2_client_id),
- getString(R.string.oauth2_redirect_uri),
- getString(R.string.oauth2_grant_type),
- oauth2QueryParameters);
-
- } else if (action.equals(ACTION_EXISTENCE_CHECK)) {
- // Existence Check
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, true);
- operation = new ExistenceCheckRemoteOperation(remotePath, OperationsService.this, successIfAbsent);
-
- } else if (action.equals(ACTION_GET_USER_NAME)) {
- // Get User Name
- operation = new GetRemoteUserNameOperation();
-
- } else if (action.equals(ACTION_RENAME)) {
- // Rename file or folder
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- String newName = operationIntent.getStringExtra(EXTRA_NEWNAME);
- operation = new RenameFileOperation(remotePath, account, newName);
-
- } else if (action.equals(ACTION_REMOVE)) {
- // Remove file or folder
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL, false);
- operation = new RemoveFileOperation(remotePath, onlyLocalCopy);
-
- } else if (action.equals(ACTION_CREATE_FOLDER)) {
- // Create Folder
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true);
- operation = new CreateFolderOperation(remotePath, createFullPath);
-
- } else if (action.equals(ACTION_SYNC_FILE)) {
- // Sync file
- String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
- boolean syncFileContents = operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
- operation = new SynchronizeFileOperation(remotePath, account, syncFileContents, getApplicationContext());
- }
-
- }
-
- } catch (IllegalArgumentException e) {
- Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
- operation = null;
- }
-
- if (operation != null) {
- mPendingOperations.add(new Pair<Target , RemoteOperation>(target, operation));
+ public long queueNewOperation(Intent operationIntent) {
+ Pair<Target, RemoteOperation> itemToQueue = newOperation(operationIntent);
+ if (itemToQueue != null) {
+ mPendingOperations.add(itemToQueue);
startService(new Intent(OperationsService.this, OperationsService.class));
- //Log_OC.wtf(TAG, "New operation added, opId: " + operation.hashCode());
- // better id than hash? ; should be good enough by the time being
- return operation.hashCode();
+ return itemToQueue.second.hashCode();
} else {
- //Log_OC.wtf(TAG, "New operation failed, returned Long.MAX_VALUE");
return Long.MAX_VALUE;
}
}
-
+
+
public boolean dispatchResultIfFinished(int operationId, OnRemoteOperationListener listener) {
Pair<RemoteOperation, RemoteOperationResult> undispatched =
mUndispatchedFinishedOperations.remove(operationId);
//Log_OC.wtf(TAG, "Sending callback later");
} else {
if (!mPendingOperations.isEmpty()) {
- nextOperation();
return true;
} else {
return false;
/**
+ * Creates a new operation, as described by operationIntent.
+ *
+ * @param operationIntent Intent describing a new operation to queue and execute.
+ * @return Pair with the new operation object and the information about its target server.
+ */
+ private Pair<Target , RemoteOperation> newOperation(Intent operationIntent) {
+ RemoteOperation operation = null;
+ Target target = null;
+ try {
+ if (!operationIntent.hasExtra(EXTRA_ACCOUNT) &&
+ !operationIntent.hasExtra(EXTRA_SERVER_URL)) {
+ Log_OC.e(TAG, "Not enough information provided in intent");
+
+ } else {
+ Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT);
+ String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL);
+ String username = operationIntent.getStringExtra(EXTRA_USERNAME);
+ String password = operationIntent.getStringExtra(EXTRA_PASSWORD);
+ String authToken = operationIntent.getStringExtra(EXTRA_AUTH_TOKEN);
+ String cookie = operationIntent.getStringExtra(EXTRA_COOKIE);
+ target = new Target(
+ account,
+ (serverUrl == null) ? null : Uri.parse(serverUrl),
+ username,
+ password,
+ authToken,
+ cookie
+ );
+
+ String action = operationIntent.getAction();
+ if (action.equals(ACTION_CREATE_SHARE)) { // Create Share
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ Intent sendIntent = operationIntent.getParcelableExtra(EXTRA_SEND_INTENT);
+ if (remotePath.length() > 0) {
+ operation = new CreateShareOperation(remotePath, ShareType.PUBLIC_LINK,
+ "", false, "", 1, sendIntent);
+ }
+
+ } else if (action.equals(ACTION_UNSHARE)) { // Unshare file
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ if (remotePath.length() > 0) {
+ operation = new UnshareLinkOperation(
+ remotePath,
+ OperationsService.this);
+ }
+
+ } else if (action.equals(ACTION_GET_SERVER_INFO)) {
+ // check OC server and get basic information from it
+ operation = new GetServerInfoOperation(serverUrl, OperationsService.this);
+
+ } else if (action.equals(ACTION_OAUTH2_GET_ACCESS_TOKEN)) {
+ /// GET ACCESS TOKEN to the OAuth server
+ String oauth2QueryParameters =
+ operationIntent.getStringExtra(EXTRA_OAUTH2_QUERY_PARAMETERS);
+ operation = new OAuth2GetAccessToken(
+ getString(R.string.oauth2_client_id),
+ getString(R.string.oauth2_redirect_uri),
+ getString(R.string.oauth2_grant_type),
+ oauth2QueryParameters);
+
+ } else if (action.equals(ACTION_EXISTENCE_CHECK)) {
+ // Existence Check
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, false);
+ operation = new ExistenceCheckRemoteOperation(remotePath, OperationsService.this, successIfAbsent);
+
+ } else if (action.equals(ACTION_GET_USER_NAME)) {
+ // Get User Name
+ operation = new GetRemoteUserNameOperation();
+
+ } else if (action.equals(ACTION_RENAME)) {
+ // Rename file or folder
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ String newName = operationIntent.getStringExtra(EXTRA_NEWNAME);
+ operation = new RenameFileOperation(remotePath, newName);
+
+ } else if (action.equals(ACTION_REMOVE)) {
+ // Remove file or folder
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL, false);
+ operation = new RemoveFileOperation(remotePath, onlyLocalCopy);
+
+ } else if (action.equals(ACTION_CREATE_FOLDER)) {
+ // Create Folder
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true);
+ operation = new CreateFolderOperation(remotePath, createFullPath);
+
+ } else if (action.equals(ACTION_SYNC_FILE)) {
+ // Sync file
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ boolean syncFileContents = operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
+ operation = new SynchronizeFileOperation(
+ remotePath, account, syncFileContents, getApplicationContext()
+ );
+
+ } else if (action.equals(ACTION_SYNC_FOLDER)) {
+ // Sync file
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ boolean syncFileContents = operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
+ operation = new SynchronizeFolderOperation(
+ this, // TODO remove this dependency from construction time
+ remotePath,
+ account,
+ System.currentTimeMillis() // TODO remove this dependency from construction time
+ );
+
+ } else if (action.equals(ACTION_MOVE_FILE)) {
+ // Move file/folder
+ String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+ String newParentPath = operationIntent.getStringExtra(EXTRA_NEW_PARENT_PATH);
+ operation = new MoveFileOperation(remotePath,newParentPath,account);
+ }
+
+ }
+
+ } catch (IllegalArgumentException e) {
+ Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
+ operation = null;
+ }
+
+ if (operation != null) {
+ return new Pair<Target , RemoteOperation>(target, operation);
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
* Performs the next operation in the queue
*/
private void nextOperation() {
if (mLastTarget == null || !mLastTarget.equals(next.first)) {
mLastTarget = next.first;
if (mLastTarget.mAccount != null) {
- mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mAccount, getApplicationContext());
- mStorageManager = new FileDataStorageManager(mLastTarget.mAccount, getContentResolver());
+ OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount, this);
+ mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, this);
+ mStorageManager =
+ new FileDataStorageManager(
+ mLastTarget.mAccount,
+ getContentResolver());
} else {
- mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(),
- mLastTarget.mFollowRedirects); // this is not good enough
- if (mLastTarget.mWebDavUrl != null) {
- mOwnCloudClient.setWebdavUri(Uri.parse(mLastTarget.mWebDavUrl));
- }
- if (mLastTarget.mUsername != null && mLastTarget.mPassword != null) {
- mOwnCloudClient.setBasicCredentials(mLastTarget.mUsername, mLastTarget.mPassword);
- } else if (mLastTarget.mAuthToken != null) {
- mOwnCloudClient.setBearerCredentials(mLastTarget.mAuthToken);
- } else if (mLastTarget.mCookie != null) {
- mOwnCloudClient.setSsoSessionCookie(mLastTarget.mCookie);
+ OwnCloudCredentials credentials = null;
+ if (mLastTarget.mUsername != null &&
+ mLastTarget.mUsername.length() > 0) {
+ credentials = OwnCloudCredentialsFactory.newBasicCredentials(
+ mLastTarget.mUsername,
+ mLastTarget.mPassword); // basic
+
+ } else if (mLastTarget.mAuthToken != null &&
+ mLastTarget.mAuthToken.length() > 0) {
+ credentials = OwnCloudCredentialsFactory.newBearerCredentials(
+ mLastTarget.mAuthToken); // bearer token
+
+ } else if (mLastTarget.mCookie != null &&
+ mLastTarget.mCookie.length() > 0) {
+ credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(
+ mLastTarget.mCookie); // SAML SSO
}
+ OwnCloudAccount ocAccount = new OwnCloudAccount(
+ mLastTarget.mServerUrl, credentials);
+ mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+ getClientFor(ocAccount, this);
mStorageManager = null;
}
}