diff options
| author | 2021-12-29 12:04:29 +0800 | |
|---|---|---|
| committer | 2022-01-06 17:22:21 +0800 | |
| commit | cfd57bccf626630a111d5cc52987cab9701c49b5 (patch) | |
| tree | 4125b33b7f7ffa6381647a4fe3ac068a7566dab0 | |
| parent | 855f02889320d37c1fa5853f3c02ca4c86cf9d7d (diff) | |
Add AGnssRil AIDL HAL (frameworks/base)
Bug: 205185251
Bug: 182975915
Test: atest VtsHalGnssTargetTest
Change-Id: I087f7c9ae18a6bc5fdc9bfcbd978ff019341fcec
9 files changed, 591 insertions, 123 deletions
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index f1141845f2bd..a8102f3aa33b 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -16,14 +16,15 @@ package com.android.server.location.gnss; -import static android.content.pm.PackageManager.FEATURE_WATCH; - import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; +import static android.content.pm.PackageManager.FEATURE_WATCH; import static android.location.provider.ProviderProperties.ACCURACY_FINE; import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_GSM_CELLID; +import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_LTE_CELLID; +import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_NR_CELLID; import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_UMTS_CELLID; import static com.android.server.location.gnss.hal.GnssNative.AGPS_SETID_TYPE_IMSI; import static com.android.server.location.gnss.hal.GnssNative.AGPS_SETID_TYPE_MSISDN; @@ -84,9 +85,18 @@ import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.telephony.CarrierConfigManager; +import android.telephony.CellIdentity; +import android.telephony.CellIdentityGsm; +import android.telephony.CellIdentityLte; +import android.telephony.CellIdentityNr; +import android.telephony.CellIdentityWcdma; +import android.telephony.CellInfo; +import android.telephony.CellInfoGsm; +import android.telephony.CellInfoLte; +import android.telephony.CellInfoNr; +import android.telephony.CellInfoWcdma; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; @@ -110,6 +120,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -1386,29 +1397,127 @@ public class GnssLocationProvider extends AbstractLocationProvider implements postWithWakeLockHeld(mNtpTimeHelper::retrieveAndInjectNtpTime); } + + private static int getCellType(CellInfo ci) { + if (ci instanceof CellInfoGsm) { + return CellInfo.TYPE_GSM; + } else if (ci instanceof CellInfoWcdma) { + return CellInfo.TYPE_WCDMA; + } else if (ci instanceof CellInfoLte) { + return CellInfo.TYPE_LTE; + } else if (ci instanceof CellInfoNr) { + return CellInfo.TYPE_NR; + } + return CellInfo.TYPE_UNKNOWN; + } + + /** + * Extract the CID/CI for GSM/WCDMA/LTE/NR + * + * @return the cell ID or -1 if invalid + */ + private static long getCidFromCellIdentity(CellIdentity id) { + if (id == null) return -1; + long cid = -1; + switch(id.getType()) { + case CellInfo.TYPE_GSM: cid = ((CellIdentityGsm) id).getCid(); break; + case CellInfo.TYPE_WCDMA: cid = ((CellIdentityWcdma) id).getCid(); break; + case CellInfo.TYPE_LTE: cid = ((CellIdentityLte) id).getCi(); break; + case CellInfo.TYPE_NR: cid = ((CellIdentityNr) id).getNci(); break; + default: break; + } + // If the CID is unreported + if (cid == (id.getType() == CellInfo.TYPE_NR + ? CellInfo.UNAVAILABLE_LONG : CellInfo.UNAVAILABLE)) { + cid = -1; + } + + return cid; + } + + private void setRefLocation(int type, CellIdentity ci) { + String mcc_str = ci.getMccString(); + String mnc_str = ci.getMncString(); + int mcc = mcc_str != null ? Integer.parseInt(mcc_str) : CellInfo.UNAVAILABLE; + int mnc = mnc_str != null ? Integer.parseInt(mnc_str) : CellInfo.UNAVAILABLE; + int lac = CellInfo.UNAVAILABLE; + int tac = CellInfo.UNAVAILABLE; + int pcid = CellInfo.UNAVAILABLE; + int arfcn = CellInfo.UNAVAILABLE; + long cid = CellInfo.UNAVAILABLE_LONG; + + switch (type) { + case AGPS_REF_LOCATION_TYPE_GSM_CELLID: + CellIdentityGsm cig = (CellIdentityGsm) ci; + cid = cig.getCid(); + lac = cig.getLac(); + break; + case AGPS_REF_LOCATION_TYPE_UMTS_CELLID: + CellIdentityWcdma ciw = (CellIdentityWcdma) ci; + cid = ciw.getCid(); + lac = ciw.getLac(); + break; + case AGPS_REF_LOCATION_TYPE_LTE_CELLID: + CellIdentityLte cil = (CellIdentityLte) ci; + cid = cil.getCi(); + tac = cil.getTac(); + pcid = cil.getPci(); + break; + case AGPS_REF_LOCATION_TYPE_NR_CELLID: + CellIdentityNr cin = (CellIdentityNr) ci; + cid = cin.getNci(); + tac = cin.getTac(); + pcid = cin.getPci(); + arfcn = cin.getNrarfcn(); + break; + default: + } + + mGnssNative.setAgpsReferenceLocationCellId( + type, mcc, mnc, lac, cid, tac, pcid, arfcn); + } + private void requestRefLocation() { TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + final int phoneType = phone.getPhoneType(); if (phoneType == TelephonyManager.PHONE_TYPE_GSM) { - GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation(); - if ((gsm_cell != null) && (phone.getNetworkOperator() != null) - && (phone.getNetworkOperator().length() > 3)) { - int type; - int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3)); - int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3)); - int networkType = phone.getNetworkType(); - if (networkType == TelephonyManager.NETWORK_TYPE_UMTS - || networkType == TelephonyManager.NETWORK_TYPE_HSDPA - || networkType == TelephonyManager.NETWORK_TYPE_HSUPA - || networkType == TelephonyManager.NETWORK_TYPE_HSPA - || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) { - type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; + + List<CellInfo> cil = phone.getAllCellInfo(); + if (cil != null) { + HashMap<Integer, CellIdentity> cellIdentityMap = new HashMap<>(); + cil.sort(Comparator.comparingInt( + (CellInfo ci) -> ci.getCellSignalStrength().getAsuLevel()).reversed()); + + for (CellInfo ci : cil) { + int status = ci.getCellConnectionStatus(); + if (status == CellInfo.CONNECTION_PRIMARY_SERVING + || status == CellInfo.CONNECTION_SECONDARY_SERVING) { + CellIdentity c = ci.getCellIdentity(); + int t = getCellType(ci); + if (getCidFromCellIdentity(c) != -1 + && !cellIdentityMap.containsKey(t)) { + cellIdentityMap.put(t, c); + } + } + } + + if (cellIdentityMap.containsKey(CellInfo.TYPE_GSM)) { + setRefLocation(AGPS_REF_LOCATION_TYPE_GSM_CELLID, + cellIdentityMap.get(CellInfo.TYPE_GSM)); + } else if (cellIdentityMap.containsKey(CellInfo.TYPE_WCDMA)) { + setRefLocation(AGPS_REF_LOCATION_TYPE_UMTS_CELLID, + cellIdentityMap.get(CellInfo.TYPE_WCDMA)); + } else if (cellIdentityMap.containsKey(CellInfo.TYPE_LTE)) { + setRefLocation(AGPS_REF_LOCATION_TYPE_LTE_CELLID, + cellIdentityMap.get(CellInfo.TYPE_LTE)); + } else if (cellIdentityMap.containsKey(CellInfo.TYPE_NR)) { + setRefLocation(AGPS_REF_LOCATION_TYPE_NR_CELLID, + cellIdentityMap.get(CellInfo.TYPE_NR)); } else { - type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; + Log.e(TAG, "No available serving cell information."); } - mGnssNative.setAgpsReferenceLocationCellId(type, mcc, mnc, gsm_cell.getLac(), - gsm_cell.getCid()); } else { Log.e(TAG, "Error getting cell location info."); } diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java index a513e0898344..01b1394e6525 100644 --- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java @@ -124,9 +124,12 @@ public class GnssNative { // IMPORTANT - must match OEM definitions, this isn't part of a hal for some reason public static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; public static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; + public static final int AGPS_REF_LOCATION_TYPE_LTE_CELLID = 4; + public static final int AGPS_REF_LOCATION_TYPE_NR_CELLID = 8; @IntDef(prefix = "AGPS_REF_LOCATION_TYPE_", value = {AGPS_REF_LOCATION_TYPE_GSM_CELLID, - AGPS_REF_LOCATION_TYPE_UMTS_CELLID}) + AGPS_REF_LOCATION_TYPE_UMTS_CELLID, AGPS_REF_LOCATION_TYPE_LTE_CELLID, + AGPS_REF_LOCATION_TYPE_NR_CELLID}) @Retention(RetentionPolicy.SOURCE) public @interface AgpsReferenceLocationType {} @@ -930,9 +933,9 @@ public class GnssNative { * Sets AGPS reference cell id location. */ public void setAgpsReferenceLocationCellId(@AgpsReferenceLocationType int type, int mcc, - int mnc, int lac, int cid) { + int mnc, int lac, long cid, int tac, int pcid, int arfcn) { Preconditions.checkState(mRegistered); - mGnssHal.setAgpsReferenceLocationCellId(type, mcc, mnc, lac, cid); + mGnssHal.setAgpsReferenceLocationCellId(type, mcc, mnc, lac, cid, tac, pcid, arfcn); } /** @@ -1433,8 +1436,8 @@ public class GnssNative { } protected void setAgpsReferenceLocationCellId(@AgpsReferenceLocationType int type, int mcc, - int mnc, int lac, int cid) { - native_agps_set_ref_location_cellid(type, mcc, mnc, lac, cid); + int mnc, int lac, long cid, int tac, int pcid, int arfcn) { + native_agps_set_ref_location_cellid(type, mcc, mnc, lac, cid, tac, pcid, arfcn); } protected boolean isPsdsSupported() { @@ -1575,7 +1578,7 @@ public class GnssNative { private static native void native_agps_set_id(int type, String setid); private static native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, - int lac, int cid); + int lac, long cid, int tac, int pcid, int arfcn); // PSDS APIs diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index be656e3f3a27..5d0023ecd53a 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -51,6 +51,7 @@ #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" #include "gnss/AGnss.h" +#include "gnss/AGnssRil.h" #include "gnss/GnssAntennaInfoCallback.h" #include "gnss/GnssBatching.h" #include "gnss/GnssConfiguration.h" @@ -76,8 +77,6 @@ static jmethodID method_setGnssHardwareModelName; static jmethodID method_psdsDownloadRequest; static jmethodID method_reportNiNotification; static jmethodID method_requestLocation; -static jmethodID method_requestRefLocation; -static jmethodID method_requestSetID; static jmethodID method_requestUtcTime; static jmethodID method_reportGnssServiceDied; static jmethodID method_reportGnssPowerStats; @@ -126,7 +125,6 @@ using android::hardware::hidl_string; using android::hardware::hidl_death_recipient; using android::hardware::gnss::V1_0::GnssLocationFlags; -using android::hardware::gnss::V1_0::IAGnssRilCallback; using android::hardware::gnss::V1_0::IGnssNavigationMessage; using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback; using android::hardware::gnss::V1_0::IGnssNi; @@ -158,8 +156,6 @@ using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback; using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback; using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback; using IGnssAntennaInfo = android::hardware::gnss::V2_1::IGnssAntennaInfo; -using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil; -using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil; using IMeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections; using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections; @@ -175,7 +171,9 @@ using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPowerIndicationCallback; using android::hardware::gnss::PsdsType; + using IAGnssAidl = android::hardware::gnss::IAGnss; +using IAGnssRilAidl = android::hardware::gnss::IAGnssRil; using IGnssAidl = android::hardware::gnss::IGnss; using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback; using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching; @@ -208,8 +206,6 @@ sp<IGnssAidl> gnssHalAidl = nullptr; sp<IGnssBatchingAidl> gnssBatchingAidlIface = nullptr; sp<IGnssPsdsAidl> gnssPsdsAidlIface = nullptr; sp<IGnssXtra> gnssXtraIface = nullptr; -sp<IAGnssRil_V1_0> agnssRilIface = nullptr; -sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr; sp<IGnssNi> gnssNiIface = nullptr; sp<IGnssPowerIndication> gnssPowerIndicationIface = nullptr; sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr; @@ -224,6 +220,7 @@ std::unique_ptr<android::gnss::GnssBatchingInterface> gnssBatchingIface = nullpt std::unique_ptr<android::gnss::GnssGeofenceInterface> gnssGeofencingIface = nullptr; std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr; std::unique_ptr<android::gnss::GnssDebugInterface> gnssDebugIface = nullptr; +std::unique_ptr<android::gnss::AGnssRilInterface> agnssRilIface = nullptr; #define WAKE_LOCK_NAME "GPS" @@ -909,29 +906,6 @@ Return<bool> GnssVisibilityControlCallback::isInEmergencySession() { return result; } -/* - * AGnssRilCallback implements the callback methods required by the AGnssRil - * interface. - */ -struct AGnssRilCallback : IAGnssRilCallback { - Return<void> requestSetIdCb(uint32_t setIdFlag) override; - Return<void> requestRefLocCb() override; -}; - -Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - -Return<void> AGnssRilCallback::requestRefLocCb() { - JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_requestRefLocation); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - return Void(); -} - /* Initializes the GNSS service handle. */ static void android_location_gnss_hal_GnssNative_set_gps_service_handle() { gnssHalAidl = waitForVintfService<IGnssAidl>(); @@ -990,8 +964,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;II)V"); method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V"); - method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); - method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification", @@ -1069,6 +1041,7 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc gnss::GnssMeasurement_class_init_once(env, clazz); gnss::GnssNavigationMessage_class_init_once(env, clazz); gnss::AGnss_class_init_once(env, clazz); + gnss::AGnssRil_class_init_once(env, clazz); gnss::Utils_class_init_once(env); } @@ -1124,20 +1097,21 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject } } - if (gnssHal_V2_0 != nullptr) { + if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { + sp<IAGnssRilAidl> agnssRilAidl; + auto status = gnssHalAidl->getExtensionAGnssRil(&agnssRilAidl); + if (checkAidlStatus(status, "Unable to get a handle to AGnssRil interface.")) { + agnssRilIface = std::make_unique<gnss::AGnssRil>(agnssRilAidl); + } + } else 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; + if (checkHidlReturn(agnssRil_V2_0, "Unable to get a handle to AGnssRil_V2_0")) { + agnssRilIface = std::make_unique<gnss::AGnssRil_V2_0>(agnssRil_V2_0); } } else if (gnssHal != nullptr) { auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil(); - if (!agnssRil_V1_0.isOk()) { - ALOGD("Unable to get a handle to AGnssRil"); - } else { - agnssRilIface = agnssRil_V1_0; + if (checkHidlReturn(agnssRil_V1_0, "Unable to get a handle to AGnssRil_V1_0")) { + agnssRilIface = std::make_unique<gnss::AGnssRil_V1_0>(agnssRil_V1_0); } } @@ -1472,12 +1446,9 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl ALOGI("Unable to initialize IGnssNi interface."); } - // Set IAGnssRil.hal callback. - sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback(); - if (agnssRilIface != nullptr) { - auto status = agnssRilIface->setCallback(aGnssRilCbIface); - checkHidlReturn(status, "IAGnssRil setCallback() failed."); - } else { + // Set IAGnssRil callback. + if (agnssRilIface == nullptr || + !agnssRilIface->setCallback(std::make_unique<gnss::AGnssRilCallback>())) { ALOGI("Unable to initialize IAGnssRil interface."); } @@ -1605,31 +1576,13 @@ static void android_location_gnss_hal_GnssNative_delete_aiding_data(JNIEnv* /* e } static void android_location_gnss_hal_GnssNative_agps_set_reference_location_cellid( - JNIEnv* /* env */, jclass, jint type, jint mcc, jint mnc, jint lac, jint cid) { - IAGnssRil_V1_0::AGnssRefLocation location; - + JNIEnv* /* env */, jclass, jint type, jint mcc, jint mnc, jint lac, jlong cid, jint tac, + jint pcid, jint arfcn) { if (agnssRilIface == nullptr) { ALOGE("%s: IAGnssRil interface not available.", __func__); return; } - - 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; - location.cellID.cid = cid; - break; - default: - ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__); - return; - break; - } - - auto result = agnssRilIface->setRefLocation(location); - checkHidlReturn(result, "IAGnssRil setRefLocation() failed."); + agnssRilIface->setRefLocation(type, mcc, mnc, lac, cid, tac, pcid, arfcn); } static void android_location_gnss_hal_GnssNative_agps_set_id(JNIEnv* env, jclass, jint type, @@ -1638,10 +1591,7 @@ static void android_location_gnss_hal_GnssNative_agps_set_id(JNIEnv* env, jclass ALOGE("%s: IAGnssRil interface not available.", __func__); return; } - - ScopedJniString jniSetId{env, setid_string}; - auto result = agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId); - checkHidlReturn(result, "IAGnssRil setSetId() failed."); + agnssRilIface->setSetId(type, setid_string); } static jint android_location_gnss_hal_GnssNative_read_nmea(JNIEnv* env, jclass, @@ -1878,31 +1828,12 @@ static void android_location_GnssNetworkConnectivityHandler_update_network_state jstring apn, jlong networkHandle, jshort capabilities) { - if (agnssRilIface_V2_0 != nullptr) { - ScopedJniString jniApn{env, apn}; - IAGnssRil_V2_0::NetworkAttributes networkAttributes = { - .networkHandle = static_cast<uint64_t>(networkHandle), - .isConnected = static_cast<bool>(connected), - .capabilities = static_cast<uint16_t>(capabilities), - .apn = jniApn - }; - - auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes); - checkHidlReturn(result, "IAGnssRil updateNetworkState_2_0() failed."); - } else if (agnssRilIface != nullptr) { - ScopedJniString jniApn{env, apn}; - hidl_string hidlApn{jniApn}; - auto result = agnssRilIface->updateNetworkState(connected, - static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming); - checkHidlReturn(result, "IAGnssRil updateNetworkState() failed."); - - if (!hidlApn.empty()) { - result = agnssRilIface->updateNetworkAvailability(available, hidlApn); - checkHidlReturn(result, "IAGnssRil updateNetworkAvailability() failed."); - } - } else { + if (agnssRilIface == nullptr) { ALOGE("%s: IAGnssRil interface not available.", __func__); + return; } + agnssRilIface->updateNetworkState(connected, type, roaming, available, apn, networkHandle, + capabilities); } static jboolean android_location_gnss_hal_GnssNative_is_geofence_supported(JNIEnv* /* env */, @@ -2418,7 +2349,7 @@ static const JNINativeMethod sLocationProviderMethods[] = { reinterpret_cast<void*>(android_location_gnss_hal_GnssNative_inject_psds_data)}, {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void*>(android_location_gnss_hal_GnssNative_agps_set_id)}, - {"native_agps_set_ref_location_cellid", "(IIIII)V", + {"native_agps_set_ref_location_cellid", "(IIIIJIII)V", reinterpret_cast<void*>( android_location_gnss_hal_GnssNative_agps_set_reference_location_cellid)}, {"native_set_agps_server", "(ILjava/lang/String;I)V", diff --git a/services/core/jni/gnss/AGnssRil.cpp b/services/core/jni/gnss/AGnssRil.cpp new file mode 100644 index 000000000000..d760b4d2195e --- /dev/null +++ b/services/core/jni/gnss/AGnssRil.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Define LOG_TAG before <log/log.h> to overwrite the default value. +#define LOG_TAG "AGnssRilJni" + +#include "AGnssRil.h" + +#include "Utils.h" + +using android::hardware::gnss::IAGnssRil; +using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil; +using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil; + +namespace android::gnss { + +// Implementation of AGnssRil (AIDL HAL) + +AGnssRil::AGnssRil(const sp<IAGnssRil>& iAGnssRil) : mIAGnssRil(iAGnssRil) { + assert(mIAGnssRil != nullptr); +} + +jboolean AGnssRil::setCallback(const std::unique_ptr<AGnssRilCallback>& callback) { + auto status = mIAGnssRil->setCallback(callback->getAidl()); + return checkAidlStatus(status, "IAGnssRilAidl setCallback() failed."); +} + +jboolean AGnssRil::setSetId(jint type, const jstring& setid_string) { + JNIEnv* env = getJniEnv(); + ScopedJniString jniSetId{env, setid_string}; + auto status = mIAGnssRil->setSetId((IAGnssRil::SetIDType)type, jniSetId.c_str()); + return checkAidlStatus(status, "IAGnssRilAidl setSetId() failed."); +} + +jboolean AGnssRil::setRefLocation(jint type, jint mcc, jint mnc, jint lac, jlong cid, jint tac, + jint pcid, jint arfcn) { + IAGnssRil::AGnssRefLocation location; + location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type); + + switch (location.type) { + case IAGnssRil::AGnssRefLocationType::GSM_CELLID: + case IAGnssRil::AGnssRefLocationType::UMTS_CELLID: + case IAGnssRil::AGnssRefLocationType::LTE_CELLID: + case IAGnssRil::AGnssRefLocationType::NR_CELLID: + location.cellID.mcc = mcc; + location.cellID.mnc = mnc; + location.cellID.lac = lac; + location.cellID.cid = cid; + location.cellID.tac = tac; + location.cellID.pcid = pcid; + location.cellID.arfcn = arfcn; + break; + default: + ALOGE("Unknown cellid (%s:%d).", __FUNCTION__, __LINE__); + return JNI_FALSE; + break; + } + + auto status = mIAGnssRil->setRefLocation(location); + return checkAidlStatus(status, "IAGnssRilAidl dataConnClosed() failed."); +} + +jboolean AGnssRil::updateNetworkState(jboolean connected, jint type, jboolean roaming, + jboolean available, const jstring& apn, jlong networkHandle, + jshort capabilities) { + JNIEnv* env = getJniEnv(); + ScopedJniString jniApn{env, apn}; + IAGnssRil::NetworkAttributes networkAttributes; + networkAttributes.networkHandle = static_cast<int64_t>(networkHandle), + networkAttributes.isConnected = static_cast<bool>(connected), + networkAttributes.capabilities = static_cast<int32_t>(capabilities), + networkAttributes.apn = jniApn.c_str(); + + auto result = mIAGnssRil->updateNetworkState(networkAttributes); + return checkAidlStatus(result, "IAGnssRilAidl updateNetworkState() failed."); +} + +// Implementation of AGnssRil_V1_0 + +AGnssRil_V1_0::AGnssRil_V1_0(const sp<IAGnssRil_V1_0>& iAGnssRil) : mAGnssRil_V1_0(iAGnssRil) { + assert(mIAGnssRil_V1_0 != nullptr); +} + +jboolean AGnssRil_V1_0::setCallback(const std::unique_ptr<AGnssRilCallback>& callback) { + auto result = mAGnssRil_V1_0->setCallback(callback->getV1_0()); + return checkHidlReturn(result, "IAGnssRil_V1_0 setCallback() failed."); +} + +jboolean AGnssRil_V1_0::setSetId(jint type, const jstring& setid_string) { + JNIEnv* env = getJniEnv(); + ScopedJniString jniSetId{env, setid_string}; + auto result = mAGnssRil_V1_0->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId); + return checkHidlReturn(result, "IAGnssRil_V1_0 setSetId() failed."); +} + +jboolean AGnssRil_V1_0::setRefLocation(jint type, jint mcc, jint mnc, jint lac, jlong cid, jint, + jint, jint) { + IAGnssRil_V1_0::AGnssRefLocation location; + 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; + location.cellID.cid = cid; + break; + default: + ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__); + return JNI_FALSE; + break; + } + + auto result = mAGnssRil_V1_0->setRefLocation(location); + return checkHidlReturn(result, "IAGnssRil_V1_0 setRefLocation() failed."); +} + +jboolean AGnssRil_V1_0::updateNetworkState(jboolean connected, jint type, jboolean roaming, + jboolean available, const jstring& apn, + jlong networkHandle, jshort capabilities) { + JNIEnv* env = getJniEnv(); + ScopedJniString jniApn{env, apn}; + hardware::hidl_string hidlApn{jniApn}; + hardware::Return<bool> result(false); + + if (!hidlApn.empty()) { + result = mAGnssRil_V1_0->updateNetworkAvailability(available, hidlApn); + checkHidlReturn(result, "IAGnssRil_V1_0 updateNetworkAvailability() failed."); + } + + result = mAGnssRil_V1_0->updateNetworkState(connected, + static_cast<IAGnssRil_V1_0::NetworkType>(type), + roaming); + return checkHidlReturn(result, "IAGnssRil_V1_0 updateNetworkState() failed."); +} + +// Implementation of AGnssRil_V2_0 + +AGnssRil_V2_0::AGnssRil_V2_0(const sp<IAGnssRil_V2_0>& iAGnssRil) + : AGnssRil_V1_0{iAGnssRil}, mAGnssRil_V2_0(iAGnssRil) { + assert(mIAGnssRil_V2_0 != nullptr); +} + +jboolean AGnssRil_V2_0::updateNetworkState(jboolean connected, jint type, jboolean roaming, + jboolean available, const jstring& apn, + jlong networkHandle, jshort capabilities) { + JNIEnv* env = getJniEnv(); + ScopedJniString jniApn{env, apn}; + IAGnssRil_V2_0::NetworkAttributes networkAttributes = + {.networkHandle = static_cast<uint64_t>(networkHandle), + .isConnected = static_cast<bool>(connected), + .capabilities = static_cast<uint16_t>(capabilities), + .apn = jniApn.c_str()}; + + auto result = mAGnssRil_V2_0->updateNetworkState_2_0(networkAttributes); + return checkHidlReturn(result, "AGnssRil_V2_0 updateNetworkState_2_0() failed."); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/AGnssRil.h b/services/core/jni/gnss/AGnssRil.h new file mode 100644 index 000000000000..ce14a77d56c4 --- /dev/null +++ b/services/core/jni/gnss/AGnssRil.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_AGNSSRIL_H +#define _ANDROID_SERVER_GNSS_AGNSSRIL_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include <android/hardware/gnss/1.0/IAGnssRil.h> +#include <android/hardware/gnss/2.0/IAGnssRil.h> +#include <android/hardware/gnss/BnAGnssRil.h> +#include <log/log.h> + +#include "AGnssRilCallback.h" +#include "jni.h" + +namespace android::gnss { + +class AGnssRilInterface { +public: + virtual ~AGnssRilInterface() {} + virtual jboolean setCallback(const std::unique_ptr<AGnssRilCallback>& callback) = 0; + virtual jboolean setSetId(jint type, const jstring& setid_string) = 0; + virtual jboolean setRefLocation(jint type, jint mcc, jint mnc, jint lac, jlong cid, jint tac, + jint pcid, jint arfcn) = 0; + virtual jboolean updateNetworkState(jboolean connected, jint type, jboolean roaming, + jboolean available, const jstring& apn, jlong networkHandle, + jshort capabilities) = 0; +}; + +class AGnssRil : public AGnssRilInterface { +public: + AGnssRil(const sp<android::hardware::gnss::IAGnssRil>& iAGnssRil); + jboolean setCallback(const std::unique_ptr<AGnssRilCallback>& callback) override; + jboolean setSetId(jint type, const jstring& setid_string) override; + jboolean setRefLocation(jint type, jint mcc, jint mnc, jint lac, jlong cid, jint tac, jint pcid, + jint arfcn) override; + jboolean updateNetworkState(jboolean connected, jint type, jboolean roaming, jboolean available, + const jstring& apn, jlong networkHandle, + jshort capabilities) override; + +private: + const sp<android::hardware::gnss::IAGnssRil> mIAGnssRil; +}; + +class AGnssRil_V1_0 : public AGnssRilInterface { +public: + AGnssRil_V1_0(const sp<android::hardware::gnss::V1_0::IAGnssRil>& iAGnssRil); + jboolean setCallback(const std::unique_ptr<AGnssRilCallback>& callback) override; + jboolean setSetId(jint type, const jstring& setid_string) override; + jboolean setRefLocation(jint type, jint mcc, jint mnc, jint lac, jlong cid, jint, jint, + jint) override; + jboolean updateNetworkState(jboolean connected, jint type, jboolean roaming, jboolean available, + const jstring& apn, jlong networkHandle, + jshort capabilities) override; + +private: + const sp<android::hardware::gnss::V1_0::IAGnssRil> mAGnssRil_V1_0; +}; + +class AGnssRil_V2_0 : public AGnssRil_V1_0 { +public: + AGnssRil_V2_0(const sp<android::hardware::gnss::V2_0::IAGnssRil>& iAGnssRil); + jboolean updateNetworkState(jboolean connected, jint type, jboolean roaming, jboolean available, + const jstring& apn, jlong networkHandle, + jshort capabilities) override; + +private: + const sp<android::hardware::gnss::V2_0::IAGnssRil> mAGnssRil_V2_0; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_AGNSSRIL_H diff --git a/services/core/jni/gnss/AGnssRilCallback.cpp b/services/core/jni/gnss/AGnssRilCallback.cpp new file mode 100644 index 000000000000..b63ccc281aa9 --- /dev/null +++ b/services/core/jni/gnss/AGnssRilCallback.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "AGnssRilCbJni" + +#include "AGnssRilCallback.h" + +namespace android::gnss { + +jmethodID method_requestSetID; +jmethodID method_requestRefLocation; + +using binder::Status; +using hardware::Return; +using hardware::Void; + +void AGnssRil_class_init_once(JNIEnv* env, jclass clazz) { + method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); + method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); +} + +Status AGnssRilCallbackAidl::requestSetIdCb(int setIdflag) { + AGnssRilCallbackUtil::requestSetIdCb(setIdflag); + return Status::ok(); +} + +Status AGnssRilCallbackAidl::requestRefLocCb() { + AGnssRilCallbackUtil::requestRefLocCb(); + return Status::ok(); +} + +Return<void> AGnssRilCallback_V1_0::requestSetIdCb(uint32_t setIdflag) { + AGnssRilCallbackUtil::requestSetIdCb(setIdflag); + return Void(); +} + +Return<void> AGnssRilCallback_V1_0::requestRefLocCb() { + AGnssRilCallbackUtil::requestRefLocCb(); + return Void(); +} + +void AGnssRilCallbackUtil::requestSetIdCb(int setIdflag) { + ALOGD("%s. setIdflag: %d, ", __func__, setIdflag); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdflag); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +void AGnssRilCallbackUtil::requestRefLocCb() { + ALOGD("%s.", __func__); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_requestRefLocation); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/AGnssRilCallback.h b/services/core/jni/gnss/AGnssRilCallback.h new file mode 100644 index 000000000000..2d12089fd6e3 --- /dev/null +++ b/services/core/jni/gnss/AGnssRilCallback.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_GNSS_AGNSSRILCALLBACK_H +#define _ANDROID_SERVER_GNSS_AGNSSRILCALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include <android/hardware/gnss/1.0/IAGnssRil.h> +#include <android/hardware/gnss/BnAGnssRilCallback.h> +#include <log/log.h> + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +void AGnssRil_class_init_once(JNIEnv* env, jclass clazz); + +/* + * AGnssRilCallbackAidl class implements the callback methods required by the + * android::hardware::gnss::IAGnssRil interface. + */ +class AGnssRilCallbackAidl : public android::hardware::gnss::BnAGnssRilCallback { +public: + binder::Status requestSetIdCb(int setIdflag) override; + binder::Status requestRefLocCb() override; +}; + +/* + * AGnssRilCallback_V1_0 implements callback methods required by the IAGnssRilCallback 1.0 + * interface. + */ +class AGnssRilCallback_V1_0 : public android::hardware::gnss::V1_0::IAGnssRilCallback { +public: + // Methods from ::android::hardware::gps::V1_0::IAGnssRilCallback follow. + hardware::Return<void> requestSetIdCb(uint32_t setIdflag) override; + hardware::Return<void> requestRefLocCb() override; +}; + +class AGnssRilCallback { +public: + AGnssRilCallback() {} + sp<AGnssRilCallbackAidl> getAidl() { + if (callbackAidl == nullptr) { + callbackAidl = sp<AGnssRilCallbackAidl>::make(); + } + return callbackAidl; + } + + sp<AGnssRilCallback_V1_0> getV1_0() { + if (callbackV1_0 == nullptr) { + callbackV1_0 = sp<AGnssRilCallback_V1_0>::make(); + } + return callbackV1_0; + } + +private: + sp<AGnssRilCallbackAidl> callbackAidl; + sp<AGnssRilCallback_V1_0> callbackV1_0; +}; + +struct AGnssRilCallbackUtil { + static void requestSetIdCb(int setIdflag); + static void requestRefLocCb(); + +private: + AGnssRilCallbackUtil() = delete; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_AGNSSRILCALLBACK_H
\ No newline at end of file diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index 63f5f526db17..d8de5a604b3d 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -25,6 +25,8 @@ cc_library_shared { srcs: [ "AGnss.cpp", "AGnssCallback.cpp", + "AGnssRil.cpp", + "AGnssRilCallback.cpp", "GnssAntennaInfoCallback.cpp", "GnssBatching.cpp", "GnssBatchingCallback.cpp", diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java index 93a2d317c40e..93929b4cfee2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java @@ -673,7 +673,8 @@ public final class FakeGnssHal extends GnssNative.GnssHal { protected void setAgpsSetId(int type, String setId) {} @Override - protected void setAgpsReferenceLocationCellId(int type, int mcc, int mnc, int lac, int cid) {} + protected void setAgpsReferenceLocationCellId(int type, int mcc, int mnc, int lac, long cid, + int tac, int pcid, int arfcn) {} @Override protected boolean isPsdsSupported() { |