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 17 package com.android.email.activity.setup; 18 19 import com.android.email.R; 20 import com.android.email.VendorPolicyLoader; 21 import com.android.email.mail.Store; 22 import com.android.email.provider.EmailContent; 23 import com.android.email.provider.EmailContent.Account; 24 25 import android.app.Activity; 26 import android.content.Intent; 27 import android.database.Cursor; 28 import android.os.Bundle; 29 import android.view.View; 30 import android.view.View.OnClickListener; 31 import android.widget.Button; 32 33 import java.net.URI; 34 import java.net.URISyntaxException; 35 36 /** 37 * Prompts the user to select an account type. The account type, along with the 38 * passed in email address, password and makeDefault are then passed on to the 39 * AccountSetupIncoming activity. 40 */ 41 public class AccountSetupAccountType extends Activity implements OnClickListener { 42 43 private static final String EXTRA_ACCOUNT = "account"; 44 private static final String EXTRA_MAKE_DEFAULT = "makeDefault"; 45 private static final String EXTRA_EAS_FLOW = "easFlow"; 46 private static final String EXTRA_ALLOW_AUTODISCOVER = "allowAutoDiscover"; 47 48 private Account mAccount; 49 private boolean mMakeDefault; 50 private boolean mAllowAutoDiscover; 51 52 public static void actionSelectAccountType(Activity fromActivity, Account account, 53 boolean makeDefault, boolean easFlowMode, boolean allowAutoDiscover) { 54 Intent i = new Intent(fromActivity, AccountSetupAccountType.class); 55 i.putExtra(EXTRA_ACCOUNT, account); 56 i.putExtra(EXTRA_MAKE_DEFAULT, makeDefault); 57 i.putExtra(EXTRA_EAS_FLOW, easFlowMode); 58 i.putExtra(EXTRA_ALLOW_AUTODISCOVER, allowAutoDiscover); 59 fromActivity.startActivity(i); 60 } 61 62 @Override 63 public void onCreate(Bundle savedInstanceState) { 64 super.onCreate(savedInstanceState); 65 66 Intent intent = getIntent(); 67 mAccount = (Account) intent.getParcelableExtra(EXTRA_ACCOUNT); 68 mMakeDefault = intent.getBooleanExtra(EXTRA_MAKE_DEFAULT, false); 69 boolean easFlowMode = intent.getBooleanExtra(EXTRA_EAS_FLOW, false); 70 mAllowAutoDiscover = intent.getBooleanExtra(EXTRA_ALLOW_AUTODISCOVER, true); 71 72 // If we're in account setup flow mode, for EAS, skip this screen and "click" EAS 73 if (easFlowMode) { 74 onExchange(true); 75 return; 76 } 77 78 // Otherwise proceed into this screen 79 setContentView(R.layout.account_setup_account_type); 80 ((Button)findViewById(R.id.pop)).setOnClickListener(this); 81 ((Button)findViewById(R.id.imap)).setOnClickListener(this); 82 final Button exchangeButton = ((Button)findViewById(R.id.exchange)); 83 exchangeButton.setOnClickListener(this); 84 85 if (isExchangeAvailable()) { 86 exchangeButton.setVisibility(View.VISIBLE); 87 if (VendorPolicyLoader.getInstance(this).useAlternateExchangeStrings()) { 88 exchangeButton.setText( 89 R.string.account_setup_account_type_exchange_action_alternate); 90 } 91 } 92 // TODO: Dynamic creation of buttons, instead of just hiding things we don't need 93 } 94 95 private void onPop() { 96 try { 97 URI uri = new URI(mAccount.getStoreUri(this)); 98 uri = new URI("pop3", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null); 99 mAccount.setStoreUri(this, uri.toString()); 100 } catch (URISyntaxException use) { 101 /* 102 * This should not happen. 103 */ 104 throw new Error(use); 105 } 106 AccountSetupIncoming.actionIncomingSettings(this, mAccount, mMakeDefault); 107 finish(); 108 } 109 110 /** 111 * The user has selected an IMAP account type. Try to put together a URI using the entered 112 * email address. Also set the mail delete policy here, because there is no UI (for IMAP). 113 */ 114 private void onImap() { 115 try { 116 URI uri = new URI(mAccount.getStoreUri(this)); 117 uri = new URI("imap", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null); 118 mAccount.setStoreUri(this, uri.toString()); 119 } catch (URISyntaxException use) { 120 /* 121 * This should not happen. 122 */ 123 throw new Error(use); 124 } 125 // Delete policy must be set explicitly, because IMAP does not provide a UI selection 126 // for it. This logic needs to be followed in the auto setup flow as well. 127 mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE); 128 AccountSetupIncoming.actionIncomingSettings(this, mAccount, mMakeDefault); 129 finish(); 130 } 131 132 /** 133 * The user has selected an exchange account type. Try to put together a URI using the entered 134 * email address. Also set the mail delete policy here, because there is no UI (for exchange), 135 * and switch the default sync interval to "push". 136 */ 137 private void onExchange(boolean easFlowMode) { 138 try { 139 URI uri = new URI(mAccount.getStoreUri(this)); 140 uri = new URI("eas+ssl+", uri.getUserInfo(), uri.getHost(), uri.getPort(), 141 null, null, null); 142 mAccount.setStoreUri(this, uri.toString()); 143 mAccount.setSenderUri(this, uri.toString()); 144 } catch (URISyntaxException use) { 145 /* 146 * This should not happen. 147 */ 148 throw new Error(use); 149 } 150 // TODO: Confirm correct delete policy for exchange 151 mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE); 152 mAccount.setSyncInterval(Account.CHECK_INTERVAL_PUSH); 153 mAccount.setSyncLookback(1); 154 AccountSetupExchange.actionIncomingSettings(this, mAccount, mMakeDefault, easFlowMode, 155 mAllowAutoDiscover); 156 finish(); 157 } 158 159 /** 160 * Determine if we can show the "exchange" option 161 * 162 * TODO: This should be dynamic and data-driven for all account types, not just hardcoded 163 * like this. 164 */ 165 private boolean isExchangeAvailable() { 166 //EXCHANGE-REMOVE-SECTION-START 167 try { 168 URI uri = new URI(mAccount.getStoreUri(this)); 169 uri = new URI("eas", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null); 170 Store.StoreInfo storeInfo = Store.StoreInfo.getStoreInfo(uri.toString(), this); 171 return (storeInfo != null && checkAccountInstanceLimit(storeInfo)); 172 } catch (URISyntaxException e) { 173 } 174 //EXCHANGE-REMOVE-SECTION-END 175 return false; 176 } 177 178 /** 179 * If the optional store specifies a limit on the number of accounts, make sure that we 180 * don't violate that limit. 181 * @return true if OK to create another account, false if not OK (limit reached) 182 */ 183 /* package */ boolean checkAccountInstanceLimit(Store.StoreInfo storeInfo) { 184 // return immediately if account defines no limit 185 if (storeInfo.mAccountInstanceLimit < 0) { 186 return true; 187 } 188 189 // count existing accounts 190 int currentAccountsCount = 0; 191 Cursor c = null; 192 try { 193 c = this.getContentResolver().query( 194 Account.CONTENT_URI, 195 Account.CONTENT_PROJECTION, 196 null, null, null); 197 while (c.moveToNext()) { 198 Account account = EmailContent.getContent(c, Account.class); 199 String storeUri = account.getStoreUri(this); 200 if (storeUri != null && storeUri.startsWith(storeInfo.mScheme)) { 201 currentAccountsCount++; 202 } 203 } 204 } finally { 205 if (c != null) { 206 c.close(); 207 } 208 } 209 210 // return true if we can accept another account 211 return (currentAccountsCount < storeInfo.mAccountInstanceLimit); 212 } 213 214 public void onClick(View v) { 215 switch (v.getId()) { 216 case R.id.pop: 217 onPop(); 218 break; 219 case R.id.imap: 220 onImap(); 221 break; 222 case R.id.exchange: 223 onExchange(false); 224 break; 225 } 226 } 227 } 228