X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/8dc6b0f62dc933f38bbd4df9a7b6ab3e241ee250..56eaed4529542c1db660f66403111a60b0673abd:/src/com/owncloud/android/services/OperationsService.java diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java index a4f9d70e..b97c4249 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -26,11 +26,16 @@ 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.OwnCloudAccount; import com.owncloud.android.lib.common.OwnCloudClient; -import com.owncloud.android.lib.common.OwnCloudClientMap; +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; @@ -38,15 +43,18 @@ import com.owncloud.android.operations.common.SyncOperation; 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; @@ -65,7 +73,6 @@ public class OperationsService extends Service { 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"; @@ -74,14 +81,13 @@ public class OperationsService extends Service { 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"; @@ -94,10 +100,13 @@ public class OperationsService extends Service { 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> mPendingOperations = new ConcurrentLinkedQueue>(); @@ -108,22 +117,18 @@ public class OperationsService extends Service { 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; } } @@ -156,17 +161,21 @@ public class OperationsService extends Service { * * 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 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; } @@ -174,7 +183,20 @@ public class OperationsService extends Service { public void onDestroy() { //Log_OC.wtf(TAG, "onDestroy init" ); // Saving cookies - OwnCloudClientMap.saveAllClients(this, MainApp.getAccountType()); + 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(); @@ -270,129 +292,26 @@ public class OperationsService extends Service { /** - * 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, operation)); + public long queueNewOperation(Intent operationIntent) { + Pair 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 undispatched = mUndispatchedFinishedOperations.remove(operationId); @@ -438,6 +357,136 @@ public class OperationsService extends Service { /** + * 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 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, operation); + } else { + return null; + } + } + + + /** * Performs the next operation in the queue */ private void nextOperation() { @@ -458,28 +507,35 @@ public class OperationsService extends Service { if (mLastTarget == null || !mLastTarget.equals(next.first)) { mLastTarget = next.first; if (mLastTarget.mAccount != null) { - mOwnCloudClient = - OwnCloudClientMap.getClientFor(mLastTarget.mAccount, this); + OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount, this); + mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton(). + getClientFor(ocAccount, this); mStorageManager = new FileDataStorageManager( mLastTarget.mAccount, getContentResolver()); } else { - mOwnCloudClient = OwnCloudClientMap.getAnonymousClientFor( - mLastTarget.mServerUrl, - this, - mLastTarget.mFollowRedirects); - - 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; } }