1 /* 2 * Copyright (C) 2010 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.policy; 18 19 import android.os.Bundle; 20 21 /** 22 * This sample is the framework that can be used to build EmailPolicy packages for inclusion 23 * on specific devices. This sample is intended for use by OEMs or other creators of system 24 * images. 25 * 26 * When this package is built and included in a system image, the Email application will detect 27 * it (using reflection) and will make calls to the getPolicy() method at certain times. This 28 * can be used to provide local customization of the Email application. 29 * 30 * Do not change the package, class name, or method name - these must match the names used in 31 * this sample code or the Email application will not find the helper. 32 * 33 * Three customization points are provided: 34 * 35 * * Alternate strings for Exchange/ActiveSync UI 36 * * Insertion of device-specific text into IMAP ID commands 37 * * Device- or Carrier- specific account presets 38 * 39 * Each policy request may contain one or more parameters; These are supplied as keyed entries 40 * in the "arguments" bundle. If there is a single argument, it will typically use the same key 41 * as the policy name. If there are multiple arguments, they keys are provided and called out. 42 * 43 * In all cases, getPolicy() should return a bundle. For default behavior, or for any unknown 44 * policy, simply return Bundle.EMPTY. 45 * 46 * To return actual data, create a new bundle and place result values in it. If there is a single 47 * return value, this value is placed in the return bundle using the same key as the request. 48 * If there are multiple return values, keys will be provided for them as well. 49 * 50 * Future versions of the Email application may access additional customization points. If 51 * the call to getPolicy() is made with an unknown or unexpected policy keys, or the expected 52 * argument values cannot be found, the method should Bundle.EMPTY. 53 */ 54 public class EmailPolicy { 55 56 /** 57 * This policy request configures the UI to conform to various Exchange/ActiveSync 58 * license requirements. In the default configuration, the UI will refer to this protocol as 59 * "Exchange", while in the alternate configuration, the UI will refer to it as 60 * "Exchange ActiveSync" or "Microsoft Exchange ActiveSync". 61 * 62 * For the default behavior, return the empty bundle. 63 * For the alternate behavior, return a bundle containing a single entry with a key of 64 * USE_ALTERNATE_EXCHANGE_STRINGS and a value of "true". 65 */ 66 private static final String USE_ALTERNATE_EXCHANGE_STRINGS = "useAlternateExchangeStrings"; 67 68 /** 69 * This policy request allows you to insert field/value pairs into the IMAP ID command, which 70 * is sent to an IMAP server on each connection. 71 * 72 * The following arguments are provided: 73 * * GET_IMAP_ID_USER - the userid of the account being connected to 74 * * GET_IMAP_ID_HOST - the hostname of the server being connected to 75 * * GET_IMAP_ID_CAPA - the values returned by the "CAPA" command 76 * 77 * For default behavior (no values inserted), return the empty bundle. 78 * To insert additional values into the IMAP ID command, return a bundle containing a single 79 * entry with a key of GET_IMAP_ID and a String value. The value must be field/value pairs 80 * surrounded by quotes and separated by spaces. Multiple field/value pairs may be provided. 81 * See RFC 2971 for more information. 82 */ 83 private static final String GET_IMAP_ID = "getImapId"; 84 private static final String GET_IMAP_ID_USER = "getImapId.user"; 85 private static final String GET_IMAP_ID_HOST = "getImapId.host"; 86 private static final String GET_IMAP_ID_CAPA = "getImapId.capabilities"; 87 88 /** 89 * This policy request allows you to supply preset server configurations to provide 90 * automatic setup/configuration for specific email providers. These values supplement (or 91 * override) the automatic configurations provided in res/xml/providers.xml in 92 * the Email sources. (See that file for more information and plenty of samples.) 93 * 94 * The only argument (with the key FIND_PROVIDER) is a string containing the domain that the 95 * user entered as part of their email address; For example, if the user enters 96 * "MyEmailAddress (at) gmail.com", the domain will be "gmail.com". 97 * 98 * If no server information is provided for this domain, simply return Bundle.EMPTY. 99 * If server information is available for this domain, it can be returned in the following 100 * values: 101 * * FIND_PROVIDER_IN_URI The server configuration for the incoming (IMAP or POP) server 102 * * FIND_PROVIDER_IN_USER Format of the username (login) value 103 * * FIND_PROVIDER_OUT_URI The server configuration for the outgoing (SMTP) server 104 * * FIND_PROVIDER_OUT_USER Format of the username (login) value 105 * 106 * Valid incoming uri schemes are: 107 * imap IMAP with no transport security. 108 * imap+tls+ IMAP with required TLS transport security. 109 * If TLS is not available the connection fails. 110 * imap+ssl+ IMAP with required SSL transport security. 111 * If SSL is not available the connection fails. 112 * 113 * pop3 POP3 with no transport security. 114 * pop3+tls+ POP3 with required TLS transport security. 115 * If TLS is not available the connection fails. 116 * pop3+ssl+ POP3 with required SSL transport security. 117 * If SSL is not available the connection fails. 118 * 119 * Valid outgoing uri schemes are: 120 * smtp SMTP with no transport security. 121 * smtp+tls+ SMTP with required TLS transport security. 122 * If TLS is not available the connection fails. 123 * smtp+ssl+ SMTP with required SSL transport security. 124 * If SSL is not available the connection fails. 125 * 126 * To the above schemes you may also add "trustallcerts" to indicate that, 127 * although link encryption is still required, "non-trusted" certificates may 128 * will be excepted. For example, "imap+ssl+trustallcerts" or 129 * "smtp+tls+trustallcerts". This should only used when necessary, as it 130 * could allow a spoofed server to intercept password and mail. 131 * 132 * The URIs should be full templates for connection, including a port if 133 * the service uses a non-default port. The default ports are as follows: 134 * imap 143 pop3 110 smtp 587 135 * imap+tls+ 143 pop3+tls+ 110 smtp+tls+ 587 136 * imap+ssl+ 993 pop3+ssl+ 995 smtp+ssl+ 465 137 * 138 * The username attribute is used to supply a template for the username 139 * that will be presented to the server. This username is built from a 140 * set of variables that are substituted with parts of the user 141 * specified email address. 142 * 143 * Valid substitution values for the username attribute are: 144 * $email - the email address the user entered 145 * $user - the value before the @ sign in the email address the user entered 146 * $domain - the value after the @ signin the email address the user entered 147 * 148 * The username attribute MUST be specified for the incoming element, so the POP3 or IMAP 149 * server can identify the mailbox to be opened. 150 * 151 * The username attribute MAY be the empty string for the outgoing element, but only if the 152 * SMTP server supports anonymous transmission (most don't). 153 * 154 * For more information about these values, and many examples, see res/xml/providers.xml in 155 * the Email sources. 156 */ 157 private static final String FIND_PROVIDER = "findProvider"; 158 private static final String FIND_PROVIDER_IN_URI = "findProvider.inUri"; 159 private static final String FIND_PROVIDER_IN_USER = "findProvider.inUser"; 160 private static final String FIND_PROVIDER_OUT_URI = "findProvider.outUri"; 161 private static final String FIND_PROVIDER_OUT_USER = "findProvider.outUser"; 162 163 /** 164 * The following data is simply examples, and would be changed (or removed) based on the 165 * requirements for your device. 166 */ 167 168 /** 169 * Sample: Email domains that will be auto-configured. In our example, a number of domains 170 * are controlled by a single mail server. 171 */ 172 private static final String[] KNOWN_DOMAINS = new String[] { 173 "physics.school.edu", "math.school.edu", "language.school.edu", "history.school.edu" 174 }; 175 176 /** 177 * Sample: When we see a particular capability (identifying a particular server), send 178 * back a special value in the IMAP ID command. 179 */ 180 private static final String MY_SERVER_CAPABILITY = "MY-SERVER-CAPABILITY"; 181 private static final String MY_DEVICE_ID = "\"DEVICE-ID-FIELD\" \"MY-DEVICE-ID-VALUE\""; 182 183 /** 184 * Entry point from the Email application. 185 * 186 * @param policy A string requesting a particular policy 187 * @param arguments A bundle containing zero or more argument values for the requested policy 188 * @return A bundle containing zero or more return values for the requested policy 189 */ 190 public static Bundle getPolicy(String policy, Bundle arguments) { 191 /* 192 * Policy: Use alternate exchange strings 193 */ 194 if (USE_ALTERNATE_EXCHANGE_STRINGS.equals(policy)) { 195 // Un-comment the following code to select alternate exchange strings 196 // Bundle alternates = new Bundle(); 197 // alternates.putBoolean(USE_ALTERNATE_EXCHANGE_STRINGS, true); 198 // return alternates; 199 } 200 201 /* 202 * Policy: For a known domain, configure to the servers for that domain 203 */ 204 if (FIND_PROVIDER.equals(policy)) { 205 String domain = arguments.getString(FIND_PROVIDER); 206 if (domain != null) { 207 domain = domain.toLowerCase(); 208 boolean isKnownDomain = false; 209 for (String knownDomain : KNOWN_DOMAINS) { 210 if (knownDomain.equals(domain)) { 211 isKnownDomain = true; 212 break; 213 } 214 } 215 if (isKnownDomain) { 216 Bundle b = new Bundle(); 217 b.putString(FIND_PROVIDER_IN_URI, "imap+ssl://imap.school.edu"); 218 b.putString(FIND_PROVIDER_IN_USER, "$email"); 219 b.putString(FIND_PROVIDER_OUT_URI, "smtp+ssl://smtp.school.edu"); 220 b.putString(FIND_PROVIDER_OUT_USER, "$email"); 221 return b; 222 } 223 } 224 } 225 226 /** 227 * Policy: If the IMAP server presents a particular capability, send back a particular 228 * identifier in the IMAP ID. 229 */ 230 if (GET_IMAP_ID.equals(policy)) { 231 String capabilities = arguments.getString(GET_IMAP_ID_CAPA); 232 if (capabilities != null) { 233 if (capabilities.toUpperCase().contains(MY_SERVER_CAPABILITY)) { 234 Bundle b = new Bundle(); 235 b.putString(GET_IMAP_ID, MY_DEVICE_ID); 236 return b; 237 } 238 } 239 } 240 241 /** 242 * For any other policy request, or any policy request that cannot be processed, 243 * return an empty bundle. 244 */ 245 return Bundle.EMPTY; 246 } 247 } 248