feat: 添加电池和GPS支持,更新配置文件,新增相关脚本和服务

This commit is contained in:
2025-09-16 17:46:18 +08:00
parent fffe32888c
commit 15936404b6
75 changed files with 3541 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 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_Constants_H_
#define android_hardware_gnss_common_Constants_H_
#include <cstdint>
namespace android {
namespace hardware {
namespace gnss {
namespace common {
const float kMockHorizontalAccuracyMeters = 5;
const float kMockVerticalAccuracyMeters = 5;
const float kMockSpeedAccuracyMetersPerSecond = 1;
const float kMockBearingAccuracyDegrees = 90;
const int64_t kMockTimestamp = 1519930775453L;
const float kGpsL1FreqHz = 1575.42 * 1e6;
const float kGpsL5FreqHz = 1176.45 * 1e6;
const float kGloG1FreqHz = 1602.0 * 1e6;
const float kIrnssL5FreqHz = 1176.45 * 1e6;
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // android_hardware_gnss_common_Constants_H_

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2020 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_MockLocation_H_
#define android_hardware_gnss_common_MockLocation_H_
#include <cstdint>
namespace android {
namespace hardware {
namespace gnss {
namespace common {
extern float gMockLatitudeDegrees;
extern float gMockLongitudeDegrees;
extern float gMockAltitudeMeters;
extern float gMockBearingDegrees;
extern float gMockSpeedMetersPerSec;
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // android_hardware_gnss_common_MockLocation_H_

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2020 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.
*/
#pragma once
#include <Constants.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
#include <hidl/Status.h>
#include <ctime>
#include <string>
namespace android {
namespace hardware {
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:
float altitudeMeters;
float bearingDegrees;
uint32_t fixId;
bool hasGMCRecord;
bool hasGGARecord;
float hDop;
float vDop;
float latDeg;
float lngDeg;
uint32_t satelliteCount;
float speedMetersPerSec;
int64_t timestamp;
public:
static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr);
private:
static void splitStr(const std::string& line, const char& delimiter,
std::vector<std::string>& out);
static float checkAndConvertToFloat(const std::string& sentence);
static int64_t nmeaPartsToTimestamp(const std::string& timeStr, const std::string& dateStr);
NmeaFixInfo();
void parseGGALine(const std::vector<std::string>& sentenceValues);
void parseRMCLine(const std::vector<std::string>& sentenceValues);
std::unique_ptr<V2_0::GnssLocation> toGnssLocation() const;
// Getters
float getAltitudeMeters() const;
float getBearingAccuracyDegrees() const;
float getBearingDegrees() const;
uint32_t getFixId() const;
float getHorizontalAccuracyMeters() const;
float getLatDeg() const;
float getLngDeg() const;
float getSpeedAccuracyMetersPerSecond() const;
float getSpeedMetersPerSec() const;
int64_t getTimestamp() const;
float getVerticalAccuracyMeters() const;
bool isValidFix() const;
void reset();
NmeaFixInfo& operator=(const NmeaFixInfo& rhs);
};
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2019 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_Utils_H_
#define android_hardware_gnss_common_default_Utils_H_
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/2.1/IGnss.h>
using ::android::hardware::hidl_vec;
namespace android {
namespace hardware {
namespace gnss {
namespace common {
struct Utils {
static aidl::android::hardware::gnss::GnssData getMockMeasurement(
const bool enableCorrVecOutputs);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
static V2_0::GnssLocation getMockLocationV2_0();
static V1_0::GnssLocation getMockLocationV1_0();
static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1(
V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz);
static V2_0::IGnssCallback::GnssSvInfo getMockSvInfoV2_0(
V1_0::IGnssCallback::GnssSvInfo gnssSvInfoV1_0, V2_0::GnssConstellationType type);
static V1_0::IGnssCallback::GnssSvInfo getMockSvInfoV1_0(int16_t svid,
V1_0::GnssConstellationType type,
float cN0DbHz, float elevationDegrees,
float azimuthDegrees,
float carrierFrequencyHz);
static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
};
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // android_hardware_gnss_common_default_Utils_H_

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 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.
*/
#pragma once
#include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
#include <mutex>
#include <thread>
namespace android::hardware::gnss::V2_1::implementation {
struct GnssAntennaInfo : public ::android::hardware::gnss::V2_1::IGnssAntennaInfo {
GnssAntennaInfo();
~GnssAntennaInfo();
// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
Return<GnssAntennaInfoStatus> setCallback(
const sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback>& callback) override;
Return<void> close() override;
private:
void start();
void stop();
void reportAntennaInfo(
const hidl_vec<
::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>&
antennaInfo) const;
// Guarded by mMutex
static sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback> sCallback;
std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive;
std::thread mThread;
// Synchronization lock for sCallback
mutable std::mutex mMutex;
};
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2019 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.
*/
#pragma once
#include <android/hardware/gnss/2.1/IGnssCallback.h>
#include <android/hardware/gnss/2.1/IGnssConfiguration.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <mutex>
#include <unordered_set>
namespace android::hardware::gnss::V2_1::implementation {
struct BlacklistedSourceHashV2_1 {
inline int operator()(
const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& source)
const {
return int(source.constellation) * 1000 + int(source.svid);
}
};
struct BlacklistedSourceEqualV2_1 {
inline bool operator()(
const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s1,
const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s2)
const {
return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
}
};
using BlacklistedSourceSetV2_1 =
std::unordered_set<::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource,
BlacklistedSourceHashV2_1, BlacklistedSourceEqualV2_1>;
using BlacklistedConstellationSetV2_1 = std::unordered_set<V2_0::GnssConstellationType>;
struct GnssConfiguration : public IGnssConfiguration {
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
Return<bool> setSuplEs(bool enabled) override;
Return<bool> setSuplVersion(uint32_t version) override;
Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override;
Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override;
Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override;
Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override;
Return<bool> setEmergencySuplPdn(bool enable) override;
// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
Return<bool> setBlacklist(
const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
std::recursive_mutex& getMutex() const;
// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
Return<bool> setBlacklist_2_1(
const hidl_vec<V2_1::IGnssConfiguration::BlacklistedSource>& blacklist) override;
Return<bool> isBlacklistedV2_1(const V2_1::IGnssCallback::GnssSvInfo& gnssSvInfo) const;
private:
mutable std::recursive_mutex mMutex;
BlacklistedSourceSetV2_1 mBlacklistedSourceSet;
BlacklistedConstellationSetV2_1 mBlacklistedConstellationSet;
};
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <android/hardware/gnss/1.0/IGnssDebug.h>
#include <hidl/Status.h>
namespace android::hardware::gnss::V1_1::implementation {
/* Interface for GNSS Debug support. */
struct GnssDebug : public V1_0::IGnssDebug {
/*
* Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
* These declarations were generated from IGnssDebug.hal.
*/
Return<void> getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) override;
};
} // namespace android::hardware::gnss::V1_1::implementation

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2019 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.
*/
#pragma once
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <atomic>
#include <mutex>
#include <thread>
namespace android::hardware::gnss::V2_1::implementation {
struct GnssMeasurement : public IGnssMeasurement {
GnssMeasurement();
~GnssMeasurement();
// Methods from V1_0::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
const sp<V1_0::IGnssMeasurementCallback>& callback) override;
Return<void> close() override;
// Methods from V1_1::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
// Methods from V2_0::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
const sp<V2_0::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
// Methods from V2_1::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_1(
const sp<V2_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) override;
private:
void start();
void stop();
void reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData&);
void reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData&);
// Guarded by mMutex
static sp<V2_1::IGnssMeasurementCallback> sCallback_2_1;
// Guarded by mMutex
static sp<V2_0::IGnssMeasurementCallback> sCallback_2_0;
std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive;
std::thread mThread;
// Synchronization lock for sCallback_2_1 and sCallback_2_0
mutable std::mutex mMutex;
};
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2019 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.
*/
#pragma once
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
namespace android::hardware::gnss::measurement_corrections::V1_1::implementation {
struct GnssMeasurementCorrections : public IMeasurementCorrections {
GnssMeasurementCorrections();
~GnssMeasurementCorrections();
// Methods from V1_0::IMeasurementCorrections follow.
Return<bool> setCorrections(const V1_0::MeasurementCorrections& corrections) override;
Return<bool> setCallback(const sp<V1_0::IMeasurementCorrectionsCallback>& callback) override;
// Methods from V1_1::IMeasurementCorrections follow.
Return<bool> setCorrections_1_1(const V1_1::MeasurementCorrections& corrections) override;
};
} // namespace android::hardware::gnss::measurement_corrections::V1_1::implementation

View File

@@ -0,0 +1,779 @@
/*
* Copyright (C) 2019 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.
*/
#pragma once
#include <android/hardware/gnss/2.1/IGnss.h>
#include <errno.h>
#include <fcntl.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <log/log.h>
#include <sys/epoll.h>
#include <atomic>
#include <mutex>
#include <string>
#include <thread>
#include <utils/SystemClock.h>
#include <cutils/properties.h>
#include "GnssAntennaInfo.h"
#include "GnssConfiguration.h"
#include "GnssDebug.h"
#include "GnssMeasurement.h"
#include "GnssMeasurementCorrections.h"
#include "MockLocation.h"
#include "NmeaFixInfo.h"
#include "Utils.h"
namespace android::hardware::gnss::common::implementation {
constexpr int INPUT_BUFFER_SIZE = 128;
constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
constexpr char GNSS_PATH[] = "/data/vendor/gps/gnss";
template <class T_IGnss>
struct GnssTemplate : public T_IGnss {
GnssTemplate();
~GnssTemplate();
// Methods from V1_0::IGnss follow.
Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
Return<bool> start() override;
Return<bool> stop() override;
Return<void> cleanup() override;
Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
int32_t uncertaintyMs) override;
Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
float accuracyMeters) override;
Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override;
Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
V1_0::IGnss::GnssPositionRecurrence recurrence,
uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
uint32_t preferredTimeMs) override;
Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override;
Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
// Methods from V1_1::IGnss follow.
Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
V1_0::IGnss::GnssPositionRecurrence recurrence,
uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
uint32_t preferredTimeMs, bool lowPowerMode) override;
Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
// Methods from V2_0::IGnss follow.
Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
Return<sp<V2_0::IGnssDebug>> getExtensionGnssDebug_2_0() override;
Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
getExtensionMeasurementCorrections() override;
Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
override;
Return<sp<V2_0::IGnssBatching>> getExtensionGnssBatching_2_0() override;
Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
// Methods from V2_1::IGnss follow.
Return<bool> setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) override;
Return<sp<V2_1::IGnssMeasurement>> getExtensionGnssMeasurement_2_1() override;
Return<sp<V2_1::IGnssConfiguration>> getExtensionGnssConfiguration_2_1() override;
Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
getExtensionMeasurementCorrections_1_1() override;
Return<sp<V2_1::IGnssAntennaInfo>> getExtensionGnssAntennaInfo() override;
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
private:
std::unique_ptr<V2_0::GnssLocation> getLocationFromHW();
void reportLocation(const V2_0::GnssLocation&) const;
void reportLocation(const V1_0::GnssLocation&) const;
void reportSvStatus(const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>&) const;
void reportGnssStatusValue(const V1_0::IGnssCallback::GnssStatusValue) const;
Return<void> help(const hidl_handle& fd);
Return<void> setLocation(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
static sp<V2_1::IGnssCallback> sGnssCallback_2_1;
static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
static sp<V1_0::IGnssCallback> sGnssCallback_1_0;
std::atomic<long> mMinIntervalMs;
sp<V2_1::implementation::GnssConfiguration> mGnssConfiguration;
std::atomic<bool> mIsActive;
std::atomic<bool> mHardwareModeChecked;
std::atomic<int> mGnssFd;
std::thread mThread;
mutable std::mutex mMutex;
virtual hidl_vec<V2_1::IGnssCallback::GnssSvInfo> filterBlocklistedSatellitesV2_1(
hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList);
virtual void notePowerConsumption();
};
template <class T_IGnss>
sp<V2_1::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_2_1 = nullptr;
template <class T_IGnss>
sp<V2_0::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_2_0 = nullptr;
template <class T_IGnss>
sp<V1_1::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_1_1 = nullptr;
template <class T_IGnss>
sp<V1_0::IGnssCallback> GnssTemplate<T_IGnss>::sGnssCallback_1_0 = nullptr;
template <class T_IGnss>
GnssTemplate<T_IGnss>::GnssTemplate()
: mMinIntervalMs(1000),
mGnssConfiguration{new V2_1::implementation::GnssConfiguration()},
mHardwareModeChecked(false),
mGnssFd(-1) {}
template <class T_IGnss>
GnssTemplate<T_IGnss>::~GnssTemplate() {
stop();
}
template <class T_IGnss>
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
float latitudeDegrees = gMockLatitudeDegrees;
float longitudeDegrees = gMockLongitudeDegrees;
float altitudeMeters = gMockAltitudeMeters;
float speedMetersPerSec = gMockSpeedMetersPerSec;
float bearingDegrees = gMockBearingDegrees;
float horizontalAccuracyMeters = kMockHorizontalAccuracyMeters;
float verticalAccuracyMeters = kMockVerticalAccuracyMeters;
float speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond;
float bearingAccuracyDegrees = kMockBearingAccuracyDegrees;
int64_t timestamp = static_cast<int64_t>(time(NULL)) - 1;
const char * gnss_dev_path = GNSS_PATH;
int gnss_fd = open(gnss_dev_path, O_RDONLY);
if (gnss_fd != -1) {
int bytes_read = -1;
std::string inputStr = "";
char inputBuffer[INPUT_BUFFER_SIZE];
while (true) {
memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
bytes_read = read(gnss_fd, &inputBuffer, INPUT_BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
inputStr += std::string(inputBuffer, bytes_read);
}
std::istringstream iss(inputStr);
std::string item;
while (std::getline(iss, item, LINE_SEPARATOR)) {
if (item.compare(0, strlen("LatitudeDegrees="), "LatitudeDegrees=") == 0) {
latitudeDegrees = std::stof(item.substr(strlen("LatitudeDegrees=")));
} else if (item.compare(0, strlen("LongitudeDegrees="), "LongitudeDegrees=") == 0) {
longitudeDegrees = std::stof(item.substr(strlen("LongitudeDegrees=")));
} else if (item.compare(0, strlen("AltitudeMeters="), "AltitudeMeters=") == 0) {
altitudeMeters = std::stof(item.substr(strlen("AltitudeMeters=")));
} else if (item.compare(0, strlen("SpeedMetersPerSec="), "SpeedMetersPerSec=") == 0) {
speedMetersPerSec = std::stof(item.substr(strlen("SpeedMetersPerSec=")));
} else if (item.compare(0, strlen("BearingDegrees="), "BearingDegrees=") == 0) {
bearingDegrees = std::stof(item.substr(strlen("BearingDegrees=")));
} else if (item.compare(0, strlen("HorizontalAccuracyMeters="), "HorizontalAccuracyMeters=") == 0) {
horizontalAccuracyMeters = std::stof(item.substr(strlen("HorizontalAccuracyMeters=")));
} else if (item.compare(0, strlen("VerticalAccuracyMeters="), "VerticalAccuracyMeters=") == 0) {
verticalAccuracyMeters = std::stof(item.substr(strlen("VerticalAccuracyMeters=")));
} else if (item.compare(0, strlen("SpeedAccuracyMetersPerSecond="), "SpeedAccuracyMetersPerSecond=") == 0) {
speedAccuracyMetersPerSecond = std::stof(item.substr(strlen("SpeedAccuracyMetersPerSecond=")));
} else if (item.compare(0, strlen("BearingAccuracyDegrees="), "BearingAccuracyDegrees=") == 0) {
bearingAccuracyDegrees = std::stof(item.substr(strlen("BearingAccuracyDegrees=")));
} else if (item.compare(0, strlen("Timestamp="), "Timestamp=") == 0) {
timestamp = std::stol(item.substr(strlen("Timestamp=")));
}
}
close(gnss_fd);
} else {
ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno);
}
const V2_0::ElapsedRealtime currentOsTimestamp = {
.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 = 1000000};
V1_0::GnssLocation locationV1 = {
.gnssLocationFlags = 0xFF,
.latitudeDegrees = latitudeDegrees,
.longitudeDegrees = longitudeDegrees,
.altitudeMeters = altitudeMeters,
.speedMetersPerSec = speedMetersPerSec,
.bearingDegrees = bearingDegrees,
.horizontalAccuracyMeters = horizontalAccuracyMeters,
.verticalAccuracyMeters = verticalAccuracyMeters,
.speedAccuracyMetersPerSecond = speedAccuracyMetersPerSecond,
.bearingAccuracyDegrees = bearingAccuracyDegrees,
.timestamp = timestamp};
V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = currentOsTimestamp};
return std::make_unique<V2_0::GnssLocation>(locationV2);
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::start() {
if (mIsActive) {
ALOGW("Gnss has started. Restarting...");
stop();
}
mIsActive = true;
this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_BEGIN);
mThread = std::thread([this]() {
while (mIsActive == true) {
auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
this->reportSvStatus(svStatus);
auto currentLocation = getLocationFromHW();
notePowerConsumption();
if (currentLocation != nullptr) {
this->reportLocation(*currentLocation);
} else {
if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
const auto location = Utils::getMockLocationV2_0();
this->reportLocation(location);
} else {
const auto location = Utils::getMockLocationV1_0();
this->reportLocation(location);
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
}
});
return true;
}
template <class T_IGnss>
hidl_vec<V2_1::IGnssCallback::GnssSvInfo> GnssTemplate<T_IGnss>::filterBlocklistedSatellitesV2_1(
hidl_vec<V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) {
ALOGD("GnssTemplate::filterBlocklistedSatellitesV2_1");
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
gnssSvInfoList[i].v2_0.v1_0.svFlag &=
~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
}
}
return gnssSvInfoList;
}
template <class T_IGnss>
void GnssTemplate<T_IGnss>::notePowerConsumption() {
ALOGD("GnssTemplate::notePowerConsumption");
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::stop() {
ALOGD("stop");
mIsActive = false;
this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_END);
if (mThread.joinable()) {
mThread.join();
}
if (mGnssFd != -1) {
close(mGnssFd);
mGnssFd = -1;
mHardwareModeChecked = false;
}
return true;
}
// Methods from V1_0::IGnss follow.
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setCallback(const sp<V1_0::IGnssCallback>& callback) {
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_1_0 = callback;
uint32_t capabilities = 0x0 | V1_0::IGnssCallback::Capabilities::MEASUREMENTS |
V1_0::IGnssCallback::Capabilities::SCHEDULING;
auto ret = sGnssCallback_1_0->gnssSetCapabilitesCb(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
ret = sGnssCallback_1_0->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
template <class T_IGnss>
Return<void> GnssTemplate<T_IGnss>::cleanup() {
sGnssCallback_2_1 = nullptr;
sGnssCallback_2_0 = nullptr;
return Void();
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::injectTime(int64_t, int64_t, int32_t) {
return true;
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::injectLocation(double, double, float) {
return true;
}
template <class T_IGnss>
Return<void> GnssTemplate<T_IGnss>::deleteAidingData(V1_0::IGnss::GnssAidingData) {
// TODO implement
return Void();
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setPositionMode(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence,
uint32_t minIntervalMs, uint32_t, uint32_t) {
mMinIntervalMs = minIntervalMs;
return true;
}
template <class T_IGnss>
Return<sp<V1_0::IAGnssRil>> GnssTemplate<T_IGnss>::getExtensionAGnssRil() {
// TODO implement
return ::android::sp<V1_0::IAGnssRil>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssGeofencing>> GnssTemplate<T_IGnss>::getExtensionGnssGeofencing() {
// TODO implement
return ::android::sp<V1_0::IGnssGeofencing>{};
}
template <class T_IGnss>
Return<sp<V1_0::IAGnss>> GnssTemplate<T_IGnss>::getExtensionAGnss() {
// TODO implement
return ::android::sp<V1_0::IAGnss>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssNi>> GnssTemplate<T_IGnss>::getExtensionGnssNi() {
// TODO implement
return ::android::sp<V1_0::IGnssNi>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement() {
ALOGD("Gnss::getExtensionGnssMeasurement");
return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
Return<sp<V1_0::IGnssNavigationMessage>>
GnssTemplate<T_IGnss>::getExtensionGnssNavigationMessage() {
// TODO implement
return ::android::sp<V1_0::IGnssNavigationMessage>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssXtra>> GnssTemplate<T_IGnss>::getExtensionXtra() {
// TODO implement
return ::android::sp<V1_0::IGnssXtra>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration() {
// TODO implement
return ::android::sp<V1_0::IGnssConfiguration>{};
}
template <class T_IGnss>
Return<sp<V1_0::IGnssDebug>> GnssTemplate<T_IGnss>::getExtensionGnssDebug() {
return new V1_1::implementation::GnssDebug();
}
template <class T_IGnss>
Return<sp<V1_0::IGnssBatching>> GnssTemplate<T_IGnss>::getExtensionGnssBatching() {
// TODO implement
return ::android::sp<V1_0::IGnssBatching>{};
}
// Methods from V1_1::IGnss follow.
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_1_1 = callback;
uint32_t capabilities = 0x0;
auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
auto gnssName = "Google Mock GNSS Implementation v2.1";
ret = sGnssCallback_1_1->gnssNameCb(gnssName);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence,
uint32_t minIntervalMs, uint32_t, uint32_t,
bool) {
mMinIntervalMs = minIntervalMs;
return true;
}
template <class T_IGnss>
Return<sp<V1_1::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_1_1() {
// TODO implement
return ::android::sp<V1_1::IGnssConfiguration>{};
}
template <class T_IGnss>
Return<sp<V1_1::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_1_1() {
// TODO implement
return ::android::sp<V1_1::IGnssMeasurement>{};
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::injectBestLocation(const V1_0::GnssLocation&) {
return true;
}
// Methods from V2_0::IGnss follow.
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
ALOGD("Gnss::setCallback_2_0");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_2_0 = callback;
using Capabilities = V2_0::IGnssCallback::Capabilities;
const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
auto gnssName = "Google Mock GNSS Implementation v2.1";
ret = sGnssCallback_2_0->gnssNameCb(gnssName);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
template <class T_IGnss>
Return<sp<V2_0::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_2_0() {
ALOGD("Gnss::getExtensionGnssConfiguration_2_0");
return mGnssConfiguration;
}
template <class T_IGnss>
Return<sp<V2_0::IGnssDebug>> GnssTemplate<T_IGnss>::getExtensionGnssDebug_2_0() {
// TODO implement
return ::android::sp<V2_0::IGnssDebug>{};
}
template <class T_IGnss>
Return<sp<V2_0::IAGnss>> GnssTemplate<T_IGnss>::getExtensionAGnss_2_0() {
// TODO implement
return ::android::sp<V2_0::IAGnss>{};
}
template <class T_IGnss>
Return<sp<V2_0::IAGnssRil>> GnssTemplate<T_IGnss>::getExtensionAGnssRil_2_0() {
// TODO implement
return ::android::sp<V2_0::IAGnssRil>{};
}
template <class T_IGnss>
Return<sp<V2_0::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_0() {
ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections() {
ALOGD("Gnss::getExtensionMeasurementCorrections()");
return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
}
template <class T_IGnss>
Return<sp<visibility_control::V1_0::IGnssVisibilityControl>>
GnssTemplate<T_IGnss>::getExtensionVisibilityControl() {
// TODO implement
return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
}
template <class T_IGnss>
Return<sp<V2_0::IGnssBatching>> GnssTemplate<T_IGnss>::getExtensionGnssBatching_2_0() {
// TODO implement
return ::android::sp<V2_0::IGnssBatching>{};
}
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::injectBestLocation_2_0(const V2_0::GnssLocation&) {
// TODO(b/124012850): Implement function.
return bool{};
}
// Methods from V2_1::IGnss follow.
template <class T_IGnss>
Return<bool> GnssTemplate<T_IGnss>::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
ALOGD("Gnss::setCallback_2_1");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_2_1 = callback;
using Capabilities = V2_1::IGnssCallback::Capabilities;
const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
Capabilities::ANTENNA_INFO;
auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
auto gnssName = "Android Mock GNSS Implementation v2.1";
ret = sGnssCallback_2_1->gnssNameCb(gnssName);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
template <class T_IGnss>
Return<sp<V2_1::IGnssMeasurement>> GnssTemplate<T_IGnss>::getExtensionGnssMeasurement_2_1() {
ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
return new V2_1::implementation::GnssMeasurement();
}
template <class T_IGnss>
Return<sp<V2_1::IGnssConfiguration>> GnssTemplate<T_IGnss>::getExtensionGnssConfiguration_2_1() {
ALOGD("Gnss::getExtensionGnssConfiguration_2_1");
return mGnssConfiguration;
}
template <class T_IGnss>
Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
GnssTemplate<T_IGnss>::getExtensionMeasurementCorrections_1_1() {
ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()");
return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections();
}
template <class T_IGnss>
Return<sp<V2_1::IGnssAntennaInfo>> GnssTemplate<T_IGnss>::getExtensionGnssAntennaInfo() {
ALOGD("Gnss::getExtensionGnssAntennaInfo");
return new V2_1::implementation::GnssAntennaInfo();
}
template <class T_IGnss>
void GnssTemplate<T_IGnss>::reportGnssStatusValue(
const V1_0::IGnssCallback::GnssStatusValue gnssStatusValue) const {
std::unique_lock<std::mutex> lock(mMutex);
if (sGnssCallback_2_1 == nullptr) {
ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
return;
}
auto ret = sGnssCallback_2_1->gnssStatusCb(gnssStatusValue);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
template <class T_IGnss>
void GnssTemplate<T_IGnss>::reportSvStatus(
const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& svInfoList) const {
std::unique_lock<std::mutex> lock(mMutex);
// TODO(skz): update this to call 2_0 callback if non-null
if (sGnssCallback_2_1 == nullptr) {
ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
return;
}
auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
template <class T_IGnss>
void GnssTemplate<T_IGnss>::reportLocation(const V1_0::GnssLocation& location) const {
std::unique_lock<std::mutex> lock(mMutex);
if (sGnssCallback_1_1 != nullptr) {
auto ret = sGnssCallback_1_1->gnssLocationCb(location);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback v1.1", __func__);
}
return;
}
if (sGnssCallback_1_0 == nullptr) {
ALOGE("%s: No non-null callback", __func__);
return;
}
auto ret = sGnssCallback_1_0->gnssLocationCb(location);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback v1.0", __func__);
}
}
template <class T_IGnss>
void GnssTemplate<T_IGnss>::reportLocation(const V2_0::GnssLocation& location) const {
std::unique_lock<std::mutex> lock(mMutex);
if (sGnssCallback_2_1 != nullptr) {
auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback v2.1", __func__);
}
return;
}
if (sGnssCallback_2_0 == nullptr) {
ALOGE("%s: No non-null callback", __func__);
return;
}
auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback v2.0", __func__);
}
}
template <class T_IGnss>
Return<void> GnssTemplate<T_IGnss>::setLocation(const hidl_handle& fd,
const hidl_vec<hidl_string>& options) {
auto lat = gMockLatitudeDegrees;
auto lon = gMockLongitudeDegrees;
auto ele = gMockAltitudeMeters;
auto bea = gMockBearingDegrees;
auto spd = gMockSpeedMetersPerSec;
for (size_t i = 1; i < options.size(); ++i) {
std::string option = options[i];
if (option.rfind("lat=", 0) == 0) {
option = option.substr(4);
lat = stof(option);
} else if (option.rfind("lon=", 0) == 0) {
option = option.substr(4);
lon = stof(option);
} else if (option.rfind("ele=", 0) == 0) {
option = option.substr(4);
ele = stof(option);
} else if (option.rfind("bea=", 0) == 0) {
option = option.substr(4);
bea = stof(option);
} else if (option.rfind("spd=", 0) == 0) {
option = option.substr(4);
spd = stof(option);
} else {
dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str());
}
}
gMockLatitudeDegrees = lat;
gMockLongitudeDegrees = lon;
gMockAltitudeMeters = ele;
gMockBearingDegrees = bea;
gMockSpeedMetersPerSec = spd;
dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f bea=%f spd=%f\n",
gMockLatitudeDegrees, gMockLongitudeDegrees, gMockAltitudeMeters, gMockBearingDegrees,
gMockSpeedMetersPerSec);
return Void();
}
template <class T_IGnss>
Return<void> GnssTemplate<T_IGnss>::help(const hidl_handle& fd) {
dprintf(fd->data[0],
"invalid option for Gnss HAL; valid options are:\n"
"location [lat=..] [lon=..] [ele=..] [bea=..] [spd=..]\n");
return Void();
}
template <class T_IGnss>
Return<void> GnssTemplate<T_IGnss>::debug(const hidl_handle& fd,
const hidl_vec<hidl_string>& options) {
if (fd == nullptr || fd->numFds == 0) {
return Void();
}
if (options.size() == 0) {
return help(fd);
} else if (options[0] == "location") {
return setLocation(fd, options);
} else {
return help(fd);
}
return Void();
}
} // namespace android::hardware::gnss::common::implementation