1ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hupackage com.android.exchange.service; 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.mail.MessagingException; 9ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.provider.Account; 10ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.provider.HostAuth; 11ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.emailcommon.service.EmailServiceProxy; 12ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.exchange.Eas; 13ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.exchange.EasResponse; 14ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport com.android.mail.utils.LogUtils; 15ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 16ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.apache.http.HttpStatus; 17ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.apache.http.client.methods.HttpPost; 18ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.apache.http.entity.StringEntity; 19ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParser; 20ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParserException; 21ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlPullParserFactory; 22ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport org.xmlpull.v1.XmlSerializer; 23ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 24ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport java.io.ByteArrayOutputStream; 25ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport java.io.IOException; 26ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Huimport java.net.URI; 27ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 28ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu/** 29ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Performs Autodiscover for Exchange servers. This feature tries to find all the configuration 30ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * options needed based on just a username and password. 31ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 32ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hupublic class EasAutoDiscover extends EasServerConnection { 33110837ebff288a75f9bda067c38e2c46797d99b5Alon Albert private static final String TAG = Eas.LOG_TAG; 34ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 35ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String AUTO_DISCOVER_SCHEMA_PREFIX = 36ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu "http://schemas.microsoft.com/exchange/autodiscover/mobilesync/"; 37ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String AUTO_DISCOVER_PAGE = "/autodiscover/autodiscover.xml"; 38ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 39ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Set of string constants for parsing the autodiscover response. 40ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // TODO: Merge this into Tags.java? It's not quite the same but conceptually belongs there. 41ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_SERVER = "Server"; 42ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_TYPE = "Type"; 43ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_MOBILE_SYNC = "MobileSync"; 44ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_URL = "Url"; 45ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_SETTINGS = "Settings"; 46ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_ACTION = "Action"; 47ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_ERROR = "Error"; 48ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_REDIRECT = "Redirect"; 49ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_USER = "User"; 50ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_EMAIL_ADDRESS = "EMailAddress"; 51ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_DISPLAY_NAME = "DisplayName"; 52ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_RESPONSE = "Response"; 53ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private static final String ELEMENT_NAME_AUTODISCOVER = "Autodiscover"; 54ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 55ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu public EasAutoDiscover(final Context context, final String username, final String password) { 56ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu super(context, new Account(), new HostAuth()); 57ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mHostAuth.mLogin = username; 58ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mHostAuth.mPassword = password; 59ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mHostAuth.mFlags = HostAuth.FLAG_AUTHENTICATE | HostAuth.FLAG_SSL; 60ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mHostAuth.mPort = 443; 61ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 62ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 63ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 64ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Do all the work of autodiscovery. 65ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return A {@link Bundle} with the host information if autodiscovery succeeded. If we failed 66ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * due to an authentication failure, we return a {@link Bundle} with no host info but with 67ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * an appropriate error code. Otherwise, we return null. 68ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 69ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu public Bundle doAutodiscover() { 70ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String domain = getDomain(); 71ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (domain == null) { 72ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 73ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 74ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 75ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final StringEntity entity = buildRequestEntity(); 76ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (entity == null) { 77ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 78ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 79ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 80432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu final HttpPost post = makePost("https://" + domain + AUTO_DISCOVER_PAGE, entity, 81432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu "text/xml", false); 82432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu final EasResponse resp = getResponse(post, domain); 83432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu if (resp == null) { 84432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu return null; 85432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu } 86432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu 87432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu try { 88432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // resp is either an authentication error, or a good response. 89432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu final int code = resp.getStatus(); 90432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu if (code == HttpStatus.SC_UNAUTHORIZED) { 9154ab11d4050d543927e4e5809484927cdfafd433Paul Sliwowski final Bundle bundle = new Bundle(1); 9254ab11d4050d543927e4e5809484927cdfafd433Paul Sliwowski bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE, 9354ab11d4050d543927e4e5809484927cdfafd433Paul Sliwowski MessagingException.AUTODISCOVER_AUTHENTICATION_FAILED); 9454ab11d4050d543927e4e5809484927cdfafd433Paul Sliwowski return bundle; 95432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu } else { 96432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu final HostAuth hostAuth = parseAutodiscover(resp); 97432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu if (hostAuth != null) { 98432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // Fill in the rest of the HostAuth 99432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // We use the user name and password that were successful during 100432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // the autodiscover process 101432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth.mLogin = mHostAuth.mLogin; 102432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth.mPassword = mHostAuth.mPassword; 103432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // Note: there is no way we can auto-discover the proper client 104432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // SSL certificate to use, if one is needed. 105432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth.mPort = 443; 106432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth.mProtocol = Eas.PROTOCOL; 107432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth.mFlags = HostAuth.FLAG_SSL | HostAuth.FLAG_AUTHENTICATE; 108432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu final Bundle bundle = new Bundle(2); 109432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu bundle.putParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH, 110432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu hostAuth); 111432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu bundle.putInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE, 112432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu MessagingException.NO_ERROR); 113432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu return bundle; 114432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu } 115ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 116432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu } finally { 117432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu resp.close(); 118ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 119432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu } catch (final IllegalArgumentException e) { 120432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // This happens when the domain is malformatted. 121432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu // TODO: Fix sanitizing of the domain -- we try to in UI but apparently not correctly. 122432f1de519032c9381650ba5a40d0ff06d19c51bYu Ping Hu LogUtils.e(TAG, "ISE with domain: %s", domain); 123ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 124ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 125ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 126ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 127ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 128ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Get the domain of our account. 129ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return The domain of the email address. 130ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 131ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private String getDomain() { 132ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int amp = mHostAuth.mLogin.indexOf('@'); 133ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (amp < 0) { 134ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 135ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 136ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return mHostAuth.mLogin.substring(amp + 1); 137ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 138ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 139ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 140ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Create the payload of the request. 141ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return A {@link StringEntity} for the request XML. 142ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 143ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private StringEntity buildRequestEntity() { 144ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 145ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final XmlSerializer s = Xml.newSerializer(); 146ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final ByteArrayOutputStream os = new ByteArrayOutputStream(1024); 147ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.setOutput(os, "UTF-8"); 148ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startDocument("UTF-8", false); 149ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "Autodiscover"); 150ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.attribute(null, "xmlns", AUTO_DISCOVER_SCHEMA_PREFIX + "requestschema/2006"); 151ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "Request"); 152ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "EMailAddress").text(mHostAuth.mLogin).endTag(null, "EMailAddress"); 153ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.startTag(null, "AcceptableResponseSchema"); 154ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.text(AUTO_DISCOVER_SCHEMA_PREFIX + "responseschema/2006"); 155ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "AcceptableResponseSchema"); 156ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "Request"); 157ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endTag(null, "Autodiscover"); 158ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu s.endDocument(); 159ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return new StringEntity(os.toString()); 160ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IOException e) { 161ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // For all exception types, we can simply punt on autodiscover. 162ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IllegalArgumentException e) { 163ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IllegalStateException e) { 164ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 165ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 166ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 167ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 168ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 169ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 170ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Perform all requests necessary and get the server response. If the post fails or is 171ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * redirected, we alter the post and retry. 172ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param post The initial {@link HttpPost} for this request. 173ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param domain The domain for our account. 174ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return If this request succeeded or has an unrecoverable authentication error, an 175ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * {@link EasResponse} with the details. For other errors, we return null. 176ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 177ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private EasResponse getResponse(final HttpPost post, final String domain) { 178ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu EasResponse resp = doPost(post, true); 179ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (resp == null) { 180ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Error in autodiscover, trying aternate address"); 181ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu post.setURI(URI.create("https://autodiscover." + domain + AUTO_DISCOVER_PAGE)); 182ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu resp = doPost(post, true); 183ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 184ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return resp; 185ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 186ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 187ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 188ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Perform one attempt to get autodiscover information. Redirection and some authentication 189ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * errors are handled by recursively calls with modified host information. 190ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param post The {@link HttpPost} for this request. 191ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param canRetry Whether we can retry after an authentication failure. 192ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return If this request succeeded or has an unrecoverable authentication error, an 193ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * {@link EasResponse} with the details. For other errors, we return null. 194ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 195ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu private EasResponse doPost(final HttpPost post, final boolean canRetry) { 196ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final EasResponse resp; 197ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 198ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu resp = executePost(post); 199ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IOException e) { 200ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 201ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 202ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 203ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int code = resp.getStatus(); 204ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 205ff7e02603bc8196f411c0c491d74a42e747b7dc5Yu Ping Hu if (resp.isRedirectError()) { 206ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String loc = resp.getRedirectAddress(); 207ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (loc != null && loc.startsWith("http")) { 208ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Posting autodiscover to redirect: " + loc); 209ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu redirectHostAuth(loc); 210ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu post.setURI(URI.create(loc)); 211ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return doPost(post, canRetry); 212ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 213ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 214ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 215ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 216ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (code == HttpStatus.SC_UNAUTHORIZED) { 217ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (canRetry && mHostAuth.mLogin.contains("@")) { 218ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Try again using the bare user name 219ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int atSignIndex = mHostAuth.mLogin.indexOf('@'); 220ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mHostAuth.mLogin = mHostAuth.mLogin.substring(0, atSignIndex); 221ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "401 received; trying username: %s", mHostAuth.mLogin); 222ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu resetAuthorization(post); 223ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return doPost(post, false); 224ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 225ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (code != HttpStatus.SC_OK) { 226ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // We'll try the next address if this doesn't work 227ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Bad response code when posting autodiscover: %d", code); 228ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 229ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 230ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 231ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return resp; 232ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 233ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 234ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 235ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Server element of the server response. 236ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 237ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 238ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 239ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 240ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 24156d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseServer(final XmlPullParser parser, final HostAuth hostAuth) 242ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 243ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu boolean mobileSync = false; 244ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 245ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 246ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SERVER)) { 247ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 248ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 249ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 250ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_TYPE)) { 251ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.nextText().equals(ELEMENT_NAME_MOBILE_SYNC)) { 252ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu mobileSync = true; 253ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 254ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (mobileSync && name.equals(ELEMENT_NAME_URL)) { 255ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String url = parser.nextText(); 256ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (url != null) { 257ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover URL: %s", url); 258ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu hostAuth.mAddress = Uri.parse(url).getHost(); 259ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 260ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 261ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 262ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 263ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 264ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 265ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 266ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Settings element of the server response. 267ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 268ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 269ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 270ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 271ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 27256d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseSettings(final XmlPullParser parser, final HostAuth hostAuth) 273ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 274ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 275ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 276ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_SETTINGS)) { 277ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 278ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 279ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 280ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_SERVER)) { 281ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseServer(parser, hostAuth); 282ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 283ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 284ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 285ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 286ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 287ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 288ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Action element of the server response. 289ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 290ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 291ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 292ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 293ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 29456d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseAction(final XmlPullParser parser, final HostAuth hostAuth) 295ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 296ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 297ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 298ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_ACTION)) { 299ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 300ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 301ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 302ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_ERROR)) { 303ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Should parse the error 304ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_REDIRECT)) { 305ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Redirect: " + parser.nextText()); 306ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_SETTINGS)) { 307ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseSettings(parser, hostAuth); 308ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 309ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 310ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 311ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 312ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 313ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 314ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the User element of the server response. 315ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 316ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 317ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 318ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 319ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 32056d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseUser(final XmlPullParser parser, final HostAuth hostAuth) 321ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 322ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 323ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu int type = parser.next(); 324ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_USER)) { 325ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 326ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 327ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu String name = parser.getName(); 328ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_EMAIL_ADDRESS)) { 329ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String addr = parser.nextText(); 330ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover, email: %s", addr); 331ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_DISPLAY_NAME)) { 332ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String dn = parser.nextText(); 333ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu LogUtils.d(TAG, "Autodiscover, user: %s", dn); 334ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 335ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 336ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 337ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 338ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 339ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 340ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the Response element of the server response. 341ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param parser The {@link XmlPullParser}. 342ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param hostAuth The {@link HostAuth} to populate with the results of parsing. 343ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws XmlPullParserException 344ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @throws IOException 345ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 34656d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static void parseResponse(final XmlPullParser parser, final HostAuth hostAuth) 347ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu throws XmlPullParserException, IOException { 348ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 349ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.next(); 350ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName().equals(ELEMENT_NAME_RESPONSE)) { 351ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 352ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG) { 353ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final String name = parser.getName(); 354ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (name.equals(ELEMENT_NAME_USER)) { 355ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseUser(parser, hostAuth); 356ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (name.equals(ELEMENT_NAME_ACTION)) { 357ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseAction(parser, hostAuth); 358ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 359ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 360ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 361ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 362ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 363ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu /** 364ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * Parse the server response for the final {@link HostAuth}. 365ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @param resp The {@link EasResponse} from the server. 366ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu * @return The final {@link HostAuth} for this server. 367ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu */ 36856d35257ef1493e849522c3c2828d904e4c5531fScott Kennedy private static HostAuth parseAutodiscover(final EasResponse resp) { 369ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // The response to Autodiscover is regular XML (not WBXML) 370ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu try { 371ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); 372ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parser.setInput(resp.getInputStream(), "UTF-8"); 373ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.getEventType() != XmlPullParser.START_DOCUMENT) { 374ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 375ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 376ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (parser.next() != XmlPullParser.START_TAG) { 377ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 378ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 379ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (!parser.getName().equals(ELEMENT_NAME_AUTODISCOVER)) { 380ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 381ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 382ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu 383ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final HostAuth hostAuth = new HostAuth(); 384ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu while (true) { 385ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu final int type = parser.nextTag(); 386ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (type == XmlPullParser.END_TAG && parser.getName() 387ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu .equals(ELEMENT_NAME_AUTODISCOVER)) { 388ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu break; 389ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } else if (type == XmlPullParser.START_TAG && parser.getName() 390ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu .equals(ELEMENT_NAME_RESPONSE)) { 391ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu parseResponse(parser, hostAuth); 392ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Valid responses will set the address. 393ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu if (hostAuth.mAddress != null) { 394ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return hostAuth; 395ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 396ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 397ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 398ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final XmlPullParserException e) { 399ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Parse error. 400ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } catch (final IOException e) { 401ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu // Error reading parser. 402ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 403ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu return null; 404ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu } 405ddbe7744f17d9dd0e26bc2d5a1e89aec9b031bddYu Ping Hu} 406