Add navigation methods to IGnss AIDL HAL (hardware/interfaces)

Bug: 205185251
Test: atest VtsHalGnssTargetTest
Change-Id: Ib412aeb0b302952d13e236554f00690206b98253
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index f02e08c..1a69f33 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -37,8 +37,8 @@
   void setCallback(in android.hardware.gnss.IAGnssCallback callback);
   void dataConnClosed();
   void dataConnFailed();
-  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in String hostname, in int port);
-  void dataConnOpen(in long networkHandle, in String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in @utf8InCpp String hostname, in int port);
+  void dataConnOpen(in long networkHandle, in @utf8InCpp String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
   @Backing(type="int") @VintfStability
   enum ApnIpType {
     INVALID = 0,
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 3477380..1b4c581 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -46,7 +46,41 @@
   android.hardware.gnss.IAGnss getExtensionAGnss();
   android.hardware.gnss.IGnssDebug getExtensionGnssDebug();
   android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl();
+  void start();
+  void stop();
+  void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+  void injectLocation(in android.hardware.gnss.GnssLocation location);
+  void injectBestLocation(in android.hardware.gnss.GnssLocation location);
+  void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags);
+  void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode);
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
+  @Backing(type="int") @VintfStability
+  enum GnssPositionMode {
+    STANDALONE = 0,
+    MS_BASED = 1,
+    MS_ASSISTED = 2,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssPositionRecurrence {
+    RECURRENCE_PERIODIC = 0,
+    RECURRENCE_SINGLE = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssAidingData {
+    DELETE_EPHEMERIS = 1,
+    DELETE_ALMANAC = 2,
+    DELETE_POSITION = 4,
+    DELETE_TIME = 8,
+    DELETE_IONO = 16,
+    DELETE_UTC = 32,
+    DELETE_HEALTH = 64,
+    DELETE_SVDIR = 128,
+    DELETE_SVSTEER = 256,
+    DELETE_SADATA = 512,
+    DELETE_RTI = 1024,
+    DELETE_CELLDB_INFO = 32768,
+    DELETE_ALL = 65535,
+  }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index fb0931c..957a75f 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -35,8 +35,60 @@
 @VintfStability
 interface IGnssCallback {
   void gnssSetCapabilitiesCb(in int capabilities);
+  void gnssStatusCb(in android.hardware.gnss.IGnssCallback.GnssStatusValue status);
+  void gnssSvStatusCb(in android.hardware.gnss.IGnssCallback.GnssSvInfo[] svInfoList);
+  void gnssLocationCb(in android.hardware.gnss.GnssLocation location);
+  void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+  void gnssAcquireWakelockCb();
+  void gnssReleaseWakelockCb();
+  void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
+  void gnssRequestTimeCb();
+  void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+  const int CAPABILITY_SCHEDULING = 1;
+  const int CAPABILITY_MSB = 2;
+  const int CAPABILITY_MSA = 4;
+  const int CAPABILITY_SINGLE_SHOT = 8;
+  const int CAPABILITY_ON_DEMAND_TIME = 16;
+  const int CAPABILITY_GEOFENCING = 32;
+  const int CAPABILITY_MEASUREMENTS = 64;
+  const int CAPABILITY_NAV_MESSAGES = 128;
+  const int CAPABILITY_LOW_POWER_MODE = 256;
   const int CAPABILITY_SATELLITE_BLOCKLIST = 512;
+  const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1024;
+  const int CAPABILITY_ANTENNA_INFO = 2048;
   const int CAPABILITY_CORRELATION_VECTOR = 4096;
   const int CAPABILITY_SATELLITE_PVT = 8192;
   const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+  @Backing(type="int") @VintfStability
+  enum GnssStatusValue {
+    NONE = 0,
+    SESSION_BEGIN = 1,
+    SESSION_END = 2,
+    ENGINE_ON = 3,
+    ENGINE_OFF = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssSvFlags {
+    NONE = 0,
+    HAS_EPHEMERIS_DATA = 1,
+    HAS_ALMANAC_DATA = 2,
+    USED_IN_FIX = 4,
+    HAS_CARRIER_FREQUENCY = 8,
+  }
+  @VintfStability
+  parcelable GnssSvInfo {
+    int svid;
+    android.hardware.gnss.GnssConstellationType constellation;
+    float cN0Dbhz;
+    float basebandCN0DbHz;
+    float elevationDegrees;
+    float azimuthDegrees;
+    long carrierFrequencyHz;
+    int svFlag;
+  }
+  @VintfStability
+  parcelable GnssSystemInfo {
+    int yearOfHw;
+    @utf8InCpp String name;
+  }
 }
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
index 3e256e2..30b2167 100644
--- a/gnss/aidl/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -60,7 +60,7 @@
      * @param hostname Hostname of the AGNSS server.
      * @param port Port number associated with the server.
      */
-    void setServer(in AGnssType type, in String hostname, in int port);
+    void setServer(in AGnssType type, in @utf8InCpp String hostname, in int port);
 
     /**
      * Notifies GNSS that a data connection is available and sets the network handle,
@@ -75,5 +75,6 @@
      * @param apn Access Point Name (follows regular APN naming convention).
      * @param apnIpType Specifies IP type of APN.
      */
-    void dataConnOpen(in long networkHandle, in String apn, in ApnIpType apnIpType);
+    void dataConnOpen(
+            in long networkHandle, in @utf8InCpp String apn, in ApnIpType apnIpType);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 1351f59..4ddc6a6 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.GnssLocation;
 import android.hardware.gnss.IAGnss;
 import android.hardware.gnss.IGnssBatching;
 import android.hardware.gnss.IGnssCallback;
@@ -45,6 +46,53 @@
     /** Any other error. */
     const int ERROR_GENERIC = 3;
 
+    /** Requested operational mode for GNSS operation. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssPositionMode {
+        /** Mode for running GNSS standalone (no assistance). */
+        STANDALONE = 0,
+        /** AGNSS MS-Based mode. */
+        MS_BASED = 1,
+        /**
+         * AGNSS MS-Assisted mode. This mode is not maintained by the platform anymore.
+         * It is strongly recommended to use MS_BASED instead.
+         */
+        MS_ASSISTED = 2,
+    }
+
+    /** Requested recurrence mode for GNSS operation. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssPositionRecurrence {
+        /** Receive GNSS fixes on a recurring basis at a specified period. */
+        RECURRENCE_PERIODIC = 0,
+        /** Request a single shot GNSS fix. */
+        RECURRENCE_SINGLE = 1,
+    }
+
+    /**
+     * Flags used to specify which aiding data to delete when calling
+     * deleteAidingData().
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssAidingData {
+        DELETE_EPHEMERIS = 0x0001,
+        DELETE_ALMANAC = 0x0002,
+        DELETE_POSITION = 0x0004,
+        DELETE_TIME = 0x0008,
+        DELETE_IONO = 0x0010,
+        DELETE_UTC = 0x0020,
+        DELETE_HEALTH = 0x0040,
+        DELETE_SVDIR = 0x0080,
+        DELETE_SVSTEER = 0x0100,
+        DELETE_SADATA = 0x0200,
+        DELETE_RTI = 0x0400,
+        DELETE_CELLDB_INFO = 0x8000,
+        DELETE_ALL = 0xFFFF
+    }
+
     /**
      * Opens the interface and provides the callback routines to the implementation of this
      * interface.
@@ -152,4 +200,81 @@
      * @return Handle to the IGnssVisibilityControl.
      */
     IGnssVisibilityControl getExtensionGnssVisibilityControl();
+
+    /**
+     * Starts a location output stream using the IGnssCallback gnssLocationCb(), following the
+     * settings from the most recent call to setPositionMode().
+     *
+     * This output must operate independently of any GNSS location batching operations,
+     * see the IGnssBatching for details.
+     */
+    void start();
+
+    /**
+     * Stops the location output stream.
+     */
+    void stop();
+
+    /**
+     * Injects the current time.
+     *
+     * @param timeMs This is the UTC time received from the NTP server, its value is given in
+     *     milliseconds since January 1, 1970.
+     * @param timeReferenceMs The corresponding value of SystemClock.elapsedRealtime() from the
+     *     device when the NTP response was received in milliseconds.
+     * @param uncertaintyMs Uncertainty associated with the value represented by time. Represented
+     *     in milliseconds.
+     */
+    void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+
+    /**
+     * Injects current location from another (typically network) location provider.
+     *
+     * @param location Current location from the location provider
+     */
+    void injectLocation(in GnssLocation location);
+
+    /**
+     * 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.
+     */
+    void injectBestLocation(in GnssLocation location);
+
+    /**
+     * Specifies that the next call to start will not use the information defined in the flags.
+     * GnssAidingData value of DELETE_ALL is passed for a cold start.
+     *
+     * @param aidingDataFlags Flags specifying the aiding data to be deleted.
+     */
+    void deleteAidingData(in GnssAidingData aidingDataFlags);
+
+    /**
+     * Sets the GnssPositionMode parameter, its associated recurrence value, the time between fixes,
+     * requested fix accuracy, time to first fix.
+     *
+     * @param mode Parameter must be one of MS_BASED or STANDALONE. It is allowed by the platform
+     *     (and it is recommended) to fallback to MS_BASED if MS_ASSISTED is passed in, and MS_BASED
+     *     is supported.
+     * @param recurrence GNSS position recurrence value, either periodic or single.
+     * @param minIntervalMs Represents the time between fixes in milliseconds.
+     * @param preferredAccuracyMeters Represents the requested fix accuracy in meters.
+     * @param preferredTimeMs Represents the requested time to first fix in milliseconds.
+     * @param lowPowerMode When true, and IGnss is the only client to the GNSS hardware, the GNSS
+     *     hardware must make strong tradeoffs to substantially restrict power use. Specifically, in
+     *     the case of a several second long minIntervalMs, the GNSS hardware must not, on average,
+     *     run power hungry operations like RF and signal searches for more than one second per
+     *     interval, and must make exactly one call to gnssSvStatusCb(), and either zero or one call
+     *     to GnssLocationCb() at each interval. When false, HAL must operate in the nominal mode
+     *     and is expected to make power and performance tradoffs such as duty-cycling when signal
+     *     conditions are good and more active searches to reacquire GNSS signals when no signals
+     *     are present. When there are additional clients using the GNSS hardware other than IGnss,
+     *     the GNSS hardware may operate in a higher power mode, on behalf of those clients.
+     */
+    void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence,
+            in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs,
+            in boolean lowPowerMode);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index aad09ef..157c912 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.GnssConstellationType;
+import android.hardware.gnss.GnssLocation;
 import android.hardware.gnss.IGnssConfiguration;
 import android.hardware.gnss.IGnssPsds;
 
@@ -26,9 +28,48 @@
  */
 @VintfStability
 interface IGnssCallback {
+    /**
+     * Capability bit mask indicating that GNSS supports scheduling fixes for RECURRENCE_PERIODIC
+     * mode.
+     *
+     * If this is not set, then the framework will use 1000ms for minInterval and will call start()
+     * and stop() to schedule the GNSS.
+     */
+    const int CAPABILITY_SCHEDULING = 1 << 0;
+
+    /** Capability bit mask indicating that GNSS supports MS-Based AGNSS mode */
+    const int CAPABILITY_MSB = 1 << 1;
+
+    /** Capability bit mask indicating that GNSS supports MS-Assisted AGNSS mode */
+    const int CAPABILITY_MSA = 1 << 2;
+
+    /** Capability bit mask indicating that GNSS supports single-shot fixes */
+    const int CAPABILITY_SINGLE_SHOT = 1 << 3;
+
+    /** Capability bit mask indicating that GNSS supports on demand time injection */
+    const int CAPABILITY_ON_DEMAND_TIME = 1 << 4;
+
+    /** Capability bit mask indicating that GNSS supports Geofencing  */
+    const int CAPABILITY_GEOFENCING = 1 << 5;
+
+    /** Capability bit mask indicating that GNSS supports Measurements. */
+    const int CAPABILITY_MEASUREMENTS = 1 << 6;
+
+    /** Capability bit mask indicating that GNSS supports Navigation Messages */
+    const int CAPABILITY_NAV_MESSAGES = 1 << 7;
+
+    /** Capability bit mask indicating that GNSS supports low power mode */
+    const int CAPABILITY_LOW_POWER_MODE = 1 << 8;
+
     /** Capability bit mask indicating that GNSS supports blocklisting satellites */
     const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9;
 
+    /** Capability bit mask indicating that GNSS supports measurement corrections */
+    const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1 << 10;
+
+    /** Capability bit mask indicating that GNSS supports measurement corrections */
+    const int CAPABILITY_ANTENNA_INFO = 1 << 11;
+
     /** Capability bit mask indicating that GNSS supports correlation vector */
     const int CAPABILITY_CORRELATION_VECTOR = 1 << 12;
 
@@ -44,4 +85,221 @@
      * @param capabilities Capability parameter is a bit field of the Capability bit masks.
      */
     void gnssSetCapabilitiesCb(in int capabilities);
+
+    /** GNSS status event values. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssStatusValue {
+        /** GNSS status unknown. */
+        NONE = 0,
+        /** GNSS has begun navigating. */
+        SESSION_BEGIN = 1,
+        /** GNSS has stopped navigating. */
+        SESSION_END = 2,
+        /** GNSS has powered on but is not navigating. */
+        ENGINE_ON = 3,
+        /** GNSS is powered off. */
+        ENGINE_OFF = 4
+    }
+
+    /**
+     * Flags that indicate information about the satellite
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssSvFlags {
+        NONE = 0,
+        HAS_EPHEMERIS_DATA = 1 << 0,
+        HAS_ALMANAC_DATA = 1 << 1,
+        USED_IN_FIX = 1 << 2,
+        HAS_CARRIER_FREQUENCY = 1 << 3,
+    }
+
+    @VintfStability
+    parcelable GnssSvInfo {
+        /**
+         * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or
+         * FCN/OSN number for Glonass. The distinction is made by looking at constellation field.
+         * Values must be in the range of:
+         *
+         * - GNSS:    1-32
+         * - SBAS:    120-151, 183-192
+         * - GLONASS: 1-24, the orbital slot number (OSN), if known.  Or, if not:
+         *            93-106, the frequency channel number (FCN) (-7 to +6) offset by
+         *            + 100
+         *            i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6
+         *            as 106.
+         * - QZSS:    193-200
+         * - Galileo: 1-36
+         * - Beidou:  1-37
+         * - IRNSS:   1-14
+         */
+        int svid;
+
+        /**
+         * Defines the constellation of the given SV.
+         */
+        GnssConstellationType constellation;
+
+        /**
+         * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+         * It contains the measured C/N0 value for the signal at the antenna port.
+         *
+         * This is a mandatory field.
+         */
+        float cN0Dbhz;
+
+        /**
+         * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+         * the measured C/N0 value for the signal measured at the baseband.
+         *
+         * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+         * which is reported in cN0DbHz.
+         *
+         * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+         * processes one of the components, then the reported basebandCN0DbHz reflects only the
+         * component that is processed.
+         *
+         * This field is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being
+         * reported that may be searched for, but not yet tracked.
+         */
+        float basebandCN0DbHz;
+
+        /** Elevation of SV in degrees. */
+        float elevationDegrees;
+
+        /** Azimuth of SV in degrees. */
+        float azimuthDegrees;
+
+        /**
+         * Carrier frequency of the signal tracked, for example it can be the
+         * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 =
+         * 1176.45 MHz, varying GLO channels, etc. If the field is zero, it is
+         * the primary common use central frequency, e.g. L1 = 1575.45 MHz for
+         * GPS.
+         *
+         * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same
+         * time, two GnssSvInfo structs must be reported for this same
+         * satellite, in one of the structs, all the values related
+         * to L1 must be filled, and in the other all of the values related to
+         * L5 must be filled.
+         *
+         * If the data is available, svFlag must contain HAS_CARRIER_FREQUENCY.
+         */
+        long carrierFrequencyHz;
+
+        /** A bit field of the GnssSvFlags. */
+        int svFlag;
+    }
+
+    /**
+     * Called to communicate the status of the GNSS engine.
+     *
+     * @param status Status information from HAL.
+     */
+    void gnssStatusCb(in GnssStatusValue status);
+
+    /**
+     * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
+     *
+     * @param svInfo SV status information from HAL.
+     */
+    void gnssSvStatusCb(in GnssSvInfo[] svInfoList);
+
+    /**
+     * Called when a GNSS location is available.
+     *
+     * @param location Location information from HAL.
+     */
+    void gnssLocationCb(in GnssLocation location);
+
+    /**
+     * Callback for reporting NMEA sentences. Called when NMEA data is available.
+     *
+     * @param timestamp Marks the instance of reporting.
+     * @param nmea Follows standard NMEA 0183. Each sentence begins with a '$'
+     * and ends with a carriage return/line feed sequence and can be no longer
+     * than 80 characters of visible text (plus the line terminators). The data
+     * is contained within this single line with data items separated by commas.
+     * The data itself is just ascii text and may extend over multiple sentences
+     * in certain specialized instances but is normally fully contained in one
+     * variable length sentence. The data may vary in the amount of precision
+     * contained in the message. For example time might be indicated to decimal
+     * parts of a second or location may be shown with 3 or even 4 digits after
+     * the decimal point. Programs that read the data must only use the commas
+     * to determine the field boundaries and not depend on column positions.
+     * There is a provision for a checksum at the end of each sentence which may
+     * or may not be checked by the unit that reads the data. The checksum field
+     * consists of a '*' and two hex digits representing an 8 bit exclusive OR
+     * of all characters between, but not including, the '$' and '*'.
+     */
+    void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+
+    /**
+     * Callback utility for acquiring the GNSS wakelock. This can be used to prevent
+     * the CPU from suspending while handling GNSS events.
+     */
+    void gnssAcquireWakelockCb();
+
+    /** Callback utility for releasing the GNSS wakelock. */
+    void gnssReleaseWakelockCb();
+
+    /**
+     * Provides information about how new the underlying GPS/GNSS hardware and software is.
+     */
+    @VintfStability
+    parcelable GnssSystemInfo {
+        /**
+         * The year in which the last update was made to the underlying hardware/firmware used to
+         * capture GNSS signals, e.g. 2016.
+         */
+        int yearOfHw;
+
+        /**
+         * The name of the GNSS HAL implementation model and version name.
+         *
+         * This is a user-visible string that identifies the model and version of the GNSS HAL.
+         * For example "ABC Co., Baseband Part 1234, RF Part 567, Software version 3.14.159"
+         *
+         * For privacy reasons, this string must not contain any device-specific serial number or
+         * other identifier that uniquely identifies an individual device.
+         */
+        @utf8InCpp String name;
+    }
+
+    /**
+     * Callback to inform the framework of the GNSS system information.
+     *
+     * This must be called in response to IGnss::setCallback
+     *
+     * @param info GnssSystemInfo about the GPS/GNSS hardware.
+     */
+    void gnssSetSystemInfoCb(in GnssSystemInfo info);
+
+    /** Callback for requesting NTP time */
+    void gnssRequestTimeCb();
+
+    /**
+     * Callback for requesting Location.
+     *
+     * HAL implementation must call this when it wants the framework to provide locations to assist
+     * with GNSS HAL operation, for example, to assist with time to first fix, error recovery, or to
+     * supplement GNSS location for other clients of the GNSS HAL.
+     *
+     * If a request is made with independentFromGnss set to true, the framework must avoid
+     * providing locations derived from GNSS locations (such as "fused" location), to help improve
+     * information independence for situations such as error recovery.
+     *
+     * In response to this method call, GNSS HAL can expect zero, one, or more calls to
+     * IGnss::injectLocation or IGnss::injectBestLocation, dependent on availability of location
+     * from other sources, which may happen at some arbitrary delay. Generally speaking, HAL
+     * implementations must be able to handle calls to IGnss::injectLocation or
+     * IGnss::injectBestLocation at any time.
+     *
+     * @param independentFromGnss True if requesting a location that is independent from GNSS.
+     * @param isUserEmergency True if the location request is for delivery of this location to an
+     *        emergency services endpoint, during a user-initiated emergency session (e.g.
+     *        during-call to E911, or up to 5 minutes after end-of-call or text to E911).
+     */
+    void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
 }
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index afb7b95..e296351 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "GnssAidl"
 
 #include "Gnss.h"
+#include <inttypes.h>
 #include <log/log.h>
 #include "AGnss.h"
 #include "GnssBatching.h"
@@ -27,16 +28,24 @@
 #include "GnssNavigationMessageInterface.h"
 #include "GnssPsds.h"
 #include "GnssVisibilityControl.h"
+#include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
+using ::android::hardware::gnss::common::Utils;
+using ndk::ScopedAStatus;
+using GnssSvInfo = IGnssCallback::GnssSvInfo;
+
+constexpr int TTFF_MILLIS = 2200;
 
 std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
 
-ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
-    ALOGD("Gnss::setCallback");
+Gnss::Gnss() : mMinIntervalMs(1000), mFirstFixReceived(false) {}
+
+ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
+    ALOGD("setCallback");
     if (callback == nullptr) {
         ALOGE("%s: Null callback ignored", __func__);
-        return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+        return ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
     }
 
     sGnssCallback = callback;
@@ -50,13 +59,99 @@
         ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
     }
 
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::close() {
-    ALOGD("Gnss::close");
+ScopedAStatus Gnss::start() {
+    ALOGD("start()");
+    if (mIsActive) {
+        ALOGW("Gnss has started. Restarting...");
+        stop();
+    }
+
+    mIsActive = true;
+    this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+    mThread = std::thread([this]() {
+        auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+        this->reportSvStatus(svStatus);
+        if (!mFirstFixReceived) {
+            std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
+            mFirstFixReceived = true;
+        }
+        while (mIsActive == true) {
+            auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+            this->reportSvStatus(svStatus);
+
+            mGnssPowerIndication->notePowerConsumption();
+            const auto location = Utils::getMockLocation();
+            this->reportLocation(location);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+        }
+    });
+    return ScopedAStatus::ok();
+}
+
+void Gnss::reportLocation(const GnssLocation& location) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: GnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssLocationCb(location);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke gnssLocationCb", __func__);
+    }
+    return;
+}
+
+void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: sGnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssSvStatusCb(svInfoList);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(std::vector<GnssSvInfo> gnssSvInfoList) {
+    ALOGD("filterBlocklistedSatellites");
+    for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+        if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
+            gnssSvInfoList[i].svFlag &= ~(uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX;
+        }
+    }
+    return gnssSvInfoList;
+}
+
+void Gnss::reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: sGnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssStatusCb(gnssStatusValue);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke gnssStatusCb", __func__);
+    }
+}
+
+ScopedAStatus Gnss::stop() {
+    ALOGD("stop");
+    mIsActive = false;
+    this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::close() {
+    ALOGD("close");
     sGnssCallback = nullptr;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
@@ -65,61 +160,93 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
-    ALOGD("Gnss::getExtensionPsds");
-    *iGnssPsds = SharedRefBase::make<GnssPsds>();
-    return ndk::ScopedAStatus::ok();
+ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int uncertaintyMs) {
+    ALOGD("injectTime. timeMs:%" PRId64 ", timeReferenceMs:%" PRId64 ", uncertaintyMs:%d", timeMs,
+          timeReferenceMs, uncertaintyMs);
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
+ScopedAStatus Gnss::injectLocation(const GnssLocation& location) {
+    ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+          location.longitudeDegrees, location.horizontalAccuracyMeters);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::injectBestLocation(const GnssLocation& location) {
+    ALOGD("injectBestLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+          location.longitudeDegrees, location.horizontalAccuracyMeters);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::deleteAidingData(GnssAidingData aidingDataFlags) {
+    ALOGD("deleteAidingData. flags:%d", (int)aidingDataFlags);
+    mFirstFixReceived = false;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::setPositionMode(GnssPositionMode, GnssPositionRecurrence, int minIntervalMs,
+                                    int /* preferredAccuracyMeters */, int /* preferredTimeMs */,
+                                    bool lowPowerMode) {
+    ALOGD("setPositionMode. minIntervalMs:%d, lowPowerMode:%d", minIntervalMs, (int)lowPowerMode);
+    mMinIntervalMs = minIntervalMs;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
+    ALOGD("getExtensionPsds");
+    *iGnssPsds = SharedRefBase::make<GnssPsds>();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionGnssConfiguration(
         std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
-    ALOGD("Gnss::getExtensionGnssConfiguration");
+    ALOGD("getExtensionGnssConfiguration");
     if (mGnssConfiguration == nullptr) {
         mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
     }
     *iGnssConfiguration = mGnssConfiguration;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
+ScopedAStatus Gnss::getExtensionGnssPowerIndication(
         std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
-    ALOGD("Gnss::getExtensionGnssPowerIndication");
+    ALOGD("getExtensionGnssPowerIndication");
     if (mGnssPowerIndication == nullptr) {
         mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
     }
 
     *iGnssPowerIndication = mGnssPowerIndication;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
+ScopedAStatus Gnss::getExtensionGnssMeasurement(
         std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
-    ALOGD("Gnss::getExtensionGnssMeasurement");
+    ALOGD("getExtensionGnssMeasurement");
 
     *iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
-    ALOGD("Gnss::getExtensionGnssBatching");
+ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+    ALOGD("getExtensionGnssBatching");
 
     *iGnssBatching = SharedRefBase::make<GnssBatching>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
-    ALOGD("Gnss::getExtensionGnssGeofence");
+ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+    ALOGD("getExtensionGnssGeofence");
 
     *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
         std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
-    ALOGD("Gnss::getExtensionGnssNavigationMessage");
+    ALOGD("getExtensionGnssNavigationMessage");
 
     *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 67fef94..384c862 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -25,6 +25,9 @@
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
 #include <aidl/android/hardware/gnss/BnGnssPsds.h>
 #include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
 #include "GnssConfiguration.h"
 #include "GnssPowerIndication.h"
 
@@ -32,8 +35,22 @@
 
 class Gnss : public BnGnss {
   public:
+    Gnss();
+    ~Gnss() { stop(); };
     ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
+    ndk::ScopedAStatus start() override;
+    ndk::ScopedAStatus stop() override;
     ndk::ScopedAStatus close() override;
+
+    ndk::ScopedAStatus injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                                  int uncertaintyMs) override;
+    ndk::ScopedAStatus injectLocation(const GnssLocation& location) override;
+    ndk::ScopedAStatus injectBestLocation(const GnssLocation& location) override;
+    ndk::ScopedAStatus deleteAidingData(GnssAidingData aidingDataFlags) override;
+    ndk::ScopedAStatus setPositionMode(GnssPositionMode mode, GnssPositionRecurrence recurrence,
+                                       int minIntervalMs, int preferredAccuracyMeters,
+                                       int preferredTimeMs, bool lowPowerMode) override;
+
     ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
     ndk::ScopedAStatus getExtensionGnssConfiguration(
             std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
@@ -57,7 +74,20 @@
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
 
   private:
+    void reportLocation(const GnssLocation&) const;
+    void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
+    std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
+            std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList);
+    void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
+
     static std::shared_ptr<IGnssCallback> sGnssCallback;
+
+    std::atomic<long> mMinIntervalMs;
+    std::atomic<bool> mIsActive;
+    std::atomic<bool> mFirstFixReceived;
+    std::thread mThread;
+
+    mutable std::mutex mMutex;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp
index 30e0d8c..96a1aa2 100644
--- a/gnss/aidl/default/GnssConfiguration.cpp
+++ b/gnss/aidl/default/GnssConfiguration.cpp
@@ -49,4 +49,14 @@
     return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
 }
 
+bool GnssConfiguration::isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const {
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    if (mBlocklistedConstellationSet.find(gnssSvInfo.constellation) !=
+        mBlocklistedConstellationSet.end()) {
+        return true;
+    }
+    BlocklistedSource source = {.constellation = gnssSvInfo.constellation, .svid = gnssSvInfo.svid};
+    return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
index 491733c..3c77f32 100644
--- a/gnss/aidl/default/GnssConfiguration.h
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <aidl/android/hardware/gnss/BnGnssCallback.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
 #include <android/hardware/gnss/2.1/IGnssCallback.h>
 #include <mutex>
@@ -62,6 +63,7 @@
     ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
 
     bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+    bool isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const;
 
   private:
     BlocklistedSourceSet mBlocklistedSourceSet;
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
index 2da3b12..d4eb0a5 100644
--- a/gnss/aidl/vts/GnssBatchingCallback.cpp
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssBatchingCallbackAidl"
+
 #include "GnssBatchingCallback.h"
 #include <inttypes.h>
 #include <log/log.h>
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index f5c745b..77a2506 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -14,11 +14,62 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssCallbackAidl"
+
 #include "GnssCallbackAidl.h"
 #include <log/log.h>
 
-android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
-    ALOGI("Capabilities received %d", capabilities);
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+using GnssSvInfo = android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSystemInfo = android::hardware::gnss::IGnssCallback::GnssSystemInfo;
+
+Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+    ALOGI("Capabilities received %#08x", capabilities);
     capabilities_cbq_.store(capabilities);
-    return android::binder::Status::ok();
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
+    ALOGI("gnssSvStatusCb");
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
+    ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
+    sv_info_list_cbq_.store(svInfoList);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssLocationCb(const GnssLocation& location) {
+    ALOGI("Location received");
+    location_cbq_.store(location);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssNmeaCb(const int64_t /* timestamp */, const std::string& /* nmea */) {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssAcquireWakelockCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssReleaseWakelockCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) {
+    ALOGI("gnssSetSystemInfoCb, year=%d, name=%s", info.yearOfHw, info.name.c_str());
+    info_cbq_.store(info);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestTimeCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestLocationCb(const bool /* independentFromGnss */,
+                                               const bool /* isUserEmergency */) {
+    return Status::ok();
 }
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index 7f802ea..209728d 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -22,11 +22,37 @@
 /* Callback class for data & Event. */
 class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
   public:
-    GnssCallbackAidl() : capabilities_cbq_("capabilities"){};
+    GnssCallbackAidl()
+        : capabilities_cbq_("capabilities"),
+          info_cbq_("system_info"),
+          location_cbq_("location"),
+          sv_info_list_cbq_("sv_info"){};
     ~GnssCallbackAidl(){};
 
     android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+    android::binder::Status gnssStatusCb(const GnssStatusValue status) override;
+    android::binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
+    android::binder::Status gnssLocationCb(
+            const android::hardware::gnss::GnssLocation& location) override;
+    android::binder::Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override;
+    android::binder::Status gnssAcquireWakelockCb() override;
+    android::binder::Status gnssReleaseWakelockCb() override;
+    android::binder::Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override;
+    android::binder::Status gnssRequestTimeCb() override;
+    android::binder::Status gnssRequestLocationCb(const bool independentFromGnss,
+                                                  const bool isUserEmergency) override;
 
     int last_capabilities_;
+    android::hardware::gnss::IGnssCallback::GnssSystemInfo last_info_;
+    android::hardware::gnss::GnssLocation last_location_;
+
     android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            android::hardware::gnss::IGnssCallback::GnssSystemInfo>
+            info_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssLocation>
+            location_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+            sv_info_list_cbq_;
 };
\ No newline at end of file
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 2447bf8..13c32ee 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -14,20 +14,31 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssHalTest"
+
 #include "gnss_hal_test.h"
 #include <hidl/ServiceManagement.h>
+#include "Utils.h"
 
-using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssLocation;
+using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssCallback;
+using android::hardware::gnss::common::Utils;
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
 
 void GnssHalTest::SetUp() {
     // Get AIDL handle
     aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
     ASSERT_NE(aidl_gnss_hal_, nullptr);
+    ALOGD("AIDL Interface Version = %d", aidl_gnss_hal_->getInterfaceVersion());
 
-    const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
-            android::hardware::gnss::V2_1::IGnss::descriptor);
-    gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
-    ASSERT_NE(gnss_hal_, nullptr);
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
+                android::hardware::gnss::V2_1::IGnss::descriptor);
+        gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
+        ASSERT_NE(gnss_hal_, nullptr);
+    }
 
     SetUpGnssCallback();
 }
@@ -40,7 +51,6 @@
     if (!status.isOk()) {
         ALOGE("Failed to setCallback");
     }
-
     ASSERT_TRUE(status.isOk());
 
     /*
@@ -48,9 +58,243 @@
      */
     EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_,
                                                           TIMEOUT_SEC));
-
     EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1);
 
-    // Invoke the super method.
-    GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+    }
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation& location, bool check_speed) {
+    Utils::checkLocation(location, check_speed, /* check_more_accuracies= */ true);
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::SetPositionMode(min_interval_msec, low_power_mode);
+    }
+
+    const int kPreferredAccuracy = 0;  // Ideally perfect (matches GnssLocationProvider)
+    const int kPreferredTimeMsec = 0;  // Ideally immediate
+
+    auto status = aidl_gnss_hal_->setPositionMode(
+            IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+            min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+    ASSERT_TRUE(status.isOk());
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
+                                             const bool low_power_mode) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckFirstLocation(min_interval_msec,
+                                                                           low_power_mode);
+    }
+
+    SetPositionMode(min_interval_msec, low_power_mode);
+    auto result = aidl_gnss_hal_->start();
+
+    EXPECT_TRUE(result.isOk());
+
+    /*
+     * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+     * so allow time to demodulate ephemeris over the air.
+     */
+    const int kFirstGnssLocationTimeoutSeconds = 75;
+
+    EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+                                                      kFirstGnssLocationTimeoutSeconds));
+    int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+    EXPECT_EQ(locationCalledCount, 1);
+
+    if (locationCalledCount > 0) {
+        // don't require speed on first fix
+        CheckLocation(aidl_gnss_cb_->last_location_, false);
+        return true;
+    }
+    return false;
+}
+
+void GnssHalTest::StopAndClearLocations() {
+    ALOGD("StopAndClearLocations");
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StopAndClearLocations();
+    }
+
+    auto status = aidl_gnss_hal_->stop();
+    EXPECT_TRUE(status.isOk());
+
+    /*
+     * Clear notify/waiting counter, allowing up till the timeout after
+     * the last reply for final startup messages to arrive (esp. system
+     * info.)
+     */
+    while (aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_, TIMEOUT_SEC)) {
+    }
+    aidl_gnss_cb_->location_cbq_.reset();
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckLocations(count);
+    }
+    const int kMinIntervalMsec = 500;
+    const int kLocationTimeoutSubsequentSec = 2;
+    const bool kLowPowerMode = false;
+
+    EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode));
+
+    for (int i = 1; i < count; i++) {
+        EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+                                                          kLocationTimeoutSubsequentSec));
+        int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+        EXPECT_EQ(locationCalledCount, i + 1);
+        // Don't cause confusion by checking details if no location yet
+        if (locationCalledCount > 0) {
+            // Should be more than 1 location by now, but if not, still don't check first fix speed
+            CheckLocation(aidl_gnss_cb_->last_location_, locationCalledCount > 1);
+        }
+    }
+}
+
+std::list<std::vector<IGnssCallback::GnssSvInfo>> GnssHalTest::convertToAidl(
+        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>>& sv_info_list) {
+    std::list<std::vector<IGnssCallback::GnssSvInfo>> aidl_sv_info_list;
+    for (const auto& sv_info_vec : sv_info_list) {
+        std::vector<IGnssCallback::GnssSvInfo> aidl_sv_info_vec;
+        for (const auto& sv_info : sv_info_vec) {
+            IGnssCallback::GnssSvInfo aidl_sv_info;
+            aidl_sv_info.svid = sv_info.v2_0.v1_0.svid;
+            aidl_sv_info.constellation =
+                    static_cast<GnssConstellationType>(sv_info.v2_0.constellation);
+            aidl_sv_info.cN0Dbhz = sv_info.v2_0.v1_0.cN0Dbhz;
+            aidl_sv_info.basebandCN0DbHz = sv_info.basebandCN0DbHz;
+            aidl_sv_info.elevationDegrees = sv_info.v2_0.v1_0.elevationDegrees;
+            aidl_sv_info.azimuthDegrees = sv_info.v2_0.v1_0.azimuthDegrees;
+            aidl_sv_info.carrierFrequencyHz = (int64_t)sv_info.v2_0.v1_0.carrierFrequencyHz;
+            aidl_sv_info.svFlag = (int)sv_info.v2_0.v1_0.svFlag;
+            aidl_sv_info_vec.push_back(aidl_sv_info);
+        }
+        aidl_sv_info_list.push_back(aidl_sv_info_vec);
+    }
+    return aidl_sv_info_list;
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ *         or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+        const int min_observations) {
+    return FindStrongFrequentNonGpsSource(convertToAidl(sv_info_list), min_observations);
+}
+
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+        const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
+        const int min_observations) {
+    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+
+    for (const auto& sv_info_vec : sv_info_list) {
+        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+            const auto& gnss_sv = sv_info_vec[iSv];
+            if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+                (gnss_sv.constellation != GnssConstellationType::GPS)) {
+                ComparableBlocklistedSource source;
+                source.id.svid = gnss_sv.svid;
+                source.id.constellation = gnss_sv.constellation;
+
+                const auto& itSignal = mapSignals.find(source);
+                if (itSignal == mapSignals.end()) {
+                    SignalCounts counts;
+                    counts.observations = 1;
+                    counts.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+                    mapSignals.insert(
+                            std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
+                } else {
+                    itSignal->second.observations++;
+                    if (itSignal->second.max_cn0_dbhz < gnss_sv.cN0Dbhz) {
+                        itSignal->second.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+                    }
+                }
+            }
+        }
+    }
+
+    float max_cn0_dbhz_with_sufficient_count = 0.;
+    int total_observation_count = 0;
+    int blocklisted_source_count_observation = 0;
+
+    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
+    for (auto const& pairSignal : mapSignals) {
+        total_observation_count += pairSignal.second.observations;
+        if ((pairSignal.second.observations >= min_observations) &&
+            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+            source_to_blocklist = pairSignal.first;
+            blocklisted_source_count_observation = pairSignal.second.observations;
+            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+        }
+    }
+    ALOGD("Among %d observations, chose svid %d, constellation %d, "
+          "with %d observations at %.1f max CNo",
+          total_observation_count, source_to_blocklist.id.svid,
+          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
+          max_cn0_dbhz_with_sufficient_count);
+
+    return source_to_blocklist.id;
+}
+
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+        const int locations_to_await, const int gnss_sv_info_list_timeout) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return static_cast<GnssConstellationType>(
+                GnssHalTestTemplate<IGnss_V2_1>::startLocationAndGetNonGpsConstellation(
+                        locations_to_await, gnss_sv_info_list_timeout));
+    }
+    aidl_gnss_cb_->location_cbq_.reset();
+    StartAndCheckLocations(locations_to_await);
+    const int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
+
+    // Tolerate 1 less sv status to handle edge cases in reporting.
+    int sv_info_list_cbq_size = aidl_gnss_cb_->sv_info_list_cbq_.size();
+    EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await);
+    ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+          sv_info_list_cbq_size, locations_to_await, location_called_count);
+
+    // Find first non-GPS constellation to blocklist
+    GnssConstellationType constellation_to_blocklist = GnssConstellationType::UNKNOWN;
+    for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+        std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+        aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout);
+        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+            auto& gnss_sv = sv_info_vec[iSv];
+            if ((gnss_sv.svFlag & (uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+                (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+                (gnss_sv.constellation != GnssConstellationType::GPS)) {
+                // found a non-GPS constellation
+                constellation_to_blocklist = gnss_sv.constellation;
+                break;
+            }
+        }
+        if (constellation_to_blocklist != GnssConstellationType::UNKNOWN) {
+            break;
+        }
+    }
+
+    if (constellation_to_blocklist == GnssConstellationType::UNKNOWN) {
+        ALOGI("No non-GPS constellations found, constellation blocklist test less effective.");
+        // Proceed functionally to blocklist something.
+        constellation_to_blocklist = GnssConstellationType::GLONASS;
+    }
+
+    return constellation_to_blocklist;
 }
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index e3ecbed..d479af3 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -41,9 +41,50 @@
   public:
     GnssHalTest(){};
     ~GnssHalTest(){};
+
+    struct ComparableBlocklistedSource {
+        android::hardware::gnss::BlocklistedSource id;
+
+        ComparableBlocklistedSource() {
+            id.constellation = android::hardware::gnss::GnssConstellationType::UNKNOWN;
+            id.svid = 0;
+        }
+
+        bool operator<(const ComparableBlocklistedSource& compare) const {
+            return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+                                                    (id.constellation < compare.id.constellation)));
+        }
+    };
+
+    struct SignalCounts {
+        int observations;
+        float max_cn0_dbhz;
+    };
+
     virtual void SetUp() override;
     virtual void SetUpGnssCallback() override;
 
+    void CheckLocation(const android::hardware::gnss::GnssLocation& location,
+                       const bool check_speed);
+    void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+    bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode);
+    void StopAndClearLocations();
+    void StartAndCheckLocations(int count);
+
+    android::hardware::gnss::GnssConstellationType startLocationAndGetNonGpsConstellation(
+            const int locations_to_await, const int gnss_sv_info_list_timeout);
+    std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
+            const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
+                    sv_info_list);
+    android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+            const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
+                    sv_info_list,
+            const int min_observations);
+    android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+            const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+                    sv_info_list,
+            const int min_observations);
+
     sp<IGnssAidl> aidl_gnss_hal_;
     sp<GnssCallbackAidl> aidl_gnss_cb_;  // Primary callback interface
 };
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 90b643c..3aa308f 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -46,6 +46,7 @@
 using android::hardware::gnss::IGnss;
 using android::hardware::gnss::IGnssBatching;
 using android::hardware::gnss::IGnssBatchingCallback;
+using android::hardware::gnss::IGnssCallback;
 using android::hardware::gnss::IGnssConfiguration;
 using android::hardware::gnss::IGnssDebug;
 using android::hardware::gnss::IGnssGeofence;
@@ -59,6 +60,7 @@
 using android::hardware::gnss::SatellitePvt;
 using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
 
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
 using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
 
 static bool IsAutomotiveDevice() {
@@ -324,7 +326,11 @@
     auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
 
     // Get a location and request another GnssPowerStats
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
 
     // Request and verify the 2nd GnssPowerStats has larger values than the 1st one
@@ -375,88 +381,6 @@
 }
 
 /*
- * FindStrongFrequentNonGpsSource:
- *
- * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
- *
- * returns the strongest source,
- *         or a source with constellation == UNKNOWN if none are found sufficient times
- */
-BlocklistedSource FindStrongFrequentNonGpsSource(
-        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
-        const int min_observations) {
-    struct ComparableBlocklistedSource {
-        BlocklistedSource id;
-
-        ComparableBlocklistedSource() {
-            id.constellation = GnssConstellationTypeAidl::UNKNOWN;
-            id.svid = 0;
-        }
-
-        bool operator<(const ComparableBlocklistedSource& compare) const {
-            return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
-                                                    (id.constellation < compare.id.constellation)));
-        }
-    };
-
-    struct SignalCounts {
-        int observations;
-        float max_cn0_dbhz;
-    };
-
-    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
-
-    for (const auto& sv_info_vec : sv_info_list) {
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
-                (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
-                ComparableBlocklistedSource source;
-                source.id.svid = gnss_sv.v2_0.v1_0.svid;
-                source.id.constellation =
-                        static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation);
-
-                const auto& itSignal = mapSignals.find(source);
-                if (itSignal == mapSignals.end()) {
-                    SignalCounts counts;
-                    counts.observations = 1;
-                    counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
-                    mapSignals.insert(
-                            std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
-                } else {
-                    itSignal->second.observations++;
-                    if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
-                        itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
-                    }
-                }
-            }
-        }
-    }
-
-    float max_cn0_dbhz_with_sufficient_count = 0.;
-    int total_observation_count = 0;
-    int blocklisted_source_count_observation = 0;
-
-    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
-    for (auto const& pairSignal : mapSignals) {
-        total_observation_count += pairSignal.second.observations;
-        if ((pairSignal.second.observations >= min_observations) &&
-            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
-            source_to_blocklist = pairSignal.first;
-            blocklisted_source_count_observation = pairSignal.second.observations;
-            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
-        }
-    }
-    ALOGD("Among %d observations, chose svid %d, constellation %d, "
-          "with %d observations at %.1f max CNo",
-          total_observation_count, source_to_blocklist.id.svid,
-          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
-          max_cn0_dbhz_with_sufficient_count);
-
-    return source_to_blocklist.id;
-}
-
-/*
  * BlocklistIndividualSatellites:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
@@ -481,12 +405,20 @@
     const int kLocationsToAwait = 3;
     const int kRetriesToUnBlocklist = 10;
 
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
-    int location_called_count = gnss_cb_->location_cbq_.calledCount();
+    int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->location_cbq_.calledCount()
+                                        : aidl_gnss_cb_->location_cbq_.calledCount();
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
@@ -498,14 +430,22 @@
      */
 
     const int kGnssSvInfoListTimeout = 2;
-    std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
-    int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
-                                                     kGnssSvInfoListTimeout);
-
-    ASSERT_EQ(count, sv_info_list_cbq_size);
-
-    BlocklistedSource source_to_blocklist =
-            FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    BlocklistedSource source_to_blocklist;
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+        int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+                                                         kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size);
+        source_to_blocklist =
+                FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    } else {
+        std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
+        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size);
+        source_to_blocklist =
+                FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    }
 
     if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) {
         // Cannot find a non-GPS satellite. Let the test pass.
@@ -529,32 +469,53 @@
     ASSERT_TRUE(status.isOk());
 
     // retry and ensure satellite not used
-    gnss_cb_->sv_info_list_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
 
-    gnss_cb_->location_cbq_.reset();
     StartAndCheckLocations(kLocationsToAwait);
 
     // early exit if test is being run with insufficient signal
-    location_called_count = gnss_cb_->location_cbq_.calledCount();
+    location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                    ? gnss_cb_->location_cbq_.calledCount()
+                                    : aidl_gnss_cb_->location_cbq_.calledCount();
     if (location_called_count == 0) {
         ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
     }
     ASSERT_TRUE(location_called_count > 0);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                    ? gnss_cb_->sv_info_list_cbq_.size()
+                                    : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                         (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
+                             (gnss_sv.constellation == source_to_blocklist.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -569,36 +530,59 @@
     int unblocklist_loops_remaining = kRetriesToUnBlocklist;
     while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
         StopAndClearLocations();
-        gnss_cb_->sv_info_list_cbq_.reset();
 
-        gnss_cb_->location_cbq_.reset();
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            gnss_cb_->sv_info_list_cbq_.reset();
+            gnss_cb_->location_cbq_.reset();
+        } else {
+            aidl_gnss_cb_->sv_info_list_cbq_.reset();
+            aidl_gnss_cb_->location_cbq_.reset();
+        }
         StartAndCheckLocations(kLocationsToAwait);
 
         // early exit loop if test is being run with insufficient signal
-        location_called_count = gnss_cb_->location_cbq_.calledCount();
+        location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->location_cbq_.calledCount()
+                                        : aidl_gnss_cb_->location_cbq_.calledCount();
         if (location_called_count == 0) {
             ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
         }
         ASSERT_TRUE(location_called_count > 0);
 
         // Tolerate 1 less sv status to handle edge cases in reporting.
-        sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+        sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
         EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
         ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
               ", tries remaining %d",
               sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
 
         for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-                const auto& gnss_sv = sv_info_vec[iSv];
-                if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                    (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                     source_to_blocklist.constellation) &&
-                    (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
-                    strongest_sv_is_reobserved = true;
-                    break;
+            if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+                hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+                gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+                for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                    auto& gnss_sv = sv_info_vec[iSv];
+                    if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                        strongest_sv_is_reobserved = true;
+                        break;
+                    }
+                }
+            } else {
+                std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+                aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+                for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                    auto& gnss_sv = sv_info_vec[iSv];
+                    if ((gnss_sv.svid == source_to_blocklist.svid) &&
+                        (gnss_sv.constellation == source_to_blocklist.constellation) &&
+                        (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                        strongest_sv_is_reobserved = true;
+                        break;
+                    }
                 }
             }
             if (strongest_sv_is_reobserved) break;
@@ -660,27 +644,47 @@
     ASSERT_TRUE(status.isOk());
 
     // retry and ensure constellation not used
-    gnss_cb_->sv_info_list_cbq_.reset();
-
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
           kLocationsToAwait);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_1.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_2.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_1.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_2.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -743,27 +747,47 @@
     StopAndClearLocations();
 
     // retry and ensure constellation not used
-    gnss_cb_->sv_info_list_cbq_.reset();
-
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
           kLocationsToAwait);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_1.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_2.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_1.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_2.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -829,7 +853,7 @@
     ASSERT_TRUE(status.isOk());
 
     // Set SUPL server host/port
-    status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+    status = iAGnss->setServer(AGnssType::SUPL, std::string("supl.google.com"), 7275);
     ASSERT_TRUE(status.isOk());
 }
 
@@ -845,7 +869,7 @@
     auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
     ASSERT_TRUE(status.isOk());
 
-    if (!IsAutomotiveDevice() && gnss_cb_->info_cbq_.calledCount() > 0) {
+    if (!IsAutomotiveDevice()) {
         ASSERT_TRUE(iGnssDebug != nullptr);
 
         IGnssDebug::DebugData data;
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index c339e72..563c6d5 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -27,14 +27,17 @@
 
 using aidl::android::hardware::gnss::ElapsedRealtime;
 using aidl::android::hardware::gnss::GnssClock;
+using aidl::android::hardware::gnss::GnssConstellationType;
 using aidl::android::hardware::gnss::GnssData;
 using aidl::android::hardware::gnss::GnssLocation;
 using aidl::android::hardware::gnss::GnssMeasurement;
 using aidl::android::hardware::gnss::IGnss;
 using aidl::android::hardware::gnss::IGnssMeasurementCallback;
 using aidl::android::hardware::gnss::SatellitePvt;
+using GnssSvInfo = aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags;
 
-using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags;
 using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
@@ -144,7 +147,7 @@
 
 GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
     aidl::android::hardware::gnss::GnssSignalType signalType = {
-            .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
+            .constellation = GnssConstellationType::GLONASS,
             .carrierFrequencyHz = 1.59975e+09,
             .codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C,
     };
@@ -289,6 +292,40 @@
     return location;
 }
 
+namespace {
+GnssSvInfo getMockSvInfo(int svid, GnssConstellationType type, float cN0DbHz, float basebandCN0DbHz,
+                         float elevationDegrees, float azimuthDegrees, long carrierFrequencyHz) {
+    GnssSvInfo svInfo = {
+            .svid = svid,
+            .constellation = type,
+            .cN0Dbhz = cN0DbHz,
+            .basebandCN0DbHz = basebandCN0DbHz,
+            .elevationDegrees = elevationDegrees,
+            .azimuthDegrees = azimuthDegrees,
+            .carrierFrequencyHz = carrierFrequencyHz,
+            .svFlag = (int)GnssSvFlags::USED_IN_FIX | (int)GnssSvFlags::HAS_EPHEMERIS_DATA |
+                      (int)GnssSvFlags::HAS_ALMANAC_DATA | (int)GnssSvFlags::HAS_CARRIER_FREQUENCY};
+    return svInfo;
+}
+}  // anonymous namespace
+
+std::vector<GnssSvInfo> Utils::getMockSvInfoList() {
+    std::vector<GnssSvInfo> gnssSvInfoList = {
+            getMockSvInfo(3, GnssConstellationType::GPS, 32.5, 27.5, 59.1, 166.5, kGpsL1FreqHz),
+            getMockSvInfo(5, GnssConstellationType::GPS, 27.0, 22.0, 29.0, 56.5, kGpsL1FreqHz),
+            getMockSvInfo(17, GnssConstellationType::GPS, 30.5, 25.5, 71.0, 77.0, kGpsL5FreqHz),
+            getMockSvInfo(26, GnssConstellationType::GPS, 24.1, 19.1, 28.0, 253.0, kGpsL5FreqHz),
+            getMockSvInfo(5, GnssConstellationType::GLONASS, 20.5, 15.5, 11.5, 116.0, kGloG1FreqHz),
+            getMockSvInfo(17, GnssConstellationType::GLONASS, 21.5, 16.5, 28.5, 186.0,
+                          kGloG1FreqHz),
+            getMockSvInfo(18, GnssConstellationType::GLONASS, 28.3, 25.3, 38.8, 69.0, kGloG1FreqHz),
+            getMockSvInfo(10, GnssConstellationType::GLONASS, 25.0, 20.0, 66.0, 247.0,
+                          kGloG1FreqHz),
+            getMockSvInfo(3, GnssConstellationType::IRNSS, 22.0, 19.7, 35.0, 112.0, kIrnssL5FreqHz),
+    };
+    return gnssSvInfoList;
+}
+
 hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
     GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS,
                                                              32.5, 59.1, 166.5, kGpsL1FreqHz);
@@ -360,15 +397,15 @@
 GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
                                         float cN0DbHz, float elevationDegrees, float azimuthDegrees,
                                         float carrierFrequencyHz) {
-    GnssSvInfoV1_0 svInfo = {.svid = svid,
-                             .constellation = type,
-                             .cN0Dbhz = cN0DbHz,
-                             .elevationDegrees = elevationDegrees,
-                             .azimuthDegrees = azimuthDegrees,
-                             .carrierFrequencyHz = carrierFrequencyHz,
-                             .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
-                                       GnssSvFlags::HAS_ALMANAC_DATA |
-                                       GnssSvFlags::HAS_CARRIER_FREQUENCY};
+    GnssSvInfoV1_0 svInfo = {
+            .svid = svid,
+            .constellation = type,
+            .cN0Dbhz = cN0DbHz,
+            .elevationDegrees = elevationDegrees,
+            .azimuthDegrees = azimuthDegrees,
+            .carrierFrequencyHz = carrierFrequencyHz,
+            .svFlag = GnssSvFlagsV1_0::USED_IN_FIX | GnssSvFlagsV1_0::HAS_EPHEMERIS_DATA |
+                      GnssSvFlagsV1_0::HAS_ALMANAC_DATA | GnssSvFlagsV1_0::HAS_CARRIER_FREQUENCY};
     return svInfo;
 }
 
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 4500ee6..7065a6fb 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -35,9 +35,13 @@
             const bool enableCorrVecOutputs);
     static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
     static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+
     static aidl::android::hardware::gnss::GnssLocation getMockLocation();
     static V2_0::GnssLocation getMockLocationV2_0();
     static V1_0::GnssLocation getMockLocationV1_0();
+
+    static std::vector<aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo>
+    getMockSvInfoList();
     static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
     static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1(
             V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz);
@@ -48,6 +52,7 @@
                                                              float cN0DbHz, float elevationDegrees,
                                                              float azimuthDegrees,
                                                              float carrierFrequencyHz);
+
     static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
 };
 
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index 47eff2e..f92e609 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,6 +44,7 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.measurement_corrections@1.1",
+        "android.hardware.gnss-V2-cpp",
     ],
     static_libs: [
         "libgtest",
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index be22ff6..06bce9d 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <Utils.h>
+#include <android/hardware/gnss/IGnss.h>
 #include "gtest/gtest.h"
 
 #include <cutils/properties.h>
@@ -27,71 +28,14 @@
 using namespace measurement_corrections::V1_0;
 using V1_0::GnssLocationFlags;
 
-void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
-                          bool check_more_accuracies) {
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
-    if (check_speed) {
-        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
-    }
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
-    // New uncertainties available in O must be provided,
-    // at least when paired with modern hardware (2017+)
-    if (check_more_accuracies) {
-        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
-        if (check_speed) {
-            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
-            if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-                EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
-            }
-        }
-    }
-    EXPECT_GE(location.latitudeDegrees, -90.0);
-    EXPECT_LE(location.latitudeDegrees, 90.0);
-    EXPECT_GE(location.longitudeDegrees, -180.0);
-    EXPECT_LE(location.longitudeDegrees, 180.0);
-    EXPECT_GE(location.altitudeMeters, -1000.0);
-    EXPECT_LE(location.altitudeMeters, 30000.0);
-    if (check_speed) {
-        EXPECT_GE(location.speedMetersPerSec, 0.0);
-        EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
+template <>
+int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) {
+    return location.timestampMillis;
+}
 
-        // Non-zero speeds must be reported with an associated bearing
-        if (location.speedMetersPerSec > 0.0) {
-            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
-        }
-    }
-
-    /*
-     * Tolerating some especially high values for accuracy estimate, in case of
-     * first fix with especially poor geometry (happens occasionally)
-     */
-    EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
-    EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
-
-    /*
-     * Some devices may define bearing as -180 to +180, others as 0 to 360.
-     * Both are okay & understandable.
-     */
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-        EXPECT_GE(location.bearingDegrees, -180.0);
-        EXPECT_LE(location.bearingDegrees, 360.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
-        EXPECT_GT(location.verticalAccuracyMeters, 0.0);
-        EXPECT_LE(location.verticalAccuracyMeters, 500.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
-        EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
-        EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
-        EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
-        EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
-    }
-
-    // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
-    EXPECT_GT(location.timestamp, 1.48e12);
+template <>
+int64_t Utils::getLocationTimestampMillis(const V1_0::GnssLocation& location) {
+    return location.timestamp;
 }
 
 const MeasurementCorrections Utils::getMockMeasurementCorrections() {
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 91c1167..40f31d2 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -21,6 +21,7 @@
 #include <android/hardware/gnss/2.0/IGnss.h>
 #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
 #include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
+#include <gtest/gtest.h>
 
 namespace android {
 namespace hardware {
@@ -28,8 +29,9 @@
 namespace common {
 
 struct Utils {
-    static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
-                              bool check_more_accuracies);
+  public:
+    template <class T>
+    static void checkLocation(const T& location, bool check_speed, bool check_more_accuracies);
     static const measurement_corrections::V1_0::MeasurementCorrections
     getMockMeasurementCorrections();
     static const measurement_corrections::V1_1::MeasurementCorrections
@@ -39,8 +41,80 @@
             V2_0::GnssConstellationType constellation);
 
     static bool isAutomotiveDevice();
+
+  private:
+    template <class T>
+    static int64_t getLocationTimestampMillis(const T&);
 };
 
+template <class T>
+void Utils::checkLocation(const T& location, bool check_speed, bool check_more_accuracies) {
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_LAT_LONG);
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_ALTITUDE);
+    if (check_speed) {
+        EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED);
+    }
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+    // New uncertainties available in O must be provided,
+    // at least when paired with modern hardware (2017+)
+    if (check_more_accuracies) {
+        EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+        if (check_speed) {
+            EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY);
+            if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+                EXPECT_TRUE(location.gnssLocationFlags &
+                            V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY);
+            }
+        }
+    }
+    EXPECT_GE(location.latitudeDegrees, -90.0);
+    EXPECT_LE(location.latitudeDegrees, 90.0);
+    EXPECT_GE(location.longitudeDegrees, -180.0);
+    EXPECT_LE(location.longitudeDegrees, 180.0);
+    EXPECT_GE(location.altitudeMeters, -1000.0);
+    EXPECT_LE(location.altitudeMeters, 30000.0);
+    if (check_speed) {
+        EXPECT_GE(location.speedMetersPerSec, 0.0);
+        EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
+
+        // Non-zero speeds must be reported with an associated bearing
+        if (location.speedMetersPerSec > 0.0) {
+            EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING);
+        }
+    }
+
+    /*
+     * Tolerating some especially high values for accuracy estimate, in case of
+     * first fix with especially poor geometry (happens occasionally)
+     */
+    EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
+    EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
+
+    /*
+     * Some devices may define bearing as -180 to +180, others as 0 to 360.
+     * Both are okay & understandable.
+     */
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+        EXPECT_GE(location.bearingDegrees, -180.0);
+        EXPECT_LE(location.bearingDegrees, 360.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+        EXPECT_GT(location.verticalAccuracyMeters, 0.0);
+        EXPECT_LE(location.verticalAccuracyMeters, 500.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
+        EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
+        EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
+        EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
+        EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
+    }
+
+    // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
+    EXPECT_GT(getLocationTimestampMillis(location), 1.48e12);
+}
+
 }  // namespace common
 }  // namespace gnss
 }  // namespace hardware
diff --git a/gnss/common/utils/vts/include/v2_1/GnssCallback.h b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
index ab1375d..09a67de 100644
--- a/gnss/common/utils/vts/include/v2_1/GnssCallback.h
+++ b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
@@ -28,7 +28,6 @@
 using android::hardware::gnss::common::GnssCallbackEventQueue;
 using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
 using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V2_0::GnssConstellationType;
 
 using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
 using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;