Modularize password entry

This commit is contained in:
str4d
2014-08-17 11:36:17 +00:00
parent bbd4cf2b8e
commit 061a98dcb7
2 changed files with 116 additions and 82 deletions

View File

@@ -1,10 +1,7 @@
package i2p.bote.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
@@ -16,14 +13,11 @@ import android.support.v4.content.Loader;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
@@ -52,6 +46,7 @@ import uk.co.senab.actionbarpulltorefresh.library.Options;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
public class EmailListFragment extends ListFragment implements
BoteHelper.RequestPasswordListener,
LoaderManager.LoaderCallbacks<List<Email>>,
MoveToDialogFragment.MoveToDialogListener,
EmailListAdapter.EmailSelector, OnRefreshListener {
@@ -71,9 +66,6 @@ public class EmailListFragment extends ListFragment implements
private MultiSelectionUtil.Controller mMultiSelectController;
private ModalChoiceListener mModalChoiceListener;
private EditText mPasswordInput;
private TextView mPasswordError;
public static EmailListFragment newInstance(String folderName) {
EmailListFragment f = new EmailListFragment();
Bundle args = new Bundle();
@@ -168,7 +160,7 @@ public class EmailListFragment extends ListFragment implements
BoteHelper.getFolderDisplayName(getActivity(), mFolder));
if (I2PBote.getInstance().isPasswordRequired()) {
// Request a password from the user.
requestPassword();
BoteHelper.requestPassword(getActivity(), this);
} else {
// Password is cached, or not set.
initializeList();
@@ -176,80 +168,13 @@ public class EmailListFragment extends ListFragment implements
}
}
/**
* Request the password from the user, and try it.
*/
private void requestPassword() {
LayoutInflater li = LayoutInflater.from(getActivity());
View promptView = li.inflate(R.layout.dialog_password, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(promptView);
mPasswordInput = (EditText) promptView.findViewById(R.id.passwordInput);
mPasswordError = (TextView) promptView.findViewById(R.id.passwordError);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
InputMethodManager imm = (InputMethodManager) EmailListFragment.this
.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mPasswordInput.getWindowToken(), 0);
dialog.dismiss();
new PasswordWaiter().execute();
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
setEmptyText(getResources().getString(
R.string.not_authed));
dialog.cancel();
}
});
AlertDialog passwordDialog = builder.create();
passwordDialog.show();
public void onPasswordVerified() {
initializeList();
}
private class PasswordWaiter extends AsyncTask<Void, Void, String> {
private final ProgressDialog dialog = new ProgressDialog(EmailListFragment.this.getActivity());
protected void onPreExecute() {
dialog.setMessage(getResources().getString(
R.string.checking_password));
dialog.setCancelable(false);
dialog.show();
}
protected String doInBackground(Void... params) {
try {
if (BoteHelper.tryPassword(mPasswordInput.getText().toString()))
return null;
else {
cancel(false);
return getResources().getString(
R.string.password_incorrect);
}
} catch (IOException e) {
cancel(false);
return getResources().getString(
R.string.password_file_error);
} catch (GeneralSecurityException e) {
cancel(false);
return getResources().getString(
R.string.password_file_error);
}
}
protected void onCancelled(String result) {
dialog.dismiss();
requestPassword();
mPasswordError.setText(result);
mPasswordError.setVisibility(View.VISIBLE);
}
protected void onPostExecute(String result) {
// Password is valid
initializeList();
dialog.dismiss();
}
public void onPasswordCanceled() {
setEmptyText(getResources().getString(
R.string.not_authed));
}
/**

View File

@@ -10,11 +10,20 @@ import javax.mail.Address;
import javax.mail.Flags.Flag;
import javax.mail.MessagingException;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.lambdaworks.codec.Base64;
@@ -250,4 +259,104 @@ public class BoteHelper extends GeneralHelper {
}
return emails;
}
public interface RequestPasswordListener {
public void onPasswordVerified();
public void onPasswordCanceled();
}
/**
* Request the password from the user, and try it.
*/
public static void requestPassword(final Context context, final RequestPasswordListener listener) {
requestPassword(context, listener, null);
}
/**
* Request the password from the user, and try it.
*
* @param error is pre-filled in the dialog if not null.
*/
public static void requestPassword(final Context context, final RequestPasswordListener listener, String error) {
LayoutInflater li = LayoutInflater.from(context);
View promptView = li.inflate(R.layout.dialog_password, null);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setView(promptView);
final EditText passwordInput = (EditText) promptView.findViewById(R.id.passwordInput);
if (error != null) {
TextView passwordError = (TextView) promptView.findViewById(R.id.passwordError);
passwordError.setText(error);
passwordError.setVisibility(View.VISIBLE);
}
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(passwordInput.getWindowToken(), 0);
dialog.dismiss();
new PasswordWaiter(context, listener).execute(passwordInput.getText().toString());
}
}).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
listener.onPasswordCanceled();
}
});
AlertDialog passwordDialog = builder.create();
passwordDialog.show();
}
private static class PasswordWaiter extends AsyncTask<String, Void, String> {
private final Context mContext;
private final ProgressDialog mDialog;
private final RequestPasswordListener mListener;
public PasswordWaiter(Context context, RequestPasswordListener listener) {
super();
mContext = context;
mDialog = new ProgressDialog(context);
mListener = listener;
}
protected void onPreExecute() {
mDialog.setMessage(mContext.getResources().getString(
R.string.checking_password));
mDialog.setCancelable(false);
mDialog.show();
}
protected String doInBackground(String... params) {
try {
if (BoteHelper.tryPassword(params[0]))
return null;
else {
cancel(false);
return mContext.getResources().getString(
R.string.password_incorrect);
}
} catch (IOException e) {
cancel(false);
return mContext.getResources().getString(
R.string.password_file_error);
} catch (GeneralSecurityException e) {
cancel(false);
return mContext.getResources().getString(
R.string.password_file_error);
}
}
protected void onCancelled(String result) {
mDialog.dismiss();
requestPassword(mContext, mListener, result);
}
protected void onPostExecute(String result) {
// Password is valid
mDialog.dismiss();
mListener.onPasswordVerified();
}
}
}