161 lines
6.5 KiB
Diff
161 lines
6.5 KiB
Diff
--- a/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
|
|
+++ b/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
|
|
@@ -66,6 +66,11 @@
|
|
#include "jni.h"
|
|
#include "utils/Log.h"
|
|
#include "utils/misc.h"
|
|
+#include <fstream>
|
|
+#include <sstream>
|
|
+#include <sys/stat.h>
|
|
+
|
|
+// Custom GPS location from file support
|
|
|
|
static jclass class_gnssPowerStats;
|
|
|
|
@@ -78,6 +83,15 @@
|
|
static jmethodID method_gnssPowerStatsCtor;
|
|
static jmethodID method_setSubHalPowerIndicationCapabilities;
|
|
|
|
+// Custom GPS location from file
|
|
+static double customLatitude = 0.0;
|
|
+static double customLongitude = 0.0;
|
|
+static bool useCustomLocation = false;
|
|
+static time_t lastFileModTime = 0;
|
|
+static const char* GPS_LOCATION_FILE = "/data/vendor/gps/custom_location.txt";
|
|
+
|
|
+// Function to read GPS coordinates from file
|
|
+static bool readGpsLocationFromFile();
|
|
+
|
|
using android::OK;
|
|
using android::sp;
|
|
using android::status_t;
|
|
@@ -200,6 +214,64 @@
|
|
std::unique_ptr<android::gnss::MeasurementCorrectionsInterface> gnssMeasurementCorrectionsIface =
|
|
nullptr;
|
|
|
|
+// Function to read GPS coordinates from file
|
|
+static bool readGpsLocationFromFile() {
|
|
+ struct stat fileStat;
|
|
+ if (stat(GPS_LOCATION_FILE, &fileStat) != 0) {
|
|
+ // File doesn't exist, disable custom location
|
|
+ useCustomLocation = false;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Check if file has been modified
|
|
+ if (fileStat.st_mtime <= lastFileModTime) {
|
|
+ return useCustomLocation; // No change in file
|
|
+ }
|
|
+
|
|
+ std::ifstream file(GPS_LOCATION_FILE);
|
|
+ if (!file.is_open()) {
|
|
+ ALOGE("Failed to open GPS location file: %s", GPS_LOCATION_FILE);
|
|
+ useCustomLocation = false;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ std::string line;
|
|
+ if (std::getline(file, line)) {
|
|
+ std::istringstream iss(line);
|
|
+ std::string latStr, lonStr;
|
|
+
|
|
+ // Expected format: "latitude,longitude" or "latitude longitude"
|
|
+ if (std::getline(iss, latStr, ',') && std::getline(iss, lonStr)) {
|
|
+ // Comma-separated format
|
|
+ } else {
|
|
+ // Space-separated format
|
|
+ iss.clear();
|
|
+ iss.str(line);
|
|
+ iss >> latStr >> lonStr;
|
|
+ }
|
|
+
|
|
+ try {
|
|
+ double lat = std::stod(latStr);
|
|
+ double lon = std::stod(lonStr);
|
|
+
|
|
+ // Validate coordinates
|
|
+ if (lat >= -90.0 && lat <= 90.0 && lon >= -180.0 && lon <= 180.0) {
|
|
+ customLatitude = lat;
|
|
+ customLongitude = lon;
|
|
+ useCustomLocation = true;
|
|
+ lastFileModTime = fileStat.st_mtime;
|
|
+ ALOGI("Custom GPS location loaded: lat=%.6f, lon=%.6f", lat, lon);
|
|
+ file.close();
|
|
+ return true;
|
|
+ } else {
|
|
+ ALOGE("Invalid GPS coordinates: lat=%.6f, lon=%.6f", lat, lon);
|
|
+ }
|
|
+ } catch (const std::exception& e) {
|
|
+ ALOGE("Failed to parse GPS coordinates: %s", e.what());
|
|
+ }
|
|
+ }
|
|
+
|
|
+ file.close();
|
|
+ useCustomLocation = false;
|
|
+ return false;
|
|
+}
|
|
+
|
|
namespace android {
|
|
|
|
namespace {
|
|
@@ -367,6 +439,9 @@
|
|
}
|
|
|
|
static jboolean android_location_gnss_hal_GnssNative_start(JNIEnv* /* env */, jclass) {
|
|
+ // Try to read custom GPS location from file when GNSS starts
|
|
+ readGpsLocationFromFile();
|
|
+
|
|
return gnssHal->start();
|
|
}
|
|
|
|
@@ -443,8 +518,17 @@
|
|
jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp,
|
|
jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
|
|
jdouble elapsedRealtimeUncertaintyNanos) {
|
|
- gnssHal->injectBestLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
|
|
+
|
|
+ // Check for custom GPS location from file
|
|
+ if (readGpsLocationFromFile()) {
|
|
+ ALOGI("Using custom GPS location: lat=%.6f, lon=%.6f", customLatitude, customLongitude);
|
|
+ gnssHal->injectBestLocation(gnssLocationFlags, customLatitude, customLongitude,
|
|
+ altitudeMeters, speedMetersPerSec, bearingDegrees,
|
|
+ horizontalAccuracyMeters, verticalAccuracyMeters,
|
|
+ speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
|
|
+ elapsedRealtimeFlags, elapsedRealtimeNanos,
|
|
+ elapsedRealtimeUncertaintyNanos);
|
|
+ } else {
|
|
+ gnssHal->injectBestLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
|
|
altitudeMeters, speedMetersPerSec, bearingDegrees,
|
|
horizontalAccuracyMeters, verticalAccuracyMeters,
|
|
speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
|
|
elapsedRealtimeFlags, elapsedRealtimeNanos,
|
|
elapsedRealtimeUncertaintyNanos);
|
|
+ }
|
|
}
|
|
|
|
static void android_location_gnss_hal_GnssNative_inject_location(
|
|
@@ -455,8 +539,17 @@
|
|
jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp,
|
|
jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
|
|
jdouble elapsedRealtimeUncertaintyNanos) {
|
|
- gnssHal->injectLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
|
|
+
|
|
+ // Check for custom GPS location from file
|
|
+ if (readGpsLocationFromFile()) {
|
|
+ ALOGI("Using custom GPS location: lat=%.6f, lon=%.6f", customLatitude, customLongitude);
|
|
+ gnssHal->injectLocation(gnssLocationFlags, customLatitude, customLongitude, altitudeMeters,
|
|
+ speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
|
|
+ verticalAccuracyMeters, speedAccuracyMetersPerSecond,
|
|
+ bearingAccuracyDegrees, timestamp, elapsedRealtimeFlags,
|
|
+ elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
|
|
+ } else {
|
|
+ gnssHal->injectLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
|
|
speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
|
|
verticalAccuracyMeters, speedAccuracyMetersPerSecond,
|
|
bearingAccuracyDegrees, timestamp, elapsedRealtimeFlags,
|
|
elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
|
|
+ }
|
|
}
|
|
|
|
static jboolean android_location_gnss_hal_GnssNative_supports_psds(JNIEnv* /* env */, jclass) {
|