Read GNSS measurement from device file when available
Test: atest CtsLocationGnssTestCases GtsLocationTestCases on CF
Bug: 190757198
Change-Id: Ic03d56a5df6b99f7b20c5840e7091ead138316b1
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index 0e489c5..9e4f7c7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -19,6 +19,8 @@
#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"
@@ -26,6 +28,8 @@
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;
@@ -68,15 +72,15 @@
std::string rawMeasurementStr = "";
if (ReplayUtils::hasGnssDeviceFile() &&
ReplayUtils::isGnssRawMeasurement(
- rawMeasurementStr = ReplayUtils::getDataFromDeviceFile(
- std::string(
- ::android::hardware::gnss::common::CMD_GET_RAWMEASUREMENT),
- mMinIntervalMillis))) {
- // TODO: implement rawMeasurementStr parser and report measurement.
+ rawMeasurementStr =
+ DeviceFileReader::Instance().getGnssRawMeasurementData())) {
ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(),
rawMeasurementStr.c_str());
- auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
- this->reportMeasurement(measurement);
+ auto measurement =
+ GnssRawMeasurementParser::getMeasurementFromStrs(rawMeasurementStr);
+ if (measurement != nullptr) {
+ this->reportMeasurement(*measurement);
+ }
} else {
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
this->reportMeasurement(measurement);
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index fd3d939..5294409 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -38,12 +38,13 @@
"v2_1/GnssDebug.cpp",
"v2_1/GnssMeasurement.cpp",
"v2_1/GnssMeasurementCorrections.cpp",
- "MockLocation.cpp",
- "Utils.cpp",
- "NmeaFixInfo.cpp",
- "GnssReplayUtils.cpp",
- "ParseUtils.cpp",
+ "DeviceFileReader.cpp",
"GnssRawMeasurementParser.cpp",
+ "GnssReplayUtils.cpp",
+ "MockLocation.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..7d4fb04
--- /dev/null
+++ b/gnss/common/utils/default/DeviceFileReader.cpp
@@ -0,0 +1,97 @@
+/*
+ * 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];
+ int mGnssFd = open(ReplayUtils::getGnssPath().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 (ReplayUtils::isGnssRawMeasurement(inputStr)) {
+ data_[CMD_GET_RAWMEASUREMENT] = inputStr;
+ } else if (ReplayUtils::isNMEA(inputStr)) {
+ data_[CMD_GET_LOCATION] = 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/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp
index fc4c477..e3f4ff8 100644
--- a/gnss/common/utils/default/GnssReplayUtils.cpp
+++ b/gnss/common/utils/default/GnssReplayUtils.cpp
@@ -40,45 +40,8 @@
}
bool ReplayUtils::isNMEA(const std::string& inputStr) {
- return !inputStr.empty() &&
- (inputStr.rfind("$GPRMC,", 0) == 0 || inputStr.rfind("$GPRMA,", 0) == 0);
-}
-
-std::string ReplayUtils::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
- char inputBuffer[INPUT_BUFFER_SIZE];
- int mGnssFd = open(getGnssPath().c_str(), O_RDWR | O_NONBLOCK);
-
- if (mGnssFd == -1) {
- return "";
- }
-
- int bytes_write = write(mGnssFd, command.c_str(), command.size());
- if (bytes_write <= 0) {
- 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) {
- return "";
- }
- 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 inputStr;
+ return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
+ inputStr.find("$GPRMA,", 0) != std::string::npos);
}
} // namespace common
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/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 6f0ced1..19b1b45 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -30,6 +30,7 @@
#include <cutils/properties.h>
+#include "DeviceFileReader.h"
#include "GnssAntennaInfo.h"
#include "GnssConfiguration.h"
#include "GnssDebug.h"
@@ -163,19 +164,9 @@
template <class T_IGnss>
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
- if (!mHardwareModeChecked) {
- // default using /dev/gnss0
- std::string gnss_dev_path = ReplayUtils::getGnssPath();
-
- mGnssFd = open(gnss_dev_path.c_str(), O_RDWR | O_NONBLOCK);
- if (mGnssFd == -1) {
- ALOGW("Failed to open %s errno: %d", gnss_dev_path.c_str(), errno);
- }
- mHardwareModeChecked = true;
- }
-
- std::string inputStr = ::android::hardware::gnss::common::ReplayUtils::getDataFromDeviceFile(
- CMD_GET_LOCATION, mMinIntervalMs);
+ mHardwareModeChecked = true;
+ std::string inputStr =
+ ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
return NmeaFixInfo::getLocationFromInputStr(inputStr);
}