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