Merge "Add AGnssRil AIDL HAL (frameworks/base)"

This commit is contained in:
Shinru Han
2022-01-11 03:35:22 +00:00
committed by Android (Google) Code Review
9 changed files with 592 additions and 124 deletions

View File

@@ -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;
} else {
type = AGPS_REF_LOCATION_TYPE_GSM_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 {
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.");
}

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -25,6 +25,8 @@ cc_library_shared {
srcs: [
"AGnss.cpp",
"AGnssCallback.cpp",
"AGnssRil.cpp",
"AGnssRilCallback.cpp",
"GnssAntennaInfoCallback.cpp",
"GnssBatching.cpp",
"GnssBatchingCallback.cpp",

View File

@@ -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() {