AccountSetupNames.java revision f4894131427ec7562fcb05388b9f3aa094e388bc
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email.activity.setup; 18 19import com.android.email.AccountBackupRestore; 20import com.android.email.R; 21import com.android.email.activity.ActivityHelper; 22import com.android.email.activity.Welcome; 23import com.android.emailcommon.provider.EmailContent.Account; 24import com.android.emailcommon.provider.EmailContent.AccountColumns; 25 26import android.app.Activity; 27import android.content.ContentValues; 28import android.content.Context; 29import android.content.Intent; 30import android.os.AsyncTask; 31import android.os.Bundle; 32import android.text.Editable; 33import android.text.TextUtils; 34import android.text.TextWatcher; 35import android.text.method.TextKeyListener; 36import android.text.method.TextKeyListener.Capitalize; 37import android.view.View; 38import android.view.View.OnClickListener; 39import android.widget.Button; 40import android.widget.EditText; 41 42/** 43 * Final screen of setup process. Collect account nickname and/or username. 44 */ 45public class AccountSetupNames extends AccountSetupActivity implements OnClickListener { 46 private static final int REQUEST_SECURITY = 0; 47 48 private EditText mDescription; 49 private EditText mName; 50 private Button mNextButton; 51 private boolean mNextPressed = false; 52 private boolean mEasAccount = false; 53 54 public static void actionSetNames(Activity fromActivity) { 55 fromActivity.startActivity(new Intent(fromActivity, AccountSetupNames.class)); 56 } 57 58 @Override 59 public void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 ActivityHelper.debugSetWindowFlags(this); 62 setContentView(R.layout.account_setup_names); 63 mDescription = (EditText) findViewById(R.id.account_description); 64 mName = (EditText) findViewById(R.id.account_name); 65 mNextButton = (Button) findViewById(R.id.next); 66 mNextButton.setOnClickListener(this); 67 68 TextWatcher validationTextWatcher = new TextWatcher() { 69 public void afterTextChanged(Editable s) { 70 validateFields(); 71 } 72 73 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 74 } 75 76 public void onTextChanged(CharSequence s, int start, int before, int count) { 77 } 78 }; 79 mName.addTextChangedListener(validationTextWatcher); 80 mName.setKeyListener(TextKeyListener.getInstance(false, Capitalize.WORDS)); 81 82 Account account = SetupData.getAccount(); 83 if (account == null) { 84 throw new IllegalStateException("unexpected null account"); 85 } 86 if (account.mHostAuthRecv == null) { 87 throw new IllegalStateException("unexpected null hostauth"); 88 } 89 90 // Remember whether we're an EAS account, since it doesn't require the user name field 91 mEasAccount = "eas".equals(account.mHostAuthRecv.mProtocol); 92 if (mEasAccount) { 93 mName.setVisibility(View.GONE); 94 findViewById(R.id.account_name_label).setVisibility(View.GONE); 95 } 96 /* 97 * Since this field is considered optional, we don't set this here. If 98 * the user fills in a value we'll reset the current value, otherwise we 99 * just leave the saved value alone. 100 */ 101 // mDescription.setText(mAccount.getDescription()); 102 if (account != null && account.getSenderName() != null) { 103 mName.setText(account.getSenderName()); 104 } 105 106 // Make sure the "done" button is in the proper state 107 validateFields(); 108 109 // Proceed immediately if in account creation mode 110 if (SetupData.getFlowMode() == SetupData.FLOW_MODE_FORCE_CREATE) { 111 onNext(); 112 } 113 } 114 115 /** 116 * Implements OnClickListener 117 */ 118 @Override 119 public void onClick(View v) { 120 switch (v.getId()) { 121 case R.id.next: 122 // Don't allow this more than once (we do some work in an async thread before 123 // finish()'ing the Activity, which allows this code to potentially be 124 // executed multiple times. 125 if (!mNextPressed) { 126 onNext(); 127 } 128 mNextPressed = true; 129 break; 130 } 131 } 132 133 /** 134 * Check input fields for legal values and enable/disable next button 135 */ 136 private void validateFields() { 137 boolean newEnabled = true; 138 // Validation is based only on the "user name" field, not shown for EAS accounts 139 if (!mEasAccount) { 140 String userName = mName.getText().toString().trim(); 141 newEnabled = !TextUtils.isEmpty(userName); 142 if (!newEnabled) { 143 mName.setError(getString(R.string.account_setup_names_user_name_empty_error)); 144 } 145 } 146 mNextButton.setEnabled(newEnabled); 147 } 148 149 /** 150 * Block the back key if we are currently processing the "next" key" 151 */ 152 @Override 153 public void onBackPressed() { 154 if (!mNextPressed) { 155 finishActivity(); 156 } 157 } 158 159 private void finishActivity() { 160 if (SetupData.getFlowMode() != SetupData.FLOW_MODE_NORMAL) { 161 AccountSetupBasics.actionAccountCreateFinishedAccountFlow(this); 162 } else { 163 Account account = SetupData.getAccount(); 164 if (account != null) { 165 AccountSetupBasics.actionAccountCreateFinished(this, account.mId); 166 } else { 167 // Safety check here; If mAccount is null (due to external issues or bugs) 168 // just rewind back to Welcome, which can handle any configuration of accounts 169 Welcome.actionStart(this); 170 } 171 } 172 finish(); 173 } 174 175 /** 176 * After clicking the next button, we'll start an async task to commit the data 177 * and other steps to finish the creation of the account. 178 */ 179 private void onNext() { 180 // Update account object from UI 181 Account account = SetupData.getAccount(); 182 String description = mDescription.getText().toString().trim(); 183 if (!TextUtils.isEmpty(description)) { 184 account.setDisplayName(description); 185 } 186 account.setSenderName(mName.getText().toString().trim()); 187 188 // Launch async task for final commit work 189 new FinalSetupTask(account).execute(); 190 } 191 192 /** 193 * Final account setup work is handled in this AsyncTask: 194 * Commit final values to provider 195 * Trigger account backup 196 * Check for security hold 197 * 198 * When this completes, we return to UI thread for the following steps: 199 * If security hold, dispatch to AccountSecurity activity 200 * Otherwise, return to AccountSetupBasics for conclusion. 201 * 202 * TODO: If there was *any* indication that security might be required, we could at least 203 * force the DeviceAdmin activation step, without waiting for the initial sync/handshake 204 * to fail. 205 * TODO: If the user doesn't update the security, don't go to the MessageList. 206 */ 207 private class FinalSetupTask extends AsyncTask<Void, Void, Boolean> { 208 209 private Account mAccount; 210 private Context mContext; 211 212 public FinalSetupTask(Account account) { 213 mAccount = account; 214 mContext = AccountSetupNames.this; 215 } 216 217 @Override 218 protected Boolean doInBackground(Void... params) { 219 // Update the account in the database 220 ContentValues cv = new ContentValues(); 221 cv.put(AccountColumns.DISPLAY_NAME, mAccount.getDisplayName()); 222 cv.put(AccountColumns.SENDER_NAME, mAccount.getSenderName()); 223 mAccount.update(mContext, cv); 224 225 // Update the backup (side copy) of the accounts 226 AccountBackupRestore.backupAccounts(AccountSetupNames.this); 227 228 return Account.isSecurityHold(mContext, mAccount.mId); 229 } 230 231 @Override 232 protected void onPostExecute(Boolean isSecurityHold) { 233 if (!isCancelled()) { 234 if (isSecurityHold) { 235 Intent i = AccountSecurity.actionUpdateSecurityIntent( 236 AccountSetupNames.this, mAccount.mId, false); 237 AccountSetupNames.this.startActivityForResult(i, REQUEST_SECURITY); 238 } else { 239 finishActivity(); 240 } 241 } 242 } 243 } 244 245 /** 246 * Handle the eventual result from the security update activity 247 * 248 * TODO: If the user doesn't update the security, don't go to the MessageList. 249 */ 250 @Override 251 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 252 switch (requestCode) { 253 case REQUEST_SECURITY: 254 finishActivity(); 255 } 256 super.onActivityResult(requestCode, resultCode, data); 257 } 258 259} 260