Browse Source

All the FileActivities bind to OperationsService on creation, and the later reports them when an operation finishes

David A. Velasco 11 years ago
parent
commit
e64a3cbf35

+ 75 - 5
src/com/owncloud/android/services/OperationsService.java

@@ -18,14 +18,19 @@
 package com.owncloud.android.services;
 
 import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
 
 import com.owncloud.android.datamodel.FileDataStorageManager;
 
+import com.owncloud.android.lib.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.network.OwnCloudClientFactory;
 import com.owncloud.android.lib.network.OwnCloudClient;
 import com.owncloud.android.operations.GetSharesOperation;
 import com.owncloud.android.operations.common.SyncOperation;
+import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
 import com.owncloud.android.lib.operations.common.RemoteOperation;
 import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 import com.owncloud.android.utils.Log_OC;
@@ -69,7 +74,7 @@ public class OperationsService extends Service {
 
     private Looper mServiceLooper;
     private ServiceHandler mServiceHandler;
-    private IBinder mBinder;
+    private OperationsServiceBinder mBinder;
     private OwnCloudClient mOwnCloudClient = null;
     private Target mLastTarget = null;
     private FileDataStorageManager mStorageManager;
@@ -150,8 +155,57 @@ public class OperationsService extends Service {
      * 
      *  It provides by itself the available operations.
      */
-    public class OperationsServiceBinder extends Binder {
-        // TODO
+    public class OperationsServiceBinder extends Binder /* implements OnRemoteOperationListener */ {
+        
+        /** 
+         * Map of listeners that will be reported about the end of operations from a {@link OperationsServiceBinder} instance 
+         */
+        private Set<OnRemoteOperationListener> mBoundListeners = new HashSet<OnRemoteOperationListener>();
+        
+        /**
+         * Cancels an operation
+         *
+         * TODO
+         */
+        public void cancel() {
+            // TODO
+        }
+        
+        
+        public void clearListeners() {
+            mBoundListeners.clear();
+        }
+
+        
+        /**
+         * Adds a listener interested in being reported about the end of operations.
+         * 
+         * @param listener      Object to notify about the end of operations.    
+         */
+        public void addOperationListener (OnRemoteOperationListener listener) {
+            mBoundListeners.add(listener);
+        }
+        
+        
+        /**
+         * Removes a listener from the list of objects interested in the being reported about the end of operations.
+         * 
+         * @param listener      Object to notify about progress of transfer.    
+         */
+        public void removeOperationListener (OnRemoteOperationListener listener) {
+            mBoundListeners.remove(listener);
+        }
+
+
+        /**
+         * TODO - IMPORTANT: update implementation when more operations are moved into the service 
+         * 
+         * @return  'True' when an operation that enforces the user to wait for completion is in process.
+         */
+        public boolean isPerformingBlockingOperation() {
+            return (mPendingOperations.size() > 0);
+        }
+
     }
     
     
@@ -243,14 +297,15 @@ public class OperationsService extends Service {
             }
             
             sendBroadcastOperationFinished(mLastTarget, mCurrentOperation, result);
+            callbackOperationListeners(mLastTarget, mCurrentOperation, result);
         }
     }
 
 
     /**
-     * Sends a LOCAL broadcast when a new operation is added to the queue.
+     * Sends a broadcast when a new operation is added to the queue.
      * 
-     * Local broadcasts are only delivered to activities in the same process.
+     * Local broadcasts are only delivered to activities in the same process, but can't be done sticky :\
      * 
      * @param target            Account or URL pointing to an OC server.
      * @param operation         Added operation.
@@ -291,6 +346,21 @@ public class OperationsService extends Service {
         //lbm.sendBroadcast(intent);
         sendStickyBroadcast(intent);
     }
+
     
+    /**
+     * 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 callbackOperationListeners(Target target, RemoteOperation operation, RemoteOperationResult result) {
+        Iterator<OnRemoteOperationListener> it = mBinder.mBoundListeners.iterator();
+        while (it.hasNext()) {
+            it.next().onRemoteOperationFinish(operation, result);
+        }
+    }
     
+
 }

+ 63 - 2
src/com/owncloud/android/ui/activity/FileActivity.java

@@ -23,9 +23,13 @@ import android.accounts.AccountManager;
 import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
 import android.accounts.OperationCanceledException;
+import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
@@ -45,6 +49,8 @@ import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCo
 import com.owncloud.android.operations.CreateShareOperation;
 import com.owncloud.android.operations.UnshareLinkOperation;
 
+import com.owncloud.android.services.OperationsService;
+import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.utils.Log_OC;
 
@@ -91,6 +97,10 @@ public class FileActivity extends SherlockFragmentActivity implements OnRemoteOp
     private FileDataStorageManager mStorageManager = null;
     
     private FileOperationsHelper mFileOperationsHelper;
+    
+    private ServiceConnection mOperationsServiceConnection = null;
+    
+    private OperationsServiceBinder mOperationsServiceBinder = null;
 
     
     /**
@@ -117,7 +127,9 @@ public class FileActivity extends SherlockFragmentActivity implements OnRemoteOp
         }
 
         setAccount(account, savedInstanceState != null);
-       
+        
+        mOperationsServiceConnection = new OperationsServiceConnection();
+        bindService(new Intent(this, OperationsService.class), mOperationsServiceConnection, Context.BIND_AUTO_CREATE);
     }
 
     
@@ -133,7 +145,6 @@ public class FileActivity extends SherlockFragmentActivity implements OnRemoteOp
         if (!validAccount) {
             swapToDefaultAccount();
         }
-        
     }
 
     
@@ -146,6 +157,24 @@ public class FileActivity extends SherlockFragmentActivity implements OnRemoteOp
     }
     
     
+    @Override 
+    protected void onStop() {
+        super.onStop();
+        if (mOperationsServiceBinder != null) {
+            mOperationsServiceBinder.removeOperationListener(this);
+            mOperationsServiceBinder = null;
+        }
+    }
+    
+    
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mOperationsServiceConnection != null)
+            unbindService(mOperationsServiceConnection);
+    }
+    
+    
     /**
      *  Sets and validates the ownCloud {@link Account} associated to the Activity. 
      * 
@@ -415,5 +444,37 @@ public class FileActivity extends SherlockFragmentActivity implements OnRemoteOp
             loading.dismiss();
         }
     }
+
+    
+    /** 
+     * Implements callback methods for service binding. Passed as a parameter to { 
+     */
+    private class OperationsServiceConnection implements ServiceConnection {
+
+        @Override
+        public void onServiceConnected(ComponentName component, IBinder service) {
+            if (component.equals(new ComponentName(FileActivity.this, OperationsService.class))) {
+                Log_OC.d(TAG, "Operations service connected");
+                mOperationsServiceBinder = (OperationsServiceBinder) service;
+                mOperationsServiceBinder.addOperationListener(FileActivity.this);
+                if (!mOperationsServiceBinder.isPerformingBlockingOperation()) {
+                    dismissLoadingDialog();
+                }
+
+            } else {
+                return;
+            }
+        }
+        
+
+        @Override
+        public void onServiceDisconnected(ComponentName component) {
+            if (component.equals(new ComponentName(FileActivity.this, OperationsService.class))) {
+                Log_OC.d(TAG, "Operations service disconnected");
+                mOperationsServiceBinder = null;
+                // TODO whatever could be waiting for the service is unbound
+            }
+        }
+    };    
     
 }