Check gnssPowerStats increase after getting a location

Bug: 168123084
Test: on device
Change-Id: I5a306f91d1223cdc9f3616583d59cd2c707c80ea
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 435afa3..6061eec 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -20,7 +20,6 @@
 #include <log/log.h>
 #include "GnssConfiguration.h"
 #include "GnssMeasurementInterface.h"
-#include "GnssPowerIndication.h"
 #include "GnssPsds.h"
 
 namespace aidl::android::hardware::gnss {
@@ -73,8 +72,11 @@
 ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
         std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
     ALOGD("Gnss::getExtensionGnssPowerIndication");
+    if (mGnssPowerIndication == nullptr) {
+        mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
+    }
 
-    *iGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
+    *iGnssPowerIndication = mGnssPowerIndication;
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index bccc7f2..76ebe4d 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
 #include <aidl/android/hardware/gnss/BnGnssPsds.h>
 #include "GnssConfiguration.h"
+#include "GnssPowerIndication.h"
 
 namespace aidl::android::hardware::gnss {
 
@@ -38,6 +39,7 @@
             std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
+    std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
 
   private:
     static std::shared_ptr<IGnssCallback> sGnssCallback;
diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp
index 9529ec9..263715c 100644
--- a/gnss/aidl/default/GnssHidlHal.cpp
+++ b/gnss/aidl/default/GnssHidlHal.cpp
@@ -31,11 +31,19 @@
     } else {
         mGnssConfigurationAidl = iGnss->mGnssConfiguration;
     }
+
+    std::shared_ptr<IGnssPowerIndication> iGnssPowerIndication;
+    status = iGnss->getExtensionGnssPowerIndication(&iGnssPowerIndication);
+    if (!status.isOk()) {
+        ALOGE("Failed to getExtensionGnssPowerIndication.");
+    } else {
+        mGnssPowerIndicationAidl = iGnss->mGnssPowerIndication;
+    }
 };
 
 hidl_vec<GnssSvInfo> GnssHidlHal::filterBlocklistedSatellitesV2_1(
         hidl_vec<GnssSvInfo> gnssSvInfoList) {
-    ALOGD("filterBlocklistSatellitesV2_1 - overridden by GnssHidlHal class");
+    ALOGD("GnssHidlHal::filterBlocklistSatellitesV2_1");
     if (mGnssConfigurationAidl == nullptr) {
         ALOGE("Handle to AIDL GnssConfiguration is not available.");
         return gnssSvInfoList;
@@ -51,4 +59,8 @@
     return gnssSvInfoList;
 }
 
+void GnssHidlHal::notePowerConsumption() {
+    mGnssPowerIndicationAidl->notePowerConsumption();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h
index 93a79a1..5fb4f97 100644
--- a/gnss/aidl/default/GnssHidlHal.h
+++ b/gnss/aidl/default/GnssHidlHal.h
@@ -32,9 +32,11 @@
     filterBlocklistedSatellitesV2_1(
             hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList)
             override;
+    void notePowerConsumption() override;
 
     std::shared_ptr<Gnss> mGnssAidl;
     std::shared_ptr<GnssConfiguration> mGnssConfigurationAidl;
+    std::shared_ptr<GnssPowerIndication> mGnssPowerIndicationAidl;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPowerIndication.cpp b/gnss/aidl/default/GnssPowerIndication.cpp
index 429cc8c..4dec1c6 100644
--- a/gnss/aidl/default/GnssPowerIndication.cpp
+++ b/gnss/aidl/default/GnssPowerIndication.cpp
@@ -50,13 +50,19 @@
     };
     GnssPowerStats gnssPowerStats = {
             .elapsedRealtime = elapsedRealtime,
-            .totalEnergyMilliJoule = 1.59975e+3,
-            .singlebandTrackingModeEnergyMilliJoule = 1.2342e+3,
-            .multibandTrackingModeEnergyMilliJoule = 3.653e+2,
+            .totalEnergyMilliJoule = 1.500e+3 + numLocationReported * 22.0,
+            .singlebandTrackingModeEnergyMilliJoule = 0.0,
+            .multibandTrackingModeEnergyMilliJoule = 1.28e+2 + numLocationReported * 4.0,
+            .singlebandAcquisitionModeEnergyMilliJoule = 0.0,
+            .multibandAcquisitionModeEnergyMilliJoule = 3.65e+2 + numLocationReported * 15.0,
             .otherModesEnergyMilliJoule = {1.232e+2, 3.234e+3},
     };
     sCallback->gnssPowerStatsCb(gnssPowerStats);
     return ndk::ScopedAStatus::ok();
 }
 
+void GnssPowerIndication::notePowerConsumption() {
+    numLocationReported++;
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssPowerIndication.h b/gnss/aidl/default/GnssPowerIndication.h
index e32fd72..93ca0b7 100644
--- a/gnss/aidl/default/GnssPowerIndication.h
+++ b/gnss/aidl/default/GnssPowerIndication.h
@@ -26,12 +26,16 @@
             const std::shared_ptr<IGnssPowerIndicationCallback>& callback) override;
     ndk::ScopedAStatus requestGnssPowerStats() override;
 
+    void notePowerConsumption();
+
   private:
     // Guarded by mMutex
     static std::shared_ptr<IGnssPowerIndicationCallback> sCallback;
 
     // Synchronization lock for sCallback
     mutable std::mutex mMutex;
+
+    int numLocationReported;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index ae0551d..9086b3d 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -30,6 +30,7 @@
 using android::hardware::gnss::ElapsedRealtime;
 using android::hardware::gnss::GnssClock;
 using android::hardware::gnss::GnssMeasurement;
+using android::hardware::gnss::GnssPowerStats;
 using android::hardware::gnss::IGnss;
 using android::hardware::gnss::IGnssConfiguration;
 using android::hardware::gnss::IGnssMeasurementCallback;
@@ -168,9 +169,12 @@
  * TestGnssPowerIndication
  * 1. Gets the GnssPowerIndicationExtension.
  * 2. Sets a GnssPowerIndicationCallback.
- * 3.
+ * 3. Requests and verifies the 1st GnssPowerStats is received.
+ * 4. Gets a location.
+ * 5. Requests the 2nd GnssPowerStats, and verifies it has larger values than the 1st one.
  */
 TEST_P(GnssHalTest, TestGnssPowerIndication) {
+    // Set up gnssPowerIndication and callback
     sp<IGnssPowerIndication> iGnssPowerIndication;
     auto status = aidl_gnss_hal_->getExtensionGnssPowerIndication(&iGnssPowerIndication);
     ASSERT_TRUE(status.isOk());
@@ -186,10 +190,49 @@
 
     EXPECT_EQ(gnssPowerIndicationCallback->capabilities_cbq_.calledCount(), 1);
 
+    // Request and verify a GnssPowerStats is received
+    gnssPowerIndicationCallback->gnss_power_stats_cbq_.reset();
     iGnssPowerIndication->requestGnssPowerStats();
+
     EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve(
             gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec));
     EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 1);
+    auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
+
+    // Get a location and request another GnssPowerStats
+    gnss_cb_->location_cbq_.reset();
+    StartAndCheckFirstLocation();
+
+    // Request and verify the 2nd GnssPowerStats has larger values than the 1st one
+    iGnssPowerIndication->requestGnssPowerStats();
+
+    EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve(
+            gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec));
+    EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 2);
+    auto powerStats2 = gnssPowerIndicationCallback->last_gnss_power_stats_;
+
+    // Elapsed realtime must increase
+    EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs);
+
+    // Total energy must increase
+    EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule);
+
+    // At least oone of singleband and multiband acquisition energy must increase
+    bool singlebandAcqEnergyIncreased = powerStats2.singlebandAcquisitionModeEnergyMilliJoule >
+                                        powerStats1.singlebandAcquisitionModeEnergyMilliJoule;
+    bool multibandAcqEnergyIncreased = powerStats2.multibandAcquisitionModeEnergyMilliJoule >
+                                       powerStats1.multibandAcquisitionModeEnergyMilliJoule;
+    EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased);
+
+    // At least one of singleband and multiband tracking energy must increase
+    bool singlebandTrackingEnergyIncreased = powerStats2.singlebandTrackingModeEnergyMilliJoule >
+                                             powerStats1.singlebandTrackingModeEnergyMilliJoule;
+    bool multibandTrackingEnergyIncreased = powerStats2.multibandTrackingModeEnergyMilliJoule >
+                                            powerStats1.multibandTrackingModeEnergyMilliJoule;
+    EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased);
+
+    // Clean up
+    StopAndClearLocations();
 }
 
 /*
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index a6e8f58..a1d6981 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -132,6 +132,7 @@
     mutable std::mutex mMutex;
     virtual hidl_vec<V2_1::IGnssCallback::GnssSvInfo> filterBlocklistedSatellitesV2_1(
             hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList);
+    virtual void notePowerConsumption();
 };
 
 template <class T_IGnss>
@@ -219,6 +220,7 @@
             auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
             this->reportSvStatus(svStatus);
             auto currentLocation = getLocationFromHW();
+            notePowerConsumption();
             if (mGnssFd != -1) {
                 // Only report location if the return from hardware is valid
                 // note that we can not merge these two "if" together, if didn't
@@ -245,7 +247,7 @@
 template <class T_IGnss>
 hidl_vec<V2_1::IGnssCallback::GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
         hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) {
-    ALOGD("filterBlocklistedSatellitesV2_1");
+    ALOGD("GnssTemplate::filterBlocklistedSatellitesV2_1");
     for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
         if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
             gnssSvInfoList[i].v2_0.v1_0.svFlag &=
@@ -256,6 +258,11 @@
 }
 
 template <class T_IGnss>
+void GnssTemplate<T_IGnss>::notePowerConsumption() {
+    ALOGD("GnssTemplate::notePowerConsumption");
+}
+
+template <class T_IGnss>
 Return<bool> GnssTemplate<T_IGnss>::stop() {
     ALOGD("stop");
     mIsActive = false;