From d461be709f81b9f418d5013d35a8c99c3beced3c Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Thu, 18 Jun 2020 02:52:40 +0000 Subject: [PATCH] =?UTF-8?q?=E3=80=8CDO=20NOT=20MERGE=E3=80=8DRevert=20"Get?= =?UTF-8?q?=20ApnIpType=20from=20ConnectivityManager#getLinkProperties()"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8f77e3476828c58fdde564a5ba36324b2f8486aa. Reason for revert: 1. Vendor reported a issue that after requesting EIMS network with IPv4v6 IP, we received onLinkPropertiesChanged() callback twice, where the initial callback is IPv4 link following a second callback with IPv4+IPv6 link, this behavior causes the wrong IP(IPv4) type to be sent to HAL. 2. We still can use hidden Telephony API in R, will fix above issue in S. Bug: 158695044 Test: Emergency SUPL test Change-Id: I1b7a4c3010c21923bda9e8dbead67215f7c600f7 --- .../gnss/GnssNetworkConnectivityHandler.java | 104 ++++++++++++------ 1 file changed, 72 insertions(+), 32 deletions(-) diff --git a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java index e17cca4238221..3fb713bc01a52 100644 --- a/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java +++ b/services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java @@ -17,9 +17,8 @@ package com.android.server.location.gnss; import android.content.Context; +import android.database.Cursor; import android.net.ConnectivityManager; -import android.net.LinkAddress; -import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; @@ -27,26 +26,25 @@ import android.net.NetworkRequest; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; -import android.telephony.PhoneStateListener; -import android.telephony.PreciseCallState; +import android.provider.Telephony.Carriers; +import android.telephony.ServiceState; +import android.telephony.TelephonyManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; +import android.telephony.PreciseCallState; +import android.telephony.PhoneStateListener; import android.util.Log; import com.android.internal.location.GpsNetInitiatedHandler; -import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; +import java.util.Map; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Map; - +import java.util.Iterator; /** * Handles network connection requests and network state change updates for AGPS data download. @@ -387,10 +385,10 @@ class GnssNetworkConnectivityHandler { private ConnectivityManager.NetworkCallback createSuplConnectivityCallback() { return new ConnectivityManager.NetworkCallback() { @Override - public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) { + public void onAvailable(Network network) { if (DEBUG) Log.d(TAG, "SUPL network connection available."); // Specific to a change to a SUPL enabled network becoming ready - handleSuplConnectionAvailable(network, linkProperties); + handleSuplConnectionAvailable(network); } @Override @@ -498,7 +496,7 @@ class GnssNetworkConnectivityHandler { return networkAttributes; } - private void handleSuplConnectionAvailable(Network network, LinkProperties linkProperties) { + private void handleSuplConnectionAvailable(Network network) { // TODO: The synchronous method ConnectivityManager.getNetworkInfo() should not be called // inside the asynchronous ConnectivityManager.NetworkCallback methods. NetworkInfo info = mConnMgr.getNetworkInfo(network); @@ -530,7 +528,7 @@ class GnssNetworkConnectivityHandler { setRouting(); } - int apnIpType = getLinkIpType(linkProperties); + int apnIpType = getApnIpType(apn); if (DEBUG) { String message = String.format( "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s", @@ -706,32 +704,74 @@ class GnssNetworkConnectivityHandler { } } - private int getLinkIpType(LinkProperties linkProperties) { + private int getApnIpType(String apn) { ensureInHandlerThread(); - boolean isIPv4 = false; - boolean isIPv6 = false; - - List linkAddresses = linkProperties.getLinkAddresses(); - for (LinkAddress linkAddress : linkAddresses) { - InetAddress inetAddress = linkAddress.getAddress(); - if (inetAddress instanceof Inet4Address) { - isIPv4 = true; - } else if (inetAddress instanceof Inet6Address) { - isIPv6 = true; + if (apn == null) { + return APN_INVALID; + } + TelephonyManager phone = (TelephonyManager) + mContext.getSystemService(Context.TELEPHONY_SERVICE); + // During an emergency call with an active sub id, get the Telephony Manager specific + // to the active sub to get the correct value from getServiceState and getNetworkType + if (mNiHandler.getInEmergency() && mActiveSubId >= 0) { + TelephonyManager subIdTelManager = + phone.createForSubscriptionId(mActiveSubId); + if (subIdTelManager != null) { + phone = subIdTelManager; } - if (DEBUG) Log.d(TAG, "LinkAddress : " + inetAddress.toString()); + } + ServiceState serviceState = phone.getServiceState(); + String projection = null; + String selection = null; + + // Carrier configuration may override framework roaming state, we need to use the actual + // modem roaming state instead of the framework roaming state. + if (serviceState != null && serviceState.getDataRoamingFromRegistration()) { + projection = Carriers.ROAMING_PROTOCOL; + } else { + projection = Carriers.PROTOCOL; + } + // No SIM case for emergency + if (TelephonyManager.NETWORK_TYPE_UNKNOWN == phone.getNetworkType() + && AGPS_TYPE_EIMS == mAGpsType) { + selection = String.format( + "type like '%%emergency%%' and apn = '%s' and carrier_enabled = 1", apn); + } else { + selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn); + } + try (Cursor cursor = mContext.getContentResolver().query( + Carriers.CONTENT_URI, + new String[]{projection}, + selection, + null, + Carriers.DEFAULT_SORT_ORDER)) { + if (null != cursor && cursor.moveToFirst()) { + return translateToApnIpType(cursor.getString(0), apn); + } else { + Log.e(TAG, "No entry found in query for APN: " + apn); + } + } catch (Exception e) { + Log.e(TAG, "Error encountered on APN query for: " + apn, e); } - if (isIPv4 && isIPv6) { - return APN_IPV4V6; - } - if (isIPv4) { + return APN_IPV4V6; + } + + private int translateToApnIpType(String ipProtocol, String apn) { + if ("IP".equals(ipProtocol)) { return APN_IPV4; } - if (isIPv6) { + if ("IPV6".equals(ipProtocol)) { return APN_IPV6; } - return APN_INVALID; + if ("IPV4V6".equals(ipProtocol)) { + return APN_IPV4V6; + } + + // we hit the default case so the ipProtocol is not recognized + String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn); + Log.e(TAG, message); + return APN_IPV4V6; } // AGPS support