1.1 --- a/src/org/gege/caldavsyncadapter/authenticator/AuthenticatorActivity.java Tue Feb 10 21:55:00 2015 +0100 1.2 +++ b/src/org/gege/caldavsyncadapter/authenticator/AuthenticatorActivity.java Tue Feb 10 22:40:00 2015 +0100 1.3 @@ -1,6 +1,6 @@ 1.4 /** 1.5 * Copyright (c) 2012-2013, Gerald Garcia 1.6 - * 1.7 + * 1.8 * This file is part of Andoid Caldav Sync Adapter Free. 1.9 * 1.10 * Andoid Caldav Sync Adapter Free is free software: you can redistribute 1.11 @@ -16,24 +16,11 @@ 1.12 * You should have received a copy of the GNU General Public License 1.13 * along with Andoid Caldav Sync Adapter Free. 1.14 * If not, see <http://www.gnu.org/licenses/>. 1.15 - * 1.16 + * 1.17 */ 1.18 1.19 package org.gege.caldavsyncadapter.authenticator; 1.20 1.21 -import java.io.IOException; 1.22 -import java.io.UnsupportedEncodingException; 1.23 -import java.net.MalformedURLException; 1.24 -import java.net.URISyntaxException; 1.25 - 1.26 -import javax.xml.parsers.ParserConfigurationException; 1.27 - 1.28 -import org.apache.http.conn.HttpHostConnectException; 1.29 -import org.gege.caldavsyncadapter.R; 1.30 -import org.gege.caldavsyncadapter.caldav.CaldavFacade; 1.31 -import org.gege.caldavsyncadapter.caldav.CaldavFacade.TestConnectionResult; 1.32 -import org.xml.sax.SAXException; 1.33 - 1.34 import android.accounts.Account; 1.35 import android.accounts.AccountManager; 1.36 import android.animation.Animator; 1.37 @@ -45,430 +32,480 @@ 1.38 import android.os.AsyncTask; 1.39 import android.os.Build; 1.40 import android.os.Bundle; 1.41 +import android.text.Editable; 1.42 import android.text.TextUtils; 1.43 +import android.text.TextWatcher; 1.44 import android.util.Log; 1.45 import android.view.KeyEvent; 1.46 import android.view.Menu; 1.47 import android.view.View; 1.48 import android.view.inputmethod.EditorInfo; 1.49 +import android.widget.CheckBox; 1.50 import android.widget.EditText; 1.51 import android.widget.TextView; 1.52 import android.widget.Toast; 1.53 1.54 +import org.apache.http.conn.HttpHostConnectException; 1.55 +import org.gege.caldavsyncadapter.Constants; 1.56 +import org.gege.caldavsyncadapter.R; 1.57 +import org.gege.caldavsyncadapter.caldav.CaldavFacade; 1.58 +import org.gege.caldavsyncadapter.caldav.CaldavFacade.TestConnectionResult; 1.59 +import org.xml.sax.SAXException; 1.60 + 1.61 +import java.io.IOException; 1.62 +import java.io.UnsupportedEncodingException; 1.63 +import java.net.MalformedURLException; 1.64 +import java.net.URISyntaxException; 1.65 +import java.util.Locale; 1.66 + 1.67 +import javax.xml.parsers.ParserConfigurationException; 1.68 + 1.69 /** 1.70 * Activity which displays a login screen to the user, offering registration as 1.71 * well. 1.72 */ 1.73 public class AuthenticatorActivity extends Activity { 1.74 - 1.75 - private static final String TAG = "AuthenticatorActivity"; 1.76 1.77 - private static final String ACCOUNT_TYPE = "org.gege.caldavsyncadapter.account"; 1.78 + private static final String TAG = "AuthenticatorActivity"; 1.79 1.80 - public static final String USER_DATA_URL_KEY = "USER_DATA_URL_KEY"; 1.81 - public static final String USER_DATA_USERNAME = "USER_DATA_USERNAME"; 1.82 - public static final String USER_DATA_VERSION = "USER_DATA_VERSION"; 1.83 - public static final String CURRENT_USER_DATA_VERSION = "1"; 1.84 - 1.85 - public static final String ACCOUNT_NAME_SPLITTER = "@"; 1.86 - 1.87 - /** 1.88 - * The default email to populate the email field with. 1.89 - */ 1.90 - public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL"; 1.91 + private static final String ACCOUNT_TYPE = "org.gege.caldavsyncadapter.account"; 1.92 1.93 - /** 1.94 - * Keep track of the login task to ensure we can cancel it if requested. 1.95 - */ 1.96 - private UserLoginTask mAuthTask = null; 1.97 + public static final String USER_DATA_URL_KEY = "USER_DATA_URL_KEY"; 1.98 + public static final String USER_DATA_USERNAME = "USER_DATA_USERNAME"; 1.99 + public static final String USER_DATA_VERSION = "USER_DATA_VERSION"; 1.100 + public static final String CURRENT_USER_DATA_VERSION = "1"; 1.101 1.102 - // Values for email and password at the time of the login attempt. 1.103 - private String mUser; 1.104 - private String mPassword; 1.105 - private Context mContext; 1.106 + public static final String ACCOUNT_NAME_SPLITTER = "@"; 1.107 1.108 - // UI references. 1.109 - private EditText mUserView; 1.110 - private EditText mPasswordView; 1.111 - private View mLoginFormView; 1.112 - private View mLoginStatusView; 1.113 - private TextView mLoginStatusMessageView; 1.114 + /** 1.115 + * The default email to populate the email field with. 1.116 + */ 1.117 + public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL"; 1.118 1.119 - private AccountManager mAccountManager; 1.120 + /** 1.121 + * Keep track of the login task to ensure we can cancel it if requested. 1.122 + */ 1.123 + private UserLoginTask mAuthTask = null; 1.124 1.125 - private String mURL; 1.126 - private EditText mURLView; 1.127 - 1.128 - private String mAccountname; 1.129 - private EditText mAccountnameView; 1.130 - 1.131 - public AuthenticatorActivity() { 1.132 - super(); 1.133 - 1.134 - } 1.135 - 1.136 - @Override 1.137 - protected void onCreate(Bundle savedInstanceState) { 1.138 - super.onCreate(savedInstanceState); 1.139 - 1.140 - mAccountManager = AccountManager.get(this); 1.141 + // Values for email and password at the time of the login attempt. 1.142 + private String mUser; 1.143 + private String mPassword; 1.144 + private String mTrustAll; 1.145 + private Context mContext; 1.146 1.147 - setContentView(R.layout.activity_authenticator); 1.148 + // UI references. 1.149 + private EditText mUserView; 1.150 + private EditText mPasswordView; 1.151 + private View mLoginFormView; 1.152 + private View mLoginStatusView; 1.153 + private TextView mLoginStatusMessageView; 1.154 + private CheckBox mTrustCheckBox; 1.155 1.156 - // Set up the login form. 1.157 - mUser = getIntent().getStringExtra(EXTRA_EMAIL); 1.158 - mUserView = (EditText) findViewById(R.id.user); 1.159 - mUserView.setText(mUser); 1.160 - 1.161 - mContext = getBaseContext(); 1.162 + private AccountManager mAccountManager; 1.163 1.164 - mPasswordView = (EditText) findViewById(R.id.password); 1.165 - mPasswordView 1.166 - .setOnEditorActionListener(new TextView.OnEditorActionListener() { 1.167 - @Override 1.168 - public boolean onEditorAction(TextView textView, int id, 1.169 - KeyEvent keyEvent) { 1.170 - if (id == R.id.login || id == EditorInfo.IME_NULL) { 1.171 - attemptLogin(); 1.172 - return true; 1.173 - } 1.174 - return false; 1.175 - } 1.176 - }); 1.177 + private String mURL; 1.178 + private EditText mURLView; 1.179 1.180 - 1.181 - mURLView = (EditText) findViewById(R.id.url); 1.182 - 1.183 - mAccountnameView = (EditText) findViewById(R.id.accountname); 1.184 - 1.185 - mLoginFormView = findViewById(R.id.login_form); 1.186 - mLoginStatusView = findViewById(R.id.login_status); 1.187 - mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message); 1.188 + private String mAccountname; 1.189 + private EditText mAccountnameView; 1.190 1.191 - findViewById(R.id.sign_in_button).setOnClickListener( 1.192 - new View.OnClickListener() { 1.193 - @Override 1.194 - public void onClick(View view) { 1.195 - attemptLogin(); 1.196 - } 1.197 - }); 1.198 - 1.199 - 1.200 - } 1.201 + public AuthenticatorActivity() { 1.202 + super(); 1.203 1.204 - @Override 1.205 - public boolean onCreateOptionsMenu(Menu menu) { 1.206 - super.onCreateOptionsMenu(menu); 1.207 - getMenuInflater().inflate(R.menu.activity_authenticator, menu); 1.208 - return true; 1.209 - } 1.210 + } 1.211 1.212 - /** 1.213 - * Attempts to sign in or register the account specified by the login form. 1.214 - * If there are form errors (invalid email, missing fields, etc.), the 1.215 - * errors are presented and no actual login attempt is made. 1.216 - */ 1.217 - public void attemptLogin() { 1.218 - if (mAuthTask != null) { 1.219 - return; 1.220 - } 1.221 + @Override 1.222 + protected void onCreate(Bundle savedInstanceState) { 1.223 + super.onCreate(savedInstanceState); 1.224 1.225 - // Reset errors. 1.226 - mUserView.setError(null); 1.227 - mPasswordView.setError(null); 1.228 + mAccountManager = AccountManager.get(this); 1.229 1.230 - // Store values at the time of the login attempt. 1.231 - mUser = mUserView.getText().toString(); 1.232 - mPassword = mPasswordView.getText().toString(); 1.233 - mURL = mURLView.getText().toString(); 1.234 - mAccountname = mAccountnameView.getText().toString(); 1.235 + setContentView(R.layout.activity_authenticator); 1.236 1.237 - boolean cancel = false; 1.238 - View focusView = null; 1.239 - 1.240 - if (!mAccountname.equals("")) { 1.241 - Account TestAccount = new Account(mAccountname, ACCOUNT_TYPE); 1.242 - String TestUrl = mAccountManager.getUserData(TestAccount, AuthenticatorActivity.USER_DATA_URL_KEY); 1.243 - if (TestUrl != null) { 1.244 - mAccountnameView.setError(getString(R.string.error_account_already_in_use)); 1.245 - focusView = mAccountnameView; 1.246 - cancel = true; 1.247 - } 1.248 - } 1.249 + // Set up the login form. 1.250 + mUser = getIntent().getStringExtra(EXTRA_EMAIL); 1.251 + mUserView = (EditText) findViewById(R.id.user); 1.252 + mUserView.setText(mUser); 1.253 1.254 - // Check for a valid password. 1.255 - if (TextUtils.isEmpty(mPassword)) { 1.256 - mPasswordView.setError(getString(R.string.error_field_required)); 1.257 - focusView = mPasswordView; 1.258 - cancel = true; 1.259 - } else if (mPassword.length() < 4) { 1.260 - mPasswordView.setError(getString(R.string.error_invalid_password)); 1.261 - focusView = mPasswordView; 1.262 - cancel = true; 1.263 - } 1.264 + mContext = getBaseContext(); 1.265 1.266 - // Check for a valid email address. 1.267 - if (TextUtils.isEmpty(mUser)) { 1.268 - mUserView.setError(getString(R.string.error_field_required)); 1.269 - focusView = mUserView; 1.270 - cancel = true; 1.271 - } 1.272 - //else if (!mUser.contains("@")) { 1.273 - // mUserView.setError(getString(R.string.error_invalid_email)); 1.274 - // focusView = mUserView; 1.275 - // cancel = true; 1.276 - //} 1.277 + mPasswordView = (EditText) findViewById(R.id.password); 1.278 + mPasswordView 1.279 + .setOnEditorActionListener(new TextView.OnEditorActionListener() { 1.280 + @Override 1.281 + public boolean onEditorAction(TextView textView, int id, 1.282 + KeyEvent keyEvent) { 1.283 + if (id == R.id.login || id == EditorInfo.IME_NULL) { 1.284 + attemptLogin(); 1.285 + return true; 1.286 + } 1.287 + return false; 1.288 + } 1.289 + }); 1.290 1.291 - if (cancel) { 1.292 - // There was an error; don't attempt login and focus the first 1.293 - // form field with an error. 1.294 - focusView.requestFocus(); 1.295 - } else { 1.296 - // Show a progress spinner, and kick off a background task to 1.297 - // perform the user login attempt. 1.298 - mLoginStatusMessageView.setText(R.string.login_progress_signing_in); 1.299 - showProgress(true); 1.300 - mAuthTask = new UserLoginTask(); 1.301 - mAuthTask.execute((Void) null); 1.302 - } 1.303 - } 1.304 1.305 - /** 1.306 - * Shows the progress UI and hides the login form. 1.307 - */ 1.308 - @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 1.309 - private void showProgress(final boolean show) { 1.310 - // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 1.311 - // for very easy animations. If available, use these APIs to fade-in 1.312 - // the progress spinner. 1.313 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 1.314 - int shortAnimTime = getResources().getInteger( 1.315 - android.R.integer.config_shortAnimTime); 1.316 + mURLView = (EditText) findViewById(R.id.url); 1.317 + // if the URL start with "https" show the option to disable SSL host verification 1.318 + mURLView.addTextChangedListener(new TextWatcher() { 1.319 + @Override 1.320 + public void onTextChanged(CharSequence s, int start, int before, int count) { 1.321 + String url = ((EditText) findViewById(R.id.url)).getText().toString(); 1.322 + int visible = url.toLowerCase(Locale.getDefault()) 1.323 + .startsWith("https") ? View.VISIBLE : View.GONE; 1.324 + ((CheckBox) findViewById(R.id.trustall)).setVisibility(visible); 1.325 + } 1.326 1.327 - mLoginStatusView.setVisibility(View.VISIBLE); 1.328 - mLoginStatusView.animate().setDuration(shortAnimTime) 1.329 - .alpha(show ? 1 : 0) 1.330 - .setListener(new AnimatorListenerAdapter() { 1.331 - @Override 1.332 - public void onAnimationEnd(Animator animation) { 1.333 - mLoginStatusView.setVisibility(show ? View.VISIBLE 1.334 - : View.GONE); 1.335 - } 1.336 - }); 1.337 + @Override 1.338 + public void beforeTextChanged(CharSequence s, int start, int count, 1.339 + int after) { 1.340 + } 1.341 1.342 - mLoginFormView.setVisibility(View.VISIBLE); 1.343 - mLoginFormView.animate().setDuration(shortAnimTime) 1.344 - .alpha(show ? 0 : 1) 1.345 - .setListener(new AnimatorListenerAdapter() { 1.346 - @Override 1.347 - public void onAnimationEnd(Animator animation) { 1.348 - mLoginFormView.setVisibility(show ? View.GONE 1.349 - : View.VISIBLE); 1.350 - } 1.351 - }); 1.352 - } else { 1.353 - // The ViewPropertyAnimator APIs are not available, so simply show 1.354 - // and hide the relevant UI components. 1.355 - mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); 1.356 - mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 1.357 - } 1.358 - } 1.359 + @Override 1.360 + public void afterTextChanged(Editable s) { 1.361 + } 1.362 + }); 1.363 1.364 - 1.365 - protected enum LoginResult { 1.366 - MalformedURLException, 1.367 - GeneralSecurityException, 1.368 - UnkonwnException, 1.369 - WrongCredentials, 1.370 - InvalidResponse, 1.371 - WrongUrl, 1.372 - ConnectionRefused, 1.373 - Success_Calendar, 1.374 - Success_Collection, 1.375 - Account_Already_In_Use 1.376 - } 1.377 - 1.378 - 1.379 - /** 1.380 - * Represents an asynchronous login/registration task used to authenticate 1.381 - * the user. 1.382 - */ 1.383 - public class UserLoginTask extends AsyncTask<Void, Void, LoginResult> { 1.384 + mAccountnameView = (EditText) findViewById(R.id.accountname); 1.385 1.386 - @Override 1.387 - protected LoginResult doInBackground(Void... params) { 1.388 + mLoginFormView = findViewById(R.id.login_form); 1.389 + mLoginStatusView = findViewById(R.id.login_status); 1.390 + mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message); 1.391 1.392 - TestConnectionResult result = null; 1.393 - 1.394 - try { 1.395 - CaldavFacade facade = new CaldavFacade(mUser, mPassword, mURL); 1.396 - String version = ""; 1.397 - try { 1.398 - version = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName; 1.399 - } catch (NameNotFoundException e) { 1.400 - version = "unknown"; 1.401 - e.printStackTrace(); 1.402 - } 1.403 - facade.setVersion(version); 1.404 - result = facade.testConnection(); 1.405 - Log.i(TAG, "testConnection status="+result); 1.406 - } catch (HttpHostConnectException e) { 1.407 - Log.w(TAG,"testConnection", e); 1.408 - return LoginResult.ConnectionRefused; 1.409 - } catch (MalformedURLException e) { 1.410 - Log.w(TAG,"testConnection", e); 1.411 - return LoginResult.MalformedURLException; 1.412 - } catch (UnsupportedEncodingException e) { 1.413 - Log.w(TAG,"testConnection", e); 1.414 - return LoginResult.UnkonwnException; 1.415 - } catch (ParserConfigurationException e) { 1.416 - Log.w(TAG,"testConnection", e); 1.417 - return LoginResult.UnkonwnException; 1.418 - } catch (SAXException e) { 1.419 - Log.w(TAG,"testConnection", e); 1.420 - return LoginResult.InvalidResponse; 1.421 - } catch (IOException e) { 1.422 - Log.w(TAG,"testConnection", e); 1.423 - return LoginResult.UnkonwnException; 1.424 - } catch (URISyntaxException e) { 1.425 - Log.w(TAG,"testConnection", e); 1.426 - return LoginResult.MalformedURLException; 1.427 - } 1.428 + findViewById(R.id.sign_in_button).setOnClickListener( 1.429 + new View.OnClickListener() { 1.430 + @Override 1.431 + public void onClick(View view) { 1.432 + attemptLogin(); 1.433 + } 1.434 + } 1.435 + ); 1.436 1.437 - if (result == null) { 1.438 - return LoginResult.UnkonwnException; 1.439 - } 1.440 - 1.441 - switch (result) { 1.442 - 1.443 - case SUCCESS: 1.444 - boolean OldAccount = false; 1.445 - LoginResult Result = LoginResult.Success_Calendar; 1.446 + mTrustCheckBox = (CheckBox) findViewById(R.id.trustall); 1.447 1.448 - if (OldAccount) { 1.449 - final Account account = new Account(mUser, ACCOUNT_TYPE); 1.450 - if (mAccountManager.addAccountExplicitly(account, mPassword, null)) { 1.451 - Log.v(TAG,"new account created"); 1.452 - mAccountManager.setUserData(account, USER_DATA_URL_KEY, mURL); 1.453 - } else { 1.454 - Log.v(TAG,"no new account created"); 1.455 - Result = LoginResult.Account_Already_In_Use; 1.456 - } 1.457 - } else { 1.458 - final Account account; 1.459 - if (mAccountname.equals("")) { 1.460 - account = new Account(mUser + ACCOUNT_NAME_SPLITTER + mURL, ACCOUNT_TYPE); 1.461 - } else { 1.462 - account = new Account(mAccountname, ACCOUNT_TYPE); 1.463 - } 1.464 - if (mAccountManager.addAccountExplicitly(account, mPassword, null)) { 1.465 - Log.v(TAG,"new account created"); 1.466 - mAccountManager.setUserData(account, USER_DATA_URL_KEY, mURL); 1.467 - mAccountManager.setUserData(account, USER_DATA_USERNAME, mUser); 1.468 - mAccountManager.setUserData(account, USER_DATA_VERSION, CURRENT_USER_DATA_VERSION); 1.469 - } else { 1.470 - Log.v(TAG,"no new account created"); 1.471 - Result = LoginResult.Account_Already_In_Use; 1.472 - } 1.473 - } 1.474 - 1.475 - return Result; 1.476 1.477 - case WRONG_CREDENTIAL: 1.478 - return LoginResult.WrongCredentials; 1.479 - 1.480 - case WRONG_SERVER_STATUS: 1.481 - return LoginResult.InvalidResponse; 1.482 - 1.483 - case WRONG_URL: 1.484 - return LoginResult.WrongUrl; 1.485 - 1.486 - case WRONG_ANSWER: 1.487 - return LoginResult.InvalidResponse; 1.488 - 1.489 - default: 1.490 - return LoginResult.UnkonwnException; 1.491 - 1.492 - } 1.493 - 1.494 - } 1.495 - 1.496 + } 1.497 1.498 - @Override 1.499 - protected void onPostExecute(final LoginResult result) { 1.500 - mAuthTask = null; 1.501 - showProgress(false); 1.502 + @Override 1.503 + public boolean onCreateOptionsMenu(Menu menu) { 1.504 + super.onCreateOptionsMenu(menu); 1.505 + return true; 1.506 + } 1.507 1.508 - int duration = Toast.LENGTH_SHORT; 1.509 - Toast toast = null; 1.510 - 1.511 - switch (result) { 1.512 - case Success_Calendar: 1.513 - toast = Toast.makeText(getApplicationContext(), R.string.success_calendar, duration); 1.514 - toast.show(); 1.515 - finish(); 1.516 - break; 1.517 - 1.518 - case Success_Collection: 1.519 - toast = Toast.makeText(getApplicationContext(), R.string.success_collection, duration); 1.520 - toast.show(); 1.521 - finish(); 1.522 - break; 1.523 - 1.524 - case MalformedURLException: 1.525 - 1.526 - toast = Toast.makeText(getApplicationContext(), R.string.error_incorrect_url_format, duration); 1.527 - toast.show(); 1.528 - mURLView.setError(getString(R.string.error_incorrect_url_format)); 1.529 - mURLView.requestFocus(); 1.530 - break; 1.531 - case InvalidResponse: 1.532 - toast = Toast.makeText(getApplicationContext(), R.string.error_invalid_server_answer, duration); 1.533 - toast.show(); 1.534 - mURLView.setError(getString(R.string.error_invalid_server_answer)); 1.535 - mURLView.requestFocus(); 1.536 - break; 1.537 - case WrongUrl: 1.538 - toast = Toast.makeText(getApplicationContext(), R.string.error_wrong_url, duration); 1.539 - toast.show(); 1.540 - mURLView.setError(getString(R.string.error_wrong_url)); 1.541 - mURLView.requestFocus(); 1.542 - break; 1.543 - 1.544 - case WrongCredentials: 1.545 - mPasswordView.setError(getString(R.string.error_incorrect_password)); 1.546 - mPasswordView.requestFocus(); 1.547 - break; 1.548 - 1.549 - case ConnectionRefused: 1.550 - toast = Toast.makeText(getApplicationContext(), R.string.error_connection_refused, duration); 1.551 - toast.show(); 1.552 - mURLView.setError(getString(R.string.error_connection_refused)); 1.553 - mURLView.requestFocus(); 1.554 - break; 1.555 - case Account_Already_In_Use: 1.556 - toast = Toast.makeText(getApplicationContext(), R.string.error_account_already_in_use, duration); 1.557 - toast.show(); 1.558 - mURLView.setError(getString(R.string.error_account_already_in_use)); 1.559 - mURLView.requestFocus(); 1.560 - break; 1.561 - default: 1.562 - toast = Toast.makeText(getApplicationContext(), R.string.error_unkown_error, duration); 1.563 - toast.show(); 1.564 - mURLView.setError(getString(R.string.error_unkown_error)); 1.565 - mURLView.requestFocus(); 1.566 - break; 1.567 - } 1.568 - 1.569 - 1.570 - 1.571 - 1.572 - } 1.573 + /** 1.574 + * Attempts to sign in or register the account specified by the login form. 1.575 + * If there are form errors (invalid email, missing fields, etc.), the 1.576 + * errors are presented and no actual login attempt is made. 1.577 + */ 1.578 + public void attemptLogin() { 1.579 + if (mAuthTask != null) { 1.580 + return; 1.581 + } 1.582 1.583 - @Override 1.584 - protected void onCancelled() { 1.585 - mAuthTask = null; 1.586 - showProgress(false); 1.587 - } 1.588 - } 1.589 -} 1.590 + // Reset errors. 1.591 + mUserView.setError(null); 1.592 + mPasswordView.setError(null); 1.593 + 1.594 + // Store values at the time of the login attempt. 1.595 + mUser = mUserView.getText().toString(); 1.596 + mPassword = mPasswordView.getText().toString(); 1.597 + mURL = mURLView.getText().toString(); 1.598 + mAccountname = mAccountnameView.getText().toString(); 1.599 + mTrustAll = (mTrustCheckBox.isChecked() ? "false" : "true"); 1.600 + boolean cancel = false; 1.601 + View focusView = null; 1.602 + 1.603 + if (!mAccountname.equals("")) { 1.604 + Account TestAccount = new Account(mAccountname, ACCOUNT_TYPE); 1.605 + String TestUrl = mAccountManager.getUserData(TestAccount, AuthenticatorActivity.USER_DATA_URL_KEY); 1.606 + if (TestUrl != null) { 1.607 + mAccountnameView.setError(getString(R.string.error_account_already_in_use)); 1.608 + focusView = mAccountnameView; 1.609 + cancel = true; 1.610 + } 1.611 + } 1.612 + 1.613 + // Check for a valid password. 1.614 + if (TextUtils.isEmpty(mPassword)) { 1.615 + mPasswordView.setError(getString(R.string.error_field_required)); 1.616 + focusView = mPasswordView; 1.617 + cancel = true; 1.618 + } 1.619 + 1.620 + // Check for a valid email address. 1.621 + if (TextUtils.isEmpty(mUser)) { 1.622 + mUserView.setError(getString(R.string.error_field_required)); 1.623 + focusView = mUserView; 1.624 + cancel = true; 1.625 + } 1.626 + //else if (!mUser.contains("@")) { 1.627 + // mUserView.setError(getString(R.string.error_invalid_email)); 1.628 + // focusView = mUserView; 1.629 + // cancel = true; 1.630 + //} 1.631 + 1.632 + if (cancel) { 1.633 + // There was an error; don't attempt login and focus the first 1.634 + // form field with an error. 1.635 + focusView.requestFocus(); 1.636 + } else { 1.637 + // Show a progress spinner, and kick off a background task to 1.638 + // perform the user login attempt. 1.639 + mLoginStatusMessageView.setText(R.string.login_progress_signing_in); 1.640 + showProgress(true); 1.641 + mAuthTask = new UserLoginTask(); 1.642 + mAuthTask.execute((Void) null); 1.643 + } 1.644 + } 1.645 + 1.646 + /** 1.647 + * Shows the progress UI and hides the login form. 1.648 + */ 1.649 + @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 1.650 + private void showProgress(final boolean show) { 1.651 + // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 1.652 + // for very easy animations. If available, use these APIs to fade-in 1.653 + // the progress spinner. 1.654 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 1.655 + int shortAnimTime = getResources().getInteger( 1.656 + android.R.integer.config_shortAnimTime); 1.657 + 1.658 + mLoginStatusView.setVisibility(View.VISIBLE); 1.659 + mLoginStatusView.animate().setDuration(shortAnimTime) 1.660 + .alpha(show ? 1 : 0) 1.661 + .setListener(new AnimatorListenerAdapter() { 1.662 + @Override 1.663 + public void onAnimationEnd(Animator animation) { 1.664 + mLoginStatusView.setVisibility(show ? View.VISIBLE 1.665 + : View.GONE); 1.666 + } 1.667 + }); 1.668 + 1.669 + mLoginFormView.setVisibility(View.VISIBLE); 1.670 + mLoginFormView.animate().setDuration(shortAnimTime) 1.671 + .alpha(show ? 0 : 1) 1.672 + .setListener(new AnimatorListenerAdapter() { 1.673 + @Override 1.674 + public void onAnimationEnd(Animator animation) { 1.675 + mLoginFormView.setVisibility(show ? View.GONE 1.676 + : View.VISIBLE); 1.677 + } 1.678 + }); 1.679 + } else { 1.680 + // The ViewPropertyAnimator APIs are not available, so simply show 1.681 + // and hide the relevant UI components. 1.682 + mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE); 1.683 + mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 1.684 + } 1.685 + } 1.686 + 1.687 + 1.688 + protected enum LoginResult { 1.689 + MalformedURLException, 1.690 + GeneralSecurityException, 1.691 + UnkonwnException, 1.692 + WrongCredentials, 1.693 + InvalidResponse, 1.694 + WrongUrl, 1.695 + ConnectionRefused, 1.696 + Success_Calendar, 1.697 + Success_Collection, 1.698 + UNTRUSTED_CERT, 1.699 + Account_Already_In_Use 1.700 + } 1.701 + 1.702 + 1.703 + /** 1.704 + * Represents an asynchronous login/registration task used to authenticate 1.705 + * the user. 1.706 + */ 1.707 + public class UserLoginTask extends AsyncTask<Void, Void, LoginResult> { 1.708 + 1.709 + @Override 1.710 + protected LoginResult doInBackground(Void... params) { 1.711 + 1.712 + TestConnectionResult result = null; 1.713 + 1.714 + try { 1.715 + CaldavFacade facade = new CaldavFacade(mUser, mPassword, mURL, mTrustAll); 1.716 + String version = ""; 1.717 + try { 1.718 + version = mContext.getPackageManager() 1.719 + .getPackageInfo(mContext.getPackageName(), 0).versionName; 1.720 + } catch (NameNotFoundException e) { 1.721 + version = "unknown"; 1.722 + e.printStackTrace(); 1.723 + } 1.724 + facade.setVersion(version); 1.725 + result = facade.testConnection(); 1.726 + Log.i(TAG, "testConnection status=" + result); 1.727 + } catch (HttpHostConnectException e) { 1.728 + Log.w(TAG, "testConnection", e); 1.729 + return LoginResult.ConnectionRefused; 1.730 + } catch (MalformedURLException e) { 1.731 + Log.w(TAG, "testConnection", e); 1.732 + return LoginResult.MalformedURLException; 1.733 + } catch (UnsupportedEncodingException e) { 1.734 + Log.w(TAG, "testConnection", e); 1.735 + return LoginResult.UnkonwnException; 1.736 + } catch (ParserConfigurationException e) { 1.737 + Log.w(TAG, "testConnection", e); 1.738 + return LoginResult.UnkonwnException; 1.739 + } catch (SAXException e) { 1.740 + Log.w(TAG, "testConnection", e); 1.741 + return LoginResult.InvalidResponse; 1.742 + } catch (IOException e) { 1.743 + Log.w(TAG, "testConnection", e); 1.744 + return LoginResult.UnkonwnException; 1.745 + } catch (URISyntaxException e) { 1.746 + Log.w(TAG, "testConnection", e); 1.747 + return LoginResult.MalformedURLException; 1.748 + } 1.749 + 1.750 + if (result == null) { 1.751 + return LoginResult.UnkonwnException; 1.752 + } 1.753 + 1.754 + switch (result) { 1.755 + 1.756 + case SSL_ERROR: 1.757 + return LoginResult.UNTRUSTED_CERT; 1.758 + case SUCCESS: 1.759 + boolean OldAccount = false; 1.760 + LoginResult Result = LoginResult.Success_Calendar; 1.761 + 1.762 + if (OldAccount) { 1.763 + final Account account = new Account(mUser, ACCOUNT_TYPE); 1.764 + if (mAccountManager.addAccountExplicitly(account, mPassword, null)) { 1.765 + Log.v(TAG, "new account created"); 1.766 + mAccountManager.setUserData(account, USER_DATA_URL_KEY, mURL); 1.767 + } else { 1.768 + Log.v(TAG, "no new account created"); 1.769 + Result = LoginResult.Account_Already_In_Use; 1.770 + } 1.771 + } else { 1.772 + final Account account; 1.773 + if (mAccountname.equals("")) { 1.774 + account = new Account(mUser + ACCOUNT_NAME_SPLITTER + mURL, ACCOUNT_TYPE); 1.775 + } else { 1.776 + account = new Account(mAccountname, ACCOUNT_TYPE); 1.777 + } 1.778 + if (mAccountManager.addAccountExplicitly(account, mPassword, null)) { 1.779 + Log.v(TAG, "new account created"); 1.780 + mAccountManager.setUserData(account, USER_DATA_URL_KEY, mURL); 1.781 + mAccountManager.setUserData(account, USER_DATA_USERNAME, mUser); 1.782 + mAccountManager.setUserData(account, USER_DATA_VERSION, CURRENT_USER_DATA_VERSION); 1.783 + mAccountManager.setUserData(account, Constants.USER_DATA_TRUST_ALL_KEY, mTrustAll); 1.784 + } else { 1.785 + Log.v(TAG, "no new account created"); 1.786 + Result = LoginResult.Account_Already_In_Use; 1.787 + } 1.788 + } 1.789 + 1.790 + return Result; 1.791 + 1.792 + case WRONG_CREDENTIAL: 1.793 + return LoginResult.WrongCredentials; 1.794 + 1.795 + case WRONG_SERVER_STATUS: 1.796 + return LoginResult.InvalidResponse; 1.797 + 1.798 + case WRONG_URL: 1.799 + return LoginResult.WrongUrl; 1.800 + 1.801 + case WRONG_ANSWER: 1.802 + return LoginResult.InvalidResponse; 1.803 + 1.804 + default: 1.805 + return LoginResult.UnkonwnException; 1.806 + 1.807 + } 1.808 + 1.809 + } 1.810 + 1.811 + 1.812 + @Override 1.813 + protected void onPostExecute(final LoginResult result) { 1.814 + mAuthTask = null; 1.815 + showProgress(false); 1.816 + 1.817 + int duration = Toast.LENGTH_SHORT; 1.818 + Toast toast = null; 1.819 + 1.820 + switch (result) { 1.821 + case Success_Calendar: 1.822 + toast = Toast.makeText(getApplicationContext(), R.string.success_calendar, duration); 1.823 + toast.show(); 1.824 + finish(); 1.825 + break; 1.826 + 1.827 + case Success_Collection: 1.828 + toast = Toast.makeText(getApplicationContext(), R.string.success_collection, duration); 1.829 + toast.show(); 1.830 + finish(); 1.831 + break; 1.832 + 1.833 + case MalformedURLException: 1.834 + 1.835 + toast = Toast.makeText(getApplicationContext(), R.string.error_incorrect_url_format, duration); 1.836 + toast.show(); 1.837 + mURLView.setError(getString(R.string.error_incorrect_url_format)); 1.838 + mURLView.requestFocus(); 1.839 + break; 1.840 + case InvalidResponse: 1.841 + toast = Toast.makeText(getApplicationContext(), R.string.error_invalid_server_answer, duration); 1.842 + toast.show(); 1.843 + mURLView.setError(getString(R.string.error_invalid_server_answer)); 1.844 + mURLView.requestFocus(); 1.845 + break; 1.846 + case WrongUrl: 1.847 + toast = Toast.makeText(getApplicationContext(), R.string.error_wrong_url, duration); 1.848 + toast.show(); 1.849 + mURLView.setError(getString(R.string.error_wrong_url)); 1.850 + mURLView.requestFocus(); 1.851 + break; 1.852 + 1.853 + case GeneralSecurityException: 1.854 + break; 1.855 + case UnkonwnException: 1.856 + break; 1.857 + case WrongCredentials: 1.858 + mPasswordView.setError(getString(R.string.error_incorrect_password)); 1.859 + mPasswordView.requestFocus(); 1.860 + break; 1.861 + 1.862 + case ConnectionRefused: 1.863 + toast = Toast.makeText(getApplicationContext(), R.string.error_connection_refused, duration); 1.864 + toast.show(); 1.865 + mURLView.setError(getString(R.string.error_connection_refused)); 1.866 + mURLView.requestFocus(); 1.867 + break; 1.868 + case UNTRUSTED_CERT: 1.869 + toast = Toast.makeText(getApplicationContext(), getString(R.string.error_untrusted_certificate), duration); 1.870 + toast.show(); 1.871 + mURLView.setError(getString(R.string.error_ssl)); 1.872 + mURLView.requestFocus(); 1.873 + break; 1.874 + case Account_Already_In_Use: 1.875 + toast = Toast.makeText(getApplicationContext(), R.string.error_account_already_in_use, duration); 1.876 + toast.show(); 1.877 + mURLView.setError(getString(R.string.error_account_already_in_use)); 1.878 + mURLView.requestFocus(); 1.879 + break; 1.880 + default: 1.881 + toast = Toast.makeText(getApplicationContext(), R.string.error_unkown_error, duration); 1.882 + toast.show(); 1.883 + mURLView.setError(getString(R.string.error_unkown_error)); 1.884 + mURLView.requestFocus(); 1.885 + break; 1.886 + } 1.887 + 1.888 + 1.889 + } 1.890 + 1.891 + @Override 1.892 + protected void onCancelled() { 1.893 + mAuthTask = null; 1.894 + showProgress(false); 1.895 + } 1.896 + } 1.897 +} 1.898 \ No newline at end of file