X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/281212045672b8439f09e50896d90a1f5c7524f1..c2c10bcff893790e7af07c51afeb43315ff2ed84:/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 0df160aa..d44a3af4 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -18,10 +18,10 @@ package com.owncloud.android.services; import java.io.IOException; -import java.util.HashMap; import java.util.Iterator; -import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentMap; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.lib.common.OwnCloudClientFactory; @@ -29,6 +29,7 @@ import com.owncloud.android.lib.common.OwnCloudClient; 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.resources.files.ExistenceCheckRemoteOperation; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.operations.common.SyncOperation; import com.owncloud.android.operations.CreateShareOperation; @@ -60,22 +61,44 @@ public class OperationsService extends Service { public static final String EXTRA_SEND_INTENT = "SEND_INTENT"; public static final String EXTRA_RESULT = "RESULT"; 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 ACTION_CREATE_SHARE = "CREATE_SHARE"; public static final String ACTION_UNSHARE = "UNSHARE"; public static final String ACTION_DETECT_AUTHENTICATION_METHOD = "DETECT_AUTHENTICATION_METHOD"; + public static final String ACTION_EXISTENCE_CHECK = "EXISTENCE_CHECK"; 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>(); + private ConcurrentLinkedQueue> mPendingOperations = + new ConcurrentLinkedQueue>(); + + private ConcurrentMap mOperationResults = + new ConcurrentHashMap(); private static class Target { public Uri mServerUrl = null; public Account mAccount = null; - public Target(Account account, Uri serverUrl) { + public String mWebDavUrl = ""; + public String mUsername = ""; + public String mPassword = ""; + public String mAuthToken = ""; + public boolean mFollowRedirects = true; + + public Target(Account account, Uri serverUrl, String webdavUrl, String username, String password, String authToken, + boolean followRedirects) { mAccount = account; mServerUrl = serverUrl; + mWebDavUrl = webdavUrl; + mUsername = username; + mPassword = password; + mAuthToken = authToken; + mFollowRedirects = followRedirects; } } @@ -101,6 +124,7 @@ public class OperationsService extends Service { mBinder = new OperationsServiceBinder(); } + /** * Entry point to add a new operation to the queue of operations. * @@ -112,51 +136,11 @@ public class OperationsService extends Service { */ @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (!intent.hasExtra(EXTRA_ACCOUNT) && !intent.hasExtra(EXTRA_SERVER_URL)) { - Log_OC.e(TAG, "Not enough information provided in intent"); - return START_NOT_STICKY; - } - try { - Account account = intent.getParcelableExtra(EXTRA_ACCOUNT); - String serverUrl = intent.getStringExtra(EXTRA_SERVER_URL); - - Target target = new Target(account, (serverUrl == null) ? null : Uri.parse(serverUrl)); - RemoteOperation operation = null; - - String action = intent.getAction(); - if (action.equals(ACTION_CREATE_SHARE)) { // Create Share - String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH); - Intent sendIntent = intent.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 = intent.getStringExtra(EXTRA_REMOTE_PATH); - if (remotePath.length() > 0) { - operation = new UnshareLinkOperation(remotePath, this.getApplicationContext()); - } - } else if (action.equals(ACTION_DETECT_AUTHENTICATION_METHOD)) { // Detect Authentication Method - String webdav_url = serverUrl + intent.getStringExtra(EXTRA_WEBDAV_PATH); - operation = new DetectAuthenticationMethodOperation(this.getApplicationContext(), webdav_url); - - } else { - // nothing we are going to handle - return START_NOT_STICKY; - } - - mPendingOperations.add(new Pair(target, operation)); - //sendBroadcastNewOperation(target, operation); - - Message msg = mServiceHandler.obtainMessage(); - msg.arg1 = startId; - mServiceHandler.sendMessage(msg); - - } catch (IllegalArgumentException e) { - Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage()); - return START_NOT_STICKY; - } - + //Log.wtf(TAG, "onStartCommand init" ); + Message msg = mServiceHandler.obtainMessage(); + msg.arg1 = startId; + mServiceHandler.sendMessage(msg); + //Log.wtf(TAG, "onStartCommand end" ); return START_NOT_STICKY; } @@ -167,6 +151,7 @@ public class OperationsService extends Service { */ @Override public IBinder onBind(Intent intent) { + //Log.wtf(TAG, "onBind" ); return mBinder; } @@ -176,7 +161,7 @@ public class OperationsService extends Service { */ @Override public boolean onUnbind(Intent intent) { - //((OperationsServiceBinder)mBinder).clearListeners(); + ((OperationsServiceBinder)mBinder).clearListeners(); return false; // not accepting rebinding (default behaviour) } @@ -191,7 +176,8 @@ public class OperationsService extends Service { /** * Map of listeners that will be reported about the end of operations from a {@link OperationsServiceBinder} instance */ - private Map mBoundListeners = new HashMap(); + private ConcurrentMap mBoundListeners = + new ConcurrentHashMap(); /** * Cancels an operation @@ -216,7 +202,9 @@ public class OperationsService extends Service { * @param callbackHandler {@link Handler} to access the listener without breaking Android threading protection. */ public void addOperationListener (OnRemoteOperationListener listener, Handler callbackHandler) { - mBoundListeners.put(listener, callbackHandler); + synchronized (mBoundListeners) { + mBoundListeners.put(listener, callbackHandler); + } } @@ -226,7 +214,9 @@ public class OperationsService extends Service { * @param listener Object to notify about progress of transfer. */ public void removeOperationListener (OnRemoteOperationListener listener) { - mBoundListeners.remove(listener); + synchronized (mBoundListeners) { + mBoundListeners.remove(listener); + } } @@ -239,6 +229,91 @@ public class OperationsService extends Service { return (!mPendingOperations.isEmpty()); } + + /** + * Creates and adds to the queue a new operation, as described by operationIntent + * + * @param operationIntent Intent describing a new operation to queue and execute. + * @return Identifier of the operation created, or -1 if failed. + */ + public int 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); + target = new Target( + account, + (serverUrl == null) ? null : Uri.parse(serverUrl), + ((webDavPath == null) || (serverUrl == null)) ? "" : webDavUrl, + (username == null) ? "" : username, + (password == null) ? "" : password, + (authToken == null) ? "" : authToken, + followRedirects + ); + + 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_DETECT_AUTHENTICATION_METHOD)) { + // Detect Authentication Method + String webdav_url = + serverUrl + operationIntent.getStringExtra(EXTRA_WEBDAV_PATH); + operation = new DetectAuthenticationMethodOperation( + OperationsService.this, + webdav_url); + } 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); + + } + } + + } 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)); + startService(new Intent(OperationsService.this, OperationsService.class)); + return operation.hashCode(); + + } else { + return -1; + } + } + + public RemoteOperationResult getOperationResultIfFinished(int mDetectAuthOpId) { + //Log_OC.wtf(TAG, "Searching result for operation with id " + mDetectAuthOpId); + return mOperationResults.remove(mDetectAuthOpId); + } + } @@ -271,11 +346,13 @@ public class OperationsService extends Service { */ private void nextOperation() { + //Log.wtf(TAG, "nextOperation init" ); + Pair next = null; synchronized(mPendingOperations) { next = mPendingOperations.peek(); } - + if (next != null) { mCurrentOperation = next.second; @@ -288,7 +365,16 @@ public class OperationsService extends Service { mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mAccount, getApplicationContext()); mStorageManager = new FileDataStorageManager(mLastTarget.mAccount, getContentResolver()); } else { - mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), true); // this is not good enough + mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), + mLastTarget.mFollowRedirects); // this is not good enough + if (mLastTarget.mWebDavUrl != "") { + mOwnCloudClient.setWebdavUri(Uri.parse(mLastTarget.mWebDavUrl)); + } + if (mLastTarget.mUsername != "" && mLastTarget.mPassword != "") { + mOwnCloudClient.setBasicCredentials(mLastTarget.mUsername, mLastTarget.mPassword); + } else if (mLastTarget.mAuthToken != "") { + mOwnCloudClient.setBearerCredentials(mLastTarget.mAuthToken); + } mStorageManager = null; } } @@ -326,6 +412,7 @@ public class OperationsService extends Service { } finally { synchronized(mPendingOperations) { mPendingOperations.poll(); + mOperationResults.put(mCurrentOperation.hashCode(), result); } } @@ -388,7 +475,9 @@ public class OperationsService extends Service { * @param operation Finished operation. * @param result Result of the operation. */ - private void callbackOperationListeners(Target target, final RemoteOperation operation, final RemoteOperationResult result) { + private void callbackOperationListeners( + Target target, final RemoteOperation operation, final RemoteOperationResult result) { + int count = 0; Iterator listeners = mBinder.mBoundListeners.keySet().iterator(); while (listeners.hasNext()) { final OnRemoteOperationListener listener = listeners.next(); @@ -400,9 +489,10 @@ public class OperationsService extends Service { listener.onRemoteOperationFinish(operation, result); } }); + count += 1; } } - + Log_OC.d(TAG, "Called " + count + " listeners"); }