Merge remote-tracking branch 'origin/operations_service' into operations_service
authorDavid A. Velasco <dvelasco@solidgear.es>
Tue, 1 Apr 2014 13:17:33 +0000 (15:17 +0200)
committerDavid A. Velasco <dvelasco@solidgear.es>
Tue, 1 Apr 2014 13:17:33 +0000 (15:17 +0200)
1  2 
owncloud-android-library
src/com/owncloud/android/authentication/AuthenticatorActivity.java
src/com/owncloud/android/services/OperationsService.java

diff --combined owncloud-android-library
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit a3683116ae04f639ff39484b1c54788bbce9fd30
 -Subproject commit cecda3333ac511267d6a70c61b1475211484ec84
++Subproject commit 6b69b5af1a79275a23339ad6382210d75b061f9f
@@@ -19,7 -19,6 +19,7 @@@
  package com.owncloud.android.authentication;\r
  \r
  import java.security.cert.X509Certificate;\r
 +import java.util.Map;\r
  \r
  import android.accounts.Account;\r
  import android.accounts.AccountManager;\r
@@@ -46,6 -45,7 +46,6 @@@ import android.support.v4.app.FragmentT
  import android.text.Editable;\r
  import android.text.InputType;\r
  import android.text.TextWatcher;\r
 -import android.util.Log;\r
  import android.view.KeyEvent;\r
  import android.view.MotionEvent;\r
  import android.view.View;\r
@@@ -69,12 -69,13 +69,12 @@@ import com.owncloud.android.lib.common.
  import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;\r
  import com.owncloud.android.lib.common.OwnCloudClientFactory;\r
  import com.owncloud.android.lib.common.OwnCloudClient;\r
 -import com.owncloud.android.operations.DetectAuthenticationMethodOperation;\r
  import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;\r
 +import com.owncloud.android.operations.GetServerInfoOperation;\r
  import com.owncloud.android.operations.OAuth2GetAccessToken;\r
  
  import com.owncloud.android.lib.common.network.CertificateCombinedException;\r
  import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;\r
 -import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation;\r
  import com.owncloud.android.lib.common.operations.RemoteOperation;\r
  import com.owncloud.android.lib.common.operations.RemoteOperationResult;\r
  import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;\r
@@@ -111,7 -112,6 +111,6 @@@ SsoWebViewClientListener, OnSslUntruste
      private static final String KEY_AUTH_MESSAGE_TEXT = "AUTH_MESSAGE_TEXT";\r
      private static final String KEY_HOST_URL_TEXT = "HOST_URL_TEXT";\r
      private static final String KEY_OC_VERSION = "OC_VERSION";\r
-     private static final String KEY_OC_VERSION_STRING = "OC_VERSION_STRING";\r
      private static final String KEY_ACCOUNT = "ACCOUNT";\r
      private static final String KEY_SERVER_VALID = "SERVER_VALID";\r
      private static final String KEY_SERVER_CHECKED = "SERVER_CHECKED";\r
  \r
      private static final String TAG_SAML_DIALOG = "samlWebViewDialog";\r
  \r
 -    private String mHostBaseUrl;\r
 -    private OwnCloudVersion mDiscoveredVersion;\r
 +    private String mHostBaseUrl;                // TODO remove\r
 +    private OwnCloudVersion mDiscoveredVersion; // TODO remove\r
  \r
      private String mAuthMessageText;\r
      private int mAuthMessageVisibility, mServerStatusText, mServerStatusIcon;\r
      private boolean mServerIsChecked, mServerIsValid, mIsSslConn;\r
      private AuthenticationMethod mServerAuthMethod = AuthenticationMethod.UNKNOWN;\r
 -    private int mDetectAuthOpId = -1;\r
 +\r
 +    private int mGetServerInfoOpId = -1;\r
 +    private int mOauth2GetAccessTokenOpId = -1;\r
  \r
      private int mAuthStatusText, mAuthStatusIcon;    \r
      private TextView mAuthStatusLayout;\r
  \r
      private final Handler mHandler = new Handler();\r
      private Thread mOperationThread;\r
-     //private GetRemoteStatusOperation mOcServerChkOperation;\r
 -    private GetRemoteStatusOperation mOcServerChkOperation;\r
 +    private GetServerInfoOperation mServerInfoOperation;\r
-     private ExistenceCheckRemoteOperation mAuthCheckOperation;\r
 +\r
+     //private ExistenceCheckRemoteOperation mAuthCheckOperation;\r
+     private int mExistenceCheckOpId = -1;\r
+     \r
      private Uri mNewCapturedUriFromOAuth2Redirection;\r
  \r
      private AccountManager mAccountMgr;\r
      \r
      private OperationsServiceBinder mOperationsServiceBinder = null;\r
  \r
 +    private GetServerInfoOperation.ServerInfo mServerInfo;\r
 +\r
      /**\r
       * {@inheritDoc}\r
       * \r
              /// retrieve extras from intent\r
              mAccount = getIntent().getExtras().getParcelable(EXTRA_ACCOUNT);\r
              if (mAccount != null) {
-                 String ocVersion = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);\r
-                 String ocVersionString = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION_STRING);
+                 String ocVersion = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);
                  if (ocVersion != null) {\r
-                     mDiscoveredVersion = new OwnCloudVersion(ocVersion, ocVersionString);\r
+                     mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
                  }\r
                  mHostBaseUrl = normalizeUrl(mAccountMgr.getUserData(mAccount, Constants.KEY_OC_BASE_URL));\r
                  mHostUrlInput.setText(mHostBaseUrl);\r
  \r
              /// server data\r
              String ocVersion = savedInstanceState.getString(KEY_OC_VERSION);\r
-             String ocVersionString = savedInstanceState.getString(KEY_OC_VERSION_STRING);\r
              if (ocVersion != null) {\r
-                 mDiscoveredVersion = new OwnCloudVersion(ocVersion, ocVersionString);\r
+                 mDiscoveredVersion = new OwnCloudVersion(ocVersion);\r
              }\r
              mHostBaseUrl = savedInstanceState.getString(KEY_HOST_URL_TEXT);\r
  \r
  \r
              mServerAuthMethod = AuthenticationMethod.valueOf(\r
                      savedInstanceState.getString(KEY_SERVER_AUTH_METHOD));\r
 -            mDetectAuthOpId = savedInstanceState.getInt(KEY_DETECT_AUTH_OP_ID);\r
 +            mGetServerInfoOpId = savedInstanceState.getInt(KEY_DETECT_AUTH_OP_ID);\r
  \r
          }\r
  \r
              mOAuth2Check.setVisibility(View.GONE);\r
          }\r
  \r
 -        //if (mServerIsChecked && !mServerIsValid && mRefreshButtonEnabled) showRefreshButton();\r
 -        if (mServerIsChecked && !mServerIsValid && refreshButtonEnabled) showRefreshButton();\r
 +        showRefreshButton(mServerIsChecked && !mServerIsValid && refreshButtonEnabled);\r
          mOkButton.setEnabled(mServerIsValid); // state not automatically recovered in configuration changes\r
  \r
          if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType) || \r
          outState.putInt(KEY_SERVER_STATUS_ICON, mServerStatusIcon);\r
          outState.putBoolean(KEY_SERVER_VALID, mServerIsValid);\r
          outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);\r
 -        outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mOcServerChkOperation != null));\r
 +        outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mServerInfoOperation != null));\r
          outState.putBoolean(KEY_IS_SSL_CONN, mIsSslConn);\r
          outState.putBoolean(KEY_PASSWORD_VISIBLE, isPasswordVisible());\r
          outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);\r
          /// server data\r
          if (mDiscoveredVersion != null) {\r
              outState.putString(KEY_OC_VERSION, mDiscoveredVersion.getVersion());\r
-             outState.putString(KEY_OC_VERSION_STRING, mDiscoveredVersion.getVersionString());\r
          }\r
          outState.putString(KEY_HOST_URL_TEXT, mHostBaseUrl);\r
  \r
          outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, (mRefreshButton.getVisibility() == View.VISIBLE));\r
          \r
          outState.putString(KEY_SERVER_AUTH_METHOD, mServerAuthMethod.name());\r
 -        outState.putInt(KEY_DETECT_AUTH_OP_ID, mDetectAuthOpId);\r
 +        outState.putInt(KEY_DETECT_AUTH_OP_ID, mGetServerInfoOpId);\r
          //Log.wtf(TAG, "onSaveInstanceState end" );\r
      }\r
  \r
          /// Showing the dialog with instructions for the user.\r
          showDialog(DIALOG_OAUTH2_LOGIN_PROGRESS);\r
  \r
 -        /// GET ACCESS TOKEN to the oAuth server \r
 +        /// GET ACCESS TOKEN to the oAuth server\r
 +        Intent getServerInfoIntent = new Intent();\r
 +        getServerInfoIntent.setAction(OperationsService.ACTION_OAUTH2_GET_ACCESS_TOKEN);\r
 +        \r
 +        getServerInfoIntent.putExtra(\r
 +                OperationsService.EXTRA_SERVER_URL, \r
 +                mOAuthTokenEndpointText.getText().toString().trim());\r
 +        \r
 +        getServerInfoIntent.putExtra(\r
 +                OperationsService.EXTRA_OAUTH2_QUERY_PARAMETERS, \r
 +                queryParameters);\r
 +        \r
 +        if (mOperationsServiceBinder != null) {\r
 +            //Log.wtf(TAG, "getting access token..." );\r
 +            mOauth2GetAccessTokenOpId = mOperationsServiceBinder.newOperation(getServerInfoIntent);\r
 +        }\r
 +        \r
 +        /*\r
          RemoteOperation operation = new OAuth2GetAccessToken(   getString(R.string.oauth2_client_id), \r
                  getString(R.string.oauth2_redirect_uri),       \r
                  getString(R.string.oauth2_grant_type),\r
          //OwnCloudClient client = OwnCloudClientUtils.createOwnCloudClient(Uri.parse(getString(R.string.oauth2_url_endpoint_access)), getApplicationContext());\r
          OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mOAuthTokenEndpointText.getText().toString().trim()), getApplicationContext(), true);\r
          operation.execute(client, this, mHandler);\r
 +        */\r
 +        \r
      }\r
  \r
  \r
                  onUrlInputFocusLost((TextView) view);\r
              }\r
              else {\r
 -                hideRefreshButton();\r
 +                showRefreshButton(false);\r
              }\r
  \r
          } else if (view.getId() == R.id.account_password) {\r
              checkOcServer();\r
          } else {\r
              mOkButton.setEnabled(mServerIsValid);\r
 -            if (!mServerIsValid) {\r
 -                showRefreshButton();\r
 -            }\r
 +            showRefreshButton(!mServerIsValid);\r
          }\r
      }\r
  \r
  \r
      private void checkOcServer() {\r
 -        String uri = trimUrlWebdav(mHostUrlInput.getText().toString().trim());\r
 +        String uri = mHostUrlInput.getText().toString().trim();\r
  \r
          if (!mHostUrlInputEnabled){\r
 -            uri = getString(R.string.server_url);\r
 +            uri = getString(R.string.server_url).trim();\r
          }\r
  \r
          mServerIsValid = false;\r
          mServerIsChecked = false;\r
          mOkButton.setEnabled(false);\r
          mDiscoveredVersion = null;\r
 -        hideRefreshButton();\r
 +        mServerAuthMethod = AuthenticationMethod.UNKNOWN;\r
 +        showRefreshButton(false);\r
 +        \r
          if (uri.length() != 0) {\r
              mServerStatusText = R.string.auth_testing_connection;\r
              mServerStatusIcon = R.drawable.progress_small;\r
              showServerStatus();\r
 -            mOcServerChkOperation = new  GetRemoteStatusOperation(uri, this);\r
 -            OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(uri), this, true);\r
 -            mOperationThread = mOcServerChkOperation.execute(client, this, mHandler);\r
 +            \r
 +            Intent getServerInfoIntent = new Intent();\r
 +            getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);\r
 +            getServerInfoIntent.putExtra(OperationsService.EXTRA_SERVER_URL, uri);\r
 +            getServerInfoIntent.putExtra(OperationsService.EXTRA_AUTH_TOKEN_TYPE, mAuthTokenType);\r
 +            if (mOperationsServiceBinder != null) {\r
 +                //Log.wtf(TAG, "checking server..." );\r
 +                mGetServerInfoOpId = mOperationsServiceBinder.newOperation(getServerInfoIntent);\r
 +            }\r
 +            \r
          } else {\r
              mServerStatusText = 0;\r
              mServerStatusIcon = 0;\r
          showDialog(DIALOG_LOGIN_PROGRESS);\r
  \r
          /// test credentials accessing the root folder\r
-         mAuthCheckOperation = new  ExistenceCheckRemoteOperation("", this, false);\r
-         OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, true);\r
-         client.setBasicCredentials(username, password);\r
-         mOperationThread = mAuthCheckOperation.execute(client, this, mHandler);\r
+         String remotePath ="";\r
+         boolean successIfAbsent = false;\r
+         boolean followRedirects = true;\r
+         startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, username, password, followRedirects);\r
+         \r
      }\r
  \r
 -            Log.wtf(TAG, "starting existenceCheckRemoteOperation..." );\r
+     private void startExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent, String webdav_path,\r
+             String username, String password, boolean followRedirects) {\r
+         \r
+         Intent existenceCheckIntent = new Intent();\r
+         existenceCheckIntent.setAction(OperationsService.ACTION_EXISTENCE_CHECK);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mHostBaseUrl);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_SUCCESS_IF_ABSENT, successIfAbsent);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_WEBDAV_PATH, webdav_path);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_USERNAME, username);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_PASSWORD, password);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_AUTH_TOKEN, mAuthToken);\r
+         existenceCheckIntent.putExtra(OperationsService.EXTRA_FOLLOW_REDIRECTS, followRedirects);\r
+         \r
+         if (mOperationsServiceBinder != null) {\r
++            Log_OC.wtf(TAG, "starting existenceCheckRemoteOperation..." );\r
+             mExistenceCheckOpId = mOperationsServiceBinder.newOperation(existenceCheckIntent);\r
+         }\r
+     }\r
  \r
      /**\r
       * Starts the OAuth 'grant type' flow to get an access token, with \r
          mAuthStatusText = R.string.oauth_login_connection;\r
          showAuthStatus();\r
  \r
 -\r
          // GET AUTHORIZATION request\r
          //Uri uri = Uri.parse(getString(R.string.oauth2_url_endpoint_auth));\r
          Uri uri = Uri.parse(mOAuthAuthEndpointText.getText().toString().trim());\r
          String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType);\r
  \r
          /// test credentials accessing the root folder\r
-         mAuthCheckOperation = new  ExistenceCheckRemoteOperation("", this, false);\r
-         OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, false);\r
-         mOperationThread = mAuthCheckOperation.execute(client, this, mHandler);\r
+         String remotePath ="";\r
+         boolean successIfAbsent = false;\r
+         boolean followRedirections = false;\r
+         startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, "", "", followRedirections);\r
  \r
      }\r
  \r
      @Override\r
      public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {\r
  \r
 -        if (operation instanceof GetRemoteStatusOperation) {\r
 -            onOcServerCheckFinish((GetRemoteStatusOperation) operation, result);\r
 +        if (operation instanceof GetServerInfoOperation) {\r
 +            if (operation.hashCode() == mGetServerInfoOpId) {\r
 +                onGetServerInfoFinish(result);\r
 +            }   // else nothing ; only the last check operation is considered; \r
 +                // multiple can be started if the user amends a URL quickly\r
  \r
          } else if (operation instanceof OAuth2GetAccessToken) {\r
 -            onGetOAuthAccessTokenFinish((OAuth2GetAccessToken)operation, result);\r
 +            onGetOAuthAccessTokenFinish(result);\r
  \r
          } else if (operation instanceof ExistenceCheckRemoteOperation)  {\r
 -            Log.wtf(TAG, "received detection response through callback" );\r
++            Log_OC.wtf(TAG, "received detection response through callback" );\r
              if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {\r
-                 onSamlBasedFederatedSingleSignOnAuthorizationStart(operation, result);\r
+                 onSamlBasedFederatedSingleSignOnAuthorizationStart(result);\r
  \r
              } else {\r
-                 onAuthorizationCheckFinish((ExistenceCheckRemoteOperation)operation, result);\r
+                 onAuthorizationCheckFinish(result);\r
              }\r
          } else if (operation instanceof GetRemoteUserNameOperation) {\r
              onGetUserNameFinish((GetRemoteUserNameOperation) operation, result);\r
  \r
 -        } else if (operation instanceof DetectAuthenticationMethodOperation) {\r
 -            Log.wtf(TAG, "received detection response through callback" );\r
 -            onDetectAuthenticationFinish(result);\r
          }\r
  \r
      }\r
  \r
 -    private void onDetectAuthenticationFinish(RemoteOperationResult result) {\r
 -        // Read authentication method\r
 -        mDetectAuthOpId = -1;\r
 -        if (result.getData().size() > 0) {\r
 -            AuthenticationMethod authMethod = (AuthenticationMethod) result.getData().get(0);\r
 -            String basic = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
 -            String oAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
 -            String saml =  AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());\r
 -\r
 -            if ( ( mAuthTokenType.equals(basic) && !authMethod.equals(AuthenticationMethod.BASIC_HTTP_AUTH) ) ||\r
 -                    ( mAuthTokenType.equals(oAuth) && !authMethod.equals(AuthenticationMethod.BEARER_TOKEN) ) || \r
 -                    ( mAuthTokenType.equals(saml)  && !authMethod.equals(AuthenticationMethod.SAML_WEB_SSO) ) ) {\r
 -\r
 -                mOkButton.setEnabled(false);\r
 -                mServerIsValid = false;\r
 -                //show an alert message ( Server Status )\r
 -                updateServerStatusIconNoRegularAuth();\r
 -                showServerStatus();\r
 -\r
 -            } else {\r
 -                mOkButton.setEnabled(true);\r
 -\r
 -                // Show server status\r
 -                showServerStatus();\r
 -            }\r
 -\r
 -        }\r
 -    }\r
 -\r
 -\r
 -\r
      private void onGetUserNameFinish(GetRemoteUserNameOperation operation, RemoteOperationResult result) {\r
  \r
          if (result.isSuccess()) {\r
  \r
      }\r
  \r
-     private void onSamlBasedFederatedSingleSignOnAuthorizationStart(RemoteOperation operation, RemoteOperationResult result) {\r
+     private void onSamlBasedFederatedSingleSignOnAuthorizationStart(RemoteOperationResult result) {\r
++        mExistenceCheckOpId = -1;\r
          try {\r
              dismissDialog(DIALOG_LOGIN_PROGRESS);\r
          } catch (IllegalArgumentException e) {\r
       * @param operation     Server check performed.\r
       * @param result        Result of the check.\r
       */\r
 -    private void onOcServerCheckFinish(GetRemoteStatusOperation operation, RemoteOperationResult result) {\r
 -        if (operation.equals(mOcServerChkOperation)) {\r
 -            /// save result state\r
 -            mServerIsChecked = true;\r
 -            mServerIsValid = result.isSuccess();\r
 -            mIsSslConn = (result.getCode() == ResultCode.OK_SSL);\r
 -            mOcServerChkOperation = null;\r
 -\r
 -\r
 -            /// retrieve discovered version and normalize server URL\r
 -            mDiscoveredVersion = operation.getDiscoveredVersion();\r
 -            mHostBaseUrl = normalizeUrl(mHostUrlInput.getText().toString());\r
 +    private void onGetServerInfoFinish(RemoteOperationResult result) {\r
 +        /// update activity state\r
 +        mServerIsChecked = true;\r
 +        mIsSslConn = (result.getCode() == ResultCode.OK_SSL);\r
 +        mServerInfoOperation = null;\r
 +        mGetServerInfoOpId = -1;\r
 +        \r
 +        // update server status, but don't show it yet\r
 +        updateServerStatusIconAndText(result);\r
  \r
 -            // Refresh server status, but don't show it\r
 -            updateServerStatusIconAndText(result);\r
 +        if (result.isSuccess()) {\r
 +            /// SUCCESS means:\r
 +            //      1. connection succeeded, and we know if it's SSL or not\r
 +            //      2. server is installed\r
 +            //      3. we got the server version\r
 +            //      4. we got the authentication method required by the server \r
 +            mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));\r
 +            mDiscoveredVersion = mServerInfo.mVersion;\r
 +            mHostBaseUrl = mServerInfo.mBaseUrl;\r
 +            mServerAuthMethod = mServerInfo.mAuthMethod;\r
 +            \r
 +            if (!authSupported(mServerAuthMethod)) {\r
 +                \r
 +                updateServerStatusIconNoRegularAuth();  // overrides updateServerStatusIconAndText()  \r
 +                mServerIsValid = false;\r
  \r
 -            /// update status icon and text\r
 -            if (mServerIsValid) {\r
 -                hideRefreshButton();\r
 -                // Try to create an account with user and pass "", to know if it is a regular server\r
 -                // Update connect button in the answer of this method\r
 -                detectAuthorizationMethod();\r
              } else {\r
 -                showRefreshButton();\r
 -                // Show server status\r
 -                showServerStatus();\r
 +                mServerIsValid = true;\r
              }\r
 +            \r
 +        } else {\r
 +            mServerIsValid = false;\r
 +        }\r
  \r
 -            /// very special case (TODO: move to a common place for all the remote operations)\r
 -            if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {\r
 -                showUntrustedCertDialog(result);\r
 -            }\r
 -\r
 -\r
 -        }   // else nothing ; only the last check operation is considered; \r
 -        // multiple can be triggered if the user amends a URL before a previous check can be triggered\r
 +        // refresh UI\r
 +        showRefreshButton(!mServerIsValid);\r
 +        showServerStatus();\r
 +        mOkButton.setEnabled(mServerIsValid);\r
 +        \r
 +        /// very special case (TODO: move to a common place for all the remote operations)\r
 +        if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {\r
 +            showUntrustedCertDialog(result);\r
 +        }\r
      }\r
  \r
  \r
 -    /**\r
 -     *  Try to access with  user/pass ""/"", to know if it is a regular server\r
 -     */\r
 -    private void detectAuthorizationMethod() {\r
 -\r
 -        Log_OC.d(TAG, "Trying empty authorization to detect authentication method");\r
 -        \r
 -        String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType);\r
 +    private boolean authSupported(AuthenticationMethod authMethod) {\r
 +        String basic = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
 +        String oAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
 +        String saml =  AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());\r
          \r
 -        /// test credentials \r
 -        //Intent detectAuthIntent = new Intent(this, OperationsService.class);\r
 -        Intent detectAuthIntent = new Intent();\r
 -        detectAuthIntent.setAction(OperationsService.ACTION_DETECT_AUTHENTICATION_METHOD);\r
 -        detectAuthIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mHostBaseUrl);\r
 -        detectAuthIntent.putExtra(OperationsService.EXTRA_WEBDAV_PATH, webdav_path);\r
 -        \r
 -        //if (mOperationsBinder != null) {  // let's let it crash to detect if is really possible\r
 -        mServerAuthMethod = AuthenticationMethod.UNKNOWN;\r
 -        if (mOperationsServiceBinder != null) {\r
 -            //Log.wtf(TAG, "starting detection..." );\r
 -            mDetectAuthOpId = mOperationsServiceBinder.newOperation(detectAuthIntent);\r
 -        }\r
 -        //}\r
 +        return (( mAuthTokenType.equals(basic) && \r
 +                    authMethod.equals(AuthenticationMethod.BASIC_HTTP_AUTH) ) ||\r
 +                ( mAuthTokenType.equals(oAuth) && \r
 +                    authMethod.equals(AuthenticationMethod.BEARER_TOKEN)) ||\r
 +                ( mAuthTokenType.equals(saml)  && \r
 +                    authMethod.equals(AuthenticationMethod.SAML_WEB_SSO))\r
 +        );\r
      }\r
  \r
  \r
 +    // TODO remove, if possible\r
      private String normalizeUrl(String url) {\r
          if (url != null && url.length() > 0) {\r
              url = url.trim();\r
                      url = "http://" + url;\r
                  }\r
              }\r
\r
-             // OC-208: Add suffix remote.php/webdav to normalize (OC-34)            \r
+             \r
              url = trimUrlWebdav(url);\r
  \r
              if (url.endsWith("/")) {\r
      }\r
  \r
  \r
 +    // TODO remove, if possible\r
      private String trimUrlWebdav(String url){       \r
          if(url.toLowerCase().endsWith(AccountUtils.WEBDAV_PATH_4_0)){\r
              url = url.substring(0, url.length() - AccountUtils.WEBDAV_PATH_4_0.length());             \r
       * Processes the result of the request for and access token send \r
       * to an OAuth authorization server.\r
       * \r
 -     * @param operation     Operation performed requesting the access token.\r
       * @param result        Result of the operation.\r
       */\r
 -    private void onGetOAuthAccessTokenFinish(OAuth2GetAccessToken operation, RemoteOperationResult result) {\r
 +    private void onGetOAuthAccessTokenFinish(RemoteOperationResult result) {\r
 +        mOauth2GetAccessTokenOpId = -1;\r
          try {\r
              dismissDialog(DIALOG_OAUTH2_LOGIN_PROGRESS);\r
          } catch (IllegalArgumentException e) {\r
              showDialog(DIALOG_LOGIN_PROGRESS);\r
  \r
              /// time to test the retrieved access token on the ownCloud server\r
 -            mAuthToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN);\r
 +            @SuppressWarnings("unchecked")\r
 +            Map<String, String> tokens = (Map<String, String>)(result.getData().get(0));\r
 +            mAuthToken = tokens.get(OAuth2Constants.KEY_ACCESS_TOKEN);\r
 +            //mAuthToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN);\r
              Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken);\r
-             mAuthCheckOperation = new ExistenceCheckRemoteOperation("", this, false);\r
-             OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(Uri.parse(mHostBaseUrl + webdav_path), this, true);\r
-             client.setBearerCredentials(mAuthToken);\r
-             mAuthCheckOperation.execute(client, this, mHandler);\r
+             \r
+             String remotePath ="";\r
+             boolean successIfAbsent = false;\r
+             boolean followRedirects = true;\r
+             startExistenceCheckRemoteOperation(remotePath, this, successIfAbsent, webdav_path, "", "", followRedirects);\r
  \r
          } else {\r
              updateAuthStatusIconAndText(result);\r
       * @param operation     Access check performed.\r
       * @param result        Result of the operation.\r
       */\r
-     private void onAuthorizationCheckFinish(ExistenceCheckRemoteOperation operation, RemoteOperationResult result) {\r
+     private void onAuthorizationCheckFinish(RemoteOperationResult result) {\r
++        mExistenceCheckOpId = -1;\r
          try {\r
              dismissDialog(DIALOG_LOGIN_PROGRESS);\r
          } catch (IllegalArgumentException e) {\r
              mServerIsChecked = true;\r
              mServerIsValid = false;\r
              mIsSslConn = false;\r
 -            mOcServerChkOperation = null;\r
 +            mServerInfoOperation = null;\r
              mDiscoveredVersion = null;\r
              mHostBaseUrl = normalizeUrl(mHostUrlInput.getText().toString());\r
  \r
              showAuthStatus();\r
  \r
              // update input controls state\r
 -            showRefreshButton();\r
 +            showRefreshButton(true);\r
              mOkButton.setEnabled(false);\r
  \r
              // very special case (TODO: move to a common place for all the remote operations) (dangerous here?)\r
              }\r
              /// add user data to the new account; TODO probably can be done in the last parameter addAccountExplicitly, or in KEY_USERDATA
              mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION,         mDiscoveredVersion.getVersion());\r
-             mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION_STRING,  mDiscoveredVersion.getVersionString());\r
              mAccountMgr.setUserData(mAccount, Constants.KEY_OC_BASE_URL,   mHostBaseUrl);\r
  
              if (isSaml) {\r
      }     \r
  \r
  \r
 -    private void showRefreshButton() {\r
 -        mRefreshButton.setVisibility(View.VISIBLE);\r
 -    }\r
 -\r
 -    private void hideRefreshButton() {\r
 -        mRefreshButton.setVisibility(View.GONE);\r
 +    private void showRefreshButton (boolean show) {\r
 +        if (show)  {\r
 +            mRefreshButton.setVisibility(View.VISIBLE);\r
 +        } else {\r
 +            mRefreshButton.setVisibility(View.GONE);\r
 +        }\r
      }\r
  \r
      /**\r
          //Log.wtf(TAG, "registering to listen for operation callbacks" );\r
          mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler);\r
          \r
 -        if (mDetectAuthOpId != -1) {\r
 +        if (mGetServerInfoOpId != -1) {\r
              RemoteOperationResult result = \r
 -                    mOperationsServiceBinder.getOperationResultIfFinished(mDetectAuthOpId);\r
 +                    mOperationsServiceBinder.getOperationResultIfFinished(mGetServerInfoOpId);\r
              if (result != null) {\r
--                //Log.wtf(TAG, "found result of operation finished while rotating");\r
 -                onDetectAuthenticationFinish(result);\r
++                //Log_OC.wtf(TAG, "found result of operation finished while rotating");\r
 +                onGetServerInfoFinish(result);\r
              }\r
 -        }\r
 -        \r
 -        if (mExistenceCheckOpId != -1) {\r
 +            \r
 +        } else if (mOauth2GetAccessTokenOpId != -1) {\r
 +            RemoteOperationResult result = \r
 +                    mOperationsServiceBinder.getOperationResultIfFinished(\r
 +                            mOauth2GetAccessTokenOpId);\r
 +            if (result != null) {\r
-                 //Log.wtf(TAG, "found result of operation finished while rotating");\r
++                //Log_OC.wtf(TAG, "found result of operation finished while rotating");\r
 +                onGetOAuthAccessTokenFinish(result);\r
 +            }\r
++            \r
++        } else if (mExistenceCheckOpId != -1) {\r
+             RemoteOperationResult result = \r
+                     mOperationsServiceBinder.getOperationResultIfFinished(mExistenceCheckOpId);\r
+             if (result != null) {\r
 -                Log.wtf(TAG, "found result of operation finished while rotating");\r
 -                if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {\r
++                //Log_OC.wtf(TAG, "found result of operation finished while rotating");\r
++                if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(\r
++                        MainApp.getAccountType()).equals(mAuthTokenType)) {\r
+                     onSamlBasedFederatedSingleSignOnAuthorizationStart(result);\r
\r
+                 } else {\r
+                     onAuthorizationCheckFinish(result);\r
+                 }\r
+             }\r
          }\r
      }\r
      \r
@@@ -23,18 -23,17 +23,19 @@@ import java.util.concurrent.ConcurrentH
  import java.util.concurrent.ConcurrentLinkedQueue;
  import java.util.concurrent.ConcurrentMap;
  
 +import com.owncloud.android.R;
  import com.owncloud.android.datamodel.FileDataStorageManager;
  import com.owncloud.android.lib.common.OwnCloudClientFactory;
  import com.owncloud.android.lib.common.OwnCloudClient;
  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.files.ExistenceCheckRemoteOperation;
  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.DetectAuthenticationMethodOperation;
 +import com.owncloud.android.operations.GetServerInfoOperation;
 +import com.owncloud.android.operations.OAuth2GetAccessToken;
  import com.owncloud.android.operations.UnshareLinkOperation;
  import com.owncloud.android.utils.Log_OC;
  
@@@ -58,16 -57,20 +59,25 @@@ 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_AUTH_TOKEN_TYPE = "AUTH_TOKEN_TYPE";
 +    public static final String EXTRA_OAUTH2_QUERY_PARAMETERS = "OAUTH2_QUERY_PARAMETERS";
      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";
 +    
++    // TODO review if ALL OF THEM are necessary
+     public static final String EXTRA_WEBDAV_PATH = "WEBDAV_PATH";
+     public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT";
+     public static final String EXTRA_USERNAME = "USERNAME";
+     public static final String EXTRA_PASSWORD = "PASSWORD";
+     public static final String EXTRA_AUTH_TOKEN = "AUTH_TOKEN";
+     public static final String EXTRA_FOLLOW_REDIRECTS = "FOLLOW_REDIRECTS";
+     
      public static final String ACTION_CREATE_SHARE = "CREATE_SHARE";
      public static final String ACTION_UNSHARE = "UNSHARE";
 -    public static final String ACTION_DETECT_AUTHENTICATION_METHOD = "DETECT_AUTHENTICATION_METHOD";
 +    public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO";
 +    public static final String ACTION_OAUTH2_GET_ACCESS_TOKEN = "OAUTH2_GET_ACCESS_TOKEN";
+     public static final String ACTION_EXISTENCE_CHECK = "EXISTENCE_CHECK";
      
      public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED";
      public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED";
      private static class Target {
          public Uri mServerUrl = null;
          public Account mAccount = null;
-         public Target(Account account, Uri serverUrl) {
+         public String mWebDavUrl = "";
+         public String mUsername = "";
+         public String mPassword = "";
+         public String mAuthToken = "";
+         public boolean mFollowRedirects = true;
+         
+         public Target(Account account, Uri serverUrl, String webdavUrl, String username, String password, String authToken,
+                 boolean followRedirects) {
              mAccount = account;
              mServerUrl = serverUrl;
+             mWebDavUrl = webdavUrl;
+             mUsername = username;
+             mPassword = password;
+             mAuthToken = authToken;
+             mFollowRedirects = followRedirects;
          }
      }
  
                  } else {
                      Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT);
                      String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL);
+                     String webDavPath = operationIntent.getStringExtra(EXTRA_WEBDAV_PATH);
+                     String webDavUrl = serverUrl + webDavPath;
+                     String username = operationIntent.getStringExtra(EXTRA_USERNAME);
+                     String password = operationIntent.getStringExtra(EXTRA_PASSWORD);
+                     String authToken = operationIntent.getStringExtra(EXTRA_AUTH_TOKEN);
+                     boolean followRedirects = operationIntent.getBooleanExtra(EXTRA_FOLLOW_REDIRECTS, true);
                      target = new Target(
                              account, 
-                             (serverUrl == null) ? null : Uri.parse(serverUrl)
+                             (serverUrl == null) ? null : Uri.parse(serverUrl),
+                             ((webDavPath == null) || (serverUrl == null)) ? "" : webDavUrl,
+                             (username == null) ? "" : username,
+                             (password == null) ? "" : password,
+                             (authToken == null) ? "" : authToken,
+                             followRedirects
                      );
                      
                      String action = operationIntent.getAction();
                              operation = new CreateShareOperation(remotePath, ShareType.PUBLIC_LINK, 
                                      "", false, "", 1, sendIntent);
                          }
++                        
                      } else if (action.equals(ACTION_UNSHARE)) {  // Unshare file
                          String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
                          if (remotePath.length() > 0) {
                                      remotePath, 
                                      OperationsService.this);
                          }
 -                    } else if (action.equals(ACTION_DETECT_AUTHENTICATION_METHOD)) { 
 -                        // Detect Authentication Method
 -                        String webdav_url = 
 -                                serverUrl + operationIntent.getStringExtra(EXTRA_WEBDAV_PATH);
 -                        operation = new DetectAuthenticationMethodOperation(
 -                                OperationsService.this, 
 -                                webdav_url);
++                        
 +                    } else if (action.equals(ACTION_GET_SERVER_INFO)) { 
 +                        // check OC server and get basic information from it
 +                        String authTokenType = 
 +                                operationIntent.getStringExtra(EXTRA_AUTH_TOKEN_TYPE);
 +                        operation = new GetServerInfoOperation(
 +                                serverUrl, authTokenType, 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_EXISTENCE_CHECK)) {
+                         // Existence Check 
+                         String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+                         boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, true);
+                         operation = new ExistenceCheckRemoteOperation(remotePath, OperationsService.this, successIfAbsent);
+                         
                      }
                  }
                      
          synchronized(mPendingOperations) {
              next = mPendingOperations.peek();
          }
-         
          if (next != null) {
              
              mCurrentOperation = next.second;
                          mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mAccount, getApplicationContext());
                          mStorageManager = new FileDataStorageManager(mLastTarget.mAccount, getContentResolver());
                      } else {
-                         mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), true);    // this is not good enough
+                         mOwnCloudClient = OwnCloudClientFactory.createOwnCloudClient(mLastTarget.mServerUrl, getApplicationContext(), 
+                                 mLastTarget.mFollowRedirects);    // this is not good enough
+                         if (mLastTarget.mWebDavUrl != "") {
+                             mOwnCloudClient.setWebdavUri(Uri.parse(mLastTarget.mWebDavUrl));
+                         }
+                         if (mLastTarget.mUsername != "" && mLastTarget.mPassword != "") {
+                             mOwnCloudClient.setBasicCredentials(mLastTarget.mUsername, mLastTarget.mPassword);
+                         } else if (mLastTarget.mAuthToken != "") {
+                             mOwnCloudClient.setBearerCredentials(mLastTarget.mAuthToken);
+                         }
                          mStorageManager = null;
                      }
                  }