1275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdonpackage com.android.exchange.eas; 2ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 3ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport android.content.Context; 4ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport android.net.Uri; 5ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport android.os.Bundle; 6ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport android.util.Xml; 7ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 8ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.provider.Account; 9ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.provider.HostAuth; 10ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.service.EmailServiceProxy; 11d793a08771c02d20c81acbedfc44d601d07d1c4fMartin Hibdonimport com.android.emailcommon.service.HostAuthCompat; 12275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdonimport com.android.exchange.CommandStatusException; 13ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.exchange.Eas; 14ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.exchange.EasResponse; 15ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.mail.utils.LogUtils; 16ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 17275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdonimport org.apache.http.HttpEntity; 18ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.apache.http.HttpStatus; 1903735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdonimport org.apache.http.client.methods.HttpUriRequest; 20ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.apache.http.entity.StringEntity; 21ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParser; 22ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParserException; 23ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParserFactory; 24ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlSerializer; 25ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 26ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport java.io.ByteArrayOutputStream; 27ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport java.io.IOException; 28ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 29275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdonpublic class EasAutoDiscover extends EasOperation { 30275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon 3103735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public final static int ATTEMPT_PRIMARY = 0; 3203735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public final static int ATTEMPT_ALTERNATE = 1; 3303735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public final static int ATTEMPT_UNAUTHENTICATED_GET = 2; 3403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public final static int ATTEMPT_MAX = 2; 3503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon 36275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public final static int RESULT_OK = 1; 37275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public final static int RESULT_SC_UNAUTHORIZED = RESULT_OP_SPECIFIC_ERROR_RESULT - 0; 38275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public final static int RESULT_REDIRECT = RESULT_OP_SPECIFIC_ERROR_RESULT - 1; 39275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public final static int RESULT_BAD_RESPONSE = RESULT_OP_SPECIFIC_ERROR_RESULT - 2; 40275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public final static int RESULT_FATAL_SERVER_ERROR = RESULT_OP_SPECIFIC_ERROR_RESULT - 3; 41275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon 42275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private final static String TAG = LogUtils.TAG; 43ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 44ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String AUTO_DISCOVER_SCHEMA_PREFIX = 45275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon "http://schemas.microsoft.com/exchange/autodiscover/mobilesync/"; 46ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String AUTO_DISCOVER_PAGE = "/autodiscover/autodiscover.xml"; 47ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 48ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Set of string constants for parsing the autodiscover response. 49ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // TODO: Merge this into Tags.java? It's not quite the same but conceptually belongs there. 50ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_SERVER = "Server"; 51ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_TYPE = "Type"; 52ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_MOBILE_SYNC = "MobileSync"; 53ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_URL = "Url"; 54ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_SETTINGS = "Settings"; 55ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_ACTION = "Action"; 56ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_ERROR = "Error"; 57ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_REDIRECT = "Redirect"; 58ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_USER = "User"; 59ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_EMAIL_ADDRESS = "EMailAddress"; 60ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_DISPLAY_NAME = "DisplayName"; 61ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_RESPONSE = "Response"; 62ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_AUTODISCOVER = "Autodiscover"; 63ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 6403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon private final int mAttemptNumber; 65275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private final String mUri; 66275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private final String mUsername; 67275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private final String mPassword; 68275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private HostAuth mHostAuth; 69275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon private String mRedirectUri; 70275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon 71ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon 72ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon private static Account makeAccount(final String username, final String password) { 73ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon final HostAuth hostAuth = new HostAuth(); 74ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon hostAuth.mLogin = username; 75ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon hostAuth.mPassword = password; 76ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon hostAuth.mPort = 443; 77ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon hostAuth.mProtocol = Eas.PROTOCOL; 78ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon hostAuth.mFlags = HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE; 79ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon final Account account = new Account(); 80ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon account.mEmailAddress = username; 81ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon account.mHostAuthRecv = hostAuth; 82ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon return account; 83ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon } 84ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon 8503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public EasAutoDiscover(final Context context, final String uri, final int attemptNumber, 8603735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon final String username, final String password) { 87275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // We don't actually need an account or a hostAuth, but the EasServerConnection requires 88275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // one. Just create dummy values. 89ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon super(context, makeAccount(username, password)); 9003735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon mAttemptNumber = attemptNumber; 91275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mUri = uri; 92275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mUsername = username; 93275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mPassword = password; 94ec620ef7363101f5ce8208d17ac496e882d995fdMartin Hibdon mHostAuth = mAccount.mHostAuthRecv; 95ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 96ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 9703735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon public static String genUri(final String domain, final int attemptNumber) { 9803735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon // Try the following uris in order, as per 9903735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon // http://msdn.microsoft.com/en-us/library/office/jj900169(v=exchg.150).aspx 10003735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon // TODO: That document also describes a fallback strategy to query DNS for an SRV record, 10103735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon // but this would require additional DNS lookup services that are not currently available 10203735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon // in the android platform, 10303735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon switch (attemptNumber) { 10403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon case ATTEMPT_PRIMARY: 10503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon return "https://" + domain + AUTO_DISCOVER_PAGE; 10603735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon case ATTEMPT_ALTERNATE: 10703735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon return "https://autodiscover." + domain + AUTO_DISCOVER_PAGE; 10803735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon case ATTEMPT_UNAUTHENTICATED_GET: 10903735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon return "http://autodiscover." + domain + AUTO_DISCOVER_PAGE; 11003735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon default: 11103735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon LogUtils.wtf(TAG, "Illegal attempt number %d", attemptNumber); 11203735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon return null; 11303735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon } 11403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon } 11503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon 116275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon protected String getRequestUri() { 117275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return mUri; 118275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } 119ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 120275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public static String getDomain(final String login) { 121275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon final int amp = login.indexOf('@'); 122275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon if (amp < 0) { 123ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 124ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 125275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return login.substring(amp + 1); 126275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } 127432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu 128275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon @Override 129275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon protected String getCommand() { 130275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return null; 131275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } 132275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon 133275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon @Override 134275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon protected HttpEntity getRequestEntity() throws IOException, MessageInvalidException { 135ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 136ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final XmlSerializer s = Xml.newSerializer(); 137ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final ByteArrayOutputStream os = new ByteArrayOutputStream(1024); 138ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.setOutput(os, "UTF-8"); 139ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startDocument("UTF-8", false); 140ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "Autodiscover"); 141ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.attribute(null, "xmlns", AUTO_DISCOVER_SCHEMA_PREFIX + "requestschema/2006"); 142ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "Request"); 143275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon s.startTag(null, "EMailAddress").text(mUsername).endTag(null, "EMailAddress"); 144ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "AcceptableResponseSchema"); 145ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.text(AUTO_DISCOVER_SCHEMA_PREFIX + "responseschema/2006"); 146ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "AcceptableResponseSchema"); 147ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "Request"); 148ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "Autodiscover"); 149ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endDocument(); 150ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return new StringEntity(os.toString()); 151ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IOException e) { 152ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // For all exception types, we can simply punt on autodiscover. 153ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IllegalArgumentException e) { 154ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IllegalStateException e) { 155ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 156ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 157ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 158ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 15903735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon /** 16003735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon * Create the request object for this operation. 16103735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon * The default is to use a POST, but some use other request types (e.g. Options). 16203735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon * @return An {@link org.apache.http.client.methods.HttpUriRequest}. 16303735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon * @throws IOException 16403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon */ 16503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon protected HttpUriRequest makeRequest() throws IOException, MessageInvalidException { 16603735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon final String requestUri = getRequestUri(); 16703735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon HttpUriRequest req; 16803735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon if (mAttemptNumber == ATTEMPT_UNAUTHENTICATED_GET) { 16903735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon req = mConnection.makeGet(requestUri); 17003735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon } else { 17103735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon req = mConnection.makePost(requestUri, getRequestEntity(), 17203735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon getRequestContentType(), addPolicyKeyHeaderToRequest()); 17303735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon } 17403735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon return req; 17503735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon } 17603735a839ba61710f887fffd6d3f605c0b127c2eMartin Hibdon 177275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public String getRedirectUri() { 178275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return mRedirectUri; 179ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 180ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 181275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon @Override 182275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon protected int handleResponse(final EasResponse response) throws 183275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon IOException, CommandStatusException { 184275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // resp is either an authentication error, or a good response. 185275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon final int code = response.getStatus(); 186ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 187275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon if (response.isRedirectError()) { 188275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon final String loc = response.getRedirectAddress(); 189ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (loc != null && loc.startsWith("http")) { 190ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Posting autodiscover to redirect: " + loc); 191275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mRedirectUri = loc; 192275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_REDIRECT; 193275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } else { 194275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon LogUtils.w(TAG, "Invalid redirect %s", loc); 195275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_FATAL_SERVER_ERROR; 196ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 197ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 198ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 199ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (code == HttpStatus.SC_UNAUTHORIZED) { 200275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon LogUtils.w(TAG, "Autodiscover received SC_UNAUTHORIZED"); 201275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_SC_UNAUTHORIZED; 202ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (code != HttpStatus.SC_OK) { 203ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // We'll try the next address if this doesn't work 204ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Bad response code when posting autodiscover: %d", code); 205275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_BAD_RESPONSE; 206275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } else { 207275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mHostAuth = parseAutodiscover(response); 208275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon if (mHostAuth != null) { 209275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // Fill in the rest of the HostAuth 210275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // We use the user name and password that were successful during 211275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // the autodiscover process 212275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mHostAuth.mLogin = mUsername; 213275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mHostAuth.mPassword = mPassword; 214275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // Note: there is no way we can auto-discover the proper client 215275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon // SSL certificate to use, if one is needed. 2163860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga if (mHostAuth.mPort == -1) { 2173860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga mHostAuth.mPort = 443; 2183860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga } 219275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mHostAuth.mProtocol = Eas.PROTOCOL; 220275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon mHostAuth.mFlags = HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE; 221275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_OK; 222275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } else { 223275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return RESULT_HARD_DATA_FAILURE; 224275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } 225ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 226275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon } 227ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 228275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon public Bundle getResultBundle() { 229275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon final Bundle bundle = new Bundle(2); 230d793a08771c02d20c81acbedfc44d601d07d1c4fMartin Hibdon final HostAuthCompat hostAuthCompat = new HostAuthCompat(mHostAuth); 231275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon bundle.putParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH, 232d793a08771c02d20c81acbedfc44d601d07d1c4fMartin Hibdon hostAuthCompat); 233275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE, 234275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon RESULT_OK); 235275e73703e09a1211ae6aa6fc2a43226e1fcdeedMartin Hibdon return bundle; 236ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 237ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 238ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 239ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Server element of the server response. 240ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 241ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 242ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 243ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 244ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 24556d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseServer(final XmlPullParser parser, final HostAuth hostAuth) 246ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 247ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu boolean mobileSync = false; 248ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 249ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 250ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SERVER)) { 251ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 252ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 253ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 254ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_TYPE)) { 255ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.nextText().equals(ELEMENT_NAME_MOBILE_SYNC)) { 256ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mobileSync = true; 257ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 258ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (mobileSync && name.equals(ELEMENT_NAME_URL)) { 259ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String url = parser.nextText(); 260ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (url != null) { 261ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover URL: %s", url); 2623860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga final Uri uri = Uri.parse(url); 2633860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga hostAuth.mAddress = uri.getHost(); 2643860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga int port = uri.getPort(); 2653860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga if (port != -1) { 2663860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga hostAuth.mPort = port; 2673860b0c076536883b808c5d865e7e3a509527a69Jorge Ruesga } 268ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 269ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 270ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 271ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 272ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 273ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 274ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 275ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Settings element of the server response. 276ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 277ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 278ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 279ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 280ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 28156d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseSettings(final XmlPullParser parser, final HostAuth hostAuth) 282ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 283ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 284ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 285ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SETTINGS)) { 286ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 287ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 288ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 289ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_SERVER)) { 290ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseServer(parser, hostAuth); 291ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 292ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 293ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 294ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 295ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 296ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 297ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Action element of the server response. 298ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 299ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 300ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 301ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 302ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 30356d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseAction(final XmlPullParser parser, final HostAuth hostAuth) 304ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 305ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 306ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 307ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_ACTION)) { 308ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 309ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 310ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 311ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_ERROR)) { 312ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Should parse the error 313ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_REDIRECT)) { 314ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Redirect: " + parser.nextText()); 315ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_SETTINGS)) { 316ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseSettings(parser, hostAuth); 317ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 318ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 319ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 320ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 321ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 322ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 323ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the User element of the server response. 324ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 325ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 326ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 327ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 328ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 32956d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseUser(final XmlPullParser parser, final HostAuth hostAuth) 330ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 331ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 332ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu int type = parser.next(); 333ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_USER)) { 334ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 335ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 336ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu String name = parser.getName(); 337ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_EMAIL_ADDRESS)) { 338ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String addr = parser.nextText(); 339ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover, email: %s", addr); 340ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_DISPLAY_NAME)) { 341ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String dn = parser.nextText(); 342ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover, user: %s", dn); 343ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 344ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 345ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 346ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 347ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 348ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 349ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Response element of the server response. 350ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 351ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 352ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 353ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 354ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 35556d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseResponse(final XmlPullParser parser, final HostAuth hostAuth) 356ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 357ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 358ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 359ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_RESPONSE)) { 360ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 361ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 362ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 363ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_USER)) { 364ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseUser(parser, hostAuth); 365ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_ACTION)) { 366ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseAction(parser, hostAuth); 367ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 368ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 369ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 370ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 371ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 372ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 373ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the server response for the final {@link HostAuth}. 374ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param resp The {@link EasResponse} from the server. 375ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return The final {@link HostAuth} for this server. 376ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 37756d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static HostAuth parseAutodiscover(final EasResponse resp) { 378ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // The response to Autodiscover is regular XML (not WBXML) 379ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 380ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); 381ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parser.setInput(resp.getInputStream(), "UTF-8"); 382ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.getEventType() != XmlPullParser.START_DOCUMENT) { 383ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 384ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 385ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.next() != XmlPullParser.START_TAG) { 386ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 387ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 388ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (!parser.getName().equals(ELEMENT_NAME_AUTODISCOVER)) { 389ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 390ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 391ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 392ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final HostAuth hostAuth = new HostAuth(); 393ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 394ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.nextTag(); 395ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName() 396ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu .equals(ELEMENT_NAME_AUTODISCOVER)) { 397ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 398ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG && parser.getName() 399ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu .equals(ELEMENT_NAME_RESPONSE)) { 400ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseResponse(parser, hostAuth); 401ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Valid responses will set the address. 402ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (hostAuth.mAddress != null) { 403ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return hostAuth; 404ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 405ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 406ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 407ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final XmlPullParserException e) { 408ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Parse error. 409ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IOException e) { 410ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Error reading parser. 411ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 412ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 413ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 414ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu} 415