GNSS HIDL 2.0 updates

Implement new GNSS HIDL 2.0 functions and callbacks
gnssRequestLocationCb_2_0, getExtensionGnssBatching_2_0,
getExtensionGnssDebug_2_0, getDebugData_2_0,
injectBestLocation_2_0, gnssSetCapabilitiesCb_2_0,
gnssLocationCb_2_0, gnssSvStatusCb_2_0, and
gnssMeasurementCb_2_0.
Fix VTS test failures from deprecated functions
setGpsLock, setSuplEs, V1:0::getExtensionAGnss, and
V1.0::getExtensionGnssNi

CRs-fixed: 2433957
Change-Id: Id10cb41c32d6c50144b0501eb2d2eaf9c9a9aaec
diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp
index 1021938..0390af7 100644
--- a/android/2.0/Gnss.cpp
+++ b/android/2.0/Gnss.cpp
@@ -81,7 +81,6 @@
     LOC_LOGE("%s] service died. cookie: %llu, who: %p",
             __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
     if (mGnss != nullptr) {
-        mGnss->stop();
         mGnss->cleanup();
     }
 }
@@ -102,26 +101,31 @@
 }
 
 GnssAPIClient* Gnss::getApi() {
-    if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
-        mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
-        if (mApi == nullptr) {
-            LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
-            return mApi;
-        }
+    if (mApi != nullptr) {
+        return mApi;
+    }
 
-        if (mPendingConfig.size == sizeof(GnssConfig)) {
-            // we have pending GnssConfig
-            mApi->gnssConfigurationUpdate(mPendingConfig);
-            // clear size to invalid mPendingConfig
-            mPendingConfig.size = 0;
-            if (mPendingConfig.assistanceServer.hostName != nullptr) {
-                free((void*)mPendingConfig.assistanceServer.hostName);
-            }
+    if (mGnssCbIface_2_0 != nullptr) {
+        mApi = new GnssAPIClient(mGnssCbIface_2_0);
+    } else if (mGnssCbIface_1_1 != nullptr) {
+        mApi = new GnssAPIClient(mGnssCbIface_1_1, mGnssNiCbIface);
+    } else if (mGnssCbIface != nullptr) {
+        mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
+    } else {
+        LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
+        return mApi;
+    }
+
+    if (mPendingConfig.size == sizeof(GnssConfig)) {
+        // we have pending GnssConfig
+        mApi->gnssConfigurationUpdate(mPendingConfig);
+        // clear size to invalid mPendingConfig
+        mPendingConfig.size = 0;
+        if (mPendingConfig.assistanceServer.hostName != nullptr) {
+            free((void*)mPendingConfig.assistanceServer.hostName);
         }
     }
-    if (mApi == nullptr) {
-        LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
-    }
+
     return mApi;
 }
 
@@ -273,7 +277,23 @@
     ENTRY_LOG_CALLFLOW();
 
     if (mApi != nullptr) {
+        mApi->gnssStop();
         mApi->gnssDisable();
+        mApi->gnssUpdateCallbacks(nullptr, nullptr);
+        mApi->gnssUpdateCallbacks_2_0(nullptr);
+    }
+    mGnssNiCbIface = nullptr;
+    if (mGnssCbIface != nullptr) {
+        mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+        mGnssCbIface = nullptr;
+    }
+    if (mGnssCbIface_1_1 != nullptr) {
+        mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+        mGnssCbIface_1_1 = nullptr;
+    }
+    if (mGnssCbIface_2_0 != nullptr) {
+        mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+        mGnssCbIface_2_0 = nullptr;
     }
 
     return Void();
@@ -330,15 +350,14 @@
 
 Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss()  {
     ENTRY_LOG_CALLFLOW();
-    //mAGnssIface = new ::android::hardware::gnss::V1_1::implementation::AGnss(this); //need V1_1 AGnss
-    //return mAGnssIface;
+    // deprecated function. Must return nullptr to pass VTS
     return nullptr;
 }
 
 Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
     ENTRY_LOG_CALLFLOW();
-    mGnssNi = new GnssNi(this);
-    return mGnssNi;
+    // deprecated function. Must return nullptr to pass VTS
+    return nullptr;
 }
 
 Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
@@ -381,8 +400,19 @@
 // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
 Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
     ENTRY_LOG_CALLFLOW();
-    callback->gnssNameCb(getVersionString());
+    auto r = callback->gnssNameCb(getVersionString());
+    if (!r.isOk()) {
+        LOC_LOGE("%s] Error from gnssNameCb description=%s",
+                __func__, r.description().c_str());
+    }
+    if (mGnssCbIface_1_1 != nullptr) {
+        mGnssCbIface_1_1->unlinkToDeath(mGnssDeathRecipient);
+    }
     mGnssCbIface_1_1 = callback;
+    if (mGnssCbIface_1_1 != nullptr) {
+        mGnssCbIface_1_1->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+    }
+
     const GnssInterface* gnssInterface = getGnssInterface();
     if (nullptr != gnssInterface) {
         OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
@@ -390,7 +420,15 @@
         };
         gnssInterface->odcpiInit(cb);
     }
-    return setCallback(callback);
+
+    GnssAPIClient* api = getApi();
+    if (api != nullptr) {
+        api->gnssUpdateCallbacks(mGnssCbIface_1_1, mGnssNiCbIface);
+        api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+        api->requestCapabilities();
+    }
+
+    return true;
 }
 
 Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
@@ -442,7 +480,20 @@
 
 void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
     ENTRY_LOG_CALLFLOW();
-    if (mGnssCbIface_1_1 != nullptr) {
+
+    if (mGnssCbIface_2_0 != nullptr) {
+        // For emergency mode, request DBH (Device based hybrid) location
+        // Mark Independent from GNSS flag to false.
+        if (ODCPI_REQUEST_TYPE_START == request.type) {
+            auto r = mGnssCbIface_2_0->gnssRequestLocationCb_2_0(!request.isEmergencyMode,
+                                                                 request.isEmergencyMode);
+            if (!r.isOk()) {
+                LOC_LOGe("Error invoking gnssRequestLocationCb_2_0 %s", r.description().c_str());
+            }
+        } else {
+            LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+        }
+    } else if (mGnssCbIface_1_1 != nullptr) {
         // For emergency mode, request DBH (Device based hybrid) location
         // Mark Independent from GNSS flag to false.
         if (ODCPI_REQUEST_TYPE_START == request.type) {
@@ -461,8 +512,37 @@
 // Methods from ::android::hardware::gnss::V2_0::IGnss follow.
 Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
     ENTRY_LOG_CALLFLOW();
-    return setCallback_1_1(callback);
+    auto r = callback->gnssNameCb(getVersionString());
+    if (!r.isOk()) {
+        LOC_LOGE("%s] Error from gnssNameCb description=%s",
+                __func__, r.description().c_str());
+    }
+    if (mGnssCbIface_2_0 != nullptr) {
+        mGnssCbIface_2_0->unlinkToDeath(mGnssDeathRecipient);
+    }
+    mGnssCbIface_2_0 = callback;
+    if (mGnssCbIface_2_0 != nullptr) {
+        mGnssCbIface_2_0->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+    }
+
+    const GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+            odcpiRequestCb(odcpiRequest);
+        };
+        gnssInterface->odcpiInit(cb);
+    }
+
+    GnssAPIClient* api = getApi();
+    if (api != nullptr) {
+        api->gnssUpdateCallbacks_2_0(mGnssCbIface_2_0);
+        api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+        api->requestCapabilities();
+    }
+
+    return true;
 }
+
 Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
     ENTRY_LOG_CALLFLOW();
     mAGnssIface_2_0 = new AGnss(this);
@@ -490,10 +570,8 @@
 }
 Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
         Gnss::getExtensionMeasurementCorrections() {
-    if (mGnssMeasCorr == nullptr) {
-        mGnssMeasCorr = new MeasurementCorrections();
-    }
-    return mGnssMeasCorr;
+    // We do not support, so return nullptr to pass VTS
+    return nullptr;
 }
 Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
         Gnss::getExtensionVisibilityControl() {
@@ -504,21 +582,27 @@
     return mVisibCtrl;
 }
 
-Return<bool> Gnss::injectBestLocation_2_0(
-    const ::android::hardware::gnss::V2_0::GnssLocation& location) {
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation& gnssLocation) {
     ENTRY_LOG_CALLFLOW();
-    /* TBD */
-    return false;
-}
-
-Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0()  {
-    ENTRY_LOG_CALLFLOW();
-    return nullptr;
+    const GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        Location location = {};
+        convertGnssLocation(gnssLocation, location);
+        gnssInterface->odcpiInject(location);
+    }
+    return true;
 }
 
 Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
     ENTRY_LOG_CALLFLOW();
-    return nullptr;
+    mGnssDebug = new GnssDebug(this);
+    return mGnssDebug;
+}
+
+Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
+    ENTRY_LOG_CALLFLOW();
+    mGnssBatching = new GnssBatching();
+    return mGnssBatching;
 }
 
 V1_0::IGnss* HIDL_FETCH_IGnss(const char* hal) {
diff --git a/android/2.0/Gnss.h b/android/2.0/Gnss.h
index df62901..a403d61 100644
--- a/android/2.0/Gnss.h
+++ b/android/2.0/Gnss.h
@@ -142,6 +142,7 @@
 
     // Callback for ODCPI request
     void odcpiRequestCb(const OdcpiRequestInfo& request);
+
  private:
     struct GnssDeathRecipient : hidl_death_recipient {
         GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
@@ -156,8 +157,6 @@
 
     sp<V1_0::IGnssNi> mGnssNi = nullptr;
     sp<V1_0::IGnssGeofencing> mGnssGeofencingIface = nullptr;
-    sp<V1_0::IGnssBatching> mGnssBatching = nullptr;
-    sp<V1_0::IGnssDebug> mGnssDebug = nullptr;
     sp<V1_0::IAGnss> mAGnssIface = nullptr;
     sp<V1_0::IGnssCallback> mGnssCbIface = nullptr;
     sp<V1_0::IGnssNiCallback> mGnssNiCbIface = nullptr;
@@ -166,6 +165,9 @@
     sp<V2_0::IAGnssRil> mGnssRil = nullptr;
     sp<V2_0::IGnssMeasurement> mGnssMeasurement = nullptr;
     sp<V2_0::IGnssConfiguration> mGnssConfig = nullptr;
+    sp<V2_0::IGnssBatching> mGnssBatching = nullptr;
+    sp<V2_0::IGnssDebug> mGnssDebug = nullptr;
+    sp<V2_0::IGnssCallback> mGnssCbIface_2_0 = nullptr;
     sp<IMeasurementCorrections> mGnssMeasCorr = nullptr;
     sp<IGnssVisibilityControl> mVisibCtrl = nullptr;
 
diff --git a/android/2.0/GnssBatching.cpp b/android/2.0/GnssBatching.cpp
index cf215ea..7a937fc 100644
--- a/android/2.0/GnssBatching.cpp
+++ b/android/2.0/GnssBatching.cpp
@@ -53,7 +53,7 @@
 
 
 // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
-Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
+Return<bool> GnssBatching::init(const sp<V1_0::IGnssBatchingCallback>& callback) {
     if (mApi != nullptr) {
         LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
         delete mApi;
@@ -117,12 +117,45 @@
 }
 
 Return<void> GnssBatching::cleanup() {
+    if (mApi != nullptr) {
+        mApi->stopSession();
+    }
     if (mGnssBatchingCbIface != nullptr) {
         mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+        mGnssBatchingCbIface = nullptr;
+    }
+    if (mGnssBatchingCbIface_2_0 != nullptr) {
+        mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+        mGnssBatchingCbIface_2_0 = nullptr;
     }
     return Void();
 }
 
+// Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+Return<bool> GnssBatching::init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) {
+    if (mApi != nullptr) {
+        LOC_LOGD("%s]: mApi is NOT nullptr, delete it first", __FUNCTION__);
+        delete mApi;
+        mApi = nullptr;
+    }
+
+    mApi = new BatchingAPIClient(callback);
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+        return false;
+    }
+
+    if (mGnssBatchingCbIface_2_0 != nullptr) {
+        mGnssBatchingCbIface_2_0->unlinkToDeath(mGnssBatchingDeathRecipient);
+    }
+    mGnssBatchingCbIface_2_0 = callback;
+    if (mGnssBatchingCbIface_2_0 != nullptr) {
+        mGnssBatchingCbIface_2_0->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+    }
+
+    return true;
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace gnss
diff --git a/android/2.0/GnssBatching.h b/android/2.0/GnssBatching.h
index f7dc65b..4c8d1db 100644
--- a/android/2.0/GnssBatching.h
+++ b/android/2.0/GnssBatching.h
@@ -21,7 +21,7 @@
 #ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
 #define ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
 
-#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
 #include <hidl/Status.h>
 
 
@@ -31,8 +31,8 @@
 namespace V2_0 {
 namespace implementation {
 
-using ::android::hardware::gnss::V1_0::IGnssBatching;
-using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
 using ::android::hidl::base::V1_0::IBase;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_memory;
@@ -48,13 +48,16 @@
     ~GnssBatching();
 
     // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
-    Return<bool> init(const sp<IGnssBatchingCallback>& callback) override;
+    Return<bool> init(const sp<V1_0::IGnssBatchingCallback>& callback) override;
     Return<uint16_t> getBatchSize() override;
     Return<bool> start(const IGnssBatching::Options& options ) override;
     Return<void> flush() override;
     Return<bool> stop() override;
     Return<void> cleanup() override;
 
+    // Methods from ::android::hardware::gnss::V2_0::IGnssBatching follow.
+    Return<bool> init_2_0(const sp<V2_0::IGnssBatchingCallback>& callback) override;
+
  private:
     struct GnssBatchingDeathRecipient : hidl_death_recipient {
         GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
@@ -67,8 +70,9 @@
 
  private:
     sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
-    sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+    sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
     BatchingAPIClient* mApi = nullptr;
+    sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0 = nullptr;
 };
 
 }  // namespace implementation
diff --git a/android/2.0/GnssConfiguration.cpp b/android/2.0/GnssConfiguration.cpp
index eb98be1..671b6e7 100644
--- a/android/2.0/GnssConfiguration.cpp
+++ b/android/2.0/GnssConfiguration.cpp
@@ -38,20 +38,8 @@
 
 // Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
 Return<bool> GnssConfiguration::setSuplEs(bool enabled)  {
-    if (mGnss == nullptr) {
-        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
-        return false;
-    }
-
-    GnssConfig config;
-    memset(&config, 0, sizeof(GnssConfig));
-    config.size = sizeof(GnssConfig);
-    config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
-    config.suplEmergencyServices = (enabled ?
-            GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES :
-            GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO);
-
-    return mGnss->updateConfiguration(config);
+    // deprecated function. Must return false to pass VTS
+    return false;
 }
 
 Return<bool> GnssConfiguration::setSuplVersion(uint32_t version)  {
@@ -174,10 +162,9 @@
     return mGnss->updateConfiguration(config);
 }
 
-Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
-    /* we no longer set GPS lock here, there is
-       visibility control for this */
-    return true;
+Return<bool> GnssConfiguration::setGpsLock(uint8_t /*lock*/) {
+    // deprecated function. Must return false to pass VTS
+    return false;
 }
 
 Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
@@ -268,7 +255,7 @@
         break;
     default:
         copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
-        LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+        LOC_LOGe("Invalid constellation %u", copyFromSource.constellation);
         retVal = false;
         break;
     }
diff --git a/android/2.0/GnssDebug.cpp b/android/2.0/GnssDebug.cpp
index 582acc9..b6b9bfe 100644
--- a/android/2.0/GnssDebug.cpp
+++ b/android/2.0/GnssDebug.cpp
@@ -33,6 +33,7 @@
 namespace implementation {
 
 using ::android::hardware::hidl_vec;
+using ::android::hardware::gnss::V2_0::IGnssDebug;
 
 #define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
 #define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS   (20000)
@@ -57,7 +58,7 @@
 {
     LOC_LOGD("%s]: ", __func__);
 
-    DebugData data = { };
+    V1_0::IGnssDebug::DebugData data = { };
 
     if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
         LOC_LOGE("GnssDebug - Null GNSS interface");
@@ -139,8 +140,8 @@
     }
 
     // satellite data block
-    SatelliteData s = { };
-    std::vector<SatelliteData> s_array = { };
+    V1_0::IGnssDebug::SatelliteData s = { };
+    std::vector<V1_0::IGnssDebug::SatelliteData> s_array;
 
     for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
         memset(&s, 0, sizeof(s));
@@ -170,6 +171,123 @@
     return Void();
 }
 
+Return<void> GnssDebug::getDebugData_2_0(getDebugData_2_0_cb _hidl_cb)
+{
+    LOC_LOGD("%s]: ", __func__);
+
+    V2_0::IGnssDebug::DebugData data = { };
+
+    if((nullptr == mGnss) || (nullptr == mGnss->getGnssInterface())){
+        LOC_LOGE("GnssDebug - Null GNSS interface");
+        _hidl_cb(data);
+        return Void();
+    }
+
+    // get debug report snapshot via hal interface
+    GnssDebugReport reports = { };
+    mGnss->getGnssInterface()->getDebugReport(reports);
+
+    // location block
+    if (reports.mLocation.mValid) {
+        data.position.valid = true;
+        data.position.latitudeDegrees = reports.mLocation.mLocation.latitude;
+        data.position.longitudeDegrees = reports.mLocation.mLocation.longitude;
+        data.position.altitudeMeters = reports.mLocation.mLocation.altitude;
+
+        data.position.speedMetersPerSec =
+            (double)(reports.mLocation.mLocation.speed);
+        data.position.bearingDegrees =
+            (double)(reports.mLocation.mLocation.bearing);
+        data.position.horizontalAccuracyMeters =
+            (double)(reports.mLocation.mLocation.accuracy);
+        data.position.verticalAccuracyMeters =
+            reports.mLocation.verticalAccuracyMeters;
+        data.position.speedAccuracyMetersPerSecond =
+            reports.mLocation.speedAccuracyMetersPerSecond;
+        data.position.bearingAccuracyDegrees =
+            reports.mLocation.bearingAccuracyDegrees;
+
+        timeval tv_now, tv_report;
+        tv_report.tv_sec  = reports.mLocation.mUtcReported.tv_sec;
+        tv_report.tv_usec = reports.mLocation.mUtcReported.tv_nsec / 1000ULL;
+        gettimeofday(&tv_now, NULL);
+        data.position.ageSeconds =
+            (tv_now.tv_sec - tv_report.tv_sec) +
+            (float)((tv_now.tv_usec - tv_report.tv_usec)) / 1000000;
+    }
+    else {
+        data.position.valid = false;
+    }
+
+    if (data.position.horizontalAccuracyMeters <= 0 ||
+        data.position.horizontalAccuracyMeters > GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS) {
+        data.position.horizontalAccuracyMeters = GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS;
+    }
+    if (data.position.verticalAccuracyMeters <= 0 ||
+        data.position.verticalAccuracyMeters > GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS) {
+        data.position.verticalAccuracyMeters = GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS;
+    }
+    if (data.position.speedAccuracyMetersPerSecond <= 0 ||
+        data.position.speedAccuracyMetersPerSecond > GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC) {
+        data.position.speedAccuracyMetersPerSecond = GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC;
+    }
+    if (data.position.bearingAccuracyDegrees <= 0 ||
+        data.position.bearingAccuracyDegrees > GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG) {
+        data.position.bearingAccuracyDegrees = GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG;
+    }
+
+    // time block
+    if (reports.mTime.mValid) {
+        data.time.timeEstimate = reports.mTime.timeEstimate;
+        data.time.timeUncertaintyNs = reports.mTime.timeUncertaintyNs;
+        data.time.frequencyUncertaintyNsPerSec =
+            reports.mTime.frequencyUncertaintyNsPerSec;
+    }
+
+    if (data.time.timeEstimate < GNSS_DEBUG_UNKNOWN_UTC_TIME) {
+        data.time.timeEstimate = GNSS_DEBUG_UNKNOWN_UTC_TIME;
+    }
+    if (data.time.timeUncertaintyNs <= 0 ||
+        data.time.timeUncertaintyNs > (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC) {
+        data.time.timeUncertaintyNs = (float)GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC;
+    }
+    if (data.time.frequencyUncertaintyNsPerSec <= 0 ||
+        data.time.frequencyUncertaintyNsPerSec > (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC) {
+        data.time.frequencyUncertaintyNsPerSec = (float)GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC;
+    }
+
+    // satellite data block
+    V2_0::IGnssDebug::SatelliteData s = { };
+    std::vector<V2_0::IGnssDebug::SatelliteData> s_array;
+
+    for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+        memset(&s, 0, sizeof(s));
+        s.v1_0.svid = reports.mSatelliteInfo[i].svid;
+        convertGnssConstellationType(
+            reports.mSatelliteInfo[i].constellation, s.constellation);
+        convertGnssEphemerisType(
+            reports.mSatelliteInfo[i].mEphemerisType, s.v1_0.ephemerisType);
+        convertGnssEphemerisSource(
+            reports.mSatelliteInfo[i].mEphemerisSource, s.v1_0.ephemerisSource);
+        convertGnssEphemerisHealth(
+            reports.mSatelliteInfo[i].mEphemerisHealth, s.v1_0.ephemerisHealth);
+
+        s.v1_0.ephemerisAgeSeconds =
+            reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+        s.v1_0.serverPredictionIsAvailable =
+            reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+        s.v1_0.serverPredictionAgeSeconds =
+            reports.mSatelliteInfo[i].serverPredictionAgeSeconds;
+
+        s_array.push_back(s);
+    }
+    data.satelliteDataArray = s_array;
+
+    // callback HIDL with collected debug data
+    _hidl_cb(data);
+    return Void();
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace gnss
diff --git a/android/2.0/GnssDebug.h b/android/2.0/GnssDebug.h
index 8d4fde3..8d75bea 100644
--- a/android/2.0/GnssDebug.h
+++ b/android/2.0/GnssDebug.h
@@ -22,7 +22,7 @@
 #define ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
 
 
-#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <android/hardware/gnss/2.0/IGnssDebug.h>
 #include <hidl/Status.h>
 
 namespace android {
@@ -31,7 +31,7 @@
 namespace V2_0 {
 namespace implementation {
 
-using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::gnss::V2_0::IGnssDebug;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::hidl_vec;
@@ -44,11 +44,10 @@
     GnssDebug(Gnss* gnss);
     ~GnssDebug() {};
 
-    /*
-     * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
-     * These declarations were generated from IGnssDebug.hal.
-     */
+    //  Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow
     Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+    //  Methods from ::android::hardware::gnss::V2_0::IGnssDebug follow.
+    Return<void> getDebugData_2_0(getDebugData_2_0_cb _hidl_cb) override;
 
 private:
     Gnss* mGnss = nullptr;
diff --git a/android/2.0/location_api/BatchingAPIClient.cpp b/android/2.0/location_api/BatchingAPIClient.cpp
index 48caee6..49cd18a 100644
--- a/android/2.0/location_api/BatchingAPIClient.cpp
+++ b/android/2.0/location_api/BatchingAPIClient.cpp
@@ -45,42 +45,35 @@
 namespace V2_0 {
 namespace implementation {
 
-using ::android::hardware::gnss::V1_0::IGnssBatching;
-using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
-using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::IGnssBatching;
+using ::android::hardware::gnss::V2_0::IGnssBatchingCallback;
+using ::android::hardware::gnss::V2_0::GnssLocation;
 
 static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
         LocationCapabilitiesMask mask);
 
-BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
+BatchingAPIClient::BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback) :
     LocationAPIClientBase(),
-    mGnssBatchingCbIface(callback),
+    mGnssBatchingCbIface(nullptr),
     mDefaultId(UINT_MAX),
-    mLocationCapabilitiesMask(0)
+    mLocationCapabilitiesMask(0),
+    mGnssBatchingCbIface_2_0(nullptr)
 {
     LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
 
-    LocationCallbacks locationCallbacks;
-    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
-    locationCallbacks.size = sizeof(LocationCallbacks);
+    gnssUpdateCallbacks(callback);
+}
 
-    locationCallbacks.trackingCb = nullptr;
-    locationCallbacks.batchingCb = nullptr;
-    if (mGnssBatchingCbIface != nullptr) {
-        locationCallbacks.batchingCb = [this](size_t count, Location* location,
-            BatchingOptions batchOptions) {
-            onBatchingCb(count, location, batchOptions);
-        };
-    }
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
-    locationCallbacks.gnssNiCb = nullptr;
-    locationCallbacks.gnssSvCb = nullptr;
-    locationCallbacks.gnssNmeaCb = nullptr;
-    locationCallbacks.gnssMeasurementsCb = nullptr;
+BatchingAPIClient::BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback) :
+    LocationAPIClientBase(),
+    mGnssBatchingCbIface(nullptr),
+    mDefaultId(UINT_MAX),
+    mLocationCapabilitiesMask(0),
+    mGnssBatchingCbIface_2_0(nullptr)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
 
-    locAPISetCallbacks(locationCallbacks);
+    gnssUpdateCallbacks_2_0(callback);
 }
 
 BatchingAPIClient::~BatchingAPIClient()
@@ -94,6 +87,51 @@
     return locAPIGetBatchSize();
 }
 
+void BatchingAPIClient::setCallbacks()
+{
+    LocationCallbacks locationCallbacks;
+    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+    locationCallbacks.size = sizeof(LocationCallbacks);
+
+    locationCallbacks.trackingCb = nullptr;
+    locationCallbacks.batchingCb = nullptr;
+    locationCallbacks.batchingCb = [this](size_t count, Location* location,
+        BatchingOptions batchOptions) {
+        onBatchingCb(count, location, batchOptions);
+    };
+    locationCallbacks.geofenceBreachCb = nullptr;
+    locationCallbacks.geofenceStatusCb = nullptr;
+    locationCallbacks.gnssLocationInfoCb = nullptr;
+    locationCallbacks.gnssNiCb = nullptr;
+    locationCallbacks.gnssSvCb = nullptr;
+    locationCallbacks.gnssNmeaCb = nullptr;
+    locationCallbacks.gnssMeasurementsCb = nullptr;
+
+    locAPISetCallbacks(locationCallbacks);
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback)
+{
+    mMutex.lock();
+    mGnssBatchingCbIface = callback;
+    mMutex.unlock();
+
+    if (mGnssBatchingCbIface != nullptr) {
+        setCallbacks();
+    }
+}
+
+void BatchingAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback)
+{
+    mMutex.lock();
+    mGnssBatchingCbIface_2_0 = callback;
+    mMutex.unlock();
+
+    if (mGnssBatchingCbIface_2_0 != nullptr) {
+        setCallbacks();
+    }
+}
+
 int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
 {
     LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
@@ -160,16 +198,32 @@
 void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
         BatchingOptions /*batchOptions*/)
 {
+    mMutex.lock();
+    auto gnssBatchingCbIface(mGnssBatchingCbIface);
+    auto gnssBatchingCbIface_2_0(mGnssBatchingCbIface_2_0);
+    mMutex.unlock();
+
     LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
-    if (mGnssBatchingCbIface != nullptr && count > 0) {
-        hidl_vec<GnssLocation> locationVec;
+    if (gnssBatchingCbIface_2_0 != nullptr && count > 0) {
+        hidl_vec<V2_0::GnssLocation> locationVec;
         locationVec.resize(count);
         for (size_t i = 0; i < count; i++) {
             convertGnssLocation(location[i], locationVec[i]);
         }
-        auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+        auto r = gnssBatchingCbIface_2_0->gnssLocationBatchCb(locationVec);
         if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
+            LOC_LOGE("%s] Error from gnssLocationBatchCb 2.0 description=%s",
+                __func__, r.description().c_str());
+        }
+    } else if (gnssBatchingCbIface != nullptr && count > 0) {
+        hidl_vec<V1_0::GnssLocation> locationVec;
+        locationVec.resize(count);
+        for (size_t i = 0; i < count; i++) {
+            convertGnssLocation(location[i], locationVec[i]);
+        }
+        auto r = gnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssLocationBatchCb 1.0 description=%s",
                 __func__, r.description().c_str());
         }
     }
diff --git a/android/2.0/location_api/BatchingAPIClient.h b/android/2.0/location_api/BatchingAPIClient.h
index 33a8c2e..7198341 100644
--- a/android/2.0/location_api/BatchingAPIClient.h
+++ b/android/2.0/location_api/BatchingAPIClient.h
@@ -30,8 +30,9 @@
 #ifndef BATCHING_API_CLINET_H
 #define BATCHING_API_CLINET_H
 
-#include <android/hardware/gnss/1.0/IGnssBatching.h>
-#include <android/hardware/gnss/1.0/IGnssBatchingCallback.h>
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnssBatching.h>
+#include <android/hardware/gnss/2.0/IGnssBatchingCallback.h>
 #include <pthread.h>
 
 #include <LocationAPIClientBase.h>
@@ -46,6 +47,9 @@
 {
 public:
     BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+    BatchingAPIClient(const sp<V2_0::IGnssBatchingCallback>& callback);
+    void gnssUpdateCallbacks(const sp<V1_0::IGnssBatchingCallback>& callback);
+    void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssBatchingCallback>& callback);
     ~BatchingAPIClient();
     int getBatchSize();
     int startSession(const V1_0::IGnssBatching::Options& options);
@@ -61,9 +65,12 @@
     void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
 
 private:
+    void setCallbacks();
+    std::mutex mMutex;
     sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
     uint32_t mDefaultId;
     LocationCapabilitiesMask mLocationCapabilitiesMask;
+    sp<V2_0::IGnssBatchingCallback> mGnssBatchingCbIface_2_0;
 };
 
 }  // namespace implementation
diff --git a/android/2.0/location_api/GnssAPIClient.cpp b/android/2.0/location_api/GnssAPIClient.cpp
index 44ae284..5610f06 100644
--- a/android/2.0/location_api/GnssAPIClient.cpp
+++ b/android/2.0/location_api/GnssAPIClient.cpp
@@ -44,34 +44,46 @@
 namespace V2_0 {
 namespace implementation {
 
-using ::android::hardware::gnss::V1_0::IGnss;
-using ::android::hardware::gnss::V1_0::IGnssCallback;
+using ::android::hardware::gnss::V2_0::IGnss;
+using ::android::hardware::gnss::V2_0::IGnssCallback;
 using ::android::hardware::gnss::V1_0::IGnssNiCallback;
-using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::GnssLocation;
 
-static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
+static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out);
+static void convertGnssSvStatus(GnssSvNotification& in,
+        hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out);
 
-GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
-    const sp<IGnssNiCallback>& niCb) :
+GnssAPIClient::GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+        const sp<V1_0::IGnssNiCallback>& niCb) :
     LocationAPIClientBase(),
     mGnssCbIface(nullptr),
     mGnssNiCbIface(nullptr),
     mControlClient(new LocationAPIControlClient()),
     mLocationCapabilitiesMask(0),
-    mLocationCapabilitiesCached(false)
+    mLocationCapabilitiesCached(false),
+    mGnssCbIface_2_0(nullptr)
 {
     LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
 
-    // set default LocationOptions.
-    memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
-    mTrackingOptions.size = sizeof(TrackingOptions);
-    mTrackingOptions.minInterval = 1000;
-    mTrackingOptions.minDistance = 0;
-    mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
-
+    initLocationOptions();
     gnssUpdateCallbacks(gpsCb, niCb);
 }
 
+GnssAPIClient::GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb) :
+    LocationAPIClientBase(),
+    mGnssCbIface(nullptr),
+    mGnssNiCbIface(nullptr),
+    mControlClient(new LocationAPIControlClient()),
+    mLocationCapabilitiesMask(0),
+    mLocationCapabilitiesCached(false),
+    mGnssCbIface_2_0(nullptr)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
+
+    initLocationOptions();
+    gnssUpdateCallbacks_2_0(gpsCb);
+}
+
 GnssAPIClient::~GnssAPIClient()
 {
     LOC_LOGD("%s]: ()", __FUNCTION__);
@@ -81,8 +93,62 @@
     }
 }
 
+void GnssAPIClient::initLocationOptions()
+{
+    // set default LocationOptions.
+    memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+    mTrackingOptions.size = sizeof(TrackingOptions);
+    mTrackingOptions.minInterval = 1000;
+    mTrackingOptions.minDistance = 0;
+    mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+}
+
+void GnssAPIClient::setCallbacks()
+{
+    LocationCallbacks locationCallbacks;
+    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+    locationCallbacks.size = sizeof(LocationCallbacks);
+
+    locationCallbacks.trackingCb = nullptr;
+    locationCallbacks.trackingCb = [this](Location location) {
+        onTrackingCb(location);
+    };
+
+    locationCallbacks.batchingCb = nullptr;
+    locationCallbacks.geofenceBreachCb = nullptr;
+    locationCallbacks.geofenceStatusCb = nullptr;
+    locationCallbacks.gnssLocationInfoCb = nullptr;
+    locationCallbacks.gnssNiCb = nullptr;
+    if (mGnssNiCbIface != nullptr) {
+        loc_core::ContextBase* context =
+                loc_core::LocContext::getLocContext(
+                        NULL, NULL,
+                        loc_core::LocContext::mLocationHalName, false);
+        if (!context->hasAgpsExtendedCapabilities()) {
+            LOC_LOGD("Registering NI CB");
+            locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotify) {
+                onGnssNiCb(id, gnssNiNotify);
+            };
+        }
+    }
+
+    locationCallbacks.gnssSvCb = nullptr;
+    locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
+        onGnssSvCb(gnssSvNotification);
+    };
+
+    locationCallbacks.gnssNmeaCb = nullptr;
+    locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
+        onGnssNmeaCb(gnssNmeaNotification);
+    };
+
+    locationCallbacks.gnssMeasurementsCb = nullptr;
+
+    locAPISetCallbacks(locationCallbacks);
+}
+
 // for GpsInterface
-void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
+void GnssAPIClient::gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
     const sp<IGnssNiCallback>& niCb)
 {
     LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
@@ -92,51 +158,22 @@
     mGnssNiCbIface = niCb;
     mMutex.unlock();
 
-    LocationCallbacks locationCallbacks;
-    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
-    locationCallbacks.size = sizeof(LocationCallbacks);
-
-    locationCallbacks.trackingCb = nullptr;
-    if (mGnssCbIface != nullptr) {
-        locationCallbacks.trackingCb = [this](Location location) {
-            onTrackingCb(location);
-        };
+    if (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr) {
+        setCallbacks();
     }
+}
 
-    locationCallbacks.batchingCb = nullptr;
-    locationCallbacks.geofenceBreachCb = nullptr;
-    locationCallbacks.geofenceStatusCb = nullptr;
-    locationCallbacks.gnssLocationInfoCb = nullptr;
+void GnssAPIClient::gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &gpsCb);
 
-    locationCallbacks.gnssNiCb = nullptr;
-    loc_core::ContextBase* context =
-            loc_core::LocContext::getLocContext(
-                    NULL, NULL,
-                    loc_core::LocContext::mLocationHalName, false);
-    if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
-        LOC_LOGD("Registering NI CB");
-        locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
-            onGnssNiCb(id, gnssNiNotification);
-        };
+    mMutex.lock();
+    mGnssCbIface_2_0 = gpsCb;
+    mMutex.unlock();
+
+    if (mGnssCbIface_2_0 != nullptr) {
+        setCallbacks();
     }
-
-    locationCallbacks.gnssSvCb = nullptr;
-    if (mGnssCbIface != nullptr) {
-        locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) {
-            onGnssSvCb(gnssSvNotification);
-        };
-    }
-
-    locationCallbacks.gnssNmeaCb = nullptr;
-    if (mGnssCbIface != nullptr) {
-        locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) {
-            onGnssNmeaCb(gnssNmeaNotification);
-        };
-    }
-
-    locationCallbacks.gnssMeasurementsCb = nullptr;
-
-    locAPISetCallbacks(locationCallbacks);
 }
 
 bool GnssAPIClient::gnssStart()
@@ -307,9 +344,10 @@
 
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (gnssCbIface != nullptr) {
+    if (gnssCbIface_2_0 != nullptr || gnssCbIface != nullptr) {
         uint32_t data = 0;
         if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
                 (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
@@ -317,20 +355,18 @@
                 (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
             data |= IGnssCallback::Capabilities::SCHEDULING;
         if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
-            data |= IGnssCallback::Capabilities::GEOFENCING;
+            data |= V1_0::IGnssCallback::Capabilities::GEOFENCING;
         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
-            data |= IGnssCallback::Capabilities::MEASUREMENTS;
+            data |= V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
             data |= IGnssCallback::Capabilities::MSB;
         if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
             data |= IGnssCallback::Capabilities::MSA;
-        auto r = gnssCbIface->gnssSetCapabilitesCb(data);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
-                __func__, r.description().c_str());
-        }
-    }
-    if (gnssCbIface != nullptr) {
+        if (capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT)
+            data |= IGnssCallback::Capabilities::LOW_POWER_MODE;
+        if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT)
+            data |= IGnssCallback::Capabilities::SATELLITE_BLACKLIST;
+
         IGnssCallback::GnssSystemInfo gnssInfo;
         if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
             capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
@@ -343,12 +379,33 @@
             gnssInfo.yearOfHw = 2015;
         }
         LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw);
-        auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
-                __func__, r.description().c_str());
+
+        if (gnssCbIface_2_0 != nullptr) {
+            auto r = gnssCbIface_2_0->gnssSetCapabilitiesCb_2_0(data);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssSetCapabilitiesCb_2_0 description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface_2_0->gnssSetSystemInfoCb(gnssInfo);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        } else if (gnssCbIface != nullptr) {
+            auto r = gnssCbIface->gnssSetCapabilitesCb(data);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s",
+                    __func__, r.description().c_str());
+            }
         }
+
     }
+
 }
 
 void GnssAPIClient::onTrackingCb(Location location)
@@ -356,17 +413,29 @@
     LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (gnssCbIface != nullptr) {
-        GnssLocation gnssLocation;
+    if (gnssCbIface_2_0 != nullptr) {
+        V2_0::GnssLocation gnssLocation;
+        convertGnssLocation(location, gnssLocation);
+        auto r = gnssCbIface_2_0->gnssLocationCb_2_0(gnssLocation);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssLocationCb_2_0 description=%s",
+                __func__, r.description().c_str());
+        }
+    } else if (gnssCbIface != nullptr) {
+        V1_0::GnssLocation gnssLocation;
         convertGnssLocation(location, gnssLocation);
         auto r = gnssCbIface->gnssLocationCb(gnssLocation);
         if (!r.isOk()) {
             LOC_LOGE("%s] Error from gnssLocationCb description=%s",
                 __func__, r.description().c_str());
         }
+    } else {
+        LOC_LOGW("%s] No GNSS Interface ready for gnssLocationCb ", __FUNCTION__);
     }
+
 }
 
 void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
@@ -449,10 +518,19 @@
     LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (gnssCbIface != nullptr) {
-        IGnssCallback::GnssSvStatus svStatus;
+    if (gnssCbIface_2_0 != nullptr) {
+        hidl_vec<V2_0::IGnssCallback::GnssSvInfo> svInfoList;
+        convertGnssSvStatus(gnssSvNotification, svInfoList);
+        auto r = gnssCbIface_2_0->gnssSvStatusCb_2_0(svInfoList);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssSvStatusCb_2_0 description=%s",
+                __func__, r.description().c_str());
+        }
+    } else if (gnssCbIface != nullptr) {
+        V1_0::IGnssCallback::GnssSvStatus svStatus;
         convertGnssSvStatus(gnssSvNotification, svStatus);
         auto r = gnssCbIface->gnssSvStatusCb(svStatus);
         if (!r.isOk()) {
@@ -466,9 +544,10 @@
 {
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (gnssCbIface != nullptr) {
+    if (gnssCbIface != nullptr || gnssCbIface_2_0 != nullptr) {
         const std::string s(gnssNmeaNotification.nmea);
         std::stringstream ss(s);
         std::string each;
@@ -476,12 +555,22 @@
             each += '\n';
             android::hardware::hidl_string nmeaString;
             nmeaString.setToExternal(each.c_str(), each.length());
-            auto r = gnssCbIface->gnssNmeaCb(
-                    static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
-            if (!r.isOk()) {
-                LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__,
-                            gnssNmeaNotification.nmea, gnssNmeaNotification.length,
-                            r.description().c_str());
+            if (gnssCbIface_2_0 != nullptr) {
+                auto r = gnssCbIface_2_0->gnssNmeaCb(
+                        static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+                if (!r.isOk()) {
+                    LOC_LOGE("%s] Error from gnssCbIface_2_0 nmea=%s length=%zu description=%s",
+                             __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+                             r.description().c_str());
+                }
+            } else if (gnssCbIface != nullptr) {
+                auto r = gnssCbIface->gnssNmeaCb(
+                        static_cast<V1_0::GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString);
+                if (!r.isOk()) {
+                    LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s",
+                             __func__, gnssNmeaNotification.nmea, gnssNmeaNotification.length,
+                             r.description().c_str());
+                }
             }
         }
     }
@@ -492,18 +581,32 @@
     LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
-        auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
-                __func__, r.description().c_str());
-        }
-        r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
-                __func__, r.description().c_str());
+    if (error == LOCATION_ERROR_SUCCESS) {
+        if (gnssCbIface_2_0 != nullptr) {
+            auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_ON description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_BEGIN description=%s",
+                    __func__, r.description().c_str());
+            }
+        } else if (gnssCbIface != nullptr) {
+            auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s",
+                    __func__, r.description().c_str());
+            }
         }
     }
 }
@@ -513,23 +616,38 @@
     LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
     mMutex.lock();
     auto gnssCbIface(mGnssCbIface);
+    auto gnssCbIface_2_0(mGnssCbIface_2_0);
     mMutex.unlock();
 
-    if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) {
-        auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
-                __func__, r.description().c_str());
-        }
-        r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
-        if (!r.isOk()) {
-            LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
-                __func__, r.description().c_str());
+    if (error == LOCATION_ERROR_SUCCESS) {
+        if (gnssCbIface_2_0 != nullptr) {
+            auto r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb 2.0 SESSION_END description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface_2_0->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb 2.0 ENGINE_OFF description=%s",
+                    __func__, r.description().c_str());
+            }
+
+        } else if (gnssCbIface != nullptr) {
+            auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s",
+                    __func__, r.description().c_str());
+            }
+            r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s",
+                    __func__, r.description().c_str());
+            }
         }
     }
 }
 
-static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
+static void convertGnssSvStatus(GnssSvNotification& in, V1_0::IGnssCallback::GnssSvStatus& out)
 {
     memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
     out.numSvs = in.count;
@@ -539,22 +657,45 @@
         out.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
     }
     for (size_t i = 0; i < out.numSvs; i++) {
-        IGnssCallback::GnssSvInfo& info = out.gnssSvList[i];
-        info.svid = in.gnssSvs[i].svId;
-        convertGnssConstellationType(in.gnssSvs[i].type, info.constellation);
-        info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
-        info.elevationDegrees = in.gnssSvs[i].elevation;
-        info.azimuthDegrees = in.gnssSvs[i].azimuth;
-        info.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
-        info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+        out.gnssSvList[i].svid = in.gnssSvs[i].svId;
+        convertGnssConstellationType(in.gnssSvs[i].type, out.gnssSvList[i].constellation);
+        out.gnssSvList[i].cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+        out.gnssSvList[i].elevationDegrees = in.gnssSvs[i].elevation;
+        out.gnssSvList[i].azimuthDegrees = in.gnssSvs[i].azimuth;
+        out.gnssSvList[i].carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+        out.gnssSvList[i].svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
-            info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+            out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
-            info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+            out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
-            info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+            out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
         if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
-            info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+            out.gnssSvList[i].svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+    }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in,
+        hidl_vec<V2_0::IGnssCallback::GnssSvInfo>& out)
+{
+    out.resize(in.count);
+    for (size_t i = 0; i < in.count; i++) {
+        out[i].v1_0.svid = in.gnssSvs[i].svId;
+        out[i].v1_0.cN0Dbhz = in.gnssSvs[i].cN0Dbhz;
+        out[i].v1_0.elevationDegrees = in.gnssSvs[i].elevation;
+        out[i].v1_0.azimuthDegrees = in.gnssSvs[i].azimuth;
+        out[i].v1_0.carrierFrequencyHz = in.gnssSvs[i].carrierFrequencyHz;
+        out[i].v1_0.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+            out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+            out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
+            out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+            out[i].v1_0.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+
+        convertGnssConstellationType(in.gnssSvs[i].type, out[i].constellation);
     }
 }
 
diff --git a/android/2.0/location_api/GnssAPIClient.h b/android/2.0/location_api/GnssAPIClient.h
index a129cee..493f9ca 100644
--- a/android/2.0/location_api/GnssAPIClient.h
+++ b/android/2.0/location_api/GnssAPIClient.h
@@ -33,7 +33,7 @@
 
 #include <mutex>
 #include <android/hardware/gnss/2.0/IGnss.h>
-//#include <android/hardware/gnss/1.1/IGnssCallback.h>
+#include <android/hardware/gnss/2.0/IGnssCallback.h>
 #include <LocationAPIClientBase.h>
 
 namespace android {
@@ -49,6 +49,7 @@
 public:
     GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
             const sp<V1_0::IGnssNiCallback>& niCb);
+    GnssAPIClient(const sp<V2_0::IGnssCallback>& gpsCb);
     virtual ~GnssAPIClient();
     GnssAPIClient(const GnssAPIClient&) = delete;
     GnssAPIClient& operator=(const GnssAPIClient&) = delete;
@@ -56,6 +57,7 @@
     // for GpsInterface
     void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
             const sp<V1_0::IGnssNiCallback>& niCb);
+    void gnssUpdateCallbacks_2_0(const sp<V2_0::IGnssCallback>& gpsCb);
     bool gnssStart();
     bool gnssStop();
     bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
@@ -91,6 +93,8 @@
     void onStopTrackingCb(LocationError error) final;
 
 private:
+    void setCallbacks();
+    void initLocationOptions();
     sp<V1_0::IGnssCallback> mGnssCbIface;
     sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
     std::mutex mMutex;
@@ -98,6 +102,7 @@
     LocationCapabilitiesMask mLocationCapabilitiesMask;
     bool mLocationCapabilitiesCached;
     TrackingOptions mTrackingOptions;
+    sp<V2_0::IGnssCallback> mGnssCbIface_2_0;
 };
 
 }  // namespace implementation
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp
index c921154..6bd5084 100644
--- a/android/2.0/location_api/LocationUtil.cpp
+++ b/android/2.0/location_api/LocationUtil.cpp
@@ -28,6 +28,8 @@
  */
 
 #include <LocationUtil.h>
+#include <log_util.h>
+#include <inttypes.h>
 
 namespace android {
 namespace hardware {
@@ -35,13 +37,13 @@
 namespace V2_0 {
 namespace implementation {
 
-using ::android::hardware::gnss::V1_0::GnssLocation;
-using ::android::hardware::gnss::V1_0::GnssConstellationType;
+using ::android::hardware::gnss::V2_0::GnssLocation;
+using ::android::hardware::gnss::V2_0::GnssConstellationType;
 using ::android::hardware::gnss::V1_0::GnssLocationFlags;
 
-void convertGnssLocation(Location& in, GnssLocation& out)
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out)
 {
-    memset(&out, 0, sizeof(GnssLocation));
+    memset(&out, 0, sizeof(V1_0::GnssLocation));
     if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
         out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
         out.latitudeDegrees = in.latitude;
@@ -79,7 +81,40 @@
     out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
 }
 
-void convertGnssLocation(const GnssLocation& in, Location& out)
+void convertGnssLocation(Location& in, V2_0::GnssLocation& out)
+{
+    memset(&out, 0, sizeof(V2_0::GnssLocation));
+    convertGnssLocation(in, out.v1_0);
+
+    struct timespec sinceBootTime;
+    struct timespec currentTime;
+    if (0 == clock_gettime(CLOCK_BOOTTIME,&sinceBootTime) &&
+        0 == clock_gettime(CLOCK_REALTIME,&currentTime)) {
+
+        int64_t sinceBootTimeNanos = sinceBootTime.tv_sec*1000000000 + sinceBootTime.tv_nsec;
+        int64_t currentTimeNanos = currentTime.tv_sec*1000000000 + currentTime.tv_nsec;
+        int64_t locationTimeNanos = in.timestamp*1000000;
+        LOC_LOGD("%s]: sinceBootTimeNanos:%" PRIi64 " currentTimeNanos:%" PRIi64 ""
+                " locationTimeNanos:%" PRIi64 "",
+                __FUNCTION__, sinceBootTimeNanos, currentTimeNanos, locationTimeNanos);
+        if (currentTimeNanos >= locationTimeNanos) {
+            int64_t ageTimeNanos = currentTimeNanos - locationTimeNanos;
+            LOC_LOGD("%s]: ageTimeNanos:%" PRIi64 ")", __FUNCTION__, ageTimeNanos);
+            if (ageTimeNanos >= 0 && ageTimeNanos <= sinceBootTimeNanos) {
+                out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIMESTAMP_NS;
+                out.elapsedRealtime.timestampNs = sinceBootTimeNanos - ageTimeNanos;
+                out.elapsedRealtime.flags |= ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS;
+                // time uncertainty is 1 ms since it is calculated from utc time that is in ms
+                out.elapsedRealtime.timeUncertaintyNs = 1000000;
+                LOC_LOGD("%s]: timestampNs:%" PRIi64 ")",
+                        __FUNCTION__, out.elapsedRealtime.timestampNs);
+            }
+        }
+    }
+
+}
+
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out)
 {
     memset(&out, 0, sizeof(out));
     if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
@@ -119,30 +154,64 @@
     out.timestamp = static_cast<uint64_t>(in.timestamp);
 }
 
-void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out)
+void convertGnssLocation(const V2_0::GnssLocation& in, Location& out)
+{
+    memset(&out, 0, sizeof(out));
+    convertGnssLocation(in.v1_0, out);
+}
+
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out)
 {
     switch(in) {
         case GNSS_SV_TYPE_GPS:
-            out = GnssConstellationType::GPS;
+            out = V1_0::GnssConstellationType::GPS;
             break;
         case GNSS_SV_TYPE_SBAS:
-            out = GnssConstellationType::SBAS;
+            out = V1_0::GnssConstellationType::SBAS;
             break;
         case GNSS_SV_TYPE_GLONASS:
-            out = GnssConstellationType::GLONASS;
+            out = V1_0::GnssConstellationType::GLONASS;
             break;
         case GNSS_SV_TYPE_QZSS:
-            out = GnssConstellationType::QZSS;
+            out = V1_0::GnssConstellationType::QZSS;
             break;
         case GNSS_SV_TYPE_BEIDOU:
-            out = GnssConstellationType::BEIDOU;
+            out = V1_0::GnssConstellationType::BEIDOU;
             break;
         case GNSS_SV_TYPE_GALILEO:
-            out = GnssConstellationType::GALILEO;
+            out = V1_0::GnssConstellationType::GALILEO;
             break;
         case GNSS_SV_TYPE_UNKNOWN:
         default:
-            out = GnssConstellationType::UNKNOWN;
+            out = V1_0::GnssConstellationType::UNKNOWN;
+            break;
+    }
+}
+
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out)
+{
+    switch(in) {
+        case GNSS_SV_TYPE_GPS:
+            out = V2_0::GnssConstellationType::GPS;
+            break;
+        case GNSS_SV_TYPE_SBAS:
+            out = V2_0::GnssConstellationType::SBAS;
+            break;
+        case GNSS_SV_TYPE_GLONASS:
+            out = V2_0::GnssConstellationType::GLONASS;
+            break;
+        case GNSS_SV_TYPE_QZSS:
+            out = V2_0::GnssConstellationType::QZSS;
+            break;
+        case GNSS_SV_TYPE_BEIDOU:
+            out = V2_0::GnssConstellationType::BEIDOU;
+            break;
+        case GNSS_SV_TYPE_GALILEO:
+            out = V2_0::GnssConstellationType::GALILEO;
+            break;
+        case GNSS_SV_TYPE_UNKNOWN:
+        default:
+            out = V2_0::GnssConstellationType::UNKNOWN;
             break;
     }
 }
diff --git a/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h
index c6f5ead..8426de7 100644
--- a/android/2.0/location_api/LocationUtil.h
+++ b/android/2.0/location_api/LocationUtil.h
@@ -30,7 +30,7 @@
 #ifndef LOCATION_UTIL_H
 #define LOCATION_UTIL_H
 
-#include <android/hardware/gnss/1.0/types.h>
+#include <android/hardware/gnss/2.0/types.h>
 #include <LocationAPI.h>
 #include <GnssDebug.h>
 
@@ -41,8 +41,11 @@
 namespace implementation {
 
 void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(Location& in, V2_0::GnssLocation& out);
 void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssLocation(const V2_0::GnssLocation& in, Location& out);
 void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& out);
 void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
 void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
 void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
diff --git a/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp
index d9cae18..23c3b16 100644
--- a/android/2.0/location_api/MeasurementAPIClient.cpp
+++ b/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -54,6 +54,8 @@
 static void convertGnssMeasurement(GnssMeasurementsData& in,
         V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
 static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
+        ::android::hardware::hidl_string& out);
 
 MeasurementAPIClient::MeasurementAPIClient() :
     mGnssMeasurementCbIface(nullptr),
@@ -362,6 +364,8 @@
     out.measurements.resize(in.count);
     for (size_t i = 0; i < in.count; i++) {
         convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_1.v1_0);
+        convertGnssConstellationType(in.measurements[i].svType, out.measurements[i].constellation);
+        convertGnssMeasurementsCodeType(in.measurements[i].codeType, out.measurements[i].codeType);
         if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
             out.measurements[i].v1_1.accumulatedDeltaRangeState |=
             IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
@@ -374,11 +378,6 @@
         if (in.measurements[i].adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_HALF_CYCLE_RESOLVED_BIT)
             out.measurements[i].v1_1.accumulatedDeltaRangeState |=
             IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_HALF_CYCLE_RESOLVED;
-
-//        out.measurements[i].codeType =
-//            static_cast<IGnssMeasurementCallback::GnssMeasurementCodeType>(in.measurements[i].codeType);
-//        out.measurements[i].otherCodeTypeName = in.measurements[i].otherCodeTypeName;
-
         if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
             out.measurements[i].state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
         if (in.measurements[i].stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
@@ -417,6 +416,57 @@
     convertGnssClock(in.clock, out.clock);
 }
 
+static void convertGnssMeasurementsCodeType(GnssMeasurementsCodeType& in,
+        ::android::hardware::hidl_string& out)
+{
+    switch(in) {
+        case GNSS_MEASUREMENTS_CODE_TYPE_A:
+            out = "A";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_B:
+            out = "B";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_C:
+            out = "C";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_I:
+            out = "I";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_L:
+            out = "L";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_M:
+            out = "M";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_P:
+            out = "P";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_Q:
+            out = "Q";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_S:
+            out = "S";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_W:
+            out = "W";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_X:
+            out = "X";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_Y:
+            out = "Y";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_Z:
+            out = "Z";
+            break;
+        case GNSS_MEASUREMENTS_CODE_TYPE_N:
+            out = "N";
+            break;
+        default:
+            out = "UNKNOWN";
+    }
+}
+
 }  // namespace implementation
 }  // namespace V2_0
 }  // namespace gnss
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
index c1a335a..2c93cb3 100644
--- a/android/measurement_corrections/1.0/MeasurementCorrections.cpp
+++ b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
@@ -54,11 +54,12 @@
 MeasurementCorrections::~MeasurementCorrections() {
 }
 
-Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) {
+Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& /*corrections*/) {
     return true;
 }
 
-Return<bool> MeasurementCorrections::setCallback(const sp<IMeasurementCorrectionsCallback>& callback) {
+Return<bool> MeasurementCorrections::setCallback(
+        const sp<V1_0::IMeasurementCorrectionsCallback>& /*callback*/) {
     return true;
 }
 
diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp
index edfc150..5253a1b 100644
--- a/gnss/GnssAdapter.cpp
+++ b/gnss/GnssAdapter.cpp
@@ -1954,9 +1954,6 @@
         if (it->second.trackingCb != nullptr || it->second.gnssLocationInfoCb != nullptr) {
             mask |= LOC_API_ADAPTER_BIT_PARSED_POSITION_REPORT;
         }
-        if (it->second.gnssNiCb != nullptr) {
-            mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
-        }
         if (it->second.gnssSvCb != nullptr) {
             mask |= LOC_API_ADAPTER_BIT_SATELLITE_REPORT;
         }
@@ -2005,6 +2002,10 @@
     // need to register for leap second info
     // for proper nmea generation
     mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO;
+
+    // always register for NI NOTIFY VERIFY to handle internally in HAL
+    mask |= LOC_API_ADAPTER_BIT_NI_NOTIFY_VERIFY_REQUEST;
+
     updateEvtMask(mask, LOC_REGISTRATION_MASK_SET);
 }