Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d461be70 authored by Shinru Han's avatar Shinru Han
Browse files

「DO NOT MERGE」Revert "Get ApnIpType from ConnectivityManager#getLinkProperties()"

This reverts commit 8f77e347.

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
parent 8f77e347
Loading
Loading
Loading
Loading
+72 −32
Original line number Diff line number Diff line
@@ -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;
        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;
            }
        }
        ServiceState serviceState = phone.getServiceState();
        String projection = null;
        String selection = null;

        List<LinkAddress> linkAddresses = linkProperties.getLinkAddresses();
        for (LinkAddress linkAddress : linkAddresses) {
            InetAddress inetAddress = linkAddress.getAddress();
            if (inetAddress instanceof Inet4Address) {
                isIPv4 = true;
            } else if (inetAddress instanceof Inet6Address) {
                isIPv6 = true;
        // 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);
            }
            if (DEBUG) Log.d(TAG, "LinkAddress : " + inetAddress.toString());
        } catch (Exception e) {
            Log.e(TAG, "Error encountered on APN query for: " + apn, e);
        }

        if (isIPv4 && isIPv6) {
        return APN_IPV4V6;
    }
        if (isIPv4) {

    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