diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java index 98578b2194131..4f45602276b5f 100644 --- a/location/java/android/location/GnssCapabilities.java +++ b/location/java/android/location/GnssCapabilities.java @@ -138,6 +138,7 @@ public final class GnssCapabilities implements Parcelable { @SubHalMeasurementCorrectionsCapabilityFlags int measurementCorrectionsFlags, @SubHalPowerCapabilityFlags int powerFlags, @NonNull List gnssSignalTypes) { + Objects.requireNonNull(gnssSignalTypes); mTopFlags = topFlags; mMeasurementCorrectionsFlags = measurementCorrectionsFlags; mPowerFlags = powerFlags; @@ -189,6 +190,21 @@ public final class GnssCapabilities implements Parcelable { } } + /** + * Returns a new GnssCapabilities object with a list of GnssSignalType. + * + * @hide + */ + public GnssCapabilities withSignalTypes(@NonNull List gnssSignalTypes) { + Objects.requireNonNull(gnssSignalTypes); + if (mGnssSignalTypes.equals(gnssSignalTypes)) { + return this; + } else { + return new GnssCapabilities(mTopFlags, mMeasurementCorrectionsFlags, mPowerFlags, + new ArrayList<>(gnssSignalTypes)); + } + } + /** * Returns {@code true} if GNSS chipset supports scheduling, {@code false} otherwise. */ @@ -452,7 +468,8 @@ public final class GnssCapabilities implements Parcelable { GnssCapabilities that = (GnssCapabilities) o; return mTopFlags == that.mTopFlags && mMeasurementCorrectionsFlags == that.mMeasurementCorrectionsFlags - && mPowerFlags == that.mPowerFlags; + && mPowerFlags == that.mPowerFlags + && mGnssSignalTypes.equals(that.mGnssSignalTypes); } @Override diff --git a/location/java/android/location/GnssSignalType.java b/location/java/android/location/GnssSignalType.java index f9c6e725cc463..16c3f2ed27d88 100644 --- a/location/java/android/location/GnssSignalType.java +++ b/location/java/android/location/GnssSignalType.java @@ -116,7 +116,7 @@ public final class GnssSignalType implements Parcelable { public String toString() { StringBuilder s = new StringBuilder(); s.append("GnssSignalType["); - s.append(" Constellation=").append(mConstellationType); + s.append("Constellation=").append(mConstellationType); s.append(", CarrierFrequencyHz=").append(mCarrierFrequencyHz); s.append(", CodeType=").append(mCodeType); s.append(']'); 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 1fa56bc3e0555..2d015a5d58c77 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 @@ -25,6 +25,7 @@ import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.GnssMeasurementsEvent; import android.location.GnssNavigationMessage; +import android.location.GnssSignalType; import android.location.GnssStatus; import android.location.Location; import android.os.Binder; @@ -1144,6 +1145,13 @@ public class GnssNative { onCapabilitiesChanged(oldCapabilities, mCapabilities); } + @NativeEntryPoint + void setSignalTypeCapabilities(List signalTypes) { + GnssCapabilities oldCapabilities = mCapabilities; + mCapabilities = oldCapabilities.withSignalTypes(signalTypes); + onCapabilitiesChanged(oldCapabilities, mCapabilities); + } + private void onCapabilitiesChanged(GnssCapabilities oldCapabilities, GnssCapabilities newCapabilities) { Binder.withCleanCallingIdentity(() -> { diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 5fa8dcced6711..3c788197b1916 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -152,7 +152,7 @@ cc_defaults { "android.hardware.broadcastradio@1.0", "android.hardware.broadcastradio@1.1", "android.hardware.contexthub@1.0", - "android.hardware.gnss-V2-cpp", + "android.hardware.gnss-V3-cpp", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index 0531ae2a8ccd4..f3ba484f62a6e 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -61,7 +61,7 @@ cc_defaults { "libnativehelper", "libhardware_legacy", "libutils", - "android.hardware.gnss-V2-cpp", + "android.hardware.gnss-V3-cpp", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", diff --git a/services/core/jni/gnss/GnssCallback.cpp b/services/core/jni/gnss/GnssCallback.cpp index b931e915a7538..3c1ac1e4144e5 100644 --- a/services/core/jni/gnss/GnssCallback.cpp +++ b/services/core/jni/gnss/GnssCallback.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "GnssCallbckJni" +#define LOG_TAG "GnssCallbackJni" #include "GnssCallback.h" @@ -31,6 +31,7 @@ using hardware::Return; using hardware::Void; using GnssLocationAidl = android::hardware::gnss::GnssLocation; +using GnssSignalType = android::hardware::gnss::GnssSignalType; using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation; using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation; using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback; @@ -42,11 +43,18 @@ jmethodID method_reportGnssServiceDied; namespace { +jclass class_arrayList; +jclass class_gnssSignalType; + +jmethodID method_arrayListAdd; +jmethodID method_arrayListCtor; +jmethodID method_gnssSignalTypeCreate; jmethodID method_reportLocation; jmethodID method_reportStatus; jmethodID method_reportSvStatus; jmethodID method_reportNmea; jmethodID method_setTopHalCapabilities; +jmethodID method_setSignalTypeCapabilities; jmethodID method_setGnssYearOfHardware; jmethodID method_setGnssHardwareModelName; jmethodID method_requestLocation; @@ -88,6 +96,8 @@ void Gnss_class_init_once(JNIEnv* env, jclass& clazz) { method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); + method_setSignalTypeCapabilities = + env->GetMethodID(clazz, "setSignalTypeCapabilities", "(Ljava/util/List;)V"); method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName", "(Ljava/lang/String;)V"); @@ -95,16 +105,58 @@ void Gnss_class_init_once(JNIEnv* env, jclass& clazz) { method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); + + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + class_arrayList = (jclass)env->NewGlobalRef(arrayListClass); + method_arrayListCtor = env->GetMethodID(class_arrayList, "", "()V"); + method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z"); + + jclass gnssSignalTypeClass = env->FindClass("android/location/GnssSignalType"); + class_gnssSignalType = (jclass)env->NewGlobalRef(gnssSignalTypeClass); + method_gnssSignalTypeCreate = + env->GetStaticMethodID(class_gnssSignalType, "create", + "(IDLjava/lang/String;)Landroid/location/GnssSignalType;"); } Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) { - ALOGD("GnssCallbackAidl::%s: %du\n", __func__, capabilities); + ALOGD("%s: %du\n", __func__, capabilities); JNIEnv* env = getJniEnv(); env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Status::ok(); } +namespace { + +jobject translateSingleSignalType(JNIEnv* env, const GnssSignalType& signalType) { + jstring jstringCodeType = env->NewStringUTF(signalType.codeType.c_str()); + jobject signalTypeObject = + env->CallStaticObjectMethod(class_gnssSignalType, method_gnssSignalTypeCreate, + signalType.constellation, signalType.carrierFrequencyHz, + jstringCodeType); + env->DeleteLocalRef(jstringCodeType); + return signalTypeObject; +} + +} // anonymous namespace + +Status GnssCallbackAidl::gnssSetSignalTypeCapabilitiesCb( + const std::vector& signalTypes) { + ALOGD("%s: %d signal types", __func__, (int)signalTypes.size()); + JNIEnv* env = getJniEnv(); + jobject arrayList = env->NewObject(class_arrayList, method_arrayListCtor); + for (auto& signalType : signalTypes) { + jobject signalTypeObject = translateSingleSignalType(env, signalType); + env->CallBooleanMethod(arrayList, method_arrayListAdd, signalTypeObject); + // Delete Local Refs + env->DeleteLocalRef(signalTypeObject); + } + env->CallVoidMethod(mCallbacksObj, method_setSignalTypeCapabilities, arrayList); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(arrayList); + return Status::ok(); +} + Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue status) { JNIEnv* env = getJniEnv(); env->CallVoidMethod(mCallbacksObj, method_reportStatus, status); diff --git a/services/core/jni/gnss/GnssCallback.h b/services/core/jni/gnss/GnssCallback.h index a7f96fb0f5c70..33acec8b5660e 100644 --- a/services/core/jni/gnss/GnssCallback.h +++ b/services/core/jni/gnss/GnssCallback.h @@ -61,6 +61,8 @@ void Gnss_class_init_once(JNIEnv* env, jclass& clazz); class GnssCallbackAidl : public hardware::gnss::BnGnssCallback { public: binder::Status gnssSetCapabilitiesCb(const int capabilities) override; + binder::Status gnssSetSignalTypeCapabilitiesCb( + const std::vector& signalTypes) override; binder::Status gnssStatusCb(const GnssStatusValue status) override; binder::Status gnssSvStatusCb(const std::vector& svInfoList) override; binder::Status gnssLocationCb(const hardware::gnss::GnssLocation& location) override; @@ -180,4 +182,4 @@ private: } // namespace android::gnss -#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H \ No newline at end of file +#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H