/**
   * 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;
  }
  @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;
  }
  /**
   * 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;
  }
  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);
      }
    }
  }
Exemple #5
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);
      }
    }
Exemple #6
0
 @Override
 protected void onNewIntent(Intent intent) {
   Log_OC.v(TAG, "onNewIntent() start");
   Account current = AccountUtils.getCurrentOwnCloudAccount(this);
   if (current != null && mAccount != null && !mAccount.name.equals(current.name)) {
     mAccount = current;
   }
   Log_OC.v(TAG, "onNewIntent() stop");
 }
Exemple #7
0
 /**
  * Since ownCloud {@link Account}s can be managed from the system setting menu, the existence of
  * the {@link Account} associated to the instance must be checked every time it is restarted.
  */
 @Override
 protected void onRestart() {
   Log_OC.v(TAG, "onRestart() start");
   super.onRestart();
   boolean validAccount = (mAccount != null && AccountUtils.exists(mAccount, this));
   if (!validAccount) {
     swapToDefaultAccount();
   }
   Log_OC.v(TAG, "onRestart() end");
 }
  /** {@inheritDoc} */
  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    Log_OC.i(TAG, "onActivityCreated() start");

    super.onActivityCreated(savedInstanceState);
    mAdapter = new LocalFileListAdapter(mContainerActivity.getInitialDirectory(), getActivity());
    setListAdapter(mAdapter);

    Log_OC.i(TAG, "onActivityCreated() stop");
  }
 /** {@inheritDoc} */
 @Override
 public View onCreateView(
     LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   Log_OC.i(TAG, "onCreateView() start");
   View v = super.onCreateView(inflater, container, savedInstanceState);
   setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
   setSwipeEnabled(false); // Disable pull-to-refresh
   setFabEnabled(false); // Disable FAB
   setMessageForEmptyList(getString(R.string.local_file_list_empty));
   Log_OC.i(TAG, "onCreateView() end");
   return v;
 }
  @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;
  }
 private void logCookiesAtRequest(Header[] headers, String when) {
   int counter = 0;
   for (int i = 0; i < headers.length; i++) {
     if (headers[i].getName().toLowerCase().equals("cookie")) {
       Log_OC.d(
           TAG + " #" + mInstanceNumber,
           "Cookies at request (" + when + ") (" + counter++ + "): " + headers[i].getValue());
     }
   }
   if (counter == 0) {
     Log_OC.d(TAG + " #" + mInstanceNumber, "No cookie at request before");
   }
 }
 private void logSetCookiesAtResponse(Header[] headers) {
   int counter = 0;
   for (int i = 0; i < headers.length; i++) {
     if (headers[i].getName().toLowerCase().equals("set-cookie")) {
       Log_OC.d(
           TAG + " #" + mInstanceNumber,
           "Set-Cookie (" + counter++ + "): " + headers[i].getValue());
     }
   }
   if (counter == 0) {
     Log_OC.d(TAG + " #" + mInstanceNumber, "No set-cookie");
   }
 }
  /**
   * Registers a local file to be observed for changes.
   *
   * @param localPath Absolute path in the local file system to the file to be observed.
   * @param account OwnCloud account associated to the local file.
   */
  private void addObservedFile(String localPath, Account account) {
    File file = new File(localPath);
    String parentPath = file.getParent();
    FolderObserver observer = mFolderObserversMap.get(parentPath);
    if (observer == null) {
      observer = new FolderObserver(parentPath, account, getApplicationContext());
      mFolderObserversMap.put(parentPath, observer);
      Log_OC.d(TAG, "Observer added for parent folder " + parentPath + "/");
    }

    observer.startWatching(file.getName());
    Log_OC.d(TAG, "Added " + localPath + " to list of observed children");
  }
  /**
   * Unregisters a local file from being observed for changes.
   *
   * @param localPath Absolute path in the local file system to the target file.
   */
  private void removeObservedFile(String localPath) {
    File file = new File(localPath);
    String parentPath = file.getParent();
    FolderObserver observer = mFolderObserversMap.get(parentPath);
    if (observer != null) {
      observer.stopWatching(file.getName());
      if (observer.isEmpty()) {
        mFolderObserversMap.remove(parentPath);
        Log_OC.d(TAG, "Observer removed for parent folder " + parentPath + "/");
      }

    } else {
      Log_OC.d(TAG, "No observer to remove for path " + localPath);
    }
  }
  /**
   * Lists the given directory on the view. When the input parameter is null, it will either refresh
   * the last known directory. list the root if there never was a directory.
   *
   * @param directory Directory to be listed
   */
  public void listDirectory(File directory) {

    // Check input parameters for null
    if (directory == null) {
      if (mDirectory != null) {
        directory = mDirectory;
      } else {
        directory = Environment.getExternalStorageDirectory();
        // TODO be careful with the state of the storage; could not be available
        if (directory == null) return; // no files to show
      }
    }

    // if that's not a directory -> List its parent
    if (!directory.isDirectory()) {
      Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString());
      directory = directory.getParentFile();
    }

    // by now, only files in the same directory will be kept as selected
    ((ListView) mCurrentListView).clearChoices();
    mAdapter.swapDirectory(directory);
    if (mDirectory == null || !mDirectory.equals(directory)) {
      mCurrentListView.setSelection(0);
    }
    mDirectory = directory;
  }
  @Override
  public void onDestroy() {
    Log_OC.v(TAG, "Destroying service");
    // Saving cookies
    try {
      OwnCloudClientManagerFactory.getDefaultSingleton()
          .saveAllClients(this, MainApp.getAccountType());

      // TODO - get rid of these exceptions
    } catch (AccountNotFoundException e) {
      e.printStackTrace();
    } catch (AuthenticatorException e) {
      e.printStackTrace();
    } catch (OperationCanceledException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }

    mUndispatchedFinishedOperations.clear();

    mOperationsBinder = null;

    mOperationsHandler.getLooper().quit();
    mOperationsHandler = null;

    mSyncFolderHandler.getLooper().quit();
    mSyncFolderHandler = null;

    super.onDestroy();
  }
  /**
   * Checks the file clicked over. Browses inside if it is a directory. Notifies the container
   * activity in any case.
   */
  @Override
  public void onItemClick(AdapterView<?> l, View v, int position, long id) {
    File file = (File) mAdapter.getItem(position);
    if (file != null) {
      /// Click on a directory
      if (file.isDirectory()) {
        // just local updates
        listDirectory(file);
        // notify the click to container Activity
        mContainerActivity.onDirectoryClick(file);
        // save index and top position
        saveIndexAndTopPosition(position);

      } else { /// Click on a file
        ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox);
        if (checkBoxV != null) {
          if (((ListView) getListView()).isItemChecked(position)) {
            checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
          } else {
            checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
          }
        }
        // notify the change to the container Activity
        mContainerActivity.onFileClick(file);
      }

    } else {
      Log_OC.w(TAG, "Null object in ListAdapter!!");
    }
  }
 /**
  * Notifies the currently subscribed listeners about the end of an operation.
  *
  * @param operation Finished operation.
  * @param result Result of the operation.
  */
 protected void dispatchResultToOperationListeners(
     final RemoteOperation operation, final RemoteOperationResult result) {
   int count = 0;
   Iterator<OnRemoteOperationListener> listeners =
       mOperationsBinder.mBoundListeners.keySet().iterator();
   while (listeners.hasNext()) {
     final OnRemoteOperationListener listener = listeners.next();
     final Handler handler = mOperationsBinder.mBoundListeners.get(listener);
     if (handler != null) {
       handler.post(
           new Runnable() {
             @Override
             public void run() {
               listener.onRemoteOperationFinish(operation, result);
             }
           });
       count += 1;
     }
   }
   if (count == 0) {
     Pair<RemoteOperation, RemoteOperationResult> undispatched =
         new Pair<RemoteOperation, RemoteOperationResult>(operation, result);
     mUndispatchedFinishedOperations.put(((Runnable) operation).hashCode(), undispatched);
   }
   Log_OC.d(TAG, "Called " + count + " listeners");
 }
  private RemoteOperationResult(boolean success, int httpCode) {
    mSuccess = success;
    mHttpCode = httpCode;

    if (success) {
      mCode = ResultCode.OK;

    } else if (httpCode > 0) {
      switch (httpCode) {
        case HttpStatus.SC_UNAUTHORIZED:
          mCode = ResultCode.UNAUTHORIZED;
          break;
        case HttpStatus.SC_NOT_FOUND:
          mCode = ResultCode.FILE_NOT_FOUND;
          break;
        case HttpStatus.SC_INTERNAL_SERVER_ERROR:
          mCode = ResultCode.INSTANCE_NOT_CONFIGURED;
          break;
        case HttpStatus.SC_CONFLICT:
          mCode = ResultCode.CONFLICT;
          break;
        case HttpStatus.SC_INSUFFICIENT_STORAGE:
          mCode = ResultCode.QUOTA_EXCEEDED;
          break;
        case HttpStatus.SC_FORBIDDEN:
          mCode = ResultCode.FORBIDDEN;
          break;
        default:
          mCode = ResultCode.UNHANDLED_HTTP_CODE;
          Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode);
      }
    }
  }
  public void shareFileWithLink(OCFile file) {

    if (isSharedSupported()) {
      if (file != null) {
        String link = "https://fake.url";
        Intent intent = createShareWithLinkIntent(link);
        String[] packagesToExclude = new String[] {mFileActivity.getPackageName()};
        DialogFragment chooserDialog =
            ShareLinkToDialog.newInstance(intent, packagesToExclude, file);
        chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);

      } else {
        Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
      }

    } else {
      // Show a Message
      Toast t =
          Toast.makeText(
              mFileActivity,
              mFileActivity.getString(R.string.share_link_no_support_share_api),
              Toast.LENGTH_LONG);
      t.show();
    }
  }
Exemple #21
0
 @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
   }
 }
  @Override
  protected int uploadFile(OwnCloudClient client) throws HttpException, IOException {
    int status = -1;

    FileChannel channel = null;
    RandomAccessFile raf = null;
    try {
      File file = new File(mLocalPath);
      raf = new RandomAccessFile(file, "r");
      channel = raf.getChannel();
      mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
      // ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
      synchronized (mDataTransferListeners) {
        ((ProgressiveDataTransferer) mEntity)
            .addDatatransferProgressListeners(mDataTransferListeners);
      }

      long offset = 0;
      String uriPrefix =
          client.getWebdavUri()
              + WebdavUtils.encodePath(mRemotePath)
              + "-chunking-"
              + Math.abs((new Random()).nextInt(9000) + 1000)
              + "-";
      long chunkCount = (long) Math.ceil((double) file.length() / CHUNK_SIZE);
      for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++, offset += CHUNK_SIZE) {
        if (mPutMethod != null) {
          mPutMethod.releaseConnection(); // let the connection available for other methods
        }
        mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
        mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
        ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset);
        mPutMethod.setRequestEntity(mEntity);
        status = client.executeMethod(mPutMethod);
        client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
        Log_OC.d(
            TAG,
            "Upload of "
                + mLocalPath
                + " to "
                + mRemotePath
                + ", chunk index "
                + chunkIndex
                + ", count "
                + chunkCount
                + ", HTTP result status "
                + status);
        if (!isSuccess(status)) break;
      }

    } finally {
      if (channel != null) channel.close();
      if (raf != null) raf.close();
      if (mPutMethod != null)
        mPutMethod.releaseConnection(); // let the connection available for other methods
    }
    return status;
  }
Exemple #23
0
  /**
   * Called when the ownCloud {@link Account} associated to the Activity was just updated.
   *
   * <p>Child classes must grant that state depending on the {@link Account} is updated.
   */
  protected void onAccountSet(boolean stateWasRecovered) {
    if (getAccount() != null) {
      mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
      mCapabilities = mStorageManager.getCapability(mAccount.name);

    } else {
      Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
    }
  }
  private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException {
    int redirectionsCount = 0;
    while (redirectionsCount < MAX_REDIRECTIONS_COUNT
        && (status == HttpStatus.SC_MOVED_PERMANENTLY
            || status == HttpStatus.SC_MOVED_TEMPORARILY
            || status == HttpStatus.SC_TEMPORARY_REDIRECT)) {

      Header location = method.getResponseHeader("Location");
      if (location == null) {
        location = method.getResponseHeader("location");
      }
      if (location != null) {
        Log_OC.d(TAG + " #" + mInstanceNumber, "Location to redirect: " + location.getValue());
        method.setURI(new URI(location.getValue(), true));
        Header destination = method.getRequestHeader("Destination");
        if (destination == null) {
          destination = method.getRequestHeader("destination");
        }
        if (destination != null) {
          String locationStr = location.getValue();
          int suffixIndex =
              locationStr.lastIndexOf(
                  (mCredentials instanceof OwnCloudBearerCredentials)
                      ? AccountUtils.ODAV_PATH
                      : AccountUtils.WEBDAV_PATH_4_0);
          String redirectionBase = locationStr.substring(0, suffixIndex);

          String destinationStr = destination.getValue();
          String destinationPath = destinationStr.substring(mBaseUri.toString().length());
          String redirectedDestination = redirectionBase + destinationPath;

          destination.setValue(redirectedDestination);
          method.setRequestHeader(destination);
        }
        status = super.executeMethod(method);
        redirectionsCount++;

      } else {
        Log_OC.d(TAG + " #" + mInstanceNumber, "No location to redirect!");
        status = HttpStatus.SC_NOT_FOUND;
      }
    }
    return status;
  }
  /**
   * 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);
  }
 private void logCookie(Cookie cookie) {
   Log_OC.d(TAG, "Cookie name: " + cookie.getName());
   Log_OC.d(TAG, "       value: " + cookie.getValue());
   Log_OC.d(TAG, "       domain: " + cookie.getDomain());
   Log_OC.d(TAG, "       path: " + cookie.getPath());
   Log_OC.d(TAG, "       version: " + cookie.getVersion());
   Log_OC.d(
       TAG,
       "       expiryDate: "
           + (cookie.getExpiryDate() != null ? cookie.getExpiryDate().toString() : "--"));
   Log_OC.d(TAG, "       comment: " + cookie.getComment());
   Log_OC.d(TAG, "       secure: " + cookie.getSecure());
 }
  /**
   * Attempts to get a new socket connection to the given host within the given time limit.
   *
   * @param host the host name/IP
   * @param port the port on the host
   * @param clientHost the local host name/IP to bind the socket to
   * @param clientPort the port on the local machine
   * @param params {@link HttpConnectionParams Http connection parameters}
   * @return Socket a new socket
   * @throws IOException if an I/O error occurs while creating the socket
   * @throws UnknownHostException if the IP address of the host cannot be determined
   */
  public Socket createSocket(
      final String host,
      final int port,
      final InetAddress localAddress,
      final int localPort,
      final HttpConnectionParams params)
      throws IOException, UnknownHostException, ConnectTimeoutException {
    Log_OC.d(
        TAG,
        "Creating SSL Socket with remote "
            + host
            + ":"
            + port
            + ", local "
            + localAddress
            + ":"
            + localPort
            + ", params: "
            + params);
    if (params == null) {
      throw new IllegalArgumentException("Parameters may not be null");
    }
    int timeout = params.getConnectionTimeout();

    // logSslInfo();

    SocketFactory socketfactory = mSslContext.getSocketFactory();
    Log_OC.d(
        TAG,
        " ... with connection timeout " + timeout + " and socket timeout " + params.getSoTimeout());
    Socket socket = socketfactory.createSocket();
    SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
    SocketAddress remoteaddr = new InetSocketAddress(host, port);
    socket.setSoTimeout(params.getSoTimeout());
    socket.bind(localaddr);
    ServerNameIndicator.setServerNameIndication(host, (SSLSocket) socket);
    socket.connect(remoteaddr, timeout);
    verifyPeerIdentity(host, port, socket);
    return socket;
  }
  @Override
  public int executeMethod(HttpMethod method) throws IOException, HttpException {
    try { // just to log
      boolean customRedirectionNeeded = false;

      try {
        method.setFollowRedirects(mFollowRedirects);
      } catch (Exception e) {
        /*
           if (mFollowRedirects)
        	Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName()
        		+ " method, custom redirection will be used if needed");
        */
        customRedirectionNeeded = mFollowRedirects;
      }

      Log_OC.d(
          TAG + " #" + mInstanceNumber, "REQUEST " + method.getName() + " " + method.getPath());

      //	        logCookiesAtRequest(method.getRequestHeaders(), "before");
      //	        logCookiesAtState("before");

      int status = super.executeMethod(method);

      if (customRedirectionNeeded) {
        status = patchRedirection(status, method);
      }

      //	        logCookiesAtRequest(method.getRequestHeaders(), "after");
      //	        logCookiesAtState("after");
      //	        logSetCookiesAtResponse(method.getResponseHeaders());

      return status;

    } catch (IOException e) {
      Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occured", e);
      throw e;
    }
  }
  /** Initialize the service. */
  @Override
  public void onCreate() {
    Log_OC.d(TAG, "onCreate");
    super.onCreate();

    mDownloadReceiver = new DownloadCompletedReceiver();
    IntentFilter filter = new IntentFilter();
    filter.addAction(FileDownloader.getDownloadAddedMessage());
    filter.addAction(FileDownloader.getDownloadFinishMessage());
    registerReceiver(mDownloadReceiver, filter);

    mFolderObserversMap = new HashMap<String, FolderObserver>();
  }