Browse Source

Merge pull request #1148 from nextcloud/webLoginFlow

New weblogin flow
Andy Scherzinger 7 years ago
parent
commit
b025f0b864

+ 1 - 1
scripts/lint/lint-results.txt

@@ -1,2 +1,2 @@
 DO NOT TOUCH; GENERATED BY DRONE
-      <span class="mdl-layout-title">Lint Report: 71 errors and 846 warnings</span>
+      <span class="mdl-layout-title">Lint Report: 71 errors and 830 warnings</span>

+ 1 - 0
src/main/AndroidManifest.xml

@@ -185,6 +185,7 @@
             android:name=".authentication.AuthenticatorActivity"
             android:exported="true"
             android:launchMode="singleTask"
+            android:configChanges="orientation|screenSize|keyboardHidden"
             android:theme="@style/Theme.ownCloud.noActionBar.Login">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />

+ 126 - 34
src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author Bartek Przybylski
@@ -53,11 +53,13 @@ import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.net.http.SslError;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
 import android.support.annotation.Nullable;
+import android.support.design.widget.TextInputLayout;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
@@ -72,6 +74,8 @@ import android.view.View;
 import android.view.View.OnFocusChangeListener;
 import android.view.View.OnTouchListener;
 import android.view.inputmethod.EditorInfo;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
 import android.webkit.HttpAuthHandler;
 import android.webkit.SslErrorHandler;
 import android.webkit.WebView;
@@ -79,6 +83,7 @@ import android.webkit.WebViewClient;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.EditText;
+import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
 import android.widget.Toast;
@@ -117,6 +122,7 @@ import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
 
 import java.security.cert.X509Certificate;
+import java.util.HashMap;
 import java.util.Map;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -168,6 +174,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private static final String KEY_USERNAME = "USERNAME";
     private static final String KEY_PASSWORD = "PASSWORD";
     private static final String KEY_ASYNC_TASK_IN_PROGRESS = "AUTH_IN_PROGRESS";
+    private static final String WEB_LOGIN = "/index.php/login/flow";
     public static final String PROTOCOL_SUFFIX = "://";
     public static final String LOGIN_URL_DATA_KEY_VALUE_SEPARATOR = ":";
     public static final String HTTPS_PROTOCOL = "https://";
@@ -233,6 +240,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private boolean webViewLoginMethod;
     private String webViewUser;
     private String webViewPassword;
+    private TextInputLayout mUsernameInputLayout;
+    private TextInputLayout mPasswordInputLayout;
 
     /**
      * {@inheritDoc}
@@ -244,6 +253,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         //Log_OC.e(TAG,  "onCreate init");
         super.onCreate(savedInstanceState);
 
+        // delete cookies for webView
+        deleteCookies();
+
         // Workaround, for fixing a problem with Android Library Suppor v7 19
         //getWindow().requestFeature(Window.FEATURE_NO_TITLE);
         if (getSupportActionBar() != null) {
@@ -284,6 +296,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             /// initialize general UI elements
             initOverallUi();
 
+            mUsernameInputLayout = (TextInputLayout) findViewById(R.id.input_layout_account_username);
+            mPasswordInputLayout = (TextInputLayout) findViewById(R.id.input_layout_account_password);
+
             mOkButton = findViewById(R.id.buttonOK);
             mOkButton.setOnClickListener(new View.OnClickListener() {
 
@@ -317,17 +332,47 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         } else {
             setContentView(R.layout.account_setup_webview);
             mLoginWebView = (WebView) findViewById(R.id.login_webview);
-            initWebViewLogin();
+            initWebViewLogin(null);
         }
 
         initServerPreFragment(savedInstanceState);
     }
 
-    private void initWebViewLogin() {
+    private void deleteCookies() {
+        CookieSyncManager.createInstance(this);
+        CookieManager cookieManager = CookieManager.getInstance();
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            cookieManager.removeAllCookies(null);
+        } else {
+            cookieManager.removeAllCookie();
+        }
+    }
+
+    private static String getWebLoginUserAgent() {
+        return Build.MANUFACTURER.substring(0, 1).toUpperCase() +
+                Build.MANUFACTURER.substring(1).toLowerCase() + " " + Build.MODEL;
+    }
+
+    private void initWebViewLogin(String baseURL) {
+        mLoginWebView.setVisibility(View.GONE);
+
+        final ProgressBar progressBar = (ProgressBar) findViewById(R.id.login_webview_progress_bar);
+
         mLoginWebView.getSettings().setAllowFileAccess(false);
         mLoginWebView.getSettings().setJavaScriptEnabled(true);
-        mLoginWebView.getSettings().setUserAgentString(MainApp.getUserAgent());
-        mLoginWebView.loadUrl(getResources().getString(R.string.webview_login_url));
+        mLoginWebView.getSettings().setUserAgentString(getWebLoginUserAgent());
+        mLoginWebView.getSettings().setSaveFormData(false);
+        mLoginWebView.getSettings().setSavePassword(false);
+
+        if (baseURL != null && !baseURL.isEmpty()){
+            Map<String, String> headers = new HashMap<>();
+            headers.put(RemoteOperation.OCS_API_HEADER, RemoteOperation.OCS_API_HEADER_VALUE);
+            mLoginWebView.loadUrl(baseURL + WEB_LOGIN, headers);
+        } else {
+            mLoginWebView.loadUrl(getResources().getString(R.string.webview_login_url));
+        }
+
         mLoginWebView.setWebViewClient(new WebViewClient() {
             @Override
             public boolean shouldOverrideUrlLoading(WebView view, String url) {
@@ -338,8 +383,17 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 return false;
             }
 
-            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+            @Override
+            public void onPageFinished(WebView view, String url) {
+                super.onPageFinished(view, url);
 
+                progressBar.setVisibility(View.GONE);
+                mLoginWebView.setVisibility(View.VISIBLE);
+            }
+
+            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+                progressBar.setVisibility(View.GONE);
+                mLoginWebView.setVisibility(View.VISIBLE);
                 mLoginWebView.loadData(DisplayUtils.getData(getResources().openRawResource(R.raw.custom_error)),"text/html; charset=UTF-8", null);
             }
         });
@@ -483,6 +537,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         }
     }
 
+    public void onTestServerConnectionClick(View v) {
+        checkOcServer();
+    }
+
 
     /**
      * @param savedInstanceState Saved activity state, as in {{@link #onCreate(Bundle)}
@@ -987,10 +1045,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
 
             Intent getServerInfoIntent = new Intent();
             getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);
-            getServerInfoIntent.putExtra(
-                    OperationsService.EXTRA_SERVER_URL,
-                    normalizeUrlSuffix(uri)
-            );
+            getServerInfoIntent.putExtra(OperationsService.EXTRA_SERVER_URL, normalizeUrlSuffix(uri));
 
             if (mOperationsServiceBinder != null) {
                 mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);
@@ -1283,8 +1338,25 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             //      4. we got the authentication method required by the server 
             mServerInfo = (GetServerInfoOperation.ServerInfo) (result.getData().get(0));
 
-            if (webViewLoginMethod) {
+            webViewLoginMethod = mServerInfo.mVersion.isWebLoginSupported();
+
+            if (webViewUser != null && !webViewUser.isEmpty() &&
+                    webViewPassword != null && !webViewPassword.isEmpty()) {
                 checkBasicAuthorization(webViewUser, webViewPassword);
+            } else if (webViewLoginMethod) {
+                // hide old login
+                mOkButton.setVisibility(View.GONE);
+                mUsernameInputLayout.setVisibility(View.GONE);
+                mPasswordInputLayout.setVisibility(View.GONE);
+
+                setContentView(R.layout.account_setup_webview);
+                mLoginWebView = (WebView) findViewById(R.id.login_webview);
+                initWebViewLogin(mServerInfo.mBaseUrl);
+            } else {
+                // show old login
+                mOkButton.setVisibility(View.VISIBLE);
+                mUsernameInputLayout.setVisibility(View.VISIBLE);
+                mPasswordInputLayout.setVisibility(View.VISIBLE);
             }
 
             if (!authSupported(mServerInfo.mAuthMethod)) {
@@ -1310,6 +1382,14 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             mOkButton.setEnabled(mServerIsValid);
         }
 
+        if (!mServerIsValid) {
+            // hide old login
+            mOkButton.setVisibility(View.GONE);
+            mUsernameInputLayout.setVisibility(View.GONE);
+            mPasswordInputLayout.setVisibility(View.GONE);
+        }
+
+
         /// very special case (TODO: move to a common place for all the remote operations)
         if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
             showUntrustedCertDialog(result);
@@ -1623,8 +1703,26 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 }
             }
 
+            // Reset webView
+            webViewPassword = null;
+            webViewUser = null;
+            deleteCookies();
+
             if (success) {
                 finish();
+            } else {
+                // init webView again
+                mLoginWebView.setVisibility(View.GONE);
+                setContentView(R.layout.account_setup);
+
+                CustomEditText serverAddressField = (CustomEditText) findViewById(R.id.hostUrlInput);
+                serverAddressField.setText(mServerInfo.mBaseUrl);
+
+                findViewById(R.id.oauth_onOff_check).setVisibility(View.GONE);
+                findViewById(R.id.server_status_text).setVisibility(View.GONE);
+                mAuthStatusView = (TextView) findViewById(R.id.auth_status_text);
+
+                showAuthStatus();
             }
 
         } else if (result.isServerFail() || result.isException()) {
@@ -1751,10 +1849,10 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         if (AccountUtils.exists(newAccount, getApplicationContext())) {
             // fail - not a new account, but an existing one; disallow
             RemoteOperationResult result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_NEW);
-            if (!webViewLoginMethod) {
-                updateAuthStatusIconAndText(result);
-                showAuthStatus();
-            }
+
+            updateAuthStatusIconAndText(result);
+            showAuthStatus();
+
             Log_OC.d(TAG, result.getLogMessage());
             return false;
 
@@ -1856,15 +1954,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * to the last check on the ownCloud server.
      */
     private void showServerStatus() {
-        if (!webViewLoginMethod) {
-            if (mServerStatusIcon == 0 && mServerStatusText == 0) {
-                mServerStatusView.setVisibility(View.INVISIBLE);
-
-            } else {
-                mServerStatusView.setText(mServerStatusText);
-                mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
-                mServerStatusView.setVisibility(View.VISIBLE);
-            }
+        if (mServerStatusIcon == 0 && mServerStatusText == 0) {
+            mServerStatusView.setVisibility(View.INVISIBLE);
+        } else {
+            mServerStatusView.setText(mServerStatusText);
+            mServerStatusView.setCompoundDrawablesWithIntrinsicBounds(mServerStatusIcon, 0, 0, 0);
+            mServerStatusView.setVisibility(View.VISIBLE);
         }
     }
 
@@ -1874,15 +1969,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
      * to the interactions with the OAuth authorization server.
      */
     private void showAuthStatus() {
-        if (!webViewLoginMethod) {
-            if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
-                mAuthStatusView.setVisibility(View.INVISIBLE);
-
-            } else {
-                mAuthStatusView.setText(mAuthStatusText);
-                mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
-                mAuthStatusView.setVisibility(View.VISIBLE);
-            }
+        if (mAuthStatusIcon == 0 && mAuthStatusText == 0) {
+            mAuthStatusView.setVisibility(View.INVISIBLE);
+        } else {
+            mAuthStatusView.setText(mAuthStatusText);
+            mAuthStatusView.setCompoundDrawablesWithIntrinsicBounds(mAuthStatusIcon, 0, 0, 0);
+            mAuthStatusView.setVisibility(View.VISIBLE);
         }
     }
 
@@ -2154,7 +2246,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     /**
      * Create and show dialog for request authentication to the user
      *
-     * @param webView Web view to emebd into the authentication dialog.
+     * @param webView Web view to embed into the authentication dialog.
      * @param handler Object responsible for catching and recovering HTTP authentication fails.
      */
     public void createAuthenticationDialog(WebView webView, HttpAuthHandler handler) {

+ 0 - 35
src/main/res/drawable/action_item_btn.xml

@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:dither="true">
-
-    <item 
-    	android:state_window_focused="false"
-        android:drawable="@android:color/transparent" />
-    <item 
-    	android:state_pressed="true"
-        android:drawable="@drawable/action_item_selected"/>
-    <item 
-    	android:state_focused="true"
-        android:drawable="@drawable/action_item_selected"/>
-    <item
-        android:drawable="@android:color/transparent"/>
-        
-</selector>

BIN
src/main/res/drawable/action_item_selected.9.png


BIN
src/main/res/drawable/arrow_down.png


BIN
src/main/res/drawable/arrow_up.png


+ 0 - 26
src/main/res/drawable/btn.xml

@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
-  <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/btn_round_pressed" />
-  <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
-  <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_round_pressed" />
-  <item android:drawable="@drawable/btn_round"/>
-</selector>

BIN
src/main/res/drawable/btn_cancel.png


+ 0 - 26
src/main/res/drawable/btn_round.xml

@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> 
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" 
-        android:shape="rectangle"> 
-        <corners android:radius="5dip" />
-        <solid android:color="#aac4d2" /> 
-        <padding android:left="15dp" android:top="5dp" android:right="15dp" android:bottom="5dp" />
-        <stroke android:width="2dip" android:color="#ffffff" />
-</shape>

+ 0 - 26
src/main/res/drawable/btn_round_pressed.xml

@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?> 
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android" 
-        android:shape="rectangle"> 
-        <corners android:radius="5dip" />
-        <solid android:color="#aac4d2" /> 
-        <padding android:left="15dp" android:top="5dp" android:right="15dp" android:bottom="5dp" />
-        <stroke android:width="5dip" android:color="#ff8000" /> 
-</shape>

+ 0 - 46
src/main/res/drawable/btn_small_round.xml

@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <!-- pressed state of button, only change: color of actual button -->
-    <item android:state_pressed="true" >
-        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-            <!-- shadow, a little down and a little to the right -->
-            <item><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#99000000" android:startColor="#99000000" />
-                </shape></item>
-            <!-- this is the actual button -->
-            <item android:bottom="1px" android:right="1px"><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#47ffffff" android:startColor="#97ffffff" />
-                </shape></item>
-        </layer-list>
-    </item>
- 
-    <!-- focused state of button, only change: color of actual button -->
-    <item android:state_focused="true" >
-        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-            <!-- shadow, a little down and a little to the right -->
-            <item><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#22000000" android:startColor="#22000000" />
-                </shape></item>
-            <!-- this is the actual button -->
-            <item android:bottom="1px" android:right="1px"><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#47ffffff" android:startColor="#97ffffff" />
-                </shape></item>
-        </layer-list>
-    </item>

   <!-- normal state of button. Template for other states. -->
-    <item>
-        <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-            <!-- shadow, a little down and a little to the right -->
-            <item>
-                <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#55000000" android:startColor="#55000000" />
-                </shape></item>
-            <!-- this is the actual button -->
-            <item android:bottom="1px" android:right="1px">
-                <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
-                    <gradient android:angle="270" android:endColor="#47ffffff" android:startColor="#97ffffff" />
-                </shape>
-            </item>
-        </layer-list>
-    </item>
-</selector>

+ 31 - 13
src/main/res/layout-land/account_setup.xml

@@ -108,6 +108,21 @@
 
                     </android.support.design.widget.TextInputLayout>
 
+					<ImageButton
+						android:id="@+id/testServerButton"
+						android:layout_width="wrap_content"
+						android:layout_height="wrap_content"
+						android:layout_gravity="center_vertical|right"
+						android:layout_marginRight="@dimen/alternate_half_padding"
+						android:padding="@dimen/zero"
+						android:scaleType="fitCenter"
+						android:src="@drawable/arrow_right"
+						android:tint="@color/white"
+						android:background="@android:color/transparent"
+						android:onClick="onTestServerConnectionClick"
+						android:contentDescription="@string/test_server_button"
+						/>
+
 					<ImageButton
 					    android:id="@+id/embeddedRefreshButton"
 					    android:layout_width="wrap_content"
@@ -191,9 +206,10 @@
                 </android.support.design.widget.TextInputLayout>
 
                 <android.support.design.widget.TextInputLayout
-                    android:id="@+id/input_layout_account_username"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content">
+					android:id="@+id/input_layout_account_username"
+					android:layout_width="match_parent"
+					android:layout_height="wrap_content"
+					android:visibility="gone">
 
 				<EditText
 					android:id="@+id/account_username"
@@ -209,9 +225,10 @@
                 </android.support.design.widget.TextInputLayout>
 
                 <android.support.design.widget.TextInputLayout
-                    android:id="@+id/input_layout_account_password"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content">
+					android:id="@+id/input_layout_account_password"
+					android:layout_width="match_parent"
+					android:layout_height="wrap_content"
+					android:visibility="gone">
 
                     <EditText
                         android:id="@+id/account_password"
@@ -252,16 +269,17 @@
         android:paddingTop="@dimen/standard_half_padding">
         
 		<android.support.v7.widget.AppCompatButton
-		    android:id="@+id/buttonOK"
+			android:id="@+id/buttonOK"
 			android:theme="@style/Button.Login"
 			style="@style/Button.Login"
-		    android:layout_width="wrap_content"
-		    android:layout_height="wrap_content"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
 			android:padding="@dimen/standard_padding"
-		    android:layout_gravity="center_horizontal"
-		    android:enabled="false"
-		    android:text="@string/setup_btn_connect"
-            android:contentDescription="@string/setup_btn_connect"/>
+			android:layout_gravity="center_horizontal"
+			android:enabled="false"
+			android:text="@string/setup_btn_connect"
+			android:contentDescription="@string/setup_btn_connect"
+			android:visibility="gone"/>
 
 		<LinearLayout
 			android:layout_width="match_parent"

+ 21 - 3
src/main/res/layout/account_setup.xml

@@ -100,6 +100,21 @@
 
             </android.support.design.widget.TextInputLayout>
 
+            <ImageButton
+                android:id="@+id/testServerButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical|right"
+                android:layout_marginRight="@dimen/alternate_half_padding"
+                android:padding="@dimen/zero"
+                android:scaleType="fitCenter"
+                android:src="@drawable/arrow_right"
+                android:tint="@color/white"
+                android:background="@android:color/transparent"
+                android:onClick="onTestServerConnectionClick"
+                android:contentDescription="@string/test_server_button"
+                />
+
             <ImageButton
 			    android:id="@+id/embeddedRefreshButton"
 			    android:layout_width="wrap_content"
@@ -183,7 +198,8 @@
         <android.support.design.widget.TextInputLayout
             android:id="@+id/input_layout_account_username"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:visibility="gone">
 
             <EditText
                 android:id="@+id/account_username"
@@ -201,7 +217,8 @@
         <android.support.design.widget.TextInputLayout
             android:id="@+id/input_layout_account_password"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:visibility="gone">
 
             <EditText
                 android:id="@+id/account_password"
@@ -239,7 +256,8 @@
             android:padding="@dimen/standard_padding"
             android:enabled="false"
             android:text="@string/setup_btn_connect"
-            android:contentDescription="@string/setup_btn_connect"/>
+            android:contentDescription="@string/setup_btn_connect"
+            android:visibility="gone"/>
 
         <LinearLayout
             android:layout_width="match_parent"

+ 13 - 5
src/main/res/layout/account_setup_webview.xml

@@ -1,12 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent">
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:orientation="vertical"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent">
 
     <WebView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/login_webview">
     </WebView>
-</LinearLayout>
+
+    <ProgressBar
+        android:id="@+id/login_webview_progress_bar"
+        style="?android:attr/progressBarStyle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:indeterminate="true"/>
+</FrameLayout>

+ 0 - 44
src/main/res/layout/action_item.xml

@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:orientation="horizontal"
-	android:layout_width="fill_parent"
-	android:layout_height="wrap_content" 
-	android:clickable="true"
-	android:focusable="true"
-	android:background="@drawable/action_item_btn">
-        	
-	<ImageView
-		android:id="@+id/icon" 
-		android:layout_width="wrap_content" 
-		android:layout_height="wrap_content"/>
-
-	<TextView 
-		android:id="@+id/title"
-		android:layout_width="fill_parent" 
-		android:layout_height="fill_parent" 
-		android:gravity="center_vertical"
-		android:paddingLeft="@dimen/alternate_half_padding_independent"
-		android:paddingRight="@dimen/alternate_padding_independent"
-		android:text="Chart"
-		android:textColor="#fff"/>
-									         
-</LinearLayout>         

+ 0 - 58
src/main/res/layout/popup.xml

@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ownCloud Android client application
-
-  Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License version 2,
-  as published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<RelativeLayout 
-  xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    >
-      
-  <ScrollView 
-    android:id="@+id/scroller"
-    android:layout_marginTop="@dimen/standard_margin_independent"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:background="@drawable/popup"
-      android:fadingEdgeLength="@dimen/alternate_half_padding_independent"
-      android:scrollbars="none">
-        
-      <LinearLayout
-        android:id="@+id/tracks"
-        android:orientation="vertical"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:layout_weight="1"
-          android:padding="@dimen/alternate_padding_independent"/>
-       
-  </ScrollView >
-  
-  <ImageView
-        android:id="@+id/arrow_up"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/arrow_up" />
-        
-  <ImageView
-        android:id="@+id/arrow_down"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/standard_quarter_margin_negative_independent"
-        android:src="@drawable/arrow_down" android:layout_below="@+id/scroller"/>
-
-</RelativeLayout>

+ 1 - 0
src/main/res/values/strings.xml

@@ -669,4 +669,5 @@
     <string name="folder_sync_folders">Configure folders</string>
 
   <string name="empty" translatable="false"/>
+    <string name="test_server_button">Test server connection</string>
 </resources>