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

Commit b4995e2f authored by Anil Admal's avatar Anil Admal
Browse files

Provide network capabilities to GNSS HAL (framework changes)

The network type in the ConnectivityManager/Network classes is
deprecated and its use should be replaced with network capabilities
instead.

Bug: 117768826
Test: Tested with code instrumentation to verify that the
      @2.0::AGnssRil.hal updateNetwork_2_0() method implementation
      is called with correct arguments.
Test: Verified @1.0::AGnssRil.hal backward compatibility on a
      Pixel 3 device.
Change-Id: I3853c4e4c435ce7bdcdfb42e5bd311e974bcad3c
parent 5a12f044
Loading
Loading
Loading
Loading
+48 −51
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
@@ -65,6 +64,10 @@ class GnssNetworkConnectivityHandler {
    private static final int APN_IPV6 = 2;
    private static final int APN_IPV4V6 = 3;

    // these must match the NetworkCapability enum flags in IAGnssRil.hal
    private static final int AGNSS_NET_CAPABILITY_NOT_METERED = 1 << 0;
    private static final int AGNSS_NET_CAPABILITY_NOT_ROAMING = 1 << 1;

    // Default time limit in milliseconds for the ConnectivityManager to find a suitable
    // network with SUPL connectivity or report an error.
    private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000;
@@ -95,23 +98,42 @@ class GnssNetworkConnectivityHandler {
     * Network attributes needed when updating HAL about network connectivity status changes.
     */
    private static class NetworkAttributes {
        NetworkCapabilities mCapabilities;
        String mApn;
        int mType = ConnectivityManager.TYPE_NONE;
        private NetworkCapabilities mCapabilities;
        private String mApn;
        private int mType = ConnectivityManager.TYPE_NONE;

        /**
         * Returns true if the capabilities that we pass on to HAL change between {@curCapabilities}
         * and {@code newCapabilities}.
         */
        static boolean hasCapabilitiesChanged(NetworkCapabilities curCapabilities,
        private static boolean hasCapabilitiesChanged(NetworkCapabilities curCapabilities,
                NetworkCapabilities newCapabilities) {
            if (curCapabilities == null || newCapabilities == null) {
                return true;
            }

            return curCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
                    != newCapabilities.hasCapability(
                    NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
            // Monitor for roaming and metered capability changes.
            return hasCapabilityChanged(curCapabilities, newCapabilities,
                    NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
                    || hasCapabilityChanged(curCapabilities, newCapabilities,
                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        }

        private static boolean hasCapabilityChanged(NetworkCapabilities curCapabilities,
                NetworkCapabilities newCapabilities, int capability) {
            return curCapabilities.hasCapability(capability)
                    != newCapabilities.hasCapability(capability);
        }

        private static short getCapabilityFlags(NetworkCapabilities capabilities) {
            short capabilityFlags = 0;
            if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
                capabilityFlags |= AGNSS_NET_CAPABILITY_NOT_ROAMING;
            }
            if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
                capabilityFlags |= AGNSS_NET_CAPABILITY_NOT_METERED;
            }
            return capabilityFlags;
        }
    }

@@ -328,36 +350,31 @@ class GnssNetworkConnectivityHandler {
        boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled();
        NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network,
                capabilities);
        String apnName = networkAttributes.mApn;
        String apn = networkAttributes.mApn;
        int type = networkAttributes.mType;
        // When isConnected is false, capabilities argument is null. So, use last received
        // capabilities.
        capabilities = networkAttributes.mCapabilities;
        boolean isRoaming = !capabilities.hasTransport(
                NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);

        Log.i(TAG, String.format(
                "updateNetworkState, state=%s, connected=%s, network=%s, capabilities=%s"
                        + ", availableNetworkCount: %d",
                        + ", apn: %s, availableNetworkCount: %d",
                agpsDataConnStateAsString(),
                isConnected,
                network,
                capabilities,
                apn,
                mAvailableNetworkAttributes.size()));

        if (native_is_agps_ril_supported()) {
            String defaultApn = getSelectedApn();
            if (defaultApn == null) {
                defaultApn = "dummy-apn";
            }

            native_update_network_state(
                    isConnected,
                    type,
                    isRoaming,
                    !capabilities.hasTransport(
                            NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING), /* isRoaming */
                    networkAvailable,
                    apnName,
                    defaultApn);
                    apn != null ? apn : "",
                    network.getNetworkHandle(),
                    NetworkAttributes.getCapabilityFlags(capabilities));
        } else if (DEBUG) {
            Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not  supported");
        }
@@ -398,9 +415,9 @@ class GnssNetworkConnectivityHandler {
        // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
        // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
        NetworkInfo info = mConnMgr.getNetworkInfo(network);
        String apnName = null;
        String apn = null;
        if (info != null) {
            apnName = info.getExtraInfo();
            apn = info.getExtraInfo();
        }

        if (DEBUG) {
@@ -413,21 +430,21 @@ class GnssNetworkConnectivityHandler {
        }

        if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
            if (apnName == null) {
            if (apn == null) {
                // assign a dummy value in the case of C2K as otherwise we will have a runtime
                // exception in the following call to native_agps_data_conn_open
                apnName = "dummy-apn";
                apn = "dummy-apn";
            }
            int apnIpType = getApnIpType(apnName);
            int apnIpType = getApnIpType(apn);
            setRouting();
            if (DEBUG) {
                String message = String.format(
                        "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
                        apnName,
                        apn,
                        apnIpType);
                Log.d(TAG, message);
            }
            native_agps_data_conn_open(apnName, apnIpType);
            native_agps_data_conn_open(apn, apnIpType);
            mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
        }
    }
@@ -596,26 +613,6 @@ class GnssNetworkConnectivityHandler {
        return APN_INVALID;
    }

    private String getSelectedApn() {
        Uri uri = Uri.parse("content://telephony/carriers/preferapn");
        try (Cursor cursor = mContext.getContentResolver().query(
                uri,
                new String[]{"apn"},
                null /* selection */,
                null /* selectionArgs */,
                Carriers.DEFAULT_SORT_ORDER)) {
            if (cursor != null && cursor.moveToFirst()) {
                return cursor.getString(0);
            } else {
                Log.e(TAG, "No APN found to select.");
            }
        } catch (Exception e) {
            Log.e(TAG, "Error encountered on selecting the APN.", e);
        }

        return null;
    }

    // AGPS support
    private native void native_agps_data_conn_open(String apn, int apnIpType);

@@ -626,6 +623,6 @@ class GnssNetworkConnectivityHandler {
    // AGPS ril support
    private static native boolean native_is_agps_ril_supported();

    private native void native_update_network_state(boolean connected, int type,
            boolean roaming, boolean available, String extraInfo, String defaultAPN);
    private native void native_update_network_state(boolean connected, int type, boolean roaming,
            boolean available, String apn, long networkHandle, short capabilities);
}
 No newline at end of file
+56 −27
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ using android::hardware::gnss::V1_0::GnssLocationFlags;
using android::hardware::gnss::V1_0::IAGnss;
using android::hardware::gnss::V1_0::IAGnssCallback;
using android::hardware::gnss::V1_0::IAGnssCallback;
using android::hardware::gnss::V1_0::IAGnssRil;
using android::hardware::gnss::V1_0::IAGnssRilCallback;
using android::hardware::gnss::V1_0::IGnssBatching;
using android::hardware::gnss::V1_0::IGnssBatchingCallback;
@@ -121,6 +120,8 @@ using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil;
using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil;

struct GnssDeathRecipient : virtual public hidl_death_recipient
{
@@ -141,7 +142,8 @@ sp<IGnss_V1_0> gnssHal = nullptr;
sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
sp<IGnssXtra> gnssXtraIface = nullptr;
sp<IAGnssRil> agnssRilIface = nullptr;
sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
sp<IAGnss> agnssIface = nullptr;
sp<IGnssBatching> gnssBatchingIface = nullptr;
@@ -1247,11 +1249,21 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass
        gnssXtraIface = gnssXtra;
    }

    auto gnssRil = gnssHal->getExtensionAGnssRil();
    if (!gnssRil.isOk()) {
    if (gnssHal_V2_0 != nullptr) {
        auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
        if (!agnssRil_V2_0.isOk()) {
            ALOGD("Unable to get a handle to AGnssRil_V2_0");
        } else {
            agnssRilIface_V2_0 = agnssRil_V2_0;
            agnssRilIface = agnssRilIface_V2_0;
        }
    } else {
        auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
        if (!agnssRil_V1_0.isOk()) {
            ALOGD("Unable to get a handle to AGnssRil");
        } else {
        agnssRilIface = gnssRil;
            agnssRilIface = agnssRil_V1_0;
        }
    }

    auto gnssAgnss = gnssHal->getExtensionAGnss();
@@ -1496,17 +1508,17 @@ static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /*

static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
        JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
    IAGnssRil::AGnssRefLocation location;
    IAGnssRil_V1_0::AGnssRefLocation location;

    if (agnssRilIface == nullptr) {
        ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
        return;
    }

    switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
        case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
        case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
          location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
    switch (static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type)) {
        case IAGnssRil_V1_0::AGnssRefLocationType::GSM_CELLID:
        case IAGnssRil_V1_0::AGnssRefLocationType::UMTS_CELLID:
          location.type = static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type);
          location.cellID.mcc = mcc;
          location.cellID.mnc = mnc;
          location.cellID.lac = lac;
@@ -1529,7 +1541,7 @@ static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobje
    }

    const char *setid = env->GetStringUTFChars(setid_string, nullptr);
    agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
    agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, setid);
    env->ReleaseStringUTFChars(setid_string, setid);
}

@@ -1771,26 +1783,44 @@ static void android_location_GnssNetworkConnectivityHandler_update_network_state
                                                                       jint type,
                                                                       jboolean roaming,
                                                                       jboolean available,
                                                                       jstring extraInfo,
                                                                       jstring apn) {
    if (agnssRilIface != nullptr) {
                                                                       jstring apn,
                                                                       jlong networkHandle,
                                                                       jshort capabilities) {
    if (agnssRilIface == nullptr) {
        ALOGE("AGnssRilInterface does not exist");
        return;
    }

    const char *c_apn = env->GetStringUTFChars(apn, nullptr);
    const android::hardware::hidl_string hidl_apn{c_apn};
    if (agnssRilIface_V2_0 != nullptr) {
        IAGnssRil_V2_0::NetworkAttributes networkAttributes = {
            .networkHandle = static_cast<uint64_t>(networkHandle),
            .isConnected = static_cast<bool>(connected),
            .capabilities = static_cast<uint16_t>(capabilities),
            .apn = hidl_apn
        };

        auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
        if (!result.isOk() || !result) {
            ALOGE("updateNetworkState_2_0 failed");
        }
    } else {
        auto result = agnssRilIface->updateNetworkState(connected,
                                                       static_cast<IAGnssRil::NetworkType>(type),
                                                       roaming);
                static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
        if (!result.isOk() || !result) {
            ALOGE("updateNetworkState failed");
        }

        const char *c_apn = env->GetStringUTFChars(apn, nullptr);
        result = agnssRilIface->updateNetworkAvailability(available, c_apn);
        if (!hidl_apn.empty()) {
            result = agnssRilIface->updateNetworkAvailability(available, hidl_apn);
            if (!result.isOk() || !result) {
                ALOGE("updateNetworkAvailability failed");
            }
        }
    }

    env->ReleaseStringUTFChars(apn, c_apn);
    } else {
        ALOGE("AGnssRilInterface does not exist");
    }
}

static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
@@ -2098,7 +2128,6 @@ static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
    }
}


static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
    if (gnssBatchingIface == nullptr) {
        return 0; // batching not supported, size = 0
@@ -2317,7 +2346,7 @@ static const JNINativeMethod sNetworkConnectivityMethods[] = {
    {"native_is_agps_ril_supported", "()Z",
            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
    {"native_update_network_state",
            "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
            "(ZIZZLjava/lang/String;JS)V",
            reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
    {"native_agps_data_conn_open",
            "(Ljava/lang/String;I)V",