diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8ff6870bf0..465dec84ab 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -151,6 +151,7 @@
+
diff --git a/owncloud-android-library b/owncloud-android-library
index 974e55a2b9..09b1c3c15a 160000
--- a/owncloud-android-library
+++ b/owncloud-android-library
@@ -1 +1 @@
-Subproject commit 974e55a2b95c652b794111254078b806f11fcf31
+Subproject commit 09b1c3c15aa2644635796c93ee918f8b0a20ff7c
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2669565eeb..fba0915c87 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -245,4 +245,7 @@
do nothing you are not online for instant upload
Failure Message:
Please check your server configuration,maybe your quota is exceeded.
+
+ Sorry, sharing is not enabled on your server. Please contact your administrator.
+ Unable to share this file or folder. Please, make sure it exists
diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
index 0b35beaa8a..12390c3d45 100644
--- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java
+++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
@@ -29,6 +29,7 @@ import com.owncloud.android.MainApp;
import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
import com.owncloud.android.lib.operations.common.OCShare;
import com.owncloud.android.lib.operations.common.ShareType;
+import com.owncloud.android.lib.utils.FileUtils;
import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.Log_OC;
@@ -1098,4 +1099,36 @@ public class FileDataStorageManager {
}
}
+
+
+ public void saveSharesDB(ArrayList shares) {
+
+ if (shares.size() > 0) {
+ // Save share file
+ saveShares(shares);
+
+ ArrayList sharedFiles = new ArrayList();
+
+ for (OCShare share : shares) {
+ // Get the path
+ String path = share.getPath();
+ if (share.isDirectory()) {
+ path = path + FileUtils.PATH_SEPARATOR;
+ }
+
+ // Update OCFile with data from share: ShareByLink żand publicLink?
+ OCFile file = getFileByPath(path);
+ if (file != null) {
+ if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
+ file.setShareByLink(true);
+ sharedFiles.add(file);
+ }
+ }
+ }
+
+ if (sharedFiles.size() > 0) {
+ updateSharedFiles(sharedFiles);
+ }
+ }
+ }
}
diff --git a/src/com/owncloud/android/operations/CreateShareOperation.java b/src/com/owncloud/android/operations/CreateShareOperation.java
index 1582f8f0f9..7659d16d5f 100644
--- a/src/com/owncloud/android/operations/CreateShareOperation.java
+++ b/src/com/owncloud/android/operations/CreateShareOperation.java
@@ -25,14 +25,18 @@ package com.owncloud.android.operations;
*/
import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.network.OwnCloudClient;
-import com.owncloud.android.lib.operations.common.RemoteOperation;
+import com.owncloud.android.lib.operations.common.OCShare;
import com.owncloud.android.lib.operations.common.RemoteOperationResult;
import com.owncloud.android.lib.operations.common.ShareType;
import com.owncloud.android.lib.operations.remote.CreateShareRemoteOperation;
+import com.owncloud.android.lib.utils.FileUtils;
+import com.owncloud.android.operations.common.SyncOperation;
+import com.owncloud.android.utils.Log_OC;
+
+public class CreateShareOperation extends SyncOperation {
-public class CreateShareOperation extends RemoteOperation {
-
private static final String TAG = CreateShareOperation.class.getSimpleName();
protected FileDataStorageManager mStorageManager;
@@ -43,7 +47,7 @@ public class CreateShareOperation extends RemoteOperation {
private boolean mPublicUpload;
private String mPassword;
private int mPermissions;
-
+
/**
* Constructor
* @param path Full path of the file/folder being shared. Mandatory argument
@@ -79,11 +83,35 @@ public class CreateShareOperation extends RemoteOperation {
RemoteOperationResult result = operation.execute(client);
if (result.isSuccess()) {
- // TODO
- // Update DB with the response
+ if (result.getData().size() > 0) {
+ OCShare share = (OCShare) result.getData().get(0);
+
+ // Update DB with the response
+ if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) {
+ share.setPath(mPath.substring(0, mPath.length()-1));
+ share.setIsDirectory(true);
+
+ } else {
+ share.setPath(mPath);
+ share.setIsDirectory(false);
+ }
+ share.setPermissions(mPermissions);
+
+ getStorageManager().saveShare(share);
+
+ // Update OCFile with data from share: ShareByLink and publicLink
+ OCFile file = getStorageManager().getFileByPath(mPath);
+ if (file!=null) {
+ file.setPublicLink(share.getShareLink());
+ getStorageManager().saveFile(file);
+ Log_OC.d(TAG, "Public Link = " + file.getPublicLink());
+
+ }
+ }
}
+
return result;
}
diff --git a/src/com/owncloud/android/operations/GetSharesForFileOperation.java b/src/com/owncloud/android/operations/GetSharesForFileOperation.java
new file mode 100644
index 0000000000..fd2dab743c
--- /dev/null
+++ b/src/com/owncloud/android/operations/GetSharesForFileOperation.java
@@ -0,0 +1,79 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+
+package com.owncloud.android.operations;
+
+import java.util.ArrayList;
+
+import com.owncloud.android.lib.network.OwnCloudClient;
+import com.owncloud.android.lib.operations.common.OCShare;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.lib.operations.remote.GetSharesForFileRemoteOperation;
+import com.owncloud.android.operations.common.SyncOperation;
+import com.owncloud.android.utils.Log_OC;
+
+/**
+ * Provide a list shares for a specific file.
+ *
+ * @author masensio
+ *
+ */
+public class GetSharesForFileOperation extends SyncOperation {
+
+ private static final String TAG = GetSharesForFileOperation.class.getSimpleName();
+
+ private String mPath;
+ private boolean mReshares;
+ private boolean mSubfiles;
+
+ /**
+ * Constructor
+ *
+ * @param path Path to file or folder
+ * @param reshares If set to ‘false’ (default), only shares from the current user are returned
+ * If set to ‘true’, all shares from the given file are returned
+ * @param subfiles If set to ‘false’ (default), lists only the folder being shared
+ * If set to ‘true’, all shared files within the folder are returned.
+ */
+ public GetSharesForFileOperation(String path, boolean reshares, boolean subfiles) {
+ mPath = path;
+ mReshares = reshares;
+ mSubfiles = subfiles;
+ }
+
+ @Override
+ protected RemoteOperationResult run(OwnCloudClient client) {
+ GetSharesForFileRemoteOperation operation = new GetSharesForFileRemoteOperation(mPath, mReshares, mSubfiles);
+ RemoteOperationResult result = operation.execute(client);
+
+ if (result.isSuccess()) {
+
+ // Update DB with the response
+ Log_OC.d(TAG, "File = " + mPath + " Share list size " + result.getData().size());
+ ArrayList shares = new ArrayList();
+ for(Object obj: result.getData()) {
+ shares.add((OCShare) obj);
+ }
+
+ getStorageManager().saveSharesDB(shares);
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/com/owncloud/android/operations/GetSharesOperation.java b/src/com/owncloud/android/operations/GetSharesOperation.java
index 3b879c0651..8f7a2ae88e 100644
--- a/src/com/owncloud/android/operations/GetSharesOperation.java
+++ b/src/com/owncloud/android/operations/GetSharesOperation.java
@@ -19,15 +19,11 @@ package com.owncloud.android.operations;
import java.util.ArrayList;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.network.OwnCloudClient;
-import com.owncloud.android.lib.operations.common.RemoteOperation;
import com.owncloud.android.lib.operations.common.RemoteOperationResult;
import com.owncloud.android.lib.operations.common.OCShare;
-import com.owncloud.android.lib.operations.common.ShareType;
import com.owncloud.android.lib.operations.remote.GetRemoteSharesOperation;
-import com.owncloud.android.lib.utils.FileUtils;
+import com.owncloud.android.operations.common.SyncOperation;
import com.owncloud.android.utils.Log_OC;
/**
@@ -35,19 +31,13 @@ import com.owncloud.android.utils.Log_OC;
* Save the data in Database
*
* @author masensio
+ * @author David A. Velasco
*/
-public class GetSharesOperation extends RemoteOperation {
+public class GetSharesOperation extends SyncOperation {
private static final String TAG = GetSharesOperation.class.getSimpleName();
- protected FileDataStorageManager mStorageManager;
-
-
- public GetSharesOperation(FileDataStorageManager storageManager) {
- mStorageManager = storageManager;
- }
-
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
GetRemoteSharesOperation operation = new GetRemoteSharesOperation();
@@ -62,41 +52,10 @@ public class GetSharesOperation extends RemoteOperation {
shares.add((OCShare) obj);
}
- saveSharesDB(shares);
+ getStorageManager().saveSharesDB(shares);
}
return result;
}
- private void saveSharesDB(ArrayList shares) {
-
- if (shares.size() > 0) {
- // Save share file
- mStorageManager.saveShares(shares);
-
- ArrayList sharedFiles = new ArrayList();
-
- for (OCShare share : shares) {
- // Get the path
- String path = share.getPath();
- if (share.isDirectory()) {
- path = path + FileUtils.PATH_SEPARATOR;
- }
-
- // Update OCFile with data from share: ShareByLink żand publicLink?
- OCFile file = mStorageManager.getFileByPath(path);
- if (file != null) {
- if (share.getShareType().equals(ShareType.PUBLIC_LINK)) {
- file.setShareByLink(true);
- sharedFiles.add(file);
- }
- }
- }
-
- if (sharedFiles.size() > 0) {
- mStorageManager.updateSharedFiles(sharedFiles);
- }
- }
- }
-
}
diff --git a/src/com/owncloud/android/operations/common/SyncOperation.java b/src/com/owncloud/android/operations/common/SyncOperation.java
new file mode 100644
index 0000000000..7a8e356a37
--- /dev/null
+++ b/src/com/owncloud/android/operations/common/SyncOperation.java
@@ -0,0 +1,129 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012-2014 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.operations.common;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.lib.network.OwnCloudClient;
+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 android.app.Activity;
+import android.content.Context;
+import android.os.Handler;
+
+
+/**
+ * Operation which execution involves both interactions with an ownCloud server and
+ * with local data in the device.
+ *
+ * Provides methods to execute the operation both synchronously or asynchronously.
+ *
+ * @author David A. Velasco
+ */
+public abstract class SyncOperation extends RemoteOperation {
+
+ //private static final String TAG = SyncOperation.class.getSimpleName();
+
+ private FileDataStorageManager mStorageManager;
+
+ public FileDataStorageManager getStorageManager() {
+ return mStorageManager;
+ }
+
+
+ /**
+ * Synchronously executes the operation on the received ownCloud account.
+ *
+ * Do not call this method from the main thread.
+ *
+ * This method should be used whenever an ownCloud account is available, instead of {@link #execute(OwnCloudClient)}.
+ *
+ * @param account ownCloud account in remote ownCloud server to reach during the execution of the operation.
+ * @param context Android context for the component calling the method.
+ * @return Result of the operation.
+ */
+ public RemoteOperationResult execute(FileDataStorageManager storageManager, Context context) {
+ if (storageManager == null) {
+ throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+ }
+ if (storageManager.getAccount() == null) {
+ throw new IllegalArgumentException("Trying to execute a sync operation with a storage manager for a NULL account");
+ }
+ mStorageManager = storageManager;
+ return super.execute(mStorageManager.getAccount(), context);
+ }
+
+
+ /**
+ * Synchronously executes the remote operation
+ *
+ * Do not call this method from the main thread.
+ *
+ * @param client Client object to reach an ownCloud server during the execution of the operation.
+ * @return Result of the operation.
+ */
+ public RemoteOperationResult execute(OwnCloudClient client, FileDataStorageManager storageManager) {
+ if (storageManager == null)
+ throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+ mStorageManager = storageManager;
+ return super.execute(client);
+ }
+
+
+ /**
+ * Asynchronously executes the remote operation
+ *
+ * This method should be used whenever an ownCloud account is available, instead of {@link #execute(OwnCloudClient)}.
+ *
+ * @param account ownCloud account in remote ownCloud server to reach during the execution of the operation.
+ * @param context Android context for the component calling the method.
+ * @param listener Listener to be notified about the execution of the operation.
+ * @param listenerHandler Handler associated to the thread where the methods of the listener objects must be called.
+ * @return Thread were the remote operation is executed.
+ */
+ public Thread execute(FileDataStorageManager storageManager, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) {
+ if (storageManager == null) {
+ throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+ }
+ if (storageManager.getAccount() == null) {
+ throw new IllegalArgumentException("Trying to execute a sync operation with a storage manager for a NULL account");
+ }
+ mStorageManager = storageManager;
+ return super.execute(storageManager.getAccount(), context, listener, listenerHandler, callerActivity);
+ }
+
+
+ /**
+ * Asynchronously executes the remote operation
+ *
+ * @param client Client object to reach an ownCloud server during the execution of the operation.
+ * @param listener Listener to be notified about the execution of the operation.
+ * @param listenerHandler Handler associated to the thread where the methods of the listener objects must be called.
+ * @return Thread were the remote operation is executed.
+ */
+ public Thread execute(OwnCloudClient client, FileDataStorageManager storageManager, OnRemoteOperationListener listener, Handler listenerHandler) {
+ if (storageManager == null) {
+ throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+ }
+ mStorageManager = storageManager;
+ return super.execute(client, listener, listenerHandler);
+ }
+
+
+}
diff --git a/src/com/owncloud/android/services/OperationsService.java b/src/com/owncloud/android/services/OperationsService.java
new file mode 100644
index 0000000000..316657c4e7
--- /dev/null
+++ b/src/com/owncloud/android/services/OperationsService.java
@@ -0,0 +1,287 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012-2013 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.owncloud.android.services;
+
+import java.io.IOException;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+
+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.RemoteOperation;
+import com.owncloud.android.lib.operations.common.RemoteOperationResult;
+import com.owncloud.android.utils.Log_OC;
+
+import android.accounts.Account;
+import android.accounts.AccountsException;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Pair;
+
+public class OperationsService extends Service {
+
+ private static final String TAG = OperationsService.class.getSimpleName();
+
+ public static final String EXTRA_ACCOUNT = "ACCOUNT";
+ public static final String EXTRA_SERVER_URL = "SERVER_URL";
+ public static final String EXTRA_RESULT = "RESULT";
+
+ 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 static class Target {
+ public Uri mServerUrl = null;
+ public Account mAccount = null;
+ public Target(Account account, Uri serverUrl) {
+ mAccount = account;
+ mServerUrl = serverUrl;
+ }
+ }
+
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+ private IBinder mBinder;
+ private OwnCloudClient mOwnCloudClient = null;
+ private Target mLastTarget = null;
+ private FileDataStorageManager mStorageManager;
+ private RemoteOperation mCurrentOperation = null;
+
+
+ /**
+ * Service initialization
+ */
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ HandlerThread thread = new HandlerThread("Operations service thread", Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper, this);
+ mBinder = new OperationsServiceBinder();
+ }
+
+ /**
+ * Entry point to add a new operation to the queue of operations.
+ *
+ * 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) {
+ 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));
+ GetSharesOperation operation = new GetSharesOperation();
+ 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;
+ }
+
+ return START_NOT_STICKY;
+ }
+
+
+ /**
+ * Provides a binder object that clients can use to perform actions on the queue of operations,
+ * except the addition of new operations.
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+
+ /**
+ * Called when ALL the bound clients were unbound.
+ */
+ @Override
+ public boolean onUnbind(Intent intent) {
+ //((OperationsServiceBinder)mBinder).clearListeners();
+ return false; // not accepting rebinding (default behaviour)
+ }
+
+
+ /**
+ * Binder to let client components to perform actions on the queue of operations.
+ *
+ * It provides by itself the available operations.
+ */
+ public class OperationsServiceBinder extends Binder {
+ // TODO
+ }
+
+
+ /**
+ * 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()}.
+ */
+ private static class ServiceHandler 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;
+ public ServiceHandler(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) {
+ mService.nextOperation();
+ mService.stopSelf(msg.arg1);
+ }
+ }
+
+
+ /**
+ * Performs the next operation in the queue
+ */
+ private void nextOperation() {
+
+ Pair next = null;
+ synchronized(mPendingOperations) {
+ next = mPendingOperations.peek();
+ }
+
+ if (next != null) {
+
+ mCurrentOperation = next.second;
+ RemoteOperationResult result = null;
+ try {
+ /// prepare client object to send the request to the ownCloud server
+ 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());
+ } else {
+ mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), true); // this is not good enough
+ mStorageManager = null;
+ }
+ }
+
+ /// perform the operation
+ if (mCurrentOperation instanceof SyncOperation) {
+ result = ((SyncOperation)mCurrentOperation).execute(mOwnCloudClient, mStorageManager);
+ } else {
+ result = mCurrentOperation.execute(mOwnCloudClient);
+ }
+
+ } catch (AccountsException e) {
+ if (mLastTarget.mAccount == null) {
+ Log_OC.e(TAG, "Error while trying to get autorization for a NULL account", e);
+ } else {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastTarget.mAccount.name, e);
+ }
+ result = new RemoteOperationResult(e);
+
+ } catch (IOException e) {
+ if (mLastTarget.mAccount == null) {
+ Log_OC.e(TAG, "Error while trying to get autorization for a NULL account", e);
+ } else {
+ Log_OC.e(TAG, "Error while trying to get autorization for " + mLastTarget.mAccount.name, e);
+ }
+ result = new RemoteOperationResult(e);
+
+ } finally {
+ synchronized(mPendingOperations) {
+ mPendingOperations.poll();
+ }
+ }
+
+ sendBroadcastOperationFinished(mLastTarget, mCurrentOperation, result);
+ }
+ }
+
+
+ /**
+ * Sends a LOCAL broadcast when a new operation is added to the queue.
+ *
+ * Local broadcasts are only delivered to activities in the same process.
+ *
+ * @param target Account or URL pointing to an OC server.
+ * @param operation Added operation.
+ */
+ private void sendBroadcastNewOperation(Target target, RemoteOperation operation) {
+ Intent intent = new Intent(ACTION_OPERATION_ADDED);
+ if (target.mAccount != null) {
+ intent.putExtra(EXTRA_ACCOUNT, target.mAccount);
+ } else {
+ intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl);
+ }
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+ lbm.sendBroadcast(intent);
+ }
+
+
+ // TODO - maybe add a notification for real start of operations
+
+ /**
+ * Sends a LOCAL broadcast when an operations finishes in order to the interested activities can update their view
+ *
+ * Local broadcasts are only delivered to activities in the same process.
+ *
+ * @param target Account or URL pointing to an OC server.
+ * @param operation Finished operation.
+ * @param result Result of the operation.
+ */
+ private void sendBroadcastOperationFinished(Target target, RemoteOperation operation, RemoteOperationResult result) {
+ Intent intent = new Intent(ACTION_OPERATION_FINISHED);
+ intent.putExtra(EXTRA_RESULT, result);
+ if (target.mAccount != null) {
+ intent.putExtra(EXTRA_ACCOUNT, target.mAccount);
+ } else {
+ intent.putExtra(EXTRA_SERVER_URL, target.mServerUrl);
+ }
+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+ lbm.sendBroadcast(intent);
+ }
+
+
+}
diff --git a/src/com/owncloud/android/ui/activity/FileActivity.java b/src/com/owncloud/android/ui/activity/FileActivity.java
index 471214b25e..4f42597f3e 100644
--- a/src/com/owncloud/android/ui/activity/FileActivity.java
+++ b/src/com/owncloud/android/ui/activity/FileActivity.java
@@ -35,6 +35,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.webkit.MimeTypeMap;
+import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.owncloud.android.MainApp;
@@ -370,36 +371,47 @@ public abstract class FileActivity extends SherlockFragmentActivity {
*/
public void shareFileWithLink(OCFile file) {
- if (file != null) {
-
- //CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1);
- //createShare.execute(getAccount(), this, this, mHandler, this);
-
- String link = "https://fake.url.lolo";
- Intent chooserIntent = null;
- List targetedShareIntents = new ArrayList();
- List resInfo = getPackageManager().queryIntentActivities(createShareWithLinkIntent(link), PackageManager.MATCH_DEFAULT_ONLY);
- String myPackageName = getPackageName();
- if (!resInfo.isEmpty()) {
- for (ResolveInfo info : resInfo) {
- if (!info.activityInfo.packageName.equalsIgnoreCase(myPackageName)) {
- Intent targetedShare = createTargetedShare(link, info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
- targetedShareIntents.add(targetedShare);
+ if (isSharedSupported()) {
+ if (file != null) {
+
+ // Create the Share
+ //CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1);
+ //createShare.execute(getStorageManager(), this, this, mHandler, this);
+
+ // TODO
+ // Get the link --> when the operation is finished
+
+ String link = "https://fake.url.lolo";
+ Intent chooserIntent = null;
+ List targetedShareIntents = new ArrayList();
+ List resInfo = getPackageManager().queryIntentActivities(createShareWithLinkIntent(link), PackageManager.MATCH_DEFAULT_ONLY);
+ String myPackageName = getPackageName();
+ if (!resInfo.isEmpty()) {
+ for (ResolveInfo info : resInfo) {
+ if (!info.activityInfo.packageName.equalsIgnoreCase(myPackageName)) {
+ Intent targetedShare = createTargetedShare(link, info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
+ targetedShareIntents.add(targetedShare);
+ }
}
}
- }
- if (targetedShareIntents.size() > 0) {
- Intent firstTargeted = targetedShareIntents.remove(0);
- chooserIntent = Intent.createChooser(firstTargeted, getString(R.string.action_share_file));
- chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {}));
+ if (targetedShareIntents.size() > 0) {
+ Intent firstTargeted = targetedShareIntents.remove(0);
+ chooserIntent = Intent.createChooser(firstTargeted, getString(R.string.action_share_file));
+ chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {}));
+ } else {
+ // to show standard message
+ chooserIntent = Intent.createChooser(null, getString(R.string.action_share_file));
+ }
+ startActivity(chooserIntent);
+
} else {
- // to show standard message
- chooserIntent = Intent.createChooser(null, getString(R.string.action_share_file));
+ Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
}
- startActivity(chooserIntent);
} else {
- Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
+ // Show a Message
+ Toast t = Toast.makeText(this, getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG);
+ t.show();
}
}
diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
index f684b790ff..237113d8ff 100644
--- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
+++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
@@ -45,6 +45,7 @@ import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
+import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -69,17 +70,16 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.operations.CreateFolderOperation;
-import com.owncloud.android.operations.GetSharesOperation;
-
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.lib.operations.common.RemoteOperationResult.ResultCode;
-
+import com.owncloud.android.operations.CreateShareOperation;
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.services.OperationsService;
import com.owncloud.android.syncadapter.FileSyncService;
import com.owncloud.android.ui.dialog.EditNameDialog;
import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener;
@@ -114,6 +114,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
private SyncBroadcastReceiver mSyncBroadcastReceiver;
private UploadFinishReceiver mUploadFinishReceiver;
private DownloadFinishReceiver mDownloadFinishReceiver;
+ private OperationsServiceReceiver mOperationsServiceReceiver;
private FileDownloaderBinder mDownloaderBinder = null;
private FileUploaderBinder mUploaderBinder = null;
private ServiceConnection mDownloadConnection = null, mUploadConnection = null;
@@ -703,6 +704,12 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
downloadIntentFilter.addAction(FileDownloader.getDownloadFinishMessage());
mDownloadFinishReceiver = new DownloadFinishReceiver();
registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
+
+ // Listen for messages from the OperationsService
+ IntentFilter operationsIntentFilter = new IntentFilter(OperationsService.ACTION_OPERATION_ADDED);
+ operationsIntentFilter.addAction(OperationsService.ACTION_OPERATION_FINISHED);
+ mOperationsServiceReceiver = new OperationsServiceReceiver();
+ LocalBroadcastManager.getInstance(this).registerReceiver(mOperationsServiceReceiver, operationsIntentFilter);
Log_OC.d(TAG, "onResume() end");
}
@@ -724,7 +731,10 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
unregisterReceiver(mDownloadFinishReceiver);
mDownloadFinishReceiver = null;
}
-
+ if (mOperationsServiceReceiver != null) {
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(mOperationsServiceReceiver);
+ mOperationsServiceReceiver = null;
+ }
Log_OC.d(TAG, "onPause() end");
}
@@ -1031,6 +1041,45 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
return (accountName != null && getAccount() != null && accountName.equals(getAccount().name));
}
}
+
+
+ /**
+ * Class waiting for broadcast events from the {@link OperationsService}.
+ *
+ * Updates the list of files when a get for shares is finished; at this moment the refresh of shares is the only
+ * operation performed in {@link OperationsService}.
+ *
+ * In the future will handle the progress or finalization of all the operations performed in {@link OperationsService},
+ * probably all the operations associated to the app model.
+ */
+ private class OperationsServiceReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (OperationsService.ACTION_OPERATION_ADDED.equals(intent.getAction())) {
+
+ } else if (OperationsService.ACTION_OPERATION_FINISHED.equals(intent.getAction())) {
+ mRefreshSharesInProgress = false;
+
+ Account account = intent.getParcelableExtra(OperationsService.EXTRA_ACCOUNT);
+ RemoteOperationResult getSharesResult = (RemoteOperationResult)intent.getSerializableExtra(OperationsService.EXTRA_RESULT);
+ if (getAccount() != null && account.name.equals(getAccount().name)
+ && mStorageManager != null
+ ) {
+ refeshListOfFilesFragment();
+ }
+ if ((getSharesResult != null) &&
+ RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED.equals(getSharesResult.getCode())) {
+ mLastSslUntrustedServerResult = getSharesResult;
+ showDialog(DIALOG_SSL_VALIDATOR);
+ }
+
+ setSupportProgressBarIndeterminateVisibility(mRefreshSharesInProgress || mSyncInProgress);
+ }
+
+ }
+
+ }
/**
@@ -1295,27 +1344,23 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
} else if (operation instanceof CreateFolderOperation) {
onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
-
- } else if (operation instanceof GetSharesOperation) {
- onGetSharesOperationFinish((GetSharesOperation) operation, result);
+
+ } else if (operation instanceof CreateShareOperation) {
+ onCreateShareOperation((CreateShareOperation) operation, result);
}
+
}
- /** Updates the data about shared files
- *
- * @param operation Get Shared Files
- * @param result Result of the operation
- */
- private void onGetSharesOperationFinish(GetSharesOperation operation, RemoteOperationResult result) {
- // Refresh the filelist with the information
- refeshListOfFilesFragment();
-
- mRefreshSharesInProgress = false;
-
- if (!mSyncInProgress) {
- setSupportProgressBarIndeterminateVisibility(false);
+ private void onCreateShareOperation(CreateShareOperation operation, RemoteOperationResult result) {
+ if (result.getCode() == ResultCode.FILE_NOT_FOUND) {
+ // Show a Message
+ Toast t = Toast.makeText(this, getString(R.string.share_link_file_no_exist), Toast.LENGTH_LONG);
+ t.show();
}
+
+ refeshListOfFilesFragment();
+
}
/**
@@ -1529,23 +1574,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
private void startGetShares() {
// Get shared files/folders
- RemoteOperation getShares = new GetSharesOperation(mStorageManager);
- getShares.execute(getAccount(), this, this, mHandler, this);
+ Intent intent = new Intent(this, OperationsService.class);
+ intent.putExtra(OperationsService.EXTRA_ACCOUNT, getAccount());
+ startService(intent);
mRefreshSharesInProgress = true;
setSupportProgressBarIndeterminateVisibility(true);
}
-// public void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
-// int childCount = viewGroup.getChildCount();
-// for (int i = 0; i < childCount; i++) {
-// View view = viewGroup.getChildAt(i);
-// view.setEnabled(enabled);
-// view.setClickable(!enabled);
-// if (view instanceof ViewGroup) {
-// enableDisableViewGroup((ViewGroup) view, enabled);
-// }
-// }
-// }
}
diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
index eebbef8d6b..0eacfe4403 100644
--- a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
+++ b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
@@ -55,9 +55,6 @@ 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.lib.operations.common.RemoteOperationResult.ResultCode;
-import com.owncloud.android.lib.operations.common.ShareType;
-import com.owncloud.android.lib.operations.remote.CreateShareRemoteOperation;
-import com.owncloud.android.operations.CreateShareOperation;
import com.owncloud.android.operations.RemoveFileOperation;
import com.owncloud.android.operations.RenameFileOperation;
import com.owncloud.android.operations.SynchronizeFileOperation;