AccountSettingsUtils.java revision 858c2822777f74947e81476125590ad06bfe4803
1/* 2 * Copyright (C) 2009 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.Email; 21import com.android.email.R; 22import com.android.email.VendorPolicyLoader; 23import com.android.email.provider.EmailContent; 24import com.android.email.provider.EmailContent.AccountColumns; 25 26import android.content.ContentValues; 27import android.content.Context; 28import android.content.res.XmlResourceParser; 29import android.text.Editable; 30import android.util.Log; 31import android.widget.EditText; 32 33import java.io.Serializable; 34import java.net.URI; 35 36public class AccountSettingsUtils { 37 38 /** 39 * Commits the UI-related settings of an account to the provider. This is static so that it 40 * can be used by the various account activities. If the account has never been saved, this 41 * method saves it; otherwise, it just saves the settings. 42 * @param context the context of the caller 43 * @param account the account whose settings will be committed 44 */ 45 public static void commitSettings(Context context, EmailContent.Account account) { 46 if (!account.isSaved()) { 47 account.save(context); 48 } else { 49 ContentValues cv = getAccountContentValues(account); 50 account.update(context, cv); 51 } 52 // Update the backup (side copy) of the accounts 53 AccountBackupRestore.backupAccounts(context); 54 } 55 56 /** 57 * Returns a set of content values to commit account changes (not including HostAuth) to 58 * the database. Does not actually commit anything. 59 */ 60 public static ContentValues getAccountContentValues(EmailContent.Account account) { 61 ContentValues cv = new ContentValues(); 62 cv.put(AccountColumns.IS_DEFAULT, account.mIsDefault); 63 cv.put(AccountColumns.DISPLAY_NAME, account.getDisplayName()); 64 cv.put(AccountColumns.SENDER_NAME, account.getSenderName()); 65 cv.put(AccountColumns.SIGNATURE, account.getSignature()); 66 cv.put(AccountColumns.SYNC_INTERVAL, account.mSyncInterval); 67 cv.put(AccountColumns.RINGTONE_URI, account.mRingtoneUri); 68 cv.put(AccountColumns.FLAGS, account.mFlags); 69 cv.put(AccountColumns.SYNC_LOOKBACK, account.mSyncLookback); 70 cv.put(AccountColumns.SECURITY_FLAGS, account.mSecurityFlags); 71 cv.put(AccountColumns.SECURITY_SYNC_KEY, account.mSecuritySyncKey); 72 return cv; 73 } 74 75 /** 76 * Search the list of known Email providers looking for one that matches the user's email 77 * domain. We check for vendor supplied values first, then we look in providers_product.xml, 78 * and finally by the entries in platform providers.xml. This provides a nominal override 79 * capability. 80 * 81 * A match is defined as any provider entry for which the "domain" attribute matches. 82 * 83 * @param domain The domain portion of the user's email address 84 * @return suitable Provider definition, or null if no match found 85 */ 86 public static Provider findProviderForDomain(Context context, String domain) { 87 Provider p = VendorPolicyLoader.getInstance(context).findProviderForDomain(domain); 88 if (p == null) { 89 p = findProviderForDomain(context, domain, R.xml.providers_product); 90 } 91 if (p == null) { 92 p = findProviderForDomain(context, domain, R.xml.providers); 93 } 94 return p; 95 } 96 97 /** 98 * Search a single resource containing known Email provider definitions. 99 * 100 * @param domain The domain portion of the user's email address 101 * @param resourceId Id of the provider resource to scan 102 * @return suitable Provider definition, or null if no match found 103 */ 104 private static Provider findProviderForDomain(Context context, String domain, int resourceId) { 105 try { 106 XmlResourceParser xml = context.getResources().getXml(resourceId); 107 int xmlEventType; 108 Provider provider = null; 109 while ((xmlEventType = xml.next()) != XmlResourceParser.END_DOCUMENT) { 110 if (xmlEventType == XmlResourceParser.START_TAG 111 && "provider".equals(xml.getName()) 112 && domain.equalsIgnoreCase(getXmlAttribute(context, xml, "domain"))) { 113 provider = new Provider(); 114 provider.id = getXmlAttribute(context, xml, "id"); 115 provider.label = getXmlAttribute(context, xml, "label"); 116 provider.domain = getXmlAttribute(context, xml, "domain"); 117 provider.note = getXmlAttribute(context, xml, "note"); 118 } 119 else if (xmlEventType == XmlResourceParser.START_TAG 120 && "incoming".equals(xml.getName()) 121 && provider != null) { 122 provider.incomingUriTemplate = new URI(getXmlAttribute(context, xml, "uri")); 123 provider.incomingUsernameTemplate = getXmlAttribute(context, xml, "username"); 124 } 125 else if (xmlEventType == XmlResourceParser.START_TAG 126 && "outgoing".equals(xml.getName()) 127 && provider != null) { 128 provider.outgoingUriTemplate = new URI(getXmlAttribute(context, xml, "uri")); 129 provider.outgoingUsernameTemplate = getXmlAttribute(context, xml, "username"); 130 } 131 else if (xmlEventType == XmlResourceParser.END_TAG 132 && "provider".equals(xml.getName()) 133 && provider != null) { 134 return provider; 135 } 136 } 137 } 138 catch (Exception e) { 139 Log.e(Email.LOG_TAG, "Error while trying to load provider settings.", e); 140 } 141 return null; 142 } 143 144 /** 145 * Attempts to get the given attribute as a String resource first, and if it fails 146 * returns the attribute as a simple String value. 147 * @param xml 148 * @param name 149 * @return the requested resource 150 */ 151 private static String getXmlAttribute(Context context, XmlResourceParser xml, String name) { 152 int resId = xml.getAttributeResourceValue(null, name, 0); 153 if (resId == 0) { 154 return xml.getAttributeValue(null, name); 155 } 156 else { 157 return context.getString(resId); 158 } 159 } 160 161 public static class Provider implements Serializable { 162 private static final long serialVersionUID = 8511656164616538989L; 163 164 public String id; 165 public String label; 166 public String domain; 167 public URI incomingUriTemplate; 168 public String incomingUsernameTemplate; 169 public URI outgoingUriTemplate; 170 public String outgoingUsernameTemplate; 171 public String note; 172 } 173 174 /** 175 * Infer potential email server addresses from domain names 176 * 177 * Incoming: Prepend "imap" or "pop3" to domain, unless "pop", "pop3", 178 * "imap", or "mail" are found. 179 * Outgoing: Prepend "smtp" if "pop", "pop3", "imap" are found. 180 * Leave "mail" as-is. 181 * TBD: Are there any useful defaults for exchange? 182 * 183 * @param server name as we know it so far 184 * @param incoming "pop3" or "imap" (or null) 185 * @param outgoing "smtp" or null 186 * @return the post-processed name for use in the UI 187 */ 188 public static String inferServerName(String server, String incoming, String outgoing) { 189 // Default values cause entire string to be kept, with prepended server string 190 int keepFirstChar = 0; 191 int firstDotIndex = server.indexOf('.'); 192 if (firstDotIndex != -1) { 193 // look at first word and decide what to do 194 String firstWord = server.substring(0, firstDotIndex).toLowerCase(); 195 boolean isImapOrPop = "imap".equals(firstWord) 196 || "pop3".equals(firstWord) || "pop".equals(firstWord); 197 boolean isMail = "mail".equals(firstWord); 198 // Now decide what to do 199 if (incoming != null) { 200 // For incoming, we leave imap/pop/pop3/mail alone, or prepend incoming 201 if (isImapOrPop || isMail) { 202 return server; 203 } 204 } else { 205 // For outgoing, replace imap/pop/pop3 with outgoing, leave mail alone, or 206 // prepend outgoing 207 if (isImapOrPop) { 208 keepFirstChar = firstDotIndex + 1; 209 } else if (isMail) { 210 return server; 211 } else { 212 // prepend 213 } 214 } 215 } 216 return ((incoming != null) ? incoming : outgoing) + '.' + server.substring(keepFirstChar); 217 } 218 219 /** 220 * Helper to set error status on password fields that have leading or trailing spaces 221 */ 222 public static void checkPasswordSpaces(Context context, EditText passwordField) { 223 // STOPSHIP - there is a bug in the framework that makes these flicker. 224 // If the bug cannot be fixed shortly, then this should be pulled before we ship 225 Editable password = passwordField.getText(); 226 int length = password.length(); 227 if (length > 0) { 228 if (password.charAt(0) == ' ' || password.charAt(length-1) == ' ') { 229 passwordField.setError(context.getString(R.string.account_password_spaces_error)); 230 } 231 } 232 } 233 234} 235