Merge "Add gnssRequestLocationCb to IGnssCallback.hal and injectBestLocation to IGnss.hal"
diff --git a/gnss/1.1/IGnss.hal b/gnss/1.1/IGnss.hal
index 0c3d876..096f251 100644
--- a/gnss/1.1/IGnss.hal
+++ b/gnss/1.1/IGnss.hal
@@ -17,6 +17,7 @@
 package android.hardware.gnss@1.1;
 
 import @1.0::IGnss;
+import @1.0::GnssLocation;
 
 import IGnssCallback;
 import IGnssConfiguration;
@@ -78,4 +79,16 @@
     * @return gnssMeasurementIface Handle to the IGnssMeasurement interface.
     */
     getExtensionGnssMeasurement_1_1() generates (IGnssMeasurement gnssMeasurementIface);
+
+    /**
+     * Injects current location from the best available location provider.
+     *
+     * Unlike injectLocation, this method may inject a recent GNSS location from the HAL
+     * implementation, if that is the best available location known to the framework.
+     *
+     * @param location Location information from the best available location provider.
+     *
+     * @return success Returns true if successful.
+     */
+    injectBestLocation(GnssLocation location) generates (bool success);
 };
\ No newline at end of file
diff --git a/gnss/1.1/IGnssCallback.hal b/gnss/1.1/IGnssCallback.hal
index 7a2849e..9fd71ae 100644
--- a/gnss/1.1/IGnssCallback.hal
+++ b/gnss/1.1/IGnssCallback.hal
@@ -35,4 +35,17 @@
      * @param name String providing the name of the GNSS HAL implementation
      */
     gnssNameCb(string name);
+
+    /**
+     * Callback for requesting Location.
+     *
+     * HAL implementation shall call this when it wants the framework to provide location to assist
+     * with GNSS HAL operation. For example, to assist with time to first fix, and/or error
+     * recovery, it may ask for a location that is independent from GNSS (e.g. from the "network"
+     * LocationProvier), or to provide a Device-Based-Hybrid location to supplement A-GPS/GNSS
+     * emergency call flows managed by the GNSS HAL.
+     *
+     * @param independentFromGnss True if requesting a location that is independent from GNSS.
+     */
+    gnssRequestLocationCb(bool independentFromGnss);
 };
\ No newline at end of file
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h
index a06db5d..6aab3cb 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.h
+++ b/gnss/1.1/vts/functional/gnss_hal_test.h
@@ -74,6 +74,9 @@
         }
         Return<void> gnssAcquireWakelockCb() override { return Void(); }
         Return<void> gnssReleaseWakelockCb() override { return Void(); }
+        Return<void> gnssRequestLocationCb(bool /* independentFromGnss */) override {
+            return Void();
+        }
         Return<void> gnssRequestTimeCb() override { return Void(); }
         // Actual (test) callback handlers
         Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
index c9e36a9..55f0acc 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp
@@ -23,6 +23,7 @@
 using android::hardware::hidl_vec;
 
 using android::hardware::gnss::V1_0::GnssConstellationType;
+using android::hardware::gnss::V1_0::GnssLocation;
 using android::hardware::gnss::V1_1::IGnssConfiguration;
 using android::hardware::gnss::V1_1::IGnssMeasurement;
 
@@ -363,4 +364,35 @@
     result = gnss_configuration_hal->setBlacklist(sources);
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
-}
\ No newline at end of file
+}
+
+/*
+ * InjectBestLocation
+ *
+ * Ensure successfully injecting a location.
+ */
+TEST_F(GnssHalTest, InjectBestLocation) {
+    GnssLocation gnssLocation = {.gnssLocationFlags = 0,  // set below
+                                 .latitudeDegrees = 43.0,
+                                 .longitudeDegrees = -180,
+                                 .altitudeMeters = 1000,
+                                 .speedMetersPerSec = 0,
+                                 .bearingDegrees = 0,
+                                 .horizontalAccuracyMeters = 0.1,
+                                 .verticalAccuracyMeters = 0.1,
+                                 .speedAccuracyMetersPerSecond = 0.1,
+                                 .bearingAccuracyDegrees = 0.1,
+                                 .timestamp = 1534567890123L};
+    gnssLocation.gnssLocationFlags |=
+        GnssLocationFlags::HAS_LAT_LONG | GnssLocationFlags::HAS_ALTITUDE |
+        GnssLocationFlags::HAS_SPEED | GnssLocationFlags::HAS_HORIZONTAL_ACCURACY |
+        GnssLocationFlags::HAS_VERTICAL_ACCURACY | GnssLocationFlags::HAS_SPEED_ACCURACY |
+        GnssLocationFlags::HAS_BEARING | GnssLocationFlags::HAS_BEARING_ACCURACY;
+
+    CheckLocation(gnssLocation, true);
+
+    auto result = gnss_hal_->injectBestLocation(gnssLocation);
+
+    ASSERT_TRUE(result.isOk());
+    EXPECT_TRUE(result);
+}