Duty Cycling and Low Power Mode GNSS feature implementations

Implementaion of 2 GNSS Android-P features:
- The Duty Cycling API to enable high accuracy applications development
- The Low Power Mode GNSS API to save power when indoor

Bug: 64009176
Test: Existing unit tests still pass.
Change-Id: I3ba3b86a635a54927c694fdd66a038757e843937
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 4cbe64d..246bd42 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -18,8 +18,11 @@
 
 #define LOG_NDEBUG 0
 
+#include <android/hardware/gnss/1.0/IGnss.h>
 #include <android/hardware/gnss/1.1/IGnss.h>
 
+#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
 #include <nativehelper/JNIHelp.h>
 #include "jni.h"
 #include "hardware_legacy/power.h"
@@ -77,23 +80,23 @@
 using android::hardware::hidl_vec;
 using android::hardware::hidl_death_recipient;
 using android::hidl::base::V1_0::IBase;
-
 using android::hardware::gnss::V1_0::GnssLocation;
 using android::hardware::gnss::V1_0::GnssLocationFlags;
-
+using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
+using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
+using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
+using android::hardware::gnss::V1_0::IGnss;
 using android::hardware::gnss::V1_0::IAGnss;
 using android::hardware::gnss::V1_0::IAGnssCallback;
 using android::hardware::gnss::V1_0::IAGnssCallback;
 using android::hardware::gnss::V1_0::IAGnssRil;
 using android::hardware::gnss::V1_0::IAGnssRilCallback;
-using android::hardware::gnss::V1_0::IGnss;
 using android::hardware::gnss::V1_0::IGnssBatching;
 using android::hardware::gnss::V1_0::IGnssBatchingCallback;
 using android::hardware::gnss::V1_0::IGnssConfiguration;
 using android::hardware::gnss::V1_0::IGnssDebug;
 using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
 using android::hardware::gnss::V1_0::IGnssGeofencing;
-using android::hardware::gnss::V1_0::IGnssMeasurement;
 using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
 using android::hardware::gnss::V1_0::IGnssNavigationMessage;
 using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
@@ -101,8 +104,6 @@
 using android::hardware::gnss::V1_0::IGnssNiCallback;
 using android::hardware::gnss::V1_0::IGnssXtra;
 using android::hardware::gnss::V1_0::IGnssXtraCallback;
-
-using IGnssV1_1 = android::hardware::gnss::V1_1::IGnss;
 using android::hardware::gnss::V1_1::IGnssCallback;
 
 struct GnssDeathRecipient : virtual public hidl_death_recipient
@@ -118,7 +119,7 @@
 
 sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
 sp<IGnss> gnssHal = nullptr;
-sp<IGnssV1_1> gnssHalV1_1 = nullptr;
+sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
 sp<IGnssXtra> gnssXtraIface = nullptr;
 sp<IAGnssRil> agnssRilIface = nullptr;
 sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
@@ -127,7 +128,8 @@
 sp<IGnssDebug> gnssDebugIface = nullptr;
 sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
 sp<IGnssNi> gnssNiIface = nullptr;
-sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
+sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
+sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
 sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
 
 #define WAKE_LOCK_NAME  "GPS"
@@ -1068,11 +1070,13 @@
         LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
     }
 
-    gnssHal = gnssHalV1_1 = IGnssV1_1::getService();
-
-    if (gnssHal == nullptr) {
+    // TODO(b/31632518)
+    gnssHal_V1_1 = IGnss_V1_1::getService();
+    if (gnssHal_V1_1 == nullptr) {
         ALOGD("gnssHal 1.1 was null, trying 1.0");
         gnssHal = IGnss::getService();
+    } else {
+        gnssHal = gnssHal_V1_1;
     }
 
     if (gnssHal != nullptr) {
@@ -1116,11 +1120,21 @@
             gnssNavigationMessageIface = gnssNavigationMessage;
         }
 
-        auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
-        if (!gnssMeasurement.isOk()) {
-            ALOGD("Unable to get a handle to GnssMeasurement");
+        if (gnssHal_V1_1 != nullptr) {
+             auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
+             if (!gnssMeasurement.isOk()) {
+                 ALOGD("Unable to get a handle to GnssMeasurement");
+             } else {
+                 gnssMeasurementIface_V1_1 = gnssMeasurement;
+                 gnssMeasurementIface = gnssMeasurementIface_V1_1;
+             }
         } else {
-            gnssMeasurementIface = gnssMeasurement;
+             auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
+             if (!gnssMeasurement_V1_0.isOk()) {
+                 ALOGD("Unable to get a handle to GnssMeasurement");
+             } else {
+                 gnssMeasurementIface = gnssMeasurement_V1_0;
+             }
         }
 
         auto gnssDebug = gnssHal->getExtensionGnssDebug();
@@ -1195,8 +1209,8 @@
     sp<IGnssCallback> gnssCbIface = new GnssCallback();
 
     Return<bool> result = false;
-    if (gnssHalV1_1 != nullptr) {
-        result = gnssHalV1_1->setCallback_1_1(gnssCbIface);
+    if (gnssHal_V1_1 != nullptr) {
+        result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
     } else {
         result = gnssHal->setCallback(gnssCbIface);
     }
@@ -1255,21 +1269,27 @@
 
 static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
         jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
-        jint preferred_time) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
-                                     static_cast<IGnss::GnssPositionRecurrence>(recurrence),
-                                     min_interval,
-                                     preferred_accuracy,
-                                     preferred_time);
-        if (!result.isOk()) {
-            ALOGE("%s: GNSS setPositionMode failed\n", __func__);
-            return JNI_FALSE;
-        } else {
-            return result;
-        }
+        jint preferred_time, jboolean low_power_mode) {
+    Return<bool> result = false;
+    if (gnssHal_V1_1 != nullptr) {
+         result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
+                                                             static_cast<IGnss::GnssPositionRecurrence>(recurrence),
+                                                             min_interval,
+                                                             preferred_accuracy,
+                                                             preferred_time,
+                                                             low_power_mode);
+     } else if (gnssHal != nullptr) {
+         result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
+                                                                      static_cast<IGnss::GnssPositionRecurrence>(recurrence),
+                                                                      min_interval,
+                                                                      preferred_accuracy,
+                                                                      preferred_time);
+    }
+    if (!result.isOk()) {
+       ALOGE("%s: GNSS setPositionMode failed\n", __func__);
+       return JNI_FALSE;
     } else {
-        return JNI_FALSE;
+       return result;
     }
 }
 
@@ -1679,16 +1699,29 @@
 }
 
 static jboolean android_location_GnssLocationProvider_start_measurement_collection(
-        JNIEnv* env,
-        jobject obj) {
+        JNIEnv* /* env */,
+        jobject /* obj */,
+        jboolean enableFullTracking) {
     if (gnssMeasurementIface == nullptr) {
         ALOGE("GNSS Measurement interface is not available.");
         return JNI_FALSE;
     }
 
     sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
-    IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
-    if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
+    IGnssMeasurement_V1_0::GnssMeasurementStatus result =
+                    IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
+    if (gnssMeasurementIface_V1_1 != nullptr) {
+         result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
+                        enableFullTracking);
+    } else {
+        if (enableFullTracking == JNI_TRUE) {
+            // full tracking mode not supported in 1.0 HAL
+            return JNI_FALSE;
+        }
+        result = gnssMeasurementIface->setCallback(cbIface);
+    }
+
+    if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
         ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
               static_cast<int32_t>(result));
         return JNI_FALSE;
@@ -1941,8 +1974,8 @@
     {"native_cleanup", "()V", reinterpret_cast<void *>(
             android_location_GnssLocationProvider_cleanup)},
     {"native_set_position_mode",
-            "(IIIII)Z",
-            reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
+                "(IIIIIZ)Z",
+                reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
     {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
     {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
     {"native_delete_aiding_data",
@@ -2010,7 +2043,7 @@
             reinterpret_cast<void *>(
                     android_location_GnssLocationProvider_is_measurement_supported)},
     {"native_start_measurement_collection",
-            "()Z",
+             "(Z)Z",
             reinterpret_cast<void *>(
                     android_location_GnssLocationProvider_start_measurement_collection)},
     {"native_stop_measurement_collection",