X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/a6a010440d881d3f9dbd2fa50d6345275c0d0a0d..ec6b9d7c70deb50152bfab5cb5f25c9a2dde28e7:/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 008ea2ef..581a686d 100644 --- a/src/com/owncloud/android/services/OperationsService.java +++ b/src/com/owncloud/android/services/OperationsService.java @@ -83,7 +83,8 @@ public class OperationsService extends Service { 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"; - + public static final String EXTRA_FILE = "FILE"; + // TODO review if ALL OF THEM are necessary public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT"; public static final String EXTRA_USERNAME = "USERNAME"; @@ -102,7 +103,7 @@ public class OperationsService extends Service { 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_CANCEL_SYNC_FOLDER = "CANCEL_SYNC_FOLDER"; // for the moment, just to download + //public static final String ACTION_CANCEL_SYNC_FOLDER = "CANCEL_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"; @@ -143,6 +144,8 @@ public class OperationsService extends Service { @Override public void onCreate() { super.onCreate(); + Log_OC.d(TAG, "Creating service"); + /// First worker thread for most of operations HandlerThread thread = new HandlerThread("Operations thread", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); @@ -164,9 +167,12 @@ public class OperationsService extends Service { */ @Override public int onStartCommand(Intent intent, int flags, int startId) { - // WIP: for the moment, only SYNC_FOLDER and CANCEL_SYNC_FOLDER is expected here; + Log_OC.d(TAG, "Starting command with id " + startId); + + // WIP: for the moment, only SYNC_FOLDER is expected here; // the rest of the operations are requested through the Binder if (ACTION_SYNC_FOLDER.equals(intent.getAction())) { + if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_REMOTE_PATH)) { Log_OC.e(TAG, "Not enough information provided in intent"); return START_NOT_STICKY; @@ -174,29 +180,17 @@ public class OperationsService extends Service { Account account = intent.getParcelableExtra(EXTRA_ACCOUNT); String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH); - OCFile file = new OCFile(remotePath); - Pair itemSyncKey = new Pair(account, file); + Pair itemSyncKey = new Pair(account, remotePath); Pair itemToQueue = newOperation(intent); if (itemToQueue != null) { - mSyncFolderHandler.add(account, file, (SynchronizeFolderOperation)itemToQueue.second); + mSyncFolderHandler.add(account, remotePath, (SynchronizeFolderOperation)itemToQueue.second); Message msg = mSyncFolderHandler.obtainMessage(); msg.arg1 = startId; msg.obj = itemSyncKey; mSyncFolderHandler.sendMessage(msg); } - } else if (ACTION_CANCEL_SYNC_FOLDER.equals(intent.getAction())) { - if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_REMOTE_PATH)) { - Log_OC.e(TAG, "Not enough information provided in intent"); - return START_NOT_STICKY; - } - Account account = intent.getParcelableExtra(EXTRA_ACCOUNT); - String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH); - - OCFile file = new OCFile(remotePath); - // Cancel operation - mSyncFolderHandler.cancel(account,file); } else { Message msg = mOperationsHandler.obtainMessage(); msg.arg1 = startId; @@ -208,7 +202,7 @@ public class OperationsService extends Service { @Override public void onDestroy() { - //Log_OC.wtf(TAG, "onDestroy init" ); + Log_OC.v(TAG, "Destroying service" ); // Saving cookies try { OwnCloudClientManagerFactory.getDefaultSingleton(). @@ -225,10 +219,16 @@ public class OperationsService extends Service { e.printStackTrace(); } - //Log_OC.wtf(TAG, "Clear mUndispatchedFinisiedOperations" ); mUndispatchedFinishedOperations.clear(); - - //Log_OC.wtf(TAG, "onDestroy end" ); + + mOperationsBinder = null; + + mOperationsHandler.getLooper().quit(); + mOperationsHandler = null; + + mSyncFolderHandler.getLooper().quit(); + mSyncFolderHandler = null; + super.onDestroy(); } @@ -267,23 +267,23 @@ public class OperationsService extends Service { new ConcurrentHashMap(); private ServiceHandler mServiceHandler = null; - - + public OperationsServiceBinder(ServiceHandler serviceHandler) { mServiceHandler = serviceHandler; } /** - * Cancels an operation + * Cancels a pending or current synchronization. * - * TODO + * @param account ownCloud account where the remote folder is stored. + * @param file A folder in the queue of pending synchronizations */ - public void cancel() { - // TODO + public void cancel(Account account, OCFile file) { + mSyncFolderHandler.cancel(account, file); } - - + + public void clearListeners() { mBoundListeners.clear(); @@ -362,128 +362,27 @@ public class OperationsService extends Service { //Log_OC.wtf(TAG, "Not finished yet"); } } - - } - - - /** - * SyncFolder worker. Performs the pending operations in the order they were requested. - * - * Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}. - */ - private static class SyncFolderHandler extends Handler { - - // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak - - OperationsService mService; - - private ConcurrentMap mPendingOperations = - new ConcurrentHashMap(); - private OwnCloudClient mOwnCloudClient = null; - private FileDataStorageManager mStorageManager; - private SynchronizeFolderOperation mCurrentSyncOperation; - - - public SyncFolderHandler(Looper looper, OperationsService service) { - super(looper); - if (service == null) { - throw new IllegalArgumentException("Received invalid NULL in parameter 'service'"); - } - mService = service; - } - - @Override - public void handleMessage(Message msg) { - Pair itemSyncKey = (Pair) msg.obj; - nextOperation(itemSyncKey.first,itemSyncKey.second); - mService.stopSelf(msg.arg1); - } - - - /** - * Performs the next operation in the queue - */ - private void nextOperation(Account account, OCFile file) { - - String syncKey = buildRemoteName(account,file); - - synchronized(mPendingOperations) { - mCurrentSyncOperation = mPendingOperations.get(syncKey); - } - - if (mCurrentSyncOperation != null) { - - RemoteOperationResult operationResult = null; - try { - - OwnCloudAccount ocAccount = new OwnCloudAccount(account, mService); - mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton(). - getClientFor(ocAccount, mService); - mStorageManager = new FileDataStorageManager( - account, - mService.getContentResolver() - ); - - - /// perform the operation - if (mCurrentSyncOperation instanceof SyncOperation) { - operationResult = ((SyncOperation)mCurrentSyncOperation).execute(mOwnCloudClient, mStorageManager); - } else { - operationResult = mCurrentSyncOperation.execute(mOwnCloudClient); - } - - } catch (AccountsException e) { - Log_OC.e(TAG, "Error while trying to get autorization", e); - operationResult = new RemoteOperationResult(e); - } catch (IOException e) { - Log_OC.e(TAG, "Error while trying to get autorization", e); - operationResult = new RemoteOperationResult(e); - - } finally { - synchronized(mPendingOperations) { - mPendingOperations.remove(syncKey); - } - } - - /// TODO notify operation result if needed - - } - } - - public void add(Account account, OCFile file, SynchronizeFolderOperation syncFolderOperation){ - String syncKey = buildRemoteName(account,file); - mPendingOperations.putIfAbsent(syncKey,syncFolderOperation); - } - + + /** - * Cancels a pending or current sync operation. - * - * @param account Owncloud account where the remote file is stored. - * @param file A file in the queue of pending downloads + * Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or waiting + * to download. + * + * If 'file' is a directory, returns 'true' if some of its descendant files is downloading or waiting + * to download. + * + * @param account ownCloud account where the remote file is stored. + * @param remotePath Path of the folder to check if something is synchronizing / downloading / uploading + * inside. */ - public void cancel(Account account, OCFile file) { - SynchronizeFolderOperation syncOperation = null; - synchronized (mPendingOperations) { - syncOperation = mPendingOperations.remove(buildRemoteName(account, file)); - } - if (syncOperation != null) { - syncOperation.cancel(); - } + public boolean isSynchronizing(Account account, String remotePath) { + return mSyncFolderHandler.isSynchronizing(account, remotePath); } - /** - * Builds a key from the account and file to download - * - * @param account Account where the file to download is stored - * @param file File to download - */ - private String buildRemoteName(Account account, OCFile file) { - return account.name + file.getRemotePath(); - } } - /** + /** * Operations worker. Performs the pending operations in the order they were requested. * * Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}. @@ -514,6 +413,7 @@ public class OperationsService extends Service { @Override public void handleMessage(Message msg) { nextOperation(); + Log_OC.d(TAG, "Stopping after command with id " + msg.arg1); mService.stopSelf(msg.arg1); } @@ -655,7 +555,7 @@ public class OperationsService extends Service { 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, + operation = new CreateShareOperation(OperationsService.this, remotePath, ShareType.PUBLIC_LINK, "", false, "", 1, sendIntent); } @@ -797,12 +697,12 @@ public class OperationsService extends Service { /** * Notifies the currently subscribed listeners about the end of an operation. - * + * * @param target Account or URL pointing to an OC server. * @param operation Finished operation. * @param result Result of the operation. */ - private void dispatchResultToOperationListeners( + protected void dispatchResultToOperationListeners( Target target, final RemoteOperation operation, final RemoteOperationResult result) { int count = 0; Iterator listeners = mOperationsBinder.mBoundListeners.keySet().iterator();