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

Commit 674a3dcb authored by Anil Admal's avatar Anil Admal Committed by Android (Google) Code Review
Browse files

Merge "Provide network capabilities to GNSS HAL (framework changes)"

parents 44cf3f75 b4995e2f
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",