Merge "Split AccountSetupBasics into Activity and Fragment" into ub-mail-master

This commit is contained in:
Tony Mantler 2014-01-09 21:51:07 +00:00 committed by Android (Google) Code Review
commit f8b253d564
7 changed files with 161 additions and 109 deletions

View File

@ -21,7 +21,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/setup_padding_top"
android:paddingLeft="@dimen/setup_padding_left"
android:paddingRight="@dimen/setup_padding_right"
@ -80,9 +80,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<include
layout="@layout/account_setup_basics_common"
/>
<fragment
android:id="@+id/basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
</RelativeLayout>
</ScrollView>

View File

@ -32,7 +32,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
>
@ -63,9 +63,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<include
layout="@layout/account_setup_basics_common"
/>
<fragment
android:id="@+id/basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
</RelativeLayout>

View File

@ -22,7 +22,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/setup_fragment_padding_top"
android:paddingLeft="@dimen/setup_fragment_padding_left"
android:paddingRight="@dimen/setup_fragment_padding_right"
@ -32,16 +32,16 @@
<!-- TODO need phone-sized UX here -->
<FrameLayout
android:id="@+id/common"
android:layout_below="@+id/top_divider"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
>
<include
layout="@layout/account_setup_basics_common"
/>
<fragment
android:id="@+id/basics_fragment"
class="com.android.email.activity.setup.AccountSetupBasicsFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
<!-- Buttons below -->

View File

@ -33,20 +33,14 @@ import android.content.Loader;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.provider.ContactsContract;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.format.DateUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.email.EmailAddressValidator;
import com.android.email.R;
import com.android.email.activity.ActivityHelper;
import com.android.email.activity.UiUtilities;
@ -91,7 +85,7 @@ import java.net.URISyntaxException;
* Note: Exchange accounts that require device security policies cannot be created automatically.
*/
public class AccountSetupBasics extends AccountSetupActivity
implements OnClickListener, TextWatcher, AccountCheckSettingsFragment.Callbacks {
implements OnClickListener, AccountCheckSettingsFragment.Callbacks {
// Set to false before shipping, logs PII
private final static boolean ENTER_DEBUG_SCREEN = false;
@ -122,9 +116,6 @@ public class AccountSetupBasics extends AccountSetupActivity
public static final String EXTRA_OAUTH_EXPIRES_IN = "expiresIn";
// Support for UI
private EditText mEmailView;
private EditText mPasswordView;
private final EmailAddressValidator mEmailValidator = new EmailAddressValidator();
private Provider mProvider;
private Button mManualButton;
// TODO: This is a temporary hack to allow us to start testing OAuth flow. It should be
@ -152,17 +143,25 @@ public class AccountSetupBasics extends AccountSetupActivity
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_OAUTH && resultCode == RESULT_OAUTH_SUCCESS) {
final String accessToken = data.getStringExtra(EXTRA_OAUTH_ACCESS_TOKEN);
final String refreshToken = data.getStringExtra(EXTRA_OAUTH_REFRESH_TOKEN);
final int expiresInSeconds = data.getIntExtra(EXTRA_OAUTH_EXPIRES_IN, 0);
if (requestCode == REQUEST_OAUTH) {
if (resultCode == RESULT_OAUTH_SUCCESS) {
final String accessToken = data.getStringExtra(EXTRA_OAUTH_ACCESS_TOKEN);
final String refreshToken = data.getStringExtra(EXTRA_OAUTH_REFRESH_TOKEN);
final int expiresInSeconds = data.getIntExtra(EXTRA_OAUTH_EXPIRES_IN, 0);
finishOAuthSetup(accessToken, refreshToken, expiresInSeconds);
finishOAuthSetup(accessToken, refreshToken, expiresInSeconds);
} else if (resultCode == RESULT_OAUTH_FAILURE
|| resultCode == RESULT_OAUTH_USER_CANCELED) {
// TODO: STOPSHIP: This setup UI is not correct, we need to figure out what to do
// in case of errors and have localized strings.
Toast.makeText(AccountSetupBasics.this,
"Failed to get token", Toast.LENGTH_LONG).show();
} else {
LogUtils.wtf(Logging.LOG_TAG, "Unknown result code from OAUTH: %d", resultCode);
}
} else {
// TODO: STOPSHIP: This setup UI is not correct, we need to figure out what to do
// in case of errors and have localized strings.
Toast.makeText(AccountSetupBasics.this,
"Failed to get token", Toast.LENGTH_LONG).show();
LogUtils.e(Logging.LOG_TAG, "Unknown request code for onActivityResult in"
+ " AccountSetupBasics: %d", requestCode);
}
}
@ -178,10 +177,6 @@ public class AccountSetupBasics extends AccountSetupActivity
}
public static void actionAccountCreateFinishedAccountFlow(Activity fromActivity) {
// TODO: handle this case - modifying state on SetupData when instantiating an Intent
// is not safe, since it's not guaranteed that an Activity will run with the Intent, and
// information can get lost.
final Intent i= new ForwardingIntent(fromActivity, AccountSetupBasics.class);
// If we're in the "account flow" (from AccountManager), we want to return to the caller
// (in the settings app)
@ -192,10 +187,6 @@ public class AccountSetupBasics extends AccountSetupActivity
}
public static void actionAccountCreateFinishedWithResult(Activity fromActivity) {
// TODO: handle this case - modifying state on SetupData when instantiating an Intent
// is not safe, since it's not guaranteed that an Activity will run with the Intent, and
// information can get lost.
final Intent i= new ForwardingIntent(fromActivity, AccountSetupBasics.class);
// If we're in the "no accounts" flow, we want to return to the caller with a result
i.putExtra(SetupDataFragment.EXTRA_SETUP_DATA,
@ -264,11 +255,6 @@ public class AccountSetupBasics extends AccountSetupActivity
setContentView(R.layout.account_setup_basics);
mEmailView = UiUtilities.getView(this, R.id.account_email);
mPasswordView = UiUtilities.getView(this, R.id.account_password);
mEmailView.addTextChangedListener(this);
mPasswordView.addTextChangedListener(this);
// Configure buttons
mManualButton = UiUtilities.getView(this, R.id.manual_setup);
@ -279,8 +265,8 @@ public class AccountSetupBasics extends AccountSetupActivity
mOAuthButton.setOnClickListener(this);
mNextButton.setOnClickListener(this);
// Force disabled until validator notifies otherwise
onEnableProceedButtons(false);
mOAuthButton.setEnabled(false);
setProceedButtonsEnabled(false);
setOAuthButtonEnabled(false);
// Lightweight debounce while Async tasks underway
mNextButtonInhibit = false;
@ -297,18 +283,6 @@ public class AccountSetupBasics extends AccountSetupActivity
mReportAccountAuthenticatorError = true;
}
// Load fields, but only once
final String userName = mSetupData.getUsername();
if (userName != null) {
mEmailView.setText(userName);
mSetupData.setUsername(null);
}
final String password = mSetupData.getPassword();
if (userName != null) {
mPasswordView.setText(password);
mSetupData.setPassword(null);
}
// Handle force account creation immediately (now that fragment is set up)
// This is never allowed in a normal user build and will exit immediately.
if (mSetupData.getFlowMode() == SetupDataFragment.FLOW_MODE_FORCE_CREATE) {
@ -422,7 +396,7 @@ public class AccountSetupBasics extends AccountSetupActivity
// removed when the real account setup flow is implemented.
// TODO: Also note that this check reads and parses the xml file each time. This
// should probably get cached somewhere.
final String email = mEmailView.getText().toString().trim();
final String email = getBasicsFragment().getEmail();
final String[] emailParts = email.split("@");
final String domain = emailParts[1].trim();
Provider provider = AccountSettingsUtils.findProviderForDomain(this, domain);
@ -443,42 +417,6 @@ public class AccountSetupBasics extends AccountSetupActivity
}
}
/**
* Implements TextWatcher
*/
@Override
public void afterTextChanged(Editable s) {
validateFields();
}
/**
* Implements TextWatcher
*/
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/**
* Implements TextWatcher
*/
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
private void validateFields() {
final boolean validEmail = !TextUtils.isEmpty(mEmailView.getText())
&& mEmailValidator.isValid(mEmailView.getText().toString().trim());
mOAuthButton.setEnabled(validEmail);
final boolean valid = !TextUtils.isEmpty(mEmailView.getText())
&& !TextUtils.isEmpty(mPasswordView.getText())
&& mEmailValidator.isValid(mEmailView.getText().toString().trim());
onEnableProceedButtons(valid);
// Warn (but don't prevent) if password has leading/trailing spaces
AccountSettingsUtils.checkPasswordSpaces(this, mPasswordView);
}
/**
* Return an existing username if found, or null. This is the result of the Callable (below).
*/
@ -490,8 +428,9 @@ public class AccountSetupBasics extends AccountSetupActivity
* Finish the auto setup process, in some cases after showing a warning dialog.
*/
private void finishAutoSetup() {
final String email = mEmailView.getText().toString().trim();
final String password = mPasswordView.getText().toString();
final AccountSetupBasicsFragment basicsFragment = getBasicsFragment();
final String email = basicsFragment.getEmail();
final String password = basicsFragment.getPassword();
try {
mProvider.expandTemplates(email);
@ -534,7 +473,7 @@ public class AccountSetupBasics extends AccountSetupActivity
private void finishOAuthSetup(final String accessToken, final String refreshToken,
int expiresInSeconds) {
final String email = mEmailView.getText().toString().trim();
final String email = getBasicsFragment().getEmail();
final String[] emailParts = email.split("@");
final String domain = emailParts[1].trim();
mProvider = AccountSettingsUtils.findProviderForDomain(this, domain);
@ -654,7 +593,7 @@ public class AccountSetupBasics extends AccountSetupActivity
*/
private void onNext() {
// Try auto-configuration from XML providers (unless in EAS mode, we can skip it)
final String email = mEmailView.getText().toString().trim();
final String email = getBasicsFragment().getEmail();
final String[] emailParts = email.split("@");
final String domain = emailParts[1].trim();
mProvider = AccountSettingsUtils.findProviderForDomain(this, domain);
@ -682,8 +621,9 @@ public class AccountSetupBasics extends AccountSetupActivity
* Ignored for IMAP & POP accounts.
*/
private void onManualSetup(boolean allowAutoDiscover) {
final String email = mEmailView.getText().toString().trim();
final String password = mPasswordView.getText().toString();
final AccountSetupBasicsFragment basicsFragment = getBasicsFragment();
final String email = basicsFragment.getEmail();
final String password = basicsFragment.getPassword();
final String[] emailParts = email.split("@");
final String user = emailParts[0].trim();
final String domain = emailParts[1].trim();
@ -691,11 +631,13 @@ public class AccountSetupBasics extends AccountSetupActivity
// Alternate entry to the debug options screen (for devices without a physical keyboard:
// Username: d@d.d
// Password: debug
if (ENTER_DEBUG_SCREEN && "d@d.d".equals(email) && "debug".equals(password)) {
mEmailView.setText("");
mPasswordView.setText("");
AccountSettings.actionSettingsWithDebug(this);
return;
if (ENTER_DEBUG_SCREEN) {
if ("d@d.d".equals(email) && "debug".equals(password)) {
basicsFragment.setEmail("");
basicsFragment.setPassword("");
AccountSettings.actionSettingsWithDebug(this);
return;
}
}
final Account account = mSetupData.getAccount();
@ -790,7 +732,11 @@ public class AccountSetupBasics extends AccountSetupActivity
throw new IllegalStateException();
}
private void onEnableProceedButtons(boolean enabled) {
public void setOAuthButtonEnabled(boolean enabled) {
mOAuthButton.setEnabled(enabled);
}
public void setProceedButtonsEnabled(boolean enabled) {
mManualButton.setEnabled(enabled);
mNextButton.setEnabled(enabled);
}
@ -845,4 +791,9 @@ public class AccountSetupBasics extends AccountSetupActivity
.create();
}
}
private AccountSetupBasicsFragment getBasicsFragment() {
return (AccountSetupBasicsFragment)
getFragmentManager().findFragmentById(R.id.basics_fragment);
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2014 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.
*/
package com.android.email.activity.setup;
import android.app.Fragment;
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 com.android.email.R;
import com.android.email.activity.UiUtilities;
import com.android.emailcommon.mail.Address;
public class AccountSetupBasicsFragment extends Fragment {
private EditText mEmailView;
private EditText mPasswordView;
public AccountSetupBasicsFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.account_setup_basics_fragment, container, false);
mEmailView = UiUtilities.getView(view, R.id.account_email);
mPasswordView = UiUtilities.getView(view, R.id.account_password);
final TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
validateFields();
}
};
mEmailView.addTextChangedListener(textWatcher);
mPasswordView.addTextChangedListener(textWatcher);
return view;
}
private void validateFields() {
final AccountSetupBasics activity = (AccountSetupBasics) getActivity();
final String emailField = getEmail();
final Address[] addresses = Address.parse(emailField);
final boolean emailValid = !TextUtils.isEmpty(emailField)
&& addresses.length == 1
&& !TextUtils.isEmpty(addresses[0].getAddress());
activity.setOAuthButtonEnabled(emailValid);
activity.setProceedButtonsEnabled(emailValid && !TextUtils.isEmpty(getPassword()));
// Warn (but don't prevent) if password has leading/trailing spaces
AccountSettingsUtils.checkPasswordSpaces(activity, mPasswordView);
}
public void setEmail(final String email) {
mEmailView.setText(email);
}
public String getEmail() {
return mEmailView.getText().toString().trim();
}
public void setPassword(final String password) {
mPasswordView.setText(password);
}
public String getPassword() {
return mPasswordView.getText().toString().trim();
}
}