Create AuthenticationFragment
This is one fragment that holds all types of authentication information, e.g. password, OAuth info, and client certificates. What gets displayed depends upon the type of account it is dealing with. So far this is only used in AccountSetupIncoming, but later it can be added to other settings fragments. There are still some issues with this, but I'd like to check it in sooner than later to unblock other work. Change-Id: Iea675ad5c1727f32ca0baa270dfa793ab7109993
This commit is contained in:
parent
018ae522d7
commit
9195a12024
BIN
res/drawable-hdpi/ic_add_authentication.png
Normal file
BIN
res/drawable-hdpi/ic_add_authentication.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 254 B |
BIN
res/drawable-hdpi/ic_clear_authentication.png
Normal file
BIN
res/drawable-hdpi/ic_clear_authentication.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -20,6 +20,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/account_setup_incoming_username_label"
|
||||
android:layout_height="wrap_content"
|
||||
@ -33,19 +34,12 @@
|
||||
android:hint="@string/account_setup_incoming_username_label"
|
||||
android:inputType="textEmailAddress"
|
||||
android:imeOptions="actionNext" />
|
||||
<TextView
|
||||
android:text="@string/account_setup_incoming_password_label"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/authentication_container"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
<EditText
|
||||
android:id="@+id/account_password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:hint="@string/account_setup_incoming_password_label"
|
||||
android:inputType="textPassword"
|
||||
android:imeOptions="actionNext" />
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- This text may be changed in code if the server is IMAP, etc. -->
|
||||
<TextView
|
||||
android:id="@+id/account_server_label"
|
||||
@ -87,10 +81,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:contentDescription="@string/account_setup_incoming_security_label" />
|
||||
<include
|
||||
android:id="@+id/client_certificate_selector"
|
||||
layout="@layout/client_certificate_selector"
|
||||
android:visibility="gone" />
|
||||
<TextView
|
||||
android:id="@+id/account_delete_policy_label"
|
||||
android:text="@string/account_setup_incoming_delete_policy_label"
|
||||
@ -103,6 +93,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:contentDescription="@string/account_setup_incoming_delete_policy_label" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/imap_path_prefix_section"
|
||||
android:layout_width="match_parent"
|
||||
@ -122,22 +113,4 @@
|
||||
android:inputType="text"
|
||||
android:imeOptions="actionDone" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/device_id_section"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:text="@string/account_setup_exchange_device_id_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
<TextView
|
||||
android:id="@+id/device_id"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#ffbebebe" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
180
res/layout/authentication_fragment.xml
Normal file
180
res/layout/authentication_fragment.xml
Normal file
@ -0,0 +1,180 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/imap_authentication"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/authentication_label"
|
||||
android:text="@string/authenticiation_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/authentication_selection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/add_authentication"
|
||||
android:contentDescription="@string/clear_authentication_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:clickable="true"
|
||||
android:src="@drawable/ic_add_authentication"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add_authentication_label"
|
||||
android:text="@string/add_authentication_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_toRightOf="@id/add_authentication"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/imap_password_selection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/account_setup_basics_password_label"
|
||||
android:text="@string/account_setup_basics_password_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/imap_account_password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_toRightOf="@id/account_setup_basics_password_label"
|
||||
android:layout_toLeftOf="@+id/clear_password"
|
||||
android:hint="@string/account_setup_incoming_password_label"
|
||||
android:inputType="textPassword"
|
||||
android:imeOptions="actionNext"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/clear_password"
|
||||
android:contentDescription="@string/clear_authentication_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:clickable="true"
|
||||
android:src="@drawable/ic_clear_authentication"
|
||||
android:layout_centerVertical="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/oauth_selection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/signed_in_with_service_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_toLeftOf="@+id/clear_oauth"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_centerVertical="true" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/clear_oauth"
|
||||
android:contentDescription="@string/clear_authentication_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:clickable="true"
|
||||
android:src="@drawable/ic_clear_authentication"
|
||||
android:layout_centerVertical="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/standard_password_selection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/account_setup_incoming_password_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/account_password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:hint="@string/account_setup_incoming_password_label"
|
||||
android:inputType="textPassword"
|
||||
android:imeOptions="actionNext" />
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/client_certificate_selector"
|
||||
layout="@layout/client_certificate_selector"
|
||||
android:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/device_id_section"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:text="@string/account_setup_exchange_device_id_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/device_id"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#ffbebebe" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
37
res/layout/password_selector.xml
Normal file
37
res/layout/password_selector.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/account_setup_incoming_password_label"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
<EditText
|
||||
android:id="@+id/account_password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:hint="@string/account_setup_incoming_password_label"
|
||||
android:inputType="textPassword"
|
||||
android:imeOptions="actionNext" />
|
||||
|
||||
</LinearLayout>
|
@ -30,6 +30,7 @@
|
||||
<attr name="defaultSsl" format="boolean"/>
|
||||
<attr name="offerTls" format="boolean"/>
|
||||
<attr name="offerCerts" format="boolean"/>
|
||||
<attr name="offerOAuth" format="boolean"/>
|
||||
<attr name="offerLocalDeletes" format="boolean"/>
|
||||
<attr name="defaultLocalDeletes" format="integer"/>
|
||||
<attr name="offerPrefix" format="boolean"/>
|
||||
|
@ -202,6 +202,14 @@
|
||||
<string name="account_setup_basics_email_label">Email address</string>
|
||||
<!-- On "Set up email" screen, hint for account email password text field -->
|
||||
<string name="account_setup_basics_password_label">Password</string>
|
||||
<!-- On the "Setup up email" screen, label indicating what service we are signed in with [CHAR LIMIT=40] -->
|
||||
<string name="signed_in_with_service_label">Signed in with %s</string>
|
||||
<!-- Label for the authentication section [CHAR LIMIT=20] -->
|
||||
<string name="authenticiation_label">Authentication</string>
|
||||
<!-- Label for the add authentication icon [CHAR LIMIT=40] -->
|
||||
<string name="add_authentication_label">Add authentication</string>
|
||||
<!-- Label for the add authentication icon [CHAR LIMIT=40] -->
|
||||
<string name="clear_authentication_label">Clear authentication</string>
|
||||
<!-- Button name on "Set up email" screen [CHAR LIMIT=20] -->
|
||||
<string name="account_setup_basics_manual_setup_action">Manual setup</string>
|
||||
<!-- Do not translate. Button name on "Set up email" screen [CHAR LIMIT=20] TODO: This is a temporary workaround
|
||||
|
@ -33,6 +33,7 @@
|
||||
The following optional attributes default to "false":
|
||||
offerTls: whether a TLS option (e.g. STARTTLS) is offered for this service
|
||||
offerCerts: whether or not certificate authentication is an option for this service
|
||||
offerOAuth: whether or not OAuth authentication is an option for this service
|
||||
usesSmtp: whether SMTP is used as the outgoing protocol for this service
|
||||
offerPrefix: whether a "prefix" is offered to the user (for IMAP)
|
||||
offerLocalDeletes: whether an option to delete locally is offered
|
||||
@ -83,6 +84,7 @@
|
||||
email:offerPrefix="true"
|
||||
email:syncChanges="true"
|
||||
email:inferPrefix="imap"
|
||||
email:offerOAuth="true"
|
||||
email:offerLoadMore="true"
|
||||
email:offerMoveTo="true"
|
||||
/>
|
||||
|
@ -388,6 +388,7 @@ public class AccountSettings extends PreferenceActivity implements FeedbackEnabl
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
|
||||
private void launchMailboxSettings(Intent intent) {
|
||||
final Folder folder = intent.getParcelableExtra(EditSettingsExtras.EXTRA_FOLDER);
|
||||
|
||||
@ -402,7 +403,6 @@ public class AccountSettings extends PreferenceActivity implements FeedbackEnabl
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
private void enableDebugMenu() {
|
||||
mShowDebugMenu = true;
|
||||
invalidateHeaders();
|
||||
|
@ -17,6 +17,9 @@
|
||||
package com.android.email.activity.setup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
@ -37,6 +40,7 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.activity.UiUtilities;
|
||||
import com.android.email.activity.setup.AuthenticationFragment.AuthenticationCallback;
|
||||
import com.android.email.provider.AccountBackupRestore;
|
||||
import com.android.email.service.EmailServiceUtils;
|
||||
import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
|
||||
@ -61,14 +65,14 @@ import java.util.ArrayList;
|
||||
* (for editing existing accounts).
|
||||
*/
|
||||
public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
implements HostCallback {
|
||||
implements HostCallback, AuthenticationCallback {
|
||||
|
||||
private static final int CERTIFICATE_REQUEST = 0;
|
||||
private final static String STATE_KEY_CREDENTIAL = "AccountSetupIncomingFragment.credential";
|
||||
private final static String STATE_KEY_LOADED = "AccountSetupIncomingFragment.loaded";
|
||||
|
||||
private EditText mUsernameView;
|
||||
private EditText mPasswordView;
|
||||
private AuthenticationFragment mAuthenticationFragment;
|
||||
private TextView mServerLabelView;
|
||||
private EditText mServerView;
|
||||
private EditText mPortView;
|
||||
@ -76,9 +80,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
private TextView mDeletePolicyLabelView;
|
||||
private Spinner mDeletePolicyView;
|
||||
private View mImapPathPrefixSectionView;
|
||||
private View mDeviceIdSectionView;
|
||||
private EditText mImapPathPrefixView;
|
||||
private CertificateSelector mClientCertificateSelector;
|
||||
// Delete policy as loaded from the device
|
||||
private int mLoadedDeletePolicy;
|
||||
|
||||
@ -123,7 +125,6 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
final View view = inflater.inflate(layoutId, container, false);
|
||||
|
||||
mUsernameView = UiUtilities.getView(view, R.id.account_username);
|
||||
mPasswordView = UiUtilities.getView(view, R.id.account_password);
|
||||
mServerLabelView = UiUtilities.getView(view, R.id.account_server_label);
|
||||
mServerView = UiUtilities.getView(view, R.id.account_server);
|
||||
mPortView = UiUtilities.getView(view, R.id.account_port);
|
||||
@ -131,9 +132,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
mDeletePolicyLabelView = UiUtilities.getView(view, R.id.account_delete_policy_label);
|
||||
mDeletePolicyView = UiUtilities.getView(view, R.id.account_delete_policy);
|
||||
mImapPathPrefixSectionView = UiUtilities.getView(view, R.id.imap_path_prefix_section);
|
||||
mDeviceIdSectionView = UiUtilities.getView(view, R.id.device_id_section);
|
||||
mImapPathPrefixView = UiUtilities.getView(view, R.id.imap_path_prefix);
|
||||
mClientCertificateSelector = UiUtilities.getView(view, R.id.client_certificate_selector);
|
||||
|
||||
// Updates the port when the user changes the security type. This allows
|
||||
// us to show a reasonable default which the user can change.
|
||||
@ -165,7 +164,6 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
getString(R.string.account_setup_username_uneditable_error));
|
||||
}
|
||||
mUsernameView.addTextChangedListener(mValidationTextWatcher);
|
||||
mPasswordView.addTextChangedListener(mValidationTextWatcher);
|
||||
mServerView.addTextChangedListener(mValidationTextWatcher);
|
||||
mPortView.addTextChangedListener(mValidationTextWatcher);
|
||||
|
||||
@ -175,6 +173,14 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
// Additional setup only used while in "settings" mode
|
||||
onCreateViewSettingsMode(view);
|
||||
|
||||
final FragmentManager fm = getFragmentManager();
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
mAuthenticationFragment = new AuthenticationFragment();
|
||||
ft.add(R.id.authentication_container, mAuthenticationFragment, "AuthenticationFragment");
|
||||
ft.commit();
|
||||
|
||||
mAuthenticationFragment.setAuthenticationCallback(this);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -184,14 +190,13 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
LogUtils.d(Logging.LOG_TAG, "AccountSetupIncomingFragment onActivityCreated");
|
||||
}
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mClientCertificateSelector.setHostActivity(this);
|
||||
|
||||
final Context context = getActivity();
|
||||
final SetupDataFragment.SetupDataContainer container =
|
||||
(SetupDataFragment.SetupDataContainer) context;
|
||||
mSetupData = container.getSetupData();
|
||||
|
||||
final HostAuth recvAuth = mSetupData.getAccount().mHostAuthRecv;
|
||||
final Account account = mSetupData.getAccount();
|
||||
final HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext);
|
||||
mServiceInfo = EmailServiceUtils.getServiceInfo(mContext, recvAuth.mProtocol);
|
||||
|
||||
if (mServiceInfo.offerLocalDeletes) {
|
||||
@ -286,14 +291,15 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
public void onDestroyView() {
|
||||
// Make sure we don't get callbacks after the views are supposed to be destroyed
|
||||
// and also don't hold onto them longer than we need
|
||||
final FragmentManager fm = getFragmentManager();
|
||||
final FragmentTransaction ft = fm.beginTransaction();
|
||||
ft.remove(mAuthenticationFragment);
|
||||
ft.commit();
|
||||
|
||||
if (mUsernameView != null) {
|
||||
mUsernameView.removeTextChangedListener(mValidationTextWatcher);
|
||||
}
|
||||
mUsernameView = null;
|
||||
if (mPasswordView != null) {
|
||||
mPasswordView.removeTextChangedListener(mValidationTextWatcher);
|
||||
}
|
||||
mPasswordView = null;
|
||||
mServerLabelView = null;
|
||||
if (mServerView != null) {
|
||||
mServerView.removeTextChangedListener(mValidationTextWatcher);
|
||||
@ -310,9 +316,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
mDeletePolicyLabelView = null;
|
||||
mDeletePolicyView = null;
|
||||
mImapPathPrefixSectionView = null;
|
||||
mDeviceIdSectionView = null;
|
||||
mImapPathPrefixView = null;
|
||||
mClientCertificateSelector = null;
|
||||
|
||||
super.onDestroyView();
|
||||
}
|
||||
@ -387,6 +391,8 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
|
||||
final Account account = mSetupData.getAccount();
|
||||
final HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext);
|
||||
mServiceInfo = EmailServiceUtils.getServiceInfo(mContext, recvAuth.mProtocol);
|
||||
mAuthenticationFragment.setAuthInfo(mServiceInfo, recvAuth);
|
||||
|
||||
final String username = recvAuth.mLogin;
|
||||
if (username != null) {
|
||||
@ -398,14 +404,6 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
//}
|
||||
mUsernameView.setText(username);
|
||||
}
|
||||
final String password = recvAuth.mPassword;
|
||||
if (password != null) {
|
||||
mPasswordView.setText(password);
|
||||
// Since username is uneditable, focus on the next editable field
|
||||
if (mSettingsMode) {
|
||||
mPasswordView.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
if (mServiceInfo.offerPrefix) {
|
||||
final String prefix = recvAuth.mDomain;
|
||||
@ -450,14 +448,11 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
private void validateFields() {
|
||||
if (!mLoaded) return;
|
||||
enableNextButton(!TextUtils.isEmpty(mUsernameView.getText())
|
||||
&& !TextUtils.isEmpty(mPasswordView.getText())
|
||||
&& mAuthenticationFragment.getAuthValid()
|
||||
&& Utility.isServerNameValid(mServerView)
|
||||
&& Utility.isPortFieldValid(mPortView));
|
||||
|
||||
mCacheLoginCredential = mUsernameView.getText().toString().trim();
|
||||
|
||||
// Warn (but don't prevent) if password has leading/trailing spaces
|
||||
AccountSettingsUtils.checkPasswordSpaces(mContext, mPasswordView);
|
||||
}
|
||||
|
||||
private int getPortFromSecurityType(boolean useSsl) {
|
||||
@ -473,20 +468,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
}
|
||||
|
||||
public void onUseSslChanged(boolean useSsl) {
|
||||
if (mServiceInfo.offerCerts) {
|
||||
final int mode = useSsl ? View.VISIBLE : View.GONE;
|
||||
mClientCertificateSelector.setVisibility(mode);
|
||||
String deviceId = "";
|
||||
try {
|
||||
deviceId = Device.getDeviceId(mContext);
|
||||
} catch (IOException e) {
|
||||
// Not required
|
||||
}
|
||||
((TextView) UiUtilities.getView(getView(), R.id.device_id)).setText(deviceId);
|
||||
|
||||
mDeviceIdSectionView.setVisibility(mode);
|
||||
//UiUtilities.setVisibilitySafe(getView(), R.id.client_certificate_divider, mode);
|
||||
}
|
||||
mAuthenticationFragment.onUseSslChanged(useSsl);
|
||||
}
|
||||
|
||||
private void updatePortFromSecurityType() {
|
||||
@ -545,7 +527,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
|
||||
final HostAuth recvAuth = account.getOrCreateHostAuthRecv(mContext);
|
||||
final String userName = mUsernameView.getText().toString().trim();
|
||||
final String userPassword = mPasswordView.getText().toString();
|
||||
final String userPassword = mAuthenticationFragment.getPassword().toString();
|
||||
recvAuth.setLogin(userName, userPassword);
|
||||
|
||||
final String serverAddress = mServerView.getText().toString().trim();
|
||||
@ -565,7 +547,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
} else {
|
||||
recvAuth.mDomain = null;
|
||||
}
|
||||
recvAuth.mClientCertAlias = mClientCertificateSelector.getCertificate();
|
||||
recvAuth.mClientCertAlias = mAuthenticationFragment.getClientCertificate();
|
||||
|
||||
mCallback.onProceedNext(SetupDataFragment.CHECK_INCOMING, this);
|
||||
clearButtonBounce();
|
||||
@ -605,12 +587,7 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == CERTIFICATE_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
final String certAlias = data.getStringExtra(CertificateRequestor.RESULT_ALIAS);
|
||||
if (certAlias != null) {
|
||||
mClientCertificateSelector.setCertificate(certAlias);
|
||||
}
|
||||
}
|
||||
public void onValidateStateChanged() {
|
||||
validateFields();
|
||||
}
|
||||
}
|
||||
|
294
src/com/android/email/activity/setup/AuthenticationFragment.java
Normal file
294
src/com/android/email/activity/setup/AuthenticationFragment.java
Normal file
@ -0,0 +1,294 @@
|
||||
package com.android.email.activity.setup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.activity.UiUtilities;
|
||||
import com.android.email.service.EmailServiceUtils;
|
||||
import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
|
||||
import com.android.email.view.CertificateSelector;
|
||||
import com.android.email.view.CertificateSelector.HostCallback;
|
||||
import com.android.email2.ui.MailActivityEmail;
|
||||
import com.android.emailcommon.Device;
|
||||
import com.android.emailcommon.Logging;
|
||||
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 com.android.mail.utils.LogUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
// FLAG:
|
||||
// * need to handle clicking on this to clear the auth info.
|
||||
// * need to handle getting oauth tokens
|
||||
// * need to handle switching from password to oauth and vice versa
|
||||
|
||||
public class AuthenticationFragment extends Fragment implements HostCallback {
|
||||
|
||||
private static final int CERTIFICATE_REQUEST = 0;
|
||||
|
||||
// Views
|
||||
private View mImapAuthenticationView;
|
||||
private View mImapPasswordContainer;
|
||||
private EditText mImapPasswordView;
|
||||
private View mImapOAuthContainer;
|
||||
private TextView mImapOAuthView;
|
||||
private View mImapAddAuthenticationView;
|
||||
private View mPasswordContainer;
|
||||
private EditText mPasswordView;
|
||||
private CertificateSelector mClientCertificateSelector;
|
||||
private View mDeviceIdSectionView;
|
||||
private boolean mViewInitialized;
|
||||
|
||||
// Watcher
|
||||
private TextWatcher mValidationTextWatcher;
|
||||
|
||||
private HostAuth mHostAuth;
|
||||
private EmailServiceInfo mServiceInfo;
|
||||
|
||||
private boolean mUseOAuth;
|
||||
private String mPassword;
|
||||
private String mOAuthProvider;
|
||||
private String mOAuthAccessToken;
|
||||
private String mOAuthRefreshToken;
|
||||
|
||||
|
||||
private boolean mAuthenticationValid;
|
||||
private AuthenticationCallback mAuthenticationCallback;
|
||||
|
||||
public interface AuthenticationCallback {
|
||||
public void onValidateStateChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mViewInitialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mClientCertificateSelector.setHostActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final View view = inflater.inflate(R.layout.authentication_fragment, container, false);
|
||||
mImapAuthenticationView = UiUtilities.getView(view, R.id.imap_authentication);
|
||||
mImapPasswordContainer = UiUtilities.getView(view, R.id.imap_password_selection);
|
||||
mImapPasswordView = UiUtilities.getView(view, R.id.imap_account_password);
|
||||
mImapOAuthContainer = UiUtilities.getView(view, R.id.oauth_selection);
|
||||
mImapOAuthView = UiUtilities.getView(view, R.id.signed_in_with_service_label);
|
||||
mImapAddAuthenticationView = UiUtilities.getView(view, R.id.authentication_selection);
|
||||
mPasswordContainer = UiUtilities.getView(view, R.id.standard_password_selection);
|
||||
mPasswordView = UiUtilities.getView(view, R.id.account_password);
|
||||
mClientCertificateSelector = UiUtilities.getView(view, R.id.client_certificate_selector);
|
||||
mDeviceIdSectionView = UiUtilities.getView(view, R.id.device_id_section);
|
||||
|
||||
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);
|
||||
mViewInitialized = true;
|
||||
if (mHostAuth != null) {
|
||||
loadInfo();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
public void setAuthenticationCallback(final AuthenticationCallback host) {
|
||||
mAuthenticationCallback = host;
|
||||
}
|
||||
|
||||
public boolean getAuthValid() {
|
||||
if (mServiceInfo == null || !mViewInitialized) {
|
||||
// XXX this is kind of weird. We can get called in onStart() of our
|
||||
// parent fragment, when we're still totally uninitialized.
|
||||
// Once we get initialized, we need to call back to allow our parent
|
||||
// to know what our state is.
|
||||
return false;
|
||||
}
|
||||
if (mServiceInfo.offerOAuth) {
|
||||
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(getActivity(), getPasswordEditText());
|
||||
}
|
||||
|
||||
private EditText getPasswordEditText() {
|
||||
if (mServiceInfo.offerOAuth) {
|
||||
return mImapPasswordView;
|
||||
} else {
|
||||
return mPasswordView;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAuthInfo(final EmailServiceInfo serviceInfo, final HostAuth hostAuth) {
|
||||
mServiceInfo = serviceInfo;
|
||||
mHostAuth = hostAuth;
|
||||
|
||||
if (mViewInitialized) {
|
||||
loadInfo();
|
||||
validateFields();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadInfo() {
|
||||
mServiceInfo = EmailServiceUtils.getServiceInfo(getActivity(), mHostAuth.mProtocol);
|
||||
|
||||
mClientCertificateSelector.setVisibility(
|
||||
mServiceInfo.offerCerts ? View.VISIBLE : View.GONE);
|
||||
|
||||
mImapPasswordView.setText(null);
|
||||
mPasswordView.setText(null);
|
||||
if (mServiceInfo.offerOAuth) {
|
||||
mPasswordContainer.setVisibility(View.GONE);
|
||||
mImapAuthenticationView.setVisibility(View.VISIBLE);
|
||||
|
||||
final Credential cred = mHostAuth.getCredential(getActivity());
|
||||
if (cred != null) {
|
||||
// We're authenticated with OAuth.
|
||||
mUseOAuth = true;
|
||||
mOAuthProvider = cred.mProviderId;
|
||||
mOAuthAccessToken = cred.mAccessToken;
|
||||
mOAuthRefreshToken = cred.mRefreshToken;
|
||||
|
||||
final OAuthProvider provider = AccountSettingsUtils.findOAuthProvider(
|
||||
getActivity(), cred.mProviderId);
|
||||
mImapPasswordContainer.setVisibility(View.GONE);
|
||||
mImapOAuthContainer.setVisibility(View.VISIBLE);
|
||||
mImapAddAuthenticationView.setVisibility(View.GONE);
|
||||
mImapOAuthView.setText(getString(R.string.signed_in_with_service_label,
|
||||
provider.label));
|
||||
// } else if (!TextUtils.isEmpty(hostAuth.mPassword)) {
|
||||
} else {
|
||||
// We're authenticated with a password.
|
||||
mUseOAuth = false;
|
||||
mPassword = mHostAuth.mPassword;
|
||||
|
||||
// XXX need to handle clicking on this to clear the password.
|
||||
mImapPasswordContainer.setVisibility(View.VISIBLE);
|
||||
mImapPasswordView.setText(mHostAuth.mPassword);
|
||||
mImapOAuthContainer.setVisibility(View.GONE);
|
||||
mImapAddAuthenticationView.setVisibility(View.GONE);
|
||||
/* } else {
|
||||
* XXX Allow us to choose what type of authentication when the password is unset.
|
||||
// We have no authentication, we need to allow either password or oauth.
|
||||
mUseOAuth = false;
|
||||
mPassword = null;
|
||||
|
||||
// XXX need to handle clicking on this to go to the add auth fragment.
|
||||
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.
|
||||
mUseOAuth = false;
|
||||
mPassword = mHostAuth.mPassword;
|
||||
|
||||
mImapAuthenticationView.setVisibility(View.GONE);
|
||||
mPasswordContainer.setVisibility(View.VISIBLE);
|
||||
mPasswordView.setVisibility(View.VISIBLE);
|
||||
mPasswordView.setText(mHostAuth.mPassword);
|
||||
if (TextUtils.isEmpty(mHostAuth.mPassword)) {
|
||||
mPasswordView.requestFocus();
|
||||
}
|
||||
}
|
||||
validateFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
if (Logging.DEBUG_LIFECYCLE && MailActivityEmail.DEBUG) {
|
||||
LogUtils.d(Logging.LOG_TAG, "AuthenticationFragment onSaveInstanceState");
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCertificateRequested() {
|
||||
final Intent intent = new Intent(CertificateRequestor.ACTION_REQUEST_CERT);
|
||||
intent.setData(Uri.parse("eas://com.android.emailcommon/certrequest"));
|
||||
startActivityForResult(intent, CERTIFICATE_REQUEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == CERTIFICATE_REQUEST && resultCode == Activity.RESULT_OK) {
|
||||
final String certAlias = data.getStringExtra(CertificateRequestor.RESULT_ALIAS);
|
||||
if (certAlias != null) {
|
||||
mClientCertificateSelector.setCertificate(certAlias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void onUseSslChanged(boolean useSsl) {
|
||||
if (mServiceInfo.offerCerts) {
|
||||
final int mode = useSsl ? View.VISIBLE : View.GONE;
|
||||
mClientCertificateSelector.setVisibility(mode);
|
||||
String deviceId = "";
|
||||
try {
|
||||
deviceId = Device.getDeviceId(getActivity());
|
||||
} catch (IOException e) {
|
||||
// Not required
|
||||
}
|
||||
((TextView) UiUtilities.getView(getView(), R.id.device_id)).setText(deviceId);
|
||||
mDeviceIdSectionView.setVisibility(mode);
|
||||
}
|
||||
}
|
||||
}
|
@ -185,6 +185,7 @@ public class EmailServiceUtils {
|
||||
public boolean defaultSsl;
|
||||
public boolean offerTls;
|
||||
public boolean offerCerts;
|
||||
public boolean offerOAuth;
|
||||
public boolean usesSmtp;
|
||||
public boolean offerLocalDeletes;
|
||||
public int defaultLocalDeletes;
|
||||
@ -544,6 +545,8 @@ public class EmailServiceUtils {
|
||||
info.offerTls = ta.getBoolean(R.styleable.EmailServiceInfo_offerTls, false);
|
||||
info.offerCerts =
|
||||
ta.getBoolean(R.styleable.EmailServiceInfo_offerCerts, false);
|
||||
info.offerOAuth =
|
||||
ta.getBoolean(R.styleable.EmailServiceInfo_offerOAuth, false);
|
||||
info.offerLocalDeletes =
|
||||
ta.getBoolean(R.styleable.EmailServiceInfo_offerLocalDeletes, false);
|
||||
info.defaultLocalDeletes =
|
||||
|
Loading…
Reference in New Issue
Block a user