Merge "Pipe GnssSignalType from HAL to Java"
diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java
index 98578b2..4f45602 100644
--- a/location/java/android/location/GnssCapabilities.java
+++ b/location/java/android/location/GnssCapabilities.java
@@ -138,6 +138,7 @@
             @SubHalMeasurementCorrectionsCapabilityFlags int measurementCorrectionsFlags,
             @SubHalPowerCapabilityFlags int powerFlags,
             @NonNull List<GnssSignalType> gnssSignalTypes) {
+        Objects.requireNonNull(gnssSignalTypes);
         mTopFlags = topFlags;
         mMeasurementCorrectionsFlags = measurementCorrectionsFlags;
         mPowerFlags = powerFlags;
@@ -190,6 +191,21 @@
     }
 
     /**
+     * Returns a new GnssCapabilities object with a list of GnssSignalType.
+     *
+     * @hide
+     */
+    public GnssCapabilities withSignalTypes(@NonNull List<GnssSignalType> 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.
      */
     public boolean hasScheduling() {
@@ -452,7 +468,8 @@
         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 f9c6e72..16c3f2e 100644
--- a/location/java/android/location/GnssSignalType.java
+++ b/location/java/android/location/GnssSignalType.java
@@ -116,7 +116,7 @@
     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 1fa56bc..2d015a5d 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.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 @@
         onCapabilitiesChanged(oldCapabilities, mCapabilities);
     }
 
+    @NativeEntryPoint
+    void setSignalTypeCapabilities(List<GnssSignalType> 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 5fa8dcc..3c78819 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -152,7 +152,7 @@
         "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 0531ae2..f3ba484f62 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -61,7 +61,7 @@
         "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 b931e91..3c1ac1e 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::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 @@
 
 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 @@
     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 @@
     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, "<init>", "()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<GnssSignalType>& 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 a7f96fb..33acec8 100644
--- a/services/core/jni/gnss/GnssCallback.h
+++ b/services/core/jni/gnss/GnssCallback.h
@@ -61,6 +61,8 @@
 class GnssCallbackAidl : public hardware::gnss::BnGnssCallback {
 public:
     binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+    binder::Status gnssSetSignalTypeCapabilitiesCb(
+            const std::vector<android::hardware::gnss::GnssSignalType>& signalTypes) override;
     binder::Status gnssStatusCb(const GnssStatusValue status) override;
     binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
     binder::Status gnssLocationCb(const hardware::gnss::GnssLocation& location) override;
@@ -180,4 +182,4 @@
 
 } // namespace android::gnss
 
-#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H
\ No newline at end of file
+#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H