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