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 23 Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {} 24 25 Gnss::~Gnss() { 26 stop(); 27 } 28 29 // Methods from ::android::hardware::gnss::V1_0::IGnss follow. 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 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::getMockLocation(); 48 this->reportLocation(location); 49 50 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); 51 } 52 }); 53 54 return true; 55 } 56 57 Return<bool> Gnss::stop() { 58 mIsActive = false; 59 if (mThread.joinable()) { 60 mThread.join(); 61 } 62 return true; 63 } 64 65 Return<void> Gnss::cleanup() { 66 // TODO implement 67 return Void(); 68 } 69 70 Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) { 71 // TODO implement 72 return bool{}; 73 } 74 75 Return<bool> Gnss::injectLocation(double, double, float) { 76 // TODO implement 77 return bool{}; 78 } 79 80 Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) { 81 return Void(); 82 } 83 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 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 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 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 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 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>> 117 Gnss::getExtensionGnssNavigationMessage() { 118 // TODO implement 119 return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{}; 120 } 121 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>> 128 Gnss::getExtensionGnssConfiguration() { 129 // TODO implement 130 return new GnssConfiguration(); 131 } 132 133 Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() { 134 return new GnssDebug(); 135 } 136 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. 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 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>> 183 Gnss::getExtensionGnssConfiguration_1_1() { 184 return mGnssConfiguration; 185 } 186 187 Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>> 188 Gnss::getExtensionGnssMeasurement_1_1() { 189 // TODO implement 190 return new GnssMeasurement(); 191 } 192 193 Return<bool> Gnss::injectBestLocation(const GnssLocation&) { 194 return true; 195 } 196 197 Return<GnssSvStatus> Gnss::getMockSvStatus() const { 198 std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex()); 199 GnssSvInfo mockGnssSvInfoList[] = { 200 Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5), 201 Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5), 202 Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0), 203 Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0), 204 Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0), 205 Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0), 206 Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0), 207 Utils::getSvInfo(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 227 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 237 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