AccountSetupNames.java revision d71d0b223a5cd02e2a8f1ec5c3f8cebab170d65f
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.provider.EmailContent; 23import com.android.email.provider.EmailContent.Account; 24import com.android.email.provider.EmailContent.AccountColumns; 25 26import android.app.Activity; 27import android.content.ContentUris; 28import android.content.ContentValues; 29import android.content.Intent; 30import android.database.Cursor; 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 Activity implements OnClickListener { 43 private static final String EXTRA_ACCOUNT_ID = "accountId"; 44 private static final String EXTRA_EAS_FLOW = "easFlow"; 45 private static final int REQUEST_SECURITY = 0; 46 47 private EditText mDescription; 48 private EditText mName; 49 private Account mAccount; 50 private Button mDoneButton; 51 52 private CheckAccountStateTask mCheckAccountStateTask; 53 54 private static final int ACCOUNT_INFO_COLUMN_FLAGS = 0; 55 private static final int ACCOUNT_INFO_COLUMN_SECURITY_FLAGS = 1; 56 private static final String[] ACCOUNT_INFO_PROJECTION = new String[] { 57 AccountColumns.FLAGS, AccountColumns.SECURITY_FLAGS }; 58 59 public static void actionSetNames(Activity fromActivity, long accountId, boolean easFlowMode) { 60 Intent i = new Intent(fromActivity, AccountSetupNames.class); 61 i.putExtra(EXTRA_ACCOUNT_ID, accountId); 62 i.putExtra(EXTRA_EAS_FLOW, easFlowMode); 63 fromActivity.startActivity(i); 64 } 65 66 @Override 67 public void onCreate(Bundle savedInstanceState) { 68 super.onCreate(savedInstanceState); 69 setContentView(R.layout.account_setup_names); 70 mDescription = (EditText)findViewById(R.id.account_description); 71 mName = (EditText)findViewById(R.id.account_name); 72 mDoneButton = (Button)findViewById(R.id.done); 73 mDoneButton.setOnClickListener(this); 74 75 TextWatcher validationTextWatcher = new TextWatcher() { 76 public void afterTextChanged(Editable s) { 77 validateFields(); 78 } 79 80 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 81 } 82 83 public void onTextChanged(CharSequence s, int start, int before, int count) { 84 } 85 }; 86 mName.addTextChangedListener(validationTextWatcher); 87 88 mName.setKeyListener(TextKeyListener.getInstance(false, Capitalize.WORDS)); 89 90 long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); 91 mAccount = EmailContent.Account.restoreAccountWithId(this, accountId); 92 93 /* 94 * Since this field is considered optional, we don't set this here. If 95 * the user fills in a value we'll reset the current value, otherwise we 96 * just leave the saved value alone. 97 */ 98 // mDescription.setText(mAccount.getDescription()); 99 if (mAccount != null && mAccount.getSenderName() != null) { 100 mName.setText(mAccount.getSenderName()); 101 } 102 if (!Utility.requiredFieldValid(mName)) { 103 mDoneButton.setEnabled(false); 104 } 105 } 106 107 @Override 108 protected void onDestroy() { 109 super.onDestroy(); 110 111 if (mCheckAccountStateTask != null && 112 mCheckAccountStateTask.getStatus() != CheckAccountStateTask.Status.FINISHED) { 113 mCheckAccountStateTask.cancel(true); 114 mCheckAccountStateTask = null; 115 } 116 } 117 118 /** 119 * TODO: Validator should also trim the name string before checking it. 120 */ 121 private void validateFields() { 122 mDoneButton.setEnabled(Utility.requiredFieldValid(mName)); 123 Utility.setCompoundDrawablesAlpha(mDoneButton, mDoneButton.isEnabled() ? 255 : 128); 124 } 125 126 @Override 127 public void onBackPressed() { 128 boolean easFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false); 129 if (easFlowMode) { 130 AccountSetupBasics.actionAccountCreateFinishedEas(this); 131 } else { 132 AccountSetupBasics.actionAccountCreateFinished(this, mAccount.mId); 133 } 134 finish(); 135 } 136 137 /** 138 * After having a chance to input the display names, we normally jump directly to the 139 * inbox for the new account. However if we're in EAS flow mode (externally-launched 140 * account creation) we simply "pop" here which should return us to the Accounts activities. 141 * 142 * TODO: Validator should also trim the description string before checking it. 143 */ 144 private void onNext() { 145 if (Utility.requiredFieldValid(mDescription)) { 146 mAccount.setDisplayName(mDescription.getText().toString()); 147 } 148 String name = mName.getText().toString(); 149 mAccount.setSenderName(name); 150 ContentValues cv = new ContentValues(); 151 cv.put(AccountColumns.DISPLAY_NAME, mAccount.getDisplayName()); 152 cv.put(AccountColumns.SENDER_NAME, name); 153 mAccount.update(this, cv); 154 // Update the backup (side copy) of the accounts 155 AccountBackupRestore.backupAccounts(this); 156 157 // Before proceeding, launch an AsyncTask to test the account for any syncing problems, 158 // and if there's a problem, bring up the UI to update the security level. 159 mCheckAccountStateTask = new CheckAccountStateTask(mAccount.mId); 160 mCheckAccountStateTask.execute(); 161 } 162 163 public void onClick(View v) { 164 switch (v.getId()) { 165 case R.id.done: 166 onNext(); 167 break; 168 } 169 } 170 171 /** 172 * This async task is launched just before exiting. It's a last chance test, before leaving 173 * this activity, for the account being in a "hold" state, and gives the user a chance to 174 * update security, enter a device PIN, etc. for a more seamless account setup experience. 175 * 176 * TODO: If there was *any* indication that security might be required, we could at least 177 * force the DeviceAdmin activation step, without waiting for the initial sync/handshake 178 * to fail. 179 * TODO: If the user doesn't update the security, don't go to the MessageList. 180 */ 181 private class CheckAccountStateTask extends AsyncTask<Void, Void, Boolean> { 182 183 private long mAccountId; 184 185 public CheckAccountStateTask(long accountId) { 186 mAccountId = accountId; 187 } 188 189 @Override 190 protected Boolean doInBackground(Void... params) { 191 Cursor c = AccountSetupNames.this.getContentResolver().query( 192 ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId), 193 ACCOUNT_INFO_PROJECTION, null, null, null); 194 try { 195 if (c.moveToFirst()) { 196 int flags = c.getInt(ACCOUNT_INFO_COLUMN_FLAGS); 197 int securityFlags = c.getInt(ACCOUNT_INFO_COLUMN_SECURITY_FLAGS); 198 if ((flags & Account.FLAGS_SECURITY_HOLD) != 0) { 199 return Boolean.TRUE; 200 } 201 } 202 } finally { 203 c.close(); 204 } 205 206 return Boolean.FALSE; 207 } 208 209 @Override 210 protected void onPostExecute(Boolean isSecurityHold) { 211 if (!isCancelled()) { 212 if (isSecurityHold) { 213 Intent i = AccountSecurity.actionUpdateSecurityIntent( 214 AccountSetupNames.this, mAccountId); 215 AccountSetupNames.this.startActivityForResult(i, REQUEST_SECURITY); 216 } else { 217 onBackPressed(); 218 } 219 } 220 } 221 } 222 223 /** 224 * Handle the eventual result from the security update activity 225 * 226 * TODO: If the user doesn't update the security, don't go to the MessageList. 227 */ 228 @Override 229 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 230 switch (requestCode) { 231 case REQUEST_SECURITY: 232 onBackPressed(); 233 } 234 super.onActivityResult(requestCode, resultCode, data); 235 } 236 237} 238