Run ExistenceCheckRemoteOperation on OperationsService
[pub/Android/ownCloud.git] / src / com / owncloud / android / authentication / AuthenticatorActivity.java
index 638b5dd..3c14404 100644 (file)
@@ -45,6 +45,7 @@ import android.support.v4.app.FragmentTransaction;
 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
@@ -111,7 +112,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     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
@@ -124,6 +124,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     private static final String KEY_AUTH_STATUS_ICON = "AUTH_STATUS_ICON";\r
     private static final String KEY_REFRESH_BUTTON_ENABLED = "KEY_REFRESH_BUTTON_ENABLED";\r
     //private static final String KEY_IS_SHARED_SUPPORTED = "KEY_IS_SHARE_SUPPORTED";\r
+    private static final String KEY_SERVER_AUTH_METHOD = "KEY_SERVER_AUTH_METHOD";\r
+    private static final String KEY_DETECT_AUTH_OP_ID = "KEY_DETECT_AUTH_OP_ID";\r
+\r
 \r
     private static final String AUTH_ON = "on";\r
     private static final String AUTH_OFF = "off";\r
@@ -144,17 +147,18 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     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 mAuthStatusText, mAuthStatusIcon;    \r
     private TextView mAuthStatusLayout;\r
 \r
-    private ServiceConnection mOperationsConnection = null;\r
-    private OperationsServiceBinder mOperationsBinder = null;\r
-    \r
     private final Handler mHandler = new Handler();\r
     private Thread mOperationThread;\r
     private GetRemoteStatusOperation mOcServerChkOperation;\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
@@ -192,7 +196,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     \r
     private OperationsServiceBinder mOperationsServiceBinder = null;\r
 \r
-\r
     /**\r
      * {@inheritDoc}\r
      * \r
@@ -204,31 +207,17 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
 \r
         // bind to Operations Service\r
-        mOperationsConnection = new ServiceConnection() {\r
-\r
-            @Override\r
-            public void onServiceConnected(ComponentName name, IBinder service) {\r
-                Log_OC.d(TAG, "Operations service connected");\r
-                mOperationsBinder = (OperationsServiceBinder) service;\r
-            }\r
-\r
-            @Override\r
-            public void onServiceDisconnected(ComponentName name) {\r
-                Log_OC.d(TAG, "Operations service crashed");\r
-                mOperationsBinder = null;\r
-            }\r
-            \r
-        };\r
+        mOperationsServiceConnection = new OperationsServiceConnection();\r
         if (!bindService(new Intent(this, OperationsService.class), \r
-                        mOperationsConnection, \r
-                        Context.BIND_AUTO_CREATE)) {\r
+                mOperationsServiceConnection, \r
+                Context.BIND_AUTO_CREATE)) {\r
             Toast.makeText(this, \r
                     R.string.error_cant_bind_to_operations_service, \r
                     Toast.LENGTH_LONG)\r
                         .show();\r
             finish();\r
         }\r
-\r
+                \r
         /// set view and get references to view elements\r
         setContentView(R.layout.account_setup);\r
         mAuthMessage = (TextView) findViewById(R.id.auth_message);\r
@@ -288,10 +277,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             /// 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
@@ -324,9 +312,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \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
@@ -347,6 +334,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             refreshButtonEnabled = savedInstanceState.getBoolean(KEY_REFRESH_BUTTON_ENABLED);\r
 \r
 \r
+            mServerAuthMethod = AuthenticationMethod.valueOf(\r
+                    savedInstanceState.getString(KEY_SERVER_AUTH_METHOD));\r
+            mDetectAuthOpId = savedInstanceState.getInt(KEY_DETECT_AUTH_OP_ID);\r
+\r
         }\r
 \r
         if (mAuthMessageVisibility== View.VISIBLE) {\r
@@ -433,8 +424,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             }\r
         });\r
         \r
-        mOperationsServiceConnection = new OperationsServiceConnection();\r
-        bindService(new Intent(this, OperationsService.class), mOperationsServiceConnection, Context.BIND_AUTO_CREATE);\r
     }\r
 \r
 \r
@@ -487,6 +476,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      */\r
     @Override\r
     protected void onSaveInstanceState(Bundle outState) {\r
+        //Log.wtf(TAG, "onSaveInstanceState init" );\r
         super.onSaveInstanceState(outState);\r
 \r
         /// connection state and info\r
@@ -505,7 +495,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         /// 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
@@ -517,8 +506,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
         // refresh button enabled\r
         outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, (mRefreshButton.getVisibility() == View.VISIBLE));\r
-\r
-\r
+        \r
+        outState.putString(KEY_SERVER_AUTH_METHOD, mServerAuthMethod.name());\r
+        outState.putInt(KEY_DETECT_AUTH_OP_ID, mDetectAuthOpId);\r
+        //Log.wtf(TAG, "onSaveInstanceState end" );\r
     }\r
 \r
 \r
@@ -545,7 +536,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      */\r
     @Override\r
     protected void onResume() {\r
+        //Log.wtf(TAG, "onResume init" );\r
         super.onResume();\r
+        \r
         if (mAction == ACTION_UPDATE_TOKEN && mJustCreated && getIntent().getBooleanExtra(EXTRA_ENFORCED_UPDATE, false)) {\r
             if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) {\r
                 //Toast.makeText(this, R.string.auth_expired_oauth_token_toast, Toast.LENGTH_LONG).show();\r
@@ -562,17 +555,33 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         if (mNewCapturedUriFromOAuth2Redirection != null) {\r
             getOAuth2AccessTokenFromCapturedRedirection();            \r
         }\r
-\r
+        \r
         mJustCreated = false;\r
 \r
+        if (mOperationsServiceBinder != null) {\r
+            doOnResumeAndBound();\r
+        }\r
+        \r
+        //Log.wtf(TAG, "onResume end" );\r
     }\r
+\r
     \r
+    @Override\r
+    protected void onPause() {\r
+        //Log.wtf(TAG, "onPause init" );\r
+        if (mOperationsServiceBinder != null) {\r
+            //Log.wtf(TAG, "unregistering to listen for operation callbacks" );\r
+            mOperationsServiceBinder.removeOperationListener(this);\r
+        }\r
+        super.onPause();\r
+        //Log.wtf(TAG, "onPause end" );\r
+    }\r
     \r
     @Override\r
     protected void onDestroy() {\r
-        if (mOperationsConnection != null) {\r
-            unbindService(mOperationsConnection);\r
-            mOperationsBinder = null;\r
+        if (mOperationsServiceConnection != null) {\r
+            unbindService(mOperationsServiceConnection);\r
+            mOperationsServiceBinder = null;\r
         }\r
         super.onDestroy();\r
     }\r
@@ -786,12 +795,32 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         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
+    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.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
@@ -835,9 +864,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         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
@@ -856,23 +886,26 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             onGetOAuthAccessTokenFinish((OAuth2GetAccessToken)operation, result);\r
 \r
         } else if (operation instanceof ExistenceCheckRemoteOperation)  {\r
+            Log.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
-            onDetectAutheticationFinish((DetectAuthenticationMethodOperation) operation, result);\r
+            Log.wtf(TAG, "received detection response through callback" );\r
+            onDetectAuthenticationFinish(result);\r
         }\r
 \r
     }\r
 \r
-    private void onDetectAutheticationFinish(DetectAuthenticationMethodOperation operation, RemoteOperationResult result) {\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
@@ -934,7 +967,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
     }\r
 \r
-    private void onSamlBasedFederatedSingleSignOnAuthorizationStart(RemoteOperation operation, RemoteOperationResult result) {\r
+    private void onSamlBasedFederatedSingleSignOnAuthorizationStart(RemoteOperationResult result) {\r
         try {\r
             dismissDialog(DIALOG_LOGIN_PROGRESS);\r
         } catch (IllegalArgumentException e) {\r
@@ -1014,12 +1047,23 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     private void detectAuthorizationMethod() {\r
 \r
         Log_OC.d(TAG, "Trying empty authorization to detect authentication method");\r
-\r
+        \r
+        String webdav_path = AccountUtils.getWebdavPath(mDiscoveredVersion, mAuthTokenType);\r
+        \r
         /// test credentials \r
-        Intent service = new Intent(this, OperationsService.class);\r
-        service.setAction(OperationsService.ACTION_DETECT_AUTHENTICATION_METHOD);\r
-        service.putExtra(OperationsService.EXTRA_SERVER_URL, mHostBaseUrl);\r
-        startService(service);\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
     }\r
 \r
 \r
@@ -1034,8 +1078,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
                     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
@@ -1251,10 +1294,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             /// time to test the retrieved access token on the ownCloud server\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
@@ -1272,7 +1316,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * @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
         try {\r
             dismissDialog(DIALOG_LOGIN_PROGRESS);\r
         } catch (IllegalArgumentException e) {\r
@@ -1419,7 +1463,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             }\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
@@ -1844,18 +1887,49 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         }\r
 \r
     }\r
+    \r
+    \r
+    private void doOnResumeAndBound() {\r
+        //Log.wtf(TAG, "registering to listen for operation callbacks" );\r
+        mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler);\r
+        \r
+        if (mDetectAuthOpId != -1) {\r
+            RemoteOperationResult result = \r
+                    mOperationsServiceBinder.getOperationResultIfFinished(mDetectAuthOpId);\r
+            if (result != null) {\r
+                //Log.wtf(TAG, "found result of operation finished while rotating");\r
+                onDetectAuthenticationFinish(result);\r
+            }\r
+        }\r
+        \r
+        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
+                    onSamlBasedFederatedSingleSignOnAuthorizationStart(result);\r
 \r
+                } else {\r
+                    onAuthorizationCheckFinish(result);\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
     /** \r
-     * Implements callback methods for service binding. Passed as a parameter to { \r
+     * Implements callback methods for service binding. \r
      */\r
     private class OperationsServiceConnection implements ServiceConnection {\r
 \r
         @Override\r
         public void onServiceConnected(ComponentName component, IBinder service) {\r
             if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) {\r
-                Log_OC.d(TAG, "Operations service connected");\r
+                //Log_OC.wtf(TAG, "Operations service connected");\r
                 mOperationsServiceBinder = (OperationsServiceBinder) service;\r
-                mOperationsServiceBinder.addOperationListener(AuthenticatorActivity.this, mHandler);\r
+                \r
+                doOnResumeAndBound();\r
+                \r
             } else {\r
                 return;\r
             }\r
@@ -1865,11 +1939,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         @Override\r
         public void onServiceDisconnected(ComponentName component) {\r
             if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) {\r
-                Log_OC.d(TAG, "Operations service disconnected");\r
+                Log_OC.e(TAG, "Operations service crashed");\r
                 mOperationsServiceBinder = null;\r
-                // TODO whatever could be waiting for the service is unbound\r
             }\r
         }\r
     \r
     }\r
+    \r
 }\r