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