1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <log/log.h>
18 #include <debug.h>
19
20 #include "Agnss.h"
21 #include "AgnssRil.h"
22 #include "GnssAntennaInfo.h"
23 #include "GnssBatching.h"
24 #include "GnssDebug.h"
25 #include "GnssGeofence.h"
26 #include "GnssMeasurementInterface.h"
27 #include "GnssNavigationMessageInterface.h"
28 #include "GnssPowerIndication.h"
29 #include "GnssPsds.h"
30 #include "GnssVisibilityControl.h"
31 #include "Gnss.h"
32 #include "MeasurementCorrectionsInterface.h"
33
34 namespace aidl {
35 namespace android {
36 namespace hardware {
37 namespace gnss {
38 namespace implementation {
39 namespace {
40 constexpr char kGnssDeviceName[] = "Android Studio Emulator GPS";
41 } // namespace
42
Gnss()43 Gnss::Gnss()
44 : mGnssBatching(ndk::SharedRefBase::make<GnssBatching>())
45 , mGnssConfiguration(ndk::SharedRefBase::make<GnssConfiguration>()) {
46 }
47
~Gnss()48 Gnss::~Gnss() {
49 }
50
setCallback(const std::shared_ptr<IGnssCallback> & callback)51 ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
52 if (callback == nullptr) {
53 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_INVALID_ARGUMENT));
54 }
55
56 callback->gnssSetCapabilitiesCb(IGnssCallback::CAPABILITY_MEASUREMENTS |
57 IGnssCallback::CAPABILITY_SCHEDULING);
58
59 callback->gnssSetSystemInfoCb({.yearOfHw = 2023, .name = kGnssDeviceName});
60
61 std::lock_guard<std::mutex> lock(mMtx);
62 mCallback = callback;
63
64 return ndk::ScopedAStatus::ok();
65 }
66
close()67 ndk::ScopedAStatus Gnss::close() {
68 mGnssHwConn.reset();
69
70 std::lock_guard<std::mutex> lock(mMtx);
71 mCallback.reset();
72
73 return ndk::ScopedAStatus::ok();
74 }
75
getExtensionPsds(std::shared_ptr<IGnssPsds> * iGnssPsds)76 ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
77 *iGnssPsds = ndk::SharedRefBase::make<GnssPsds>();
78 return ndk::ScopedAStatus::ok();
79 }
80
getExtensionGnssConfiguration(std::shared_ptr<IGnssConfiguration> * iGnssConfiguration)81 ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
82 std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
83 *iGnssConfiguration = mGnssConfiguration;
84 return ndk::ScopedAStatus::ok();
85 }
86
getExtensionGnssMeasurement(std::shared_ptr<IGnssMeasurementInterface> * iGnssMeasurement)87 ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
88 std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
89 *iGnssMeasurement = ndk::SharedRefBase::make<GnssMeasurementInterface>();
90 return ndk::ScopedAStatus::ok();
91 }
92
getExtensionGnssPowerIndication(std::shared_ptr<IGnssPowerIndication> * iGnssPowerIndication)93 ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
94 std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
95 *iGnssPowerIndication = ndk::SharedRefBase::make<GnssPowerIndication>(
96 std::bind(&Gnss::getRunningTime, this));
97 return ndk::ScopedAStatus::ok();
98 }
99
getExtensionGnssBatching(std::shared_ptr<IGnssBatching> * iGnssBatching)100 ndk::ScopedAStatus Gnss::getExtensionGnssBatching(
101 std::shared_ptr<IGnssBatching>* iGnssBatching) {
102 *iGnssBatching = mGnssBatching;
103 return ndk::ScopedAStatus::ok();
104 }
105
getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence> * iGnssGeofence)106 ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(
107 std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
108 *iGnssGeofence = ndk::SharedRefBase::make<GnssGeofence>();
109 return ndk::ScopedAStatus::ok();
110 }
111
getExtensionGnssNavigationMessage(std::shared_ptr<IGnssNavigationMessageInterface> * iGnssNavigationMessage)112 ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
113 std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
114 *iGnssNavigationMessage = ndk::SharedRefBase::make<GnssNavigationMessageInterface>();
115 return ndk::ScopedAStatus::ok();
116 }
117
getExtensionAGnss(std::shared_ptr<IAGnss> * iAGnss)118 ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
119 *iAGnss = ndk::SharedRefBase::make<AGnss>();
120 return ndk::ScopedAStatus::ok();
121 }
122
getExtensionAGnssRil(std::shared_ptr<IAGnssRil> * iAGnssRil)123 ndk::ScopedAStatus Gnss::getExtensionAGnssRil(std::shared_ptr<IAGnssRil>* iAGnssRil) {
124 *iAGnssRil = ndk::SharedRefBase::make<AGnssRil>();
125 return ndk::ScopedAStatus::ok();
126 }
127
getExtensionGnssDebug(std::shared_ptr<IGnssDebug> * iGnssDebug)128 ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
129 *iGnssDebug = ndk::SharedRefBase::make<GnssDebug>();
130 return ndk::ScopedAStatus::ok();
131 }
132
getExtensionGnssVisibilityControl(std::shared_ptr<IGnssVisibilityControl> * iGnssVisibilityControl)133 ndk::ScopedAStatus Gnss::getExtensionGnssVisibilityControl(
134 std::shared_ptr<IGnssVisibilityControl>* iGnssVisibilityControl) {
135 *iGnssVisibilityControl = ndk::SharedRefBase::make<GnssVisibilityControl>();
136 return ndk::ScopedAStatus::ok();
137 }
138
start()139 ndk::ScopedAStatus Gnss::start() {
140 {
141 std::lock_guard<std::mutex> lock(mMtx);
142 if (!mCallback) {
143 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_INVALID_ARGUMENT));
144 }
145 }
146
147 if (!mGnssHwConn) {
148 auto conn = std::make_unique<GnssHwConn>(*this);
149 if (!conn->ok()) {
150 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_GENERIC));
151 }
152
153 std::lock_guard<std::mutex> lock(mMtx);
154 mSessionState = SessionState::STARTING;
155 mStartT = std::chrono::steady_clock::now();
156 mGnssHwConn = std::move(conn);
157 }
158
159 return ndk::ScopedAStatus::ok();
160 }
161
stop()162 ndk::ScopedAStatus Gnss::stop() {
163 if (!mGnssHwConn) {
164 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_INVALID_ARGUMENT));
165 }
166
167 {
168 std::lock_guard<std::mutex> lock(mMtx);
169 if (mCallback) {
170 if (mSessionState == SessionState::STARTED) {
171 mCallback->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
172 mSessionState = SessionState::STOPPED;
173 }
174 } else {
175 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_INVALID_ARGUMENT));
176 }
177 }
178
179 mGnssHwConn.reset();
180
181 return ndk::ScopedAStatus::ok();
182 }
183
injectTime(int64_t,int64_t,int)184 ndk::ScopedAStatus Gnss::injectTime(int64_t /*timeMs*/,
185 int64_t /*timeReferenceMs*/,
186 int /*uncertaintyMs*/) {
187 return ndk::ScopedAStatus::ok();
188 }
189
injectLocation(const GnssLocation &)190 ndk::ScopedAStatus Gnss::injectLocation(const GnssLocation& /*location*/) {
191 return ndk::ScopedAStatus::ok();
192 }
193
injectBestLocation(const GnssLocation &)194 ndk::ScopedAStatus Gnss::injectBestLocation(const GnssLocation& /*location*/) {
195 return ndk::ScopedAStatus::ok();
196 }
197
deleteAidingData(const GnssAidingData)198 ndk::ScopedAStatus Gnss::deleteAidingData(const GnssAidingData /*aidingDataFlags*/) {
199 return ndk::ScopedAStatus::ok();
200 }
201
setPositionMode(const PositionModeOptions & options)202 ndk::ScopedAStatus Gnss::setPositionMode(const PositionModeOptions& options) {
203 if (options.minIntervalMs < 0) {
204 return ndk::ScopedAStatus::fromExceptionCode(FAILURE(IGnss::ERROR_INVALID_ARGUMENT));
205 }
206
207 std::lock_guard<std::mutex> lock(mMtx);
208
209 mRecurrence = options.recurrence ==
210 (IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC) ? -1 : 1;
211 mMinInterval = std::chrono::milliseconds(options.minIntervalMs);
212 mFirstFix = Clock::now();
213 mLastFix = mFirstFix - mMinInterval;
214 mLowPowerMode = options.lowPowerMode;
215
216 return ndk::ScopedAStatus::ok();
217 }
218
getExtensionGnssAntennaInfo(std::shared_ptr<IGnssAntennaInfo> * iGnssAntennaInfo)219 ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo(
220 std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) {
221 *iGnssAntennaInfo = ndk::SharedRefBase::make<GnssAntennaInfo>();
222 return ndk::ScopedAStatus::ok();
223 }
224
getExtensionMeasurementCorrections(std::shared_ptr<IMeasurementCorrectionsInterface> * iMeasurementCorrections)225 ndk::ScopedAStatus Gnss::getExtensionMeasurementCorrections(
226 std::shared_ptr<IMeasurementCorrectionsInterface>* iMeasurementCorrections) {
227 *iMeasurementCorrections = ndk::SharedRefBase::make<MeasurementCorrectionsInterface>();
228 return ndk::ScopedAStatus::ok();
229 }
230
startSvStatus()231 ndk::ScopedAStatus Gnss::startSvStatus() {
232 std::lock_guard<std::mutex> lock(mMtx);
233 mSendSvStatus = true;
234 return ndk::ScopedAStatus::ok();
235 }
236
stopSvStatus()237 ndk::ScopedAStatus Gnss::stopSvStatus() {
238 std::lock_guard<std::mutex> lock(mMtx);
239 mSendSvStatus = false;
240 return ndk::ScopedAStatus::ok();
241 }
242
startNmea()243 ndk::ScopedAStatus Gnss::startNmea() {
244 std::lock_guard<std::mutex> lock(mMtx);
245 mSendNmea = true;
246 return ndk::ScopedAStatus::ok();
247 }
248
stopNmea()249 ndk::ScopedAStatus Gnss::stopNmea() {
250 std::lock_guard<std::mutex> lock(mMtx);
251 mSendNmea = false;
252 return ndk::ScopedAStatus::ok();
253 }
254
onGnssStatusCb(const IGnssCallback::GnssStatusValue status)255 void Gnss::onGnssStatusCb(const IGnssCallback::GnssStatusValue status) {
256 std::lock_guard<std::mutex> lock(mMtx);
257 if (mCallback) {
258 mCallback->gnssStatusCb(status);
259 }
260 }
261
onGnssSvStatusCb(std::vector<IGnssCallback::GnssSvInfo> svInfo)262 void Gnss::onGnssSvStatusCb(std::vector<IGnssCallback::GnssSvInfo> svInfo) {
263 std::lock_guard<std::mutex> lock(mMtx);
264 if (!mCallback || !mSendSvStatus) {
265 return;
266 }
267
268 switch (mSessionState) {
269 case SessionState::STARTING:
270 mCallback->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
271 mSessionState = SessionState::STARTED;
272 break;
273
274 case SessionState::STARTED:
275 break; // do nothing
276
277 default:
278 return;
279 }
280
281 mCallback->gnssSvStatusCb(std::move(svInfo));
282 }
283
onGnssNmeaCb(const int64_t timestampMs,std::string nmea)284 void Gnss::onGnssNmeaCb(const int64_t timestampMs, std::string nmea) {
285 std::lock_guard<std::mutex> lock(mMtx);
286 if (!mCallback || !mSendNmea) {
287 return;
288 }
289
290 if (!isWarmedUpLocked(Clock::now())) {
291 return;
292 }
293
294 switch (mSessionState) {
295 case SessionState::STARTING:
296 mCallback->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
297 mSessionState = SessionState::STARTED;
298 break;
299
300 case SessionState::STARTED:
301 break; // do nothing
302
303 default:
304 return;
305 }
306
307 mCallback->gnssNmeaCb(timestampMs, std::move(nmea));
308 }
309
onGnssLocationCb(GnssLocation location)310 void Gnss::onGnssLocationCb(GnssLocation location) {
311 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
312
313 std::lock_guard<std::mutex> lock(mMtx);
314 if (!mCallback) {
315 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
316 return;
317 }
318
319 const auto now = Clock::now();
320 if (!isWarmedUpLocked(now) || (now < mFirstFix) || (now < (mLastFix + mMinInterval))) {
321 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
322 return;
323 }
324
325 switch (mSessionState) {
326 case SessionState::STARTING:
327 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
328 mCallback->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
329 mSessionState = SessionState::STARTED;
330 break;
331
332 case SessionState::STARTED:
333 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
334 break; // do nothing
335
336 default:
337 ALOGD("%s:%s:%d", "Gnss", __func__, __LINE__);
338 return;
339 }
340
341 if (mRecurrence == 0) {
342 return;
343 } else if (mRecurrence > 0) {
344 --mRecurrence;
345 }
346
347 mLastFix = now;
348 mCallback->gnssLocationCb(location);
349 mGnssBatching->onGnssLocationCb(std::move(location));
350 }
351
getRunningTime() const352 double Gnss::getRunningTime() const {
353 std::lock_guard<std::mutex> lock(mMtx);
354 return getRunningTimeLocked(Clock::now());
355 }
356
getRunningTimeLocked(const Clock::time_point now) const357 double Gnss::getRunningTimeLocked(const Clock::time_point now) const {
358 if (mStartT.has_value()) {
359 return std::chrono::duration<double>(now - mStartT.value()).count();
360 } else {
361 return 0.0;
362 }
363 }
364
isWarmedUpLocked(const Clock::time_point now) const365 bool Gnss::isWarmedUpLocked(const Clock::time_point now) const {
366 return getRunningTimeLocked(now) >= 3.5; // CTS requires warming up time
367 }
368
369 } // namespace implementation
370 } // namespace gnss
371 } // namespace hardware
372 } // namespace android
373 } // namespace aidl
374