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