Merge "GNSS HAL 2.0 implementation"
diff --git a/android/2.0/AGnss.cpp b/android/2.0/AGnss.cpp
new file mode 100644
index 0000000..ce38798
--- /dev/null
+++ b/android/2.0/AGnss.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_AGnssInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+static AGnss* spAGnss = nullptr;
+
+AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
+    spAGnss = this;
+}
+
+AGnss::~AGnss() {
+    spAGnss = nullptr;
+}
+
+void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status){
+}
+
+void AGnss::statusIpV4Cb(AGnssExtStatusIpV4 status) {
+}
+
+Return<void> AGnss::setCallback(const sp<V2_0::IAGnssCallback>& callback) {
+    return Void();
+}
+
+Return<bool> AGnss::dataConnClosed() {
+    return true;
+}
+
+Return<bool> AGnss::dataConnFailed() {
+    return true;
+}
+
+Return<bool> AGnss::dataConnOpen(uint64_t networkHandle, const hidl_string& apn,
+        V2_0::IAGnss::ApnIpType apnIpType) {
+    return true;
+}
+
+Return<bool> AGnss::setServer(V2_0::IAGnssCallback::AGnssType type,
+                              const hidl_string& hostname,
+                              int32_t port) {
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/AGnss.h b/android/2.0/AGnss.h
new file mode 100644
index 0000000..ed9c0e8
--- /dev/null
+++ b/android/2.0/AGnss.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
+
+#include <android/hardware/gnss/2.0/IAGnss.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct AGnss : public V2_0::IAGnss {
+
+    AGnss(Gnss* gnss);
+    ~AGnss();
+    /*
+     * Methods from ::android::hardware::gnss::V2_0::IAGnss interface follow.
+     * These declarations were generated from IAGnss.hal.
+     */
+    Return<void> setCallback(const sp<V2_0::IAGnssCallback>& callback) override;
+
+    Return<bool> dataConnClosed() override;
+
+    Return<bool> dataConnFailed() override;
+
+    Return<bool> dataConnOpen(uint64_t networkHandle, const hidl_string& apn,
+            V2_0::IAGnss::ApnIpType apnIpType) override;
+
+    Return<bool> setServer(V2_0::IAGnssCallback::AGnssType type,
+                         const hidl_string& hostname, int32_t port) override;
+
+    void statusIpV4Cb(AGnssExtStatusIpV4 status);
+
+    /* Data call setup callback passed down to GNSS HAL implementation */
+    static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status);
+
+ private:
+    Gnss* mGnss = nullptr;
+    sp<IAGnssCallback> mAGnssCbIface = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_AGNSS_H
diff --git a/android/2.0/AGnssRil.cpp b/android/2.0/AGnssRil.cpp
new file mode 100644
index 0000000..e17a06d
--- /dev/null
+++ b/android/2.0/AGnssRil.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc__AGnssRilInterface"
+
+#include <log_util.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sstream>
+#include <string>
+#include "Gnss.h"
+#include "AGnssRil.h"
+#include <DataItemConcreteTypesBase.h>
+
+typedef void* (getLocationInterface)();
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+
+AGnssRil::AGnssRil(Gnss* gnss) : mGnss(gnss) {
+    ENTRY_LOG_CALLFLOW();
+}
+
+AGnssRil::~AGnssRil() {
+    ENTRY_LOG_CALLFLOW();
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected, NetworkType type, bool /*roaming*/) {
+    ENTRY_LOG_CALLFLOW();
+    // Extra NetworkTypes not available in IAgnssRil enums
+    const int NetworkType_BLUETOOTH = 7;
+    const int NetworkType_ETHERNET = 9;
+    const int NetworkType_PROXY = 16;
+
+    // for XTRA
+    if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
+        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        switch(type)
+        {
+            case IAGnssRil::NetworkType::MOBILE:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+                break;
+            case IAGnssRil::NetworkType::WIFI:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+                break;
+            case IAGnssRil::NetworkType::MMS:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+                break;
+            case IAGnssRil::NetworkType::SUPL:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+                break;
+            case IAGnssRil::NetworkType::DUN:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+                break;
+            case IAGnssRil::NetworkType::HIPRI:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+                break;
+            case IAGnssRil::NetworkType::WIMAX:
+                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+                break;
+            default:
+                {
+                    int networkType = (int) type;
+                    // Handling network types not available in IAgnssRil
+                    switch(networkType)
+                    {
+                        case NetworkType_BLUETOOTH:
+                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+                            break;
+                        case NetworkType_ETHERNET:
+                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+                            break;
+                        case NetworkType_PROXY:
+                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+                            break;
+                        default:
+                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+                    }
+                }
+                break;
+        }
+        mGnss->getGnssInterface()->updateConnectionStatus(connected, typeout);
+    }
+    return true;
+}
+Return<bool> AGnssRil::updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) {
+    ENTRY_LOG_CALLFLOW();
+
+    if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
+        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_METERED) {
+            typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+        } else {
+            typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+        }
+        mGnss->getGnssInterface()->updateConnectionStatus(attributes.isConnected, typeout);
+    }
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/AGnssRil.h b/android/2.0/AGnssRil.h
new file mode 100644
index 0000000..a04d8aa
--- /dev/null
+++ b/android/2.0/AGnssRil.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+#define ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
+
+#include <android/hardware/gnss/2.0/IAGnssRil.h>
+#include <hidl/Status.h>
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+/*
+ * Extended interface for AGNSS RIL support. An Assisted GNSS Radio Interface Layer interface
+ * allows the GNSS chipset to request radio interface layer information from Android platform.
+ * Examples of such information are reference location, unique subscriber ID, phone number string
+ * and network availability changes. Also contains wrapper methods to allow methods from
+ * IAGnssiRilCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct AGnssRil : public V2_0::IAGnssRil {
+    AGnssRil(Gnss* gnss);
+    ~AGnssRil();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+     * These declarations were generated from IAGnssRil.hal.
+     */
+    Return<void> setCallback(const sp<V1_0::IAGnssRilCallback>& /*callback*/) override {
+        return Void();
+    }
+    Return<void> setRefLocation(const V1_0::IAGnssRil::AGnssRefLocation& /*agnssReflocation*/) override {
+        return Void();
+    }
+    Return<bool> setSetId(V1_0::IAGnssRil::SetIDType /*type*/, const hidl_string& /*setid*/) override {
+        return false;
+    }
+    Return<bool> updateNetworkAvailability(bool /*available*/,
+                                    const hidl_string& /*apn*/) override {
+        return false;
+    }
+    Return<bool> updateNetworkState(bool connected, V1_0::IAGnssRil::NetworkType type, bool roaming) override;
+
+    // Methods from ::android::hardware::gnss::V2_0::IAGnssRil follow
+    Return<bool> updateNetworkState_2_0(const V2_0::IAGnssRil::NetworkAttributes& attributes) override;
+
+ private:
+    Gnss* mGnss = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_AGNSSRIL_H_
diff --git a/android/2.0/Android.mk b/android/2.0/Android.mk
new file mode 100644
index 0000000..0fa50bd
--- /dev/null
+++ b/android/2.0/Android.mk
@@ -0,0 +1,92 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    AGnss.cpp \
+    Gnss.cpp \
+    AGnssRil.cpp \
+    GnssMeasurement.cpp \
+    GnssConfiguration.cpp \
+    GnssBatching.cpp \
+    GnssGeofencing.cpp \
+    GnssNi.cpp \
+    GnssDebug.cpp \
+    ../measurement_corrections/1.0/MeasurementCorrections.cpp \
+    ../visibility_control/1.0/GnssVisibilityControl.cpp
+
+LOCAL_SRC_FILES += \
+    location_api/GnssAPIClient.cpp \
+    location_api/MeasurementAPIClient.cpp \
+    location_api/GeofenceAPIClient.cpp \
+    location_api/BatchingAPIClient.cpp \
+    location_api/LocationUtil.cpp \
+
+LOCAL_C_INCLUDES:= \
+    $(LOCAL_PATH)/location_api \
+    $(LOCAL_PATH)/../measurement_corrections/1.0 \
+    $(LOCAL_PATH)/../visibility_control/1.0
+LOCAL_HEADER_LIBRARIES := \
+    libgps.utils_headers \
+    libloc_core_headers \
+    libloc_pla_headers \
+    liblocation_api_headers
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    libcutils \
+    libutils \
+    android.hardware.gnss@1.0 \
+    android.hardware.gnss@1.1 \
+    android.hardware.gnss@2.0 \
+    android.hardware.gnss.measurement_corrections@1.0 \
+    android.hardware.gnss.visibility_control@1.0
+
+LOCAL_SHARED_LIBRARIES += \
+    libloc_core \
+    libgps.utils \
+    libdl \
+    liblocation_api \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc
+LOCAL_SRC_FILES := \
+    service.cpp \
+
+LOCAL_HEADER_LIBRARIES := \
+    libgps.utils_headers \
+    libloc_core_headers \
+    libloc_pla_headers \
+    liblocation_api_headers
+
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libgps.utils \
+    libqti_vndfwk_detect \
+
+LOCAL_SHARED_LIBRARIES += \
+    libhwbinder \
+    libhidlbase \
+    libhidltransport \
+    android.hardware.gnss@1.0 \
+    android.hardware.gnss@1.1 \
+    android.hardware.gnss@2.0 \
+
+LOCAL_CFLAGS += $(GNSS_CFLAGS)
+include $(BUILD_EXECUTABLE)
diff --git a/android/2.0/Gnss.cpp b/android/2.0/Gnss.cpp
new file mode 100644
index 0000000..0a4b34b
--- /dev/null
+++ b/android/2.0/Gnss.cpp
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssInterface"
+
+#include <fstream>
+#include <log_util.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "Gnss.h"
+#include "LocationUtil.h"
+
+typedef void* (getLocationInterface)();
+
+#define IMAGES_INFO_FILE "/sys/devices/soc0/images"
+#define DELIMITER ";"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+static std::string getVersionString() {
+    static std::string version;
+    if (!version.empty())
+        return version;
+
+    char value[PROPERTY_VALUE_MAX] = {0};
+    property_get("ro.hardware", value, "unknown");
+    version.append(value).append(DELIMITER);
+
+    std::ifstream in(IMAGES_INFO_FILE);
+    std::string s;
+    while(getline(in, s)) {
+        std::size_t found = s.find("CRM:");
+        if (std::string::npos == found) {
+            continue;
+        }
+
+        // skip over space characters after "CRM:"
+        const char* substr = s.c_str();
+        found += 4;
+        while (0 != substr[found] && isspace(substr[found])) {
+            found++;
+        }
+        if (s.find("11:") != found) {
+            continue;
+        }
+        s.erase(0, found + 3);
+
+        found = s.find_first_of("\r\n");
+        if (std::string::npos != found) {
+            s.erase(s.begin() + found, s.end());
+        }
+        version.append(s).append(DELIMITER);
+    }
+    return version;
+}
+
+void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+    LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+            __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+    if (mGnss != nullptr) {
+        mGnss->stop();
+        mGnss->cleanup();
+    }
+}
+
+Gnss::Gnss() {
+    ENTRY_LOG_CALLFLOW();
+    // clear pending GnssConfig
+    memset(&mPendingConfig, 0, sizeof(GnssConfig));
+    mGnssDeathRecipient = new GnssDeathRecipient(this);
+}
+
+Gnss::~Gnss() {
+    ENTRY_LOG_CALLFLOW();
+    if (mApi != nullptr) {
+        delete mApi;
+        mApi = nullptr;
+    }
+}
+
+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 (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;
+}
+
+GnssInterface* Gnss::getGnssInterface() {
+    static bool getGnssInterfaceFailed = false;
+    if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
+        LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
+        getLocationInterface* getter = NULL;
+        const char *error = NULL;
+        dlerror();
+        void *handle = dlopen("libgnss.so", RTLD_NOW);
+        if (NULL == handle || (error = dlerror()) != NULL)  {
+            LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
+        } else {
+            getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
+            if ((error = dlerror()) != NULL)  {
+                LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
+                getter = NULL;
+            }
+        }
+
+        if (NULL == getter) {
+            getGnssInterfaceFailed = true;
+        } else {
+            mGnssInterface = (GnssInterface*)(*getter)();
+        }
+    }
+    return mGnssInterface;
+}
+
+Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback)  {
+    ENTRY_LOG_CALLFLOW();
+    if (mGnssCbIface != nullptr) {
+        mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
+    }
+    mGnssCbIface = callback;
+    if (mGnssCbIface != nullptr) {
+        mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
+    }
+
+    GnssAPIClient* api = getApi();
+    if (api != nullptr) {
+        api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+        api->gnssEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
+        api->requestCapabilities();
+    }
+    return true;
+}
+
+Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
+    ENTRY_LOG_CALLFLOW();
+    mGnssNiCbIface = callback;
+    GnssAPIClient* api = getApi();
+    if (api != nullptr) {
+        api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
+    }
+    return true;
+}
+
+Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
+    ENTRY_LOG_CALLFLOW();
+    GnssAPIClient* api = getApi();
+    if (api) {
+        api->gnssConfigurationUpdate(gnssConfig);
+    } else if (gnssConfig.flags != 0) {
+        // api is not ready yet, update mPendingConfig with gnssConfig
+        mPendingConfig.size = sizeof(GnssConfig);
+
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+            mPendingConfig.gpsLock = gnssConfig.gpsLock;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+            mPendingConfig.suplVersion = gnssConfig.suplVersion;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT;
+            mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer);
+            mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type;
+            if (mPendingConfig.assistanceServer.hostName != nullptr) {
+                free((void*)mPendingConfig.assistanceServer.hostName);
+                mPendingConfig.assistanceServer.hostName =
+                    strdup(gnssConfig.assistanceServer.hostName);
+            }
+            mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+            mPendingConfig.lppProfile = gnssConfig.lppProfile;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT;
+            mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT;
+            mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+            mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+            mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+            mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+            mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
+        }
+        if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+            mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+            mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+        }
+    }
+    return true;
+}
+
+Return<bool> Gnss::start()  {
+    ENTRY_LOG_CALLFLOW();
+    bool retVal = false;
+    GnssAPIClient* api = getApi();
+    if (api) {
+        retVal = api->gnssStart();
+    }
+    return retVal;
+}
+
+Return<bool> Gnss::stop()  {
+    ENTRY_LOG_CALLFLOW();
+    bool retVal = false;
+    GnssAPIClient* api = getApi();
+    if (api) {
+        retVal = api->gnssStop();
+    }
+    return retVal;
+}
+
+Return<void> Gnss::cleanup()  {
+    ENTRY_LOG_CALLFLOW();
+
+    if (mApi != nullptr) {
+        mApi->gnssDisable();
+    }
+
+    return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+                                  double longitudeDegrees,
+                                  float accuracyMeters)  {
+    ENTRY_LOG_CALLFLOW();
+    GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                              int32_t uncertaintyMs) {
+    ENTRY_LOG_CALLFLOW();
+    GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
+        return true;
+    } else {
+        return false;
+    }
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)  {
+    ENTRY_LOG_CALLFLOW();
+    GnssAPIClient* api = getApi();
+    if (api) {
+        api->gnssDeleteAidingData(aidingDataFlags);
+    }
+    return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+                                   V1_0::IGnss::GnssPositionRecurrence recurrence,
+                                   uint32_t minIntervalMs,
+                                   uint32_t preferredAccuracyMeters,
+                                   uint32_t preferredTimeMs)  {
+    ENTRY_LOG_CALLFLOW();
+    bool retVal = false;
+    GnssAPIClient* api = getApi();
+    if (api) {
+        retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+                preferredAccuracyMeters, preferredTimeMs);
+    }
+    return retVal;
+}
+
+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;
+    return nullptr;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
+    ENTRY_LOG_CALLFLOW();
+    mGnssNi = new GnssNi(this);
+    return mGnssNi;
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+    ENTRY_LOG_CALLFLOW();
+    if (mGnssMeasurement == nullptr)
+        mGnssMeasurement = new GnssMeasurement();
+    return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
+    ENTRY_LOG_CALLFLOW();
+    mGnssConfig = new GnssConfiguration(this);
+    return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
+    ENTRY_LOG_CALLFLOW();
+    mGnssGeofencingIface = new GnssGeofencing();
+    return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching()  {
+    ENTRY_LOG_CALLFLOW();
+    mGnssBatching = new GnssBatching();
+    return mGnssBatching;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
+    ENTRY_LOG_CALLFLOW();
+    mGnssDebug = new GnssDebug(this);
+    return mGnssDebug;
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+    ENTRY_LOG_CALLFLOW();
+    mGnssRil = new AGnssRil(this);
+    return mGnssRil;
+}
+
+// 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());
+    mGnssCbIface_1_1 = callback;
+    GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) {
+            odcpiRequestCb(odcpiRequest);
+        };
+        gnssInterface->odcpiInit(cb);
+    }
+    return setCallback(callback);
+}
+
+Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+        V1_0::IGnss::GnssPositionRecurrence recurrence,
+        uint32_t minIntervalMs,
+        uint32_t preferredAccuracyMeters,
+        uint32_t preferredTimeMs,
+        bool lowPowerMode) {
+    ENTRY_LOG_CALLFLOW();
+    bool retVal = false;
+    GnssAPIClient* api = getApi();
+    if (api) {
+        GnssPowerMode powerMode = lowPowerMode?
+                GNSS_POWER_MODE_M4 : GNSS_POWER_MODE_M2;
+        retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs,
+                preferredAccuracyMeters, preferredTimeMs, powerMode, minIntervalMs);
+    }
+    return retVal;
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+    ENTRY_LOG_CALLFLOW();
+    if (mGnssMeasurement == nullptr)
+        mGnssMeasurement = new GnssMeasurement();
+    return mGnssMeasurement;
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
+    ENTRY_LOG_CALLFLOW();
+    if (mGnssConfig == nullptr)
+        mGnssConfig = new GnssConfiguration(this);
+    return mGnssConfig;
+}
+
+Return<bool> Gnss::injectBestLocation(const GnssLocation& gnssLocation) {
+    ENTRY_LOG_CALLFLOW();
+    GnssInterface* gnssInterface = getGnssInterface();
+    if (nullptr != gnssInterface) {
+        Location location = {};
+        convertGnssLocation(gnssLocation, location);
+        gnssInterface->odcpiInject(location);
+    }
+    return true;
+}
+
+void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) {
+    ENTRY_LOG_CALLFLOW();
+    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) {
+            auto r = mGnssCbIface_1_1->gnssRequestLocationCb(!request.isEmergencyMode);
+            if (!r.isOk()) {
+                LOC_LOGe("Error invoking gnssRequestLocationCb %s", r.description().c_str());
+            }
+        } else {
+            LOC_LOGv("Unsupported ODCPI request type: %d", request.type);
+        }
+    } else {
+        LOC_LOGe("ODCPI request not supported.");
+    }
+}
+
+// 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);
+}
+Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
+    ENTRY_LOG_CALLFLOW();
+    mAGnssIface_2_0 = new AGnss(this);
+    return mAGnssIface_2_0;
+}
+Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
+    mGnssRil = new AGnssRil(this);
+    return mGnssRil;
+}
+
+Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
+    ENTRY_LOG_CALLFLOW();
+    mGnssConfig = new GnssConfiguration(this);
+    return mGnssConfig;
+}
+Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
+    ENTRY_LOG_CALLFLOW();
+    if (mGnssMeasurement == nullptr)
+        mGnssMeasurement = new GnssMeasurement();
+    return mGnssMeasurement;
+}
+Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+        Gnss::getExtensionMeasurementCorrections() {
+    if (mGnssMeasCorr == nullptr) {
+        mGnssMeasCorr = new MeasurementCorrections();
+    }
+    return mGnssMeasCorr;
+}
+Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+        Gnss::getExtensionVisibilityControl() {
+    if (mVisibCtrl == nullptr) {
+        mVisibCtrl = new GnssVisibilityControl();
+    }
+    return mVisibCtrl;
+}
+IGnss* HIDL_FETCH_IGnss(const char* hal) {
+    ENTRY_LOG_CALLFLOW();
+    IGnss* iface = nullptr;
+    iface = new Gnss();
+    if (iface == nullptr) {
+        LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal);
+    }
+    return iface;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/Gnss.h b/android/2.0/Gnss.h
new file mode 100644
index 0000000..bef1e3a
--- /dev/null
+++ b/android/2.0/Gnss.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssConfiguration.h>
+#include <GnssMeasurement.h>
+#include <GnssBatching.h>
+#include <GnssGeofencing.h>
+#include <GnssNi.h>
+#include <GnssDebug.h>
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <MeasurementCorrections.h>
+#include <GnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include "GnssAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::MeasurementCorrections;
+using ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
+using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
+
+struct Gnss : public IGnss {
+    Gnss();
+    ~Gnss();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+     * These declarations were generated from Gnss.hal.
+     */
+    Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback)  override;
+    Return<bool> start()  override;
+    Return<bool> stop()  override;
+    Return<void> cleanup()  override;
+    Return<bool> injectLocation(double latitudeDegrees,
+                                double longitudeDegrees,
+                                float accuracyMeters)  override;
+    Return<bool> injectTime(int64_t timeMs,
+                            int64_t timeReferenceMs,
+                            int32_t uncertaintyMs) override;
+    Return<void> deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags)  override;
+    Return<bool> setPositionMode(V1_0::IGnss::GnssPositionMode mode,
+                                 V1_0::IGnss::GnssPositionRecurrence recurrence,
+                                 uint32_t minIntervalMs,
+                                 uint32_t preferredAccuracyMeters,
+                                 uint32_t preferredTimeMs)  override;
+    Return<sp<V1_0::IAGnss>> getExtensionAGnss() override;
+    Return<sp<V1_0::IGnssNi>> getExtensionGnssNi() override;
+    Return<sp<V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() override;
+    Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+    Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() override;
+    Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() override;
+
+    Return<sp<V1_0::IAGnssRil>> getExtensionAGnssRil() override;
+
+    inline Return<sp<V1_0::IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
+        return nullptr;
+    }
+
+    inline Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override {
+        return nullptr;
+    }
+
+    Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+
+    // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+    Return<bool> setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) override;
+    Return<bool> setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode,
+            V1_0::IGnss::GnssPositionRecurrence recurrence,
+            uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+            uint32_t preferredTimeMs, bool lowPowerMode) override;
+    Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+    Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
+    Return<bool> injectBestLocation(const GnssLocation& location) override;
+
+    // Methods from ::android::hardware::gnss::V2_0::IGnss follow.
+    Return<bool> setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) override;
+    Return<sp<V2_0::IAGnss>> getExtensionAGnss_2_0() override;
+    Return<sp<V2_0::IAGnssRil>> getExtensionAGnssRil_2_0() override;
+
+    Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
+    Return<sp<::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections>>
+            getExtensionMeasurementCorrections() override;
+    Return<sp<V2_0::IGnssMeasurement>> getExtensionGnssMeasurement_2_0() override;
+    /**
+     * This method returns the IGnssVisibilityControl interface.
+     *
+     * @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
+     */
+    Return<sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>>
+            getExtensionVisibilityControl() override;
+
+
+
+    // These methods are not part of the IGnss base class.
+    GnssAPIClient* getApi();
+    Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
+    Return<bool> updateConfiguration(GnssConfig& gnssConfig);
+    GnssInterface* getGnssInterface();
+
+    // Callback for ODCPI request
+    void odcpiRequestCb(const OdcpiRequestInfo& request);
+ private:
+    struct GnssDeathRecipient : hidl_death_recipient {
+        GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
+        }
+        ~GnssDeathRecipient() = default;
+        virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+        sp<Gnss> mGnss;
+    };
+
+ private:
+    sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
+
+    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;
+    sp<V1_1::IGnssCallback> mGnssCbIface_1_1 = nullptr;
+    sp<V2_0::IAGnss> mAGnssIface_2_0 = nullptr;
+    sp<V2_0::IAGnssRil> mGnssRil = nullptr;
+    sp<V2_0::IGnssMeasurement> mGnssMeasurement = nullptr;
+    sp<V2_0::IGnssConfiguration> mGnssConfig = nullptr;
+    sp<IMeasurementCorrections> mGnssMeasCorr = nullptr;
+    sp<IGnssVisibilityControl> mVisibCtrl = nullptr;
+
+    GnssAPIClient* mApi = nullptr;
+    GnssConfig mPendingConfig;
+    GnssInterface* mGnssInterface = nullptr;
+};
+
+extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSS_H
diff --git a/android/2.0/GnssBatching.cpp b/android/2.0/GnssBatching.cpp
new file mode 100644
index 0000000..cf215ea
--- /dev/null
+++ b/android/2.0/GnssBatching.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssBatchingInterface"
+
+#include <log_util.h>
+#include <BatchingAPIClient.h>
+#include "GnssBatching.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
+        uint64_t cookie, const wp<IBase>& who) {
+    LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+            __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+}
+
+GnssBatching::GnssBatching() : mApi(nullptr) {
+    mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
+}
+
+GnssBatching::~GnssBatching() {
+    if (mApi != nullptr) {
+        delete mApi;
+        mApi = nullptr;
+    }
+}
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<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 != nullptr) {
+        mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+    }
+    mGnssBatchingCbIface = callback;
+    if (mGnssBatchingCbIface != nullptr) {
+        mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/);
+    }
+
+    return true;
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+    uint16_t ret = 0;
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        ret = mApi->getBatchSize();
+    }
+    return ret;
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+    bool ret = false;
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        ret = mApi->startSession(options);
+    }
+    return ret;
+}
+
+Return<void> GnssBatching::flush() {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        mApi->flushBatchedLocations();
+    }
+    return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+    bool ret = false;
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        ret = mApi->stopSession();
+    }
+    return ret;
+}
+
+Return<void> GnssBatching::cleanup() {
+    if (mGnssBatchingCbIface != nullptr) {
+        mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssBatching.h b/android/2.0/GnssBatching.h
new file mode 100644
index 0000000..f7dc65b
--- /dev/null
+++ b/android/2.0/GnssBatching.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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 <hidl/Status.h>
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssBatching;
+using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class BatchingAPIClient;
+struct GnssBatching : public IGnssBatching {
+    GnssBatching();
+    ~GnssBatching();
+
+    // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+    Return<bool> init(const sp<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;
+
+ private:
+    struct GnssBatchingDeathRecipient : hidl_death_recipient {
+        GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
+            mGnssBatching(gnssBatching) {
+        }
+        ~GnssBatchingDeathRecipient() = default;
+        virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+        sp<GnssBatching> mGnssBatching;
+    };
+
+ private:
+    sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
+    sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
+    BatchingAPIClient* mApi = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSBATCHING_H
diff --git a/android/2.0/GnssConfiguration.cpp b/android/2.0/GnssConfiguration.cpp
new file mode 100644
index 0000000..93a843a
--- /dev/null
+++ b/android/2.0/GnssConfiguration.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssConfigurationInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// 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);
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version)  {
+    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_VERSION_VALID_BIT;
+    switch (version) {
+        case 0x00020002:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
+            break;
+        case 0x00020000:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
+            break;
+        case 0x00010000:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
+            return false;
+            break;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode)  {
+    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_MODE_BIT;
+    switch (mode) {
+        case 0:
+            config.suplModeMask = 0; // STANDALONE ONLY
+            break;
+        case 1:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
+            break;
+        case 2:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+            break;
+        case 3:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
+            return false;
+            break;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+    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_LPP_PROFILE_VALID_BIT;
+    switch (lppProfile) {
+        case 0:
+            config.lppProfile = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE;
+            break;
+        case 1:
+            config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE;
+            break;
+        case 2:
+            config.lppProfile = GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE;
+            break;
+        case 3:
+            config.lppProfile = GNSS_CONFIG_LPP_PROFILE_USER_PLANE_AND_CONTROL_PLANE;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid lppProfile: %d.", __FUNCTION__, lppProfile);
+            return false;
+            break;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+    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_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+    if (protocol & (1<<0)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
+    }
+    if (protocol & (1<<1)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
+    }
+    if (protocol & (1<<2)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
+    }
+    if (protocol & (1<<3)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+    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_GPS_LOCK_VALID_BIT;
+    switch (lock) {
+        case 0:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+            break;
+        case 1:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
+            break;
+        case 2:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
+            break;
+        case 3:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
+            return false;
+            break;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(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_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+    config.emergencyPdnForEmergencySupl = (enabled ?
+            GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
+            GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
+
+    return mGnss->updateConfiguration(config);
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+            const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
+
+    ENTRY_LOG_CALLFLOW();
+    if (nullptr == mGnss) {
+        LOC_LOGe("mGnss is null");
+        return false;
+    }
+
+    // blValid is true if blacklist is empty, i.e. clearing the BL;
+    // if blacklist is not empty, blValid is initialied to false, and later
+    // updated in the for loop to become true only if there is at least
+    // one {constellation, svid} in the list that is valid.
+    bool blValid = (0 == blacklist.size());
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+    config.blacklistedSvIds.clear();
+
+    GnssSvIdSource source = {};
+    for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+        // Set blValid true if any one source is valid
+        blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
+        config.blacklistedSvIds.push_back(source);
+    }
+
+    // Update configuration only if blValid is true
+    // i.e. only if atleast one source is valid for blacklisting
+    return (blValid && mGnss->updateConfiguration(config));
+}
+
+bool GnssConfiguration::setBlacklistedSource(
+        GnssSvIdSource& copyToSource,
+        const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+    bool retVal = true;
+    uint16_t svIdOffset = 0;
+    copyToSource.size = sizeof(GnssSvIdSource);
+    copyToSource.svId = copyFromSource.svid;
+
+    switch(copyFromSource.constellation) {
+    case GnssConstellationType::GPS:
+        copyToSource.constellation = GNSS_SV_TYPE_GPS;
+        LOC_LOGe("GPS SVs can't be blacklisted.");
+        retVal = false;
+        break;
+    case GnssConstellationType::SBAS:
+        copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+        LOC_LOGe("SBAS SVs can't be blacklisted.");
+        retVal = false;
+        break;
+    case GnssConstellationType::GLONASS:
+        copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+        svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
+        break;
+    case GnssConstellationType::QZSS:
+        copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+        svIdOffset = 0;
+        break;
+    case GnssConstellationType::BEIDOU:
+        copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+        svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
+        break;
+    case GnssConstellationType::GALILEO:
+        copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+        svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
+        break;
+    default:
+        copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+        LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+        retVal = false;
+        break;
+    }
+
+    if (copyToSource.svId > 0 && svIdOffset > 0) {
+        copyToSource.svId += svIdOffset;
+    }
+
+    return retVal;
+}
+
+// Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSeconds) {
+    //TODO emergencyExtensionSeconds is not supporded in GnssConfig yet
+    return false;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssConfiguration.h b/android/2.0/GnssConfiguration.h
new file mode 100644
index 0000000..202a9fd
--- /dev/null
+++ b/android/2.0/GnssConfiguration.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+
+ /* Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
+
+#include <android/hardware/gnss/2.0/IGnssConfiguration.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct Gnss;
+struct GnssConfiguration : public V2_0::IGnssConfiguration {
+    GnssConfiguration(Gnss* gnss);
+    ~GnssConfiguration() = default;
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow.
+     * These declarations were generated from IGnssConfiguration.hal.
+     */
+    Return<bool> setSuplVersion(uint32_t version) override;
+    Return<bool> setSuplMode(uint8_t mode) override;
+    Return<bool> setSuplEs(bool enabled) override;
+    Return<bool> setLppProfile(uint8_t lppProfile) override;
+    Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
+    Return<bool> setEmergencySuplPdn(bool enable) override;
+    Return<bool> setGpsLock(uint8_t lock) override;
+
+    // Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+    Return<bool> setBlacklist(
+            const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) override;
+
+    // Methods from ::android::hardware::gnss::V2_0::IGnssConfiguration follow.
+    Return<bool> setEsExtensionSec(uint32_t emergencyExtensionSeconds) override;
+
+ private:
+    Gnss* mGnss = nullptr;
+    bool setBlacklistedSource(
+            GnssSvIdSource& copyToSource,
+            const GnssConfiguration::BlacklistedSource& copyFromSource);
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSCONFIGURATION_H
diff --git a/android/2.0/GnssDebug.cpp b/android/2.0/GnssDebug.cpp
new file mode 100644
index 0000000..582acc9
--- /dev/null
+++ b/android/2.0/GnssDebug.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssDebugInterface"
+
+#include <log/log.h>
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssDebug.h"
+#include "LocationUtil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_vec;
+
+#define GNSS_DEBUG_UNKNOWN_HORIZONTAL_ACCURACY_METERS (20000000)
+#define GNSS_DEBUG_UNKNOWN_VERTICAL_ACCURACY_METERS   (20000)
+#define GNSS_DEBUG_UNKNOWN_SPEED_ACCURACY_PER_SEC     (500)
+#define GNSS_DEBUG_UNKNOWN_BEARING_ACCURACY_DEG       (180)
+
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME            (1483228800000LL) // 1/1/2017 00:00 GMT
+#define GNSS_DEBUG_UNKNOWN_UTC_TIME_UNC        (1.57783680E17) // 5 years in ns
+#define GNSS_DEBUG_UNKNOWN_FREQ_UNC_NS_PER_SEC (2.0e5)  // ppm
+
+GnssDebug::GnssDebug(Gnss* gnss) : mGnss(gnss)
+{
+}
+
+/*
+ * This methods requests position, time and satellite ephemeris debug information
+ * from the HAL.
+ *
+ * @return void
+*/
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)
+{
+    LOC_LOGD("%s]: ", __func__);
+
+    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
+    SatelliteData s = { };
+    std::vector<SatelliteData> s_array = { };
+
+    for (uint32_t i=0; i<reports.mSatelliteInfo.size(); i++) {
+        memset(&s, 0, sizeof(s));
+        s.svid = reports.mSatelliteInfo[i].svid;
+        convertGnssConstellationType(
+            reports.mSatelliteInfo[i].constellation, s.constellation);
+        convertGnssEphemerisType(
+            reports.mSatelliteInfo[i].mEphemerisType, s.ephemerisType);
+        convertGnssEphemerisSource(
+            reports.mSatelliteInfo[i].mEphemerisSource, s.ephemerisSource);
+        convertGnssEphemerisHealth(
+            reports.mSatelliteInfo[i].mEphemerisHealth, s.ephemerisHealth);
+
+        s.ephemerisAgeSeconds =
+            reports.mSatelliteInfo[i].ephemerisAgeSeconds;
+        s.serverPredictionIsAvailable =
+            reports.mSatelliteInfo[i].serverPredictionIsAvailable;
+        s.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
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssDebug.h b/android/2.0/GnssDebug.h
new file mode 100644
index 0000000..8d4fde3
--- /dev/null
+++ b/android/2.0/GnssDebug.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
+
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssDebug;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/* Interface for GNSS Debug support. */
+struct Gnss;
+struct GnssDebug : public IGnssDebug {
+    GnssDebug(Gnss* gnss);
+    ~GnssDebug() {};
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+     * These declarations were generated from IGnssDebug.hal.
+     */
+    Return<void> getDebugData(getDebugData_cb _hidl_cb) override;
+
+private:
+    Gnss* mGnss = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSDEBUG_H
diff --git a/android/2.0/GnssGeofencing.cpp b/android/2.0/GnssGeofencing.cpp
new file mode 100644
index 0000000..b72d835
--- /dev/null
+++ b/android/2.0/GnssGeofencing.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssHal_GnssGeofencing"
+
+#include <log_util.h>
+#include <GeofenceAPIClient.h>
+#include "GnssGeofencing.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
+        uint64_t cookie, const wp<IBase>& who) {
+    LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+            __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+    if (mGnssGeofencing != nullptr) {
+        mGnssGeofencing->removeAllGeofences();
+    }
+}
+
+GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
+    mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
+}
+
+GnssGeofencing::~GnssGeofencing() {
+    if (mApi != nullptr) {
+        delete mApi;
+        mApi = nullptr;
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback)  {
+    if (mApi != nullptr) {
+        LOC_LOGd("mApi is NOT nullptr");
+        return Void();
+    }
+
+    mApi = new GeofenceAPIClient(callback);
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: failed to create mApi", __FUNCTION__);
+    }
+
+    if (mGnssGeofencingCbIface != nullptr) {
+        mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient);
+    }
+    mGnssGeofencingCbIface = callback;
+    if (mGnssGeofencingCbIface != nullptr) {
+        mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/);
+    }
+
+    return Void();
+}
+
+Return<void> GnssGeofencing::addGeofence(
+        int32_t geofenceId,
+        double latitudeDegrees,
+        double longitudeDegrees,
+        double radiusMeters,
+        IGnssGeofenceCallback::GeofenceTransition lastTransition,
+        int32_t monitorTransitions,
+        uint32_t notificationResponsivenessMs,
+        uint32_t unknownTimerMs)  {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        mApi->geofenceAdd(
+                geofenceId,
+                latitudeDegrees,
+                longitudeDegrees,
+                radiusMeters,
+                static_cast<int32_t>(lastTransition),
+                monitorTransitions,
+                notificationResponsivenessMs,
+                unknownTimerMs);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId)  {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        mApi->geofencePause(geofenceId);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions)  {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        mApi->geofenceResume(geofenceId, monitorTransitions);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId)  {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+    } else {
+        mApi->geofenceRemove(geofenceId);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::removeAllGeofences()  {
+    if (mApi == nullptr) {
+        LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
+    } else {
+        mApi->geofenceRemoveAll();
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssGeofencing.h b/android/2.0/GnssGeofencing.h
new file mode 100644
index 0000000..caa56d0
--- /dev/null
+++ b/android/2.0/GnssGeofencing.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
+
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::IGnssGeofencing;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class GeofenceAPIClient;
+struct GnssGeofencing : public IGnssGeofencing {
+    GnssGeofencing();
+    ~GnssGeofencing();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+     * These declarations were generated from IGnssGeofencing.hal.
+     */
+    Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback)  override;
+    Return<void> addGeofence(int32_t geofenceId,
+                             double latitudeDegrees,
+                             double longitudeDegrees,
+                             double radiusMeters,
+                             IGnssGeofenceCallback::GeofenceTransition lastTransition,
+                             int32_t monitorTransitions,
+                             uint32_t notificationResponsivenessMs,
+                             uint32_t unknownTimerMs)  override;
+
+    Return<void> pauseGeofence(int32_t geofenceId)  override;
+    Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions)  override;
+    Return<void> removeGeofence(int32_t geofenceId)  override;
+
+ private:
+    // This method is not part of the IGnss base class.
+    // It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
+    Return<void> removeAllGeofences();
+
+ private:
+    struct GnssGeofencingDeathRecipient : hidl_death_recipient {
+        GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
+            mGnssGeofencing(gnssGeofencing) {
+        }
+        ~GnssGeofencingDeathRecipient() = default;
+        virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+        sp<GnssGeofencing> mGnssGeofencing;
+    };
+
+ private:
+    sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
+    sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
+    GeofenceAPIClient* mApi = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSGEOFENCING_H
diff --git a/android/2.0/GnssMeasurement.cpp b/android/2.0/GnssMeasurement.cpp
new file mode 100644
index 0000000..5984a60
--- /dev/null
+++ b/android/2.0/GnssMeasurement.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssMeasurementInterface"
+
+#include <log_util.h>
+#include "GnssMeasurement.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
+        uint64_t cookie, const wp<IBase>& who) {
+    LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+            __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+}
+
+GnssMeasurement::GnssMeasurement() {
+    mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
+    mApi = new MeasurementAPIClient();
+}
+
+GnssMeasurement::~GnssMeasurement() {
+    if (mApi) {
+        delete mApi;
+        mApi = nullptr;
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<V1_0::IGnssMeasurementCallback>& callback)  {
+
+    Return<IGnssMeasurement::GnssMeasurementStatus> ret =
+        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+    if (mGnssMeasurementCbIface != nullptr) {
+        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+    }
+
+    if (callback == nullptr) {
+        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+        return ret;
+    }
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+        return ret;
+    }
+
+    mGnssMeasurementCbIface = callback;
+    mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+    return mApi->measurementSetCallback(callback);
+}
+
+Return<void> GnssMeasurement::close()  {
+    if (mApi == nullptr) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+        return Void();
+    }
+
+    if (mGnssMeasurementCbIface != nullptr) {
+        mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
+        mGnssMeasurementCbIface = nullptr;
+    }
+    if (mGnssMeasurementCbIface_1_1 != nullptr) {
+        mGnssMeasurementCbIface_1_1->unlinkToDeath(mGnssMeasurementDeathRecipient);
+        mGnssMeasurementCbIface_1_1 = nullptr;
+    }
+    mApi->measurementClose();
+
+    return Void();
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
+        const sp<V1_1::IGnssMeasurementCallback>& callback, bool enableFullTracking) {
+
+    Return<IGnssMeasurement::GnssMeasurementStatus> ret =
+        IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+    if (mGnssMeasurementCbIface_1_1 != nullptr) {
+        LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
+        return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
+    }
+
+    if (callback == nullptr) {
+        LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
+        return ret;
+    }
+    if (nullptr == mApi) {
+        LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
+        return ret;
+    }
+
+    mGnssMeasurementCbIface_1_1 = callback;
+    mGnssMeasurementCbIface_1_1->linkToDeath(mGnssMeasurementDeathRecipient, 0);
+
+    GnssPowerMode powerMode = enableFullTracking?
+            GNSS_POWER_MODE_M1 : GNSS_POWER_MODE_M2;
+
+    return mApi->measurementSetCallback_1_1(callback, powerMode);
+}
+// Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
+        const sp<V2_0::IGnssMeasurementCallback>& callback,
+        bool enableFullTracking) {
+    return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssMeasurement.h b/android/2.0/GnssMeasurement.h
new file mode 100644
index 0000000..6f3480b
--- /dev/null
+++ b/android/2.0/GnssMeasurement.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
+
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class MeasurementAPIClient;
+struct GnssMeasurement : public V2_0::IGnssMeasurement {
+    GnssMeasurement();
+    ~GnssMeasurement();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+     * These declarations were generated from IGnssMeasurement.hal.
+     */
+    Return<GnssMeasurement::GnssMeasurementStatus> setCallback(
+        const sp<V1_0::IGnssMeasurementCallback>& callback) override;
+    Return<void> close() override;
+
+    // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+    Return<GnssMeasurement::GnssMeasurementStatus> setCallback_1_1(
+            const sp<V1_1::IGnssMeasurementCallback>& callback,
+            bool enableFullTracking) override;
+
+    // Methods from ::android::hardware::gnss::V2_0::IGnssMeasurement follow.
+    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback_2_0(
+            const sp<V2_0::IGnssMeasurementCallback>& callback,
+            bool enableFullTracking) override;
+ private:
+    struct GnssMeasurementDeathRecipient : hidl_death_recipient {
+        GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
+            mGnssMeasurement(gnssMeasurement) {
+        }
+        ~GnssMeasurementDeathRecipient() = default;
+        virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+        sp<GnssMeasurement> mGnssMeasurement;
+    };
+
+ private:
+    sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
+    sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
+    sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1 = nullptr;
+    MeasurementAPIClient* mApi;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSMEASUREMENT_H
diff --git a/android/2.0/GnssNi.cpp b/android/2.0/GnssNi.cpp
new file mode 100644
index 0000000..d65a488
--- /dev/null
+++ b/android/2.0/GnssNi.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssNiInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp<IBase>& who) {
+    LOC_LOGE("%s] service died. cookie: %llu, who: %p",
+            __FUNCTION__, static_cast<unsigned long long>(cookie), &who);
+    // we do nothing here
+    // Gnss::GnssDeathRecipient will stop the session
+}
+
+GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
+    mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback)  {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return Void();
+    }
+
+    mGnss->setGnssNiCb(callback);
+
+    if (mGnssNiCbIface != nullptr) {
+        mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
+    }
+    mGnssNiCbIface = callback;
+    if (mGnssNiCbIface != nullptr) {
+        mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
+    }
+
+    return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse)  {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return Void();
+    }
+
+    GnssAPIClient* api = mGnss->getApi();
+    if (api == nullptr) {
+        LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
+        return Void();
+    }
+
+    api->gnssNiRespond(notifId, userResponse);
+
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/GnssNi.h b/android/2.0/GnssNi.h
new file mode 100644
index 0000000..26e281f
--- /dev/null
+++ b/android/2.0/GnssNi.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+#define ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
+
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNi;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct Gnss;
+struct GnssNi : public IGnssNi {
+    GnssNi(Gnss* gnss);
+    ~GnssNi() = default;
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+     * These declarations were generated from IGnssNi.hal.
+     */
+    Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
+    Return<void> respond(int32_t notifId,
+                         IGnssNiCallback::GnssUserResponseType userResponse) override;
+
+ private:
+    struct GnssNiDeathRecipient : hidl_death_recipient {
+        GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
+        }
+        ~GnssNiDeathRecipient() = default;
+        virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
+        sp<GnssNi> mGnssNi;
+    };
+
+ private:
+    sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
+    sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
+    Gnss* mGnss = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V2_0_GNSSNI_H
diff --git a/android/2.0/android.hardware.gnss@2.0-service-qti.rc b/android/2.0/android.hardware.gnss@2.0-service-qti.rc
new file mode 100644
index 0000000..36ee47c
--- /dev/null
+++ b/android/2.0/android.hardware.gnss@2.0-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.0-service-qti
+    class hal
+    user gps
+    group system gps radio
diff --git a/android/2.0/location_api/BatchingAPIClient.cpp b/android/2.0/location_api/BatchingAPIClient.cpp
new file mode 100644
index 0000000..48caee6
--- /dev/null
+++ b/android/2.0/location_api/BatchingAPIClient.cpp
@@ -0,0 +1,196 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_BatchingAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "BatchingAPIClient.h"
+
+#include "limits.h"
+
+
+namespace android {
+namespace hardware {
+namespace gnss {
+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;
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+        LocationCapabilitiesMask mask);
+
+BatchingAPIClient::BatchingAPIClient(const sp<IGnssBatchingCallback>& callback) :
+    LocationAPIClientBase(),
+    mGnssBatchingCbIface(callback),
+    mDefaultId(UINT_MAX),
+    mLocationCapabilitiesMask(0)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+    LocationCallbacks locationCallbacks;
+    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+    locationCallbacks.size = sizeof(LocationCallbacks);
+
+    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;
+
+    locAPISetCallbacks(locationCallbacks);
+}
+
+BatchingAPIClient::~BatchingAPIClient()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+int BatchingAPIClient::getBatchSize()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    return locAPIGetBatchSize();
+}
+
+int BatchingAPIClient::startSession(const IGnssBatching::Options& opts)
+{
+    LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+            static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+    int retVal = -1;
+    LocationOptions options;
+    convertBatchOption(opts, options, mLocationCapabilitiesMask);
+    uint32_t mode = 0;
+    if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+        mode = SESSION_MODE_ON_FULL;
+    }
+    if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+        retVal = 1;
+    }
+    return retVal;
+}
+
+int BatchingAPIClient::updateSessionOptions(const IGnssBatching::Options& opts)
+{
+    LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
+            static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
+    int retVal = -1;
+    LocationOptions options;
+    convertBatchOption(opts, options, mLocationCapabilitiesMask);
+
+    uint32_t mode = 0;
+    if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
+        mode = SESSION_MODE_ON_FULL;
+    }
+    if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
+        retVal = 1;
+    }
+    return retVal;
+}
+
+int BatchingAPIClient::stopSession()
+{
+    LOC_LOGD("%s]: ", __FUNCTION__);
+    int retVal = -1;
+    if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) {
+        retVal = 1;
+    }
+    return retVal;
+}
+
+void BatchingAPIClient::getBatchedLocation(int last_n_locations)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations);
+    locAPIGetBatchedLocations(mDefaultId, last_n_locations);
+}
+
+void BatchingAPIClient::flushBatchedLocations()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    locAPIGetBatchedLocations(mDefaultId, SIZE_MAX);
+}
+
+void BatchingAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+    LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+    mLocationCapabilitiesMask = capabilitiesMask;
+}
+
+void BatchingAPIClient::onBatchingCb(size_t count, Location* location,
+        BatchingOptions /*batchOptions*/)
+{
+    LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count);
+    if (mGnssBatchingCbIface != nullptr && count > 0) {
+        hidl_vec<GnssLocation> locationVec;
+        locationVec.resize(count);
+        for (size_t i = 0; i < count; i++) {
+            convertGnssLocation(location[i], locationVec[i]);
+        }
+        auto r = mGnssBatchingCbIface->gnssLocationBatchCb(locationVec);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssLocationBatchCb description=%s",
+                __func__, r.description().c_str());
+        }
+    }
+}
+
+static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out,
+        LocationCapabilitiesMask mask)
+{
+    memset(&out, 0, sizeof(LocationOptions));
+    out.size = sizeof(LocationOptions);
+    out.minInterval = (uint32_t)(in.periodNanos / 1000000L);
+    out.minDistance = 0;
+    out.mode = GNSS_SUPL_MODE_STANDALONE;
+    if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)
+        out.mode = GNSS_SUPL_MODE_MSA;
+    if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT)
+        out.mode = GNSS_SUPL_MODE_MSB;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/location_api/BatchingAPIClient.h b/android/2.0/location_api/BatchingAPIClient.h
new file mode 100644
index 0000000..33a8c2e
--- /dev/null
+++ b/android/2.0/location_api/BatchingAPIClient.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#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 <pthread.h>
+
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+class BatchingAPIClient : public LocationAPIClientBase
+{
+public:
+    BatchingAPIClient(const sp<V1_0::IGnssBatchingCallback>& callback);
+    ~BatchingAPIClient();
+    int getBatchSize();
+    int startSession(const V1_0::IGnssBatching::Options& options);
+    int updateSessionOptions(const V1_0::IGnssBatching::Options& options);
+    int stopSession();
+    void getBatchedLocation(int last_n_locations);
+    void flushBatchedLocations();
+
+    inline LocationCapabilitiesMask getCapabilities() { return mLocationCapabilitiesMask; }
+
+    // callbacks
+    void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+    void onBatchingCb(size_t count, Location* location, BatchingOptions batchOptions) final;
+
+private:
+    sp<V1_0::IGnssBatchingCallback> mGnssBatchingCbIface;
+    uint32_t mDefaultId;
+    LocationCapabilitiesMask mLocationCapabilitiesMask;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+#endif // BATCHING_API_CLINET_H
diff --git a/android/2.0/location_api/GeofenceAPIClient.cpp b/android/2.0/location_api/GeofenceAPIClient.cpp
new file mode 100644
index 0000000..fabf8bb
--- /dev/null
+++ b/android/2.0/location_api/GeofenceAPIClient.cpp
@@ -0,0 +1,275 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_GeofenceApiClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GeofenceAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
+    LocationAPIClientBase(),
+    mGnssGeofencingCbIface(callback)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+    LocationCallbacks locationCallbacks;
+    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+    locationCallbacks.size = sizeof(LocationCallbacks);
+
+    locationCallbacks.trackingCb = nullptr;
+    locationCallbacks.batchingCb = nullptr;
+
+    locationCallbacks.geofenceBreachCb = nullptr;
+    if (mGnssGeofencingCbIface != nullptr) {
+        locationCallbacks.geofenceBreachCb =
+            [this](GeofenceBreachNotification geofenceBreachNotification) {
+                onGeofenceBreachCb(geofenceBreachNotification);
+            };
+
+        locationCallbacks.geofenceStatusCb =
+            [this](GeofenceStatusNotification geofenceStatusNotification) {
+                onGeofenceStatusCb(geofenceStatusNotification);
+            };
+    }
+
+    locationCallbacks.gnssLocationInfoCb = nullptr;
+    locationCallbacks.gnssNiCb = nullptr;
+    locationCallbacks.gnssSvCb = nullptr;
+    locationCallbacks.gnssNmeaCb = nullptr;
+    locationCallbacks.gnssMeasurementsCb = nullptr;
+
+    locAPISetCallbacks(locationCallbacks);
+}
+
+void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+        double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+        uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
+{
+    LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
+            geofence_id, latitude, longitude, radius_meters,
+            last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
+
+    GeofenceOption options;
+    memset(&options, 0, sizeof(GeofenceOption));
+    options.size = sizeof(GeofenceOption);
+    if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+        options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
+    if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+        options.breachTypeMask |=  GEOFENCE_BREACH_EXIT_BIT;
+    options.responsiveness = notification_responsiveness_ms;
+
+    GeofenceInfo data;
+    data.size = sizeof(GeofenceInfo);
+    data.latitude = latitude;
+    data.longitude = longitude;
+    data.radius = radius_meters;
+
+    LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
+    if (LOCATION_ERROR_SUCCESS != err) {
+        onAddGeofencesCb(1, &err, &geofence_id);
+    }
+}
+
+void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+    locAPIPauseGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
+{
+    LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
+    GeofenceBreachTypeMask mask = 0;
+    if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
+        mask |= GEOFENCE_BREACH_ENTER_BIT;
+    if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
+        mask |=  GEOFENCE_BREACH_EXIT_BIT;
+    locAPIResumeGeofences(1, &geofence_id, &mask);
+}
+
+void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
+    locAPIRemoveGeofences(1, &geofence_id);
+}
+
+void GeofenceAPIClient::geofenceRemoveAll()
+{
+    LOC_LOGD("%s]", __FUNCTION__);
+    // TODO locAPIRemoveAllGeofences();
+}
+
+// callbacks
+void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
+{
+    LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
+    if (mGnssGeofencingCbIface != nullptr) {
+        for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
+            GnssLocation gnssLocation;
+            convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
+
+            IGnssGeofenceCallback::GeofenceTransition transition;
+            if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
+                transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
+            else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
+                transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
+            else {
+                // continue with other breach if transition is
+                // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
+                continue;
+            }
+
+            auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+                    geofenceBreachNotification.ids[i], gnssLocation, transition,
+                    static_cast<V1_0::GnssUtcTime>(geofenceBreachNotification.timestamp));
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
+    if (mGnssGeofencingCbIface != nullptr) {
+        IGnssGeofenceCallback::GeofenceAvailability status =
+            IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
+        if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
+            status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
+        }
+        GnssLocation gnssLocation;
+        memset(&gnssLocation, 0, sizeof(GnssLocation));
+        auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
+                __func__, r.description().c_str());
+        }
+    }
+}
+
+void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+    LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+    if (mGnssGeofencingCbIface != nullptr) {
+        for (size_t i = 0; i < count; i++) {
+            IGnssGeofenceCallback::GeofenceStatus status =
+                IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+            if (errors[i] == LOCATION_ERROR_SUCCESS)
+                status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+            else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
+                status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
+            auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+    LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+    if (mGnssGeofencingCbIface != nullptr) {
+        for (size_t i = 0; i < count; i++) {
+            IGnssGeofenceCallback::GeofenceStatus status =
+                IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+            if (errors[i] == LOCATION_ERROR_SUCCESS)
+                status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+            else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+                status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+            auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+    LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+    if (mGnssGeofencingCbIface != nullptr) {
+        for (size_t i = 0; i < count; i++) {
+            IGnssGeofenceCallback::GeofenceStatus status =
+                IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+            if (errors[i] == LOCATION_ERROR_SUCCESS)
+                status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+            else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+                status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+            auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
+{
+    LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
+    if (mGnssGeofencingCbIface != nullptr) {
+        for (size_t i = 0; i < count; i++) {
+            IGnssGeofenceCallback::GeofenceStatus status =
+                IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
+            if (errors[i] == LOCATION_ERROR_SUCCESS)
+                status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
+            else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
+                status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
+            auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/location_api/GeofenceAPIClient.h b/android/2.0/location_api/GeofenceAPIClient.h
new file mode 100644
index 0000000..71049de
--- /dev/null
+++ b/android/2.0/location_api/GeofenceAPIClient.h
@@ -0,0 +1,76 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GEOFENCE_API_CLINET_H
+#define GEOFENCE_API_CLINET_H
+
+
+#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GeofenceAPIClient : public LocationAPIClientBase
+{
+public:
+    GeofenceAPIClient(const sp<V1_0::IGnssGeofenceCallback>& callback);
+    virtual ~GeofenceAPIClient() = default;
+
+    void geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
+            double radius_meters, int32_t last_transition, int32_t monitor_transitions,
+            uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms);
+    void geofencePause(uint32_t geofence_id);
+    void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions);
+    void geofenceRemove(uint32_t geofence_id);
+    void geofenceRemoveAll();
+
+    // callbacks
+    void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final;
+    void onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) final;
+    void onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+    void onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+    void onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+    void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final;
+
+private:
+    sp<V1_0::IGnssGeofenceCallback> mGnssGeofencingCbIface;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+#endif // GEOFENCE_API_CLINET_H
diff --git a/android/2.0/location_api/GnssAPIClient.cpp b/android/2.0/location_api/GnssAPIClient.cpp
new file mode 100644
index 0000000..ceb0aa4
--- /dev/null
+++ b/android/2.0/location_api/GnssAPIClient.cpp
@@ -0,0 +1,565 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_GnssAPIClient"
+#define SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC (590 * 60 * 60 * 1000) // 590 hours
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "GnssAPIClient.h"
+#include <LocDualContext.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnss;
+using ::android::hardware::gnss::V1_0::IGnssCallback;
+using ::android::hardware::gnss::V1_0::IGnssNiCallback;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out);
+
+GnssAPIClient::GnssAPIClient(const sp<IGnssCallback>& gpsCb,
+    const sp<IGnssNiCallback>& niCb) :
+    LocationAPIClientBase(),
+    mGnssCbIface(nullptr),
+    mGnssNiCbIface(nullptr),
+    mControlClient(new LocationAPIControlClient()),
+    mLocationCapabilitiesMask(0),
+    mLocationCapabilitiesCached(false)
+{
+    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;
+
+    gnssUpdateCallbacks(gpsCb, niCb);
+}
+
+GnssAPIClient::~GnssAPIClient()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    if (mControlClient) {
+        delete mControlClient;
+        mControlClient = nullptr;
+    }
+}
+
+// for GpsInterface
+void GnssAPIClient::gnssUpdateCallbacks(const sp<IGnssCallback>& gpsCb,
+    const sp<IGnssNiCallback>& niCb)
+{
+    LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb);
+
+    mMutex.lock();
+    mGnssCbIface = gpsCb;
+    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);
+        };
+    }
+
+    locationCallbacks.batchingCb = nullptr;
+    locationCallbacks.geofenceBreachCb = nullptr;
+    locationCallbacks.geofenceStatusCb = nullptr;
+    locationCallbacks.gnssLocationInfoCb = nullptr;
+
+    locationCallbacks.gnssNiCb = nullptr;
+    loc_core::ContextBase* context =
+            loc_core::LocDualContext::getLocFgContext(
+                    NULL, NULL,
+                    loc_core::LocDualContext::mLocationHalName, false);
+    if (mGnssNiCbIface != nullptr && !context->hasAgpsExtendedCapabilities()) {
+        LOC_LOGD("Registering NI CB");
+        locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) {
+            onGnssNiCb(id, gnssNiNotification);
+        };
+    }
+
+    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()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    bool retVal = true;
+    locAPIStartTracking(mTrackingOptions);
+    return retVal;
+}
+
+bool GnssAPIClient::gnssStop()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    bool retVal = true;
+    locAPIStopTracking();
+    return retVal;
+}
+
+bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode,
+        IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs,
+        uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs,
+        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+    LOC_LOGD("%s]: (%d %d %d %d %d %d %d)", __FUNCTION__,
+            (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters,
+            preferredTimeMs, (int)powerMode, timeBetweenMeasurement);
+    bool retVal = true;
+    memset(&mTrackingOptions, 0, sizeof(TrackingOptions));
+    mTrackingOptions.size = sizeof(TrackingOptions);
+    mTrackingOptions.minInterval = minIntervalMs;
+    if (IGnss::GnssPositionMode::MS_ASSISTED == mode ||
+            IGnss::GnssPositionRecurrence::RECURRENCE_SINGLE == recurrence) {
+        // We set a very large interval to simulate SINGLE mode. Once we report a fix,
+        // the caller should take the responsibility to stop the session.
+        // For MSA, we always treat it as SINGLE mode.
+        mTrackingOptions.minInterval = SINGLE_SHOT_MIN_TRACKING_INTERVAL_MSEC;
+    }
+    mTrackingOptions.minDistance = preferredAccuracyMeters;
+    if (mode == IGnss::GnssPositionMode::STANDALONE)
+        mTrackingOptions.mode = GNSS_SUPL_MODE_STANDALONE;
+    else if (mode == IGnss::GnssPositionMode::MS_BASED)
+        mTrackingOptions.mode = GNSS_SUPL_MODE_MSB;
+    else if (mode ==  IGnss::GnssPositionMode::MS_ASSISTED)
+        mTrackingOptions.mode = GNSS_SUPL_MODE_MSA;
+    else {
+        LOC_LOGD("%s]: invalid GnssPositionMode: %d", __FUNCTION__, (int)mode);
+        retVal = false;
+    }
+    if (GNSS_POWER_MODE_INVALID != powerMode) {
+        mTrackingOptions.powerMode = powerMode;
+        mTrackingOptions.tbm = timeBetweenMeasurement;
+    }
+    locAPIUpdateTrackingOptions(mTrackingOptions);
+    return retVal;
+}
+
+// for GpsNiInterface
+void GnssAPIClient::gnssNiRespond(int32_t notifId,
+        IGnssNiCallback::GnssUserResponseType userResponse)
+{
+    LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast<int>(userResponse));
+    GnssNiResponse data;
+    switch (userResponse) {
+    case IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT:
+        data = GNSS_NI_RESPONSE_ACCEPT;
+        break;
+    case IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY:
+        data = GNSS_NI_RESPONSE_DENY;
+        break;
+    case IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP:
+        data = GNSS_NI_RESPONSE_NO_RESPONSE;
+        break;
+    default:
+        data = GNSS_NI_RESPONSE_IGNORE;
+        break;
+    }
+
+    locAPIGnssNiResponse(notifId, data);
+}
+
+// these apis using LocationAPIControlClient
+void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags)
+{
+    LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags);
+    if (mControlClient == nullptr) {
+        return;
+    }
+    GnssAidingData data;
+    memset(&data, 0, sizeof (GnssAidingData));
+    data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS_BIT |
+        GNSS_AIDING_DATA_SV_TYPE_GLONASS_BIT |
+        GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT |
+        GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT |
+        GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT;
+
+    if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL)
+        data.deleteAll = true;
+    else {
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION)
+            data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME)
+            data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC)
+            data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA)
+            data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI)
+            data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI_BIT;
+        if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO)
+            data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB_BIT;
+    }
+    mControlClient->locAPIGnssDeleteAidingData(data);
+}
+
+void GnssAPIClient::gnssEnable(LocationTechnologyType techType)
+{
+    LOC_LOGD("%s]: (%0d)", __FUNCTION__, techType);
+    if (mControlClient == nullptr) {
+        return;
+    }
+    mControlClient->locAPIEnable(techType);
+}
+
+void GnssAPIClient::gnssDisable()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    if (mControlClient == nullptr) {
+        return;
+    }
+    mControlClient->locAPIDisable();
+}
+
+void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig)
+{
+    LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags);
+    if (mControlClient == nullptr) {
+        return;
+    }
+    mControlClient->locAPIGnssUpdateConfig(gnssConfig);
+}
+
+void GnssAPIClient::requestCapabilities() {
+    // only send capablities if it's already cached, otherwise the first time LocationAPI
+    // is initialized, capabilities will be sent by LocationAPI
+    if (mLocationCapabilitiesCached) {
+        onCapabilitiesCb(mLocationCapabilitiesMask);
+    }
+}
+
+// callbacks
+void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask)
+{
+    LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask);
+    mLocationCapabilitiesMask = capabilitiesMask;
+    mLocationCapabilitiesCached = true;
+
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    mMutex.unlock();
+
+    if (gnssCbIface != nullptr) {
+        uint32_t data = 0;
+        if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) ||
+                (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) ||
+                (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) ||
+                (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT))
+            data |= IGnssCallback::Capabilities::SCHEDULING;
+        if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT)
+            data |= IGnssCallback::Capabilities::GEOFENCING;
+        if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT)
+            data |= 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) {
+        IGnssCallback::GnssSystemInfo gnssInfo;
+        if (capabilitiesMask & LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT ||
+            capabilitiesMask & LOCATION_CAPABILITIES_AGPM_BIT) {
+            gnssInfo.yearOfHw = 2018;
+        } else if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) {
+            gnssInfo.yearOfHw = 2017;
+        } else if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) {
+            gnssInfo.yearOfHw = 2016;
+        } else {
+            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());
+        }
+    }
+}
+
+void GnssAPIClient::onTrackingCb(Location location)
+{
+    LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags);
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    mMutex.unlock();
+
+    if (gnssCbIface != nullptr) {
+        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());
+        }
+    }
+}
+
+void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification)
+{
+    LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id);
+    mMutex.lock();
+    auto gnssNiCbIface(mGnssNiCbIface);
+    mMutex.unlock();
+
+    if (gnssNiCbIface == nullptr) {
+        LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__);
+        return;
+    }
+
+    IGnssNiCallback::GnssNiNotification notificationGnss = {};
+
+    notificationGnss.notificationId = id;
+
+    if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE)
+        notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE;
+    else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL)
+        notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL;
+    else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE)
+        notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE;
+    else if (gnssNiNotification.type == GNSS_NI_TYPE_EMERGENCY_SUPL)
+        notificationGnss.niType = IGnssNiCallback::GnssNiType::EMERGENCY_SUPL;
+
+    if (gnssNiNotification.options & GNSS_NI_OPTIONS_NOTIFICATION_BIT)
+        notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY;
+    if (gnssNiNotification.options & GNSS_NI_OPTIONS_VERIFICATION_BIT)
+        notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY;
+    if (gnssNiNotification.options & GNSS_NI_OPTIONS_PRIVACY_OVERRIDE_BIT)
+        notificationGnss.notifyFlags |= IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE;
+
+    notificationGnss.timeoutSec = gnssNiNotification.timeout;
+
+    if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT)
+        notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT;
+    else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY)
+        notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY;
+    else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE ||
+            gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE)
+        notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP;
+
+    notificationGnss.requestorId = gnssNiNotification.requestor;
+
+    notificationGnss.notificationMessage = gnssNiNotification.message;
+
+    if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+        notificationGnss.requestorIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+    else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+        notificationGnss.requestorIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+    else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+        notificationGnss.requestorIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+    else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+        notificationGnss.requestorIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+    if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE)
+        notificationGnss.notificationIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_NONE;
+    else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT)
+        notificationGnss.notificationIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT;
+    else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8)
+        notificationGnss.notificationIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8;
+    else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2)
+        notificationGnss.notificationIdEncoding =
+            IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2;
+
+    gnssNiCbIface->niNotifyCb(notificationGnss);
+}
+
+void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification)
+{
+    LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count);
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    mMutex.unlock();
+
+    if (gnssCbIface != nullptr) {
+        IGnssCallback::GnssSvStatus svStatus;
+        convertGnssSvStatus(gnssSvNotification, svStatus);
+        auto r = gnssCbIface->gnssSvStatusCb(svStatus);
+        if (!r.isOk()) {
+            LOC_LOGE("%s] Error from gnssSvStatusCb description=%s",
+                __func__, r.description().c_str());
+        }
+    }
+}
+
+void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification)
+{
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    mMutex.unlock();
+
+    if (gnssCbIface != nullptr) {
+        const std::string s(gnssNmeaNotification.nmea);
+        std::stringstream ss(s);
+        std::string each;
+        while(std::getline(ss, each, '\n')) {
+            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());
+            }
+        }
+    }
+}
+
+void GnssAPIClient::onStartTrackingCb(LocationError error)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    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());
+        }
+    }
+}
+
+void GnssAPIClient::onStopTrackingCb(LocationError error)
+{
+    LOC_LOGD("%s]: (%d)", __FUNCTION__, error);
+    mMutex.lock();
+    auto gnssCbIface(mGnssCbIface);
+    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());
+        }
+    }
+}
+
+static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out)
+{
+    memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus));
+    out.numSvs = in.count;
+    if (out.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+        LOC_LOGW("%s]: Too many satellites %u. Clamps to %d.",
+                __FUNCTION__,  out.numSvs, V1_0::GnssMax::SVS_COUNT);
+        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);
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
+            info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
+            info.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;
+        if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_CARRIER_FREQUENCY_BIT)
+            info.svFlag |= IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY;
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/location_api/GnssAPIClient.h b/android/2.0/location_api/GnssAPIClient.h
new file mode 100644
index 0000000..a129cee
--- /dev/null
+++ b/android/2.0/location_api/GnssAPIClient.h
@@ -0,0 +1,108 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GNSS_API_CLINET_H
+#define GNSS_API_CLINET_H
+
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnss.h>
+//#include <android/hardware/gnss/1.1/IGnssCallback.h>
+#include <LocationAPIClientBase.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class GnssAPIClient : public LocationAPIClientBase
+{
+public:
+    GnssAPIClient(const sp<V1_0::IGnssCallback>& gpsCb,
+            const sp<V1_0::IGnssNiCallback>& niCb);
+    virtual ~GnssAPIClient();
+    GnssAPIClient(const GnssAPIClient&) = delete;
+    GnssAPIClient& operator=(const GnssAPIClient&) = delete;
+
+    // for GpsInterface
+    void gnssUpdateCallbacks(const sp<V1_0::IGnssCallback>& gpsCb,
+            const sp<V1_0::IGnssNiCallback>& niCb);
+    bool gnssStart();
+    bool gnssStop();
+    bool gnssSetPositionMode(V1_0::IGnss::GnssPositionMode mode,
+            V1_0::IGnss::GnssPositionRecurrence recurrence,
+            uint32_t minIntervalMs,
+            uint32_t preferredAccuracyMeters,
+            uint32_t preferredTimeMs,
+            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+            uint32_t timeBetweenMeasurement = 0);
+
+    // for GpsNiInterface
+    void gnssNiRespond(int32_t notifId, V1_0::IGnssNiCallback::GnssUserResponseType userResponse);
+
+    // these apis using LocationAPIControlClient
+    void gnssDeleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags);
+    void gnssEnable(LocationTechnologyType techType);
+    void gnssDisable();
+    void gnssConfigurationUpdate(const GnssConfig& gnssConfig);
+
+    inline LocationCapabilitiesMask gnssGetCapabilities() const {
+        return mLocationCapabilitiesMask;
+    }
+    void requestCapabilities();
+
+    // callbacks we are interested in
+    void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final;
+    void onTrackingCb(Location location) final;
+    void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final;
+    void onGnssSvCb(GnssSvNotification gnssSvNotification) final;
+    void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final;
+
+    void onStartTrackingCb(LocationError error) final;
+    void onStopTrackingCb(LocationError error) final;
+
+private:
+    sp<V1_0::IGnssCallback> mGnssCbIface;
+    sp<V1_0::IGnssNiCallback> mGnssNiCbIface;
+    std::mutex mMutex;
+    LocationAPIControlClient* mControlClient;
+    LocationCapabilitiesMask mLocationCapabilitiesMask;
+    bool mLocationCapabilitiesCached;
+    TrackingOptions mTrackingOptions;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+#endif // GNSS_API_CLINET_H
diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp
new file mode 100644
index 0000000..c921154
--- /dev/null
+++ b/android/2.0/location_api/LocationUtil.cpp
@@ -0,0 +1,206 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <LocationUtil.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssLocation;
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+using ::android::hardware::gnss::V1_0::GnssLocationFlags;
+
+void convertGnssLocation(Location& in, GnssLocation& out)
+{
+    memset(&out, 0, sizeof(GnssLocation));
+    if (in.flags & LOCATION_HAS_LAT_LONG_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG;
+        out.latitudeDegrees = in.latitude;
+        out.longitudeDegrees = in.longitude;
+    }
+    if (in.flags & LOCATION_HAS_ALTITUDE_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE;
+        out.altitudeMeters = in.altitude;
+    }
+    if (in.flags & LOCATION_HAS_SPEED_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED;
+        out.speedMetersPerSec = in.speed;
+    }
+    if (in.flags & LOCATION_HAS_BEARING_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING;
+        out.bearingDegrees = in.bearing;
+    }
+    if (in.flags & LOCATION_HAS_ACCURACY_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY;
+        out.horizontalAccuracyMeters = in.accuracy;
+    }
+    if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY;
+        out.verticalAccuracyMeters = in.verticalAccuracy;
+    }
+    if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY;
+        out.speedAccuracyMetersPerSecond = in.speedAccuracy;
+    }
+    if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) {
+        out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY;
+        out.bearingAccuracyDegrees = in.bearingAccuracy;
+    }
+
+    out.timestamp = static_cast<V1_0::GnssUtcTime>(in.timestamp);
+}
+
+void convertGnssLocation(const GnssLocation& in, Location& out)
+{
+    memset(&out, 0, sizeof(out));
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) {
+        out.flags |= LOCATION_HAS_LAT_LONG_BIT;
+        out.latitude = in.latitudeDegrees;
+        out.longitude = in.longitudeDegrees;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) {
+        out.flags |= LOCATION_HAS_ALTITUDE_BIT;
+        out.altitude = in.altitudeMeters;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) {
+        out.flags |= LOCATION_HAS_SPEED_BIT;
+        out.speed = in.speedMetersPerSec;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+        out.flags |= LOCATION_HAS_BEARING_BIT;
+        out.bearing = in.bearingDegrees;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
+        out.flags |= LOCATION_HAS_ACCURACY_BIT;
+        out.accuracy = in.horizontalAccuracyMeters;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+        out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT;
+        out.verticalAccuracy = in.verticalAccuracyMeters;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+        out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT;
+        out.speedAccuracy = in.speedAccuracyMetersPerSecond;
+    }
+    if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+        out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT;
+        out.bearingAccuracy = in.bearingAccuracyDegrees;
+    }
+
+    out.timestamp = static_cast<uint64_t>(in.timestamp);
+}
+
+void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out)
+{
+    switch(in) {
+        case GNSS_SV_TYPE_GPS:
+            out = GnssConstellationType::GPS;
+            break;
+        case GNSS_SV_TYPE_SBAS:
+            out = GnssConstellationType::SBAS;
+            break;
+        case GNSS_SV_TYPE_GLONASS:
+            out = GnssConstellationType::GLONASS;
+            break;
+        case GNSS_SV_TYPE_QZSS:
+            out = GnssConstellationType::QZSS;
+            break;
+        case GNSS_SV_TYPE_BEIDOU:
+            out = GnssConstellationType::BEIDOU;
+            break;
+        case GNSS_SV_TYPE_GALILEO:
+            out = GnssConstellationType::GALILEO;
+            break;
+        case GNSS_SV_TYPE_UNKNOWN:
+        default:
+            out = GnssConstellationType::UNKNOWN;
+            break;
+    }
+}
+
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out)
+{
+    switch(in) {
+        case GNSS_EPH_TYPE_EPHEMERIS:
+            out = GnssDebug::SatelliteEphemerisType::EPHEMERIS;
+            break;
+        case GNSS_EPH_TYPE_ALMANAC:
+            out = GnssDebug::SatelliteEphemerisType::ALMANAC_ONLY;
+            break;
+        case GNSS_EPH_TYPE_UNKNOWN:
+        default:
+            out = GnssDebug::SatelliteEphemerisType::NOT_AVAILABLE;
+            break;
+    }
+}
+
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out)
+{
+    switch(in) {
+        case GNSS_EPH_SOURCE_DEMODULATED:
+            out = GnssDebug::SatelliteEphemerisSource::DEMODULATED;
+            break;
+        case GNSS_EPH_SOURCE_SUPL_PROVIDED:
+            out = GnssDebug::SatelliteEphemerisSource::SUPL_PROVIDED;
+            break;
+        case GNSS_EPH_SOURCE_OTHER_SERVER_PROVIDED:
+            out = GnssDebug::SatelliteEphemerisSource::OTHER_SERVER_PROVIDED;
+            break;
+        case GNSS_EPH_SOURCE_LOCAL:
+        case GNSS_EPH_SOURCE_UNKNOWN:
+        default:
+            out = GnssDebug::SatelliteEphemerisSource::OTHER;
+            break;
+    }
+}
+
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out)
+{
+    switch(in) {
+        case GNSS_EPH_HEALTH_GOOD:
+            out = GnssDebug::SatelliteEphemerisHealth::GOOD;
+            break;
+        case GNSS_EPH_HEALTH_BAD:
+            out = GnssDebug::SatelliteEphemerisHealth::BAD;
+            break;
+        case GNSS_EPH_HEALTH_UNKNOWN:
+        default:
+            out = GnssDebug::SatelliteEphemerisHealth::UNKNOWN;
+            break;
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/location_api/LocationUtil.h b/android/2.0/location_api/LocationUtil.h
new file mode 100644
index 0000000..c6f5ead
--- /dev/null
+++ b/android/2.0/location_api/LocationUtil.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef LOCATION_UTIL_H
+#define LOCATION_UTIL_H
+
+#include <android/hardware/gnss/1.0/types.h>
+#include <LocationAPI.h>
+#include <GnssDebug.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+void convertGnssLocation(Location& in, V1_0::GnssLocation& out);
+void convertGnssLocation(const V1_0::GnssLocation& in, Location& out);
+void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out);
+void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out);
+void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out);
+void convertGnssEphemerisHealth(GnssEphemerisHealth& in, GnssDebug::SatelliteEphemerisHealth& out);
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+#endif // LOCATION_UTIL_H
diff --git a/android/2.0/location_api/MeasurementAPIClient.cpp b/android/2.0/location_api/MeasurementAPIClient.cpp
new file mode 100644
index 0000000..bcc2234
--- /dev/null
+++ b/android/2.0/location_api/MeasurementAPIClient.cpp
@@ -0,0 +1,320 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "LocSvc_MeasurementAPIClient"
+
+#include <log_util.h>
+#include <loc_cfg.h>
+
+#include "LocationUtil.h"
+#include "MeasurementAPIClient.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V2_0::IGnssMeasurementCallback;
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+        V1_0::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+        V1_1::IGnssMeasurementCallback::GnssData& out);
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+        V1_0::IGnssMeasurementCallback::GnssMeasurement& out);
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out);
+
+MeasurementAPIClient::MeasurementAPIClient() :
+    mGnssMeasurementCbIface(nullptr),
+    mGnssMeasurementCbIface_1_1(nullptr),
+    mTracking(false)
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+MeasurementAPIClient::~MeasurementAPIClient()
+{
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+}
+
+// for GpsInterface
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback(const sp<V1_0::IGnssMeasurementCallback>& callback)
+{
+    LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
+
+    mMutex.lock();
+    mGnssMeasurementCbIface = callback;
+    mMutex.unlock();
+
+    return startTracking();
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::measurementSetCallback_1_1(
+        const sp<V1_1::IGnssMeasurementCallback>& callback,
+        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+    LOC_LOGD("%s]: (%p) (powermode: %d) (tbm: %d)",
+            __FUNCTION__, &callback, (int)powerMode, timeBetweenMeasurement);
+
+    mMutex.lock();
+    mGnssMeasurementCbIface_1_1 = callback;
+    mMutex.unlock();
+
+    return startTracking(powerMode, timeBetweenMeasurement);
+}
+
+Return<IGnssMeasurement::GnssMeasurementStatus>
+MeasurementAPIClient::startTracking(
+        GnssPowerMode powerMode, uint32_t timeBetweenMeasurement)
+{
+    LocationCallbacks locationCallbacks;
+    memset(&locationCallbacks, 0, sizeof(LocationCallbacks));
+    locationCallbacks.size = sizeof(LocationCallbacks);
+
+    locationCallbacks.trackingCb = nullptr;
+    locationCallbacks.batchingCb = nullptr;
+    locationCallbacks.geofenceBreachCb = nullptr;
+    locationCallbacks.geofenceStatusCb = nullptr;
+    locationCallbacks.gnssLocationInfoCb = nullptr;
+    locationCallbacks.gnssNiCb = nullptr;
+    locationCallbacks.gnssSvCb = nullptr;
+    locationCallbacks.gnssNmeaCb = nullptr;
+
+    locationCallbacks.gnssMeasurementsCb = nullptr;
+    if (mGnssMeasurementCbIface_1_1 != nullptr || mGnssMeasurementCbIface != nullptr) {
+        locationCallbacks.gnssMeasurementsCb =
+            [this](GnssMeasurementsNotification gnssMeasurementsNotification) {
+                onGnssMeasurementsCb(gnssMeasurementsNotification);
+            };
+    }
+
+    locAPISetCallbacks(locationCallbacks);
+
+    TrackingOptions options = {};
+    memset(&options, 0, sizeof(TrackingOptions));
+    options.size = sizeof(TrackingOptions);
+    options.minInterval = 1000;
+    options.mode = GNSS_SUPL_MODE_STANDALONE;
+    if (GNSS_POWER_MODE_INVALID != powerMode) {
+        options.powerMode = powerMode;
+        options.tbm = timeBetweenMeasurement;
+    }
+
+    mTracking = true;
+    LOC_LOGD("%s]: start tracking session", __FUNCTION__);
+    locAPIStartTracking(options);
+    return IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
+}
+
+// for GpsMeasurementInterface
+void MeasurementAPIClient::measurementClose() {
+    LOC_LOGD("%s]: ()", __FUNCTION__);
+    mTracking = false;
+    locAPIStopTracking();
+}
+
+// callbacks
+void MeasurementAPIClient::onGnssMeasurementsCb(
+        GnssMeasurementsNotification gnssMeasurementsNotification)
+{
+    LOC_LOGD("%s]: (count: %zu active: %d)",
+            __FUNCTION__, gnssMeasurementsNotification.count, mTracking);
+    if (mTracking) {
+        mMutex.lock();
+        sp<V1_0::IGnssMeasurementCallback> gnssMeasurementCbIface = nullptr;
+        sp<V1_1::IGnssMeasurementCallback> gnssMeasurementCbIface_1_1 = nullptr;
+        if (mGnssMeasurementCbIface_1_1 != nullptr) {
+            gnssMeasurementCbIface_1_1 = mGnssMeasurementCbIface_1_1;
+        } else if (mGnssMeasurementCbIface != nullptr) {
+            gnssMeasurementCbIface = mGnssMeasurementCbIface;
+        }
+        mMutex.unlock();
+
+        if (gnssMeasurementCbIface_1_1 != nullptr) {
+            V1_1::IGnssMeasurementCallback::GnssData gnssData;
+            convertGnssData_1_1(gnssMeasurementsNotification, gnssData);
+            auto r = gnssMeasurementCbIface_1_1->gnssMeasurementCb(gnssData);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from gnssMeasurementCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        } else if (gnssMeasurementCbIface != nullptr) {
+            V1_0::IGnssMeasurementCallback::GnssData gnssData;
+            convertGnssData(gnssMeasurementsNotification, gnssData);
+            auto r = gnssMeasurementCbIface->GnssMeasurementCb(gnssData);
+            if (!r.isOk()) {
+                LOC_LOGE("%s] Error from GnssMeasurementCb description=%s",
+                    __func__, r.description().c_str());
+            }
+        }
+    }
+}
+
+static void convertGnssMeasurement(GnssMeasurementsData& in,
+        V1_0::IGnssMeasurementCallback::GnssMeasurement& out)
+{
+    memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssMeasurement));
+    if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR;
+    if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY;
+    if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES;
+    if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE;
+    if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY;
+    if (in.flags & GNSS_MEASUREMENTS_DATA_AUTOMATIC_GAIN_CONTROL_BIT)
+        out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL;
+    out.svid = in.svId;
+    convertGnssConstellationType(in.svType, out.constellation);
+    out.timeOffsetNs = in.timeOffsetNs;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK;
+    if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC;
+    if (in.stateMask &  GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT)
+        out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC;
+    out.receivedSvTimeInNs = in.receivedSvTimeNs;
+    out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs;
+    out.cN0DbHz = in.carrierToNoiseDbHz;
+    out.pseudorangeRateMps = in.pseudorangeRateMps;
+    out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps;
+    if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT)
+        out.accumulatedDeltaRangeState |=
+            IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID;
+    if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT)
+        out.accumulatedDeltaRangeState |=
+            IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET;
+    if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT)
+        out.accumulatedDeltaRangeState |=
+            IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP;
+    out.accumulatedDeltaRangeM = in.adrMeters;
+    out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters;
+    out.carrierFrequencyHz = in.carrierFrequencyHz;
+    out.carrierCycles = in.carrierCycles;
+    out.carrierPhase = in.carrierPhase;
+    out.carrierPhaseUncertainty = in.carrierPhaseUncertainty;
+    uint8_t indicator =
+        static_cast<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
+    if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
+        indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
+    if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
+        indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
+    out.multipathIndicator =
+        static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
+    out.snrDb = in.signalToNoiseRatioDb;
+    out.agcLevelDb = in.agcLevelDb;
+}
+
+static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out)
+{
+    memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock));
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT;
+    if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT)
+        out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY;
+    out.leapSecond = in.leapSecond;
+    out.timeNs = in.timeNs;
+    out.timeUncertaintyNs = in.timeUncertaintyNs;
+    out.fullBiasNs = in.fullBiasNs;
+    out.biasNs = in.biasNs;
+    out.biasUncertaintyNs = in.biasUncertaintyNs;
+    out.driftNsps = in.driftNsps;
+    out.driftUncertaintyNsps = in.driftUncertaintyNsps;
+    out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount;
+}
+
+static void convertGnssData(GnssMeasurementsNotification& in,
+        V1_0::IGnssMeasurementCallback::GnssData& out)
+{
+    out.measurementCount = in.count;
+    if (out.measurementCount > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+        LOC_LOGW("%s]: Too many measurement %u. Clamps to %d.",
+                __FUNCTION__,  out.measurementCount, V1_0::GnssMax::SVS_COUNT);
+        out.measurementCount = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+    }
+    for (size_t i = 0; i < out.measurementCount; i++) {
+        convertGnssMeasurement(in.measurements[i], out.measurements[i]);
+    }
+    convertGnssClock(in.clock, out.clock);
+}
+
+static void convertGnssData_1_1(GnssMeasurementsNotification& in,
+        V1_1::IGnssMeasurementCallback::GnssData& out)
+{
+    out.measurements.resize(in.count);
+    for (size_t i = 0; i < in.count; i++) {
+        convertGnssMeasurement(in.measurements[i], out.measurements[i].v1_0);
+    }
+    convertGnssClock(in.clock, out.clock);
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/2.0/location_api/MeasurementAPIClient.h b/android/2.0/location_api/MeasurementAPIClient.h
new file mode 100644
index 0000000..db2c2fa
--- /dev/null
+++ b/android/2.0/location_api/MeasurementAPIClient.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation, nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MEASUREMENT_API_CLINET_H
+#define MEASUREMENT_API_CLINET_H
+
+#include <mutex>
+#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
+//#include <android/hardware/gnss/1.1/IGnssMeasurementCallback.h>
+#include <LocationAPIClientBase.h>
+#include <hidl/Status.h>
+#include <gps_extended_c.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V2_0 {
+namespace implementation {
+
+using ::android::sp;
+
+class MeasurementAPIClient : public LocationAPIClientBase
+{
+public:
+    MeasurementAPIClient();
+    virtual ~MeasurementAPIClient();
+    MeasurementAPIClient(const MeasurementAPIClient&) = delete;
+    MeasurementAPIClient& operator=(const MeasurementAPIClient&) = delete;
+
+    // for GpsMeasurementInterface
+    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback(
+            const sp<V1_0::IGnssMeasurementCallback>& callback);
+    Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> measurementSetCallback_1_1(
+            const sp<V1_1::IGnssMeasurementCallback>& callback,
+            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+    void measurementClose();
+    Return<IGnssMeasurement::GnssMeasurementStatus> startTracking(
+            GnssPowerMode powerMode = GNSS_POWER_MODE_INVALID,
+            uint32_t timeBetweenMeasurement = GPS_DEFAULT_FIX_INTERVAL_MS);
+
+    // callbacks we are interested in
+    void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final;
+
+private:
+    std::mutex mMutex;
+    sp<V1_0::IGnssMeasurementCallback> mGnssMeasurementCbIface;
+    sp<V1_1::IGnssMeasurementCallback> mGnssMeasurementCbIface_1_1;
+
+    bool mTracking;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+#endif // MEASUREMENT_API_CLINET_H
diff --git a/android/2.0/service.cpp b/android/2.0/service.cpp
new file mode 100644
index 0000000..1fdccab
--- /dev/null
+++ b/android/2.0/service.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "android.hardware.gnss@2.0-service-qti"
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <hidl/LegacySupport.h>
+#include "loc_cfg.h"
+
+extern "C" {
+#include "vndfwk-detect.h"
+}
+using android::hardware::gnss::V2_0::IGnss;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    bool vendorEnhanced = isRunningWithVendorEnhancedFramework();
+    setVendorEnhanced(vendorEnhanced);
+
+    if (!vendorEnhanced) {
+        return defaultPassthroughServiceImplementation<IGnss>();
+    } else {
+        return -1;
+    }
+}
diff --git a/android/Android.mk b/android/Android.mk
index bff117e..c1bdd59 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -1,5 +1,8 @@
 LOCAL_PATH := $(call my-dir)
 ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),)
+ifeq ($(GNSS_HIDL_VERSION),2.0)
+include $(LOCAL_PATH)/2.0/Android.mk
+else
 ifeq ($(GNSS_HIDL_VERSION),1.1)
 include $(LOCAL_PATH)/1.1/Android.mk
 else
@@ -7,4 +10,6 @@
 endif
 else #QMAA flag set, build dummy android.hardware.gnss@1.0-impl-qti
 include $(LOCAL_PATH)/dummy/Android.mk
+endif
+
 endif #BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE
diff --git a/android/dummy/Android.mk b/android/dummy/Android.mk
index d438888..05114e1 100644
--- a/android/dummy/Android.mk
+++ b/android/dummy/Android.mk
@@ -1,9 +1,9 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-#build dummy android.hardware.gnss@1.0-impl-qti
+#build dummy android.hardware.gnss@2.0-impl-qti
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti
+LOCAL_MODULE := android.hardware.gnss@2.0-impl-qti
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := GnssDummy.cpp
@@ -20,19 +20,11 @@
 LOCAL_CFLAGS += $(GNSS_CFLAGS)
 include $(BUILD_SHARED_LIBRARY)
 
-BUILD_GNSS_HIDL_SERVICE := true
-ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true)
-ifneq ($(LW_FEATURE_SET),true)
-#BUILD_GNSS_HIDL_SERVICE := false
-endif # LW_FEATURE_SET
-endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET
-
-ifeq ($(BUILD_GNSS_HIDL_SERVICE), true)
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.gnss@1.0-service-qti
+LOCAL_MODULE := android.hardware.gnss@2.0-service-qti
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc
+LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc
 LOCAL_SRC_FILES := \
     serviceDummy.cpp \
 
@@ -60,4 +52,3 @@
 
 LOCAL_CFLAGS += $(GNSS_CFLAGS)
 include $(BUILD_EXECUTABLE)
-endif # BUILD_GNSS_HIDL_SERVICE
diff --git a/android/dummy/android.hardware.gnss@1.0-service-qti.rc b/android/dummy/android.hardware.gnss@1.0-service-qti.rc
deleted file mode 100644
index b5da6f9..0000000
--- a/android/dummy/android.hardware.gnss@1.0-service-qti.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-qti
-    class hal
-    user gps
-    group system gps radio
diff --git a/android/dummy/android.hardware.gnss@2.0-service-qti.rc b/android/dummy/android.hardware.gnss@2.0-service-qti.rc
new file mode 100644
index 0000000..36ee47c
--- /dev/null
+++ b/android/dummy/android.hardware.gnss@2.0-service-qti.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@2.0-service-qti
+    class hal
+    user gps
+    group system gps radio
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.cpp b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
new file mode 100644
index 0000000..bca4c45
--- /dev/null
+++ b/android/measurement_corrections/1.0/MeasurementCorrections.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "LocSvc_MeasurementCorrectionsInterface"
+
+#include <log_util.h>
+#include "MeasurementCorrections.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+MeasurementCorrections::MeasurementCorrections() {
+}
+
+MeasurementCorrections::~MeasurementCorrections() {
+}
+
+Return<bool> MeasurementCorrections::setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) {
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace measurement_corrections
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/measurement_corrections/1.0/MeasurementCorrections.h b/android/measurement_corrections/1.0/MeasurementCorrections.h
new file mode 100644
index 0000000..231c534
--- /dev/null
+++ b/android/measurement_corrections/1.0/MeasurementCorrections.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+#define ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
+
+#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace measurement_corrections {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+using ::android::hardware::gnss::V1_0::GnssLocation;
+
+struct MeasurementCorrections : public IMeasurementCorrections {
+    MeasurementCorrections();
+    ~MeasurementCorrections();
+
+// Methods from ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections follow.
+Return<bool> setCorrections(const ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections& corrections) override;
+
+};
+
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace measurement_corrections
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V1_0_MeasurementCorrections_H
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.cpp b/android/visibility_control/1.0/GnssVisibilityControl.cpp
new file mode 100644
index 0000000..5608050
--- /dev/null
+++ b/android/visibility_control/1.0/GnssVisibilityControl.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "GnssVisibilityControl.h"
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+GnssVisibilityControl::GnssVisibilityControl() {}
+GnssVisibilityControl::~GnssVisibilityControl() {}
+
+// Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+Return<bool> GnssVisibilityControl::enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) {
+    return true;
+}
+/**
+ * Registers the callback for HAL implementation to use.
+ *
+ * @param callback Handle to IGnssVisibilityControlCallback interface.
+ */
+Return<bool> GnssVisibilityControl::setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) {
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace visibility_control
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/android/visibility_control/1.0/GnssVisibilityControl.h b/android/visibility_control/1.0/GnssVisibilityControl.h
new file mode 100644
index 0000000..3023347
--- /dev/null
+++ b/android/visibility_control/1.0/GnssVisibilityControl.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+#define ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
+
+#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <location_interface.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace visibility_control {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct GnssVisibilityControl : public IGnssVisibilityControl {
+    GnssVisibilityControl();
+    ~GnssVisibilityControl();
+
+    // Methods from ::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl follow.
+    Return<bool> enableNfwLocationAccess(const hidl_vec<::android::hardware::hidl_string>& proxyApps) override;
+    /**
+     * Registers the callback for HAL implementation to use.
+     *
+     * @param callback Handle to IGnssVisibilityControlCallback interface.
+     */
+    Return<bool> setCallback(const ::android::sp<::android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback>& callback) override;
+
+};
+
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace visibility_control
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V1_0_GnssVisibilityControl_H
diff --git a/build/target_specific_features.mk b/build/target_specific_features.mk
index 0c0f730..447f860 100644
--- a/build/target_specific_features.mk
+++ b/build/target_specific_features.mk
@@ -36,11 +36,14 @@
 GNSS_HIDL_1_0_TARGET_LIST += qcs605
 GNSS_HIDL_1_0_TARGET_LIST += sdm845
 GNSS_HIDL_1_0_TARGET_LIST += sdm660
-GNSS_HIDL_1_1_TARGET_LIST := msmnile
+GNSS_HIDL_2_0_TARGET_LIST := msmnile
 GNSS_HIDL_1_1_TARGET_LIST += $(MSMSTEPPE)
 GNSS_HIDL_1_1_TARGET_LIST += $(TRINKET)
 
 
+ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
+GNSS_HIDL_VERSION = 2.0
+endif
 ifneq (,$(filter $(GNSS_HIDL_1_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
 GNSS_HIDL_VERSION = 1.0
 endif