1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-11 20:15:03 -05:00

Revert "Revert "Improved autoconfiguration screen. User can follow progress better, has an indicator the phone is busy. Added buttons to cancel or continue.""

This reverts commit 555318de515f962a742281b025821b96f6ad463a.
This commit is contained in:
dzan 2011-07-16 14:51:29 +02:00 committed by Andrew Chen
parent 70e25c93e8
commit 9df96d07c5
4 changed files with 151 additions and 110 deletions

View File

@ -12,14 +12,40 @@
android:gravity="center_horizontal"
android:paddingBottom="6dip"/>
<ProgressBar android:id="@+id/autoconfig_progress"
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/status_message"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
style="@android:style/Widget.ProgressBar.Large" />
android:layout_marginBottom="10dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true">
<TextView android:id="@+id/autoconfig_warning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Warning blaat blaat" />
<ProgressBar android:id="@+id/autoconfig_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/status_message"
android:layout_centerHorizontal="true"
android:layout_marginBottom="60dp"
style="@android:style/Widget.ProgressBar.Large" />
<Button android:id="@+id/autoconfig_button_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/autoconfig_progress"
android:text="@string/cancel_action"/>
<Button android:id="@+id/autoconfig_button_next"
android:drawableRight="@drawable/button_indicator_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/autoconfig_progress"
android:layout_toRightOf="@id/autoconfig_button_cancel"
android:text="@string/next_action"/>
</RelativeLayout>
<!-- TODO: add a cancel button
<include layout="@layout/wizard_cancel"/> -->
</RelativeLayout>

View File

@ -379,6 +379,8 @@ http://k9mail.googlecode.com/
<string name="account_setup_autoconfig_missing">not found!</string>
<string name="account_setup_autoconfig_succesful">successful!</string>
<string name="account_setup_autoconfig_fail">failed!</string>
<string name="account_setup_autoconfig_forcemanual">No settings found, use manual configuration.</string>
<string name="account_setup_autoconfig_trynext">Searching other places for configuration settings...</string>
<string name="account_setup_names_title">You\'re almost done!</string>
<string name="account_setup_names_instructions">Your account is set up, and mail is on its way!</string>

View File

@ -8,6 +8,7 @@ import android.os.*;
import android.os.Process;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.fsck.k9.K9;
@ -15,6 +16,7 @@ import com.fsck.k9.R;
import com.fsck.k9.activity.K9Activity;
import com.fsck.k9.helper.configxmlparser.ConfigurationXMLHandler;
import com.fsck.k9.mail.store.TrustManagerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@ -27,6 +29,7 @@ import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.TimeoutException;
/**
* User: dzan
@ -35,14 +38,11 @@ import java.util.Arrays;
public class AccountSetupAutoConfiguration extends K9Activity implements View.OnClickListener {
// constants for the intent/activity system
// TODO: read about intents and make this one result right
public static final int ACTIVITY_REQUEST_CODE = 1;
private static final String EMAIL_ADDRESS = "account";
private static final String PASSWORD = "password";
// timeout for testing services availability ( in ms )
private static final int TIMEOUT = 20000;
private static final int TIMEOUT = 5000;
// location of mozilla's ispdb
private String databaseBaseUrl = "https://live.mozillamessaging.com/autoconfig/v1.1/";
@ -78,10 +78,17 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
private TextView mMessageView;
private ProgressBar mProgressCircle;
private Button mCancelButton;
private Button mNextButton;
private TextView mWarningMsg;
private String mEmailAddress;
private String mPassword;
private String mLastMessage;
private boolean bForceManual = false;
private boolean bDoneSearching = false;
private boolean bFound = false;
private boolean bParseFailed = false;
/*
Start the auto-configuration activity
@ -90,7 +97,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
Intent i = new Intent(context, AccountSetupAutoConfiguration.class);
i.putExtra(EMAIL_ADDRESS, email);
i.putExtra(PASSWORD, password);
context.startActivityForResult(i, ACTIVITY_REQUEST_CODE);
context.startActivity(i);
}
/*
@ -103,10 +110,17 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
// Setting up the view
setContentView(R.layout.account_setup_autoconfig);
mMessageView = (TextView)findViewById(R.id.status_message);
mWarningMsg = (TextView)findViewById(R.id.autoconfig_warning);
mWarningMsg.setVisibility(View.GONE);
mProgressCircle = (ProgressBar)findViewById(R.id.autoconfig_progress);
mProgressCircle.setIndeterminate(true);
mProgressCircle.setVisibility(View.VISIBLE);
// ((Button)findViewById(R.id.cancel)).setOnClickListener(this);
mCancelButton = (Button)findViewById(R.id.autoconfig_button_cancel);
mCancelButton.setOnClickListener(this);
mNextButton = (Button)findViewById(R.id.autoconfig_button_next);
mNextButton.setOnClickListener(this);
mNextButton.setEnabled(false);
// Getting our data to work with
mEmailAddress = getIntent().getStringExtra(EMAIL_ADDRESS);
@ -134,11 +148,16 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
Check if configuration data exists and if it does read in
*/
int i = 0;
while( i < urlTemplates.size() ){
while( i < urlTemplates.size() && !bFound ){
try{
// inform the user
setMessage(urlInfoStatements.get(i),true);
// to make sure
bParseFailed = false;
bForceManual = false;
bDoneSearching = false;
// preparing the urls
if( !domain.contains("%user%") ){ // else SHIT
tmpURL = urlTemplates.get(i).replaceAll("%domain%",domain);
@ -147,24 +166,26 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
data = getXMLData(new URL(tmpURL));
// might be the user cancelled by now or the app was destroyed
if (mDestroyed) return;
if (mCanceled) { finish(); return; }
if( !data.isEmpty() ){
setMessage(R.string.account_setup_autoconfig_found,false);
// parse and finish
// remember if i >= UNSAFE_URL_START => POSSIBLE UNSAFE DATA, alert user!!!
setMessage(R.string.account_setup_autoconfig_processing,true);
parse(data);
setMessage(R.string.account_setup_autoconfig_succesful,false);
// Give user some time to read output
try { Thread.sleep(1750);
} catch (InterruptedException e) { e.printStackTrace(); }
// alert user these settings might be tampered with!!! ( no https )
if( i >= UNSAFE_URL_START )
mWarningMsg.setVisibility(View.VISIBLE);
finish();
return;
bFound = true;
continue;
}
// end the output if needed
closeUserInformationIfNeeded(i);
}catch (SocketTimeoutException ex){
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
tmpURL+"' ( time-out is"+TIMEOUT+" )", ex);
@ -174,18 +195,21 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
}catch (UnknownHostException ex){
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
tmpURL+"'", ex);
}
catch (SSLPeerUnverifiedException ex){
}catch (SSLPeerUnverifiedException ex){
Log.e(K9.LOG_TAG, "Error while testing settings", ex);
acceptKeyDialog(
R.string.account_setup_failed_dlg_certificate_message_fmt,i,ex);
}
catch(IOException ex) {
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
tmpURL+"'", ex);
} catch (ErrorCodeException ex) {
acceptKeyDialog(R.string.account_setup_failed_dlg_certificate_message_fmt,i,ex);
}catch (SAXException e) {
setMessage(R.string.account_setup_autoconfig_fail,false);
bParseFailed = true;
}catch (ParserConfigurationException e) {
setMessage(R.string.account_setup_autoconfig_fail,false);
bParseFailed = true;
}catch (ErrorCodeException ex) {
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '" +
tmpURL + "' site didn't respond as expected. Got code: " + ex.getErrorCode(), ex);
}catch(IOException ex) {
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
tmpURL+"'", ex);
} finally {
// might be the user cancelled by now or the app was destroyed
if (mDestroyed) return;
@ -193,37 +217,56 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
// check next url
++i;
// this was the last option..
if(i == urlTemplates.size() ){
bForceManual = true;
setMessage(R.string.account_setup_autoconfig_forcemanual, true);
}else{
if( bParseFailed )
setMessage(R.string.account_setup_autoconfig_trynext,true);
}
}
// no server-side config was found
closeUserInformationIfNeeded(i-1);
}
bDoneSearching = true;
runOnUiThread(new Runnable() {
public void run() {
// TODO: set appropriate warning messages in here
// 1. All good, continue
// 2. Nothing came up, must manually config.. + help?
// 3. Data did not came over HTTPS this could be UNSAFE !!!!!!
mProgressCircle.setVisibility(View.INVISIBLE);
mWarningMsg.setVisibility(View.VISIBLE);
mNextButton.setEnabled(true);
if( bForceManual )
mNextButton.setText(getString(R.string.account_setup_basics_manual_setup_action));
}
});
}
}
.start();
}
/*
Start parsing the xml
*/
private void parse(String data) {
try{
XMLReader xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xr.setContentHandler(new ConfigurationXMLHandler());
//xr.parse(data);
// TODO: take care of these
} catch (ParserConfigurationException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (SAXException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
private void parse(String data) throws IOException, SAXException, ParserConfigurationException {
XMLReader xr = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xr.setContentHandler(new ConfigurationXMLHandler());
// TODO: see if this has performance consequences, otherwise change all so we pass around InputSource not string
xr.parse(new InputSource(new StringReader(data)));
}
/*
Checks if an url is available / exists
*/
private String getXMLData(URL url) throws IOException, ErrorCodeException{
private String getXMLData(URL url) throws IOException, ErrorCodeException, SocketTimeoutException {
// think we should assume no redirects
// TODO: use k9's own TrustManager so the right exception gets throwed and the user can choose to accept the certificate
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
@ -234,14 +277,23 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
// get the data
String tmp, line;
BufferedReader reader;
tmp = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while( (line = reader.readLine()) != null)
tmp += line;
if( conn.getResponseCode() != 200 )
throw new ErrorCodeException("Server did not return as expected.",conn.getResponseCode());
conn.disconnect();
try{
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while( (line = reader.readLine()) != null)
tmp += line;
if( conn.getResponseCode() != 200 )
throw new ErrorCodeException("Server did not return as expected.",conn.getResponseCode());
}
catch (SocketTimeoutException ex)
{ throw ex; }
finally
{ conn.disconnect(); }
return tmp;
}
@ -251,7 +303,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
private void setMessage(int resId, final boolean newLine){
setMessage(getString(resId), newLine);
}
private void setMessage(final String msg, final boolean newline) {
private synchronized void setMessage(final String msg, final boolean newline) {
mHandler.post(new Runnable() {
public void run() {
// don't print if same as last message or when process should be destroyed
@ -270,9 +322,10 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
}
private void closeUserInformationIfNeeded(int urlNumb) {
int a = urlInfoStatements.get(urlNumb);
int b = urlInfoStatements.get(urlNumb+1);
if( urlNumb == urlInfoStatements.size() - 1 || a != b ){
if( bForceManual ) return;
if( urlNumb == urlInfoStatements.size() - 1
|| (int)urlInfoStatements.get(urlNumb) != urlInfoStatements.get(urlNumb+1) ){
mHandler.post(new Runnable() {
public void run() {
mMessageView.setText(mMessageView.getText().toString()+
@ -295,6 +348,10 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
Alert user he canceled and stop the thread
*/
private void onCancel() {
if( bDoneSearching ){
finish();
return;
}
mCanceled = true;
setMessage(R.string.account_setup_check_settings_canceling_msg, true);
}
@ -318,9 +375,19 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
public void onClick(View v) {
switch (v.getId()) {
case R.id.cancel:
case R.id.autoconfig_button_cancel:
onCancel();
break;
case R.id.autoconfig_button_next:
// autoconfig failed, proceed by manual setup
if( bForceManual ){
// launch confirm activities
}else{
}
break;
default: return;
}
}

View File

@ -1,54 +0,0 @@
// This could be useful later ( if this way of parsing is too slow )
/*
Strings
*/
/*// main structure tags
private final static String CLIENT_CONFIG = "clientConfig"; // root
private final static String CLIENT_CONFIG_UPDATE = "clientConfigUpdate";
private final static String EMAIL_PROVIDER = "emailProvider"; // semi-root, container of whole isp data
private final static String ID = "id";
private final static String INCOMING_SERVER = "incomingServer";
private final static String OUTGOING_SERVER = "outgoingServer";
private final static String TYPE = "type";
// email provider extra information
private final static String DOMAIN = "domain";
private final static String DISPLAY_NAME = "displayName";
private final static String DISPLAY_SHORT_NAME = "displayShortName";
private final static String ENABLE = "enable";
private final static String VISIT_URL = "visiturl"; // attribute of enable
private final static String INSTRUCTION = "instruction"; // child of ^ containing text instructions
//private final static String INSTRUCTION = "instruction"; // could also be tag
private final static String URL = "url"; // attribute of instruction as a tag
private final static String DESCR = "descr"; // child containing urls
private final static String LANG = "lang"; // language of description
private final static String IDENTITY = "identity";
private final static String INPUT_FIELD = "inputField";
private final static String KEY = "key";
private final static String LABEL = "label";
private final static String DOCUMENTATION = "documentation"; // has all kinds of subelements urls & descriptions
// server settings
private final static String HOSTNAME = "hostname";
private final static String PORT = "port";
private final static String SOCKET_TYPE = "socketType";
private final static String USERNAME = "username";
private final static String AUTHENTICATION = "authentication";
// server types ( attributes of outgoing/incoming-Server
private final static String POP3 = "pop3"; // also a tag with extra info
private final static String IMAP = "imap";
private final static String SMTP = "smtp";
// pop3 options
private final static String LEAVE_MESSAGES_ON_SERVER = "leaveMessagesOnServer";
private final static String DOWNLOAD_ON_BIFF = "downloadOnBiff";
private final static String DAYS_TO_LEAVE_MESSAGES_ON_SERVER = "daysToLeaveMessagesOnServer";
private final static String CHECK_INTERVAL = "checkInterval";
private final static String MINUTES = "minutes";
// outgoing server settings
private final static String RESTRICTION = "restriction";
private final static String ADD_THIS_SERVER = "addThisServer";
private final static String USE_GLOBAL_PREFERRED_SERVER = "useGlobalPreferredServer"; */