Home | History | Annotate | Download | only in default
      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