summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shinru Han <shinruhan@google.com> 2021-12-29 12:04:29 +0800
committer Shinru Han <shinruhan@google.com> 2022-01-06 17:22:21 +0800
commitcfd57bccf626630a111d5cc52987cab9701c49b5 (patch)
tree4125b33b7f7ffa6381647a4fe3ac068a7566dab0
parent855f02889320d37c1fa5853f3c02ca4c86cf9d7d (diff)
Add AGnssRil AIDL HAL (frameworks/base)
Bug: 205185251 Bug: 182975915 Test: atest VtsHalGnssTargetTest Change-Id: I087f7c9ae18a6bc5fdc9bfcbd978ff019341fcec
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java147
-rw-r--r--services/core/java/com/android/server/location/gnss/hal/GnssNative.java15
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp125
-rw-r--r--services/core/jni/gnss/AGnssRil.cpp172
-rw-r--r--services/core/jni/gnss/AGnssRil.h91
-rw-r--r--services/core/jni/gnss/AGnssRilCallback.cpp69
-rw-r--r--services/core/jni/gnss/AGnssRilCallback.h90
-rw-r--r--services/core/jni/gnss/Android.bp2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java3
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() {