Exemple #1
0
    @Override
    public void run(AccountManagerFuture<Bundle> future) {
      FileActivity.this.mRedirectingToSetupAccount = false;
      boolean accountWasSet = false;
      if (future != null) {
        try {
          Bundle result;
          result = future.getResult();
          String name = result.getString(AccountManager.KEY_ACCOUNT_NAME);
          String type = result.getString(AccountManager.KEY_ACCOUNT_TYPE);
          if (AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), name)) {
            setAccount(new Account(name, type), false);
            accountWasSet = true;
          }
        } catch (OperationCanceledException e) {
          Log_OC.d(TAG, "Account creation canceled");

        } catch (Exception e) {
          Log_OC.e(TAG, "Account creation finished in exception: ", e);
        }

      } else {
        Log_OC.e(TAG, "Account creation callback with null bundle");
      }
      if (!accountWasSet) {
        moveTaskToBack(true);
      }
    }
  @Override
  protected RemoteOperationResult run(OwnCloudClient client) {
    RemoteOperationResult result = null;

    /// download will be performed to a temporal file, then moved to the final location
    File tmpFile = new File(getTmpPath());

    /// perform the download
    try {
      tmpFile.getParentFile().mkdirs();
      int status = downloadFile(client, tmpFile);
      result =
          new RemoteOperationResult(
              isSuccess(status), status, (mGet != null ? mGet.getResponseHeaders() : null));
      Log_OC.i(
          TAG,
          "Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage());

    } catch (Exception e) {
      result = new RemoteOperationResult(e);
      Log_OC.e(
          TAG,
          "Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage(),
          e);
    }

    return result;
  }
  public RemoteOperationResult(boolean success, String bodyResponse, int httpCode) {
    mSuccess = success;
    mHttpCode = httpCode;

    if (success) {
      mCode = ResultCode.OK;

    } else if (httpCode > 0) {
      switch (httpCode) {
        case HttpStatus.SC_BAD_REQUEST:
          InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
          InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser();
          try {
            if (xmlParser.parseXMLResponse(is))
              mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;

          } catch (Exception e) {
            mCode = ResultCode.UNHANDLED_HTTP_CODE;
            Log_OC.e(TAG, "Exception reading exception from server", e);
          }
          break;
        default:
          mCode = ResultCode.UNHANDLED_HTTP_CODE;
          Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode);
      }
    }
  }
  /**
   * Handles requests to: - (re)start watching (ACTION_START_OBSERVE) - add an {@link OCFile} to be
   * watched (ATION_ADD_OBSERVED_FILE) - stop observing an {@link OCFile} (ACTION_DEL_OBSERVED_FILE)
   */
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log_OC.d(TAG, "Starting command " + intent);

    if (intent == null || ACTION_START_OBSERVE.equals(intent.getAction())) {
      // NULL occurs when system tries to restart the service after its
      // process was killed
      startObservation();
      return Service.START_STICKY;

    } else if (ACTION_ADD_OBSERVED_FILE.equals(intent.getAction())) {
      OCFile file = (OCFile) intent.getParcelableExtra(ARG_FILE);
      Account account = (Account) intent.getParcelableExtra(ARG_ACCOUNT);
      addObservedFile(file, account);

    } else if (ACTION_DEL_OBSERVED_FILE.equals(intent.getAction())) {
      removeObservedFile(
          (OCFile) intent.getParcelableExtra(ARG_FILE),
          (Account) intent.getParcelableExtra(ARG_ACCOUNT));

    } else {
      Log_OC.e(TAG, "Unknown action recieved; ignoring it: " + intent.getAction());
    }

    return Service.START_STICKY;
  }
  /**
   * Entry point to add a new operation to the queue of operations.
   *
   * <p>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.
   */
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log_OC.d(TAG, "Starting command with id " + startId);

    // WIP: for the moment, only SYNC_FOLDER is expected here;
    // the rest of the operations are requested through the Binder
    if (ACTION_SYNC_FOLDER.equals(intent.getAction())) {

      if (!intent.hasExtra(EXTRA_ACCOUNT) || !intent.hasExtra(EXTRA_REMOTE_PATH)) {
        Log_OC.e(TAG, "Not enough information provided in intent");
        return START_NOT_STICKY;
      }
      Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
      String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);

      Pair<Account, String> itemSyncKey = new Pair<Account, String>(account, remotePath);

      Pair<Target, RemoteOperation> itemToQueue = newOperation(intent);
      if (itemToQueue != null) {
        mSyncFolderHandler.add(
            account, remotePath, (SynchronizeFolderOperation) itemToQueue.second);
        Message msg = mSyncFolderHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = itemSyncKey;
        mSyncFolderHandler.sendMessage(msg);
      }

    } else {
      Message msg = mOperationsHandler.obtainMessage();
      msg.arg1 = startId;
      mOperationsHandler.sendMessage(msg);
    }

    return START_NOT_STICKY;
  }
  /**
   * Unregisters the local copy of a remote file to be observed for local changes.
   *
   * @param file Object representing a remote file which local copy must be not observed longer.
   * @param account OwnCloud account containing file.
   */
  private void removeObservedFile(OCFile file, Account account) {
    Log_OC.v(TAG, "Removing a file from being watched");

    if (file == null) {
      Log_OC.e(TAG, "Trying to remove a NULL file");
      return;
    }
    if (account == null) {
      Log_OC.e(TAG, "Trying to add a file with a NULL account to observer");
      return;
    }

    String localPath = file.getStoragePath();
    if (localPath == null || localPath.length() <= 0) {
      localPath = FileStorageUtils.getDefaultSavePathFor(account.name, file);
    }

    removeObservedFile(localPath);
  }
  /**
   * Registers the local copy of a remote file to be observed for local changes, an automatically
   * updated in the ownCloud server.
   *
   * <p>This method does NOT perform a {@link SynchronizeFileOperation} over the file.
   *
   * @param file Object representing a remote file which local copy must be observed.
   * @param account OwnCloud account containing file.
   */
  private void addObservedFile(OCFile file, Account account) {
    Log_OC.v(TAG, "Adding a file to be watched");

    if (file == null) {
      Log_OC.e(TAG, "Trying to add a NULL file to observer");
      return;
    }
    if (account == null) {
      Log_OC.e(TAG, "Trying to add a file with a NULL account to observer");
      return;
    }

    String localPath = file.getStoragePath();
    if (localPath == null || localPath.length() <= 0) {
      // file downloading or to be downloaded for the first time
      localPath = FileStorageUtils.getDefaultSavePathFor(account.name, file);
    }

    addObservedFile(localPath, account);
  }
  @Override
  protected RemoteOperationResult run(OwnCloudClient client) {
    RemoteOperationResult result = null;
    int status = -1;

    GetMethod get = null;

    try {
      // Get Method
      get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);

      // Add Parameters to Get Method
      get.setQueryString(
          new NameValuePair[] {
            new NameValuePair(PARAM_PATH, mRemoteFilePath),
            new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)),
            new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles))
          });

      get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);

      status = client.executeMethod(get);

      if (isSuccess(status)) {
        String response = get.getResponseBodyAsString();

        // Parse xml response and obtain the list of shares
        ShareToRemoteOperationResultParser parser =
            new ShareToRemoteOperationResultParser(new ShareXMLParser());
        parser.setOwnCloudVersion(client.getOwnCloudVersion());
        parser.setServerBaseUri(client.getBaseUri());
        result = parser.parse(response);

        if (result.isSuccess()) {
          Log_OC.d(TAG, "Got " + result.getData().size() + " shares");
        }

      } else {
        result = new RemoteOperationResult(false, status, get.getResponseHeaders());
      }

    } catch (Exception e) {
      result = new RemoteOperationResult(e);
      Log_OC.e(TAG, "Exception while getting shares", e);

    } finally {
      if (get != null) {
        get.releaseConnection();
      }
    }
    return result;
  }
  /**
   * Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation.
   *
   * @param responseBodyAsStream InputStream with the HTTP response to exhaust.
   */
  public void exhaustResponse(InputStream responseBodyAsStream) {
    if (responseBodyAsStream != null) {
      try {
        while (responseBodyAsStream.read(sExhaustBuffer) >= 0) ;
        responseBodyAsStream.close();

      } catch (IOException io) {
        Log_OC.e(
            TAG,
            "Unexpected exception while exhausting not interesting HTTP response;"
                + " will be IGNORED",
            io);
      }
    }
  }
  @Override
  public void writeRequest(final OutputStream out) throws IOException {
    // byte[] tmp = new byte[4096];
    ByteBuffer tmp = ByteBuffer.allocate(4096);
    int readResult = 0;

    //                    globally in some fashionable manner
    RandomAccessFile raf = new RandomAccessFile(mFile, "r");
    FileChannel channel = raf.getChannel();
    Iterator<OnDatatransferProgressListener> it = null;
    long transferred = 0;
    long size = mFile.length();
    if (size == 0) size = -1;
    try {
      while ((readResult = channel.read(tmp)) >= 0) {
        out.write(tmp.array(), 0, readResult);
        tmp.clear();
        transferred += readResult;
        synchronized (mDataTransferListeners) {
          it = mDataTransferListeners.iterator();
          while (it.hasNext()) {
            it.next().onTransferProgress(readResult, transferred, size, mFile.getAbsolutePath());
          }
        }
      }

    } catch (IOException io) {
      Log_OC.e("FileRequestException", io.getMessage());
      throw new RuntimeException(
          "Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really",
          io);

    } finally {
      channel.close();
      raf.close();
    }
  }
  protected int downloadFile(OwnCloudClient client, File targetFile)
      throws HttpException, IOException, OperationCancelledException {
    int status = -1;
    boolean savedFile = false;
    mGet = new GetMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
    Iterator<OnDatatransferProgressListener> it = null;

    FileOutputStream fos = null;
    try {
      status = client.executeMethod(mGet);
      if (isSuccess(status)) {
        targetFile.createNewFile();
        BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream());
        fos = new FileOutputStream(targetFile);
        long transferred = 0;

        Header contentLength = mGet.getResponseHeader("Content-Length");
        long totalToTransfer =
            (contentLength != null && contentLength.getValue().length() > 0)
                ? Long.parseLong(contentLength.getValue())
                : 0;

        byte[] bytes = new byte[4096];
        int readResult = 0;
        while ((readResult = bis.read(bytes)) != -1) {
          synchronized (mCancellationRequested) {
            if (mCancellationRequested.get()) {
              mGet.abort();
              throw new OperationCancelledException();
            }
          }
          fos.write(bytes, 0, readResult);
          transferred += readResult;
          synchronized (mDataTransferListeners) {
            it = mDataTransferListeners.iterator();
            while (it.hasNext()) {
              it.next()
                  .onTransferProgress(
                      readResult, transferred, totalToTransfer, targetFile.getName());
            }
          }
        }
        if (transferred == totalToTransfer) { // Check if the file is completed
          savedFile = true;
          Header modificationTime = mGet.getResponseHeader("Last-Modified");
          if (modificationTime == null) {
            modificationTime = mGet.getResponseHeader("last-modified");
          }
          if (modificationTime != null) {
            Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
            mModificationTimestamp = (d != null) ? d.getTime() : 0;
          } else {
            Log_OC.e(
                TAG, "Could not read modification time from response downloading " + mRemotePath);
          }

          mEtag = WebdavUtils.getEtagFromResponse(mGet);
          if (mEtag.length() == 0) {
            Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath);
          }

        } else {
          client.exhaustResponse(mGet.getResponseBodyAsStream());
          // TODO some kind of error control!
        }

      } else {
        client.exhaustResponse(mGet.getResponseBodyAsStream());
      }

    } finally {
      if (fos != null) fos.close();
      if (!savedFile && targetFile.exists()) {
        targetFile.delete();
      }
      mGet.releaseConnection(); // let the connection available for other methods
    }
    return status;
  }
  @Override
  protected RemoteOperationResult run(OwnCloudClient client) {
    AccountManager accountMngr = AccountManager.get(mContext);
    String statUrl = accountMngr.getUserData(mAccount, Constants.KEY_OC_BASE_URL);
    statUrl += AccountUtils.STATUS_PATH;
    RemoteOperationResult result = null;
    GetMethod get = null;
    try {
      get = new GetMethod(statUrl);
      int status = client.executeMethod(get);
      if (status != HttpStatus.SC_OK) {
        client.exhaustResponse(get.getResponseBodyAsStream());
        result = new RemoteOperationResult(false, status, get.getResponseHeaders());

      } else {
        String response = get.getResponseBodyAsString();
        if (response != null) {
          JSONObject json = new JSONObject(response);
          if (json != null && json.getString("version") != null) {

            String version = json.getString("version");
            mOwnCloudVersion = new OwnCloudVersion(version);
            if (mOwnCloudVersion.isVersionValid()) {
              accountMngr.setUserData(
                  mAccount, Constants.KEY_OC_VERSION, mOwnCloudVersion.getVersion());
              Log_OC.d(TAG, "Got new OC version " + mOwnCloudVersion.toString());

              result = new RemoteOperationResult(ResultCode.OK);

            } else {
              Log_OC.w(
                  TAG, "Invalid version number received from server: " + json.getString("version"));
              result = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
            }
          }
        }
        if (result == null) {
          result =
              new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
        }
      }
      Log_OC.i(
          TAG,
          "Check for update of ownCloud server version at "
              + client.getWebdavUri()
              + ": "
              + result.getLogMessage());

    } catch (JSONException e) {
      result = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
      Log_OC.e(
          TAG,
          "Check for update of ownCloud server version at "
              + client.getWebdavUri()
              + ": "
              + result.getLogMessage(),
          e);

    } catch (Exception e) {
      result = new RemoteOperationResult(e);
      Log_OC.e(
          TAG,
          "Check for update of ownCloud server version at "
              + client.getWebdavUri()
              + ": "
              + result.getLogMessage(),
          e);

    } finally {
      if (get != null) get.releaseConnection();
    }
    return result;
  }
  /**
   * Creates a new operation, as described by operationIntent.
   *
   * <p>TODO - move to ServiceHandler (probably)
   *
   * @param operationIntent Intent describing a new operation to queue and execute.
   * @return Pair with the new operation object and the information about its target server.
   */
  private Pair<Target, RemoteOperation> newOperation(Intent operationIntent) {
    RemoteOperation operation = null;
    Target target = null;
    try {
      if (!operationIntent.hasExtra(EXTRA_ACCOUNT) && !operationIntent.hasExtra(EXTRA_SERVER_URL)) {
        Log_OC.e(TAG, "Not enough information provided in intent");

      } else {
        Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT);
        String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL);
        String cookie = operationIntent.getStringExtra(EXTRA_COOKIE);
        target = new Target(account, (serverUrl == null) ? null : Uri.parse(serverUrl), cookie);

        String action = operationIntent.getAction();
        if (action.equals(ACTION_CREATE_SHARE_VIA_LINK)) { // Create public share via link
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
          if (remotePath.length() > 0) {
            operation = new CreateShareViaLinkOperation(remotePath, password);
          }

        } else if (ACTION_UPDATE_SHARE.equals(action)) {
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          long shareId = operationIntent.getLongExtra(EXTRA_SHARE_ID, -1);
          if (remotePath != null && remotePath.length() > 0) {
            operation = new UpdateShareViaLinkOperation(remotePath);

            String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
            ((UpdateShareViaLinkOperation) operation).setPassword(password);

            long expirationDate =
                operationIntent.getLongExtra(EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS, 0);
            ((UpdateShareViaLinkOperation) operation).setExpirationDate(expirationDate);

            if (operationIntent.hasExtra(EXTRA_SHARE_PUBLIC_UPLOAD)) {
              ((UpdateShareViaLinkOperation) operation)
                  .setPublicUpload(
                      operationIntent.getBooleanExtra(EXTRA_SHARE_PUBLIC_UPLOAD, false));
            }

          } else if (shareId > 0) {
            operation = new UpdateSharePermissionsOperation(shareId);
            int permissions = operationIntent.getIntExtra(EXTRA_SHARE_PERMISSIONS, 1);
            ((UpdateSharePermissionsOperation) operation).setPermissions(permissions);
          }

        } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) {
          // Create private share with user or group
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH);
          ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE);
          int permissions = operationIntent.getIntExtra(EXTRA_SHARE_PERMISSIONS, -1);
          if (remotePath.length() > 0) {
            operation =
                new CreateShareWithShareeOperation(remotePath, shareeName, shareType, permissions);
          }

        } else if (action.equals(ACTION_UNSHARE)) { // Unshare file
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE);
          String shareWith = operationIntent.getStringExtra(EXTRA_SHARE_WITH);
          if (remotePath.length() > 0) {
            operation =
                new UnshareOperation(remotePath, shareType, shareWith, OperationsService.this);
          }

        } else if (action.equals(ACTION_GET_SERVER_INFO)) {
          // check OC server and get basic information from it
          operation = new GetServerInfoOperation(serverUrl, OperationsService.this);

        } else if (action.equals(ACTION_OAUTH2_GET_ACCESS_TOKEN)) {
          /// GET ACCESS TOKEN to the OAuth server
          String oauth2QueryParameters =
              operationIntent.getStringExtra(EXTRA_OAUTH2_QUERY_PARAMETERS);
          operation =
              new OAuth2GetAccessToken(
                  getString(R.string.oauth2_client_id),
                  getString(R.string.oauth2_redirect_uri),
                  getString(R.string.oauth2_grant_type),
                  oauth2QueryParameters);

        } else if (action.equals(ACTION_GET_USER_NAME)) {
          // Get User Name
          operation = new GetRemoteUserInfoOperation();

        } else if (action.equals(ACTION_RENAME)) {
          // Rename file or folder
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          String newName = operationIntent.getStringExtra(EXTRA_NEWNAME);
          operation = new RenameFileOperation(remotePath, newName);

        } else if (action.equals(ACTION_REMOVE)) {
          // Remove file or folder
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL, false);
          operation = new RemoveFileOperation(remotePath, onlyLocalCopy);

        } else if (action.equals(ACTION_CREATE_FOLDER)) {
          // Create Folder
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true);
          operation = new CreateFolderOperation(remotePath, createFullPath);

        } else if (action.equals(ACTION_SYNC_FILE)) {
          // Sync file
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          boolean syncFileContents =
              operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
          operation =
              new SynchronizeFileOperation(
                  remotePath, account, syncFileContents, getApplicationContext());

        } else if (action.equals(ACTION_SYNC_FOLDER)) {
          // Sync folder (all its descendant files are sync'ed)
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          operation =
              new SynchronizeFolderOperation(
                  this, // TODO remove this dependency from construction time
                  remotePath,
                  account,
                  System.currentTimeMillis() // TODO remove this dependency from construction time
                  );

        } else if (action.equals(ACTION_MOVE_FILE)) {
          // Move file/folder
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          String newParentPath = operationIntent.getStringExtra(EXTRA_NEW_PARENT_PATH);
          operation = new MoveFileOperation(remotePath, newParentPath, account);

        } else if (action.equals(ACTION_COPY_FILE)) {
          // Copy file/folder
          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
          String newParentPath = operationIntent.getStringExtra(EXTRA_NEW_PARENT_PATH);
          operation = new CopyFileOperation(remotePath, newParentPath, account);

        } else if (action.equals(ACTION_CHECK_CURRENT_CREDENTIALS)) {
          // Check validity of currently stored credentials for a given account
          operation = new CheckCurrentCredentialsOperation(account);
        }
      }

    } catch (IllegalArgumentException e) {
      Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
      operation = null;
    }

    if (operation != null) {
      return new Pair<Target, RemoteOperation>(target, operation);
    } else {
      return null;
    }
  }
    /** Performs the next operation in the queue */
    private void nextOperation() {

      // Log_OC.e(TAG, "nextOperation init" );

      Pair<Target, RemoteOperation> 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) {
              OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount, mService);
              mOwnCloudClient =
                  OwnCloudClientManagerFactory.getDefaultSingleton()
                      .getClientFor(ocAccount, mService);

              OwnCloudVersion version =
                  com.owncloud.android.authentication.AccountUtils.getServerVersion(
                      mLastTarget.mAccount);
              mOwnCloudClient.setOwnCloudVersion(version);

              mStorageManager =
                  new FileDataStorageManager(mLastTarget.mAccount, mService.getContentResolver());
            } else {
              OwnCloudCredentials credentials = null;
              if (mLastTarget.mCookie != null && mLastTarget.mCookie.length() > 0) {
                // just used for GetUserName
                // TODO refactor to run GetUserName as AsyncTask in the context of
                // AuthenticatorActivity
                credentials =
                    OwnCloudCredentialsFactory.newSamlSsoCredentials(
                        null, // unknown
                        mLastTarget.mCookie); // SAML SSO
              }
              OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mServerUrl, credentials);
              mOwnCloudClient =
                  OwnCloudClientManagerFactory.getDefaultSingleton()
                      .getClientFor(ocAccount, mService);
              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 authorization for a NULL account", e);
          } else {
            Log_OC.e(
                TAG, "Error while trying to get authorization 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 authorization for a NULL account", e);
          } else {
            Log_OC.e(
                TAG, "Error while trying to get authorization for " + mLastTarget.mAccount.name, e);
          }
          result = new RemoteOperationResult(e);
        } catch (Exception e) {
          if (mLastTarget.mAccount == null) {
            Log_OC.e(TAG, "Unexpected error for a NULL account", e);
          } else {
            Log_OC.e(TAG, "Unexpected error for " + mLastTarget.mAccount.name, e);
          }
          result = new RemoteOperationResult(e);

        } finally {
          synchronized (mPendingOperations) {
            mPendingOperations.poll();
          }
        }

        // sendBroadcastOperationFinished(mLastTarget, mCurrentOperation, result);
        mService.dispatchResultToOperationListeners(mCurrentOperation, result);
      }
    }