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