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