Merge branch 'share_link__unshare_file' into wide_scope_library_clean_up
authorDavid A. Velasco <dvelasco@solidgear.es>
Mon, 17 Feb 2014 12:01:55 +0000 (13:01 +0100)
committerDavid A. Velasco <dvelasco@solidgear.es>
Mon, 17 Feb 2014 12:01:55 +0000 (13:01 +0100)
15 files changed:
1  2 
src/com/owncloud/android/datamodel/FileDataStorageManager.java
src/com/owncloud/android/files/FileOperationsHelper.java
src/com/owncloud/android/files/services/FileDownloader.java
src/com/owncloud/android/files/services/FileUploader.java
src/com/owncloud/android/operations/CreateShareOperation.java
src/com/owncloud/android/operations/GetSharesOperation.java
src/com/owncloud/android/operations/UnshareLinkOperation.java
src/com/owncloud/android/services/OperationsService.java
src/com/owncloud/android/ui/activity/FileActivity.java
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/fragment/FileDetailFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/ui/preview/PreviewImageActivity.java
src/com/owncloud/android/ui/preview/PreviewImageFragment.java
src/com/owncloud/android/ui/preview/PreviewMediaFragment.java

@@@ -27,9 -27,9 +27,9 @@@ import java.util.Vector
  
  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.lib.resources.shares.OCShare;
 +import com.owncloud.android.lib.resources.shares.ShareType;
 +import com.owncloud.android.lib.resources.files.FileUtils;
  import com.owncloud.android.utils.FileStorageUtils;
  import com.owncloud.android.utils.Log_OC;
  
@@@ -1115,8 -1115,22 +1115,22 @@@ public class FileDataStorageManager 
          }
          
      } 
+     
+     public void removeShare(OCShare share){
+         Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE;
+         String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+         String [] whereArgs = new String[]{mAccount.name, share.getPath()};
+         if (getContentProviderClient() != null) {
+             try {
+                 getContentProviderClient().delete(share_uri, where, whereArgs);
+             } catch (RemoteException e) {
+                 e.printStackTrace();
+             }
+         } else {
+             getContentResolver().delete(share_uri, where, whereArgs); 
+         }
+     }
+     
      public void saveSharesDB(ArrayList<OCShare> shares) {
          saveShares(shares);
  
@@@ -28,10 -28,9 +28,9 @@@ import android.widget.Toast
  
  import com.owncloud.android.R;
  import com.owncloud.android.datamodel.OCFile;
 -import com.owncloud.android.lib.accounts.OwnCloudAccount;
 -import com.owncloud.android.lib.network.webdav.WebdavUtils;
 +import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
 +import com.owncloud.android.lib.common.network.WebdavUtils;
- import com.owncloud.android.lib.resources.shares.ShareType;
- import com.owncloud.android.operations.CreateShareOperation;
+ import com.owncloud.android.services.OperationsService;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.dialog.ActivityChooserDialog;
  import com.owncloud.android.utils.Log_OC;
@@@ -108,12 -107,13 +107,13 @@@ public class FileOperationsHelper 
          
          if (file != null) {
              callerActivity.showLoadingDialog();
-             CreateShareOperation createShare = new CreateShareOperation(file.getRemotePath(), ShareType.PUBLIC_LINK, "", false, "", 1, sendIntent);
-             createShare.execute(callerActivity.getStorageManager(), 
-                                 callerActivity, 
-                                 callerActivity.getRemoteOperationListener(), 
-                                 callerActivity.getHandler(), 
-                                 callerActivity);
+             
+             Intent service = new Intent(callerActivity, OperationsService.class);
+             service.setAction(OperationsService.ACTION_CREATE_SHARE);
+             service.putExtra(OperationsService.EXTRA_ACCOUNT, callerActivity.getAccount());
+             service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+             service.putExtra(OperationsService.EXTRA_SEND_INTENT, sendIntent);
+             callerActivity.startService(service);
              
          } else {
              Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
      public boolean isSharedSupported(FileActivity callerActivity) {
          if (callerActivity.getAccount() != null) {
              AccountManager accountManager = AccountManager.get(callerActivity);
 -            return Boolean.parseBoolean(accountManager.getUserData(callerActivity.getAccount(), OwnCloudAccount.Constants.KEY_SUPPORTS_SHARE_API));
 +            return Boolean.parseBoolean(accountManager.getUserData(callerActivity.getAccount(), Constants.KEY_SUPPORTS_SHARE_API));
          }
          return false;
      }
  
+     
+     public void unshareFileWithLink(OCFile file, FileActivity callerActivity) {
+         
+         if (isSharedSupported(callerActivity)) {
+             // Unshare the file
+             Intent service = new Intent(callerActivity, OperationsService.class);
+             service.setAction(OperationsService.ACTION_UNSHARE);
+             service.putExtra(OperationsService.EXTRA_ACCOUNT, callerActivity.getAccount());
+             service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+             callerActivity.startService(service);
+             
+             callerActivity.showLoadingDialog();
+             
+         } else {
+             // Show a Message
+             Toast t = Toast.makeText(callerActivity, callerActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG);
+             t.show();
+             
+         }
+     }
  }
@@@ -33,13 -33,13 +33,13 @@@ import com.owncloud.android.authenticat
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
  
 -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.lib.common.network.OnDatatransferProgressListener;
 +import com.owncloud.android.lib.common.OwnCloudClientFactory;
 +import com.owncloud.android.lib.common.OwnCloudClient;
  import com.owncloud.android.operations.DownloadFileOperation;
 -import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 -import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
 -import com.owncloud.android.lib.utils.FileUtils;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 +import com.owncloud.android.lib.resources.files.FileUtils;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.activity.FileDisplayActivity;
  import com.owncloud.android.ui.preview.PreviewImageActivity;
@@@ -382,7 -382,7 +382,7 @@@ public class FileDownloader extends Ser
       * Updates the OC File after a successful download.
       */
      private void saveDownloadedFile() {
-         OCFile file = mCurrentDownload.getFile();
+         OCFile file = mStorageManager.getFileById(mCurrentDownload.getFile().getFileId());
          long syncDate = System.currentTimeMillis();
          file.setLastSyncDateForProperties(syncDate);
          file.setLastSyncDateForData(syncDate);
@@@ -34,19 -34,19 +34,19 @@@ import com.owncloud.android.datamodel.F
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.db.DbHandler;
  import com.owncloud.android.operations.CreateFolderOperation;
 -import com.owncloud.android.lib.operations.common.RemoteFile;
 -import com.owncloud.android.lib.operations.common.RemoteOperation;
 -import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 +import com.owncloud.android.lib.resources.files.RemoteFile;
 +import com.owncloud.android.lib.common.operations.RemoteOperation;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  import com.owncloud.android.operations.UploadFileOperation;
 -import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
 -import com.owncloud.android.lib.operations.remote.ExistenceCheckRemoteOperation;
 -import com.owncloud.android.lib.operations.remote.ReadRemoteFileOperation;
 -import com.owncloud.android.lib.utils.FileUtils;
 -import com.owncloud.android.lib.utils.OwnCloudVersion;
 -import com.owncloud.android.lib.network.OnDatatransferProgressListener;
 -import com.owncloud.android.lib.accounts.OwnCloudAccount;
 -import com.owncloud.android.lib.network.OwnCloudClientFactory;
 -import com.owncloud.android.lib.network.OwnCloudClient;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 +import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
 +import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
 +import com.owncloud.android.lib.resources.files.FileUtils;
 +import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 +import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
 +import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 +import com.owncloud.android.lib.common.OwnCloudClientFactory;
 +import com.owncloud.android.lib.common.OwnCloudClient;
  import com.owncloud.android.ui.activity.FailedUploadActivity;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.activity.FileDisplayActivity;
@@@ -253,7 -253,7 +253,7 @@@ public class FileUploader extends Servi
              }
          }
  
 -        OwnCloudVersion ocv = new OwnCloudVersion(AccountManager.get(this).getUserData(account, OwnCloudAccount.Constants.KEY_OC_VERSION));
 +        OwnCloudVersion ocv = new OwnCloudVersion(AccountManager.get(this).getUserData(account, Constants.KEY_OC_VERSION));
          boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
          AbstractList<String> requestedUploads = new Vector<String>();
          String uploadKey = null;
       */
      private void saveUploadedFile() {
          OCFile file = mCurrentUpload.getFile();
+         if (file.fileExists()) {
+             file = mStorageManager.getFileById(file.getFileId());
+         }
          long syncDate = System.currentTimeMillis();
          file.setLastSyncDateForData(syncDate);
  
@@@ -28,12 -28,12 +28,12 @@@ import android.content.Intent
  
  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.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.lib.common.OwnCloudClient;
 +import com.owncloud.android.lib.resources.shares.OCShare;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 +import com.owncloud.android.lib.resources.shares.ShareType;
 +import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation;
 +import com.owncloud.android.lib.resources.files.FileUtils;
  import com.owncloud.android.operations.common.SyncOperation;
  import com.owncloud.android.utils.Log_OC;
  
@@@ -83,7 -83,7 +83,7 @@@ public class CreateShareOperation exten
  
      @Override
      protected RemoteOperationResult run(OwnCloudClient client) {
 -        CreateShareRemoteOperation operation = new CreateShareRemoteOperation(mPath, mShareType, mShareWith, mPublicUpload, mPassword, mPermissions);
 +        CreateRemoteShareOperation operation = new CreateRemoteShareOperation(mPath, mShareType, mShareWith, mPublicUpload, mPassword, mPermissions);
          RemoteOperationResult result = operation.execute(client);
  
          if (result.isSuccess()) {
                  OCShare share = (OCShare) result.getData().get(0);
  
                  // Update DB with the response
+                 share.setPath(mPath);
                  if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) {
-                     share.setPath(mPath.substring(0, mPath.length()-1));
                      share.setIsFolder(true);
-                     
                  } else {
-                     share.setPath(mPath);
                      share.setIsFolder(false);
                  }
                  share.setPermissions(mPermissions);
@@@ -1,5 -1,5 +1,5 @@@
  /* ownCloud Android client application
-  *   Copyright (C) 2012-2013 ownCloud Inc.
+  *   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,
@@@ -19,10 -19,10 +19,10 @@@ package com.owncloud.android.operations
  
  import java.util.ArrayList;
  
 -import com.owncloud.android.lib.network.OwnCloudClient;
 -import com.owncloud.android.lib.operations.common.RemoteOperationResult;
 -import com.owncloud.android.lib.operations.common.OCShare;
 -import com.owncloud.android.lib.operations.remote.GetRemoteSharesOperation;
 +import com.owncloud.android.lib.common.OwnCloudClient;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 +import com.owncloud.android.lib.resources.shares.OCShare;
 +import com.owncloud.android.lib.resources.shares.GetRemoteSharesOperation;
  import com.owncloud.android.operations.common.SyncOperation;
  import com.owncloud.android.utils.Log_OC;
  
index 0000000,d4f9c37..2bacc4b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,93 +1,93 @@@
 -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.common.RemoteOperationResult.ResultCode;
 -import com.owncloud.android.lib.operations.remote.ExistenceCheckRemoteOperation;
+ /* ownCloud Android client application
+  *   Copyright (C) 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 <http://www.gnu.org/licenses/>.
+  *
+  */
+ package com.owncloud.android.operations;
+ import android.content.Context;
+ import com.owncloud.android.datamodel.OCFile;
++import com.owncloud.android.lib.common.OwnCloudClient;
++import com.owncloud.android.lib.common.operations.RemoteOperationResult;
++import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
++import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
++import com.owncloud.android.lib.resources.shares.OCShare;
+ import com.owncloud.android.lib.operations.remote.RemoveRemoteShareOperation;
+ import com.owncloud.android.operations.common.SyncOperation;
+ import com.owncloud.android.utils.Log_OC;
+ /**
+  * Unshare file/folder
+  * Save the data in Database
+  * 
+  * @author masensio
+  */
+ public class UnshareLinkOperation extends SyncOperation {
+     private static final String TAG = UnshareLinkOperation.class.getSimpleName();
+     
+     private String mRemotePath;
+     private Context mContext;
+     
+     
+     public UnshareLinkOperation(String remotePath, Context context) {
+         mRemotePath = remotePath;
+         mContext = context;
+     }
+     @Override
+     protected RemoteOperationResult run(OwnCloudClient client) {
+         RemoteOperationResult result  = null;
+         
+         // Get Share for a file
+         OCShare share = getStorageManager().getShareByPath(mRemotePath);
+         
+         if (share != null) {
+             RemoveRemoteShareOperation operation = new RemoveRemoteShareOperation((int) share.getIdRemoteShared());
+             result = operation.execute(client);
+             if (result.isSuccess() || result.getCode() == ResultCode.SHARE_NOT_FOUND) {
+                 Log_OC.d(TAG, "Share id = " + share.getIdRemoteShared() + " deleted");
+                 OCFile file = getStorageManager().getFileByPath(mRemotePath);
+                 file.setShareByLink(false);
+                 file.setPublicLink("");
+                 getStorageManager().saveFile(file);
+                 getStorageManager().removeShare(share);
+                 
+                 if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
+                     if (existsFile(client, file.getRemotePath())) {
+                         result = new RemoteOperationResult(ResultCode.OK);
+                     } else {
+                         getStorageManager().removeFile(file, true, true);
+                     }
+                 }
+             } 
+                 
+         } else {
+             result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND);
+         }
+         return result;
+     }
+     
+     private boolean existsFile(OwnCloudClient client, String remotePath){
+         ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext, false);
+         RemoteOperationResult result = existsOperation.execute(client);
+         return result.isSuccess();
+     }
+ }
  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.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.lib.common.OwnCloudClientFactory;
 +import com.owncloud.android.lib.common.OwnCloudClient;
- import com.owncloud.android.operations.GetSharesOperation;
- import com.owncloud.android.operations.common.SyncOperation;
++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.shares.ShareType;
++import com.owncloud.android.operations.common.SyncOperation;
+ import com.owncloud.android.operations.CreateShareOperation;
+ import com.owncloud.android.operations.UnshareLinkOperation;
 -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.lib.operations.common.ShareType;
  import com.owncloud.android.utils.Log_OC;
  
  import android.accounts.Account;
@@@ -51,7 -57,12 +56,12 @@@ public class OperationsService extends 
      
      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 EXTRA_REMOTE_PATH = "REMOTE_PATH";
+     public static final String EXTRA_SEND_INTENT = "SEND_INTENT";
+     public static final String EXTRA_RESULT = "RESULT";
+     
+     public static final String ACTION_CREATE_SHARE = "CREATE_SHARE";
+     public static final String ACTION_UNSHARE = "UNSHARE";
      
      public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED";
      public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED";
@@@ -69,7 -80,7 +79,7 @@@
  
      private Looper mServiceLooper;
      private ServiceHandler mServiceHandler;
-     private IBinder mBinder;
+     private OperationsServiceBinder mBinder;
      private OwnCloudClient mOwnCloudClient = null;
      private Target mLastTarget = null;
      private FileDataStorageManager mStorageManager;
          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();
+             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 {
+                 // nothing we are going to handle
+                 return START_NOT_STICKY;
+             }
+             
              mPendingOperations.add(new Pair<Target , RemoteOperation>(target, operation));
-             sendBroadcastNewOperation(target, operation);
+             //sendBroadcastNewOperation(target, operation);
              
              Message msg = mServiceHandler.obtainMessage();
              msg.arg1 = startId;
       * 
       *  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 Map<OnRemoteOperationListener, Handler> mBoundListeners = new HashMap<OnRemoteOperationListener, Handler>();
+         
+         /**
+          * 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.    
+          * @param callbackHandler   {@link Handler} to access the listener without breaking Android threading protection.
+          */
+         public void addOperationListener (OnRemoteOperationListener listener, Handler callbackHandler) {
+             mBoundListeners.put(listener, callbackHandler);
+         }
+         
+         
+         /**
+          * 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.isEmpty());
+         }
      }
      
      
                  }
              }
              
-             sendBroadcastOperationFinished(mLastTarget, mCurrentOperation, result);
+             //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.
          //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, final RemoteOperation operation, final RemoteOperationResult result) {
+         Iterator<OnRemoteOperationListener> listeners = mBinder.mBoundListeners.keySet().iterator();
+         while (listeners.hasNext()) {
+             final OnRemoteOperationListener listener = listeners.next();
+             final Handler handler = mBinder.mBoundListeners.get(listener);
+             if (handler != null) { 
+                 handler.post(new Runnable() {
+                     @Override
+                     public void run() {
+                         listener.onRemoteOperationFinish(operation, result);
+                     }
+                 });
+             }
+         }
+             
+     }
      
  }
@@@ -23,9 -23,13 +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;
@@@ -38,12 -42,15 +42,15 @@@ import com.owncloud.android.authenticat
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.files.FileOperationsHelper;
 -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.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.operations.RemoteOperationResult.ResultCode;
  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;
  
@@@ -90,6 -97,10 +97,10 @@@ public class FileActivity extends Sherl
      private FileDataStorageManager mStorageManager = null;
      
      private FileOperationsHelper mFileOperationsHelper;
+     
+     private ServiceConnection mOperationsServiceConnection = null;
+     
+     private OperationsServiceBinder mOperationsServiceBinder = null;
  
      
      /**
          }
  
          setAccount(account, savedInstanceState != null);
-        
+         
+         mOperationsServiceConnection = new OperationsServiceConnection();
+         bindService(new Intent(this, OperationsService.class), mOperationsServiceConnection, Context.BIND_AUTO_CREATE);
      }
  
      
          if (!validAccount) {
              swapToDefaultAccount();
          }
-         
      }
  
      
          if (mAccountWasSet) {
              onAccountSet(mAccountWasRestored);
          }
+         if (mOperationsServiceBinder != null) {
+             mOperationsServiceBinder.addOperationListener(FileActivity.this, mHandler);
+         }
+     }
+     
+     
+     @Override 
+     protected void onStop() {
+         super.onStop();
+         if (mOperationsServiceBinder != null) {
+             mOperationsServiceBinder.removeOperationListener(this);
+         }
+     }
+     
+     
+     @Override
+     protected void onDestroy() {
+         super.onDestroy();
+         if (mOperationsServiceConnection != null) {
+             unbindService(mOperationsServiceConnection);
+             mOperationsServiceBinder = null;
+         }
      }
      
      
          Log_OC.d(TAG, "Received result of operation in FileActivity - common behaviour for all the FileActivities ");
          if (operation instanceof CreateShareOperation) {
              onCreateShareOperationFinish((CreateShareOperation) operation, result);
-         }
+             
+         } else if (operation instanceof UnshareLinkOperation) {
+             onUnshareLinkOperationFinish((UnshareLinkOperation)operation, result);
+         
+         } 
      }
  
      private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
          dismissLoadingDialog();
          if (result.isSuccess()) {
+             updateFileFromDB();
+             
              Intent sendIntent = operation.getSendIntent();
              startActivity(sendIntent);
              
-         } else if (result.getCode() == ResultCode.FILE_NOT_FOUND)  {        // Error --> SHARE_NOT_FOUND
+         } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND)  {        // Error --> SHARE_NOT_FOUND
                  Toast t = Toast.makeText(this, getString(R.string.share_link_file_no_exist), Toast.LENGTH_LONG);
                  t.show();
          } else {    // Generic error
      }
      
      
+     private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, RemoteOperationResult result) {
+         dismissLoadingDialog();
+         
+         if (result.isSuccess()){
+             updateFileFromDB();
+             
+         } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND)  {        // Error --> SHARE_NOT_FOUND
+             Toast t = Toast.makeText(this, getString(R.string.unshare_link_file_no_exist), Toast.LENGTH_LONG);
+             t.show();
+         } else {    // Generic error
+             // Show a Message, operation finished without success
+             Toast t = Toast.makeText(this, getString(R.string.unshare_link_file_error), Toast.LENGTH_LONG);
+             t.show();
+         }
+         
+     }
+     
+     
+     private void updateFileFromDB(){
+       OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath());
+       if (file != null) {
+           setFile(file);
+       }
+     }
+     
      /**
       * Show loading dialog 
       */
              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, mHandler);
+                 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
+             }
+         }
+     };    
      
  }
@@@ -67,14 -67,15 +67,15 @@@ import com.owncloud.android.files.servi
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
  import com.owncloud.android.operations.CreateFolderOperation;
  
 -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.common.operations.RemoteOperation;
 +import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 +import com.owncloud.android.lib.common.operations.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.operations.UnshareLinkOperation;
  import com.owncloud.android.services.OperationsService;
  import com.owncloud.android.syncadapter.FileSyncAdapter;
  import com.owncloud.android.ui.dialog.EditNameDialog;
@@@ -85,6 -86,7 +86,7 @@@ import com.owncloud.android.ui.fragment
  import com.owncloud.android.ui.fragment.FileFragment;
  import com.owncloud.android.ui.fragment.OCFileListFragment;
  import com.owncloud.android.ui.preview.PreviewImageActivity;
+ import com.owncloud.android.ui.preview.PreviewImageFragment;
  import com.owncloud.android.ui.preview.PreviewMediaFragment;
  import com.owncloud.android.ui.preview.PreviewVideoActivity;
  import com.owncloud.android.utils.DisplayUtils;
@@@ -186,6 -188,11 +188,11 @@@ OCFileListFragment.ContainerActivity, F
          mRightFragmentContainer = findViewById(R.id.right_fragment_container);
          if (savedInstanceState == null) {
              createMinFragments();
+         } else {
+             Log_OC.d(TAG, "Init the secondFragment again");
+             if (mDualPane) {
+                 initFragmentsWithFile();                
+             }
          }
  
          // Action bar setup
      protected void onStart() {
          super.onStart();
          getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
+         refeshListOfFilesFragment();
      }
  
      @Override
          transaction.add(R.id.left_fragment_container, listOfFiles, TAG_LIST_OF_FILES);
          transaction.commit();
      }
+     
      private void initFragmentsWithFile() {
          if (getAccount() != null && getFile() != null) {
              /// First fragment
  
          } else if (operation instanceof CreateFolderOperation) {
              onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
-         
+             
          } else if (operation instanceof CreateShareOperation) {
              onCreateShareOperationFinish((CreateShareOperation) operation, result);
-         }
+             
+         } else if (operation instanceof UnshareLinkOperation) {
+             onUnshareLinkOperationFinish((UnshareLinkOperation)operation, result);
+         
+         } 
          
      }
  
+     
      private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
          if (result.isSuccess()) {
+             refreshShowDetails();
              refeshListOfFilesFragment();
          }
      }
  
      
+     private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, RemoteOperationResult result) {
+         if (result.isSuccess()) {
+             refreshShowDetails();
+             refeshListOfFilesFragment();
+         } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
+             cleanSecondFragment();
+             refeshListOfFilesFragment();
+         }
+     }
+     
+     private void refreshShowDetails() {
+         FileFragment details = getSecondFragment();
+         if (details != null) {
+             OCFile file = details.getFile();
+             if (file != null) {
+                 file = getStorageManager().getFileByPath(file.getRemotePath()); 
+                 if (details instanceof PreviewMediaFragment) {
+                     // Refresh  OCFile of the fragment
+                     ((PreviewMediaFragment) details).updateFile(file);
+                 } else {
+                     showDetails(file);
+                 } 
+             }
+             invalidateOptionsMenu();
+         } 
+     }
+     
      /**
       * Updates the view associated to the activity after the finish of an operation trying to remove a 
       * file. 
@@@ -50,11 -50,11 +50,11 @@@ import com.owncloud.android.files.servi
  import com.owncloud.android.files.services.FileUploader;
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 -import com.owncloud.android.lib.network.OnDatatransferProgressListener;
 -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.common.network.OnDatatransferProgressListener;
 +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.operations.RemoteOperationResult.ResultCode;
  import com.owncloud.android.operations.RemoveFileOperation;
  import com.owncloud.android.operations.RenameFileOperation;
  import com.owncloud.android.operations.SynchronizeFileOperation;
@@@ -186,6 -186,10 +186,10 @@@ public class FileDetailFragment extend
          super.onActivityCreated(savedInstanceState);
          if (mAccount != null) {
              mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
+             OCFile file = mStorageManager.getFileByPath(getFile().getRemotePath());
+             if (file != null) {
+                 setFile(file);
+             }
          }
      }
          
              toHide.add(R.id.action_remove_file);
              
          }
+         
+         // Options shareLink
+         if (!file.isShareByLink()) {
+             toHide.add(R.id.action_unshare_file);
+         } else {
+             toShow.add(R.id.action_unshare_file);
+         }
+         
          MenuItem item = null;
          for (int i : toHide) {
              item = menu.findItem(i);
                  activity.getFileOperationsHelper().shareFileWithLink(getFile(), activity);
                  return true;
              }
+             case R.id.action_unshare_file: {
+                 FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                 activity.getFileOperationsHelper().unshareFileWithLink(getFile(), activity);
+                 return true;
+             }
              case R.id.action_open_file_with: {
                  FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
                  activity.getFileOperationsHelper().openFile(getFile(), activity);
@@@ -27,8 -27,8 +27,8 @@@ import com.owncloud.android.datamodel.F
  import com.owncloud.android.datamodel.OCFile;
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 -import com.owncloud.android.lib.operations.common.OnRemoteOperationListener;
 -import com.owncloud.android.lib.operations.common.RemoteOperation;
 +import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 +import com.owncloud.android.lib.common.operations.RemoteOperation;
  import com.owncloud.android.operations.RemoveFileOperation;
  import com.owncloud.android.operations.RenameFileOperation;
  import com.owncloud.android.operations.SynchronizeFileOperation;
@@@ -257,6 -257,11 +257,11 @@@ public class OCFileListFragment extend
                  toHide.add(R.id.action_cancel_upload);
              }
          }
+         
+         // Options shareLink
+         if (!targetFile.isShareByLink()) {
+             toHide.add(R.id.action_unshare_file);
+         }
  
          for (int i : toHide) {
              item = menu.findItem(i);
      public boolean onContextItemSelected (MenuItem item) {
          AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
          mTargetFile = (OCFile) mAdapter.getItem(info.position);
-         switch (item.getItemId()) {
+         switch (item.getItemId()) {                
              case R.id.action_share_file: {
                  FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
                  activity.getFileOperationsHelper().shareFileWithLink(mTargetFile, activity);
                  return true;
              }
+             case R.id.action_unshare_file: {
+                 FileDisplayActivity activity = (FileDisplayActivity) getSherlockActivity();
+                 activity.getFileOperationsHelper().unshareFileWithLink(mTargetFile, activity);
+                 return true;
+             }
              case R.id.action_rename_file: {
                  String fileName = mTargetFile.getFileName();
                  int extensionStart = mTargetFile.isFolder() ? -1 : fileName.lastIndexOf(".");
                  return super.onContextItemSelected(item); 
          }
      }
-     
  
      /**
       * Use this to query the {@link OCFile} that is currently
           * @param file
           */
          public void onBrowsedDownTo(OCFile folder);
-         
          public void startDownloadForPreview(OCFile file);
  
          public void startMediaPreview(OCFile file, int i, boolean b);
@@@ -45,6 -45,12 +45,12 @@@ import com.owncloud.android.files.servi
  import com.owncloud.android.files.services.FileUploader;
  import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 -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.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.operations.RemoteOperationResult.ResultCode;
+ import com.owncloud.android.operations.CreateShareOperation;
+ import com.owncloud.android.operations.UnshareLinkOperation;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.activity.FileDisplayActivity;
  import com.owncloud.android.ui.activity.PinCodeActivity;
@@@ -59,7 -65,7 +65,7 @@@ import com.owncloud.android.utils.Log_O
   *  
   *  @author David A. Velasco
   */
- public class PreviewImageActivity extends FileActivity implements FileFragment.ContainerActivity, ViewPager.OnPageChangeListener, OnTouchListener {
+ public class PreviewImageActivity extends FileActivity implements FileFragment.ContainerActivity, ViewPager.OnPageChangeListener, OnTouchListener , OnRemoteOperationListener{
      
      public static final int DIALOG_SHORT_WAIT = 0;
  
          outState.putBoolean(KEY_WAITING_FOR_BINDER, mRequestWaitingForBinder);    
      }
  
+     @Override
+     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+         super.onRemoteOperationFinish(operation, result);
+         
+         if (operation instanceof CreateShareOperation) {
+             onCreateShareOperationFinish((CreateShareOperation) operation, result);
+             
+         } else if (operation instanceof UnshareLinkOperation) {
+             onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result);
+             
+         }
+     }
+     
+     
+     private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, RemoteOperationResult result) {
+         if (result.isSuccess()) {
+             OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath());
+             if (file != null) {
+                 setFile(file);
+             }
+             invalidateOptionsMenu();
+         } else if  (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
+             backToDisplayActivity();
+         }
+             
+     }
+     
+     private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
+         if (result.isSuccess()) {
+             OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath());
+             if (file != null) {
+                 setFile(file);
+             }
+             invalidateOptionsMenu();
+         }
+     }
+     
      /** Defines callbacks for service binding, passed to bindService() */
      private class PreviewImageServiceConnection implements ServiceConnection {
  
@@@ -52,10 -52,10 +52,10 @@@ import com.actionbarsherlock.view.MenuI
  import com.owncloud.android.R;
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.datamodel.OCFile;
 -import com.owncloud.android.lib.network.webdav.WebdavUtils;
 -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.common.network.WebdavUtils;
 +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.operations.RemoveFileOperation;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.fragment.ConfirmationDialogFragment;
@@@ -176,8 -176,22 +176,22 @@@ public class PreviewImageFragment exten
          mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
          if (savedInstanceState != null) {
              if (!mIgnoreFirstSavedState) {
-                 setFile((OCFile)savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_FILE));
+                 OCFile file = (OCFile)savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_FILE);
                  mAccount = savedInstanceState.getParcelable(PreviewImageFragment.EXTRA_ACCOUNT);
+                 
+                 // Update the file
+                 if (mAccount!= null) {
+                     mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());
+                     OCFile updatedFile = mStorageManager.getFileByPath(file.getRemotePath());
+                     if (updatedFile != null) {
+                         setFile(updatedFile);
+                     } else {
+                         setFile(file);
+                     }
+                 } else {
+                     setFile(file);
+                 }
              } else {
                  mIgnoreFirstSavedState = false;
              }
          toHide.add(R.id.action_cancel_upload);
          toHide.add(R.id.action_download_file);
          toHide.add(R.id.action_rename_file);    // by now
+         
+         // Options shareLink
+         if (!getFile().isShareByLink()) {
+             toHide.add(R.id.action_unshare_file);
+         }
  
          for (int i : toHide) {
              item = menu.findItem(i);
          
      }
  
+     /**
+      * {@inheritDoc}
+      */
+     @Override
+     public void onPrepareOptionsMenu(Menu menu) {
+         super.onPrepareOptionsMenu(menu);
+         
+         MenuItem item = menu.findItem(R.id.action_unshare_file);
+         // Options shareLink
+         OCFile file = ((FileActivity) getSherlockActivity()).getFile();
+         if (!file.isShareByLink()) {
+             item.setVisible(false);
+             item.setEnabled(false);
+         } else {
+             item.setVisible(true);
+             item.setEnabled(true);
+         }
+             
+     }
+     
      
      /**
       * {@inheritDoc}
                  act.getFileOperationsHelper().shareFileWithLink(getFile(), act);
                  return true;
              }
+             case R.id.action_unshare_file: {
+                 FileActivity act = (FileActivity)getSherlockActivity();
+                 act.getFileOperationsHelper().unshareFileWithLink(getFile(), act);
+                 return true;
+             }
              case R.id.action_open_file_with: {
                  openFile();
                  return true;
      }
  
      
      private void seeDetails() {
          ((FileFragment.ContainerActivity)getActivity()).showDetails(getFile());        
      }
@@@ -57,10 -57,10 +57,10 @@@ import com.owncloud.android.datamodel.O
  import com.owncloud.android.media.MediaControlView;
  import com.owncloud.android.media.MediaService;
  import com.owncloud.android.media.MediaServiceBinder;
 -import com.owncloud.android.lib.network.webdav.WebdavUtils;
 -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.common.network.WebdavUtils;
 +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.operations.RemoveFileOperation;
  import com.owncloud.android.ui.activity.FileActivity;
  import com.owncloud.android.ui.activity.FileDisplayActivity;
@@@ -289,7 -289,12 +289,12 @@@ public class PreviewMediaFragment exten
          toHide.add(R.id.action_download_file);
          toHide.add(R.id.action_sync_file);
          toHide.add(R.id.action_rename_file);    // by now
+         
+         // Options shareLink
+         if (!getFile().isShareByLink()) {
+             toHide.add(R.id.action_unshare_file);
+         }
+         
          for (int i : toHide) {
              item = menu.findItem(i);
              if (item != null) {
          
      }
  
+     /**
+      * {@inheritDoc}
+      */
+     @Override
+     public void onPrepareOptionsMenu(Menu menu) {
+         super.onPrepareOptionsMenu(menu);
+         
+         MenuItem item = menu.findItem(R.id.action_unshare_file);
+         // Options shareLink
+         if (!getFile().isShareByLink()) {            
+             item.setVisible(false);
+             item.setEnabled(false);
+         } else {
+             item.setVisible(true);
+             item.setEnabled(true);
+         }
+     }
+     
      
      /**
       * {@inheritDoc}
                  shareFileWithLink();
                  return true;
              }
+             case R.id.action_unshare_file: {
+                 unshareFileWithLink();
+                 return true;
+             }
              case R.id.action_open_file_with: {
                  openFile();
                  return true;
                  return false;
          }
      }
+     
  
+     /**
+      * Update the file of the fragment with file value
+      * @param file
+      */
+     public void updateFile(OCFile file){
+         setFile(file);
+     }
+     
+     private void unshareFileWithLink() {
+         stopPreview(false);
+         FileActivity activity = (FileActivity)((FileFragment.ContainerActivity)getActivity());
+         activity.getFileOperationsHelper().unshareFileWithLink(getFile(), activity);
+     }
      
      private void shareFileWithLink() {
          stopPreview(false);
  
          @Override
          public void onServiceConnected(ComponentName component, IBinder service) {
-             if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
-                 Log_OC.d(TAG, "Media service connected");
-                 mMediaServiceBinder = (MediaServiceBinder) service;
-                 if (mMediaServiceBinder != null) {
-                     prepareMediaController();
-                     playAudio();    // do not wait for the touch of nobody to play audio
-                     
-                     Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready");
-                     
-                 } else {
-                     Log_OC.e(TAG, "Unexpected response from MediaService while binding");
+             if (getActivity() != null) {
+                 if (component.equals(new ComponentName(getActivity(), MediaService.class))) {
+                     Log_OC.d(TAG, "Media service connected");
+                     mMediaServiceBinder = (MediaServiceBinder) service;
+                     if (mMediaServiceBinder != null) {
+                         prepareMediaController();
+                         playAudio();    // do not wait for the touch of nobody to play audio
+                         Log_OC.d(TAG, "Successfully bound to MediaService, MediaController ready");
+                     } else {
+                         Log_OC.e(TAG, "Unexpected response from MediaService while binding");
+                     }
                  }
              }
          }