From eeb364a1e8916609bee877b893443bd940ea87da Mon Sep 17 00:00:00 2001 From: Ye Wen Date: Fri, 20 May 2016 15:58:50 -0700 Subject: Wait for IPv4 provisioned when connecting to IPv4 MMS URL T-Mobile's MMS network is IPv6 based. Sometimes MMS URL is provisioned as static IPv4 address, e.g for "unrecognized" devices. In that case, IPv4 provisioning takes some time. MMS service needs to wait for it before making connection. b/27245530 Change-Id: I62e370a1e6abd668f0b1333664aadf87583045dd --- src/com/android/mms/service/MmsHttpClient.java | 52 ++++++++++++++++++++-- src/com/android/mms/service/MmsNetworkManager.java | 2 +- src/com/android/mms/service/SendRequest.java | 2 +- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/com/android/mms/service/MmsHttpClient.java b/src/com/android/mms/service/MmsHttpClient.java index b4d3ba6..1c88bbf 100644 --- a/src/com/android/mms/service/MmsHttpClient.java +++ b/src/com/android/mms/service/MmsHttpClient.java @@ -17,6 +17,8 @@ package com.android.mms.service; import android.content.Context; +import android.net.ConnectivityManager; +import android.net.LinkProperties; import android.net.Network; import android.os.Bundle; import android.telephony.SmsManager; @@ -25,7 +27,6 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Base64; import android.util.Log; - import com.android.mms.service.exception.MmsHttpException; import java.io.BufferedInputStream; @@ -36,6 +37,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; +import java.net.Inet4Address; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.ProtocolException; @@ -68,18 +71,24 @@ public class MmsHttpClient { private static final String HEADER_VALUE_CONTENT_TYPE_WITHOUT_CHARSET = "application/vnd.wap.mms-message"; + private static final int IPV4_WAIT_ATTEMPTS = 15; + private static final long IPV4_WAIT_DELAY_MS = 1000; // 1 seconds + private final Context mContext; private final Network mNetwork; + private final ConnectivityManager mConnectivityManager; /** * Constructor - * - * @param context The Context object + * @param context The Context object * @param network The Network for creating an OKHttp client + * @param connectivityManager */ - public MmsHttpClient(Context context, Network network) { + public MmsHttpClient(Context context, Network network, + ConnectivityManager connectivityManager) { mContext = context; mNetwork = network; + mConnectivityManager = connectivityManager; } /** @@ -113,6 +122,7 @@ public class MmsHttpClient { new InetSocketAddress(mNetwork.getByName(proxyHost), proxyPort)); } final URL url = new URL(urlString); + maybeWaitForIpv4(requestId, url); // Now get the connection connection = (HttpURLConnection) mNetwork.openConnection(url, proxy); connection.setDoInput(true); @@ -209,6 +219,40 @@ public class MmsHttpClient { } } + private void maybeWaitForIpv4(final String requestId, final URL url) { + // If it's a literal IPv4 address and we're on an IPv6-only network, + // wait until IPv4 is available. + Inet4Address ipv4Literal = null; + try { + ipv4Literal = (Inet4Address) InetAddress.parseNumericAddress(url.getHost()); + } catch (IllegalArgumentException | ClassCastException e) { + // Ignore + } + if (ipv4Literal == null) { + // Not an IPv4 address. + return; + } + for (int i = 0; i < IPV4_WAIT_ATTEMPTS; i++) { + final LinkProperties lp = mConnectivityManager.getLinkProperties(mNetwork); + if (lp != null) { + if (!lp.isReachable(ipv4Literal)) { + LogUtil.w(requestId, "HTTP: IPv4 not yet provisioned"); + try { + Thread.sleep(IPV4_WAIT_DELAY_MS); + } catch (InterruptedException e) { + // Ignore + } + } else { + LogUtil.i(requestId, "HTTP: IPv4 provisioned"); + break; + } + } else { + LogUtil.w(requestId, "HTTP: network disconnected, skip ipv4 check"); + break; + } + } + } + private static void logHttpHeaders(Map> headers, String requestId) { final StringBuilder sb = new StringBuilder(); if (headers != null) { diff --git a/src/com/android/mms/service/MmsNetworkManager.java b/src/com/android/mms/service/MmsNetworkManager.java index ed78258..67b0af6 100644 --- a/src/com/android/mms/service/MmsNetworkManager.java +++ b/src/com/android/mms/service/MmsNetworkManager.java @@ -229,7 +229,7 @@ public class MmsNetworkManager { if (mMmsHttpClient == null) { if (mNetwork != null) { // Create new MmsHttpClient for the current Network - mMmsHttpClient = new MmsHttpClient(mContext, mNetwork); + mMmsHttpClient = new MmsHttpClient(mContext, mNetwork, mConnectivityManager); } } return mMmsHttpClient; diff --git a/src/com/android/mms/service/SendRequest.java b/src/com/android/mms/service/SendRequest.java index 435e12c..21cd43c 100644 --- a/src/com/android/mms/service/SendRequest.java +++ b/src/com/android/mms/service/SendRequest.java @@ -242,7 +242,7 @@ public class SendRequest extends MmsRequest { return ; } if (!(pdu instanceof SendReq)) { - LogUtil.e(requestId, "updateDestinationAddress: not SendReq"); + LogUtil.i(requestId, "updateDestinationAddress: not SendReq"); return; } -- cgit v1.2.3