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