Merge "Implement bootctrl aidl"
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index fcc1f98..9e4f7c7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -19,11 +19,17 @@
 #include "GnssMeasurementInterface.h"
 #include <aidl/android/hardware/gnss/BnGnss.h>
 #include <log/log.h>
+#include "DeviceFileReader.h"
+#include "GnssRawMeasurementParser.h"
+#include "GnssReplayUtils.h"
 #include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
 
 using Utils = ::android::hardware::gnss::common::Utils;
+using ReplayUtils = ::android::hardware::gnss::common::ReplayUtils;
+using GnssRawMeasurementParser = ::android::hardware::gnss::common::GnssRawMeasurementParser;
+using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
 
 std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
 
@@ -63,9 +69,22 @@
     mIsActive = true;
     mThread = std::thread([this, enableCorrVecOutputs]() {
         while (mIsActive == true) {
-            auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
-            this->reportMeasurement(measurement);
-
+            std::string rawMeasurementStr = "";
+            if (ReplayUtils::hasGnssDeviceFile() &&
+                ReplayUtils::isGnssRawMeasurement(
+                        rawMeasurementStr =
+                                DeviceFileReader::Instance().getGnssRawMeasurementData())) {
+                ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(),
+                      rawMeasurementStr.c_str());
+                auto measurement =
+                        GnssRawMeasurementParser::getMeasurementFromStrs(rawMeasurementStr);
+                if (measurement != nullptr) {
+                    this->reportMeasurement(*measurement);
+                }
+            } else {
+                auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
+                this->reportMeasurement(measurement);
+            }
             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
         }
     });
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index a1d3123..dda8a44 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -38,9 +38,14 @@
         "v2_1/GnssDebug.cpp",
         "v2_1/GnssMeasurement.cpp",
         "v2_1/GnssMeasurementCorrections.cpp",
+        "DeviceFileReader.cpp",
+        "FixLocationParser.cpp",
+        "GnssRawMeasurementParser.cpp",
+        "GnssReplayUtils.cpp",
         "MockLocation.cpp",
-        "Utils.cpp",
         "NmeaFixInfo.cpp",
+        "ParseUtils.cpp",
+        "Utils.cpp",
     ],
     export_include_dirs: ["include"],
     shared_libs: [
diff --git a/gnss/common/utils/default/DeviceFileReader.cpp b/gnss/common/utils/default/DeviceFileReader.cpp
new file mode 100644
index 0000000..dfc086a
--- /dev/null
+++ b/gnss/common/utils/default/DeviceFileReader.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "DeviceFileReader.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+void DeviceFileReader::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
+    char inputBuffer[INPUT_BUFFER_SIZE];
+    std::string deviceFilePath = "";
+    if (command == CMD_GET_LOCATION) {
+        deviceFilePath = ReplayUtils::getFixedLocationPath();
+    } else if (command == CMD_GET_RAWMEASUREMENT) {
+        deviceFilePath = ReplayUtils::getGnssPath();
+    } else {
+        // Invalid command
+        return;
+    }
+
+    int mGnssFd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK);
+
+    if (mGnssFd == -1) {
+        return;
+    }
+
+    int bytes_write = write(mGnssFd, command.c_str(), command.size());
+    if (bytes_write <= 0) {
+        close(mGnssFd);
+        return;
+    }
+
+    struct epoll_event ev, events[1];
+    ev.data.fd = mGnssFd;
+    ev.events = EPOLLIN;
+    int epoll_fd = epoll_create1(0);
+    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
+    int bytes_read = -1;
+    std::string inputStr = "";
+    int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
+
+    if (epoll_ret == -1) {
+        close(mGnssFd);
+        return;
+    }
+    while (true) {
+        memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
+        bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
+        if (bytes_read <= 0) {
+            break;
+        }
+        s_buffer_ += std::string(inputBuffer, bytes_read);
+    }
+    close(mGnssFd);
+
+    // Trim end of file mark(\n\n\n\n).
+    auto pos = s_buffer_.find("\n\n\n\n");
+    if (pos != std::string::npos) {
+        inputStr = s_buffer_.substr(0, pos);
+        s_buffer_ = s_buffer_.substr(pos + 4);
+    } else {
+        return;
+    }
+
+    // Cache the injected data.
+    if (command == CMD_GET_LOCATION) {
+        // TODO validate data
+        data_[CMD_GET_LOCATION] = inputStr;
+    } else if (command == CMD_GET_RAWMEASUREMENT) {
+        if (ReplayUtils::isGnssRawMeasurement(inputStr)) {
+            data_[CMD_GET_RAWMEASUREMENT] = inputStr;
+        }
+    }
+}
+
+std::string DeviceFileReader::getLocationData() {
+    std::unique_lock<std::mutex> lock(mMutex);
+    getDataFromDeviceFile(CMD_GET_LOCATION, 20);
+    return data_[CMD_GET_LOCATION];
+}
+
+std::string DeviceFileReader::getGnssRawMeasurementData() {
+    std::unique_lock<std::mutex> lock(mMutex);
+    getDataFromDeviceFile(CMD_GET_RAWMEASUREMENT, 20);
+    return data_[CMD_GET_RAWMEASUREMENT];
+}
+
+DeviceFileReader::DeviceFileReader() {}
+
+DeviceFileReader::~DeviceFileReader() {}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/FixLocationParser.cpp b/gnss/common/utils/default/FixLocationParser.cpp
new file mode 100644
index 0000000..f0177b4
--- /dev/null
+++ b/gnss/common/utils/default/FixLocationParser.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FixLocationParser.h"
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+std::unique_ptr<V2_0::GnssLocation> FixLocationParser::getLocationFromInputStr(
+        const std::string& locationStr) {
+    /*
+     * Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps,
+     * AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees,
+     * elapsedRealtimeNanos
+     */
+    if (locationStr.empty()) {
+        return nullptr;
+    }
+    std::vector<std::string> locationStrRecords;
+    ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords);
+    if (locationStrRecords.empty()) {
+        return nullptr;
+    }
+
+    std::vector<std::string> locationValues;
+    ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues);
+    if (locationValues.size() < 12) {
+        return nullptr;
+    }
+    V2_0::ElapsedRealtime elapsedRealtime = {
+            .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+                     V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+
+    V1_0::GnssLocation locationV1 = {
+            .gnssLocationFlags = 0xFF,
+            .latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0),
+            .longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0),
+            .altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0),
+            .speedMetersPerSec = ParseUtils::tryParsefloat(locationValues[5], 0),
+            .bearingDegrees = ParseUtils::tryParsefloat(locationValues[7], 0),
+            .horizontalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
+            .verticalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
+            .speedAccuracyMetersPerSecond = ParseUtils::tryParsefloat(locationValues[9], 0),
+            .bearingAccuracyDegrees = ParseUtils::tryParsefloat(locationValues[10], 0),
+            .timestamp = ParseUtils::tryParseLongLong(locationValues[8], 0)};
+
+    V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = elapsedRealtime};
+    return std::make_unique<V2_0::GnssLocation>(locationV2);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/GnssRawMeasurementParser.cpp b/gnss/common/utils/default/GnssRawMeasurementParser.cpp
new file mode 100644
index 0000000..c066229
--- /dev/null
+++ b/gnss/common/utils/default/GnssRawMeasurementParser.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssRawMeasurementParser.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+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::GnssMeasurement;
+using aidl::android::hardware::gnss::GnssMultipathIndicator;
+using aidl::android::hardware::gnss::GnssSignalType;
+
+using ParseUtils = ::android::hardware::gnss::common::ParseUtils;
+
+std::unordered_map<std::string, int> GnssRawMeasurementParser::getColumnIdNameMappingFromHeader(
+        const std::string& header) {
+    std::vector<std::string> columnNames;
+    std::unordered_map<std::string, int> columnNameIdMapping;
+    std::string s = header;
+    // Trim left spaces
+    s.erase(s.begin(),
+            std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
+    // Trim right spaces
+    s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); })
+                    .base(),
+            s.end());
+    // Remove comment symbol, start from `Raw`.
+    s = s.substr(s.find("Raw"));
+
+    ParseUtils::splitStr(s, COMMA_SEPARATOR, columnNames);
+    int columnId = 0;
+    for (auto& name : columnNames) {
+        columnNameIdMapping[name] = columnId++;
+    }
+
+    return columnNameIdMapping;
+}
+
+int GnssRawMeasurementParser::getClockFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int clockFlags = 0;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("LeapSecond")].empty()) {
+        clockFlags |= GnssClock::HAS_LEAP_SECOND;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullBiasNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_FULL_BIAS;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_BIAS;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_BIAS_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")].empty()) {
+        clockFlags |= GnssClock::HAS_DRIFT;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftUncertaintyNanosPerSecond")]
+                 .empty()) {
+        clockFlags |= GnssClock::HAS_DRIFT_UNCERTAINTY;
+    }
+    return clockFlags;
+}
+
+int GnssRawMeasurementParser::getElapsedRealtimeFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int elapsedRealtimeFlags = ElapsedRealtime::HAS_TIMESTAMP_NS;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")].empty()) {
+        elapsedRealtimeFlags |= ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS;
+    }
+    return elapsedRealtimeFlags;
+}
+
+int GnssRawMeasurementParser::getRawMeasurementFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int rawMeasurementFlags = 0;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("SnrInDb")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SNR;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierFrequencyHz")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_FREQUENCY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierCycles")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_CYCLES;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhase")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhaseUncertainty")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("AgcDb")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasNanos")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasUncertaintyNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("SatelliteInterSignalBiasNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at(
+                                            "SatelliteInterSignalBiasUncertaintyNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY;
+    }
+    // HAS_SATELLITE_PVT and HAS_CORRELATION_VECTOR fields currently not in rawmeasurement
+    // output, need add them later.
+    return rawMeasurementFlags;
+}
+
+GnssConstellationType GnssRawMeasurementParser::getGnssConstellationType(int constellationType) {
+    GnssConstellationType gnssConstellationType =
+            aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
+
+    switch (constellationType) {
+        case 1:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GPS;
+            break;
+        case 2:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::SBAS;
+            break;
+        case 3:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GLONASS;
+            break;
+        case 4:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::QZSS;
+            break;
+        case 5:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::BEIDOU;
+            break;
+        case 6:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GALILEO;
+            break;
+        default:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
+    }
+
+    return gnssConstellationType;
+}
+
+std::unique_ptr<GnssData> GnssRawMeasurementParser::getMeasurementFromStrs(
+        std::string& rawMeasurementStr) {
+    /*
+     * Raw,utcTimeMillis,TimeNanos,LeapSecond,TimeUncertaintyNanos,FullBiasNanos,BiasNanos,
+     * BiasUncertaintyNanos,DriftNanosPerSecond,DriftUncertaintyNanosPerSecond,
+     * HardwareClockDiscontinuityCount,Svid,TimeOffsetNanos,State,ReceivedSvTimeNanos,
+     * ReceivedSvTimeUncertaintyNanos,Cn0DbHz,PseudorangeRateMetersPerSecond,
+     * PseudorangeRateUncertaintyMetersPerSecond,AccumulatedDeltaRangeState,
+     * AccumulatedDeltaRangeMeters,AccumulatedDeltaRangeUncertaintyMeters,CarrierFrequencyHz,
+     * CarrierCycles,CarrierPhase,CarrierPhaseUncertainty,MultipathIndicator,SnrInDb,
+     * ConstellationType,AgcDb,BasebandCn0DbHz,FullInterSignalBiasNanos,
+     * FullInterSignalBiasUncertaintyNanos,SatelliteInterSignalBiasNanos,
+     * SatelliteInterSignalBiasUncertaintyNanos,CodeType,ChipsetElapsedRealtimeNanos
+     */
+    ALOGD("Parsing %zu bytes rawMeasurementStr.", rawMeasurementStr.size());
+    if (rawMeasurementStr.empty()) {
+        return nullptr;
+    }
+    std::vector<std::string> rawMeasurementStrRecords;
+    ParseUtils::splitStr(rawMeasurementStr, LINE_SEPARATOR, rawMeasurementStrRecords);
+    if (rawMeasurementStrRecords.size() <= 1) {
+        ALOGE("Raw GNSS Measurements parser failed. (No records) ");
+        return nullptr;
+    }
+
+    // Get the column name mapping from the header.
+    std::unordered_map<std::string, int> columnNameIdMapping =
+            getColumnIdNameMappingFromHeader(rawMeasurementStrRecords[0]);
+
+    if (columnNameIdMapping.size() < 37 || !ParseUtils::isValidHeader(columnNameIdMapping)) {
+        ALOGE("Raw GNSS Measurements parser failed. (No header or missing columns.) ");
+        return nullptr;
+    }
+
+    // Set GnssClock from 1st record.
+    std::size_t pointer = 1;
+    std::vector<std::string> firstRecordValues;
+    ParseUtils::splitStr(rawMeasurementStrRecords[pointer], COMMA_SEPARATOR, firstRecordValues);
+    GnssClock clock = {
+            .gnssClockFlags = getClockFlags(firstRecordValues, columnNameIdMapping),
+            .timeNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("TimeNanos")], 0),
+            .fullBiasNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("FullBiasNanos")], 0),
+            .biasNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("BiasNanos")], 0),
+            .biasUncertaintyNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")], 0),
+            .driftNsps = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
+            .driftUncertaintyNsps = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
+            .hwClockDiscontinuityCount = ParseUtils::tryParseInt(
+                    firstRecordValues[columnNameIdMapping.at("HardwareClockDiscontinuityCount")],
+                    0)};
+
+    ElapsedRealtime timestamp = {
+            .flags = getElapsedRealtimeFlags(firstRecordValues, columnNameIdMapping),
+            .timestampNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("ChipsetElapsedRealtimeNanos")]),
+            .timeUncertaintyNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")], 0)};
+
+    std::vector<GnssMeasurement> measurementsVec;
+    for (pointer = 1; pointer < rawMeasurementStrRecords.size(); pointer++) {
+        std::vector<std::string> rawMeasurementValues;
+        std::string line = rawMeasurementStrRecords[pointer];
+        ParseUtils::splitStr(line, COMMA_SEPARATOR, rawMeasurementValues);
+        GnssSignalType signalType = {
+                .constellation = getGnssConstellationType(ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("ConstellationType")], 0)),
+                .carrierFrequencyHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("CarrierFrequencyHz")], 0),
+                .codeType = rawMeasurementValues[columnNameIdMapping.at("CodeType")],
+        };
+        GnssMeasurement measurement = {
+                .flags = getRawMeasurementFlags(rawMeasurementValues, columnNameIdMapping),
+                .svid = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("Svid")], 0),
+                .signalType = signalType,
+                .receivedSvTimeInNs = ParseUtils::tryParseLongLong(
+                        rawMeasurementValues[columnNameIdMapping.at("ReceivedSvTimeNanos")], 0),
+                .receivedSvTimeUncertaintyInNs =
+                        ParseUtils::tryParseLongLong(rawMeasurementValues[columnNameIdMapping.at(
+                                                             "ReceivedSvTimeUncertaintyNanos")],
+                                                     0),
+                .antennaCN0DbHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("Cn0DbHz")], 0),
+                .basebandCN0DbHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("BasebandCn0DbHz")], 0),
+                .agcLevelDb = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("AgcDb")], 0),
+                .pseudorangeRateMps =
+                        ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
+                                                           "PseudorangeRateMetersPerSecond")],
+                                                   0),
+                .pseudorangeRateUncertaintyMps = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "PseudorangeRateUncertaintyMetersPerSecond")],
+                        0),
+                .accumulatedDeltaRangeState = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeState")],
+                        0),
+                .accumulatedDeltaRangeM = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeMeters")],
+                        0),
+                .accumulatedDeltaRangeUncertaintyM = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "AccumulatedDeltaRangeUncertaintyMeters")],
+                        0),
+                .multipathIndicator = GnssMultipathIndicator::UNKNOWN,  // Not in GnssLogger yet.
+                .state = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("State")], 0),
+                .fullInterSignalBiasNs = ParseUtils::tryParseDouble(rawMeasurementValues[31], 0),
+                .fullInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("FullInterSignalBiasNanos")],
+                        0),
+                .satelliteInterSignalBiasNs =
+                        ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
+                                                           "SatelliteInterSignalBiasNanos")],
+                                                   0),
+                .satelliteInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "SatelliteInterSignalBiasUncertaintyNanos")],
+                        0),
+                .satellitePvt = {},
+                .correlationVectors = {}};
+        measurementsVec.push_back(measurement);
+    }
+
+    GnssData gnssData = {
+            .measurements = measurementsVec, .clock = clock, .elapsedRealtime = timestamp};
+    return std::make_unique<GnssData>(gnssData);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp
new file mode 100644
index 0000000..d6769bd
--- /dev/null
+++ b/gnss/common/utils/default/GnssReplayUtils.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GnssReplayUtils.h"
+
+#include <array>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+std::string ReplayUtils::getGnssPath() {
+    std::array<char, PROPERTY_VALUE_MAX> devname_value;
+
+    devname_value.fill(0);
+    if (property_get("debug.location.gnss.devname", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    devname_value.fill(0);
+    if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    return GNSS_PATH;
+}
+
+std::string ReplayUtils::getFixedLocationPath() {
+    std::array<char, PROPERTY_VALUE_MAX> devname_value;
+
+    devname_value.fill(0);
+    if (property_get("debug.location.fixedlocation.devname", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    devname_value.fill(0);
+    if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    return FIXED_LOCATION_PATH;
+}
+
+bool ReplayUtils::hasGnssDeviceFile() {
+    struct stat sb;
+    return stat(getGnssPath().c_str(), &sb) != -1;
+}
+
+bool ReplayUtils::hasFixedLocationDeviceFile() {
+    struct stat sb;
+    return stat(getFixedLocationPath().c_str(), &sb) != -1;
+}
+
+bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) {
+    // TODO: add more logic check to by pass invalid data.
+    return !inputStr.empty() && (inputStr.find("Raw") != std::string::npos);
+}
+
+bool ReplayUtils::isNMEA(const std::string& inputStr) {
+    return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
+                                 inputStr.find("$GPRMA,", 0) != std::string::npos);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/ParseUtils.cpp b/gnss/common/utils/default/ParseUtils.cpp
new file mode 100644
index 0000000..648edf7
--- /dev/null
+++ b/gnss/common/utils/default/ParseUtils.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ParseUtils.h>
+#include <sstream>
+#include <stdexcept>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+int ParseUtils::tryParseInt(const std::string& s, int defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stoi(s);
+    }
+}
+
+float ParseUtils::tryParsefloat(const std::string& s, float defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stof(s);
+    }
+}
+
+double ParseUtils::tryParseDouble(const std::string& s, double defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stod(s);
+    }
+}
+
+long ParseUtils::tryParseLong(const std::string& s, long defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stol(s);
+    }
+}
+
+long long ParseUtils::tryParseLongLong(const std::string& s, long long defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stoll(s);
+    }
+}
+
+void ParseUtils::splitStr(const std::string& line, const char& delimiter,
+                          std::vector<std::string>& out) {
+    std::istringstream iss(line);
+    std::string item;
+    while (std::getline(iss, item, delimiter)) {
+        out.push_back(item);
+    }
+}
+
+bool ParseUtils::isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    std::vector<std::string> requiredHeaderColumns = {"Raw",
+                                                      "utcTimeMillis",
+                                                      "TimeNanos",
+                                                      "LeapSecond",
+                                                      "TimeUncertaintyNanos",
+                                                      "FullBiasNanos",
+                                                      "BiasNanos",
+                                                      "BiasUncertaintyNanos",
+                                                      "DriftNanosPerSecond",
+                                                      "DriftUncertaintyNanosPerSecond",
+                                                      "HardwareClockDiscontinuityCount",
+                                                      "Svid",
+                                                      "TimeOffsetNanos",
+                                                      "State",
+                                                      "ReceivedSvTimeNanos",
+                                                      "ReceivedSvTimeUncertaintyNanos",
+                                                      "Cn0DbHz",
+                                                      "PseudorangeRateMetersPerSecond",
+                                                      "PseudorangeRateUncertaintyMetersPerSecond",
+                                                      "AccumulatedDeltaRangeState",
+                                                      "AccumulatedDeltaRangeMeters",
+                                                      "AccumulatedDeltaRangeUncertaintyMeters",
+                                                      "CarrierFrequencyHz",
+                                                      "CarrierCycles",
+                                                      "CarrierPhase",
+                                                      "CarrierPhaseUncertainty",
+                                                      "MultipathIndicator",
+                                                      "SnrInDb",
+                                                      "ConstellationType",
+                                                      "AgcDb",
+                                                      "BasebandCn0DbHz",
+                                                      "FullInterSignalBiasNanos",
+                                                      "FullInterSignalBiasUncertaintyNanos",
+                                                      "SatelliteInterSignalBiasNanos",
+                                                      "SatelliteInterSignalBiasUncertaintyNanos",
+                                                      "CodeType",
+                                                      "ChipsetElapsedRealtimeNanos"};
+
+    for (const auto& columnName : requiredHeaderColumns) {
+        if (columnNameIdMapping.find(columnName) == columnNameIdMapping.end()) {
+            ALOGE("Missing column %s in header.", columnName.c_str());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 22afee1..489413e 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -34,6 +34,19 @@
 const float kGloG1FreqHz = 1602.0 * 1e6;
 const float kIrnssL5FreqHz = 1176.45 * 1e6;
 
+// Location replay constants
+constexpr char GNSS_PATH[] = "/dev/gnss0";
+constexpr char FIXED_LOCATION_PATH[] = "/dev/gnss1";
+constexpr int INPUT_BUFFER_SIZE = 256;
+constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
+constexpr char CMD_GET_RAWMEASUREMENT[] = "CMD_GET_RAWMEASUREMENT";
+constexpr char LINE_SEPARATOR = '\n';
+constexpr char COMMA_SEPARATOR = ',';
+constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
+constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
+constexpr double TIMESTAMP_EPSILON = 0.001;
+constexpr int MIN_COL_NUM = 13;
+
 }  // namespace common
 }  // namespace gnss
 }  // namespace hardware
diff --git a/gnss/common/utils/default/include/DeviceFileReader.h b/gnss/common/utils/default/include/DeviceFileReader.h
new file mode 100644
index 0000000..c2a5c5f
--- /dev/null
+++ b/gnss/common/utils/default/include/DeviceFileReader.h
@@ -0,0 +1,53 @@
+
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef android_hardware_gnss_common_default_DeviceFileReader_H_
+#define android_hardware_gnss_common_default_DeviceFileReader_H_
+
+#include <log/log.h>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include "Constants.h"
+#include "GnssReplayUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+class DeviceFileReader {
+  public:
+    static DeviceFileReader& Instance() {
+        static DeviceFileReader reader;
+        return reader;
+    }
+    std::string getLocationData();
+    std::string getGnssRawMeasurementData();
+    void getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
+
+  private:
+    DeviceFileReader();
+    ~DeviceFileReader();
+    std::unordered_map<std::string, std::string> data_;
+    std::string s_buffer_;
+    std::mutex mMutex;
+};
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_DeviceFileReader_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/FixLocationParser.h b/gnss/common/utils/default/include/FixLocationParser.h
new file mode 100644
index 0000000..19748a9
--- /dev/null
+++ b/gnss/common/utils/default/include/FixLocationParser.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_FixLocationParser_H_
+#define android_hardware_gnss_common_default_FixLocationParser_H_
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+
+#include <utils/SystemClock.h>
+#include <string>
+#include <vector>
+
+#include <Constants.h>
+#include <Utils.h>
+#include <log/log.h>
+#include "Constants.h"
+#include "ParseUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct FixLocationParser {
+  public:
+    static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_FixLocationParser_H_
diff --git a/gnss/common/utils/default/include/GnssRawMeasurementParser.h b/gnss/common/utils/default/include/GnssRawMeasurementParser.h
new file mode 100644
index 0000000..7d6b4ef
--- /dev/null
+++ b/gnss/common/utils/default/include/GnssRawMeasurementParser.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
+#define android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
+
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include <string>
+#include <unordered_map>
+
+#include "Constants.h"
+#include "ParseUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct GnssRawMeasurementParser {
+    static std::unique_ptr<aidl::android::hardware::gnss::GnssData> getMeasurementFromStrs(
+            std::string& rawMeasurementStr);
+    static int getClockFlags(const std::vector<std::string>& rawMeasurementRecordValues,
+                             const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static int getElapsedRealtimeFlags(
+            const std::vector<std::string>& rawMeasurementRecordValues,
+            const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static int getRawMeasurementFlags(
+            const std::vector<std::string>& rawMeasurementRecordValues,
+            const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static std::unordered_map<std::string, int> getColumnIdNameMappingFromHeader(
+            const std::string& header);
+    static aidl::android::hardware::gnss::GnssConstellationType getGnssConstellationType(
+            int constellationType);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/GnssReplayUtils.h b/gnss/common/utils/default/include/GnssReplayUtils.h
new file mode 100644
index 0000000..d1bbed4
--- /dev/null
+++ b/gnss/common/utils/default/include/GnssReplayUtils.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_GnssReplayUtils_H_
+#define android_hardware_gnss_common_GnssReplayUtils_H_
+
+#include <cutils/properties.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <chrono>
+#include <string>
+#include <thread>
+
+#include "Constants.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct ReplayUtils {
+    static std::string getGnssPath();
+
+    static std::string getFixedLocationPath();
+
+    static std::string getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
+
+    static bool hasGnssDeviceFile();
+
+    static bool hasFixedLocationDeviceFile();
+
+    static bool isGnssRawMeasurement(const std::string& inputStr);
+
+    static bool isNMEA(const std::string& inputStr);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_GnssReplayUtils_H_
diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h
index c96eece..5c27045 100644
--- a/gnss/common/utils/default/include/NmeaFixInfo.h
+++ b/gnss/common/utils/default/include/NmeaFixInfo.h
@@ -27,13 +27,6 @@
 namespace gnss {
 namespace common {
 
-constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
-constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
-constexpr char LINE_SEPARATOR = '\n';
-constexpr char COMMA_SEPARATOR = ',';
-constexpr double TIMESTAMP_EPSILON = 0.001;
-constexpr int MIN_COL_NUM = 13;
-
 /** Helper class to parse and store the GNSS fix details information. */
 class NmeaFixInfo {
   private:
diff --git a/gnss/common/utils/default/include/ParseUtils.h b/gnss/common/utils/default/include/ParseUtils.h
new file mode 100644
index 0000000..3a56313
--- /dev/null
+++ b/gnss/common/utils/default/include/ParseUtils.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_ParseUtils_H_
+#define android_hardware_gnss_common_default_ParseUtils_H_
+
+#include <log/log.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct ParseUtils {
+    static int tryParseInt(const std::string& s, int defaultVal = 0);
+    static float tryParsefloat(const std::string& s, float defaultVal = 0.0);
+    static double tryParseDouble(const std::string& s, double defaultVal = 0.0);
+    static long tryParseLong(const std::string& s, long defaultVal = 0);
+    static long long tryParseLongLong(const std::string& s, long long defaultVal = 0);
+    static void splitStr(const std::string& line, const char& delimiter,
+                         std::vector<std::string>& out);
+    static bool isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_ParseUtils_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 48cab99..473e587 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -30,13 +30,15 @@
 
 #include <cutils/properties.h>
 
+#include "DeviceFileReader.h"
+#include "FixLocationParser.h"
 #include "GnssAntennaInfo.h"
 #include "GnssConfiguration.h"
 #include "GnssDebug.h"
 #include "GnssMeasurement.h"
 #include "GnssMeasurementCorrections.h"
+#include "GnssReplayUtils.h"
 #include "MockLocation.h"
-#include "NmeaFixInfo.h"
 #include "Utils.h"
 
 namespace android::hardware::gnss::common::implementation {
@@ -159,53 +161,13 @@
 
 template <class T_IGnss>
 std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
-    char inputBuffer[INPUT_BUFFER_SIZE];
-    if (!mHardwareModeChecked) {
-        // default using gnss0
-        const char * gnss_dev_path = GNSS_PATH;
-        char devname_value[PROPERTY_VALUE_MAX] = "";
-        if (property_get("debug.location.gnss.devname", devname_value, NULL) > 0) {
-            gnss_dev_path = devname_value;
-            ALOGD("using %s instead of the default %s", gnss_dev_path, GNSS_PATH);
-        }
-
-        mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK);
-        if (mGnssFd == -1) {
-            ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno);
-        }
-        mHardwareModeChecked = true;
-    }
-
-    if (mGnssFd == -1) {
+    mHardwareModeChecked = true;
+    if (!ReplayUtils::hasFixedLocationDeviceFile()) {
         return nullptr;
     }
-
-    int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
-    if (bytes_write <= 0) {
-        return nullptr;
-    }
-
-    struct epoll_event ev, events[1];
-    ev.data.fd = mGnssFd;
-    ev.events = EPOLLIN;
-    int epoll_fd = epoll_create1(0);
-    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
-    int bytes_read = -1;
-    std::string inputStr = "";
-    int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
-
-    if (epoll_ret == -1) {
-        return nullptr;
-    }
-    while (true) {
-        memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
-        bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
-        if (bytes_read <= 0) {
-            break;
-        }
-        inputStr += std::string(inputBuffer, bytes_read);
-    }
-    return NmeaFixInfo::getLocationFromInputStr(inputStr);
+    std::string inputStr =
+            ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
+    return FixLocationParser::getLocationFromInputStr(inputStr);
 }
 
 template <class T_IGnss>
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 29b31d2..a41f37f 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -90,7 +90,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index e9d4b76..7c1c118 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -58,7 +58,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 2177924..7e4b5bb 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -85,7 +85,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 9fa0f0a..07071cc 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -92,7 +92,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index d296828..3218206 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -17,54 +17,10 @@
     },
     {
       "name": "neuralnetworks_utils_hal_aidl_test"
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_0TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_1TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
     }
   ],
   "presubmit-large": [
     {
-      "name": "VtsHalNeuralnetworksV1_2TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_3TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
       "name": "VtsHalNeuralnetworksTargetTest",
       "options": [
         {
diff --git a/security/OWNERS b/security/OWNERS
index 54d820a..4142fc1 100644
--- a/security/OWNERS
+++ b/security/OWNERS
@@ -1,3 +1,6 @@
+# Please assign all bugs related to /hardware/interfaces/security to the team alias,
+# android-hardware-security@google.com.  This will get them auto-assigned to the on-call triage
+# engineer, ensuring quickest response.
 drysdale@google.com
 jbires@google.com
 jdanis@google.com
diff --git a/security/keymint/RKP_README.md b/security/keymint/RKP_README.md
new file mode 100644
index 0000000..89a2598
--- /dev/null
+++ b/security/keymint/RKP_README.md
@@ -0,0 +1,374 @@
+# Remote Provisioning HAL
+
+## Objective
+
+Design a HAL to support over-the-air provisioning of certificates for asymmetric
+keys. The HAL must interact effectively with Keystore (and other daemons) and
+protect device privacy and security.
+
+Note that this API is designed for KeyMint, but with the intention that it
+should be usable for other HALs that require certificate provisioning.
+Throughout this document we'll refer to the Keystore and KeyMint (formerly
+called Keymaster) components, but only for concreteness and convenience; those
+labels could be replaced with the names of any system and secure area
+components, respectively, that need certificates provisioned.
+
+## Key design decisions
+
+### General approach
+
+To more securely and reliably get keys and certificates to Android devices, we
+need to create a system where no party outside of the device's secure components
+is responsible for managing private keys. The strategy we've chosen is to
+deliver certificates over the air, using an asymmetric key pair created
+on-device in the factory as a root of trust to create an authenticated, secure
+channel. In this document we refer to this device-unique asymmetric key pair as
+Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
+Key Certificate containing DK\_pub is denoted DKC.
+
+In order for the provisioning service to use DK (or a key authenticated by DK),
+it must know whether a given DK\_pub is known and trusted. To prove trust, we
+ask device OEMs to use one of two mechanisms:
+
+1.  (Preferred, recommended) The device OEM extracts DK\_pub from each device it
+    manufactures and uploads the public keys to a backend server.
+
+1.  The device OEM signs the DK\_pub to produce DKC and stores it on the device.
+    This has the advantage that they don't need to upload a DK\_pub for every
+    device immediately, but the disadvantage that they have to manage their
+    private signing keys, which means they have to have HSMs, configure and
+    secure them correctly, etc. Some backend providers may also require that the
+    OEM passes a factory security audit, and additionally promises to upload the
+    keys eventually as well.
+
+Note that in the full elaboration of this plan, DK\_pub is not the key used to
+establish a secure channel. Instead, DK\_pub is just the first public key in a
+chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
+in the chain are device-unique and are joined in a certificate chain called the
+_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
+provisioning project it is a chain of certificates corresponding to boot phases.
+We speak of the BCC even for phase 1, though in phase 1 it contains only a
+single self-signed DKC. This is described in more depth in the Phases section
+below.
+
+The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
+additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
+part of the BCC but included as optional fields in the certificate request
+structure.
+
+The format of the the DK and BCC is specified within [Open Profile for DICE]
+(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md).  To
+map phrases within this document to their equivalent terminology in the DICE
+specification, read the terms as follows: the DK corresponds to the UDS-derived
+key pair, DKC corresponds to the UDS certificate, and the BCC entries between
+DK\_pub and KM\_pub correspond to a chain of CDI certificates.
+
+Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
+this spec additionally constrains some of the choices allowed in open-DICE.
+Specifically, these include which entries are required and which are optional in
+the BCC payload, and which algorithms are acceptable for use.
+
+### Phases
+
+RKP will be deployed in three phases, in terms of managing the root of trust
+binding between the device and the backend. To briefly describe them:
+
+* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
+  the same key and the certificate is self-signed.
+* Phase 2: This is identical to phase 1, except it leverages the hardware root
+  of trust process described by DICE. Instead of trust being rooted in the TEE,
+  it is now rooted in the ROM by key material blown into fuses which are only
+  accessible to the ROM code.
+* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
+  public key extraction or certification in their facilities, along with the OEM
+  doing it in the factory. This tightens up the "supply chain" and aims to make
+  key upload management more secure.
+
+### Privacy considerations
+
+Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
+identifiers for the device, we must limit access to them to the absolute minimum
+possible. We do this in two ways:
+
+1.  We require KeyMint (which knows the BCC and either knows or at least has the
+ability to use KM\_priv) to refuse to ever divulge the BCC or additional
+signatures in plaintext. Instead, KeyMint requires the caller to provide an
+_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
+returning it. When provisioning production keys, the EEK must be signed by an
+approved authority whose public key is embedded in KeyMint. When certifying test
+keys, KeyMint will accept any EEK without checking the signature, but will
+encrypt and return a test BCC, rather than the real one.  The result is that
+only an entity in possession of an Trusted EEK (TEEK) private key can discover
+the plaintext of the production BCC.
+1.  Having thus limited access to the public keys to the trusted party only, we
+need to prevent the entity from abusing this unique device identifier.  The
+approach and mechanisms for doing that are beyond the scope of this document
+(they must be addressed in the server design), but generally involve taking care
+to ensure that we do not create any links between user IDs, IP addresses or
+issued certificates and the device pubkey.
+
+Although the details of the mechanisms for preventing the entity from abusing
+the BCC are, as stated, beyond the scope of this document, there is a subtle
+design decision here made specifically to enable abuse prevention. Specifically
+the `CertificateRequest` message sent to the server is (in
+[CDDL](https://tools.ietf.org/html/rfc8610)):
+
+```
+cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,
+    ProtectedData,
+    MacedKeysToSign
+]
+```
+
+The public keys to be attested by the server are in `MacedKeysToSign`, which is
+a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
+MAC key is signed by DK\_pub.
+
+This structure allows the backend component that has access to EEK\_priv to
+decrypt `ProtectedData`, validate that the request is from an authorized device,
+check that the request is fresh and verify and extract the MAC key. That backend
+component never sees any data related to the keys to be signed, but can provide
+the MAC key to another backend component that can verify `MacedKeysToSign` and
+proceed to generate the certificates.
+
+In this way, we can partition the provisioning server into one component that
+knows the device identity, as represented by DK\_pub, but never sees the keys to
+be certified or certificates generated, and another component that sees the keys
+to be certified and certificates generated but does not know the device
+identity.
+
+### Key and cryptographic message formatting
+
+For simplicity of generation and parsing, compactness of wire representation,
+and flexibility and standardization, we've settled on using the CBOR Object
+Signing and Encryption (COSE) standard, defined in [RFC
+8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably
+simple, yet easily-extensible, wire formats for:
+
+*   Keys,
+*   MACed messages,
+*   Signed messages, and
+*   Encrypted messages
+
+COSE enables easy layering of these message formats, such as using a COSE\_Sign
+structure to contain a COSE\_Key with a public key in it. We call this a
+"certificate".
+
+Due to the complexity of the standard, we'll spell out the COSE structures
+completely in this document and in the HAL and other documentation, so that
+although implementors will need to understand CBOR and the CBOR Data Definition
+Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)),
+they shouldn't need to understand COSE.
+
+Note, however, that the certificate chains returned from the provisioning server
+are standard X.509 certificates.
+
+### Algorithm choices
+
+This document uses:
+
+*   ECDSA P-256 for attestation signing keys;
+*   Remote provisioning protocol signing keys:
+  *  Ed25519 / P-256
+*   ECDH keys:
+  *  X25519 / P-256
+*   AES-GCM for all encryption;
+*   SHA-256 for all message digesting;
+*   HMAC-SHA-256 for all MACing; and
+*   HKDF-SHA-256 for all key derivation.
+
+We believe that Curve25519 offers the best tradeoff in terms of security,
+efficiency and global trustworthiness, and that it is now sufficiently
+widely-used and widely-implemented to make it a practical choice.
+
+However, since Secure Elements (SE) do not currently offer support for curve
+25519, we are allowing implementations to instead make use of EC P-256 for
+signing and ECDH. To put it simply, the device unique key pair will be a P-256
+key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt
+message will have its payload encrypted with P-256 ECDH key exchange instead of
+X25519.
+
+The CDDL in the rest of the document will use the '/' operator to show areas
+where either curve 25519 or P-256 may be used. Since there is no easy way to
+bind choices across different CDDL groups, it is important that the implementor
+stays consistent in which type is chosen. E.g. taking ES256 as the choice for
+algorithm implies the implementor should also choose the P256 public key group
+further down in the COSE structure.
+
+### Testability
+
+It's critical that the remote provisioning implementation be testable, to
+minimize the probability that broken devices are sold to end users. To support
+testing, the remote provisioning HAL methods take a `testMode` argument. Keys
+created in test mode are tagged to indicate this. The provisioning server will
+check for the test mode tag and issue test certificates that do not chain back
+to a trusted public key. In test mode, any EEK will be accepted, enabling
+testing tools to use EEKs for which they have the private key so they can
+validate the content of certificate requests. The BCC included in the
+`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
+
+Keystore (or similar) will need to be able to handle both testMode keys and
+production keys and keep them distinct, generating test certificate requests
+when asked with a test EEK and production certificate requests when asked with a
+production EEK. Likewise, the interface used to instruct Keystore to create keys
+will need to be able to specify whether test or production keys are desired.
+
+## Design
+
+### Certificate provisioning flow
+
+TODO(jbires): Replace this with a `.png` containing a sequence diagram.  The
+provisioning flow looks something like this:
+
+Provisioner -> Keystore: Prepare N keys
+Keystore -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate  key pair
+KeyMint --> Keystore: key\_blob,pubkey
+Keystore -> Keystore: Store key\_blob,pubkey
+Provisioner -> Server: Get TEEK
+Server --> Provisioner: TEEK
+Provisioner -> Keystore: genCertReq(N, TEEK)
+Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
+KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
+KeyMint --> Keystore: signature, encrypted BCC
+Keystore -> Keystore: Construct cert\_request
+Keystore --> Provisioner: cert\_request
+Provisioner --> Server: cert\_request
+Server -> Server: Validate cert\_request
+Server -> Server: Generate certificates
+Server --> Provisioner: certificates
+Provisioner -> Keystore: certificates
+Keystore -> Keystore: Store certificates
+
+The actors in the above diagram are:
+
+*   **Server** is the backend certificate provisioning server. It has access to
+    the uploaded device public keys and is responsible for providing encryption
+    keys, decrypting and validating requests, and generating certificates in
+    response to requests.
+*   **Provisioner** is an application that is responsible for communicating with
+    the server and all of the system components that require key certificates
+    from the server. It also implements the policy that defines how many key
+    pairs each client should keep in their pool.
+*   **Keystore** is the [Android keystore
+    daemon](https://developer.android.com/training/articles/keystore) (or, more
+    generally, whatever system component manages communications with a
+    particular secure aread component).
+*   **KeyMint** is the secure area component that manages cryptographic keys and
+    performs attestations (or perhaps some other secure area component).
+
+### `BCC`
+
+The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
+DK\_pub as well as other often device-unique certificates. The BCC is
+represented as a COSE\_Key containing DK\_pub followed by an array of
+COSE\_Sign1 "certificates" containing public keys and optional additional
+information, ordered from root to leaf, with each certificate signing the next.
+The first certificate in the array is signed by DK\_pub, the last certificate
+has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
+there is only one entry; DK\_pub and KM\_pub are the same key and the
+certificate is self-signed.
+
+Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
+8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
+in the Open Profile for DICE. Of these additional fields, only the
+_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
+KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
+Open Profile for DICE are expected for other entries (each of which corresponds
+to a particular firmware component or boot stage). The CWT fields _iss_ and
+_sub_ identify the issuer and subject of the certificate and are consistent
+along the BCC entries; the issuer of a given entry matches the subject of the
+previous entry.
+
+The BCC is designed to be constructed using the Open Profile for DICE. In this
+case the DK key pair is derived from the UDS as described by that profile and
+all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
+The KM key pair is not part of the derived DICE chain. It is generated (not
+derived) by the KeyMint module, certified by the last key in the DICE chain, and
+added as the leaf BCC entry. The key usage field in this leaf certificate must
+indicate the key is not used to sign certificates. If a UDS certificate is
+available on the device it should appear in the certificate request as the leaf
+of a DKCertChain in AdditionalDKSignatures (see
+[CertificateRequest](#certificaterequest)).
+
+The Open Profile for DICE allows for an arbitrary configuration descriptor. For
+BCC entries, this configuration descriptor is a CBOR map with the following
+optional fields. If no fields are relevant, an empty map should be encoded.
+Additional implementation-specific fields may be added using key values not in
+the range \[-70000, -70999\] (these are reserved for future additions here).
+
+```
+| Name              | Key    | Value type | Meaning                           |
+| ----------------- | ------ | ---------- | ----------------------------------|
+| Component name    | -70002 | tstr       | Name of firmware component / boot |
+:                   :        :            : stage                             :
+| Component version | -70003 | int        | Version of firmware component /   |
+:                   :        :            : boot stage                        :
+| Resettable        | -70004 | null       | If present, key changes on factory|
+:                   :        :            : reset                             :
+```
+
+Please see
+[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+for a full CDDL definition of the BCC.
+
+### `CertificateRequest`
+
+The full CBOR message that will be sent to the server to request certificates
+is:
+
+```cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,       // Provided by the server
+    ProtectedData,          // See ProtectedData.aidl
+    MacedKeysToSign         // See IRemotelyProvisionedComponent.aidl
+]
+
+DeviceInfo = [
+    VerifiedDeviceInfo,     // See DeviceInfo.aidl
+    UnverifiedDeviceInfo
+]
+
+// Unverified info is anything provided by the HLOS. Subject to change out of
+// step with the HAL.
+UnverifiedDeviceInfo = {
+    ? "fingerprint" : tstr,
+}
+
+```
+
+It will be the responsibility of Keystore and the Provisioner to construct the
+`CertificateRequest`. The HAL provides a method to generate the elements that
+need to be constructed on the secure side, which are the tag field of
+`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
+`ProtectedData`.
+
+### HAL
+
+The remote provisioning HAL provides a simple interface that can be implemented
+by multiple secure components that require remote provisioning. It would be
+slightly simpler to extend the KeyMint API, but that approach would only serve
+the needs of KeyMint, this is more general.
+
+NOTE the data structures defined in this HAL may look a little bloated and
+complex. This is because the COSE data structures are fully spelled-out; we
+could make it much more compact by not re-specifying the standardized elements
+and instead just referencing the standard, but it seems better to fully specify
+them. If the apparent complexity seems daunting, consider what the same would
+look like if traditional ASN.1 DER-based structures from X.509 and related
+standards were used and also fully elaborated.
+
+Please see the related HAL documentation directly in the source code at the
+following links:
+
+*   [IRemotelyProvisionedComponent
+    HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl)
+*   [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+*   [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl)
+*   [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
+*   [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
index eabbf1b..da3ff3a 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
@@ -38,11 +38,12 @@
     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        // Stop Wi-Fi
-        ASSERT_TRUE(stopWifiFramework());  // stop & wait for wifi to shutdown.
-
         wifi_instance_name_ = std::get<0>(GetParam());
         supplicant_instance_name_ = std::get<1>(GetParam());
+
+        // Stop & wait for wifi to shutdown.
+        ASSERT_TRUE(stopWifiFramework(wifi_instance_name_));
+
         std::system("/system/bin/start");
         ASSERT_TRUE(waitForFrameworkReady());
         isP2pOn_ =
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 086166a..6760663 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -28,26 +28,42 @@
 
 using ::android::sp;
 using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
+using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::hardware::wifi::V1_0::ChipModeId;
-using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
-using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
-using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiChip;
 using ::android::wifi_system::InterfaceTool;
 using ::android::wifi_system::SupplicantManager;
 
 namespace {
+
+bool waitForWifiHalStop(const std::string& wifi_instance_name) {
+    sp<IWifi> wifi = getWifi(wifi_instance_name);
+    int count = 50; /* wait at most 5 seconds for completion */
+    while (count-- > 0) {
+        if (wifi != nullptr && !wifi->isStarted()) {
+            return true;
+        }
+        usleep(100000);
+        wifi = getWifi(wifi_instance_name);
+    }
+    LOG(ERROR) << "Wifi HAL was not stopped";
+    return false;
+}
+
 bool waitForSupplicantState(bool is_running) {
     SupplicantManager supplicant_manager;
     int count = 50; /* wait at most 5 seconds for completion */
@@ -113,10 +129,10 @@
     return waitForSupplicantStart();  // wait for wifi to start.
 }
 
-bool stopWifiFramework() {
+bool stopWifiFramework(const std::string& wifi_instance_name) {
     std::system("svc wifi disable");
     std::system("cmd wifi set-scan-always-available disabled");
-    return waitForSupplicantStop();  // wait for wifi to shutdown.
+    return waitForSupplicantStop() && waitForWifiHalStop(wifi_instance_name);
 }
 
 void stopSupplicant() { stopSupplicant(""); }
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 7228623..2198d7c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -33,7 +33,7 @@
 bool startWifiFramework();
 
 // Used to stop the android wifi framework before every test.
-bool stopWifiFramework();
+bool stopWifiFramework(const std::string& wifi_instance_name);
 
 void stopSupplicant(const std::string& wifi_instance_name);
 // Used to configure the chip, driver and start wpa_supplicant before every
@@ -77,12 +77,13 @@
     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        // Stop Wi-Fi
-        ASSERT_TRUE(stopWifiFramework());  // stop & wait for wifi to shutdown.
-
-        // should always be v1.0 wifi
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
+        wifi_v1_0_instance_name_ =
+            std::get<0>(GetParam());  // should always be v1.0 wifi
         supplicant_instance_name_ = std::get<1>(GetParam());
+
+        // Stop & wait for wifi to shutdown.
+        ASSERT_TRUE(stopWifiFramework(wifi_v1_0_instance_name_));
+
         std::system("/system/bin/start");
         ASSERT_TRUE(waitForFrameworkReady());
         isP2pOn_ =
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index 17e0394..31042a2 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -78,7 +78,7 @@
 void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
 
 void initializeService() {
-    ASSERT_TRUE(stopWifiFramework());
+    ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
     std::system("/system/bin/start");
     ASSERT_TRUE(waitForFrameworkReady());
     stopSupplicantService();