Mock blacklisting satellites in default implementation

- Mock GnssDebug to pass the sanity check.

Bug: 73845705

Test: All Gnss v1.1 VTS tests are passing on gce_x86

Change-Id: I258fb1671d2b682f471207192b8a0feb138c16ab
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 977a22f..44aed2b 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -5,6 +5,7 @@
     vendor: true,
     srcs: [
         "Gnss.cpp",
+        "GnssDebug.cpp",
         "GnssConfiguration.cpp",
         "GnssMeasurement.cpp",
         "service.cpp",
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
index 98a79ee..bbc4940 100644
--- a/gnss/1.1/default/Gnss.cpp
+++ b/gnss/1.1/default/Gnss.cpp
@@ -1,9 +1,11 @@
 #define LOG_TAG "Gnss"
 
+#include <android/hardware/gnss/1.0/types.h>
 #include <log/log.h>
 
 #include "Gnss.h"
-#include "GnssConfiguration.h"
+#include "GnssConstants.h"
+#include "GnssDebug.h"
 #include "GnssMeasurement.h"
 
 namespace android {
@@ -12,10 +14,12 @@
 namespace V1_1 {
 namespace implementation {
 
+using GnssSvFlags = IGnssCallback::GnssSvFlags;
+
 const uint32_t MIN_INTERVAL_MILLIS = 100;
 sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr;
 
-Gnss::Gnss() : mMinIntervalMs(1000) {}
+Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
 
 Gnss::~Gnss() {
     stop();
@@ -36,7 +40,10 @@
     mIsActive = true;
     mThread = std::thread([this]() {
         while (mIsActive == true) {
-            V1_0::GnssLocation location = this->getMockLocation();
+            auto svStatus = this->getMockSvStatus();
+            this->reportSvStatus(svStatus);
+
+            auto location = this->getMockLocation();
             this->reportLocation(location);
 
             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
@@ -70,7 +77,6 @@
 }
 
 Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) {
-    // TODO implement
     return Void();
 }
 
@@ -124,8 +130,7 @@
 }
 
 Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
-    // TODO implement
-    return ::android::sp<::android::hardware::gnss::V1_0::IGnssDebug>{};
+    return new GnssDebug();
 }
 
 Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
@@ -175,8 +180,7 @@
 
 Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
 Gnss::getExtensionGnssConfiguration_1_1() {
-    // TODO implement
-    return new GnssConfiguration();
+    return mGnssConfiguration;
 }
 
 Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>>
@@ -185,27 +189,66 @@
     return new GnssMeasurement();
 }
 
-Return<bool> Gnss::injectBestLocation(const ::android::hardware::gnss::V1_0::GnssLocation&) {
-    // TODO implement
-    return bool{};
+Return<bool> Gnss::injectBestLocation(const GnssLocation&) {
+    return true;
 }
 
-Return<V1_0::GnssLocation> Gnss::getMockLocation() {
-    V1_0::GnssLocation location = {.gnssLocationFlags = 0xFF,
-                                   .latitudeDegrees = 37.4219999,
-                                   .longitudeDegrees = -122.0840575,
-                                   .altitudeMeters = 1.60062531,
-                                   .speedMetersPerSec = 0,
-                                   .bearingDegrees = 0,
-                                   .horizontalAccuracyMeters = 5,
-                                   .verticalAccuracyMeters = 5,
-                                   .speedAccuracyMetersPerSecond = 1,
-                                   .bearingAccuracyDegrees = 90,
-                                   .timestamp = 1519930775453L};
+Return<GnssLocation> Gnss::getMockLocation() const {
+    GnssLocation location = {.gnssLocationFlags = 0xFF,
+                             .latitudeDegrees = kMockLatitudeDegrees,
+                             .longitudeDegrees = kMockLongitudeDegrees,
+                             .altitudeMeters = kMockAltitudeMeters,
+                             .speedMetersPerSec = kMockSpeedMetersPerSec,
+                             .bearingDegrees = kMockBearingDegrees,
+                             .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+                             .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+                             .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+                             .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+                             .timestamp = kMockTimestamp};
     return location;
 }
 
-Return<void> Gnss::reportLocation(const V1_0::GnssLocation& location) {
+Return<GnssSvInfo> Gnss::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
+                                   float elevationDegrees, float azimuthDegrees) const {
+    GnssSvInfo svInfo = {.svid = svid,
+                         .constellation = type,
+                         .cN0Dbhz = cN0DbHz,
+                         .elevationDegrees = elevationDegrees,
+                         .azimuthDegrees = azimuthDegrees,
+                         .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
+                                   GnssSvFlags::HAS_ALMANAC_DATA};
+    return svInfo;
+}
+
+Return<GnssSvStatus> Gnss::getMockSvStatus() const {
+    std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
+    GnssSvInfo mockGnssSvInfoList[] = {
+        getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
+        getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
+        getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
+        getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
+        getSvInfo(30, GnssConstellationType::GPS, 20.5, 11.5, 116.0),
+        getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
+
+    GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
+    for (uint32_t i = 0; i < svStatus.numSvs; i++) {
+        if (mGnssConfiguration->isBlacklisted(mockGnssSvInfoList[i])) {
+            /**
+             * Note well, this is a simple, mock emulation of not using a satellite by changing the
+             * used bit.  Simply blanking the used bit, as is done here, is *not* an acceptable
+             * actual device implementation - actual devices *must not* use the satellite in the
+             * position calculation, as specified in IGnssConfiguration.hal.
+             */
+            mockGnssSvInfoList[i].svFlag &=
+                ~static_cast<uint8_t>(IGnssCallback::GnssSvFlags::USED_IN_FIX);
+        }
+        svStatus.gnssSvList[i] = mockGnssSvInfoList[i];
+    }
+
+    return svStatus;
+}
+
+Return<void> Gnss::reportLocation(const GnssLocation& location) const {
     std::unique_lock<std::mutex> lock(mMutex);
     if (sGnssCallback == nullptr) {
         ALOGE("%s: sGnssCallback is null.", __func__);
@@ -215,6 +258,16 @@
     return Void();
 }
 
+Return<void> Gnss::reportSvStatus(const GnssSvStatus& svStatus) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: sGnssCallback is null.", __func__);
+        return Void();
+    }
+    sGnssCallback->gnssSvStatusCb(svStatus);
+    return Void();
+}
+
 }  // namespace implementation
 }  // namespace V1_1
 }  // namespace gnss
diff --git a/gnss/1.1/default/Gnss.h b/gnss/1.1/default/Gnss.h
index 68c3498..99af34c 100644
--- a/gnss/1.1/default/Gnss.h
+++ b/gnss/1.1/default/Gnss.h
@@ -7,6 +7,7 @@
 #include <atomic>
 #include <mutex>
 #include <thread>
+#include "GnssConfiguration.h"
 
 namespace android {
 namespace hardware {
@@ -22,6 +23,11 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
+using GnssConstellationType = V1_0::GnssConstellationType;
+using GnssLocation = V1_0::GnssLocation;
+using GnssSvInfo = V1_0::IGnssCallback::GnssSvInfo;
+using GnssSvStatus = V1_0::IGnssCallback::GnssSvStatus;
+
 /**
  * Unlike the gnss/1.0/default implementation, which is a shim layer to the legacy gps.h, this
  * default implementation serves as a mock implementation for emulators
@@ -78,14 +84,19 @@
 
     // Methods from ::android::hidl::base::V1_0::IBase follow.
    private:
-    Return<V1_0::GnssLocation> getMockLocation();
-    Return<void> reportLocation(const V1_0::GnssLocation& location);
+    Return<GnssLocation> getMockLocation() const;
+    Return<GnssSvStatus> getMockSvStatus() const;
+    Return<GnssSvInfo> getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
+                                 float elevationDegress, float azimuthDegress) const;
+    Return<void> reportLocation(const GnssLocation&) const;
+    Return<void> reportSvStatus(const GnssSvStatus&) const;
 
-    static sp<::android::hardware::gnss::V1_1::IGnssCallback> sGnssCallback;
+    static sp<IGnssCallback> sGnssCallback;
+    std::atomic<long> mMinIntervalMs;
+    sp<GnssConfiguration> mGnssConfiguration;
     std::atomic<bool> mIsActive;
     std::thread mThread;
-    std::mutex mMutex;
-    std::atomic<long> mMinIntervalMs;
+    mutable std::mutex mMutex;
 };
 
 }  // namespace implementation
diff --git a/gnss/1.1/default/GnssConfiguration.cpp b/gnss/1.1/default/GnssConfiguration.cpp
index d05f317..2717571 100644
--- a/gnss/1.1/default/GnssConfiguration.cpp
+++ b/gnss/1.1/default/GnssConfiguration.cpp
@@ -1,4 +1,7 @@
+#define LOG_TAG "GnssConfiguration"
+
 #include "GnssConfiguration.h"
+#include <log/log.h>
 
 namespace android {
 namespace hardware {
@@ -43,10 +46,33 @@
 }
 
 // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
-Return<bool> GnssConfiguration::setBlacklist(
-    const hidl_vec<::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource>&) {
-    // TODO implement
-    return bool{};
+Return<bool> GnssConfiguration::setBlacklist(const hidl_vec<BlacklistedSource>& sourceList) {
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    mBlacklistedConstellationSet.clear();
+    mBlacklistedSourceSet.clear();
+    for (auto source : sourceList) {
+        if (source.svid == 0) {
+            // Wildcard blacklist, i.e., blacklist entire constellation.
+            mBlacklistedConstellationSet.insert(source.constellation);
+        } else {
+            mBlacklistedSourceSet.insert(source);
+        }
+    }
+    return true;
+}
+
+Return<bool> GnssConfiguration::isBlacklisted(const GnssSvInfo& gnssSvInfo) const {
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    if (mBlacklistedConstellationSet.find(gnssSvInfo.constellation) !=
+        mBlacklistedConstellationSet.end()) {
+        return true;
+    }
+    BlacklistedSource source = {.constellation = gnssSvInfo.constellation, .svid = gnssSvInfo.svid};
+    return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end());
+}
+
+std::recursive_mutex& GnssConfiguration::getMutex() const {
+    return mMutex;
 }
 
 // Methods from ::android::hidl::base::V1_0::IBase follow.
diff --git a/gnss/1.1/default/GnssConfiguration.h b/gnss/1.1/default/GnssConfiguration.h
index 4f7ed2b..9b2699b 100644
--- a/gnss/1.1/default/GnssConfiguration.h
+++ b/gnss/1.1/default/GnssConfiguration.h
@@ -1,9 +1,12 @@
 #ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
 #define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H
 
+#include <android/hardware/gnss/1.1/IGnssCallback.h>
 #include <android/hardware/gnss/1.1/IGnssConfiguration.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include <mutex>
+#include <unordered_set>
 
 namespace android {
 namespace hardware {
@@ -19,6 +22,26 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
+using BlacklistedSource = ::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource;
+using GnssConstellationType = V1_0::GnssConstellationType;
+using GnssSvInfo = V1_0::IGnssCallback::GnssSvInfo;
+
+struct BlacklistedSourceHash {
+    inline int operator()(const BlacklistedSource& source) const {
+        return int(source.constellation) * 1000 + int(source.svid);
+    }
+};
+
+struct BlacklistedSourceEqual {
+    inline bool operator()(const BlacklistedSource& s1, const BlacklistedSource& s2) const {
+        return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
+    }
+};
+
+using BlacklistedSourceSet =
+    std::unordered_set<BlacklistedSource, BlacklistedSourceHash, BlacklistedSourceEqual>;
+using BlacklistedConstellationSet = std::unordered_set<GnssConstellationType>;
+
 struct GnssConfiguration : public IGnssConfiguration {
     // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
     Return<bool> setSuplEs(bool enabled) override;
@@ -30,11 +53,15 @@
     Return<bool> setEmergencySuplPdn(bool enable) override;
 
     // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
-    Return<bool> setBlacklist(
-        const hidl_vec<::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource>&
-            blacklist) override;
+    Return<bool> setBlacklist(const hidl_vec<BlacklistedSource>& blacklist) override;
 
-    // Methods from ::android::hidl::base::V1_0::IBase follow.
+    Return<bool> isBlacklisted(const GnssSvInfo& gnssSvInfo) const;
+    std::recursive_mutex& getMutex() const;
+
+   private:
+    BlacklistedSourceSet mBlacklistedSourceSet;
+    BlacklistedConstellationSet mBlacklistedConstellationSet;
+    mutable std::recursive_mutex mMutex;
 };
 
 }  // namespace implementation
diff --git a/gnss/1.1/default/GnssConstants.h b/gnss/1.1/default/GnssConstants.h
new file mode 100644
index 0000000..9ce1a12
--- /dev/null
+++ b/gnss/1.1/default/GnssConstants.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_1_GnssConstants_H_
+#define android_hardware_gnss_V1_1_GnssConstants_H_
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+const float kMockLatitudeDegrees = 37.4219999;
+const float kMockLongitudeDegrees = -122.0840575;
+const float kMockAltitudeMeters = 1.60062531;
+const float kMockSpeedMetersPerSec = 0;
+const float kMockBearingDegrees = 0;
+const float kMockHorizontalAccuracyMeters = 5;
+const float kMockVerticalAccuracyMeters = 5;
+const float kMockSpeedAccuracyMetersPerSecond = 1;
+const float kMockBearingAccuracyDegrees = 90;
+const int64_t kMockTimestamp = 1519930775453L;
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_1_GnssConstants_H_
diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp
new file mode 100644
index 0000000..62870e4
--- /dev/null
+++ b/gnss/1.1/default/GnssDebug.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssDebug"
+
+#include <log/log.h>
+
+#include "GnssConstants.h"
+#include "GnssDebug.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+Return<void> GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) {
+    PositionDebug positionDebug = {
+        .valid = true,
+        .latitudeDegrees = kMockLatitudeDegrees,
+        .longitudeDegrees = kMockLongitudeDegrees,
+        .altitudeMeters = kMockAltitudeMeters,
+        .speedMetersPerSec = kMockSpeedMetersPerSec,
+        .bearingDegrees = kMockBearingDegrees,
+        .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+        .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+        .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+        .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+        .ageSeconds = 0.99};
+
+    TimeDebug timeDebug = {.timeEstimate = kMockTimestamp,
+                           .timeUncertaintyNs = 1000,
+                           .frequencyUncertaintyNsPerSec = 5.0e4};
+
+    DebugData data = {.position = positionDebug, .time = timeDebug};
+
+    _hidl_cb(data);
+
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/1.1/default/GnssDebug.h b/gnss/1.1/default/GnssDebug.h
new file mode 100644
index 0000000..6d149fa
--- /dev/null
+++ b/gnss/1.1/default/GnssDebug.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_V1_1_GnssDebug_H_
+#define android_hardware_gnss_V1_1_GnssDebug_H_
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using V1_0::IGnssDebug;
+
+/* Interface for GNSS Debug support. */
+struct GnssDebug : public IGnssDebug {
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+     * These declarations were generated from IGnssDebug.hal.
+     */
+    Return<void> getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_1_GnssDebug_H_