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