blob: 0a1bc605eac5bbf24019a284000886779fc92eb3 [file] [log] [blame]
package com.android.email.activity.setup;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.email.R;
import com.android.email.activity.UiUtilities;
import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
import com.android.email.view.CertificateSelector;
import com.android.email.view.CertificateSelector.HostCallback;
import com.android.emailcommon.Device;
import com.android.emailcommon.VendorPolicyLoader.OAuthProvider;
import com.android.emailcommon.provider.Credential;
import com.android.emailcommon.provider.HostAuth;
import com.android.emailcommon.utility.CertificateRequestor;
import java.io.IOException;
// FLAG:
// * need to handle adding new authentication
// * need to handle a set, but invalid, OAuth info
public class AuthenticationView extends LinearLayout implements HostCallback, OnClickListener {
private final static String SUPER_STATE = "super_state";
private final static String SAVE_PASSWORD = "save_password";
private final static String SAVE_OFFER_OAUTH = "save_offer_oauth";
private final static String SAVE_OFFER_CERTS = "save_offer_certs";
private final static String SAVE_USE_OAUTH = "save_use_oauth";
private final static String SAVE_OAUTH_PROVIDER = "save_oauth_provider";
private final static String SAVE_OAUTH_ACCESS_TOKEN = "save_oauth_access_token";
private final static String SAVE_OAUTH_REFRESH_TOKEN = "save_oauth_refresh_token";
// Views
private View mImapAuthenticationView;
private View mImapPasswordContainer;
private EditText mImapPasswordView;
private View mImapOAuthContainer;
private TextView mImapOAuthView;
private View mImapAddAuthenticationView;
private View mPasswordContainer;
private View mClearImapPasswordView;
private View mClearOAuthView;
private View mAddAuthenticationView;
private EditText mPasswordView;
private CertificateSelector mClientCertificateSelector;
private View mDeviceIdSectionView;
private TextWatcher mValidationTextWatcher;
private boolean mOfferOAuth;
private boolean mOfferCerts;
private boolean mUseOAuth;
private String mOAuthProvider;
private String mOAuthAccessToken;
private String mOAuthRefreshToken;
private boolean mAuthenticationValid;
private AuthenticationCallback mAuthenticationCallback;
public interface AuthenticationCallback {
public void onValidateStateChanged();
public void onCertificateRequested();
}
public AuthenticationView(Context context) {
this(context, null);
}
public AuthenticationView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AuthenticationView(Context context, AttributeSet attrs, int defstyle) {
super(context, attrs, defstyle);
LayoutInflater.from(context).inflate(R.layout.authentication_view, this, true);
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
mImapAuthenticationView = UiUtilities.getView(this, R.id.imap_authentication);
mImapPasswordContainer = UiUtilities.getView(this, R.id.imap_password_selection);
mImapPasswordView = UiUtilities.getView(this, R.id.imap_account_password);
mImapOAuthContainer = UiUtilities.getView(this, R.id.oauth_selection);
mImapOAuthView = UiUtilities.getView(this, R.id.signed_in_with_service_label);
mImapAddAuthenticationView = UiUtilities.getView(this, R.id.authentication_selection);
mPasswordContainer = UiUtilities.getView(this, R.id.standard_password_selection);
mPasswordView = UiUtilities.getView(this, R.id.account_password);
mClientCertificateSelector = UiUtilities.getView(this, R.id.client_certificate_selector);
mDeviceIdSectionView = UiUtilities.getView(this, R.id.device_id_section);
mClearImapPasswordView = UiUtilities.getView(this, R.id.clear_password);
mClearOAuthView = UiUtilities.getView(this, R.id.clear_oauth);
mAddAuthenticationView = UiUtilities.getView(this, R.id.add_authentication);
mClearImapPasswordView.setOnClickListener(this);
mClearOAuthView.setOnClickListener(this);
mAddAuthenticationView.setOnClickListener(this);
mClientCertificateSelector.setHostCallback(this);
mValidationTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
validateFields();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
};
mPasswordView.addTextChangedListener(mValidationTextWatcher);
mImapPasswordView.addTextChangedListener(mValidationTextWatcher);
}
public void setAuthenticationCallback(final AuthenticationCallback host) {
mAuthenticationCallback = host;
}
public boolean getAuthValid() {
if (mOfferOAuth) {
if (mUseOAuth) {
return mOAuthProvider != null;
} else {
return !TextUtils.isEmpty(mImapPasswordView.getText());
}
} else {
return !TextUtils.isEmpty(mPasswordView.getText());
}
}
public String getPassword() {
return getPasswordEditText().getText().toString();
}
public String getClientCertificate() {
return mClientCertificateSelector.getCertificate();
}
public String getOAuthProvider() {
// FLAG: need to handle this getting updated.
return mOAuthProvider;
}
private void validateFields() {
boolean valid = getAuthValid();
if (valid != mAuthenticationValid) {
mAuthenticationCallback.onValidateStateChanged();
mAuthenticationValid = valid;
}
// Warn (but don't prevent) if password has leading/trailing spaces
AccountSettingsUtils.checkPasswordSpaces(getContext(), getPasswordEditText());
}
private EditText getPasswordEditText() {
if (mOfferOAuth) {
return mImapPasswordView;
} else {
return mPasswordView;
}
}
public void setAuthInfo(final boolean offerOAuth, final boolean offerCerts,
final HostAuth hostAuth) {
mOfferOAuth = offerOAuth;
mOfferCerts = offerCerts;
if (mOfferOAuth) {
final Credential cred = hostAuth.getCredential(getContext());
if (cred != null) {
// We're authenticated with OAuth.
mUseOAuth = true;
mOAuthProvider = cred.mProviderId;
mOAuthAccessToken = cred.mAccessToken;
mOAuthRefreshToken = cred.mRefreshToken;
} else {
mUseOAuth = false;
}
} else {
// We're using a POP or Exchange account, which does not offer oAuth.
mUseOAuth = false;
}
getPasswordEditText().setText(hostAuth.mPassword);
if (mOfferOAuth && mUseOAuth) {
// We're authenticated with OAuth.
final OAuthProvider provider = AccountSettingsUtils.findOAuthProvider(
getContext(), mOAuthProvider);
mImapOAuthView.setText(getContext().getString(R.string.signed_in_with_service_label,
provider.label));
}
updateVisibility();
validateFields();
}
private void updateVisibility() {
mClientCertificateSelector.setVisibility(
mOfferCerts ? View.VISIBLE : View.GONE);
if (mOfferOAuth) {
mPasswordContainer.setVisibility(View.GONE);
mImapAuthenticationView.setVisibility(View.VISIBLE);
if (mUseOAuth) {
// We're authenticated with OAuth.
mImapPasswordContainer.setVisibility(View.GONE);
mImapOAuthContainer.setVisibility(View.VISIBLE);
mImapAddAuthenticationView.setVisibility(View.GONE);
} else if (!TextUtils.isEmpty(getPassword())) {
// We're authenticated with a password.
mImapPasswordContainer.setVisibility(View.VISIBLE);
mImapOAuthContainer.setVisibility(View.GONE);
mImapAddAuthenticationView.setVisibility(View.GONE);
if (TextUtils.isEmpty(mImapPasswordView.getText())) {
mImapPasswordView.requestFocus();
}
} else {
// We have no authentication, we need to allow either password or oauth.
mImapPasswordContainer.setVisibility(View.GONE);
mImapOAuthContainer.setVisibility(View.GONE);
mImapAddAuthenticationView.setVisibility(View.VISIBLE);
}
} else {
// We're using a POP or Exchange account, which does not offer oAuth.
mImapAuthenticationView.setVisibility(View.GONE);
mPasswordContainer.setVisibility(View.VISIBLE);
mPasswordView.setVisibility(View.VISIBLE);
if (TextUtils.isEmpty(mPasswordView.getText())) {
mPasswordView.requestFocus();
}
}
}
@Override
public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(SUPER_STATE, super.onSaveInstanceState());
bundle.putBoolean(SAVE_OFFER_OAUTH, mOfferOAuth);
bundle.putBoolean(SAVE_OFFER_CERTS, mOfferCerts);
bundle.putBoolean(SAVE_USE_OAUTH, mUseOAuth);
bundle.putString(SAVE_PASSWORD, getPassword());
bundle.putString(SAVE_OAUTH_PROVIDER, mOAuthProvider);
bundle.putString(SAVE_OAUTH_ACCESS_TOKEN, mOAuthAccessToken);
bundle.putString(SAVE_OAUTH_REFRESH_TOKEN, mOAuthRefreshToken);
return bundle;
}
@Override
public void onRestoreInstanceState(Parcelable parcelable) {
if (parcelable instanceof Bundle) {
Bundle bundle = (Bundle)parcelable;
super.onRestoreInstanceState(bundle.getParcelable(SUPER_STATE));
mOfferOAuth = bundle.getBoolean(SAVE_OFFER_OAUTH);
mOfferCerts = bundle.getBoolean(SAVE_OFFER_CERTS);
mUseOAuth = bundle.getBoolean(SAVE_USE_OAUTH);
mOAuthProvider = bundle.getString(SAVE_OAUTH_PROVIDER);
mOAuthAccessToken = bundle.getString(SAVE_OAUTH_ACCESS_TOKEN);
mOAuthRefreshToken = bundle.getString(SAVE_OAUTH_REFRESH_TOKEN);
final String password = bundle.getString(SAVE_PASSWORD);
getPasswordEditText().setText(password);
if (!TextUtils.isEmpty(mOAuthProvider)) {
final OAuthProvider provider = AccountSettingsUtils.findOAuthProvider(
getContext(), mOAuthProvider);
if (provider != null) {
mImapOAuthView.setText(getContext().getString(R.string.signed_in_with_service_label,
provider.label));
}
}
updateVisibility();
}
}
@Override
public void onCertificateRequested() {
mAuthenticationCallback.onCertificateRequested();
}
public void setCertificate(final String certAlias) {
mClientCertificateSelector.setCertificate(certAlias);
}
public void onUseSslChanged(boolean useSsl) {
if (mOfferCerts) {
final int mode = useSsl ? View.VISIBLE : View.GONE;
mClientCertificateSelector.setVisibility(mode);
String deviceId = "";
try {
deviceId = Device.getDeviceId(getContext());
} catch (IOException e) {
// Not required
}
((TextView) UiUtilities.getView(this, R.id.device_id)).setText(deviceId);
mDeviceIdSectionView.setVisibility(mode);
}
}
@Override
public void onClick(View view) {
if (view == mClearImapPasswordView) {
getPasswordEditText().setText(null);
updateVisibility();
} else if (view == mClearOAuthView) {
mUseOAuth = false;
mOAuthProvider = null;
updateVisibility();
} else if (view == mAddAuthenticationView) {
// FLAG Launch the add authentication screen
}
}
}