AccountSetupNames.java revision 8bcb572ccfdac6974c111fe6dfc753a5e0d4e7ca
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.Welcome; 23import com.android.email.provider.EmailContent.Account; 24import com.android.email.provider.EmailContent.AccountColumns; 25import com.android.email.provider.EmailContent.HostAuth; 26 27import android.app.Activity; 28import android.content.ContentValues; 29import android.content.Intent; 30import android.os.AsyncTask; 31import android.os.Bundle; 32import android.text.Editable; 33import android.text.TextWatcher; 34import android.text.method.TextKeyListener; 35import android.text.method.TextKeyListener.Capitalize; 36import android.view.Menu; 37import android.view.MenuItem; 38import android.view.View; 39import android.widget.EditText; 40 41public class AccountSetupNames extends AccountSetupActivity { 42 private static final int REQUEST_SECURITY = 0; 43 44 private EditText mDescription; 45 private EditText mName; 46 private boolean mEasAccount = false; 47 private boolean mNextButtonEnabled; 48 49 private CheckAccountStateTask mCheckAccountStateTask; 50 51 public static void actionSetNames(Activity fromActivity) { 52 fromActivity.startActivity(new Intent(fromActivity, AccountSetupNames.class)); 53 } 54 55 @Override 56 public void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.account_setup_names); 59 mDescription = (EditText)findViewById(R.id.account_description); 60 mName = (EditText)findViewById(R.id.account_name); 61 62 TextWatcher validationTextWatcher = new TextWatcher() { 63 public void afterTextChanged(Editable s) { 64 validateFields(); 65 } 66 67 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 68 } 69 70 public void onTextChanged(CharSequence s, int start, int before, int count) { 71 } 72 }; 73 mName.addTextChangedListener(validationTextWatcher); 74 mName.setKeyListener(TextKeyListener.getInstance(false, Capitalize.WORDS)); 75 76 Account account = SetupData.getAccount(); 77 // Shouldn't happen, but it could 78 if (account == null) { 79 onBackPressed(); 80 return; 81 } 82 // Get the hostAuth for receiving 83 HostAuth hostAuth = HostAuth.restoreHostAuthWithId(this, account.mHostAuthKeyRecv); 84 if (hostAuth == null) { 85 onBackPressed(); 86 return; 87 } 88 89 // Remember whether we're an EAS account, since it doesn't require the user name field 90 mEasAccount = hostAuth.mProtocol.equals("eas"); 91 if (mEasAccount) { 92 mName.setVisibility(View.GONE); 93 findViewById(R.id.account_name_label).setVisibility(View.GONE); 94 } 95 /* 96 * Since this field is considered optional, we don't set this here. If 97 * the user fills in a value we'll reset the current value, otherwise we 98 * just leave the saved value alone. 99 */ 100 // mDescription.setText(mAccount.getDescription()); 101 if (account != null && account.getSenderName() != null) { 102 mName.setText(account.getSenderName()); 103 } 104 105 // Make sure the "done" button is in the proper state 106 validateFields(); 107 } 108 109 @Override 110 protected void onDestroy() { 111 super.onDestroy(); 112 113 if (mCheckAccountStateTask != null && 114 mCheckAccountStateTask.getStatus() != CheckAccountStateTask.Status.FINISHED) { 115 mCheckAccountStateTask.cancel(true); 116 mCheckAccountStateTask = null; 117 } 118 } 119 120 /** 121 * Add "Next" button when this activity is displayed 122 */ 123 @Override 124 public boolean onCreateOptionsMenu(Menu menu) { 125 getMenuInflater().inflate(R.menu.account_setup_next_option, menu); 126 return super.onCreateOptionsMenu(menu); 127 } 128 129 /** 130 * Enable/disable "Next" button 131 */ 132 @Override 133 public boolean onPrepareOptionsMenu(Menu menu) { 134 menu.findItem(R.id.next).setEnabled(mNextButtonEnabled); 135 return super.onPrepareOptionsMenu(menu); 136 } 137 138 /** 139 * Respond to clicks in the "Next" button 140 */ 141 @Override 142 public boolean onOptionsItemSelected(MenuItem item) { 143 switch (item.getItemId()) { 144 case R.id.next: 145 onNext(); 146 return true; 147 } 148 return super.onOptionsItemSelected(item); 149 } 150 151 /** 152 * TODO: Validator should also trim the name string before checking it. 153 */ 154 private void validateFields() { 155 boolean newEnabled = !mEasAccount || Utility.isTextViewNotEmpty(mName); 156 if (newEnabled != mNextButtonEnabled) { 157 mNextButtonEnabled = newEnabled; 158 invalidateOptionsMenu(); 159 } 160 } 161 162 @Override 163 public void onBackPressed() { 164 if (SetupData.getFlowMode() != SetupData.FLOW_MODE_NORMAL) { 165 AccountSetupBasics.actionAccountCreateFinishedAccountFlow(this); 166 } else { 167 Account account = SetupData.getAccount(); 168 if (account != null) { 169 AccountSetupBasics.actionAccountCreateFinished(this, account.mId); 170 } else { 171 // Safety check here; If mAccount is null (due to external issues or bugs) 172 // just rewind back to Welcome, which can handle any configuration of accounts 173 Welcome.actionStart(this); 174 } 175 } 176 finish(); 177 } 178 179 /** 180 * After having a chance to input the display names, we normally jump directly to the 181 * inbox for the new account. However if we're in EAS flow mode (externally-launched 182 * account creation) we simply "pop" here which should return us to the Accounts activities. 183 * 184 * TODO: Validator should also trim the description string before checking it. 185 */ 186 private void onNext() { 187 Account account = SetupData.getAccount(); 188 if (Utility.isTextViewNotEmpty(mDescription)) { 189 account.setDisplayName(mDescription.getText().toString()); 190 } 191 String name = mName.getText().toString(); 192 account.setSenderName(name); 193 ContentValues cv = new ContentValues(); 194 cv.put(AccountColumns.DISPLAY_NAME, account.getDisplayName()); 195 cv.put(AccountColumns.SENDER_NAME, name); 196 account.update(this, cv); 197 // Update the backup (side copy) of the accounts 198 AccountBackupRestore.backupAccounts(this); 199 200 // Before proceeding, launch an AsyncTask to test the account for any syncing problems, 201 // and if there's a problem, bring up the UI to update the security level. 202 mCheckAccountStateTask = new CheckAccountStateTask(account.mId); 203 mCheckAccountStateTask.execute(); 204 } 205 206 /** 207 * This async task is launched just before exiting. It's a last chance test, before leaving 208 * this activity, for the account being in a "hold" state, and gives the user a chance to 209 * update security, enter a device PIN, etc. for a more seamless account setup experience. 210 * 211 * TODO: If there was *any* indication that security might be required, we could at least 212 * force the DeviceAdmin activation step, without waiting for the initial sync/handshake 213 * to fail. 214 * TODO: If the user doesn't update the security, don't go to the MessageList. 215 */ 216 private class CheckAccountStateTask extends AsyncTask<Void, Void, Boolean> { 217 218 private long mAccountId; 219 220 public CheckAccountStateTask(long accountId) { 221 mAccountId = accountId; 222 } 223 224 @Override 225 protected Boolean doInBackground(Void... params) { 226 return Account.isSecurityHold(AccountSetupNames.this, mAccountId); 227 } 228 229 @Override 230 protected void onPostExecute(Boolean isSecurityHold) { 231 if (!isCancelled()) { 232 if (isSecurityHold) { 233 Intent i = AccountSecurity.actionUpdateSecurityIntent( 234 AccountSetupNames.this, mAccountId); 235 AccountSetupNames.this.startActivityForResult(i, REQUEST_SECURITY); 236 } else { 237 onBackPressed(); 238 } 239 } 240 } 241 } 242 243 /** 244 * Handle the eventual result from the security update activity 245 * 246 * TODO: If the user doesn't update the security, don't go to the MessageList. 247 */ 248 @Override 249 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 250 switch (requestCode) { 251 case REQUEST_SECURITY: 252 onBackPressed(); 253 } 254 super.onActivityResult(requestCode, resultCode, data); 255 } 256 257} 258