1 #define LOG_TAG "Gnss"
2
3 #include "Gnss.h"
4 #include <android/hardware/gnss/1.0/types.h>
5 #include <log/log.h>
6 #include "Constants.h"
7 #include "GnssDebug.h"
8 #include "GnssMeasurement.h"
9 #include "Utils.h"
10
11 namespace android {
12 namespace hardware {
13 namespace gnss {
14 namespace V1_1 {
15 namespace implementation {
16
17 using ::android::hardware::gnss::common::Utils;
18 using GnssSvFlags = IGnssCallback::GnssSvFlags;
19 using namespace ::android::hardware::gnss::common;
20
21 const uint32_t MIN_INTERVAL_MILLIS = 100;
22 sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr;
23
Gnss()24 Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
25
~Gnss()26 Gnss::~Gnss() {
27 stop();
28 }
29
30 // Methods from ::android::hardware::gnss::V1_0::IGnss follow.
setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback> &)31 Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) {
32 // Mock handles only new callback (see setCallback1_1) coming from Android P+
33 return false;
34 }
35
start()36 Return<bool> Gnss::start() {
37 if (mIsActive) {
38 ALOGW("Gnss has started. Restarting...");
39 stop();
40 }
41
42 mIsActive = true;
43 mThread = std::thread([this]() {
44 while (mIsActive == true) {
45 auto svStatus = this->getMockSvStatus();
46 this->reportSvStatus(svStatus);
47
48 auto location = Utils::getMockLocationV1_0();
49 this->reportLocation(location);
50
51 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
52 }
53 });
54
55 return true;
56 }
57
stop()58 Return<bool> Gnss::stop() {
59 mIsActive = false;
60 if (mThread.joinable()) {
61 mThread.join();
62 }
63 return true;
64 }
65
cleanup()66 Return<void> Gnss::cleanup() {
67 // TODO implement
68 return Void();
69 }
70
injectTime(int64_t,int64_t,int32_t)71 Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
72 // TODO implement
73 return bool{};
74 }
75
injectLocation(double,double,float)76 Return<bool> Gnss::injectLocation(double, double, float) {
77 // TODO implement
78 return bool{};
79 }
80
deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData)81 Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) {
82 return Void();
83 }
84
setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,uint32_t,uint32_t,uint32_t)85 Return<bool> Gnss::setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
86 ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,
87 uint32_t, uint32_t, uint32_t) {
88 // TODO implement
89 return bool{};
90 }
91
getExtensionAGnssRil()92 Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
93 // TODO implement
94 return ::android::sp<::android::hardware::gnss::V1_0::IAGnssRil>{};
95 }
96
getExtensionGnssGeofencing()97 Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
98 // TODO implement
99 return ::android::sp<::android::hardware::gnss::V1_0::IGnssGeofencing>{};
100 }
101
getExtensionAGnss()102 Return<sp<::android::hardware::gnss::V1_0::IAGnss>> Gnss::getExtensionAGnss() {
103 // TODO implement
104 return ::android::sp<::android::hardware::gnss::V1_0::IAGnss>{};
105 }
106
getExtensionGnssNi()107 Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
108 // TODO implement
109 return ::android::sp<::android::hardware::gnss::V1_0::IGnssNi>{};
110 }
111
getExtensionGnssMeasurement()112 Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
113 // TODO implement
114 return new GnssMeasurement();
115 }
116
117 Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>>
getExtensionGnssNavigationMessage()118 Gnss::getExtensionGnssNavigationMessage() {
119 // TODO implement
120 return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{};
121 }
122
getExtensionXtra()123 Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
124 // TODO implement
125 return ::android::sp<::android::hardware::gnss::V1_0::IGnssXtra>{};
126 }
127
128 Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>>
getExtensionGnssConfiguration()129 Gnss::getExtensionGnssConfiguration() {
130 // TODO implement
131 return new GnssConfiguration();
132 }
133
getExtensionGnssDebug()134 Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
135 return new GnssDebug();
136 }
137
getExtensionGnssBatching()138 Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
139 // TODO implement
140 return ::android::sp<::android::hardware::gnss::V1_0::IGnssBatching>{};
141 }
142
143 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
setCallback_1_1(const sp<::android::hardware::gnss::V1_1::IGnssCallback> & callback)144 Return<bool> Gnss::setCallback_1_1(
145 const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) {
146 if (callback == nullptr) {
147 ALOGE("%s: Null callback ignored", __func__);
148 return false;
149 }
150
151 sGnssCallback = callback;
152
153 uint32_t capabilities = 0x0;
154 auto ret = sGnssCallback->gnssSetCapabilitesCb(capabilities);
155 if (!ret.isOk()) {
156 ALOGE("%s: Unable to invoke callback", __func__);
157 }
158
159 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
160
161 ret = sGnssCallback->gnssSetSystemInfoCb(gnssInfo);
162 if (!ret.isOk()) {
163 ALOGE("%s: Unable to invoke callback", __func__);
164 }
165
166 auto gnssName = "Google Mock GNSS Implementation v1.1";
167 ret = sGnssCallback->gnssNameCb(gnssName);
168 if (!ret.isOk()) {
169 ALOGE("%s: Unable to invoke callback", __func__);
170 }
171
172 return true;
173 }
174
setPositionMode_1_1(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,uint32_t minIntervalMs,uint32_t,uint32_t,bool)175 Return<bool> Gnss::setPositionMode_1_1(
176 ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
177 ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
178 uint32_t, uint32_t, bool) {
179 mMinIntervalMs = (minIntervalMs < MIN_INTERVAL_MILLIS) ? MIN_INTERVAL_MILLIS : minIntervalMs;
180 return true;
181 }
182
183 Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
getExtensionGnssConfiguration_1_1()184 Gnss::getExtensionGnssConfiguration_1_1() {
185 return mGnssConfiguration;
186 }
187
188 Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>>
getExtensionGnssMeasurement_1_1()189 Gnss::getExtensionGnssMeasurement_1_1() {
190 // TODO implement
191 return new GnssMeasurement();
192 }
193
injectBestLocation(const GnssLocation &)194 Return<bool> Gnss::injectBestLocation(const GnssLocation&) {
195 return true;
196 }
197
getMockSvStatus() const198 Return<GnssSvStatus> Gnss::getMockSvStatus() const {
199 std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
200 GnssSvInfo mockGnssSvInfoList[] = {
201 Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5,
202 kGpsL1FreqHz),
203 Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5, kGpsL1FreqHz),
204 Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0,
205 kGpsL5FreqHz),
206 Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0,
207 kGpsL5FreqHz),
208 Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0,
209 kGloG1FreqHz),
210 Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0,
211 kGloG1FreqHz),
212 Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0,
213 kGloG1FreqHz),
214 Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0,
215 kGloG1FreqHz)};
216
217 GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
218 for (uint32_t i = 0; i < svStatus.numSvs; i++) {
219 if (mGnssConfiguration->isBlacklisted(mockGnssSvInfoList[i])) {
220 /**
221 * Note well, this is a simple, mock emulation of not using a satellite by changing the
222 * used bit. Simply blanking the used bit, as is done here, is *not* an acceptable
223 * actual device implementation - actual devices *must not* use the satellite in the
224 * position calculation, as specified in IGnssConfiguration.hal.
225 */
226 mockGnssSvInfoList[i].svFlag &=
227 ~static_cast<uint8_t>(IGnssCallback::GnssSvFlags::USED_IN_FIX);
228 }
229 svStatus.gnssSvList[i] = mockGnssSvInfoList[i];
230 }
231
232 return svStatus;
233 }
234
reportLocation(const GnssLocation & location) const235 Return<void> Gnss::reportLocation(const GnssLocation& location) const {
236 std::unique_lock<std::mutex> lock(mMutex);
237 if (sGnssCallback == nullptr) {
238 ALOGE("%s: sGnssCallback is null.", __func__);
239 return Void();
240 }
241 sGnssCallback->gnssLocationCb(location);
242 return Void();
243 }
244
reportSvStatus(const GnssSvStatus & svStatus) const245 Return<void> Gnss::reportSvStatus(const GnssSvStatus& svStatus) const {
246 std::unique_lock<std::mutex> lock(mMutex);
247 if (sGnssCallback == nullptr) {
248 ALOGE("%s: sGnssCallback is null.", __func__);
249 return Void();
250 }
251 sGnssCallback->gnssSvStatusCb(svStatus);
252 return Void();
253 }
254
255 } // namespace implementation
256 } // namespace V1_1
257 } // namespace gnss
258 } // namespace hardware
259 } // namespace android
260