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

0
BoardConfig.mk Normal file
View File

View File

@@ -0,0 +1,22 @@
#!/vendor/bin/sh
SRC_PATH=/vendor/etc/init/hw/battery/power_supply
DEST_PATH=/data/vendor/battery/power_supply
copy_files() {
if [ -f $DEST_PATH/battery/v ]; then
ret=$(cmp -s $SRC_PATH/battery/v $DEST_PATH/battery/v || echo -n 1)
if [ "$ret" != "1" ]; then
return
fi
fi
rm -rf $DEST_PATH
cp -r $SRC_PATH $DEST_PATH
echo `expr 80 + $RANDOM % 20` > $DEST_PATH/battery/capacity
chmod -R 777 $DEST_PATH
}
copy_files
mount --bind $DEST_PATH /sys/class/power_supply
chmod 755 /sys/class/power_supply

View File

@@ -0,0 +1 @@
64

View File

@@ -0,0 +1 @@
Normal

View File

@@ -0,0 +1 @@
2926000

View File

@@ -0,0 +1 @@
4524000

View File

@@ -0,0 +1 @@
4524000

View File

@@ -0,0 +1 @@
-68125

View File

@@ -0,0 +1 @@
3250000

View File

@@ -0,0 +1 @@
3240000

View File

@@ -0,0 +1 @@
13213213

View File

@@ -0,0 +1 @@
Good

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
Charging

View File

@@ -0,0 +1 @@
Li-ion

View File

@@ -0,0 +1 @@
100

View File

@@ -0,0 +1 @@
-1

View File

@@ -0,0 +1 @@
Battery

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
20000000

View File

@@ -0,0 +1 @@
20000000

View File

@@ -0,0 +1 @@
20000000

View File

@@ -0,0 +1 @@
687500

View File

@@ -0,0 +1 @@
100000

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
Unknown

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@
687500

View File

@@ -0,0 +1 @@
100000

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
USB

View File

@@ -0,0 +1 @@
5000000

View File

@@ -0,0 +1 @@
4600000

View File

@@ -0,0 +1,69 @@
/*
* 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.
*/
// package {
// // See: http://go/android-license-faq
// // A large-scale-change added 'default_applicable_licenses' to import
// // all of the 'license_kinds' from "hardware_interfaces_license"
// // to get the below license kinds:
// // SPDX-license-identifier-Apache-2.0
// default_applicable_licenses: ["hardware_interfaces_license"],
// }
cc_binary {
name: "android.hardware.gnss-service",
relative_install_path: "hw",
// init_rc: [
// "gnss-xxx-service.rc",
// ],
vintf_fragments: [
"gnss-xxx.xml",
"gnss-xxx@2.1-service.xml",
],
vendor: true,
cflags: [
"-Wall",
"-Wextra",
],
shared_libs: [
"libbase",
"libcutils",
"libbinder_ndk",
"libhidlbase",
"libutils",
"liblog",
"android.hardware.gnss@2.1",
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss-V1-ndk_platform",
],
srcs: [
"Gnss.cpp",
"GnssHidlHal.cpp",
"GnssPowerIndication.cpp",
"GnssPsds.cpp",
"GnssConfiguration.cpp",
"GnssMeasurementInterface.cpp",
"service.cpp",
],
static_libs: [
"android.hardware.gnss@common-default-lib2",
],
}

View File

@@ -0,0 +1,91 @@
/*
* 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.
*/
#define LOG_TAG "GnssAidl"
#include "Gnss.h"
#include <log/log.h>
#include "GnssConfiguration.h"
#include "GnssMeasurementInterface.h"
#include "GnssPsds.h"
namespace aidl::android::hardware::gnss {
std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
ALOGD("Gnss::setCallback");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
}
sGnssCallback = callback;
int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
IGnssCallback::CAPABILITY_SATELLITE_PVT |
IGnssCallback::CAPABILITY_CORRELATION_VECTOR);
auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
if (!status.isOk()) {
ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::close() {
ALOGD("Gnss::close");
sGnssCallback = nullptr;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
ALOGD("Gnss::getExtensionPsds");
*iGnssPsds = SharedRefBase::make<GnssPsds>();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
ALOGD("Gnss::getExtensionGnssConfiguration");
if (mGnssConfiguration == nullptr) {
mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
}
*iGnssConfiguration = mGnssConfiguration;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
ALOGD("Gnss::getExtensionGnssPowerIndication");
if (mGnssPowerIndication == nullptr) {
mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
}
*iGnssPowerIndication = mGnssPowerIndication;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
ALOGD("Gnss::getExtensionGnssMeasurement");
*iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
return ndk::ScopedAStatus::ok();
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,48 @@
/*
* 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 <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
#include "GnssConfiguration.h"
#include "GnssPowerIndication.h"
namespace aidl::android::hardware::gnss {
class Gnss : public BnGnss {
public:
ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
ndk::ScopedAStatus close() override;
ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
ndk::ScopedAStatus getExtensionGnssConfiguration(
std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
ndk::ScopedAStatus getExtensionGnssPowerIndication(
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
ndk::ScopedAStatus getExtensionGnssMeasurement(
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
private:
static std::shared_ptr<IGnssCallback> sGnssCallback;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,52 @@
/*
* 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.
*/
#define LOG_TAG "GnssConfigurationAidl"
#include "GnssConfiguration.h"
#include <log/log.h>
namespace aidl::android::hardware::gnss {
ndk::ScopedAStatus GnssConfiguration::setBlocklist(const vector<BlocklistedSource>& sourceList) {
ALOGD("GnssConfiguration::setBlocklist");
std::unique_lock<std::recursive_mutex> lock(mMutex);
mBlocklistedConstellationSet.clear();
mBlocklistedSourceSet.clear();
for (const auto& source : sourceList) {
if (source.svid == 0) {
// Wildcard blocklist, i.e., blocklist entire constellation.
mBlocklistedConstellationSet.insert(source.constellation);
} else {
mBlocklistedSourceSet.insert(source);
}
}
return ndk::ScopedAStatus::ok();
}
bool GnssConfiguration::isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
std::unique_lock<std::recursive_mutex> lock(mMutex);
if (mBlocklistedConstellationSet.find(static_cast<GnssConstellationType>(
gnssSvInfo.v2_0.constellation)) != mBlocklistedConstellationSet.end()) {
return true;
}
BlocklistedSource source = {
.constellation = static_cast<GnssConstellationType>(gnssSvInfo.v2_0.constellation),
.svid = gnssSvInfo.v2_0.v1_0.svid};
return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,72 @@
/*
* 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 <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <android/hardware/gnss/2.1/IGnssCallback.h>
#include <mutex>
#include <unordered_set>
#include <vector>
namespace aidl::android::hardware::gnss {
struct BlocklistedSourceHash {
inline int operator()(const BlocklistedSource& source) const {
return int(source.constellation) * 1000 + int(source.svid);
}
};
struct BlocklistedSourceEqual {
inline bool operator()(const BlocklistedSource& s1, const BlocklistedSource& s2) const {
return (s1.constellation == s2.constellation) && (s1.svid == s2.svid);
}
};
using GnssSvInfoV2_1 = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
using std::vector;
using BlocklistedSourceSet =
std::unordered_set<BlocklistedSource, BlocklistedSourceHash, BlocklistedSourceEqual>;
using BlocklistedConstellationSet =
std::unordered_set<android::hardware::gnss::GnssConstellationType>;
struct GnssConfiguration : public BnGnssConfiguration {
public:
ndk::ScopedAStatus setSuplVersion(int) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus setSuplMode(int) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus setLppProfile(int) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus setGlonassPositioningProtocol(int) override {
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus setEmergencySuplPdn(bool) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus setEsExtensionSec(int) override { return ndk::ScopedAStatus::ok(); }
ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
private:
BlocklistedSourceSet mBlocklistedSourceSet;
BlocklistedConstellationSet mBlocklistedConstellationSet;
mutable std::recursive_mutex mMutex;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,65 @@
/*
* 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.
*/
#define LOG_TAG "GnssHidlHal"
#include "GnssHidlHal.h"
namespace aidl::android::hardware::gnss {
using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo;
GnssHidlHal::GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl) : mGnssAidl(gnssAidl) {
Gnss* iGnss = mGnssAidl.get();
std::shared_ptr<IGnssConfiguration> iGnssConfiguration;
auto status = iGnss->getExtensionGnssConfiguration(&iGnssConfiguration);
if (!status.isOk()) {
ALOGE("Failed to getExtensionGnssConfiguration.");
} else {
mGnssConfigurationAidl = iGnss->mGnssConfiguration;
}
std::shared_ptr<IGnssPowerIndication> iGnssPowerIndication;
status = iGnss->getExtensionGnssPowerIndication(&iGnssPowerIndication);
if (!status.isOk()) {
ALOGE("Failed to getExtensionGnssPowerIndication.");
} else {
mGnssPowerIndicationAidl = iGnss->mGnssPowerIndication;
}
};
hidl_vec<GnssSvInfo> GnssHidlHal::filterBlocklistedSatellitesV2_1(
hidl_vec<GnssSvInfo> gnssSvInfoList) {
if (mGnssConfigurationAidl == nullptr) {
ALOGE("Handle to AIDL GnssConfiguration is not available.");
return gnssSvInfoList;
}
for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) {
ALOGD("Blocklisted constellation: %d, svid: %d",
(int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid);
gnssSvInfoList[i].v2_0.v1_0.svFlag &= ~static_cast<uint8_t>(
::android::hardware::gnss::V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
}
}
return gnssSvInfoList;
}
void GnssHidlHal::notePowerConsumption() {
mGnssPowerIndicationAidl->notePowerConsumption();
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,42 @@
/*
* 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 "Gnss.h"
#include "GnssConfiguration.h"
#include "v2_1/GnssTemplate.h"
namespace aidl::android::hardware::gnss {
class GnssHidlHal : public ::android::hardware::gnss::common::implementation::GnssTemplate<
::android::hardware::gnss::V2_1::IGnss> {
public:
GnssHidlHal(const std::shared_ptr<Gnss>& gnssAidl);
private:
hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>
filterBlocklistedSatellitesV2_1(
hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList)
override;
void notePowerConsumption() override;
std::shared_ptr<Gnss> mGnssAidl;
std::shared_ptr<GnssConfiguration> mGnssConfigurationAidl;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndicationAidl;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,94 @@
/*
* 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.
*/
#define LOG_TAG "GnssMeasIfaceAidl"
#include "GnssMeasurementInterface.h"
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
#include "Utils.h"
namespace aidl::android::hardware::gnss {
using Utils = ::android::hardware::gnss::common::Utils;
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
GnssMeasurementInterface::GnssMeasurementInterface() : mMinIntervalMillis(1000) {}
GnssMeasurementInterface::~GnssMeasurementInterface() {
stop();
}
ndk::ScopedAStatus GnssMeasurementInterface::setCallback(
const std::shared_ptr<IGnssMeasurementCallback>& callback, const bool enableFullTracking,
const bool enableCorrVecOutputs) {
ALOGD("setCallback: enableFullTracking: %d enableCorrVecOutputs: %d", (int)enableFullTracking,
(int)enableCorrVecOutputs);
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
if (mIsActive) {
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
start(enableCorrVecOutputs);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssMeasurementInterface::close() {
ALOGD("close");
stop();
std::unique_lock<std::mutex> lock(mMutex);
sCallback = nullptr;
return ndk::ScopedAStatus::ok();
}
void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
ALOGD("start");
mIsActive = true;
mThread = std::thread([this, enableCorrVecOutputs]() {
while (mIsActive == true) {
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
this->reportMeasurement(measurement);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
}
});
mThread.detach();
}
void GnssMeasurementInterface::stop() {
ALOGD("stop");
mIsActive = false;
}
void GnssMeasurementInterface::reportMeasurement(const GnssData& data) {
ALOGD("reportMeasurement()");
std::shared_ptr<IGnssMeasurementCallback> callbackCopy;
{
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback == nullptr) {
ALOGE("%s: GnssMeasurement::sCallback is null.", __func__);
return;
}
callbackCopy = sCallback;
}
callbackCopy->gnssMeasurementCb(data);
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,52 @@
/*
* 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 <aidl/android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <atomic>
#include <mutex>
#include <thread>
namespace aidl::android::hardware::gnss {
struct GnssMeasurementInterface : public BnGnssMeasurementInterface {
public:
GnssMeasurementInterface();
~GnssMeasurementInterface();
ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssMeasurementCallback>& callback,
const bool enableFullTracking,
const bool enableCorrVecOutputs) override;
ndk::ScopedAStatus close() override;
private:
void start(const bool enableCorrVecOutputs);
void stop();
void reportMeasurement(const GnssData&);
std::atomic<long> mMinIntervalMillis;
std::atomic<bool> mIsActive;
std::thread mThread;
// Guarded by mMutex
static std::shared_ptr<IGnssMeasurementCallback> sCallback;
// Synchronization lock for sCallback
mutable std::mutex mMutex;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,68 @@
/*
* 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.
*/
#define LOG_TAG "GnssPowerIndicationAidl"
#include "GnssPowerIndication.h"
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
#include <utils/SystemClock.h>
namespace aidl::android::hardware::gnss {
std::shared_ptr<IGnssPowerIndicationCallback> GnssPowerIndication::sCallback = nullptr;
ndk::ScopedAStatus GnssPowerIndication::setCallback(
const std::shared_ptr<IGnssPowerIndicationCallback>& callback) {
ALOGD("setCallback");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
sCallback->setCapabilitiesCb(IGnssPowerIndicationCallback::CAPABILITY_TOTAL |
IGnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_TRACKING |
IGnssPowerIndicationCallback::CAPABILITY_MULTIBAND_TRACKING |
IGnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_ACQUISITION |
IGnssPowerIndicationCallback::CAPABILITY_MULTIBAND_ACQUISITION |
IGnssPowerIndicationCallback::CAPABILITY_OTHER_MODES);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssPowerIndication::requestGnssPowerStats() {
ALOGD("requestGnssPowerStats");
std::unique_lock<std::mutex> lock(mMutex);
ElapsedRealtime elapsedRealtime = {
.flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
.timestampNs = ::android::elapsedRealtimeNano(),
.timeUncertaintyNs = 1000,
};
GnssPowerStats gnssPowerStats = {
.elapsedRealtime = elapsedRealtime,
.totalEnergyMilliJoule = 1.500e+3 + numLocationReported * 22.0,
.singlebandTrackingModeEnergyMilliJoule = 0.0,
.multibandTrackingModeEnergyMilliJoule = 1.28e+2 + numLocationReported * 4.0,
.singlebandAcquisitionModeEnergyMilliJoule = 0.0,
.multibandAcquisitionModeEnergyMilliJoule = 3.65e+2 + numLocationReported * 15.0,
.otherModesEnergyMilliJoule = {1.232e+2, 3.234e+3},
};
sCallback->gnssPowerStatsCb(gnssPowerStats);
return ndk::ScopedAStatus::ok();
}
void GnssPowerIndication::notePowerConsumption() {
numLocationReported++;
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,41 @@
/*
* 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 <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
namespace aidl::android::hardware::gnss {
struct GnssPowerIndication : public BnGnssPowerIndication {
public:
ndk::ScopedAStatus setCallback(
const std::shared_ptr<IGnssPowerIndicationCallback>& callback) override;
ndk::ScopedAStatus requestGnssPowerStats() override;
void notePowerConsumption();
private:
// Guarded by mMutex
static std::shared_ptr<IGnssPowerIndicationCallback> sCallback;
// Synchronization lock for sCallback
mutable std::mutex mMutex;
int numLocationReported;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,44 @@
/*
* 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.
*/
#define LOG_TAG "GnssPsdsAidl"
#include "GnssPsds.h"
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <log/log.h>
namespace aidl::android::hardware::gnss {
std::shared_ptr<IGnssPsdsCallback> GnssPsds::sCallback = nullptr;
ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) {
ALOGD("setCallback");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType,
const std::vector<uint8_t>& psdsData) {
ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast<int>(psdsType),
static_cast<int>(psdsData.size()));
if (psdsData.size() > 0) {
return ndk::ScopedAStatus::ok();
} else {
return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
}
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,37 @@
/*
* 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 <aidl/android/hardware/gnss/BnGnssPsds.h>
namespace aidl::android::hardware::gnss {
struct GnssPsds : public BnGnssPsds {
public:
ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssPsdsCallback>& callback) override;
ndk::ScopedAStatus injectPsdsData(PsdsType psdsType,
const std::vector<uint8_t>& psdsData) override;
private:
// Guarded by mMutex
static std::shared_ptr<IGnssPsdsCallback> sCallback;
// Synchronization lock for sCallback
mutable std::mutex mMutex;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,4 @@
service gnss /vendor/bin/hw/android.hardware.gnss-service
class hal
user nobody
group nobody

View File

@@ -0,0 +1,9 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.gnss</name>
<interface>
<name>IGnss</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View File

@@ -0,0 +1,12 @@
<manifest version="1.0" type="device">
<hal format="hidl">
<name>android.hardware.gnss</name>
<transport>hwbinder</transport>
<version>2.1</version>
<version>1.1</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

View File

@@ -0,0 +1,58 @@
/*
* Copyright 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.
*/
#define LOG_TAG "Gnss-main"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <log/log.h>
#include <pthread.h>
#include "Gnss.h"
#include "GnssHidlHal.h"
using aidl::android::hardware::gnss::Gnss;
using aidl::android::hardware::gnss::GnssHidlHal;
using ::android::OK;
using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
using ::android::hardware::gnss::V2_1::IGnss;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
std::shared_ptr<Gnss> gnssAidl = ndk::SharedRefBase::make<Gnss>();
const std::string instance = std::string() + Gnss::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(gnssAidl->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
sp<IGnss> gnss = new GnssHidlHal(gnssAidl);
configureRpcThreadpool(1, true /* will join */);
if (gnss->registerAsService() != OK) {
ALOGE("Could not register gnss 2.1 service.");
return 0;
}
joinRpcThreadpool();
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}

7
gps/gnss/common/OWNERS Normal file
View File

@@ -0,0 +1,7 @@
wyattriley@google.com
gomo@google.com
smalkos@google.com
yuhany@google.com
# VTS team
yim@google.com

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.
//
// package {
// // See: http://go/android-license-faq
// // A large-scale-change added 'default_applicable_licenses' to import
// // all of the 'license_kinds' from "hardware_interfaces_license"
// // to get the below license kinds:
// // SPDX-license-identifier-Apache-2.0
// default_applicable_licenses: ["hardware_interfaces_license"],
// }
cc_library_static {
name: "android.hardware.gnss@common-default-lib2",
vendor_available: true,
relative_install_path: "hw",
cflags: [
"-Wall",
"-Wextra",
"-Werror",
],
srcs: [
"v2_1/GnssAntennaInfo.cpp",
"v2_1/GnssConfiguration.cpp",
"v2_1/GnssDebug.cpp",
"v2_1/GnssMeasurement.cpp",
"v2_1/GnssMeasurementCorrections.cpp",
"MockLocation.cpp",
"Utils.cpp",
"NmeaFixInfo.cpp",
],
export_include_dirs: ["include"],
shared_libs: [
"libcutils",
"libhidlbase",
"libutils",
"android.hardware.gnss@1.0",
"android.hardware.gnss@2.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss-V1-ndk_platform",
],
}

View File

@@ -0,0 +1,27 @@
/*
* 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.
*/
#include "MockLocation.h"
namespace android::hardware::gnss::common {
float gMockLatitudeDegrees{37.4219999};
float gMockLongitudeDegrees{-122.0840575};
float gMockAltitudeMeters{1.60062531};
float gMockBearingDegrees{0};
float gMockSpeedMetersPerSec{0};
} // namespace android::hardware::gnss::common

View File

@@ -0,0 +1,273 @@
/*
* 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.
*/
#define LOG_TAG "NmeaFixInfo"
#include <Constants.h>
#include <NmeaFixInfo.h>
#include <Utils.h>
#include <log/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <utils/SystemClock.h>
#include <limits>
#include <sstream>
#include <string>
#include <vector>
namespace android {
namespace hardware {
namespace gnss {
namespace common {
NmeaFixInfo::NmeaFixInfo() : hasGMCRecord(false), hasGGARecord(false) {}
float NmeaFixInfo::getAltitudeMeters() const {
return altitudeMeters;
}
float NmeaFixInfo::checkAndConvertToFloat(const std::string& sentence) {
if (sentence.empty()) {
return std::numeric_limits<float>::quiet_NaN();
}
return std::stof(sentence);
}
float NmeaFixInfo::getBearingAccuracyDegrees() const {
// Current NMEA doesn't contains beaing accuracy inforamtion
return kMockBearingAccuracyDegrees;
}
float NmeaFixInfo::getBearingDegrees() const {
return bearingDegrees;
}
float NmeaFixInfo::getHorizontalAccuracyMeters() const {
// Current NMEA doesn't contains horizontal accuracy inforamtion
return kMockHorizontalAccuracyMeters;
}
float NmeaFixInfo::getLatDeg() const {
return latDeg;
}
float NmeaFixInfo::getLngDeg() const {
return lngDeg;
}
float NmeaFixInfo::getSpeedAccuracyMetersPerSecond() const {
// Current NMEA doesn't contains speed accuracy inforamtion
return kMockSpeedAccuracyMetersPerSecond;
}
float NmeaFixInfo::getSpeedMetersPerSec() const {
return speedMetersPerSec;
}
int64_t NmeaFixInfo::getTimestamp() const {
return timestamp;
}
float NmeaFixInfo::getVerticalAccuracyMeters() const {
// Current NMEA doesn't contains vertical accuracy inforamtion
return kMockVerticalAccuracyMeters;
}
int64_t NmeaFixInfo::nmeaPartsToTimestamp(const std::string& timeStr, const std::string& dateStr) {
/**
* In NMEA format, the full time can only get from the $GPRMC record, see
* the following example:
* $GPRMC,213204.00,A,3725.371240,N,12205.589239,W,000.0,000.0,290819,,,A*49
* the datetime is stored in two parts, 213204 and 290819, which means
* 2019/08/29 21:32:04, however for in unix the year starts from 1900, we
* need to add the offset.
*/
struct tm tm;
const int32_t unixYearOffset = 100;
tm.tm_mday = std::stoi(dateStr.substr(0, 2).c_str());
tm.tm_mon = std::stoi(dateStr.substr(2, 2).c_str()) - 1;
tm.tm_year = std::stoi(dateStr.substr(4, 2).c_str()) + unixYearOffset;
tm.tm_hour = std::stoi(timeStr.substr(0, 2).c_str());
tm.tm_min = std::stoi(timeStr.substr(2, 2).c_str());
tm.tm_sec = std::stoi(timeStr.substr(4, 2).c_str());
return static_cast<int64_t>(mktime(&tm) - timezone);
}
bool NmeaFixInfo::isValidFix() const {
return hasGMCRecord && hasGGARecord;
}
void NmeaFixInfo::parseGGALine(const std::vector<std::string>& sentenceValues) {
if (sentenceValues.size() == 0 || sentenceValues[0].compare(GPGA_RECORD_TAG) != 0) {
return;
}
// LatDeg, need covert to degree, if it is 'N', should be negative value
this->latDeg = std::stof(sentenceValues[2].substr(0, 2)) +
(std::stof(sentenceValues[2].substr(2)) / 60.0);
if (sentenceValues[3].compare("N") != 0) {
this->latDeg *= -1;
}
// LngDeg, need covert to degree, if it is 'E', should be negative value
this->lngDeg = std::stof(sentenceValues[4].substr(0, 3)) +
std::stof(sentenceValues[4].substr(3)) / 60.0;
if (sentenceValues[5].compare("E") != 0) {
this->lngDeg *= -1;
}
this->altitudeMeters = std::stof(sentenceValues[9]);
this->hDop = sentenceValues[8].empty() ? std::numeric_limits<float>::quiet_NaN()
: std::stof(sentenceValues[8]);
this->hasGGARecord = true;
}
void NmeaFixInfo::parseRMCLine(const std::vector<std::string>& sentenceValues) {
if (sentenceValues.size() == 0 || sentenceValues[0].compare(GPRMC_RECORD_TAG) != 0) {
return;
}
this->speedMetersPerSec = checkAndConvertToFloat(sentenceValues[7]);
this->bearingDegrees = checkAndConvertToFloat(sentenceValues[8]);
this->timestamp = nmeaPartsToTimestamp(sentenceValues[1], sentenceValues[9]);
this->hasGMCRecord = true;
}
/** invalid the current NmeaFixInfo */
void NmeaFixInfo::reset() {
this->altitudeMeters = 0;
this->bearingDegrees = 0;
this->fixId = 0;
this->hasGMCRecord = false;
this->hasGGARecord = false;
this->latDeg = 0;
this->lngDeg = 0;
this->hDop = 0;
this->vDop = 0;
this->satelliteCount = 0;
this->speedMetersPerSec = 0;
this->timestamp = 0;
}
void NmeaFixInfo::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);
}
}
NmeaFixInfo& NmeaFixInfo::operator=(const NmeaFixInfo& rhs) {
if (this == &rhs) return *this;
this->altitudeMeters = rhs.altitudeMeters;
this->bearingDegrees = rhs.bearingDegrees;
this->fixId = rhs.fixId;
this->hasGMCRecord = rhs.hasGMCRecord;
this->hasGGARecord = rhs.hasGGARecord;
this->hDop = rhs.hDop;
this->vDop = rhs.vDop;
this->latDeg = rhs.latDeg;
this->lngDeg = rhs.lngDeg;
this->satelliteCount = rhs.satelliteCount;
this->speedMetersPerSec = rhs.speedMetersPerSec;
this->timestamp = rhs.timestamp;
return *this;
}
/**
* Parses the input string in NMEA format and convert to GnssLocation.
* Currently version only cares about $GPGGA and $GPRMC records. but we
* can easily extend to other types supported by NMEA if needed.
*/
std::unique_ptr<V2_0::GnssLocation> NmeaFixInfo::getLocationFromInputStr(
const std::string& inputStr) {
std::vector<std::string> nmeaRecords;
splitStr(inputStr, LINE_SEPARATOR, nmeaRecords);
NmeaFixInfo nmeaFixInfo;
NmeaFixInfo candidateFixInfo;
uint32_t fixId = 0;
double lastTimeStamp = 0;
for (const auto& line : nmeaRecords) {
if (line.compare(0, strlen(GPGA_RECORD_TAG), GPGA_RECORD_TAG) != 0 &&
line.compare(0, strlen(GPRMC_RECORD_TAG), GPRMC_RECORD_TAG) != 0) {
continue;
}
std::vector<std::string> sentenceValues;
splitStr(line, COMMA_SEPARATOR, sentenceValues);
if (sentenceValues.size() < MIN_COL_NUM) {
continue;
}
double currentTimeStamp = std::stof(sentenceValues[1]);
// If see a new timestamp, report correct location.
if ((currentTimeStamp - lastTimeStamp) > TIMESTAMP_EPSILON &&
candidateFixInfo.isValidFix()) {
nmeaFixInfo = candidateFixInfo;
candidateFixInfo.reset();
fixId++;
}
if (line.compare(0, strlen(GPGA_RECORD_TAG), GPGA_RECORD_TAG) == 0) {
candidateFixInfo.fixId = fixId;
candidateFixInfo.parseGGALine(sentenceValues);
} else if (line.compare(0, strlen(GPRMC_RECORD_TAG), GPRMC_RECORD_TAG) == 0) {
candidateFixInfo.parseRMCLine(sentenceValues);
}
}
if (candidateFixInfo.isValidFix()) {
nmeaFixInfo = candidateFixInfo;
candidateFixInfo.reset();
}
if (!nmeaFixInfo.isValidFix()) {
return nullptr;
}
return nmeaFixInfo.toGnssLocation();
}
/**
* Parses the input string in NMEA format and convert to GnssLocation.
*/
std::unique_ptr<V2_0::GnssLocation> NmeaFixInfo::toGnssLocation() const {
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 = this->getLatDeg(),
.longitudeDegrees = this->getLngDeg(),
.altitudeMeters = this->getAltitudeMeters(),
.speedMetersPerSec = this->getSpeedMetersPerSec(),
.bearingDegrees = this->getBearingDegrees(),
.horizontalAccuracyMeters = this->getHorizontalAccuracyMeters(),
.verticalAccuracyMeters = this->getVerticalAccuracyMeters(),
.speedAccuracyMetersPerSecond = this->getSpeedAccuracyMetersPerSecond(),
.bearingAccuracyDegrees = this->getBearingAccuracyDegrees(),
.timestamp = this->getTimestamp()};
V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = currentOsTimestamp};
return std::make_unique<V2_0::GnssLocation>(locationV2);
}
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android

View File

@@ -0,0 +1,405 @@
/*
* 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.
*/
#include <Constants.h>
#include <MockLocation.h>
#include <Utils.h>
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <utils/SystemClock.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::GnssData;
using aidl::android::hardware::gnss::GnssMeasurement;
using aidl::android::hardware::gnss::IGnss;
using aidl::android::hardware::gnss::IGnssMeasurementCallback;
using aidl::android::hardware::gnss::SatellitePvt;
using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags;
using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType;
using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback;
using GnssSignalType = V2_1::GnssSignalType;
using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData;
using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData;
using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo;
using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo;
using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo;
using Row = V2_1::IGnssAntennaInfoCallback::Row;
using Coord = V2_1::IGnssAntennaInfoCallback::Coord;
GnssDataV2_1 Utils::getMockMeasurementV2_1() {
GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0();
V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = {
.v2_0 = gnssDataV2_0.measurements[0],
.flags = (uint32_t)(GnssMeasurementFlagsV2_1::HAS_CARRIER_FREQUENCY |
GnssMeasurementFlagsV2_1::HAS_CARRIER_PHASE |
GnssMeasurementFlagsV2_1::HAS_FULL_ISB |
GnssMeasurementFlagsV2_1::HAS_FULL_ISB_UNCERTAINTY |
GnssMeasurementFlagsV2_1::HAS_SATELLITE_ISB |
GnssMeasurementFlagsV2_1::HAS_SATELLITE_ISB_UNCERTAINTY),
.fullInterSignalBiasNs = 30.0,
.fullInterSignalBiasUncertaintyNs = 250.0,
.satelliteInterSignalBiasNs = 20.0,
.satelliteInterSignalBiasUncertaintyNs = 150.0,
.basebandCN0DbHz = 25.0,
};
GnssSignalType referenceSignalTypeForIsb = {
.constellation = GnssConstellationTypeV2_0::GPS,
.carrierFrequencyHz = 1.59975e+09,
.codeType = "C",
};
V2_1::IGnssMeasurementCallback::GnssClock gnssClockV2_1 = {
.v1_0 = gnssDataV2_0.clock,
.referenceSignalTypeForIsb = referenceSignalTypeForIsb,
};
hidl_vec<V2_1::IGnssMeasurementCallback::GnssMeasurement> measurements(1);
measurements[0] = gnssMeasurementV2_1;
GnssDataV2_1 gnssDataV2_1 = {
.measurements = measurements,
.clock = gnssClockV2_1,
.elapsedRealtime = gnssDataV2_0.elapsedRealtime,
};
return gnssDataV2_1;
}
GnssDataV2_0 Utils::getMockMeasurementV2_0() {
V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
.flags = (uint32_t)GnssMeasurementFlagsV1_0::HAS_CARRIER_FREQUENCY,
.svid = (int16_t)6,
.constellation = V1_0::GnssConstellationType::UNKNOWN,
.timeOffsetNs = 0.0,
.receivedSvTimeInNs = 8195997131077,
.receivedSvTimeUncertaintyInNs = 15,
.cN0DbHz = 30.0,
.pseudorangeRateMps = -484.13739013671875,
.pseudorangeRateUncertaintyMps = 1.0379999876022339,
.accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
.accumulatedDeltaRangeM = 0.0,
.accumulatedDeltaRangeUncertaintyM = 0.0,
.carrierFrequencyHz = 1.59975e+09,
.multipathIndicator =
V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
.v1_1 = measurement_1_1,
.codeType = "C",
.state = GnssMeasurementStateV2_0::STATE_CODE_LOCK |
GnssMeasurementStateV2_0::STATE_BIT_SYNC |
GnssMeasurementStateV2_0::STATE_SUBFRAME_SYNC |
GnssMeasurementStateV2_0::STATE_TOW_DECODED |
GnssMeasurementStateV2_0::STATE_GLO_STRING_SYNC |
GnssMeasurementStateV2_0::STATE_GLO_TOD_DECODED,
.constellation = GnssConstellationTypeV2_0::GLONASS,
};
hidl_vec<IGnssMeasurementCallbackV2_0::GnssMeasurement> measurements(1);
measurements[0] = measurement_2_0;
V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
.fullBiasNs = -1226701900521857520,
.biasNs = 0.59689998626708984,
.biasUncertaintyNs = 47514.989972114563,
.driftNsps = -51.757811607455452,
.driftUncertaintyNsps = 310.64968328491528,
.hwClockDiscontinuityCount = 1};
V2_0::ElapsedRealtime timestamp = {
.flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
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};
GnssDataV2_0 gnssData = {
.measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
return gnssData;
}
GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
aidl::android::hardware::gnss::GnssSignalType signalType = {
.constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
.carrierFrequencyHz = 1.59975e+09,
.codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C,
};
GnssMeasurement measurement = {
.flags = GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL |
GnssMeasurement::HAS_CARRIER_FREQUENCY | GnssMeasurement::HAS_CARRIER_PHASE |
GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY |
GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY |
GnssMeasurement::HAS_SATELLITE_ISB |
GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY |
GnssMeasurement::HAS_SATELLITE_PVT,
.svid = 13,
.signalType = signalType,
.receivedSvTimeInNs = 8195997131077,
.receivedSvTimeUncertaintyInNs = 15,
.antennaCN0DbHz = 30.0,
.basebandCN0DbHz = 26.5,
.agcLevelDb = 2.3,
.pseudorangeRateMps = -484.13739013671875,
.pseudorangeRateUncertaintyMps = 1.0379999876022339,
.accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN,
.accumulatedDeltaRangeM = 1.52,
.accumulatedDeltaRangeUncertaintyM = 2.43,
.multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN,
.state = GnssMeasurement::STATE_CODE_LOCK | GnssMeasurement::STATE_BIT_SYNC |
GnssMeasurement::STATE_SUBFRAME_SYNC | GnssMeasurement::STATE_TOW_DECODED |
GnssMeasurement::STATE_GLO_STRING_SYNC |
GnssMeasurement::STATE_GLO_TOD_DECODED,
.fullInterSignalBiasNs = 21.5,
.fullInterSignalBiasUncertaintyNs = 792.0,
.satelliteInterSignalBiasNs = 233.9,
.satelliteInterSignalBiasUncertaintyNs = 921.2,
.satellitePvt = {.flags = SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO |
SatellitePvt::HAS_IONO | SatellitePvt::HAS_TROPO,
.satPosEcef = {.posXMeters = 10442993.1153328,
.posYMeters = -19926932.8051666,
.posZMeters = -12034295.0216203,
.ureMeters = 1000.2345678},
.satVelEcef = {.velXMps = -478.667183715732,
.velYMps = 1580.68371984114,
.velZMps = -3030.52994449997,
.ureRateMps = 10.2345678},
.satClockInfo = {.satHardwareCodeBiasMeters = 1.396983861923e-09,
.satTimeCorrectionMeters = -7113.08964331,
.satClkDriftMps = 0},
.ionoDelayMeters = 3.069949602639317e-08,
.tropoDelayMeters = 3.882265204404031},
.correlationVectors = {}};
GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS |
GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT |
GnssClock::HAS_DRIFT_UNCERTAINTY,
.timeNs = 35854545000000,
.fullBiasNs = -234621900521857520,
.biasNs = 0.2352389998626708984,
.biasUncertaintyNs = 274.989972114563,
.driftNsps = -124.3742360,
.driftUncertaintyNsps = 239.6234285828,
.hwClockDiscontinuityCount = 999};
ElapsedRealtime timestamp = {
.flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
.timestampNs = ::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};
if (enableCorrVecOutputs) {
aidl::android::hardware::gnss::CorrelationVector correlationVector1 = {
.frequencyOffsetMps = 10,
.samplingWidthM = 30,
.samplingStartM = 0,
.magnitude = {0, 5000, 10000, 5000, 0, 0, 3000, 0}};
aidl::android::hardware::gnss::CorrelationVector correlationVector2 = {
.frequencyOffsetMps = 20,
.samplingWidthM = 30,
.samplingStartM = -10,
.magnitude = {0, 3000, 5000, 3000, 0, 0, 1000, 0}};
measurement.correlationVectors = {correlationVector1, correlationVector2};
measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR;
}
GnssData gnssData = {
.measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp};
return gnssData;
}
V2_0::GnssLocation Utils::getMockLocationV2_0() {
const V2_0::ElapsedRealtime timestamp = {
.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};
V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocationV1_0(),
.elapsedRealtime = timestamp};
return location;
}
V1_0::GnssLocation Utils::getMockLocationV1_0() {
V1_0::GnssLocation location = {
.gnssLocationFlags = 0xFF,
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
.speedMetersPerSec = gMockSpeedMetersPerSec,
.bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
.bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
.timestamp =
static_cast<int64_t>(kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6)};
return location;
}
hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS,
32.5, 59.1, 166.5, kGpsL1FreqHz);
GnssSvInfoV2_0 gnssSvInfoV2_0 =
Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS);
hidl_vec<GnssSvInfoV2_1> gnssSvInfoList = {
Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0,
29.0, 56.5, kGpsL1FreqHz),
V2_0::GnssConstellationType::GPS),
22.0),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5,
71.0, 77.0, kGpsL5FreqHz),
V2_0::GnssConstellationType::GPS),
25.5),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1,
28.0, 253.0, kGpsL5FreqHz),
V2_0::GnssConstellationType::GPS),
19.1),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS,
20.5, 11.5, 116.0, kGloG1FreqHz),
V2_0::GnssConstellationType::GLONASS),
15.5),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS,
21.5, 28.5, 186.0, kGloG1FreqHz),
V2_0::GnssConstellationType::GLONASS),
16.5),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS,
28.3, 38.8, 69.0, kGloG1FreqHz),
V2_0::GnssConstellationType::GLONASS),
25.3),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS,
25.0, 66.0, 247.0, kGloG1FreqHz),
V2_0::GnssConstellationType::GLONASS),
20.0),
getMockSvInfoV2_1(
getMockSvInfoV2_0(getMockSvInfoV1_0(3, V1_0::GnssConstellationType::UNKNOWN,
22.0, 35.0, 112.0, kIrnssL5FreqHz),
V2_0::GnssConstellationType::IRNSS),
19.7),
};
return gnssSvInfoList;
}
GnssSvInfoV2_1 Utils::getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz) {
GnssSvInfoV2_1 gnssSvInfoV2_1 = {
.v2_0 = gnssSvInfoV2_0,
.basebandCN0DbHz = basebandCN0DbHz,
};
return gnssSvInfoV2_1;
}
GnssSvInfoV2_0 Utils::getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0,
V2_0::GnssConstellationType type) {
GnssSvInfoV2_0 gnssSvInfoV2_0 = {
.v1_0 = gnssSvInfoV1_0,
.constellation = type,
};
return gnssSvInfoV2_0;
}
GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
float cN0DbHz, float elevationDegrees, float azimuthDegrees,
float carrierFrequencyHz) {
GnssSvInfoV1_0 svInfo = {.svid = svid,
.constellation = type,
.cN0Dbhz = cN0DbHz,
.elevationDegrees = elevationDegrees,
.azimuthDegrees = azimuthDegrees,
.carrierFrequencyHz = carrierFrequencyHz,
.svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
GnssSvFlags::HAS_ALMANAC_DATA |
GnssSvFlags::HAS_CARRIER_FREQUENCY};
return svInfo;
}
hidl_vec<GnssAntennaInfo> Utils::getMockAntennaInfos() {
GnssAntennaInfo mockAntennaInfo_1 = {
.carrierFrequencyMHz = kGpsL1FreqHz * 1e-6,
.phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1,
.xUncertainty = 0.1,
.y = 2,
.yUncertainty = 0.1,
.z = 3,
.zUncertainty = 0.1},
.phaseCenterVariationCorrectionMillimeters =
{
Row{hidl_vec<double>{1, -1, 5, -2, 3, -1}},
Row{hidl_vec<double>{-2, 3, 2, 0, 1, 2}},
Row{hidl_vec<double>{1, 3, 2, -1, -3, 5}},
},
.phaseCenterVariationCorrectionUncertaintyMillimeters =
{
Row{hidl_vec<double>{0.1, 0.2, 0.4, 0.1, 0.2, 0.3}},
Row{hidl_vec<double>{0.3, 0.2, 0.3, 0.6, 0.1, 0.1}},
Row{hidl_vec<double>{0.1, 0.1, 0.4, 0.2, 0.5, 0.3}},
},
.signalGainCorrectionDbi =
{
Row{hidl_vec<double>{2, -3, 1, -3, 0, -4}},
Row{hidl_vec<double>{1, 0, -4, 1, 3, -2}},
Row{hidl_vec<double>{3, -2, 0, -2, 3, 0}},
},
.signalGainCorrectionUncertaintyDbi =
{
Row{hidl_vec<double>{0.3, 0.1, 0.2, 0.6, 0.1, 0.3}},
Row{hidl_vec<double>{0.1, 0.1, 0.5, 0.2, 0.3, 0.1}},
Row{hidl_vec<double>{0.2, 0.4, 0.2, 0.1, 0.1, 0.2}},
},
};
GnssAntennaInfo mockAntennaInfo_2 = {
.carrierFrequencyMHz = kGpsL5FreqHz * 1e-6,
.phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5,
.xUncertainty = 0.1,
.y = 6,
.yUncertainty = 0.1,
.z = 7,
.zUncertainty = 0.1},
};
hidl_vec<GnssAntennaInfo> mockAntennaInfos = {
mockAntennaInfo_1,
mockAntennaInfo_2,
};
return mockAntennaInfos;
}
} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android

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

View File

@@ -0,0 +1,101 @@
/*
* 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.
*/
#define LOG_TAG "GnssAntennaInfo"
#include "v2_1/GnssAntennaInfo.h"
#include "Utils.h"
#include <log/log.h>
using ::android::hardware::gnss::common::Utils;
namespace android::hardware::gnss::V2_1::implementation {
sp<IGnssAntennaInfoCallback> GnssAntennaInfo::sCallback = nullptr;
GnssAntennaInfo::GnssAntennaInfo() : mMinIntervalMillis(1000) {}
GnssAntennaInfo::~GnssAntennaInfo() {
stop();
}
// Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow.
Return<GnssAntennaInfo::GnssAntennaInfoStatus> GnssAntennaInfo::setCallback(
const sp<IGnssAntennaInfoCallback>& callback) {
ALOGD("setCallback");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
if (mIsActive) {
ALOGW("GnssAntennaInfo callback already set. Resetting the callback...");
stop();
}
start();
return GnssAntennaInfoStatus::SUCCESS;
}
Return<void> GnssAntennaInfo::close() {
ALOGD("close");
stop();
std::unique_lock<std::mutex> lock(mMutex);
sCallback = nullptr;
return Void();
}
// Private methods
void GnssAntennaInfo::start() {
ALOGD("start");
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
if (sCallback != nullptr) {
auto antennaInfos = Utils::getMockAntennaInfos();
this->reportAntennaInfo(antennaInfos);
}
/** For mock implementation this is good. On real device, we should only report
antennaInfo at start and when there is a configuration change. **/
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
}
});
}
void GnssAntennaInfo::stop() {
ALOGD("stop");
mIsActive = false;
if (mThread.joinable()) {
mThread.join();
}
}
void GnssAntennaInfo::reportAntennaInfo(
const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& antennaInfo) const {
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback == nullptr) {
ALOGE("%s: No non-null callback", __func__);
return;
}
auto ret = sCallback->gnssAntennaInfoCb(antennaInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,101 @@
/*
* 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.
*/
#define LOG_TAG "GnssConfiguration"
#include "v2_1/GnssConfiguration.h"
#include <log/log.h>
namespace android::hardware::gnss::V2_1::implementation {
using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo;
using BlacklistedSourceV2_1 = V2_1::IGnssConfiguration::BlacklistedSource;
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setSuplEs(bool enable) {
ALOGD("setSuplEs enable: %d", enable);
// Method deprecated in 2.0 and not expected to be called by the framework.
return false;
}
Return<bool> GnssConfiguration::setSuplVersion(uint32_t) {
return true;
}
Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) {
return true;
}
Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock> gpsLock) {
ALOGD("setGpsLock gpsLock: %hhu", static_cast<GpsLock>(gpsLock));
// Method deprecated in 2.0 and not expected to be called by the framework.
return false;
}
Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) {
return true;
}
Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) {
return true;
}
Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) {
return true;
}
// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setBlacklist(
const hidl_vec<V1_1::IGnssConfiguration::BlacklistedSource>&) {
// TODO (b/122463906): Reuse 1.1 implementation.
return bool{};
}
// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
ALOGD("setEsExtensionSec emergencyExtensionSeconds: %d", emergencyExtensionSeconds);
return true;
}
// Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setBlacklist_2_1(
const hidl_vec<BlacklistedSourceV2_1>& sourceList) {
std::unique_lock<std::recursive_mutex> lock(mMutex);
mBlacklistedConstellationSet.clear();
mBlacklistedSourceSet.clear();
for (auto source : sourceList) {
if (source.svid == 0) {
// Wildcard blacklist, i.e., blacklist entire constellation.
mBlacklistedConstellationSet.insert(source.constellation);
} else {
mBlacklistedSourceSet.insert(source);
}
}
return true;
}
Return<bool> GnssConfiguration::isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const {
std::unique_lock<std::recursive_mutex> lock(mMutex);
if (mBlacklistedConstellationSet.find(gnssSvInfo.v2_0.constellation) !=
mBlacklistedConstellationSet.end()) {
return true;
}
BlacklistedSourceV2_1 source = {.constellation = gnssSvInfo.v2_0.constellation,
.svid = gnssSvInfo.v2_0.v1_0.svid};
return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end());
}
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2016 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.
*/
#define LOG_TAG "GnssDebug"
#include <log/log.h>
#include "Constants.h"
#include "MockLocation.h"
#include "v2_1/GnssDebug.h"
using namespace ::android::hardware::gnss::common;
namespace android::hardware::gnss::V1_1::implementation {
// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
Return<void> GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) {
PositionDebug positionDebug = {
.valid = true,
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
.speedMetersPerSec = gMockSpeedMetersPerSec,
.bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
.bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
.ageSeconds = 0.99};
TimeDebug timeDebug = {.timeEstimate = kMockTimestamp,
.timeUncertaintyNs = 1000,
.frequencyUncertaintyNsPerSec = 5.0e4};
DebugData data = {.position = positionDebug, .time = timeDebug};
_hidl_cb(data);
return Void();
}
} // namespace android::hardware::gnss::V1_1::implementation

View File

@@ -0,0 +1,143 @@
/*
* 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.
*/
#define LOG_TAG "GnssMeasurement"
#include "v2_1/GnssMeasurement.h"
#include <log/log.h>
#include "Utils.h"
namespace android::hardware::gnss::V2_1::implementation {
using common::Utils;
sp<V2_1::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_1 = nullptr;
sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback_2_0 = nullptr;
GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {}
GnssMeasurement::~GnssMeasurement() {
stop();
}
// Methods from V1_0::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
const sp<V1_0::IGnssMeasurementCallback>&) {
// TODO implement
return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
}
Return<void> GnssMeasurement::close() {
ALOGD("close");
stop();
std::unique_lock<std::mutex> lock(mMutex);
sCallback_2_1 = nullptr;
sCallback_2_0 = nullptr;
return Void();
}
// Methods from V1_1::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
const sp<V1_1::IGnssMeasurementCallback>&, bool) {
// TODO implement
return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
}
// Methods from V2_0::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
const sp<V2_0::IGnssMeasurementCallback>& callback, bool) {
ALOGD("setCallback_2_0");
std::unique_lock<std::mutex> lock(mMutex);
sCallback_2_0 = callback;
if (mIsActive) {
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
start();
return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
}
// Methods from V2_1::IGnssMeasurement follow.
Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_1(
const sp<V2_1::IGnssMeasurementCallback>& callback, bool) {
ALOGD("setCallback_2_1");
std::unique_lock<std::mutex> lock(mMutex);
sCallback_2_1 = callback;
if (mIsActive) {
ALOGW("GnssMeasurement callback already set. Resetting the callback...");
stop();
}
start();
return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
}
void GnssMeasurement::start() {
ALOGD("start");
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
if (sCallback_2_1 != nullptr) {
auto measurement = Utils::getMockMeasurementV2_1();
this->reportMeasurement(measurement);
} else {
auto measurement = Utils::getMockMeasurementV2_0();
this->reportMeasurement(measurement);
}
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
}
});
}
void GnssMeasurement::stop() {
ALOGD("stop");
mIsActive = false;
if (mThread.joinable()) {
mThread.join();
}
}
void GnssMeasurement::reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback_2_0 == nullptr) {
ALOGE("%s: GnssMeasurement::sCallback_2_0 is null.", __func__);
return;
}
auto ret = sCallback_2_0->gnssMeasurementCb_2_0(data);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
void GnssMeasurement::reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData& data) {
ALOGD("reportMeasurement()");
std::unique_lock<std::mutex> lock(mMutex);
if (sCallback_2_1 == nullptr) {
ALOGE("%s: GnssMeasurement::sCallback_2_1 is null.", __func__);
return;
}
auto ret = sCallback_2_1->gnssMeasurementCb_2_1(data);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
}
} // namespace android::hardware::gnss::V2_1::implementation

View File

@@ -0,0 +1,103 @@
/*
* 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.
*/
#define LOG_TAG "GnssMeasurementCorrections"
#include "v2_1/GnssMeasurementCorrections.h"
#include <log/log.h>
namespace android::hardware::gnss::measurement_corrections::V1_1::implementation {
GnssMeasurementCorrections::GnssMeasurementCorrections() {}
GnssMeasurementCorrections::~GnssMeasurementCorrections() {}
// Methods from V1_0::IMeasurementCorrections follow.
Return<bool> GnssMeasurementCorrections::setCorrections(
const V1_0::MeasurementCorrections& corrections) {
ALOGD("setCorrections");
ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, "
"satCorrections.size: %d",
corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters,
corrections.horizontalPositionUncertaintyMeters,
corrections.verticalPositionUncertaintyMeters,
static_cast<unsigned long long>(corrections.toaGpsNanosecondsOfWeek),
static_cast<int>(corrections.satCorrections.size()));
for (auto singleSatCorrection : corrections.satCorrections) {
ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d, cfHz: %f, probLos: %f,"
" epl: %f, eplUnc: %f",
static_cast<int>(singleSatCorrection.singleSatCorrectionFlags),
static_cast<int>(singleSatCorrection.constellation),
static_cast<int>(singleSatCorrection.svid), singleSatCorrection.carrierFrequencyHz,
singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters,
singleSatCorrection.excessPathLengthUncertaintyMeters);
ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
singleSatCorrection.reflectingPlane.latitudeDegrees,
singleSatCorrection.reflectingPlane.longitudeDegrees,
singleSatCorrection.reflectingPlane.altitudeMeters,
singleSatCorrection.reflectingPlane.azimuthDegrees);
}
return true;
}
Return<bool> GnssMeasurementCorrections::setCallback(
const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
using Capabilities = V1_0::IMeasurementCorrectionsCallback::Capabilities;
auto ret =
callback->setCapabilitiesCb(Capabilities::LOS_SATS | Capabilities::EXCESS_PATH_LENGTH |
Capabilities::REFLECTING_PLANE);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
return false;
}
return true;
}
// Methods from V1_1::IMeasurementCorrections follow.
Return<bool> GnssMeasurementCorrections::setCorrections_1_1(
const V1_1::MeasurementCorrections& corrections) {
ALOGD("setCorrections_1_1");
ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu,"
"satCorrections.size: %d, hasEnvironmentBearing: %d, environmentBearingDeg: %f,"
"environmentBearingUncDeg: %f",
corrections.v1_0.latitudeDegrees, corrections.v1_0.longitudeDegrees,
corrections.v1_0.altitudeMeters, corrections.v1_0.horizontalPositionUncertaintyMeters,
corrections.v1_0.verticalPositionUncertaintyMeters,
static_cast<unsigned long long>(corrections.v1_0.toaGpsNanosecondsOfWeek),
static_cast<int>(corrections.v1_0.satCorrections.size()),
corrections.hasEnvironmentBearing, corrections.environmentBearingDegrees,
corrections.environmentBearingUncertaintyDegrees);
for (auto singleSatCorrection : corrections.satCorrections) {
ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d, cfHz: %f, probLos: %f,"
" epl: %f, eplUnc: %f",
static_cast<int>(singleSatCorrection.v1_0.singleSatCorrectionFlags),
static_cast<int>(singleSatCorrection.constellation),
static_cast<int>(singleSatCorrection.v1_0.svid),
singleSatCorrection.v1_0.carrierFrequencyHz, singleSatCorrection.v1_0.probSatIsLos,
singleSatCorrection.v1_0.excessPathLengthMeters,
singleSatCorrection.v1_0.excessPathLengthUncertaintyMeters);
ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
singleSatCorrection.v1_0.reflectingPlane.latitudeDegrees,
singleSatCorrection.v1_0.reflectingPlane.longitudeDegrees,
singleSatCorrection.v1_0.reflectingPlane.altitudeMeters,
singleSatCorrection.v1_0.reflectingPlane.azimuthDegrees);
}
return true;
}
} // namespace android::hardware::gnss::measurement_corrections::V1_1::implementation

10
gps/init.redroid.gps.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/vendor/bin/sh
if [ ! -f /data/vendor/gps/gnss ]; then
echo "LatitudeDegrees=30.281026818001678" > /data/vendor/gps/gnss
echo "LongitudeDegrees=120.01934876982831" >> /data/vendor/gps/gnss
echo "AltitudeMeters=1.60062531" >> /data/vendor/gps/gnss
echo "BearingDegrees=0" >> /data/vendor/gps/gnss
echo "SpeedMetersPerSec=0" >> /data/vendor/gps/gnss
chmod 777 /data/vendor/gps/gnss
fi

View File

@@ -1,4 +1,6 @@
# convert legacy props
on late-init
umount /sys/fs/fuse/connections
# overlay data
on early-init && property:ro.kernel.redroid.overlay=1
@@ -45,3 +47,20 @@ on early-init && property:ro.kernel.redroid.gpu.mode=*
on early-init && property:ro.kernel.redroid.gpu.node=*
setprop ro.boot.redroid_gpu_node ${ro.kernel.redroid.gpu.node}
# Battery
on post-fs-data
mkdir /data/vendor/battery 0751 root root
exec -- /system/bin/sh /vendor/bin/hw/init.redroid.battery.sh
# GPS
on post-fs-data
mkdir /data/vendor/gps 0751 root root
exec -- /system/bin/sh /vendor/bin/hw/init.redroid.gps.sh
service gnss /vendor/bin/hw/android.hardware.gnss-service
class hal
user nobody
group nobody

View File

@@ -1,3 +1,6 @@
include vendor/redroid/BoardConfig.mk
# skip androidx.window.extensions check
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
@@ -16,3 +19,49 @@ PRODUCT_COPY_FILES += \
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.touchscreen.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.touchscreen.xml \
######################
# battery config
######################
#
# Power HAL
#
PRODUCT_PACKAGES += \
android.hardware.power-service.example
#
# PowerStats HAL
#
PRODUCT_PACKAGES += \
android.hardware.power.stats-service.example
PRODUCT_COPY_FILES += \
vendor/redroid/battery/init.redroid.battery.sh:$(TARGET_COPY_OUT_VENDOR)/bin/hw/init.redroid.battery.sh \
$(call find-copy-subdir-files,*,vendor/redroid/battery/power_supply,$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/battery/power_supply) \
######################
# gps config
######################
PRODUCT_PACKAGES += \
android.hardware.gnss-service
PRODUCT_COPY_FILES += \
vendor/redroid/gps/init.redroid.gps.sh:$(TARGET_COPY_OUT_VENDOR)/bin/hw/init.redroid.gps.sh \
######################
# gms config
######################
$(call inherit-product-if-exists, vendor/redroid/gapps/arm64/arm64-vendor.mk)
# disable setupwizard
PRODUCT_SYSTEM_EXT_PROPERTIES += \
ro.setupwizard.mode=DISABLED
######################
# zygisk config
######################
$(call inherit-product-if-exists, vendor/magisk/device.mk)