• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "GnssAidl"
18 
19 #include "Gnss.h"
20 #include <inttypes.h>
21 #include <log/log.h>
22 #include <utils/Timers.h>
23 #include "AGnss.h"
24 #include "AGnssRil.h"
25 #include "DeviceFileReader.h"
26 #include "FixLocationParser.h"
27 #include "GnssAntennaInfo.h"
28 #include "GnssBatching.h"
29 #include "GnssConfiguration.h"
30 #include "GnssDebug.h"
31 #include "GnssGeofence.h"
32 #include "GnssNavigationMessageInterface.h"
33 #include "GnssPsds.h"
34 #include "GnssVisibilityControl.h"
35 #include "MeasurementCorrectionsInterface.h"
36 #include "Utils.h"
37 
38 namespace aidl::android::hardware::gnss {
39 using ::android::hardware::gnss::common::Utils;
40 
41 using ndk::ScopedAStatus;
42 using GnssSvInfo = IGnssCallback::GnssSvInfo;
43 
44 constexpr int TTFF_MILLIS = 2200;
45 
46 std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
47 
Gnss()48 Gnss::Gnss() : mMinIntervalMs(1000), mFirstFixReceived(false) {}
49 
setCallback(const std::shared_ptr<IGnssCallback> & callback)50 ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
51     ALOGD("setCallback");
52     if (callback == nullptr) {
53         ALOGE("%s: Null callback ignored", __func__);
54         return ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
55     }
56     sGnssCallback = callback;
57 
58     int capabilities =
59             (int)(IGnssCallback::CAPABILITY_MEASUREMENTS | IGnssCallback::CAPABILITY_SCHEDULING |
60                   IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST |
61                   IGnssCallback::CAPABILITY_SATELLITE_PVT |
62                   IGnssCallback::CAPABILITY_CORRELATION_VECTOR |
63                   IGnssCallback::CAPABILITY_ANTENNA_INFO |
64                   IGnssCallback::CAPABILITY_ACCUMULATED_DELTA_RANGE);
65     auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities);
66     if (!status.isOk()) {
67         ALOGE("%s: Unable to invoke callback.gnssSetCapabilitiesCb", __func__);
68     }
69 
70     IGnssCallback::GnssSystemInfo systemInfo = {
71             .yearOfHw = 2022,
72             .name = "Google, Cuttlefish, AIDL v3",
73     };
74     status = sGnssCallback->gnssSetSystemInfoCb(systemInfo);
75     if (!status.isOk()) {
76         ALOGE("%s: Unable to invoke callback.gnssSetSystemInfoCb", __func__);
77     }
78     GnssSignalType signalType1 = {
79             .constellation = GnssConstellationType::GPS,
80             .carrierFrequencyHz = 1.57542e+09,
81             .codeType = GnssSignalType::CODE_TYPE_C,
82     };
83     GnssSignalType signalType2 = {
84             .constellation = GnssConstellationType::GLONASS,
85             .carrierFrequencyHz = 1.5980625e+09,
86             .codeType = GnssSignalType::CODE_TYPE_C,
87     };
88     status = sGnssCallback->gnssSetSignalTypeCapabilitiesCb(
89             std::vector<GnssSignalType>({signalType1, signalType2}));
90     if (!status.isOk()) {
91         ALOGE("%s: Unable to invoke callback.gnssSetSignalTypeCapabilitiesCb", __func__);
92     }
93     return ScopedAStatus::ok();
94 }
95 
getLocationFromHW()96 std::unique_ptr<GnssLocation> Gnss::getLocationFromHW() {
97     if (!::android::hardware::gnss::common::ReplayUtils::hasFixedLocationDeviceFile()) {
98         return nullptr;
99     }
100     std::string inputStr =
101             ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
102     return ::android::hardware::gnss::common::FixLocationParser::getLocationFromInputStr(inputStr);
103 }
104 
start()105 ScopedAStatus Gnss::start() {
106     ALOGD("start()");
107     if (mIsActive) {
108         ALOGW("Gnss has started. Restarting...");
109         stop();
110     }
111 
112     mIsActive = true;
113     mThreadBlocker.reset();
114     // notify measurement engine to update measurement interval
115     mGnssMeasurementInterface->setLocationEnabled(true);
116     this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
117     mThread = std::thread([this]() {
118         if (!mGnssMeasurementEnabled || mMinIntervalMs <= mGnssMeasurementIntervalMs) {
119             this->reportSvStatus();
120         }
121         if (!mFirstFixReceived) {
122             std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
123             mFirstFixReceived = true;
124         }
125         do {
126             if (!mIsActive) {
127                 break;
128             }
129             if (!mGnssMeasurementEnabled || mMinIntervalMs <= mGnssMeasurementIntervalMs) {
130                 this->reportSvStatus();
131             }
132             this->reportNmea();
133 
134             auto currentLocation = getLocationFromHW();
135             mGnssPowerIndication->notePowerConsumption();
136             if (currentLocation != nullptr) {
137                 this->reportLocation(*currentLocation);
138             } else {
139                 const auto location = Utils::getMockLocation();
140                 this->reportLocation(location);
141             }
142         } while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMs)));
143     });
144     return ScopedAStatus::ok();
145 }
146 
stop()147 ScopedAStatus Gnss::stop() {
148     ALOGD("stop");
149     mIsActive = false;
150     mGnssMeasurementInterface->setLocationEnabled(false);
151     this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
152     mThreadBlocker.notify();
153     if (mThread.joinable()) {
154         mThread.join();
155     }
156     return ScopedAStatus::ok();
157 }
158 
close()159 ScopedAStatus Gnss::close() {
160     ALOGD("close");
161     sGnssCallback = nullptr;
162     return ScopedAStatus::ok();
163 }
164 
reportLocation(const GnssLocation & location)165 void Gnss::reportLocation(const GnssLocation& location) {
166     std::unique_lock<std::mutex> lock(mMutex);
167     if (sGnssCallback == nullptr) {
168         ALOGE("%s: GnssCallback is null.", __func__);
169         return;
170     }
171     mLastLocation = std::make_shared<GnssLocation>(location);
172     auto status = sGnssCallback->gnssLocationCb(location);
173     if (!status.isOk()) {
174         ALOGE("%s: Unable to invoke gnssLocationCb", __func__);
175     }
176     return;
177 }
178 
reportSvStatus() const179 void Gnss::reportSvStatus() const {
180     if (mIsSvStatusActive) {
181         auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
182         reportSvStatus(svStatus);
183     }
184 }
185 
reportSvStatus(const std::vector<GnssSvInfo> & svInfoList) const186 void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
187     std::unique_lock<std::mutex> lock(mMutex);
188     if (sGnssCallback == nullptr) {
189         ALOGE("%s: sGnssCallback is null.", __func__);
190         return;
191     }
192     auto status = sGnssCallback->gnssSvStatusCb(svInfoList);
193     if (!status.isOk()) {
194         ALOGE("%s: Unable to invoke callback", __func__);
195     }
196 }
197 
filterBlocklistedSatellites(std::vector<GnssSvInfo> gnssSvInfoList) const198 std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(
199         std::vector<GnssSvInfo> gnssSvInfoList) const {
200     for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
201         if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
202             gnssSvInfoList[i].svFlag &= ~(uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX;
203         }
204     }
205     return gnssSvInfoList;
206 }
207 
reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const208 void Gnss::reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const {
209     std::unique_lock<std::mutex> lock(mMutex);
210     if (sGnssCallback == nullptr) {
211         ALOGE("%s: sGnssCallback is null.", __func__);
212         return;
213     }
214     auto status = sGnssCallback->gnssStatusCb(gnssStatusValue);
215     if (!status.isOk()) {
216         ALOGE("%s: Unable to invoke gnssStatusCb", __func__);
217     }
218 }
219 
reportNmea() const220 void Gnss::reportNmea() const {
221     if (mIsNmeaActive) {
222         std::unique_lock<std::mutex> lock(mMutex);
223         if (sGnssCallback == nullptr) {
224             ALOGE("%s: sGnssCallback is null.", __func__);
225             return;
226         }
227         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
228         auto status = sGnssCallback->gnssNmeaCb(now, "$TEST,0,1,2,3,4,5");
229         if (!status.isOk()) {
230             ALOGE("%s: Unable to invoke callback", __func__);
231         }
232     }
233 }
234 
startSvStatus()235 ScopedAStatus Gnss::startSvStatus() {
236     ALOGD("startSvStatus");
237     mIsSvStatusActive = true;
238     return ScopedAStatus::ok();
239 }
240 
stopSvStatus()241 ScopedAStatus Gnss::stopSvStatus() {
242     ALOGD("stopSvStatus");
243     mIsSvStatusActive = false;
244     return ScopedAStatus::ok();
245 }
startNmea()246 ScopedAStatus Gnss::startNmea() {
247     ALOGD("startNmea");
248     mIsNmeaActive = true;
249     return ScopedAStatus::ok();
250 }
stopNmea()251 ScopedAStatus Gnss::stopNmea() {
252     ALOGD("stopNmea");
253     mIsNmeaActive = false;
254     return ScopedAStatus::ok();
255 }
256 
getExtensionAGnss(std::shared_ptr<IAGnss> * iAGnss)257 ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
258     ALOGD("Gnss::getExtensionAGnss");
259     *iAGnss = SharedRefBase::make<AGnss>();
260     return ndk::ScopedAStatus::ok();
261 }
262 
injectTime(int64_t timeMs,int64_t timeReferenceMs,int uncertaintyMs)263 ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int uncertaintyMs) {
264     ALOGD("injectTime. timeMs:%" PRId64 ", timeReferenceMs:%" PRId64 ", uncertaintyMs:%d", timeMs,
265           timeReferenceMs, uncertaintyMs);
266     return ScopedAStatus::ok();
267 }
268 
getExtensionAGnssRil(std::shared_ptr<IAGnssRil> * iAGnssRil)269 ScopedAStatus Gnss::getExtensionAGnssRil(std::shared_ptr<IAGnssRil>* iAGnssRil) {
270     ALOGD("Gnss::getExtensionAGnssRil");
271     *iAGnssRil = SharedRefBase::make<AGnssRil>();
272     return ndk::ScopedAStatus::ok();
273 }
274 
injectLocation(const GnssLocation & location)275 ScopedAStatus Gnss::injectLocation(const GnssLocation& location) {
276     ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
277           location.longitudeDegrees, location.horizontalAccuracyMeters);
278     return ScopedAStatus::ok();
279 }
280 
injectBestLocation(const GnssLocation & location)281 ScopedAStatus Gnss::injectBestLocation(const GnssLocation& location) {
282     ALOGD("injectBestLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
283           location.longitudeDegrees, location.horizontalAccuracyMeters);
284     return ScopedAStatus::ok();
285 }
286 
deleteAidingData(GnssAidingData aidingDataFlags)287 ScopedAStatus Gnss::deleteAidingData(GnssAidingData aidingDataFlags) {
288     ALOGD("deleteAidingData. flags:%d", (int)aidingDataFlags);
289     mFirstFixReceived = false;
290     return ScopedAStatus::ok();
291 }
292 
setPositionMode(const PositionModeOptions & options)293 ScopedAStatus Gnss::setPositionMode(const PositionModeOptions& options) {
294     ALOGD("setPositionMode. minIntervalMs:%d, lowPowerMode:%d", options.minIntervalMs,
295           (int)options.lowPowerMode);
296     mMinIntervalMs = std::max(1000, options.minIntervalMs);
297     mGnssMeasurementInterface->setLocationInterval(mMinIntervalMs);
298     return ScopedAStatus::ok();
299 }
300 
getExtensionPsds(std::shared_ptr<IGnssPsds> * iGnssPsds)301 ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
302     ALOGD("getExtensionPsds");
303     *iGnssPsds = SharedRefBase::make<GnssPsds>();
304     return ScopedAStatus::ok();
305 }
306 
getExtensionGnssConfiguration(std::shared_ptr<IGnssConfiguration> * iGnssConfiguration)307 ScopedAStatus Gnss::getExtensionGnssConfiguration(
308         std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
309     ALOGD("getExtensionGnssConfiguration");
310     if (mGnssConfiguration == nullptr) {
311         mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
312     }
313     *iGnssConfiguration = mGnssConfiguration;
314     return ScopedAStatus::ok();
315 }
316 
getExtensionGnssPowerIndication(std::shared_ptr<IGnssPowerIndication> * iGnssPowerIndication)317 ScopedAStatus Gnss::getExtensionGnssPowerIndication(
318         std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
319     ALOGD("getExtensionGnssPowerIndication");
320     if (mGnssPowerIndication == nullptr) {
321         mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
322     }
323 
324     *iGnssPowerIndication = mGnssPowerIndication;
325     return ScopedAStatus::ok();
326 }
327 
getExtensionGnssMeasurement(std::shared_ptr<IGnssMeasurementInterface> * iGnssMeasurement)328 ScopedAStatus Gnss::getExtensionGnssMeasurement(
329         std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
330     ALOGD("getExtensionGnssMeasurement");
331     if (mGnssMeasurementInterface == nullptr) {
332         mGnssMeasurementInterface = SharedRefBase::make<GnssMeasurementInterface>();
333         mGnssMeasurementInterface->setGnssInterface(static_cast<std::shared_ptr<Gnss>>(this));
334     }
335     *iGnssMeasurement = mGnssMeasurementInterface;
336     return ScopedAStatus::ok();
337 }
338 
getExtensionGnssBatching(std::shared_ptr<IGnssBatching> * iGnssBatching)339 ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
340     ALOGD("getExtensionGnssBatching");
341 
342     *iGnssBatching = SharedRefBase::make<GnssBatching>();
343     return ScopedAStatus::ok();
344 }
345 
getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence> * iGnssGeofence)346 ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
347     ALOGD("getExtensionGnssGeofence");
348 
349     *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
350     return ScopedAStatus::ok();
351 }
352 
getExtensionGnssNavigationMessage(std::shared_ptr<IGnssNavigationMessageInterface> * iGnssNavigationMessage)353 ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
354         std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
355     ALOGD("getExtensionGnssNavigationMessage");
356 
357     *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
358     return ScopedAStatus::ok();
359 }
360 
getExtensionGnssDebug(std::shared_ptr<IGnssDebug> * iGnssDebug)361 ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
362     ALOGD("Gnss::getExtensionGnssDebug");
363     *iGnssDebug = SharedRefBase::make<GnssDebug>();
364     return ndk::ScopedAStatus::ok();
365 }
366 
getExtensionGnssVisibilityControl(std::shared_ptr<visibility_control::IGnssVisibilityControl> * iGnssVisibilityControl)367 ndk::ScopedAStatus Gnss::getExtensionGnssVisibilityControl(
368         std::shared_ptr<visibility_control::IGnssVisibilityControl>* iGnssVisibilityControl) {
369     ALOGD("Gnss::getExtensionGnssVisibilityControl");
370 
371     *iGnssVisibilityControl = SharedRefBase::make<visibility_control::GnssVisibilityControl>();
372     return ndk::ScopedAStatus::ok();
373 }
374 
getExtensionGnssAntennaInfo(std::shared_ptr<IGnssAntennaInfo> * iGnssAntennaInfo)375 ndk::ScopedAStatus Gnss::getExtensionGnssAntennaInfo(
376         std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) {
377     ALOGD("Gnss::getExtensionGnssAntennaInfo");
378 
379     *iGnssAntennaInfo = SharedRefBase::make<GnssAntennaInfo>();
380     return ndk::ScopedAStatus::ok();
381 }
382 
getExtensionMeasurementCorrections(std::shared_ptr<measurement_corrections::IMeasurementCorrectionsInterface> * iMeasurementCorrections)383 ndk::ScopedAStatus Gnss::getExtensionMeasurementCorrections(
384         std::shared_ptr<measurement_corrections::IMeasurementCorrectionsInterface>*
385                 iMeasurementCorrections) {
386     ALOGD("Gnss::getExtensionMeasurementCorrections");
387 
388     *iMeasurementCorrections =
389             SharedRefBase::make<measurement_corrections::MeasurementCorrectionsInterface>();
390     return ndk::ScopedAStatus::ok();
391 }
392 
setGnssMeasurementEnabled(const bool enabled)393 void Gnss::setGnssMeasurementEnabled(const bool enabled) {
394     mGnssMeasurementEnabled = enabled;
395 }
396 
setGnssMeasurementInterval(const long intervalMs)397 void Gnss::setGnssMeasurementInterval(const long intervalMs) {
398     mGnssMeasurementIntervalMs = intervalMs;
399 }
400 
getLastLocation() const401 std::shared_ptr<GnssLocation> Gnss::getLastLocation() const {
402     return mLastLocation;
403 }
404 
405 }  // namespace aidl::android::hardware::gnss
406