[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/connectivity/gps/service/1.0/AGnss.cpp b/src/connectivity/gps/service/1.0/AGnss.cpp
new file mode 100644
index 0000000..29c6ddd
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/AGnss.cpp
@@ -0,0 +1,198 @@
+/*
+ * 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_AGnssInterface"
+
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnss::sThreadFuncArgsList;
+sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr;
+bool AGnss::sInterfaceExists = false;
+
+AGpsCallbacks AGnss::sAGnssCb = {
+    .status_cb = statusCb,
+    .create_thread_cb = createThreadCb
+};
+
+AGnss::AGnss(const AGpsInterface* aGpsIface) : mAGnssIface(aGpsIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+AGnss::~AGnss() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+void AGnss::statusCb(AGpsStatus* status) {
+    if (sAGnssCbIface == nullptr) {
+        ALOGE("%s: AGNSS Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (status == nullptr) {
+        ALOGE("AGNSS status is invalid");
+        return;
+    }
+
+    /*
+     * Logic based on AGnssStatus processing by GnssLocationProvider. Size of
+     * AGpsStatus is checked for backward compatibility since some devices may
+     * be sending out an older version of AGpsStatus that only supports IPv4.
+     */
+    size_t statusSize = status->size;
+    if (status->size == sizeof(AGpsStatus)) {
+        switch (status->addr.ss_family)
+        {
+            case AF_INET:
+                {
+                    /*
+                     * ss_family indicates IPv4.
+                     */
+                    struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(&(status->addr));
+                    IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+                        .type = static_cast<IAGnssCallback::AGnssType>(status->type),
+                        .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+                        .ipV4Addr = in->sin_addr.s_addr,
+                    };
+
+                    /*
+                     * Callback to client with agnssStatusIpV4Cb.
+                     */
+                    auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+                    if (!ret.isOk()) {
+                        ALOGE("%s: Unable to invoke callback", __func__);
+                    }
+                    break;
+                }
+            case AF_INET6:
+                {
+                    /*
+                     * ss_family indicates IPv6. Callback to client with agnssStatusIpV6Cb.
+                     */
+                    IAGnssCallback::AGnssStatusIpV6 aGnssStatusIpV6;
+
+                    aGnssStatusIpV6.type = static_cast<IAGnssCallback::AGnssType>(status->type);
+                    aGnssStatusIpV6.status = static_cast<IAGnssCallback::AGnssStatusValue>(
+                            status->status);
+
+                    struct sockaddr_in6* in6 = reinterpret_cast<struct sockaddr_in6 *>(
+                            &(status->addr));
+                    memcpy(&(aGnssStatusIpV6.ipV6Addr[0]), in6->sin6_addr.s6_addr,
+                           aGnssStatusIpV6.ipV6Addr.size());
+                    auto ret = sAGnssCbIface->agnssStatusIpV6Cb(aGnssStatusIpV6);
+                    if (!ret.isOk()) {
+                        ALOGE("%s: Unable to invoke callback", __func__);
+                    }
+                    break;
+                }
+             default:
+                    ALOGE("Invalid ss_family found: %d", status->addr.ss_family);
+        }
+    } else if (statusSize >= sizeof(AGpsStatus_v2)) {
+        AGpsStatus_v2* statusV2 = reinterpret_cast<AGpsStatus_v2*>(status);
+        uint32_t ipV4Addr = statusV2->ipaddr;
+        IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+            .type = static_cast<IAGnssCallback::AGnssType>(AF_INET),
+            .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+            /*
+             * For older versions of AGpsStatus, change IP addr to net order. This
+             * was earlier being done in GnssLocationProvider.
+             */
+            .ipV4Addr = htonl(ipV4Addr)
+        };
+        /*
+         * Callback to client with agnssStatusIpV4Cb.
+         */
+        auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+        if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid size for AGPS Status", __func__);
+    }
+}
+
+pthread_t AGnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+/*
+ * Implementation of methods from ::android::hardware::gnss::V1_0::IAGnss follow.
+ */
+Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return Void();
+    }
+
+    sAGnssCbIface = callback;
+
+    mAGnssIface->init(&sAGnssCb);
+    return Void();
+}
+
+Return<bool> AGnss::dataConnClosed()  {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_closed() == 0);
+}
+
+Return<bool> AGnss::dataConnFailed()  {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_failed() == 0);
+}
+
+Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
+                              const hidl_string& hostname,
+                              int32_t port) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->set_server(static_cast<AGpsType>(type), hostname.c_str(), port) == 0);
+}
+
+Return<bool> AGnss::dataConnOpen(const hidl_string& apn, IAGnss::ApnIpType apnIpType) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_open_with_apn_ip_type(apn.c_str(),
+                                                     static_cast<uint16_t>(apnIpType)) == 0);
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/AGnss.h b/src/connectivity/gps/service/1.0/AGnss.h
new file mode 100644
index 0000000..2a8eed0
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/AGnss.h
@@ -0,0 +1,85 @@
+/*
+ * 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_V1_0_AGnss_H_
+#define android_hardware_gnss_V1_0_AGnss_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnss.h>
+#include <hardware/gps_internal.h>
+#include <hidl/Status.h>
+#include <netinet/in.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnss;
+using ::android::hardware::gnss::V1_0::IAGnssCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Extended interface for AGNSS support. Also contains wrapper methods to allow
+ * methods from IAGnssCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct AGnss : public IAGnss {
+    AGnss(const AGpsInterface* agpsIface);
+    ~AGnss();
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
+     * These declarations were generated from IAGnss.hal.
+     */
+    Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
+    Return<bool> dataConnClosed() override;
+    Return<bool> dataConnFailed() override;
+    Return<bool> setServer(IAGnssCallback::AGnssType type,
+                         const hidl_string& hostname, int32_t port) override;
+    Return<bool> dataConnOpen(const hidl_string& apn,
+                                           IAGnss::ApnIpType apnIpType) override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IAGnss base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void statusCb(AGpsStatus* status);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static AGpsCallbacks sAGnssCb;
+
+ private:
+    const AGpsInterface* mAGnssIface = nullptr;
+    static sp<IAGnssCallback> sAGnssCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_AGnss_H_
diff --git a/src/connectivity/gps/service/1.0/AGnssRil.cpp b/src/connectivity/gps/service/1.0/AGnssRil.cpp
new file mode 100644
index 0000000..1458327
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/AGnssRil.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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_AGnssRilInterface"
+
+#include "AGnssRil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnssRil::sThreadFuncArgsList;
+sp<IAGnssRilCallback> AGnssRil::sAGnssRilCbIface = nullptr;
+bool AGnssRil::sInterfaceExists = false;
+
+AGpsRilCallbacks AGnssRil::sAGnssRilCb = {
+    .request_setid = AGnssRil::requestSetId,
+    .request_refloc = AGnssRil::requestRefLoc,
+    .create_thread_cb = AGnssRil::createThreadCb
+};
+
+AGnssRil::AGnssRil(const AGpsRilInterface* aGpsRilIface) : mAGnssRilIface(aGpsRilIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+AGnssRil::~AGnssRil() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+void AGnssRil::requestSetId(uint32_t flags) {
+    if (sAGnssRilCbIface == nullptr) {
+        ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sAGnssRilCbIface->requestSetIdCb(flags);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void AGnssRil::requestRefLoc(uint32_t /*flags*/) {
+    if (sAGnssRilCbIface == nullptr) {
+        ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sAGnssRilCbIface->requestRefLocCb();
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+pthread_t AGnssRil::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+Return<void> AGnssRil::setCallback(const sp<IAGnssRilCallback>& callback)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return Void();
+    }
+
+    sAGnssRilCbIface = callback;
+
+    mAGnssRilIface->init(&sAGnssRilCb);
+    return Void();
+}
+
+Return<void> AGnssRil::setRefLocation(const IAGnssRil::AGnssRefLocation& aGnssRefLocation)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return Void();
+    }
+
+    AGpsRefLocation aGnssRefloc;
+    aGnssRefloc.type = static_cast<uint16_t>(aGnssRefLocation.type);
+
+    auto& cellID = aGnssRefLocation.cellID;
+    aGnssRefloc.u.cellID = {
+        .type = static_cast<uint16_t>(cellID.type),
+        .mcc = cellID.mcc,
+        .mnc = cellID.mnc,
+        .lac = cellID.lac,
+        .cid = cellID.cid,
+        .tac = cellID.tac,
+        .pcid = cellID.pcid
+    };
+
+    mAGnssRilIface->set_ref_location(&aGnssRefloc, sizeof(aGnssRefloc));
+    return Void();
+}
+
+Return<bool> AGnssRil::setSetId(IAGnssRil::SetIDType type, const hidl_string& setid)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->set_set_id(static_cast<uint16_t>(type), setid.c_str());
+    return true;
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected,
+                                          IAGnssRil::NetworkType type,
+                                          bool roaming) {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->update_network_state(connected,
+                                         static_cast<int>(type),
+                                         roaming,
+                                         nullptr /* extra_info */);
+    return true;
+}
+
+Return<bool> AGnssRil::updateNetworkAvailability(bool available, const hidl_string& apn)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->update_network_availability(available, apn.c_str());
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/AGnssRil.h b/src/connectivity/gps/service/1.0/AGnssRil.h
new file mode 100644
index 0000000..6215a9e
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/AGnssRil.h
@@ -0,0 +1,88 @@
+/*
+ * 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_V1_0_AGnssRil_H_
+#define android_hardware_gnss_V1_0_AGnssRil_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnssRil.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnssRil;
+using ::android::hardware::gnss::V1_0::IAGnssRilCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * 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 IAGnssRil {
+    AGnssRil(const AGpsRilInterface* aGpsRilIface);
+    ~AGnssRil();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+     * These declarations were generated from IAGnssRil.hal.
+     */
+    Return<void> setCallback(const sp<IAGnssRilCallback>& callback) override;
+    Return<void> setRefLocation(const IAGnssRil::AGnssRefLocation& agnssReflocation) override;
+    Return<bool> setSetId(IAGnssRil::SetIDType type, const hidl_string& setid) override;
+    Return<bool> updateNetworkState(bool connected,
+                                    IAGnssRil::NetworkType type,
+                                    bool roaming) override;
+    Return<bool> updateNetworkAvailability(bool available, const hidl_string& apn) override;
+    static void requestSetId(uint32_t flags);
+    static void requestRefLoc(uint32_t flags);
+
+    /*
+     * Callback method to be passed into the conventional GNSS HAL by the default
+     * implementation. This method is not part of the IAGnssRil base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static AGpsRilCallbacks sAGnssRilCb;
+
+ private:
+    const AGpsRilInterface* mAGnssRilIface = nullptr;
+    static sp<IAGnssRilCallback> sAGnssRilCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_AGnssRil_H_
diff --git a/src/connectivity/gps/service/1.0/Android.mk b/src/connectivity/gps/service/1.0/Android.mk
new file mode 100644
index 0000000..db53aff
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/Android.mk
@@ -0,0 +1,63 @@
+#ifdef HIDL_V1_0
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.0-impl-mediatek
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := mtk
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    ThreadCreationWrapper.cpp \
+    AGnss.cpp \
+    AGnssRil.cpp \
+    Gnss.cpp \
+    GnssBatching.cpp \
+    GnssDebug.cpp \
+    GnssGeofencing.cpp \
+    GnssMeasurement.cpp \
+    GnssNavigationMessage.cpp \
+    GnssNi.cpp \
+    GnssXtra.cpp \
+    GnssConfiguration.cpp \
+    GnssUtils.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libhidlbase \
+    libhidltransport \
+    libutils \
+    android.hardware.gnss@1.0 \
+    libhardware \
+
+LOCAL_CFLAGS += -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := mtk
+LOCAL_MODULE := android.hardware.gnss@1.0-service-mediatek
+LOCAL_INIT_RC := android.hardware.gnss@1.0-service-mediatek.rc
+LOCAL_SRC_FILES := \
+    service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libhardware \
+    libbinder \
+    libhidlbase \
+    libhidltransport \
+    android.hardware.gnss@1.0 \
+
+LOCAL_REQUIRED_MODULES := \
+    android.hardware.gnss@1.0-impl-mediatek
+
+include $(BUILD_EXECUTABLE)
+
+#endif
diff --git a/src/connectivity/gps/service/1.0/Gnss.cpp b/src/connectivity/gps/service/1.0/Gnss.cpp
new file mode 100644
index 0000000..c91e67a
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/Gnss.cpp
@@ -0,0 +1,816 @@
+/*
+ * 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_GnssInterface"
+
+#include "Gnss.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+#ifndef UNUSED
+#define UNUSED(x) (x)=(x)
+#endif
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> Gnss::sThreadFuncArgsList;
+sp<IGnssCallback> Gnss::sGnssCbIface = nullptr;
+bool Gnss::sInterfaceExists = false;
+bool Gnss::sWakelockHeldGnss = false;
+bool Gnss::sWakelockHeldFused = false;
+
+GpsCallbacks_ext Gnss::sGnssCb = {
+    .size = sizeof(GpsCallbacks_ext),
+    .location_cb = locationCb,
+    .status_cb = statusCb,
+    .sv_status_cb = gpsSvStatusCb,
+    .nmea_cb = nmeaCb,
+    .set_capabilities_cb = setCapabilitiesCb,
+    .acquire_wakelock_cb = acquireWakelockCb,
+    .release_wakelock_cb = releaseWakelockCb,
+    .create_thread_cb = createThreadCb,
+    .request_utc_time_cb = requestUtcTimeCb,
+    .set_system_info_cb = setSystemInfoCb,
+    .gnss_sv_status_cb = gnssSvStatusCb,
+
+    .set_name_cb = setNameCb,
+    .request_location_cb = requestLocationCb
+};
+
+uint32_t Gnss::sCapabilitiesCached = 0;
+uint16_t Gnss::sYearOfHwCached = 0;
+sem_t Gnss::sSem;
+
+Gnss::Gnss(gps_device_t_ext* gnssDevice) :
+        mDeathRecipient(new GnssHidlDeathRecipient(this)) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+
+    if (gnssDevice == nullptr) {
+        ALOGE("%s: Invalid device_t handle", __func__);
+        return;
+    }
+
+    mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
+    sem_init(&sSem, 0, 1);
+}
+
+Gnss::~Gnss() {
+    sInterfaceExists = false;
+    sThreadFuncArgsList.clear();
+    sem_destroy(&sSem);
+}
+
+void Gnss::locationCb(GpsLocation_ext* location) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (location == nullptr) {
+        ALOGE("%s: Invalid location from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    GnssLocation gnssLocation = V1_0::implementation::convertToGnssLocation(location);
+    auto ret = sGnssCbIface->gnssLocationCb(gnssLocation);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::statusCb(GpsStatus* gnssStatus) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (gnssStatus == nullptr) {
+        ALOGE("%s: Invalid GpsStatus from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssStatusValue status =
+            static_cast<IGnssCallback::GnssStatusValue>(gnssStatus->status);
+
+    auto ret = sGnssCbIface->gnssStatusCb(status);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::gnssSvStatusCb(GnssSvStatus_ext* status) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (status == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = status->num_svs;
+
+    if (svStatus.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+        ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, V1_0::GnssMax::SVS_COUNT);
+        svStatus.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+    }
+
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        auto svInfo = status->gnss_sv_list[i];
+        IGnssCallback::GnssSvInfo gnssSvInfo = {
+            .svid = svInfo.legacySvInfo.svid,
+            .constellation = static_cast<V1_0::GnssConstellationType>(
+                    svInfo.legacySvInfo.constellation),
+            .cN0Dbhz = svInfo.legacySvInfo.c_n0_dbhz,
+            .elevationDegrees = svInfo.legacySvInfo.elevation,
+            .azimuthDegrees = svInfo.legacySvInfo.azimuth,
+            .svFlag = static_cast<uint8_t>(svInfo.legacySvInfo.flags),
+            .carrierFrequencyHz = svInfo.carrier_frequency};
+        svStatus.gnssSvList[i] = gnssSvInfo;
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+/*
+ * This enum is used by gpsSvStatusCb() method below to convert GpsSvStatus
+ * to GnssSvStatus for backward compatibility. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum SvidValues : uint16_t {
+    GLONASS_SVID_OFFSET = 64,
+    GLONASS_SVID_COUNT = 24,
+    BEIDOU_SVID_OFFSET = 200,
+    BEIDOU_SVID_COUNT = 35,
+    SBAS_SVID_MIN = 33,
+    SBAS_SVID_MAX = 64,
+    SBAS_SVID_ADD = 87,
+    QZSS_SVID_MIN = 193,
+    QZSS_SVID_MAX = 200
+};
+
+/*
+ * The following code that converts GpsSvStatus to GnssSvStatus is moved here from
+ * GnssLocationProvider. GnssLocationProvider does not require it anymore since GpsSvStatus is
+ * being deprecated and is no longer part of the GNSS interface.
+ */
+void Gnss::gpsSvStatusCb(GpsSvStatus* svInfo) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (svInfo == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = svInfo->num_svs;
+    /*
+     * Clamp the list size since GnssSvStatus can support a maximum of
+     * GnssMax::SVS_COUNT entries.
+     */
+    ///M: fix max numSvs as GPS_MAX_SVS
+    if (svStatus.numSvs > static_cast<uint32_t>(GPS_MAX_SVS)) {
+        ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, GPS_MAX_SVS);
+        svStatus.numSvs = static_cast<uint32_t>(GPS_MAX_SVS);
+    }
+    /// M: mtk update end
+
+    uint32_t ephemerisMask = svInfo->ephemeris_mask;
+    uint32_t almanacMask = svInfo->almanac_mask;
+    uint32_t usedInFixMask = svInfo->used_in_fix_mask;
+    /*
+     * Conversion from GpsSvInfo to IGnssCallback::GnssSvInfo happens below.
+     */
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList[i];
+        info.svid = svInfo->sv_list[i].prn;
+        if (info.svid >= 1 && info.svid <= 32) {
+            info.constellation = GnssConstellationType::GPS;
+        } else if (info.svid > GLONASS_SVID_OFFSET &&
+                   info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
+            info.constellation = GnssConstellationType::GLONASS;
+            info.svid -= GLONASS_SVID_OFFSET;
+        } else if (info.svid > BEIDOU_SVID_OFFSET &&
+                 info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
+            info.constellation = GnssConstellationType::BEIDOU;
+            info.svid -= BEIDOU_SVID_OFFSET;
+        } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
+            info.constellation = GnssConstellationType::SBAS;
+            info.svid += SBAS_SVID_ADD;
+        } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
+            info.constellation = GnssConstellationType::QZSS;
+        } else {
+            ALOGD("Unknown constellation type with Svid = %d.", info.svid);
+            info.constellation = GnssConstellationType::UNKNOWN;
+        }
+
+        info.cN0Dbhz = svInfo->sv_list[i].snr;
+        info.elevationDegrees = svInfo->sv_list[i].elevation;
+        info.azimuthDegrees = svInfo->sv_list[i].azimuth;
+        // TODO: b/31702236
+        info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+
+        /*
+         * Only GPS info is valid for these fields, as these masks are just 32
+         * bits, by GPS prn.
+         */
+        if (info.constellation == GnssConstellationType::GPS) {
+            int32_t svidMask = (1 << (info.svid - 1));
+            if ((ephemerisMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+            }
+            if ((almanacMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+            }
+            if ((usedInFixMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+            }
+        }
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::nmeaCb(GpsUtcTime timestamp, const char* nmea, int length) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    android::hardware::hidl_string nmeaString;
+    nmeaString.setToExternal(nmea, length);
+    auto ret = sGnssCbIface->gnssNmeaCb(timestamp, nmeaString);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::setCapabilitiesCb(uint32_t capabilities) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssSetCapabilitesCb(capabilities);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sCapabilitiesCached = capabilities;
+    sem_post(&sSem);
+}
+
+void Gnss::acquireWakelockCb() {
+    acquireWakelockGnss();
+}
+
+void Gnss::releaseWakelockCb() {
+    releaseWakelockGnss();
+}
+
+
+void Gnss::acquireWakelockGnss() {
+    sWakelockHeldGnss = true;
+    updateWakelock();
+}
+
+void Gnss::releaseWakelockGnss() {
+    sWakelockHeldGnss = false;
+    updateWakelock();
+}
+
+void Gnss::acquireWakelockFused() {
+    sWakelockHeldFused = true;
+    updateWakelock();
+}
+
+void Gnss::releaseWakelockFused() {
+    sWakelockHeldFused = false;
+    updateWakelock();
+}
+
+void Gnss::updateWakelock() {
+    // Track the state of the last request - in case the wake lock in the layer above is reference
+    // counted.
+    static bool sWakelockHeld = false;
+
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (sWakelockHeldGnss || sWakelockHeldFused) {
+        if (!sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock acquired due to gps: %d, fused: %d", __func__,
+                    sWakelockHeldGnss, sWakelockHeldFused);
+            sWakelockHeld = true;
+            auto ret = sGnssCbIface->gnssAcquireWakelockCb();
+            if (!ret.isOk()) {
+                ALOGE("%s: Unable to invoke callback", __func__);
+            }
+        }
+    } else {
+        if (sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock released", __func__);
+        } else  {
+            // To avoid burning power, always release, even if logic got here with sWakelock false
+            // which it shouldn't, unless underlying *.h implementation makes duplicate requests.
+            ALOGW("%s: GNSS HAL Wakelock released, duplicate request", __func__);
+        }
+        sWakelockHeld = false;
+        auto ret = sGnssCbIface->gnssReleaseWakelockCb();
+        if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+        }
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::requestUtcTimeCb() {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssRequestTimeCb();
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+pthread_t Gnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void Gnss::setSystemInfoCb(const LegacyGnssSystemInfo* info) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (info == nullptr) {
+        ALOGE("Invalid GnssSystemInfo from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSystemInfo gnssInfo = {
+        .yearOfHw = info->year_of_hw
+    };
+
+    auto ret = sGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sYearOfHwCached = info->year_of_hw;
+    sem_post(&sSem);
+}
+
+void Gnss::setNameCb(const char* name, int length) {
+    UNUSED(name);
+    UNUSED(length);
+}
+
+void Gnss::requestLocationCb(bool independentFromGnss) {
+    UNUSED(independentFromGnss);
+}
+
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    if (callback == nullptr)  {
+        ALOGE("%s: Null callback ignored", __func__);
+        return false;
+    }
+
+    sem_wait(&sSem);
+    if (sGnssCbIface != NULL) {
+        ALOGW("%s called more than once. Unexpected unless test.", __func__);
+        sGnssCbIface->unlinkToDeath(mDeathRecipient);
+    }
+
+    sGnssCbIface = callback;
+    callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+    sem_post(&sSem);
+
+    // If this was received in the past, send it up again to refresh caller.
+    // mGnssIface will override after init() is called below, if needed
+    // (though it's unlikely the gps.h capabilities or system info will change.)
+    if (sCapabilitiesCached != 0) {
+        setCapabilitiesCb(sCapabilitiesCached);
+    }
+    if (sYearOfHwCached != 0) {
+        LegacyGnssSystemInfo info;
+        info.year_of_hw = sYearOfHwCached;
+        setSystemInfoCb(&info);
+    }
+
+    return (mGnssIface->init(&sGnssCb) == 0);
+}
+
+Return<bool> Gnss::start()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->start() == 0);
+}
+
+Return<bool> Gnss::stop()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->stop() == 0);
+}
+
+Return<void> Gnss::cleanup()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->cleanup();
+    }
+    return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+                                  double longitudeDegrees,
+                                  float accuracyMeters)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
+}
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                              int32_t uncertaintyMs) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_time(timeMs, timeReferenceMs, uncertaintyMs) == 0);
+}
+
+Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->delete_aiding_data(static_cast<GpsAidingData>(aidingDataFlags));
+    }
+    return Void();
+}
+
+Return<bool> Gnss::setPositionMode(IGnss::GnssPositionMode mode,
+                                   IGnss::GnssPositionRecurrence recurrence,
+                                   uint32_t minIntervalMs,
+                                   uint32_t preferredAccuracyMeters,
+                                   uint32_t preferredTimeMs)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->set_position_mode(static_cast<GpsPositionMode>(mode),
+                                          static_cast<GpsPositionRecurrence>(recurrence),
+                                          minIntervalMs,
+                                          preferredAccuracyMeters,
+                                          preferredTimeMs,
+                                          false /* lowPowerMode*/) == 0);
+}
+
+Return<sp<IAGnssRil>> Gnss::getExtensionAGnssRil() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssRil == nullptr) {
+        const AGpsRilInterface* agpsRilIface = static_cast<const AGpsRilInterface*>(
+                mGnssIface->get_extension(AGPS_RIL_INTERFACE));
+        if (agpsRilIface == nullptr) {
+            ALOGI("%s: GnssRil interface not implemented by HAL", __func__);
+        } else {
+            mGnssRil = new AGnssRil(agpsRilIface);
+        }
+    }
+    return mGnssRil;
+}
+
+Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    /*if (mGnssConfig == nullptr) {
+        const GnssConfigurationInterface* gnssConfigIface =
+                static_cast<const GnssConfigurationInterface*>(
+                        mGnssIface->get_extension(GNSS_CONFIGURATION_INTERFACE));
+
+        if (gnssConfigIface == nullptr) {*/
+            ALOGW("%s: GnssConfiguration interface not implemented by HAL", __func__);
+        /*} else {
+            mGnssConfig = new GnssConfiguration(gnssConfigIface);
+        }
+    }*/
+    return mGnssConfig;
+}
+
+Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    /*if (mGnssGeofencingIface == nullptr) {
+        const GpsGeofencingInterface* gpsGeofencingIface =
+                static_cast<const GpsGeofencingInterface*>(
+                        mGnssIface->get_extension(GPS_GEOFENCING_INTERFACE));
+
+        if (gpsGeofencingIface == nullptr) {*/
+            ALOGE("%s: GnssGeofencing interface not implemented by HAL", __func__);
+/*        } else {
+            mGnssGeofencingIface = new GnssGeofencing(gpsGeofencingIface);
+        }
+    }
+*/
+    return mGnssGeofencingIface;
+}
+
+Return<sp<IAGnss>> Gnss::getExtensionAGnss()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mAGnssIface == nullptr) {
+        const AGpsInterface* agpsIface = static_cast<const AGpsInterface*>(
+                mGnssIface->get_extension(AGPS_INTERFACE));
+        if (agpsIface == nullptr) {
+            ALOGE("%s: AGnss interface not implemented by HAL", __func__);
+        } else {
+            mAGnssIface = new V1_0::implementation::AGnss(agpsIface);
+        }
+    }
+    return mAGnssIface;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNi == nullptr) {
+        const GpsNiInterface* gpsNiIface = static_cast<const GpsNiInterface*>(
+                mGnssIface->get_extension(GPS_NI_INTERFACE));
+        if (gpsNiIface == nullptr) {
+            ALOGI("%s: GnssNi interface not implemented by HAL", __func__);
+        } else {
+            mGnssNi = new GnssNi(gpsNiIface);
+        }
+    }
+    return mGnssNi;
+}
+
+Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssMeasurement == nullptr) {
+        const GpsMeasurementInterface_ext* gpsMeasurementIface =
+                static_cast<const GpsMeasurementInterface_ext*>(
+                        mGnssIface->get_extension(GPS_MEASUREMENT_INTERFACE));
+
+        if (gpsMeasurementIface == nullptr) {
+            ALOGE("%s: GnssMeasurement interface not implemented by HAL", __func__);
+        } else {
+            mGnssMeasurement = new GnssMeasurement(gpsMeasurementIface);
+        }
+    }
+    return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNavigationMessage == nullptr) {
+        const GpsNavigationMessageInterface* gpsNavigationMessageIface =
+                static_cast<const GpsNavigationMessageInterface*>(
+                        mGnssIface->get_extension(GPS_NAVIGATION_MESSAGE_INTERFACE));
+
+        if (gpsNavigationMessageIface == nullptr) {
+            ALOGI("%s: GnssNavigationMessage interface not implemented by HAL", __func__);
+        } else {
+            mGnssNavigationMessage = new GnssNavigationMessage(gpsNavigationMessageIface);
+        }
+    }
+
+    return mGnssNavigationMessage;
+}
+
+Return<sp<IGnssXtra>> Gnss::getExtensionXtra()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssXtraIface == nullptr) {
+        const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
+                mGnssIface->get_extension(GPS_XTRA_INTERFACE));
+
+        if (gpsXtraIface == nullptr) {
+            ALOGI("%s: GnssXtra interface not implemented by HAL", __func__);
+        } else {
+            mGnssXtraIface = new GnssXtra(gpsXtraIface);
+        }
+    }
+
+    return mGnssXtraIface;
+}
+
+Return<sp<IGnssDebug>> Gnss::getExtensionGnssDebug()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssDebug == nullptr) {
+        const GpsDebugInterface* gpsDebugIface = static_cast<const GpsDebugInterface*>(
+                mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
+
+        if (gpsDebugIface == nullptr) {
+            ALOGI("%s: GnssDebug interface not implemented by HAL", __func__);
+        } else {
+            mGnssDebug = new GnssDebug(gpsDebugIface);
+        }
+    }
+
+    return mGnssDebug;
+}
+
+Return<sp<IGnssBatching>> Gnss::getExtensionGnssBatching()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssBatching == nullptr) {
+        hw_module_t* module;
+        const FlpLocationInterface* flpLocationIface = nullptr;
+        int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+        if (err != 0) {
+            ALOGE("gnss flp hw_get_module failed: %d", err);
+        } else if (module == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null module");
+        } else if (module->methods == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null methods");
+        } else {
+            hw_device_t* device;
+            err = module->methods->open(module, FUSED_LOCATION_HARDWARE_MODULE_ID, &device);
+            if (err != 0) {
+                ALOGE("flpDevice open failed: %d", err);
+            } else {
+                flp_device_t * flpDevice = reinterpret_cast<flp_device_t*>(device);
+                flpLocationIface = flpDevice->get_flp_interface(flpDevice);
+            }
+        }
+
+        if (flpLocationIface == nullptr) {
+            ALOGE("%s: GnssBatching interface is not implemented by HAL", __func__);
+        } else {
+            mGnssBatching = new GnssBatching(flpLocationIface);
+        }
+    }
+    return mGnssBatching;
+}
+
+void Gnss::handleHidlDeath() {
+    ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+    /// M: move here! Do not callback to system_server to avoid gnss hidl service NE
+    /*
+     * This has died, so close it off in case (race condition) callbacks happen
+     * before HAL processes above messages.
+     */
+    sem_wait(&sSem);
+    sGnssCbIface = nullptr;
+    sem_post(&sSem);
+
+    // commands down to the HAL implementation
+    stop(); // stop ongoing GPS tracking
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+    if (mGnssNavigationMessage != nullptr) {
+        mGnssNavigationMessage->close();
+    }
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+    cleanup();
+
+}
+
+IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
+    hw_module_t* module;
+    IGnss* iface = nullptr;
+    int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+    if (err == 0) {
+        hw_device_t* device;
+        err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
+        if (err == 0) {
+            iface = new Gnss(reinterpret_cast<gps_device_t_ext*>(device));
+        } else {
+            ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+        }
+    } else {
+      ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+    }
+    return iface;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/Gnss.h b/src/connectivity/gps/service/1.0/Gnss.h
new file mode 100644
index 0000000..96fcf6f
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/Gnss.h
@@ -0,0 +1,194 @@
+/*
+ * 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_V1_0_Gnss_H_
+#define android_hardware_gnss_V1_0_Gnss_H_
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssBatching.h>
+#include <GnssConfiguration.h>
+#include <GnssDebug.h>
+#include <GnssGeofencing.h>
+#include <GnssMeasurement.h>
+#include <GnssNavigationMessage.h>
+#include <GnssNi.h>
+#include <GnssXtra.h>
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnss.h>
+#include <hardware/fused_location.h>
+#include <hidl/Status.h>
+#include "hardware/gps_mtk.h"
+
+#include <semaphore.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssSystemInfo = ::GnssSystemInfo;
+using GnssConstellationType = V1_0::GnssConstellationType;
+using GnssLocation = V1_0::GnssLocation;
+
+/*
+ * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
+ * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+class Gnss : public IGnss {
+  public:
+    Gnss(gps_device_t_ext* gnss_device);
+    ~Gnss();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+     * These declarations were generated from Gnss.hal.
+     */
+    Return<bool> setCallback(const sp<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(IGnss::GnssAidingData aidingDataFlags)  override;
+    Return<bool> setPositionMode(IGnss::GnssPositionMode mode,
+                                 IGnss::GnssPositionRecurrence recurrence,
+                                 uint32_t minIntervalMs,
+                                 uint32_t preferredAccuracyMeters,
+                                 uint32_t preferredTimeMs)  override;
+    Return<sp<IAGnssRil>> getExtensionAGnssRil() override;
+    Return<sp<IGnssGeofencing>> getExtensionGnssGeofencing() override;
+    Return<sp<IAGnss>> getExtensionAGnss() override;
+    Return<sp<IGnssNi>> getExtensionGnssNi() override;
+    Return<sp<IGnssMeasurement>> getExtensionGnssMeasurement() override;
+    Return<sp<IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
+    Return<sp<IGnssXtra>> getExtensionXtra() override;
+    Return<sp<IGnssConfiguration>> getExtensionGnssConfiguration() override;
+    Return<sp<IGnssDebug>> getExtensionGnssDebug() override;
+    Return<sp<IGnssBatching>> getExtensionGnssBatching() override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnss base class.
+     */
+    static void locationCb(GpsLocation_ext* location);
+    static void statusCb(GpsStatus* gnss_status);
+    static void nmeaCb(GpsUtcTime timestamp, const char* nmea, int length);
+    static void setCapabilitiesCb(uint32_t capabilities);
+    static void acquireWakelockCb();
+    static void releaseWakelockCb();
+    static void requestUtcTimeCb();
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void gnssSvStatusCb(GnssSvStatus_ext* status);
+    /*
+     * Deprecated callback added for backward compatibility to devices that do
+     * not support GnssSvStatus.
+     */
+    static void gpsSvStatusCb(GpsSvStatus* status);
+    static void setSystemInfoCb(const LegacyGnssSystemInfo* info);
+
+    /*
+     * Wakelock consolidation, only needed for dual use of a gps.h & fused_location.h HAL
+     *
+     * Ensures that if the last call from either legacy .h was to acquire a wakelock, that a
+     * wakelock is held.  Otherwise releases it.
+     */
+    static void acquireWakelockFused();
+    static void releaseWakelockFused();
+
+    static void setNameCb(const char* name, int length);
+    static void requestLocationCb(bool independentFromGnss);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsCallbacks_ext sGnssCb;
+
+ private:
+    /*
+     * For handling system-server death while GNSS service lives on.
+     */
+    class GnssHidlDeathRecipient : public hidl_death_recipient {
+      public:
+        GnssHidlDeathRecipient(const sp<Gnss> gnss) : mGnss(gnss) {
+        }
+
+        virtual void serviceDied(uint64_t /*cookie*/,
+                const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+            mGnss->handleHidlDeath();
+        }
+      private:
+        sp<Gnss> mGnss;
+    };
+
+    // for wakelock consolidation, see above
+    static void acquireWakelockGnss();
+    static void releaseWakelockGnss();
+    static void updateWakelock();
+    static bool sWakelockHeldGnss;
+    static bool sWakelockHeldFused;
+
+    /*
+     * Cleanup for death notification
+     */
+    void handleHidlDeath();
+
+    sp<V1_0::implementation::GnssXtra> mGnssXtraIface = nullptr;
+    sp<V1_0::implementation::AGnssRil> mGnssRil = nullptr;
+    sp<V1_0::implementation::GnssGeofencing> mGnssGeofencingIface = nullptr;
+    sp<V1_0::implementation::AGnss> mAGnssIface = nullptr;
+    sp<V1_0::implementation::GnssNi> mGnssNi = nullptr;
+    sp<V1_0::implementation::GnssMeasurement> mGnssMeasurement = nullptr;
+    sp<V1_0::implementation::GnssNavigationMessage> mGnssNavigationMessage = nullptr;
+    sp<V1_0::implementation::GnssDebug> mGnssDebug = nullptr;
+    sp<V1_0::implementation::GnssConfiguration> mGnssConfig = nullptr;
+    sp<V1_0::implementation::GnssBatching> mGnssBatching = nullptr;
+
+    ///M: add semphore protection
+    static sem_t sSem;
+
+    sp<GnssHidlDeathRecipient> mDeathRecipient;
+    const GpsInterface_ext* mGnssIface = nullptr;
+    static sp<IGnssCallback> sGnssCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+
+    // Values saved for resend
+    static uint32_t sCapabilitiesCached;
+    static uint16_t sYearOfHwCached;
+};
+
+extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_Gnss_H_
diff --git a/src/connectivity/gps/service/1.0/GnssBatching.cpp b/src/connectivity/gps/service/1.0/GnssBatching.cpp
new file mode 100644
index 0000000..1601ea8
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssBatching.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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_GnssBatchingInterface"
+
+#include "GnssBatching.h"
+#include <Gnss.h> // for wakelock consolidation
+#include <GnssUtils.h>
+
+#include <log/log.h>  // for ALOGE
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssBatchingCallback> GnssBatching::sGnssBatchingCbIface = nullptr;
+bool GnssBatching::sFlpSupportsBatching = false;
+
+FlpCallbacks GnssBatching::sFlpCb = {
+    .size = sizeof(FlpCallbacks),
+    .location_cb = locationCb,
+    .acquire_wakelock_cb = acquireWakelockCb,
+    .release_wakelock_cb = releaseWakelockCb,
+    .set_thread_event_cb = setThreadEventCb,
+    .flp_capabilities_cb = flpCapabilitiesCb,
+    .flp_status_cb = flpStatusCb,
+};
+
+GnssBatching::GnssBatching(const FlpLocationInterface* flpLocationIface) :
+    mFlpLocationIface(flpLocationIface) {
+}
+
+/*
+ * This enum is used locally by various methods below. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum BatchingValues : uint16_t {
+    // Numbers 0-3 were used in earlier implementations - using 4 to be distinct to the HAL
+    FLP_GNSS_BATCHING_CLIENT_ID = 4,
+    // Tech. mask of GNSS, and sensor aiding, for legacy HAL to fit with GnssBatching API
+    FLP_TECH_MASK_GNSS_AND_SENSORS = FLP_TECH_MASK_GNSS | FLP_TECH_MASK_SENSORS,
+    // Putting a cap to avoid possible memory issues.  Unlikely values this high are supported.
+    MAX_LOCATIONS_PER_BATCH = 1000
+};
+
+void GnssBatching::locationCb(int32_t locationsCount, FlpLocation** locations) {
+    if (sGnssBatchingCbIface == nullptr) {
+        ALOGE("%s: GNSS Batching Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (locations == nullptr) {
+        ALOGE("%s: Invalid locations from GNSS HAL", __func__);
+        return;
+    }
+
+    if (locationsCount < 0) {
+        ALOGE("%s: Negative location count: %d set to 0", __func__, locationsCount);
+        locationsCount = 0;
+    } else if (locationsCount > MAX_LOCATIONS_PER_BATCH) {
+        ALOGW("%s: Unexpected high location count: %d set to %d", __func__, locationsCount,
+                MAX_LOCATIONS_PER_BATCH);
+        locationsCount = MAX_LOCATIONS_PER_BATCH;
+    }
+
+    /**
+     * Note:
+     * Some existing implementations may drop duplicate locations.  These could be expanded here
+     * but as there's ambiguity between no-GPS-fix vs. dropped duplicates in that implementation,
+     * and that's not specified by the fused_location.h, that isn't safe to do here.
+     * Fortunately, this shouldn't be a major issue in cases where GNSS batching is typically
+     * used (e.g. when user is likely in vehicle/bicycle.)
+     */
+    std::vector<android::hardware::gnss::V1_0::GnssLocation> gnssLocations;
+    for (int iLocation = 0; iLocation < locationsCount; iLocation++) {
+        if (locations[iLocation] == nullptr) {
+            ALOGE("%s: Null location at slot: %d of %d, skipping", __func__, iLocation,
+                    locationsCount);
+            continue;
+        }
+        if ((locations[iLocation]->sources_used & ~FLP_TECH_MASK_GNSS_AND_SENSORS) != 0)
+        {
+            ALOGE("%s: Unrequested location type %d at slot: %d of %d, skipping", __func__,
+                    locations[iLocation]->sources_used, iLocation, locationsCount);
+            continue;
+        }
+        gnssLocations.push_back(convertToGnssLocation(locations[iLocation]));
+    }
+
+    auto ret = sGnssBatchingCbIface->gnssLocationBatchCb(gnssLocations);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssBatching::acquireWakelockCb() {
+    Gnss::acquireWakelockFused();
+}
+
+void GnssBatching::releaseWakelockCb() {
+    Gnss::releaseWakelockFused();
+}
+
+// this can just return success, because threads are now set up on demand in the jni layer
+int32_t GnssBatching::setThreadEventCb(ThreadEvent /*event*/) {
+    return FLP_RESULT_SUCCESS;
+}
+
+void GnssBatching::flpCapabilitiesCb(int32_t capabilities) {
+    ALOGD("%s capabilities %d", __func__, capabilities);
+
+    if (capabilities & CAPABILITY_GNSS) {
+        // once callback is received and capabilities high enough, we know version is
+        // high enough for flush()
+        sFlpSupportsBatching = true;
+    }
+}
+
+void GnssBatching::flpStatusCb(int32_t status) {
+    ALOGD("%s (default implementation) not forwarding status: %d", __func__, status);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching is unavailable", __func__);
+        return false;
+    }
+
+    sGnssBatchingCbIface = callback;
+
+    return (mFlpLocationIface->init(&sFlpCb) == 0);
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return 0;
+    }
+
+    return mFlpLocationIface->get_batch_size();
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return false;
+    }
+
+    if (!sFlpSupportsBatching) {
+        ALOGE("%s: Flp batching interface not supported, no capabilities callback received",
+                __func__);
+        return false;
+    }
+
+    FlpBatchOptions optionsHw;
+    // Legacy code used 9999 mW for High accuracy, and 21 mW for balanced.
+    // New GNSS API just expects reasonable GNSS chipset behavior - do something efficient
+    // given the interval.  This 100 mW limit should be quite sufficient (esp. given legacy code
+    // implementations may not even use this value.)
+    optionsHw.max_power_allocation_mW = 100;
+    optionsHw.sources_to_use = FLP_TECH_MASK_GNSS_AND_SENSORS;
+    optionsHw.flags = 0;
+    if (options.flags & Flag::WAKEUP_ON_FIFO_FULL) {
+        optionsHw.flags |= FLP_BATCH_WAKEUP_ON_FIFO_FULL;
+    }
+    optionsHw.period_ns = options.periodNanos;
+    optionsHw.smallest_displacement_meters = 0; // Zero offset - just use time interval
+
+    return (mFlpLocationIface->start_batching(FLP_GNSS_BATCHING_CLIENT_ID, &optionsHw)
+            == FLP_RESULT_SUCCESS);
+}
+
+Return<void> GnssBatching::flush() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return Void();
+    }
+
+    mFlpLocationIface->flush_batched_locations();
+
+    return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mFlpLocationIface->stop_batching(FLP_GNSS_BATCHING_CLIENT_ID) == FLP_RESULT_SUCCESS);
+}
+
+Return<void> GnssBatching::cleanup() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return Void();
+    }
+
+    mFlpLocationIface->cleanup();
+
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssBatching.h b/src/connectivity/gps/service/1.0/GnssBatching.h
new file mode 100644
index 0000000..001c27d
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssBatching.h
@@ -0,0 +1,67 @@
+#ifndef ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
+#define ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <hardware/fused_location.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+struct GnssBatching : public IGnssBatching {
+    GnssBatching(const FlpLocationInterface* flpLocationIface);
+
+    // 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;
+
+    /*
+     * Callback methods to be passed into the conventional FLP HAL by the default
+     * implementation. These methods are not part of the IGnssBatching base class.
+     */
+    static void locationCb(int32_t locationsCount, FlpLocation** locations);
+    static void acquireWakelockCb();
+    static void releaseWakelockCb();
+    static int32_t setThreadEventCb(ThreadEvent event);
+    static void flpCapabilitiesCb(int32_t capabilities);
+    static void flpStatusCb(int32_t status);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static FlpCallbacks sFlpCb;
+
+ private:
+    const FlpLocationInterface* mFlpLocationIface = nullptr;
+    static sp<IGnssBatchingCallback> sGnssBatchingCbIface;
+    static bool sFlpSupportsBatching;
+};
+
+extern "C" IGnssBatching* HIDL_FETCH_IGnssBatching(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
diff --git a/src/connectivity/gps/service/1.0/GnssConfiguration.cpp b/src/connectivity/gps/service/1.0/GnssConfiguration.cpp
new file mode 100644
index 0000000..0c1aa86
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssConfiguration.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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_GnssConfigurationInterface"
+
+#include <log/log.h>
+
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+GnssConfiguration::GnssConfiguration(const GnssConfigurationInterface* gnssConfigInfc)
+    : mGnssConfigIface(gnssConfigInfc) {}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_ES=" + std::to_string(enabled ? 1 : 0) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_VER=" + std::to_string(version) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+
+    return true;
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_MODE=" + std::to_string(mode) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "LPP_PROFILE=" + std::to_string(lppProfile) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "A_GLONASS_POS_PROTOCOL_SELECT=" +
+            std::to_string(protocol) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "GPS_LOCK=" + std::to_string(lock) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=" + std::to_string(enabled ? 1 : 0)
+            + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssConfiguration.h b/src/connectivity/gps/service/1.0/GnssConfiguration.h
new file mode 100644
index 0000000..a6eca88
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssConfiguration.h
@@ -0,0 +1,66 @@
+/*
+ * 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_V1_0_GnssConfiguration_H_
+#define android_hardware_gnss_V1_0_GnssConfiguration_H_
+
+#include <android/hardware/gnss/1.0/IGnssConfiguration.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssConfiguration;
+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 GnssConfiguration : public IGnssConfiguration {
+    GnssConfiguration(const GnssConfigurationInterface* gnssConfigIface);
+
+    /*
+     * 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;
+
+ private:
+    const GnssConfigurationInterface* mGnssConfigIface = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssConfiguration_H_
diff --git a/src/connectivity/gps/service/1.0/GnssDebug.cpp b/src/connectivity/gps/service/1.0/GnssDebug.cpp
new file mode 100644
index 0000000..cfc38ca
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssDebug.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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_GnssDebugInterface"
+
+#include <log/log.h>
+
+#include "GnssDebug.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+GnssDebug::GnssDebug(const GpsDebugInterface* gpsDebugIface) : mGnssDebugIface(gpsDebugIface) {}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)  {
+    /*
+     * This is a new interface and hence there is no way to retrieve the
+     * debug data from the HAL.
+     */
+    DebugData data = {};
+
+    _hidl_cb(data);
+
+    /*
+     * Log the debug data sent from the conventional Gnss HAL. This code is
+     * moved here from GnssLocationProvider.
+     */
+    if (mGnssDebugIface) {
+        char buffer[kMaxDebugStrLen + 1];
+        size_t length = mGnssDebugIface->get_internal_state(buffer, kMaxDebugStrLen);
+        length = std::max(length, kMaxDebugStrLen);
+        buffer[length] = '\0';
+        ALOGD("Gnss Debug Data: %s", buffer);
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssDebug.h b/src/connectivity/gps/service/1.0/GnssDebug.h
new file mode 100644
index 0000000..9a17dde
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssDebug.h
@@ -0,0 +1,62 @@
+/*
+ * 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_V1_0_GnssDebug_H_
+#define android_hardware_gnss_V1_0_GnssDebug_H_
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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 GnssDebug : public IGnssDebug {
+    GnssDebug(const GpsDebugInterface* gpsDebugIface);
+
+    /*
+     * 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:
+    /*
+     * Constant added for backward compatibility to conventional GPS Hals which
+     * returned a debug string.
+     */
+    const size_t kMaxDebugStrLen = 2047;
+    const GpsDebugInterface* mGnssDebugIface = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssDebug_H_
diff --git a/src/connectivity/gps/service/1.0/GnssGeofencing.cpp b/src/connectivity/gps/service/1.0/GnssGeofencing.cpp
new file mode 100644
index 0000000..3d51140
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssGeofencing.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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 "GnssGeofencing.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssGeofencing::sThreadFuncArgsList;
+sp<IGnssGeofenceCallback> GnssGeofencing::mGnssGeofencingCbIface = nullptr;
+bool GnssGeofencing::sInterfaceExists = false;
+
+GpsGeofenceCallbacks_ext GnssGeofencing::sGnssGfCb = {
+    .geofence_transition_callback = gnssGfTransitionCb,
+    .geofence_status_callback = gnssGfStatusCb,
+    .geofence_add_callback = gnssGfAddCb,
+    .geofence_remove_callback = gnssGfRemoveCb,
+    .geofence_pause_callback = gnssGfPauseCb,
+    .geofence_resume_callback = gnssGfResumeCb,
+    .create_thread_cb = createThreadCb
+};
+
+GnssGeofencing::GnssGeofencing(const GpsGeofencingInterface_ext* gpsGeofencingIface)
+    : mGnssGeofencingIface(gpsGeofencingIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+GnssGeofencing::~GnssGeofencing() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+void GnssGeofencing::gnssGfTransitionCb(int32_t geofenceId,
+                                        GpsLocation_ext* location,
+                                        int32_t transition,
+                                        GpsUtcTime timestamp) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (location == nullptr) {
+        ALOGE("%s : Invalid location from GNSS HAL", __func__);
+        return;
+    }
+
+    GnssLocation gnssLocation = convertToGnssLocation(location);
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+            geofenceId,
+            gnssLocation,
+            static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
+            timestamp);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfStatusCb(int32_t status, GpsLocation_ext* location) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    GnssLocation gnssLocation;
+
+    if (location != nullptr) {
+        gnssLocation = convertToGnssLocation(location);
+    } else {
+        gnssLocation = {};
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceStatusCb(
+            static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfAddCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceAddCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfRemoveCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfPauseCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofencePauseCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfResumeCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceResumeCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+pthread_t GnssGeofencing::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback)  {
+    mGnssGeofencingCbIface = callback;
+
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->init(&sGnssGfCb);
+    }
+
+    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 (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+        return Void();
+    } else {
+        mGnssGeofencingIface->add_geofence_area(
+                geofenceId,
+                latitudeDegrees,
+                longitudeDegrees,
+                radiusMeters,
+                static_cast<int32_t>(lastTransition),
+                monitorTransitions,
+                notificationResponsivenessMs,
+                unknownTimerMs);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->pause_geofence(geofenceId);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->resume_geofence(geofenceId, monitorTransitions);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->remove_geofence_area(geofenceId);
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssGeofencing.h b/src/connectivity/gps/service/1.0/GnssGeofencing.h
new file mode 100644
index 0000000..ef93163
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssGeofencing.h
@@ -0,0 +1,98 @@
+/*
+ * 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_V1_0_GnssGeofencing_H_
+#define android_hardware_gnss_V1_0_GnssGeofencing_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+#include "hardware/gps_mtk.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+/*
+ * Interface for GNSS Geofencing support. It also contains wrapper methods to allow
+ * methods from IGnssGeofenceCallback interface to be passed into the
+ * conventional implementation of the GNSS HAL.
+ */
+struct GnssGeofencing : public IGnssGeofencing {
+    GnssGeofencing(const GpsGeofencingInterface_ext* gpsGeofencingIface);
+    ~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;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssGeofencing base class.
+     */
+    static void gnssGfTransitionCb(int32_t geofence_id, GpsLocation_ext* location,
+                                   int32_t transition, GpsUtcTime timestamp);
+    static void gnssGfStatusCb(int32_t status, GpsLocation_ext* last_location);
+    static void gnssGfAddCb(int32_t geofence_id, int32_t status);
+    static void gnssGfRemoveCb(int32_t geofence_id, int32_t status);
+    static void gnssGfPauseCb(int32_t geofence_id, int32_t status);
+    static void gnssGfResumeCb(int32_t geofence_id, int32_t status);
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsGeofenceCallbacks_ext sGnssGfCb;
+
+ private:
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static sp<IGnssGeofenceCallback> mGnssGeofencingCbIface;
+    const GpsGeofencingInterface_ext* mGnssGeofencingIface = nullptr;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssGeofencing_H_
diff --git a/src/connectivity/gps/service/1.0/GnssMeasurement.cpp b/src/connectivity/gps/service/1.0/GnssMeasurement.cpp
new file mode 100644
index 0000000..8b47086
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssMeasurement.cpp
@@ -0,0 +1,265 @@
+/*
+ * 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_GnssMeasurementInterface"
+
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssMeasurementCallback> GnssMeasurement::sGnssMeasureCbIface = nullptr;
+GpsMeasurementCallbacks_ext GnssMeasurement::sGnssMeasurementCbs = {
+    .size = sizeof(GpsMeasurementCallbacks_ext),
+    .measurement_callback = gpsMeasurementCb,
+    .gnss_measurement_callback = gnssMeasurementCb
+};
+
+GnssMeasurement::GnssMeasurement(const GpsMeasurementInterface_ext* gpsMeasurementIface)
+    : mGnssMeasureIface(gpsMeasurementIface) {}
+
+void GnssMeasurement::gnssMeasurementCb(GnssData_ext* halGnssData) {
+    if (sGnssMeasureCbIface == nullptr) {
+        ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (halGnssData == nullptr) {
+        ALOGE("%s: Invalid GnssData from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssMeasurementCallback::GnssData gnssData;
+    gnssData.measurementCount = std::min(halGnssData->measurement_count,
+                                         static_cast<size_t>(GnssMax::SVS_COUNT));
+
+    for (size_t i = 0; i < gnssData.measurementCount; i++) {
+        auto entry = halGnssData->measurements[i];
+        auto state = static_cast<GnssMeasurementState>(entry.legacyMeasurement.state);
+        if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED) {
+          state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
+        }
+        if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED) {
+          state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
+        }
+        gnssData.measurements[i] = (V1_0::IGnssMeasurementCallback::GnssMeasurement){
+            .flags = entry.legacyMeasurement.flags,
+            .svid = entry.legacyMeasurement.svid,
+            .constellation = static_cast<V1_0::GnssConstellationType>(
+                    entry.legacyMeasurement.constellation),
+            .timeOffsetNs = entry.legacyMeasurement.time_offset_ns,
+            .state = state,
+            .receivedSvTimeInNs = entry.legacyMeasurement.received_sv_time_in_ns,
+            .receivedSvTimeUncertaintyInNs =
+                    entry.legacyMeasurement.received_sv_time_uncertainty_in_ns,
+            .cN0DbHz = entry.legacyMeasurement.c_n0_dbhz,
+            .pseudorangeRateMps = entry.legacyMeasurement.pseudorange_rate_mps,
+            .pseudorangeRateUncertaintyMps =
+                    entry.legacyMeasurement.pseudorange_rate_uncertainty_mps,
+            .accumulatedDeltaRangeState = entry.legacyMeasurement.accumulated_delta_range_state,
+            .accumulatedDeltaRangeM = entry.legacyMeasurement.accumulated_delta_range_m,
+            .accumulatedDeltaRangeUncertaintyM =
+                    entry.legacyMeasurement.accumulated_delta_range_uncertainty_m,
+            .carrierFrequencyHz = entry.legacyMeasurement.carrier_frequency_hz,
+            .carrierCycles = entry.legacyMeasurement.carrier_cycles,
+            .carrierPhase = entry.legacyMeasurement.carrier_phase,
+            .carrierPhaseUncertainty = entry.legacyMeasurement.carrier_phase_uncertainty,
+            .multipathIndicator = static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+                    entry.legacyMeasurement.multipath_indicator),
+            .snrDb = entry.legacyMeasurement.snr_db,
+            .agcLevelDb = entry.agc_level_db
+        };
+    }
+
+    auto clockVal = halGnssData->clock;
+    gnssData.clock = {
+        .gnssClockFlags = clockVal.flags,
+        .leapSecond = clockVal.leap_second,
+        .timeNs = clockVal.time_ns,
+        .timeUncertaintyNs = clockVal.time_uncertainty_ns,
+        .fullBiasNs = clockVal.full_bias_ns,
+        .biasNs = clockVal.bias_ns,
+        .biasUncertaintyNs = clockVal.bias_uncertainty_ns,
+        .driftNsps = clockVal.drift_nsps,
+        .driftUncertaintyNsps = clockVal.drift_uncertainty_nsps,
+        .hwClockDiscontinuityCount = clockVal.hw_clock_discontinuity_count
+    };
+
+    auto ret = sGnssMeasureCbIface->GnssMeasurementCb(gnssData);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+/*
+ * The code in the following method has been moved here from GnssLocationProvider.
+ * It converts GpsData to GnssData. This code is no longer required in
+ * GnssLocationProvider since GpsData is deprecated and no longer part of the
+ * GNSS interface.
+ */
+void GnssMeasurement::gpsMeasurementCb(GpsData* gpsData) {
+    if (sGnssMeasureCbIface == nullptr) {
+        ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (gpsData == nullptr) {
+        ALOGE("%s: Invalid GpsData from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssMeasurementCallback::GnssData gnssData;
+    gnssData.measurementCount = std::min(gpsData->measurement_count,
+                                         static_cast<size_t>(GnssMax::SVS_COUNT));
+
+
+    for (size_t i = 0; i < gnssData.measurementCount; i++) {
+        auto entry = gpsData->measurements[i];
+        gnssData.measurements[i].flags = entry.flags;
+        gnssData.measurements[i].svid = static_cast<int32_t>(entry.prn);
+        if (entry.prn >= 1 && entry.prn <= 32) {
+            gnssData.measurements[i].constellation = GnssConstellationType::GPS;
+        } else {
+            gnssData.measurements[i].constellation =
+                  GnssConstellationType::UNKNOWN;
+        }
+
+        gnssData.measurements[i].timeOffsetNs = entry.time_offset_ns;
+        gnssData.measurements[i].state = entry.state;
+        gnssData.measurements[i].receivedSvTimeInNs = entry.received_gps_tow_ns;
+        gnssData.measurements[i].receivedSvTimeUncertaintyInNs =
+            entry.received_gps_tow_uncertainty_ns;
+        gnssData.measurements[i].cN0DbHz = entry.c_n0_dbhz;
+        gnssData.measurements[i].pseudorangeRateMps = entry.pseudorange_rate_mps;
+        gnssData.measurements[i].pseudorangeRateUncertaintyMps =
+                entry.pseudorange_rate_uncertainty_mps;
+        gnssData.measurements[i].accumulatedDeltaRangeState =
+                entry.accumulated_delta_range_state;
+        gnssData.measurements[i].accumulatedDeltaRangeM =
+                entry.accumulated_delta_range_m;
+        gnssData.measurements[i].accumulatedDeltaRangeUncertaintyM =
+                entry.accumulated_delta_range_uncertainty_m;
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
+            gnssData.measurements[i].carrierFrequencyHz = entry.carrier_frequency_hz;
+        } else {
+            gnssData.measurements[i].carrierFrequencyHz = 0;
+        }
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE) {
+            gnssData.measurements[i].carrierPhase = entry.carrier_phase;
+        } else {
+            gnssData.measurements[i].carrierPhase = 0;
+        }
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
+            gnssData.measurements[i].carrierPhaseUncertainty = entry.carrier_phase_uncertainty;
+        } else {
+            gnssData.measurements[i].carrierPhaseUncertainty = 0;
+        }
+
+        gnssData.measurements[i].multipathIndicator =
+                static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+                        entry.multipath_indicator);
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_SNR) {
+            gnssData.measurements[i].snrDb = entry.snr_db;
+        } else {
+            gnssData.measurements[i].snrDb = 0;
+        }
+    }
+
+    auto clockVal = gpsData->clock;
+    static uint32_t discontinuity_count_to_handle_old_clock_type = 0;
+
+    gnssData.clock.leapSecond = clockVal.leap_second;
+    /*
+     * GnssClock only supports the more effective HW_CLOCK type, so type
+     * handling and documentation complexity has been removed.  To convert the
+     * old GPS_CLOCK types (active only in a limited number of older devices),
+     * the GPS time information is handled as an always discontinuous HW clock,
+     * with the GPS time information put into the full_bias_ns instead - so that
+     * time_ns - full_bias_ns = local estimate of GPS time. Additionally, the
+     * sign of full_bias_ns and bias_ns has flipped between GpsClock &
+     * GnssClock, so that is also handled below.
+     */
+    switch (clockVal.type) {
+        case GPS_CLOCK_TYPE_UNKNOWN:
+            // Clock type unsupported.
+            ALOGE("Unknown clock type provided.");
+            break;
+        case GPS_CLOCK_TYPE_LOCAL_HW_TIME:
+            // Already local hardware time. No need to do anything.
+            break;
+        case GPS_CLOCK_TYPE_GPS_TIME:
+            // GPS time, need to convert.
+            clockVal.flags |= GPS_CLOCK_HAS_FULL_BIAS;
+            clockVal.full_bias_ns = clockVal.time_ns;
+            clockVal.time_ns = 0;
+            gnssData.clock.hwClockDiscontinuityCount =
+                    discontinuity_count_to_handle_old_clock_type++;
+            break;
+    }
+
+    gnssData.clock.timeNs = clockVal.time_ns;
+    gnssData.clock.timeUncertaintyNs = clockVal.time_uncertainty_ns;
+    /*
+     * Definition of sign for full_bias_ns & bias_ns has been changed since N,
+     * so flip signs here.
+     */
+    gnssData.clock.fullBiasNs = -(clockVal.full_bias_ns);
+    gnssData.clock.biasNs = -(clockVal.bias_ns);
+    gnssData.clock.biasUncertaintyNs = clockVal.bias_uncertainty_ns;
+    gnssData.clock.driftNsps = clockVal.drift_nsps;
+    gnssData.clock.driftUncertaintyNsps = clockVal.drift_uncertainty_nsps;
+    gnssData.clock.gnssClockFlags = clockVal.flags;
+
+    auto ret = sGnssMeasureCbIface->GnssMeasurementCb(gnssData);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<GnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
+        const sp<IGnssMeasurementCallback>& callback)  {
+    if (mGnssMeasureIface == nullptr) {
+        ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+        return GnssMeasurementStatus::ERROR_GENERIC;
+    }
+    sGnssMeasureCbIface = callback;
+
+    return static_cast<GnssMeasurement::GnssMeasurementStatus>(
+            mGnssMeasureIface->init(&sGnssMeasurementCbs, false /*enableFullTracking*/));
+}
+
+Return<void> GnssMeasurement::close()  {
+    if (mGnssMeasureIface == nullptr) {
+        ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+    } else {
+        mGnssMeasureIface->close();
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssMeasurement.h b/src/connectivity/gps/service/1.0/GnssMeasurement.h
new file mode 100644
index 0000000..219de89
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssMeasurement.h
@@ -0,0 +1,84 @@
+/*
+ * 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_V1_0_GnssMeasurement_H_
+#define android_hardware_gnss_V1_0_GnssMeasurement_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssMeasurement;
+using ::android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+
+/*
+ * Extended interface for GNSS Measurements support. Also contains wrapper methods to allow methods
+ * from IGnssMeasurementCallback interface to be passed into the conventional implementation of the
+ * GNSS HAL.
+ */
+struct GnssMeasurement : public IGnssMeasurement {
+    GnssMeasurement(const GpsMeasurementInterface_ext* gpsMeasurementIface);
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+     * These declarations were generated from IGnssMeasurement.hal.
+     */
+    Return<GnssMeasurementStatus> setCallback(
+        const sp<IGnssMeasurementCallback>& callback) override;
+    Return<void> close() override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssMeasurement base class.
+     */
+    static void gnssMeasurementCb(GnssData_ext* data);
+     /*
+      * Deprecated callback added for backward compatibity for devices that do
+      * not support GnssData measurements.
+      */
+    static void gpsMeasurementCb(GpsData* data);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsMeasurementCallbacks_ext sGnssMeasurementCbs;
+
+ private:
+    const GpsMeasurementInterface_ext* mGnssMeasureIface = nullptr;
+    static sp<IGnssMeasurementCallback> sGnssMeasureCbIface;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssMeasurement_H_
diff --git a/src/connectivity/gps/service/1.0/GnssNavigationMessage.cpp b/src/connectivity/gps/service/1.0/GnssNavigationMessage.cpp
new file mode 100644
index 0000000..6f509d0
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssNavigationMessage.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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_GnssNavigationMessageInterface"
+
+#include <log/log.h>
+
+#include "GnssNavigationMessage.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssNavigationMessageCallback> GnssNavigationMessage::sGnssNavigationMsgCbIface = nullptr;
+
+GpsNavigationMessageCallbacks GnssNavigationMessage::sGnssNavigationMessageCb = {
+    .size = sizeof(GpsNavigationMessageCallbacks),
+    .navigation_message_callback = nullptr,
+    .gnss_navigation_message_callback = gnssNavigationMessageCb
+};
+
+GnssNavigationMessage::GnssNavigationMessage(
+        const GpsNavigationMessageInterface* gpsNavigationMessageIface) :
+    mGnssNavigationMessageIface(gpsNavigationMessageIface) {}
+
+void GnssNavigationMessage::gnssNavigationMessageCb(LegacyGnssNavigationMessage* message) {
+    if (sGnssNavigationMsgCbIface == nullptr) {
+        ALOGE("%s: GnssNavigation Message Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (message == nullptr) {
+        ALOGE("%s, received invalid GnssNavigationMessage from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssNavigationMessageCallback::GnssNavigationMessage navigationMsg;
+
+    navigationMsg.svid = message->svid;
+    navigationMsg.type =
+            static_cast<IGnssNavigationMessageCallback::GnssNavigationMessageType>(message->type);
+    navigationMsg.status = message->status;
+    navigationMsg.messageId = message->message_id;
+    navigationMsg.submessageId = message->submessage_id;
+    navigationMsg.data.setToExternal(message->data, message->data_length);
+
+    auto ret = sGnssNavigationMsgCbIface->gnssNavigationMessageCb(navigationMsg);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+Return<GnssNavigationMessage::GnssNavigationMessageStatus> GnssNavigationMessage::setCallback(
+        const sp<IGnssNavigationMessageCallback>& callback)  {
+    if (mGnssNavigationMessageIface == nullptr) {
+        ALOGE("%s: GnssNavigationMessage not available", __func__);
+        return GnssNavigationMessageStatus::ERROR_GENERIC;
+    }
+
+    sGnssNavigationMsgCbIface = callback;
+
+    return static_cast<GnssNavigationMessage::GnssNavigationMessageStatus>(
+            mGnssNavigationMessageIface->init(&sGnssNavigationMessageCb));
+}
+
+Return<void> GnssNavigationMessage::close()  {
+    if (mGnssNavigationMessageIface == nullptr) {
+        ALOGE("%s: GnssNavigationMessage not available", __func__);
+    } else {
+        mGnssNavigationMessageIface->close();
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssNavigationMessage.h b/src/connectivity/gps/service/1.0/GnssNavigationMessage.h
new file mode 100644
index 0000000..882854b
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssNavigationMessage.h
@@ -0,0 +1,77 @@
+/*
+ * 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_V1_0_GnssNavigationMessage_H_
+#define android_hardware_gnss_V1_0_GnssNavigationMessage_H_
+
+#include <android/hardware/gnss/1.0/IGnssNavigationMessage.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessage;
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssNavigationMessage = ::GnssNavigationMessage;
+
+/*
+ * Extended interface for GNSS navigation message reporting support. Also contains wrapper methods
+ * to allow methods from IGnssNavigationMessageCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct GnssNavigationMessage : public IGnssNavigationMessage {
+    GnssNavigationMessage(const GpsNavigationMessageInterface* gpsNavigationMessageIface);
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+     * These declarations were generated from IGnssNavigationMessage.hal.
+     */
+    Return<GnssNavigationMessageStatus> setCallback(
+        const sp<IGnssNavigationMessageCallback>& callback) override;
+    Return<void> close() override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+     * These methods are not part of the IGnssNavigationMessage base class.
+     */
+    static void gnssNavigationMessageCb(LegacyGnssNavigationMessage* message);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsNavigationMessageCallbacks sGnssNavigationMessageCb;
+ private:
+    const GpsNavigationMessageInterface* mGnssNavigationMessageIface = nullptr;
+    static sp<IGnssNavigationMessageCallback> sGnssNavigationMsgCbIface;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssNavigationMessage_H_
diff --git a/src/connectivity/gps/service/1.0/GnssNi.cpp b/src/connectivity/gps/service/1.0/GnssNi.cpp
new file mode 100644
index 0000000..d17891d
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssNi.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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_GnssNiInterface"
+
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList;
+sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr;
+bool GnssNi::sInterfaceExists = false;
+
+GpsNiCallbacks GnssNi::sGnssNiCb = {
+    .notify_cb = niNotifyCb,
+    .create_thread_cb = createThreadCb
+};
+
+GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+GnssNi::~GnssNi() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void GnssNi::niNotifyCb(GpsNiNotification* notification) {
+    if (sGnssNiCbIface == nullptr) {
+        ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (notification == nullptr) {
+        ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssNiCallback::GnssNiNotification notificationGnss = {
+        .notificationId =  notification->notification_id,
+        .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type),
+        .notifyFlags = notification->notify_flags,
+        .timeoutSec = static_cast<uint32_t>(notification->timeout),
+        .defaultResponse =
+                static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response),
+        .requestorId = notification->requestor_id,
+        .notificationMessage = notification->text,
+        .requestorIdEncoding =
+                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding),
+        .notificationIdEncoding =
+                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding)
+    };
+
+    auto ret = sGnssNiCbIface->niNotifyCb(notificationGnss);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback)  {
+    if (mGnssNiIface == nullptr) {
+       ALOGE("%s: GnssNi interface is unavailable", __func__);
+       return Void();
+    }
+
+    sGnssNiCbIface = callback;
+
+    mGnssNiIface->init(&sGnssNiCb);
+    return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse)  {
+    if (mGnssNiIface == nullptr) {
+        ALOGE("%s: GnssNi interface is unavailable", __func__);
+    } else {
+        mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse));
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssNi.h b/src/connectivity/gps/service/1.0/GnssNi.h
new file mode 100644
index 0000000..fe850b1
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssNi.h
@@ -0,0 +1,81 @@
+/*
+ * 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_V1_0_GnssNi_H_
+#define android_hardware_gnss_V1_0_GnssNi_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+/*
+ * Extended interface for Network-initiated (NI) support. This interface is used to respond to
+ * NI notifications originating from the HAL. Also contains wrapper methods to allow methods from
+ * IGnssNiCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct GnssNi : public IGnssNi {
+    GnssNi(const GpsNiInterface* gpsNiIface);
+    ~GnssNi();
+
+    /*
+     * 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;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssNi base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void niNotifyCb(GpsNiNotification* notification);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsNiCallbacks sGnssNiCb;
+
+ private:
+    const GpsNiInterface* mGnssNiIface = nullptr;
+    static sp<IGnssNiCallback> sGnssNiCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssNi_H_
diff --git a/src/connectivity/gps/service/1.0/GnssUtils.cpp b/src/connectivity/gps/service/1.0/GnssUtils.cpp
new file mode 100644
index 0000000..0234aa3
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssUtils.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#include "GnssUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using android::hardware::gnss::V1_0::GnssLocation;
+
+GnssLocation convertToGnssLocation(GpsLocation_ext* location) {
+    GnssLocation gnssLocation = {};
+    if (location != nullptr) {
+        gnssLocation = {
+            .gnssLocationFlags = static_cast<uint16_t>(location->legacyLocation.flags & 0xff),
+            .latitudeDegrees = location->legacyLocation.latitude,
+            .longitudeDegrees = location->legacyLocation.longitude,
+            .altitudeMeters = location->legacyLocation.altitude,
+            .speedMetersPerSec = location->legacyLocation.speed,
+            .bearingDegrees = location->legacyLocation.bearing,
+            .horizontalAccuracyMeters = location->horizontalAccuracyMeters,
+            .verticalAccuracyMeters = location->verticalAccuracyMeters,
+            .speedAccuracyMetersPerSecond = location->speedAccuracyMetersPerSecond,
+            .bearingAccuracyDegrees = location->bearingAccuracyDegrees,
+            .timestamp = location->legacyLocation.timestamp
+        };
+    }
+
+    return gnssLocation;
+}
+
+GnssLocation convertToGnssLocation(FlpLocation* flpLocation) {
+    GnssLocation gnssLocation = {};
+    if (flpLocation != nullptr) {
+        gnssLocation = {.gnssLocationFlags = 0,  // clear here and set below
+                        .latitudeDegrees = flpLocation->latitude,
+                        .longitudeDegrees = flpLocation->longitude,
+                        .altitudeMeters = flpLocation->altitude,
+                        .speedMetersPerSec = flpLocation->speed,
+                        .bearingDegrees = flpLocation->bearing,
+                        .horizontalAccuracyMeters = flpLocation->accuracy,
+                        .verticalAccuracyMeters = 0,
+                        .speedAccuracyMetersPerSecond = 0,
+                        .bearingAccuracyDegrees = 0,
+                        .timestamp = flpLocation->timestamp};
+        // FlpLocation flags different from GnssLocation flags
+        if (flpLocation->flags & FLP_LOCATION_HAS_LAT_LONG) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_LAT_LONG;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_ALTITUDE) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_ALTITUDE;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_SPEED) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_SPEED;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_BEARING) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_BEARING;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_ACCURACY) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_HORIZONTAL_ACCURACY;
+        }
+    }
+
+    return gnssLocation;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssUtils.h b/src/connectivity/gps/service/1.0/GnssUtils.h
new file mode 100644
index 0000000..7cfef2e
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssUtils.h
@@ -0,0 +1,48 @@
+/*
+ * 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_V1_0_GnssUtil_H_
+#define android_hardware_gnss_V1_0_GnssUtil_H_
+
+#include <hardware/fused_location.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+/*
+ * This method converts a GpsLocation struct to a GnssLocation
+ * struct.
+ */
+GnssLocation convertToGnssLocation(GpsLocation_ext* location);
+
+/*
+ * This method converts an FlpLocation struct to a GnssLocation
+ * struct.
+ */
+GnssLocation convertToGnssLocation(FlpLocation* location);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif
diff --git a/src/connectivity/gps/service/1.0/GnssXtra.cpp b/src/connectivity/gps/service/1.0/GnssXtra.cpp
new file mode 100644
index 0000000..d124ce1
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssXtra.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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_GnssXtraInterface"
+
+#include "GnssXtra.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssXtra::sThreadFuncArgsList;
+sp<IGnssXtraCallback> GnssXtra::sGnssXtraCbIface = nullptr;
+bool GnssXtra::sInterfaceExists = false;
+
+GpsXtraCallbacks GnssXtra::sGnssXtraCb = {
+    .download_request_cb = gnssXtraDownloadRequestCb,
+    .create_thread_cb = createThreadCb,
+};
+
+GnssXtra::~GnssXtra() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+pthread_t GnssXtra::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+GnssXtra::GnssXtra(const GpsXtraInterface* xtraIface) : mGnssXtraIface(xtraIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+void GnssXtra::gnssXtraDownloadRequestCb() {
+    if (sGnssXtraCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sGnssXtraCbIface->downloadRequestCb();
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+Return<bool> GnssXtra::setCallback(const sp<IGnssXtraCallback>& callback)  {
+    if (mGnssXtraIface == nullptr) {
+        ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+        return false;
+    }
+
+    sGnssXtraCbIface = callback;
+
+    return (mGnssXtraIface->init(&sGnssXtraCb) == 0);
+}
+
+Return<bool> GnssXtra::injectXtraData(const hidl_string& xtraData)  {
+    if (mGnssXtraIface == nullptr) {
+        ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+        return false;
+    }
+
+    char* buf = new char[xtraData.size()];
+    const char* data = xtraData.c_str();
+
+    memcpy(buf, data, xtraData.size());
+
+    int ret = mGnssXtraIface->inject_xtra_data(buf, xtraData.size());
+    delete[] buf;
+    return (ret == 0);
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.0/GnssXtra.h b/src/connectivity/gps/service/1.0/GnssXtra.h
new file mode 100644
index 0000000..7a0733a
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/GnssXtra.h
@@ -0,0 +1,80 @@
+/*
+ * 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_V1_0_GnssXtra_H_
+#define android_hardware_gnss_V1_0_GnssXtra_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssXtra.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssXtra;
+using ::android::hardware::gnss::V1_0::IGnssXtraCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * This interface is used by the GNSS HAL to request the framework to download XTRA data.
+ * Also contains wrapper methods to allow methods from IGnssXtraCallback interface to be passed
+ * into the conventional implementation of the GNSS HAL.
+ */
+struct GnssXtra : public IGnssXtra {
+    GnssXtra(const GpsXtraInterface* xtraIface);
+    ~GnssXtra();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+     * These declarations were generated from IGnssXtra.hal.
+     */
+    Return<bool> setCallback(const sp<IGnssXtraCallback>& callback) override;
+    Return<bool> injectXtraData(const hidl_string& xtraData) override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+     * These methods are not part of the IGnssXtra base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void gnssXtraDownloadRequestCb();
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsXtraCallbacks sGnssXtraCb;
+
+ private:
+    const GpsXtraInterface* mGnssXtraIface = nullptr;
+    static sp<IGnssXtraCallback> sGnssXtraCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssXtra_H_
diff --git a/src/connectivity/gps/service/1.0/NOTICE b/src/connectivity/gps/service/1.0/NOTICE
new file mode 100644
index 0000000..bf532e5
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/NOTICE
@@ -0,0 +1,182 @@
+
+Copyright (C) 2016 The Android Open Source Project
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+
+
diff --git a/src/connectivity/gps/service/1.0/OWNERS b/src/connectivity/gps/service/1.0/OWNERS
new file mode 100644
index 0000000..6c25bd7
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/OWNERS
@@ -0,0 +1,3 @@
+wyattriley@google.com
+gomo@google.com
+smalkos@google.com
diff --git a/src/connectivity/gps/service/1.0/ThreadCreationWrapper.cpp b/src/connectivity/gps/service/1.0/ThreadCreationWrapper.cpp
new file mode 100644
index 0000000..2a5638f
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/ThreadCreationWrapper.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include <ThreadCreationWrapper.h>
+
+void* threadFunc(void* arg) {
+    ThreadFuncArgs* threadArgs = reinterpret_cast<ThreadFuncArgs*>(arg);
+    threadArgs->fptr(threadArgs->args);
+    return nullptr;
+}
+
+pthread_t createPthread(const char* name,
+                        void (*start)(void*),
+                        void* arg, std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs) {
+    pthread_t threadId;
+    auto threadArgs = new ThreadFuncArgs(start, arg);
+    auto argPtr = std::unique_ptr<ThreadFuncArgs>(threadArgs);
+
+    listArgs->push_back(std::move(argPtr));
+
+    int ret = pthread_create(&threadId, nullptr, threadFunc, reinterpret_cast<void*>(
+            threadArgs));
+    if (ret != 0) {
+        ALOGE("pthread creation unsuccessful");
+    } else {
+        pthread_setname_np(threadId, name);
+    }
+    return threadId;
+}
diff --git a/src/connectivity/gps/service/1.0/ThreadCreationWrapper.h b/src/connectivity/gps/service/1.0/ThreadCreationWrapper.h
new file mode 100644
index 0000000..99c8670
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/ThreadCreationWrapper.h
@@ -0,0 +1,58 @@
+/*
+ * 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_THREADCREATIONWRAPPER_H
+#define ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
+
+#include <pthread.h>
+#include <vector>
+#include <log/log.h>
+
+typedef void (*threadEntryFunc)(void* ret);
+
+/*
+ * This class facilitates createThreadCb methods in various GNSS interfaces to wrap
+ * pthread_create() from libc since its function signature differs from what is required by the
+ * conventional GNSS HAL. The arguments passed to pthread_create() need to be on heap and not on
+ * the stack of createThreadCb.
+ */
+struct ThreadFuncArgs {
+    ThreadFuncArgs(void (*start)(void*), void* arg) : fptr(start), args(arg) {}
+
+    /* pointer to the function of type void()(void*) that needs to be wrapped */
+    threadEntryFunc fptr;
+    /* argument for fptr to be called with */
+    void* args;
+};
+
+/*
+ * This method is simply a wrapper. It is required since pthread_create() requires an entry
+ * function pointer of type void*()(void*) and the GNSS hal requires as input a function pointer of
+ * type void()(void*).
+ */
+void* threadFunc(void* arg);
+
+/*
+ * This method is called by createThreadCb with a pointer to the vector that
+ * holds the pointers to the thread arguments. The arg and start parameters are
+ * first used to create a ThreadFuncArgs object which is then saved in the
+ * listArgs parameters. The created ThreadFuncArgs object is then used to invoke
+ * threadFunc() method which in-turn invokes pthread_create.
+ */
+pthread_t createPthread(const char* name, void (*start)(void*), void* arg,
+                        std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs);
+
+#endif
diff --git a/src/connectivity/gps/service/1.0/android.hardware.gnss@1.0-service-mediatek.rc b/src/connectivity/gps/service/1.0/android.hardware.gnss@1.0-service-mediatek.rc
new file mode 100644
index 0000000..9f05c56
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/android.hardware.gnss@1.0-service-mediatek.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@1.0-service-mediatek
+    class hal
+    user system
+    group system gps
diff --git a/src/connectivity/gps/service/1.0/hardware/gps_mtk.h b/src/connectivity/gps/service/1.0/hardware/gps_mtk.h
new file mode 100644
index 0000000..b32199e
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/hardware/gps_mtk.h
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2010 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_INCLUDE_HARDWARE_GPS_MTK_H
+#define ANDROID_INCLUDE_HARDWARE_GPS_MTK_H
+
+#include <hardware/gps_internal.h>
+
+__BEGIN_DECLS
+
+// MTK extended GpsAidingData values.
+#define GPS_DELETE_HOT_STILL 0x2000
+#define GPS_DELETE_EPO      0x4000
+
+// ====================vzw debug screen API =================
+/**
+ * Name for the VZW debug interface.
+ */
+#define VZW_DEBUG_INTERFACE      "vzw-debug"
+
+#define VZW_DEBUG_STRING_MAXLEN      200
+
+/** Represents data of VzwDebugData. */
+typedef struct {
+    /** set to sizeof(VzwDebugData) */
+    size_t size;
+
+    char  vzw_msg_data[VZW_DEBUG_STRING_MAXLEN];
+} VzwDebugData;
+
+
+typedef void (* vzw_debug_callback)(VzwDebugData* vzw_message);
+
+/** Callback structure for the Vzw debug interface. */
+typedef struct {
+    vzw_debug_callback vzw_debug_cb;
+} VzwDebugCallbacks;
+
+
+/** Extended interface for VZW DEBUG support. */
+typedef struct {
+    /** set to sizeof(VzwDebugInterface) */
+    size_t          size;
+
+    /** Registers the callbacks for Vzw debug message. */
+    int  (*init)( VzwDebugCallbacks* callbacks );
+
+    /** Set Vzw debug screen enable/disable **/
+    void (*set_vzw_debug_screen)(bool enabled);
+} VzwDebugInterface;
+
+////////////////////// GNSS HIDL v1.0 ////////////////////////////
+
+/** Represents a location. */
+typedef struct {
+    GpsLocation legacyLocation;
+    /**
+    * Represents expected horizontal position accuracy, radial, in meters
+    * (68% confidence).
+    */
+    float           horizontalAccuracyMeters;
+
+    /**
+    * Represents expected vertical position accuracy in meters
+    * (68% confidence).
+    */
+    float           verticalAccuracyMeters;
+
+    /**
+    * Represents expected speed accuracy in meter per seconds
+    * (68% confidence).
+    */
+    float           speedAccuracyMetersPerSecond;
+
+    /**
+    * Represents expected bearing accuracy in degrees
+    * (68% confidence).
+    */
+    float           bearingAccuracyDegrees;
+
+} GpsLocation_ext;
+
+
+typedef struct {
+    GnssSvInfo legacySvInfo;
+
+    /// v1.0 ///
+    float carrier_frequency;
+
+} GnssSvInfo_ext;
+
+/**
+ * Represents SV status.
+ */
+typedef struct {
+    /** set to sizeof(GnssSvStatus) */
+    size_t size;
+
+    /** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
+    int num_svs;
+    /**
+     * Pointer to an array of SVs information for all GNSS constellations,
+     * except GPS, which is reported using sv_list
+     */
+    GnssSvInfo_ext gnss_sv_list[GNSS_MAX_SVS];
+
+} GnssSvStatus_ext;
+
+/**
+ * Callback with location information. Can only be called from a thread created
+ * by create_thread_cb.
+ */
+typedef void (* gps_location_ext_callback)(GpsLocation_ext* location);
+
+/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gnss_sv_status_ext_callback)(GnssSvStatus_ext* sv_info);
+
+/**
+ * The callback associated with the geofence.
+ * Parameters:
+ *      geofence_id - The id associated with the add_geofence_area.
+ *      location    - The current GPS location.
+ *      transition  - Can be one of GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED,
+ *                    GPS_GEOFENCE_UNCERTAIN.
+ *      timestamp   - Timestamp when the transition was detected.
+ *
+ * The callback should only be called when the caller is interested in that
+ * particular transition. For instance, if the caller is interested only in
+ * ENTERED transition, then the callback should NOT be called with the EXITED
+ * transition.
+ *
+ * IMPORTANT: If a transition is triggered resulting in this callback, the GPS
+ * subsystem will wake up the application processor, if its in suspend state.
+ */
+typedef void (*gps_geofence_transition_ext_callback) (int32_t geofence_id,
+        GpsLocation_ext* location, int32_t transition, GpsUtcTime timestamp);
+
+/**
+ * The callback associated with the availability of the GPS system for geofencing
+ * monitoring. If the GPS system determines that it cannot monitor geofences
+ * because of lack of reliability or unavailability of the GPS signals, it will
+ * call this callback with GPS_GEOFENCE_UNAVAILABLE parameter.
+ *
+ * Parameters:
+ *  status - GPS_GEOFENCE_UNAVAILABLE or GPS_GEOFENCE_AVAILABLE.
+ *  last_location - Last known location.
+ */
+typedef void (*gps_geofence_status_ext_callback) (int32_t status,
+        GpsLocation_ext* last_location);
+
+typedef struct {
+    gps_geofence_transition_ext_callback geofence_transition_callback;
+    gps_geofence_status_ext_callback geofence_status_callback;
+    gps_geofence_add_callback geofence_add_callback;
+    gps_geofence_remove_callback geofence_remove_callback;
+    gps_geofence_pause_callback geofence_pause_callback;
+    gps_geofence_resume_callback geofence_resume_callback;
+    gps_create_thread create_thread_cb;
+} GpsGeofenceCallbacks_ext;
+
+/** Extended interface for GPS_Geofencing support */
+typedef struct {
+   /** set to sizeof(GpsGeofencingInterface) */
+   size_t          size;
+
+   /**
+    * Opens the geofence interface and provides the callback routines
+    * to the implementation of this interface.
+    */
+   void  (*init)( GpsGeofenceCallbacks_ext* callbacks );
+
+   /**
+    * Add a geofence area. This api currently supports circular geofences.
+    * Parameters:
+    *    geofence_id - The id for the geofence. If a geofence with this id
+    *       already exists, an error value (GPS_GEOFENCE_ERROR_ID_EXISTS)
+    *       should be returned.
+    *    latitude, longtitude, radius_meters - The lat, long and radius
+    *       (in meters) for the geofence
+    *    last_transition - The current state of the geofence. For example, if
+    *       the system already knows that the user is inside the geofence,
+    *       this will be set to GPS_GEOFENCE_ENTERED. In most cases, it
+    *       will be GPS_GEOFENCE_UNCERTAIN.
+    *    monitor_transition - Which transitions to monitor. Bitwise OR of
+    *       GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and
+    *       GPS_GEOFENCE_UNCERTAIN.
+    *    notification_responsiveness_ms - Defines the best-effort description
+    *       of how soon should the callback be called when the transition
+    *       associated with the Geofence is triggered. For instance, if set
+    *       to 1000 millseconds with GPS_GEOFENCE_ENTERED, the callback
+    *       should be called 1000 milliseconds within entering the geofence.
+    *       This parameter is defined in milliseconds.
+    *       NOTE: This is not to be confused with the rate that the GPS is
+    *       polled at. It is acceptable to dynamically vary the rate of
+    *       sampling the GPS for power-saving reasons; thus the rate of
+    *       sampling may be faster or slower than this.
+    *    unknown_timer_ms - The time limit after which the UNCERTAIN transition
+    *       should be triggered. This parameter is defined in milliseconds.
+    *       See above for a detailed explanation.
+    */
+   void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude,
+       double radius_meters, int last_transition, int monitor_transitions,
+       int notification_responsiveness_ms, int unknown_timer_ms);
+
+   /**
+    * Pause monitoring a particular geofence.
+    * Parameters:
+    *   geofence_id - The id for the geofence.
+    */
+   void (*pause_geofence) (int32_t geofence_id);
+
+   /**
+    * Resume monitoring a particular geofence.
+    * Parameters:
+    *   geofence_id - The id for the geofence.
+    *   monitor_transitions - Which transitions to monitor. Bitwise OR of
+    *       GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and
+    *       GPS_GEOFENCE_UNCERTAIN.
+    *       This supersedes the value associated provided in the
+    *       add_geofence_area call.
+    */
+   void (*resume_geofence) (int32_t geofence_id, int monitor_transitions);
+
+   /**
+    * Remove a geofence area. After the function returns, no notifications
+    * should be sent.
+    * Parameter:
+    *   geofence_id - The id for the geofence.
+    */
+   void (*remove_geofence_area) (int32_t geofence_id);
+} GpsGeofencingInterface_ext;
+
+typedef struct {
+    GnssMeasurement legacyMeasurement;
+
+    /**
+     * Automatic gain control (AGC) level. AGC acts as a variable gain
+     * amplifier adjusting the power of the incoming signal. The AGC level
+     * may be used to indicate potential interference. When AGC is at a
+     * nominal level, this value must be set as 0. Higher gain (and/or lower
+     * input power) must be output as a positive number. Hence in cases of
+     * strong jamming, in the band of this signal, this value must go more
+     * negative.
+     *
+     * Note: Different hardware designs (e.g. antenna, pre-amplification, or
+     * other RF HW components) may also affect the typical output of of this
+     * value on any given hardware design in an open sky test - the
+     * important aspect of this output is that changes in this value are
+     * indicative of changes on input signal power in the frequency band for
+     * this measurement.
+     */
+    double agc_level_db;
+} GnssMeasurement_ext;
+
+/**
+ * Represents a reading of GNSS measurements. For devices where GnssSystemInfo's
+ * year_of_hw is set to 2016+, it is mandatory that these be provided, on
+ * request, when the GNSS receiver is searching/tracking signals.
+ *
+ * - Reporting of GPS constellation measurements is mandatory.
+ * - Reporting of all tracked constellations are encouraged.
+ */
+typedef struct {
+    /** set to sizeof(GnssData) */
+    size_t size;
+
+    /** Number of measurements. */
+    size_t measurement_count;
+
+    /** The array of measurements. */
+    GnssMeasurement_ext measurements[GNSS_MAX_MEASUREMENT];
+
+    /** The GPS clock time reading. */
+    GnssClock clock;
+} GnssData_ext;
+
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ *    data - A data structure containing the measurements.
+ */
+typedef void (*gnss_measurement_ext_callback) (GnssData_ext* data);
+
+typedef struct {
+    /** set to sizeof(GpsMeasurementCallbacks) */
+    size_t size;
+    gps_measurement_callback measurement_callback;
+    gnss_measurement_ext_callback gnss_measurement_callback;
+} GpsMeasurementCallbacks_ext;
+
+
+/////// Gnss debug ////
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t GnssUtcTime;
+
+typedef enum {
+    /** Ephemeris is known for this satellite. */
+    EPHEMERIS,
+    /**
+     * Ephemeris is not known, but Almanac (approximate location) is known.
+     */
+    ALMANAC_ONLY,
+    /**
+     * Both ephemeris & almanac are not known (e.g. during a cold start
+     * blind search.)
+     */
+    NOT_AVAILABLE
+} SatelliteEphemerisType;
+
+typedef enum {
+    /**
+     * The ephemeris (or almanac only) information was demodulated from the
+     * signal received on the device
+     */
+    DEMODULATED,
+    /**
+     * The ephemeris (or almanac only) information was received from a SUPL
+     * server.
+     */
+    SUPL_PROVIDED,
+    /**
+     * The ephemeris (or almanac only) information was provided by another
+     * server.
+     */
+    OTHER_SERVER_PROVIDED,
+    /**
+     * The ephemeris (or almanac only) information was provided by another
+     * method, e.g. injected via a local debug tool, from build defaults
+     * (e.g. almanac), or is from a satellite
+     * with SatelliteEphemerisType::NOT_AVAILABLE.
+     */
+    OTHER
+} SatelliteEphemerisSource;
+
+typedef enum {
+    /** The ephemeris is known good. */
+    GOOD,
+    /** The ephemeris is known bad. */
+    BAD,
+    /** The ephemeris is unknown to be good or bad. */
+    UNKNOWN
+} SatelliteEphemerisHealth;
+
+/**
+ * Provides the current best known position from any
+ * source (GNSS or injected assistance).
+ */
+typedef struct {
+    /**
+     * Validity of the data in this struct. False only if no
+     * latitude/longitude information is known.
+     */
+    bool valid;
+    /** Latitude expressed in degrees */
+    double latitudeDegrees;
+    /** Longitude expressed in degrees */
+    double longitudeDegrees;
+    /** Altitude above ellipsoid expressed in meters */
+    float altitudeMeters;
+    /** Represents horizontal speed in meters per second. */
+    float speedMetersPerSec;
+    /** Represents heading in degrees. */
+    float bearingDegrees;
+    /**
+     * Estimated horizontal accuracy of position expressed in meters,
+     * radial, 68% confidence.
+     */
+    double horizontalAccuracyMeters;
+    /**
+     * Estimated vertical accuracy of position expressed in meters, with
+     * 68% confidence.
+     */
+    double verticalAccuracyMeters;
+    /**
+     * Estimated speed accuracy in meters per second with 68% confidence.
+     */
+    double speedAccuracyMetersPerSecond;
+    /**
+     * estimated bearing accuracy degrees with 68% confidence.
+     */
+    double bearingAccuracyDegrees;
+    /**
+     * Time duration before this report that this position information was
+     * valid.  This can, for example, be a previous injected location with
+     * an age potentially thousands of seconds old, or
+     * extrapolated to the current time (with appropriately increased
+     * accuracy estimates), with a (near) zero age.
+     */
+    float ageSeconds;
+} PositionDebug;
+
+/**
+ * Provides the current best known UTC time estimate.
+ * If no fresh information is available, e.g. after a delete all,
+ * then whatever the effective defaults are on the device must be
+ * provided (e.g. Jan. 1, 2017, with an uncertainty of 5 years) expressed
+ * in the specified units.
+ */
+typedef struct {
+    /** UTC time estimate. */
+    GnssUtcTime timeEstimate;
+    /** 68% error estimate in time. */
+    float timeUncertaintyNs;
+    /**
+     * 68% error estimate in local clock drift,
+     * in nanoseconds per second (also known as parts per billion - ppb.)
+     */
+    float frequencyUncertaintyNsPerSec;
+} TimeDebug;
+
+/**
+ * Provides a single satellite info that has decoded navigation data.
+ */
+typedef struct {
+    /** Satellite vehicle ID number */
+    int16_t svid;
+    /** Defines the constellation type of the given SV. */
+    GnssConstellationType constellation;
+
+    /**
+     * Defines the standard broadcast ephemeris or almanac availability for
+     * the satellite.  To report status of predicted orbit and clock
+     * information, see the serverPrediction fields below.
+     */
+    SatelliteEphemerisType ephemerisType;
+    /** Defines the ephemeris source of the satellite. */
+    SatelliteEphemerisSource ephemerisSource;
+    /**
+     * Defines whether the satellite is known healthy
+     * (safe for use in location calculation.)
+     */
+    SatelliteEphemerisHealth ephemerisHealth;
+    /**
+     * Time duration from this report (current time), minus the
+     * effective time of the ephemeris source (e.g. TOE, TOA.)
+     * Set to 0 when ephemerisType is NOT_AVAILABLE.
+     */
+    float ephemerisAgeSeconds;
+
+    /**
+     * True if a server has provided a predicted orbit and clock model for
+     * this satellite.
+     */
+    bool serverPredictionIsAvailable;
+    /**
+     * Time duration from this report (current time) minus the time of the
+     * start of the server predicted information.  For example, a 1 day
+     * old prediction would be reported as 86400 seconds here.
+     */
+    float serverPredictionAgeSeconds;
+} SatelliteData;
+
+/**
+ * Provides a set of debug information that is filled by the GNSS chipset
+ * when the method getDebugData() is invoked.
+ */
+typedef struct {
+    /** Current best known position. */
+    PositionDebug position;
+    /** Current best know time estimate */
+    TimeDebug time;
+    /**
+     * Provides a list of the available satellite data, for all
+     * satellites and constellations the device can track,
+     * including GnssConstellationType UNKNOWN.
+     */
+    SatelliteData satelliteDataArray[GNSS_MAX_SVS];
+} DebugData;
+
+
+/** Extended interface for DEBUG support. */
+typedef struct {
+    /** set to sizeof(GpsDebugInterface) */
+    size_t          size;
+
+    /**
+     * This function should return any information that the native
+     * implementation wishes to include in a bugreport.
+     */
+    // size_t (*get_internal_state)(char* buffer, size_t bufferSize);
+    /// v1.0 ///
+    bool (*get_internal_state)(DebugData* debugData);
+} GpsDebugInterface_ext;
+
+
+////////////////////// GNSS HIDL v1.1 ////////////////////////////
+
+/**
+ * Callback for reporting driver name information.
+ */
+typedef void (* gnss_set_name_callback)(const char* name, int length);
+
+/**
+ * Callback for requesting framework NLP or Fused location injection.
+ */
+typedef void (* gnss_request_location_callback)(bool independentFromGnss);
+
+/** New GPS callback structure. */
+typedef struct {
+    /** set to sizeof(GpsCallbacks) */
+    size_t      size;
+    gps_location_ext_callback location_cb;
+    gps_status_callback status_cb;
+    gps_sv_status_callback sv_status_cb;
+    gps_nmea_callback nmea_cb;
+    gps_set_capabilities set_capabilities_cb;
+    gps_acquire_wakelock acquire_wakelock_cb;
+    gps_release_wakelock release_wakelock_cb;
+    gps_create_thread create_thread_cb;
+    gps_request_utc_time request_utc_time_cb;
+
+    gnss_set_system_info set_system_info_cb;
+    gnss_sv_status_ext_callback gnss_sv_status_cb;
+
+    /////v1.1////
+    gnss_set_name_callback set_name_cb;
+    gnss_request_location_callback request_location_cb;
+} GpsCallbacks_ext;
+
+
+/** Represents the standard GPS interface. */
+typedef struct {
+    /** set to sizeof(GpsInterface) */
+    size_t          size;
+    /**
+     * Opens the interface and provides the callback routines
+     * to the implementation of this interface.
+     */
+    /// v1.0 ///
+//    int   (*init)( GpsCallbacks* callbacks );
+    /// v1.1 ///
+    int   (*init)( GpsCallbacks_ext* callbacks );
+
+    /** Starts navigating. */
+    int   (*start)( void );
+
+    /** Stops navigating. */
+    int   (*stop)( void );
+
+    /** Closes the interface. */
+    void  (*cleanup)( void );
+
+    /** Injects the current time. */
+    int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
+                         int uncertainty);
+
+    /**
+     * Injects current location from another location provider (typically cell
+     * ID). Latitude and longitude are measured in degrees expected accuracy is
+     * measured in meters
+     */
+    int  (*inject_location)(double latitude, double longitude, float accuracy);
+
+    /**
+     * Specifies that the next call to start will not use the
+     * information defined in the flags. GPS_DELETE_ALL is passed for
+     * a cold start.
+     */
+    void  (*delete_aiding_data)(GpsAidingData flags);
+
+    /**
+     * min_interval represents the time between fixes in milliseconds.
+     * preferred_accuracy represents the requested fix accuracy in meters.
+     * preferred_time represents the requested time to first fix in milliseconds.
+     *
+     * 'mode' parameter should be one of GPS_POSITION_MODE_MS_BASED
+     * or GPS_POSITION_MODE_STANDALONE.
+     * It is allowed by the platform (and it is recommended) to fallback to
+     * GPS_POSITION_MODE_MS_BASED if GPS_POSITION_MODE_MS_ASSISTED is passed in, and
+     * GPS_POSITION_MODE_MS_BASED is supported.
+     */
+     /// v1.0 ///
+//    int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+//            uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
+    /// v1.1 ///
+    int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+            uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time,
+            bool lowPowerMode);
+
+
+    /** Get a pointer to extension information. */
+    const void* (*get_extension)(const char* name);
+
+    /// v1.1 ///
+    int  (*inject_fused_location)(double latitude, double longitude, float accuracy);
+
+} GpsInterface_ext;
+
+
+/**
+ * Extended interface for GPS Measurements support.
+ */
+typedef struct {
+    /** Set to sizeof(GpsMeasurementInterface_ext) */
+    size_t size;
+
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     * After a successful call to 'init' the HAL must begin to provide updates at its own phase.
+     *
+     * Status:
+     *    GPS_MEASUREMENT_OPERATION_SUCCESS
+     *    GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a
+     *              corresponding call to 'close'
+     *    GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL
+     *              will not generate any updates upon returning this error code.
+     */
+    /// v1.0 ///
+//    int (*init) (GpsMeasurementCallbacks* callbacks);
+    /// v1.1 ///
+    int (*init) (GpsMeasurementCallbacks_ext* callbacks, bool enableFullTracking);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     * After a call to stop, the previously registered callbacks must be considered invalid by the
+     * HAL.
+     * If stop is invoked without a previous 'init', this function should perform no work.
+     */
+    void (*close) ();
+
+} GpsMeasurementInterface_ext;
+
+
+/**
+ * Interface for passing GNSS configuration contents from platform to HAL.
+ */
+typedef struct {
+    /** Set to sizeof(GnssConfigurationInterface) */
+    size_t size;
+
+    /**
+     * Deliver GNSS configuration contents to HAL.
+     * Parameters:
+     *     config_data - a pointer to a char array which holds what usually is expected from
+                         file(/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'.
+     *     length - total number of UTF8 characters in configuraiton data.
+     *
+     * IMPORTANT:
+     *      GPS HAL should expect this function can be called multiple times. And it may be
+     *      called even when GpsLocationProvider is already constructed and enabled. GPS HAL
+     *      should maintain the existing requests for various callback regardless the change
+     *      in configuration data.
+     */
+    void (*configuration_update) (const char* config_data, int32_t length);
+
+   //// v1.1 ////
+   void (*setBlacklist) (long long* blacklist, int32_t size);
+} GnssConfigurationInterface_ext;
+
+struct gps_device_t_ext {
+    struct hw_device_t common;
+
+    /**
+     * Set the provided lights to the provided values.
+     *
+     * Returns: 0 on succes, error code on failure.
+     */
+    const GpsInterface_ext* (*get_gps_interface)(struct gps_device_t_ext* dev);
+};
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_GPS_MTK_H */
+
diff --git a/src/connectivity/gps/service/1.0/service.cpp b/src/connectivity/gps/service/1.0/service.cpp
new file mode 100644
index 0000000..0704e7f
--- /dev/null
+++ b/src/connectivity/gps/service/1.0/service.cpp
@@ -0,0 +1,17 @@
+#define LOG_TAG "android.hardware.gnss@1.0-service"
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+#include <hidl/LegacySupport.h>
+
+#include <binder/ProcessState.h>
+
+using android::hardware::gnss::V1_0::IGnss;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    // The GNSS HAL may communicate to other vendor components via
+    // /dev/vndbinder
+    android::ProcessState::initWithDriver("/dev/vndbinder");
+    return defaultPassthroughServiceImplementation<IGnss>();
+}
diff --git a/src/connectivity/gps/service/1.1/AGnss.cpp b/src/connectivity/gps/service/1.1/AGnss.cpp
new file mode 100644
index 0000000..29c6ddd
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/AGnss.cpp
@@ -0,0 +1,198 @@
+/*
+ * 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_AGnssInterface"
+
+#include "AGnss.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnss::sThreadFuncArgsList;
+sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr;
+bool AGnss::sInterfaceExists = false;
+
+AGpsCallbacks AGnss::sAGnssCb = {
+    .status_cb = statusCb,
+    .create_thread_cb = createThreadCb
+};
+
+AGnss::AGnss(const AGpsInterface* aGpsIface) : mAGnssIface(aGpsIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+AGnss::~AGnss() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+void AGnss::statusCb(AGpsStatus* status) {
+    if (sAGnssCbIface == nullptr) {
+        ALOGE("%s: AGNSS Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (status == nullptr) {
+        ALOGE("AGNSS status is invalid");
+        return;
+    }
+
+    /*
+     * Logic based on AGnssStatus processing by GnssLocationProvider. Size of
+     * AGpsStatus is checked for backward compatibility since some devices may
+     * be sending out an older version of AGpsStatus that only supports IPv4.
+     */
+    size_t statusSize = status->size;
+    if (status->size == sizeof(AGpsStatus)) {
+        switch (status->addr.ss_family)
+        {
+            case AF_INET:
+                {
+                    /*
+                     * ss_family indicates IPv4.
+                     */
+                    struct sockaddr_in* in = reinterpret_cast<struct sockaddr_in*>(&(status->addr));
+                    IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+                        .type = static_cast<IAGnssCallback::AGnssType>(status->type),
+                        .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+                        .ipV4Addr = in->sin_addr.s_addr,
+                    };
+
+                    /*
+                     * Callback to client with agnssStatusIpV4Cb.
+                     */
+                    auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+                    if (!ret.isOk()) {
+                        ALOGE("%s: Unable to invoke callback", __func__);
+                    }
+                    break;
+                }
+            case AF_INET6:
+                {
+                    /*
+                     * ss_family indicates IPv6. Callback to client with agnssStatusIpV6Cb.
+                     */
+                    IAGnssCallback::AGnssStatusIpV6 aGnssStatusIpV6;
+
+                    aGnssStatusIpV6.type = static_cast<IAGnssCallback::AGnssType>(status->type);
+                    aGnssStatusIpV6.status = static_cast<IAGnssCallback::AGnssStatusValue>(
+                            status->status);
+
+                    struct sockaddr_in6* in6 = reinterpret_cast<struct sockaddr_in6 *>(
+                            &(status->addr));
+                    memcpy(&(aGnssStatusIpV6.ipV6Addr[0]), in6->sin6_addr.s6_addr,
+                           aGnssStatusIpV6.ipV6Addr.size());
+                    auto ret = sAGnssCbIface->agnssStatusIpV6Cb(aGnssStatusIpV6);
+                    if (!ret.isOk()) {
+                        ALOGE("%s: Unable to invoke callback", __func__);
+                    }
+                    break;
+                }
+             default:
+                    ALOGE("Invalid ss_family found: %d", status->addr.ss_family);
+        }
+    } else if (statusSize >= sizeof(AGpsStatus_v2)) {
+        AGpsStatus_v2* statusV2 = reinterpret_cast<AGpsStatus_v2*>(status);
+        uint32_t ipV4Addr = statusV2->ipaddr;
+        IAGnssCallback::AGnssStatusIpV4 aGnssStatusIpV4 = {
+            .type = static_cast<IAGnssCallback::AGnssType>(AF_INET),
+            .status = static_cast<IAGnssCallback::AGnssStatusValue>(status->status),
+            /*
+             * For older versions of AGpsStatus, change IP addr to net order. This
+             * was earlier being done in GnssLocationProvider.
+             */
+            .ipV4Addr = htonl(ipV4Addr)
+        };
+        /*
+         * Callback to client with agnssStatusIpV4Cb.
+         */
+        auto ret = sAGnssCbIface->agnssStatusIpV4Cb(aGnssStatusIpV4);
+        if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+        }
+    } else {
+        ALOGE("%s: Invalid size for AGPS Status", __func__);
+    }
+}
+
+pthread_t AGnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+/*
+ * Implementation of methods from ::android::hardware::gnss::V1_0::IAGnss follow.
+ */
+Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return Void();
+    }
+
+    sAGnssCbIface = callback;
+
+    mAGnssIface->init(&sAGnssCb);
+    return Void();
+}
+
+Return<bool> AGnss::dataConnClosed()  {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_closed() == 0);
+}
+
+Return<bool> AGnss::dataConnFailed()  {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_failed() == 0);
+}
+
+Return<bool> AGnss::setServer(IAGnssCallback::AGnssType type,
+                              const hidl_string& hostname,
+                              int32_t port) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->set_server(static_cast<AGpsType>(type), hostname.c_str(), port) == 0);
+}
+
+Return<bool> AGnss::dataConnOpen(const hidl_string& apn, IAGnss::ApnIpType apnIpType) {
+    if (mAGnssIface == nullptr) {
+        ALOGE("%s: AGnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mAGnssIface->data_conn_open_with_apn_ip_type(apn.c_str(),
+                                                     static_cast<uint16_t>(apnIpType)) == 0);
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/AGnss.h b/src/connectivity/gps/service/1.1/AGnss.h
new file mode 100644
index 0000000..2a8eed0
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/AGnss.h
@@ -0,0 +1,85 @@
+/*
+ * 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_V1_0_AGnss_H_
+#define android_hardware_gnss_V1_0_AGnss_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnss.h>
+#include <hardware/gps_internal.h>
+#include <hidl/Status.h>
+#include <netinet/in.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnss;
+using ::android::hardware::gnss::V1_0::IAGnssCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * Extended interface for AGNSS support. Also contains wrapper methods to allow
+ * methods from IAGnssCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct AGnss : public IAGnss {
+    AGnss(const AGpsInterface* agpsIface);
+    ~AGnss();
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow.
+     * These declarations were generated from IAGnss.hal.
+     */
+    Return<void> setCallback(const sp<IAGnssCallback>& callback) override;
+    Return<bool> dataConnClosed() override;
+    Return<bool> dataConnFailed() override;
+    Return<bool> setServer(IAGnssCallback::AGnssType type,
+                         const hidl_string& hostname, int32_t port) override;
+    Return<bool> dataConnOpen(const hidl_string& apn,
+                                           IAGnss::ApnIpType apnIpType) override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IAGnss base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void statusCb(AGpsStatus* status);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static AGpsCallbacks sAGnssCb;
+
+ private:
+    const AGpsInterface* mAGnssIface = nullptr;
+    static sp<IAGnssCallback> sAGnssCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_AGnss_H_
diff --git a/src/connectivity/gps/service/1.1/AGnssRil.cpp b/src/connectivity/gps/service/1.1/AGnssRil.cpp
new file mode 100644
index 0000000..1458327
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/AGnssRil.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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_AGnssRilInterface"
+
+#include "AGnssRil.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> AGnssRil::sThreadFuncArgsList;
+sp<IAGnssRilCallback> AGnssRil::sAGnssRilCbIface = nullptr;
+bool AGnssRil::sInterfaceExists = false;
+
+AGpsRilCallbacks AGnssRil::sAGnssRilCb = {
+    .request_setid = AGnssRil::requestSetId,
+    .request_refloc = AGnssRil::requestRefLoc,
+    .create_thread_cb = AGnssRil::createThreadCb
+};
+
+AGnssRil::AGnssRil(const AGpsRilInterface* aGpsRilIface) : mAGnssRilIface(aGpsRilIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+AGnssRil::~AGnssRil() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+void AGnssRil::requestSetId(uint32_t flags) {
+    if (sAGnssRilCbIface == nullptr) {
+        ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sAGnssRilCbIface->requestSetIdCb(flags);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void AGnssRil::requestRefLoc(uint32_t /*flags*/) {
+    if (sAGnssRilCbIface == nullptr) {
+        ALOGE("%s: AGNSSRil Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sAGnssRilCbIface->requestRefLocCb();
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+pthread_t AGnssRil::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+Return<void> AGnssRil::setCallback(const sp<IAGnssRilCallback>& callback)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return Void();
+    }
+
+    sAGnssRilCbIface = callback;
+
+    mAGnssRilIface->init(&sAGnssRilCb);
+    return Void();
+}
+
+Return<void> AGnssRil::setRefLocation(const IAGnssRil::AGnssRefLocation& aGnssRefLocation)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return Void();
+    }
+
+    AGpsRefLocation aGnssRefloc;
+    aGnssRefloc.type = static_cast<uint16_t>(aGnssRefLocation.type);
+
+    auto& cellID = aGnssRefLocation.cellID;
+    aGnssRefloc.u.cellID = {
+        .type = static_cast<uint16_t>(cellID.type),
+        .mcc = cellID.mcc,
+        .mnc = cellID.mnc,
+        .lac = cellID.lac,
+        .cid = cellID.cid,
+        .tac = cellID.tac,
+        .pcid = cellID.pcid
+    };
+
+    mAGnssRilIface->set_ref_location(&aGnssRefloc, sizeof(aGnssRefloc));
+    return Void();
+}
+
+Return<bool> AGnssRil::setSetId(IAGnssRil::SetIDType type, const hidl_string& setid)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->set_set_id(static_cast<uint16_t>(type), setid.c_str());
+    return true;
+}
+
+Return<bool> AGnssRil::updateNetworkState(bool connected,
+                                          IAGnssRil::NetworkType type,
+                                          bool roaming) {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->update_network_state(connected,
+                                         static_cast<int>(type),
+                                         roaming,
+                                         nullptr /* extra_info */);
+    return true;
+}
+
+Return<bool> AGnssRil::updateNetworkAvailability(bool available, const hidl_string& apn)  {
+    if (mAGnssRilIface == nullptr) {
+        ALOGE("%s: AGnssRil interface is unavailable", __func__);
+        return false;
+    }
+
+    mAGnssRilIface->update_network_availability(available, apn.c_str());
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/AGnssRil.h b/src/connectivity/gps/service/1.1/AGnssRil.h
new file mode 100644
index 0000000..6215a9e
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/AGnssRil.h
@@ -0,0 +1,88 @@
+/*
+ * 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_V1_0_AGnssRil_H_
+#define android_hardware_gnss_V1_0_AGnssRil_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IAGnssRil.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IAGnssRil;
+using ::android::hardware::gnss::V1_0::IAGnssRilCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * 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 IAGnssRil {
+    AGnssRil(const AGpsRilInterface* aGpsRilIface);
+    ~AGnssRil();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IAGnssRil follow.
+     * These declarations were generated from IAGnssRil.hal.
+     */
+    Return<void> setCallback(const sp<IAGnssRilCallback>& callback) override;
+    Return<void> setRefLocation(const IAGnssRil::AGnssRefLocation& agnssReflocation) override;
+    Return<bool> setSetId(IAGnssRil::SetIDType type, const hidl_string& setid) override;
+    Return<bool> updateNetworkState(bool connected,
+                                    IAGnssRil::NetworkType type,
+                                    bool roaming) override;
+    Return<bool> updateNetworkAvailability(bool available, const hidl_string& apn) override;
+    static void requestSetId(uint32_t flags);
+    static void requestRefLoc(uint32_t flags);
+
+    /*
+     * Callback method to be passed into the conventional GNSS HAL by the default
+     * implementation. This method is not part of the IAGnssRil base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static AGpsRilCallbacks sAGnssRilCb;
+
+ private:
+    const AGpsRilInterface* mAGnssRilIface = nullptr;
+    static sp<IAGnssRilCallback> sAGnssRilCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_AGnssRil_H_
diff --git a/src/connectivity/gps/service/1.1/Android.mk b/src/connectivity/gps/service/1.1/Android.mk
new file mode 100644
index 0000000..acd55f8
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/Android.mk
@@ -0,0 +1,64 @@
+ifdef HIDL_V1_1
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.gnss@1.1-impl-mediatek
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := mtk
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_SRC_FILES := \
+    ThreadCreationWrapper.cpp \
+    AGnss.cpp \
+    AGnssRil.cpp \
+    Gnss.cpp \
+    GnssBatching.cpp \
+    GnssDebug.cpp \
+    GnssGeofencing.cpp \
+    GnssMeasurement.cpp \
+    GnssNavigationMessage.cpp \
+    GnssNi.cpp \
+    GnssXtra.cpp \
+    GnssConfiguration.cpp \
+    GnssUtils.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libhidlbase \
+    libhidltransport \
+    libutils \
+    android.hardware.gnss@1.0 \
+    android.hardware.gnss@1.1 \
+    libhardware \
+
+LOCAL_CFLAGS += -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := mtk
+LOCAL_MODULE := android.hardware.gnss@1.1-service-mediatek
+LOCAL_INIT_RC := android.hardware.gnss@1.1-service-mediatek.rc
+LOCAL_SRC_FILES := \
+    service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libcutils \
+    libdl \
+    libbase \
+    libutils \
+    libhardware \
+    libbinder \
+    libhidlbase \
+    libhidltransport \
+    android.hardware.gnss@1.1 \
+
+LOCAL_REQUIRED_MODULES := \
+    android.hardware.gnss@1.1-impl-mediatek
+
+include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/src/connectivity/gps/service/1.1/Gnss.cpp b/src/connectivity/gps/service/1.1/Gnss.cpp
new file mode 100644
index 0000000..4559008
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/Gnss.cpp
@@ -0,0 +1,872 @@
+/*
+ * 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_GnssInterface"
+
+#include "Gnss.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> Gnss::sThreadFuncArgsList;
+sp<IGnssCallback> Gnss::sGnssCbIface = nullptr;
+bool Gnss::sInterfaceExists = false;
+bool Gnss::sWakelockHeldGnss = false;
+bool Gnss::sWakelockHeldFused = false;
+
+GpsCallbacks_ext Gnss::sGnssCb = {
+    .size = sizeof(GpsCallbacks_ext),
+    .location_cb = locationCb,
+    .status_cb = statusCb,
+    .sv_status_cb = gpsSvStatusCb,
+    .nmea_cb = nmeaCb,
+    .set_capabilities_cb = setCapabilitiesCb,
+    .acquire_wakelock_cb = acquireWakelockCb,
+    .release_wakelock_cb = releaseWakelockCb,
+    .create_thread_cb = createThreadCb,
+    .request_utc_time_cb = requestUtcTimeCb,
+    .set_system_info_cb = setSystemInfoCb,
+    .gnss_sv_status_cb = gnssSvStatusCb,
+
+    .set_name_cb = setNameCb,
+    .request_location_cb = requestLocationCb
+};
+
+uint32_t Gnss::sCapabilitiesCached = 0;
+uint16_t Gnss::sYearOfHwCached = 0;
+sem_t Gnss::sSem;
+
+Gnss::Gnss(gps_device_t_ext* gnssDevice) :
+        mDeathRecipient(new GnssHidlDeathRecipient(this)) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+
+    if (gnssDevice == nullptr) {
+        ALOGE("%s: Invalid device_t handle", __func__);
+        return;
+    }
+
+    mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
+    sem_init(&sSem, 0, 1);
+}
+
+Gnss::~Gnss() {
+    sInterfaceExists = false;
+    sThreadFuncArgsList.clear();
+    sem_destroy(&sSem);
+}
+
+void Gnss::locationCb(GpsLocation_ext* location) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (location == nullptr) {
+        ALOGE("%s: Invalid location from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    GnssLocation gnssLocation = V1_0::implementation::convertToGnssLocation(location);
+    auto ret = sGnssCbIface->gnssLocationCb(gnssLocation);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::statusCb(GpsStatus* gnssStatus) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (gnssStatus == nullptr) {
+        ALOGE("%s: Invalid GpsStatus from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssStatusValue status =
+            static_cast<IGnssCallback::GnssStatusValue>(gnssStatus->status);
+
+    auto ret = sGnssCbIface->gnssStatusCb(status);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::gnssSvStatusCb(GnssSvStatus_ext* status) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (status == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = status->num_svs;
+
+    if (svStatus.numSvs > static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT)) {
+        ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, V1_0::GnssMax::SVS_COUNT);
+        svStatus.numSvs = static_cast<uint32_t>(V1_0::GnssMax::SVS_COUNT);
+    }
+
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        auto svInfo = status->gnss_sv_list[i];
+        IGnssCallback::GnssSvInfo gnssSvInfo = {
+            .svid = svInfo.legacySvInfo.svid,
+            .constellation = static_cast<V1_0::GnssConstellationType>(
+                    svInfo.legacySvInfo.constellation),
+            .cN0Dbhz = svInfo.legacySvInfo.c_n0_dbhz,
+            .elevationDegrees = svInfo.legacySvInfo.elevation,
+            .azimuthDegrees = svInfo.legacySvInfo.azimuth,
+            .svFlag = static_cast<uint8_t>(svInfo.legacySvInfo.flags),
+            .carrierFrequencyHz = svInfo.carrier_frequency};
+        svStatus.gnssSvList[i] = gnssSvInfo;
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+/*
+ * This enum is used by gpsSvStatusCb() method below to convert GpsSvStatus
+ * to GnssSvStatus for backward compatibility. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum SvidValues : uint16_t {
+    GLONASS_SVID_OFFSET = 64,
+    GLONASS_SVID_COUNT = 24,
+    BEIDOU_SVID_OFFSET = 200,
+    BEIDOU_SVID_COUNT = 35,
+    SBAS_SVID_MIN = 33,
+    SBAS_SVID_MAX = 64,
+    SBAS_SVID_ADD = 87,
+    QZSS_SVID_MIN = 193,
+    QZSS_SVID_MAX = 200
+};
+
+/*
+ * The following code that converts GpsSvStatus to GnssSvStatus is moved here from
+ * GnssLocationProvider. GnssLocationProvider does not require it anymore since GpsSvStatus is
+ * being deprecated and is no longer part of the GNSS interface.
+ */
+void Gnss::gpsSvStatusCb(GpsSvStatus* svInfo) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (svInfo == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = svInfo->num_svs;
+    /*
+     * Clamp the list size since GnssSvStatus can support a maximum of
+     * GnssMax::SVS_COUNT entries.
+     */
+    ///M: fix max numSvs as GPS_MAX_SVS
+    if (svStatus.numSvs > static_cast<uint32_t>(GPS_MAX_SVS)) {
+        ALOGW("Too many satellites %u. Clamps to %d.", svStatus.numSvs, GPS_MAX_SVS);
+        svStatus.numSvs = static_cast<uint32_t>(GPS_MAX_SVS);
+    }
+    /// M: mtk update end
+
+    uint32_t ephemerisMask = svInfo->ephemeris_mask;
+    uint32_t almanacMask = svInfo->almanac_mask;
+    uint32_t usedInFixMask = svInfo->used_in_fix_mask;
+    /*
+     * Conversion from GpsSvInfo to IGnssCallback::GnssSvInfo happens below.
+     */
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList[i];
+        info.svid = svInfo->sv_list[i].prn;
+        if (info.svid >= 1 && info.svid <= 32) {
+            info.constellation = GnssConstellationType::GPS;
+        } else if (info.svid > GLONASS_SVID_OFFSET &&
+                   info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
+            info.constellation = GnssConstellationType::GLONASS;
+            info.svid -= GLONASS_SVID_OFFSET;
+        } else if (info.svid > BEIDOU_SVID_OFFSET &&
+                 info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
+            info.constellation = GnssConstellationType::BEIDOU;
+            info.svid -= BEIDOU_SVID_OFFSET;
+        } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
+            info.constellation = GnssConstellationType::SBAS;
+            info.svid += SBAS_SVID_ADD;
+        } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
+            info.constellation = GnssConstellationType::QZSS;
+        } else {
+            ALOGD("Unknown constellation type with Svid = %d.", info.svid);
+            info.constellation = GnssConstellationType::UNKNOWN;
+        }
+
+        info.cN0Dbhz = svInfo->sv_list[i].snr;
+        info.elevationDegrees = svInfo->sv_list[i].elevation;
+        info.azimuthDegrees = svInfo->sv_list[i].azimuth;
+        // TODO: b/31702236
+        info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+
+        /*
+         * Only GPS info is valid for these fields, as these masks are just 32
+         * bits, by GPS prn.
+         */
+        if (info.constellation == GnssConstellationType::GPS) {
+            int32_t svidMask = (1 << (info.svid - 1));
+            if ((ephemerisMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+            }
+            if ((almanacMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+            }
+            if ((usedInFixMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+            }
+        }
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::nmeaCb(GpsUtcTime timestamp, const char* nmea, int length) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    android::hardware::hidl_string nmeaString;
+    nmeaString.setToExternal(nmea, length);
+    auto ret = sGnssCbIface->gnssNmeaCb(timestamp, nmeaString);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::setCapabilitiesCb(uint32_t capabilities) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssSetCapabilitesCb(capabilities);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sCapabilitiesCached = capabilities;
+    sem_post(&sSem);
+}
+
+void Gnss::acquireWakelockCb() {
+    acquireWakelockGnss();
+}
+
+void Gnss::releaseWakelockCb() {
+    releaseWakelockGnss();
+}
+
+
+void Gnss::acquireWakelockGnss() {
+    sWakelockHeldGnss = true;
+    updateWakelock();
+}
+
+void Gnss::releaseWakelockGnss() {
+    sWakelockHeldGnss = false;
+    updateWakelock();
+}
+
+void Gnss::acquireWakelockFused() {
+    sWakelockHeldFused = true;
+    updateWakelock();
+}
+
+void Gnss::releaseWakelockFused() {
+    sWakelockHeldFused = false;
+    updateWakelock();
+}
+
+void Gnss::updateWakelock() {
+    // Track the state of the last request - in case the wake lock in the layer above is reference
+    // counted.
+    static bool sWakelockHeld = false;
+
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (sWakelockHeldGnss || sWakelockHeldFused) {
+        if (!sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock acquired due to gps: %d, fused: %d", __func__,
+                    sWakelockHeldGnss, sWakelockHeldFused);
+            sWakelockHeld = true;
+            auto ret = sGnssCbIface->gnssAcquireWakelockCb();
+            if (!ret.isOk()) {
+                ALOGE("%s: Unable to invoke callback", __func__);
+            }
+        }
+    } else {
+        if (sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock released", __func__);
+        } else  {
+            // To avoid burning power, always release, even if logic got here with sWakelock false
+            // which it shouldn't, unless underlying *.h implementation makes duplicate requests.
+            ALOGW("%s: GNSS HAL Wakelock released, duplicate request", __func__);
+        }
+        sWakelockHeld = false;
+        auto ret = sGnssCbIface->gnssReleaseWakelockCb();
+        if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+        }
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::requestUtcTimeCb() {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssRequestTimeCb();
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+pthread_t Gnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void Gnss::setSystemInfoCb(const LegacyGnssSystemInfo* info) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (info == nullptr) {
+        ALOGE("Invalid GnssSystemInfo from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSystemInfo gnssInfo = {
+        .yearOfHw = info->year_of_hw
+    };
+
+    auto ret = sGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sYearOfHwCached = info->year_of_hw;
+    sem_post(&sSem);
+}
+
+void Gnss::setNameCb(const char* name, int length) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    android::hardware::hidl_string nameString;
+    nameString.setToExternal(name, length);
+    auto ret = sGnssCbIface->gnssNameCb(nameString);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void Gnss::requestLocationCb(bool independentFromGnss) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssRequestLocationCb(independentFromGnss);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) {
+    return false;
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnss follow.
+Return<bool> Gnss::setCallback_1_1(
+    const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    if (callback == nullptr)  {
+        ALOGE("%s: Null callback ignored", __func__);
+        return false;
+    }
+
+    sem_wait(&sSem);
+    if (sGnssCbIface != NULL) {
+        ALOGW("%s called more than once. Unexpected unless test.", __func__);
+        sGnssCbIface->unlinkToDeath(mDeathRecipient);
+    }
+
+    sGnssCbIface = callback;
+    callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+    sem_post(&sSem);
+
+    // If this was received in the past, send it up again to refresh caller.
+    // mGnssIface will override after init() is called below, if needed
+    // (though it's unlikely the gps.h capabilities or system info will change.)
+    if (sCapabilitiesCached != 0) {
+        setCapabilitiesCb(sCapabilitiesCached);
+    }
+    if (sYearOfHwCached != 0) {
+        LegacyGnssSystemInfo info;
+        info.year_of_hw = sYearOfHwCached;
+        setSystemInfoCb(&info);
+    }
+
+    return (mGnssIface->init(&sGnssCb) == 0);
+}
+
+Return<bool> Gnss::start()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->start() == 0);
+}
+
+Return<bool> Gnss::stop()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->stop() == 0);
+}
+
+Return<void> Gnss::cleanup()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->cleanup();
+    }
+    return Void();
+}
+
+Return<bool> Gnss::injectLocation(double latitudeDegrees,
+                                  double longitudeDegrees,
+                                  float accuracyMeters)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
+}
+
+Return<bool> Gnss::injectBestLocation(const GnssLocation&) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    double latitudeDegrees = 0;
+    double longitudeDegrees = 0;
+    float accuracyMeters = 0;
+
+    return (mGnssIface->inject_fused_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
+}
+
+
+Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                              int32_t uncertaintyMs) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_time(timeMs, timeReferenceMs, uncertaintyMs) == 0);
+}
+
+Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->delete_aiding_data(static_cast<GpsAidingData>(aidingDataFlags));
+    }
+    return Void();
+}
+
+Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
+        V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t, uint32_t)  {
+    return false;
+}
+
+Return<bool> Gnss::setPositionMode_1_1(
+    ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode mode,
+    ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence recurrence,
+    uint32_t minIntervalMs,
+    uint32_t preferredAccuracyMeters,
+    uint32_t preferredTimeMs,
+    bool lowPowerMode) {
+                                  
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->set_position_mode(static_cast<GpsPositionMode>(mode),
+                                          static_cast<GpsPositionRecurrence>(recurrence),
+                                          minIntervalMs,
+                                          preferredAccuracyMeters,
+                                          preferredTimeMs,
+                                          lowPowerMode) == 0);
+}
+
+Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssRil == nullptr) {
+        const AGpsRilInterface* agpsRilIface = static_cast<const AGpsRilInterface*>(
+                mGnssIface->get_extension(AGPS_RIL_INTERFACE));
+        if (agpsRilIface == nullptr) {
+            ALOGI("%s: GnssRil interface not implemented by HAL", __func__);
+        } else {
+            mGnssRil = new V1_0::implementation::AGnssRil(agpsRilIface);
+        }
+    }
+    return mGnssRil;
+}
+
+Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration()  {
+    return nullptr;
+}
+
+Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssConfig == nullptr) {
+        const GnssConfigurationInterface_ext* gnssConfigIface =
+                static_cast<const GnssConfigurationInterface_ext*>(
+                        mGnssIface->get_extension(GNSS_CONFIGURATION_INTERFACE));
+
+        if (gnssConfigIface == nullptr) {
+            ALOGW("%s: GnssConfiguration interface not implemented by HAL", __func__);
+        } else {
+            mGnssConfig = new V1_1::implementation::GnssConfiguration(gnssConfigIface);
+        }
+    }
+    return mGnssConfig;
+}
+
+Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssGeofencingIface == nullptr) {
+        const GpsGeofencingInterface_ext* gpsGeofencingIface =
+                static_cast<const GpsGeofencingInterface_ext*>(
+                        mGnssIface->get_extension(GPS_GEOFENCING_INTERFACE));
+
+        if (gpsGeofencingIface == nullptr) {
+            ALOGE("%s: GnssGeofencing interface not implemented by HAL", __func__);
+        } else {
+            mGnssGeofencingIface = new V1_0::implementation::GnssGeofencing(gpsGeofencingIface);
+        }
+    }
+
+    return mGnssGeofencingIface;
+}
+
+Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mAGnssIface == nullptr) {
+        const AGpsInterface* agpsIface = static_cast<const AGpsInterface*>(
+                mGnssIface->get_extension(AGPS_INTERFACE));
+        if (agpsIface == nullptr) {
+            ALOGE("%s: AGnss interface not implemented by HAL", __func__);
+        } else {
+            mAGnssIface = new V1_0::implementation::AGnss(agpsIface);
+        }
+    }
+    return mAGnssIface;
+}
+
+Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNi == nullptr) {
+        const GpsNiInterface* gpsNiIface = static_cast<const GpsNiInterface*>(
+                mGnssIface->get_extension(GPS_NI_INTERFACE));
+        if (gpsNiIface == nullptr) {
+            ALOGI("%s: GnssNi interface not implemented by HAL", __func__);
+        } else {
+            mGnssNi = new V1_0::implementation::GnssNi(gpsNiIface);
+        }
+    }
+    return mGnssNi;
+}
+
+Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
+    return nullptr;
+}
+
+Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
+
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssMeasurement == nullptr) {
+        const GpsMeasurementInterface_ext* gpsMeasurementIface =
+                static_cast<const GpsMeasurementInterface_ext*>(
+                        mGnssIface->get_extension(GPS_MEASUREMENT_INTERFACE));
+
+        if (gpsMeasurementIface == nullptr) {
+            ALOGE("%s: GnssMeasurement interface not implemented by HAL", __func__);
+        } else {
+            mGnssMeasurement = new V1_1::implementation::GnssMeasurement(gpsMeasurementIface);
+        }
+    }
+    return mGnssMeasurement;
+}
+
+Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNavigationMessage == nullptr) {
+        const GpsNavigationMessageInterface* gpsNavigationMessageIface =
+                static_cast<const GpsNavigationMessageInterface*>(
+                        mGnssIface->get_extension(GPS_NAVIGATION_MESSAGE_INTERFACE));
+
+        if (gpsNavigationMessageIface == nullptr) {
+            ALOGI("%s: GnssNavigationMessage interface not implemented by HAL", __func__);
+        } else {
+            mGnssNavigationMessage = new V1_0::implementation::GnssNavigationMessage(gpsNavigationMessageIface);
+        }
+    }
+
+    return mGnssNavigationMessage;
+}
+
+Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssXtraIface == nullptr) {
+        const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
+                mGnssIface->get_extension(GPS_XTRA_INTERFACE));
+
+        if (gpsXtraIface == nullptr) {
+            ALOGI("%s: GnssXtra interface not implemented by HAL", __func__);
+        } else {
+            mGnssXtraIface = new V1_0::implementation::GnssXtra(gpsXtraIface);
+        }
+    }
+
+    return mGnssXtraIface;
+}
+
+Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssDebug == nullptr) {
+        const GpsDebugInterface_ext* gpsDebugIface = static_cast<const GpsDebugInterface_ext*>(
+                mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
+
+        if (gpsDebugIface == nullptr) {
+            ALOGI("%s: GnssDebug interface not implemented by HAL", __func__);
+        } else {
+            mGnssDebug = new V1_0::implementation::GnssDebug(gpsDebugIface);
+        }
+    }
+
+    return mGnssDebug;
+}
+
+Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssBatching == nullptr) {
+        hw_module_t* module;
+        const FlpLocationInterface* flpLocationIface = nullptr;
+        int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+        if (err != 0) {
+            ALOGE("gnss flp hw_get_module failed: %d", err);
+        } else if (module == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null module");
+        } else if (module->methods == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null methods");
+        } else {
+            hw_device_t* device;
+            err = module->methods->open(module, FUSED_LOCATION_HARDWARE_MODULE_ID, &device);
+            if (err != 0) {
+                ALOGE("flpDevice open failed: %d", err);
+            } else {
+                flp_device_t * flpDevice = reinterpret_cast<flp_device_t*>(device);
+                flpLocationIface = flpDevice->get_flp_interface(flpDevice);
+            }
+        }
+
+        if (flpLocationIface == nullptr) {
+            ALOGE("%s: GnssBatching interface is not implemented by HAL", __func__);
+        } else {
+            mGnssBatching = new V1_0::implementation::GnssBatching(flpLocationIface);
+        }
+    }
+    return mGnssBatching;
+}
+
+void Gnss::handleHidlDeath() {
+    ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+    /// M: move here! Do not callback to system_server to avoid gnss hidl service NE
+    /*
+     * This has died, so close it off in case (race condition) callbacks happen
+     * before HAL processes above messages.
+     */
+    sem_wait(&sSem);
+    sGnssCbIface = nullptr;
+    sem_post(&sSem);
+
+    // commands down to the HAL implementation
+    stop(); // stop ongoing GPS tracking
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+    if (mGnssNavigationMessage != nullptr) {
+        mGnssNavigationMessage->close();
+    }
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+    cleanup();
+
+}
+
+IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
+    hw_module_t* module;
+    IGnss* iface = nullptr;
+    int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+    if (err == 0) {
+        hw_device_t* device;
+        err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
+        if (err == 0) {
+            iface = new Gnss(reinterpret_cast<gps_device_t_ext*>(device));
+        } else {
+            ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+        }
+    } else {
+      ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+    }
+    return iface;
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/Gnss.h b/src/connectivity/gps/service/1.1/Gnss.h
new file mode 100644
index 0000000..602482d
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/Gnss.h
@@ -0,0 +1,205 @@
+/*
+ * 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_V1_1_Gnss_H_
+#define android_hardware_gnss_V1_1_Gnss_H_
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssBatching.h>
+#include <GnssConfiguration.h>
+#include <GnssDebug.h>
+#include <GnssGeofencing.h>
+#include <GnssMeasurement.h>
+#include <GnssNavigationMessage.h>
+#include <GnssNi.h>
+#include <GnssXtra.h>
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <hardware/fused_location.h>
+#include <hidl/Status.h>
+#include "hardware/gps_mtk.h"
+
+#include <semaphore.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssSystemInfo = ::GnssSystemInfo;
+using GnssConstellationType = V1_0::GnssConstellationType;
+using GnssLocation = V1_0::GnssLocation;
+
+/*
+ * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
+ * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+class Gnss : public IGnss {
+  public:
+    Gnss(gps_device_t_ext* gnss_device);
+    ~Gnss();
+
+    // Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+    Return<bool> setCallback(
+        const sp<V1_0::IGnssCallback>& callback) override;
+    Return<bool> start() override;
+    Return<bool> stop() override;
+    Return<void> cleanup() override;
+    Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                            int32_t uncertaintyMs) override;
+    Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees,
+                                float accuracyMeters) 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::IAGnssRil>> getExtensionAGnssRil() override;
+    Return<sp<V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() 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::IGnssNavigationMessage>>
+    getExtensionGnssNavigationMessage() override;
+    Return<sp<V1_0::IGnssXtra>> getExtensionXtra() override;
+    Return<sp<V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() override;
+    Return<sp<V1_0::IGnssDebug>> getExtensionGnssDebug() override;
+    Return<sp<V1_0::IGnssBatching>> getExtensionGnssBatching() 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::IGnssConfiguration>>
+    getExtensionGnssConfiguration_1_1() override;
+    Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
+    Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
+
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnss base class.
+     */
+    static void locationCb(GpsLocation_ext* location);
+    static void statusCb(GpsStatus* gnss_status);
+    static void nmeaCb(GpsUtcTime timestamp, const char* nmea, int length);
+    static void setCapabilitiesCb(uint32_t capabilities);
+    static void acquireWakelockCb();
+    static void releaseWakelockCb();
+    static void requestUtcTimeCb();
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void gnssSvStatusCb(GnssSvStatus_ext* status);
+    /*
+     * Deprecated callback added for backward compatibility to devices that do
+     * not support GnssSvStatus.
+     */
+    static void gpsSvStatusCb(GpsSvStatus* status);
+    static void setSystemInfoCb(const LegacyGnssSystemInfo* info);
+
+    /*
+     * Wakelock consolidation, only needed for dual use of a gps.h & fused_location.h HAL
+     *
+     * Ensures that if the last call from either legacy .h was to acquire a wakelock, that a
+     * wakelock is held.  Otherwise releases it.
+     */
+    static void acquireWakelockFused();
+    static void releaseWakelockFused();
+
+    static void setNameCb(const char* name, int length);
+    static void requestLocationCb(bool independentFromGnss);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsCallbacks_ext sGnssCb;
+
+ private:
+    /*
+     * For handling system-server death while GNSS service lives on.
+     */
+    class GnssHidlDeathRecipient : public hidl_death_recipient {
+      public:
+        GnssHidlDeathRecipient(const sp<Gnss> gnss) : mGnss(gnss) {
+        }
+
+        virtual void serviceDied(uint64_t /*cookie*/,
+                const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+            mGnss->handleHidlDeath();
+        }
+      private:
+        sp<Gnss> mGnss;
+    };
+
+    // for wakelock consolidation, see above
+    static void acquireWakelockGnss();
+    static void releaseWakelockGnss();
+    static void updateWakelock();
+    static bool sWakelockHeldGnss;
+    static bool sWakelockHeldFused;
+
+    /*
+     * Cleanup for death notification
+     */
+    void handleHidlDeath();
+
+    sp<V1_0::implementation::GnssXtra> mGnssXtraIface = nullptr;
+    sp<V1_0::implementation::AGnssRil> mGnssRil = nullptr;
+    sp<V1_0::implementation::GnssGeofencing> mGnssGeofencingIface = nullptr;
+    sp<V1_0::implementation::AGnss> mAGnssIface = nullptr;
+    sp<V1_0::implementation::GnssNi> mGnssNi = nullptr;
+    sp<V1_1::implementation::GnssMeasurement> mGnssMeasurement = nullptr;
+    sp<V1_0::implementation::GnssNavigationMessage> mGnssNavigationMessage = nullptr;
+    sp<V1_0::implementation::GnssDebug> mGnssDebug = nullptr;
+    sp<V1_1::implementation::GnssConfiguration> mGnssConfig = nullptr;
+    sp<V1_0::implementation::GnssBatching> mGnssBatching = nullptr;
+
+    ///M: add semphore protection
+    static sem_t sSem;
+
+    sp<GnssHidlDeathRecipient> mDeathRecipient;
+    const GpsInterface_ext* mGnssIface = nullptr;
+    static sp<V1_1::IGnssCallback> sGnssCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+
+    // Values saved for resend
+    static uint32_t sCapabilitiesCached;
+    static uint16_t sYearOfHwCached;
+};
+
+extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_1_Gnss_H_
diff --git a/src/connectivity/gps/service/1.1/GnssBatching.cpp b/src/connectivity/gps/service/1.1/GnssBatching.cpp
new file mode 100644
index 0000000..292b811
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssBatching.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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_GnssBatchingInterface"
+
+#include "GnssBatching.h"
+#include <Gnss.h> // for wakelock consolidation
+#include <GnssUtils.h>
+
+#include <log/log.h>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssBatchingCallback> GnssBatching::sGnssBatchingCbIface = nullptr;
+bool GnssBatching::sFlpSupportsBatching = false;
+
+FlpCallbacks GnssBatching::sFlpCb = {
+    .size = sizeof(FlpCallbacks),
+    .location_cb = locationCb,
+    .acquire_wakelock_cb = acquireWakelockCb,
+    .release_wakelock_cb = releaseWakelockCb,
+    .set_thread_event_cb = setThreadEventCb,
+    .flp_capabilities_cb = flpCapabilitiesCb,
+    .flp_status_cb = flpStatusCb,
+};
+
+GnssBatching::GnssBatching(const FlpLocationInterface* flpLocationIface) :
+    mFlpLocationIface(flpLocationIface) {
+}
+
+/*
+ * This enum is used locally by various methods below. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum BatchingValues : uint16_t {
+    // Numbers 0-3 were used in earlier implementations - using 4 to be distinct to the HAL
+    FLP_GNSS_BATCHING_CLIENT_ID = 4,
+    // Tech. mask of GNSS, and sensor aiding, for legacy HAL to fit with GnssBatching API
+    FLP_TECH_MASK_GNSS_AND_SENSORS = FLP_TECH_MASK_GNSS | FLP_TECH_MASK_SENSORS,
+    // Putting a cap to avoid possible memory issues.  Unlikely values this high are supported.
+    MAX_LOCATIONS_PER_BATCH = 1000
+};
+
+void GnssBatching::locationCb(int32_t locationsCount, FlpLocation** locations) {
+    if (sGnssBatchingCbIface == nullptr) {
+        ALOGE("%s: GNSS Batching Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (locations == nullptr) {
+        ALOGE("%s: Invalid locations from GNSS HAL", __func__);
+        return;
+    }
+
+    if (locationsCount < 0) {
+        ALOGE("%s: Negative location count: %d set to 0", __func__, locationsCount);
+        locationsCount = 0;
+    } else if (locationsCount > MAX_LOCATIONS_PER_BATCH) {
+        ALOGW("%s: Unexpected high location count: %d set to %d", __func__, locationsCount,
+                MAX_LOCATIONS_PER_BATCH);
+        locationsCount = MAX_LOCATIONS_PER_BATCH;
+    }
+
+    /**
+     * Note:
+     * Some existing implementations may drop duplicate locations.  These could be expanded here
+     * but as there's ambiguity between no-GPS-fix vs. dropped duplicates in that implementation,
+     * and that's not specified by the fused_location.h, that isn't safe to do here.
+     * Fortunately, this shouldn't be a major issue in cases where GNSS batching is typically
+     * used (e.g. when user is likely in vehicle/bicycle.)
+     */
+    std::vector<android::hardware::gnss::V1_0::GnssLocation> gnssLocations;
+    for (int iLocation = 0; iLocation < locationsCount; iLocation++) {
+        if (locations[iLocation] == nullptr) {
+            ALOGE("%s: Null location at slot: %d of %d, skipping", __func__, iLocation,
+                    locationsCount);
+            continue;
+        }
+        if ((locations[iLocation]->sources_used & ~FLP_TECH_MASK_GNSS_AND_SENSORS) != 0)
+        {
+            ALOGE("%s: Unrequested location type %d at slot: %d of %d, skipping", __func__,
+                    locations[iLocation]->sources_used, iLocation, locationsCount);
+            continue;
+        }
+        gnssLocations.push_back(convertToGnssLocation(locations[iLocation]));
+    }
+
+    auto ret = sGnssBatchingCbIface->gnssLocationBatchCb(gnssLocations);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssBatching::acquireWakelockCb() {
+    V1_1::implementation::Gnss::acquireWakelockFused();
+}
+
+void GnssBatching::releaseWakelockCb() {
+    V1_1::implementation::Gnss::releaseWakelockFused();
+}
+
+// this can just return success, because threads are now set up on demand in the jni layer
+int32_t GnssBatching::setThreadEventCb(ThreadEvent /*event*/) {
+    return FLP_RESULT_SUCCESS;
+}
+
+void GnssBatching::flpCapabilitiesCb(int32_t capabilities) {
+    ALOGD("%s capabilities %d", __func__, capabilities);
+
+    if (capabilities & CAPABILITY_GNSS) {
+        // once callback is received and capabilities high enough, we know version is
+        // high enough for flush()
+        sFlpSupportsBatching = true;
+    }
+}
+
+void GnssBatching::flpStatusCb(int32_t status) {
+    ALOGD("%s (default implementation) not forwarding status: %d", __func__, status);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
+Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching is unavailable", __func__);
+        return false;
+    }
+
+    sGnssBatchingCbIface = callback;
+
+    return (mFlpLocationIface->init(&sFlpCb) == 0);
+}
+
+Return<uint16_t> GnssBatching::getBatchSize() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return 0;
+    }
+
+    return mFlpLocationIface->get_batch_size();
+}
+
+Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return false;
+    }
+
+    if (!sFlpSupportsBatching) {
+        ALOGE("%s: Flp batching interface not supported, no capabilities callback received",
+                __func__);
+        return false;
+    }
+
+    FlpBatchOptions optionsHw;
+    // Legacy code used 9999 mW for High accuracy, and 21 mW for balanced.
+    // New GNSS API just expects reasonable GNSS chipset behavior - do something efficient
+    // given the interval.  This 100 mW limit should be quite sufficient (esp. given legacy code
+    // implementations may not even use this value.)
+    optionsHw.max_power_allocation_mW = 100;
+    optionsHw.sources_to_use = FLP_TECH_MASK_GNSS_AND_SENSORS;
+    optionsHw.flags = 0;
+    if (options.flags & Flag::WAKEUP_ON_FIFO_FULL) {
+        optionsHw.flags |= FLP_BATCH_WAKEUP_ON_FIFO_FULL;
+    }
+    optionsHw.period_ns = options.periodNanos;
+    optionsHw.smallest_displacement_meters = 0; // Zero offset - just use time interval
+
+    return (mFlpLocationIface->start_batching(FLP_GNSS_BATCHING_CLIENT_ID, &optionsHw)
+            == FLP_RESULT_SUCCESS);
+}
+
+Return<void> GnssBatching::flush() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return Void();
+    }
+
+    mFlpLocationIface->flush_batched_locations();
+
+    return Void();
+}
+
+Return<bool> GnssBatching::stop() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mFlpLocationIface->stop_batching(FLP_GNSS_BATCHING_CLIENT_ID) == FLP_RESULT_SUCCESS);
+}
+
+Return<void> GnssBatching::cleanup() {
+    if (mFlpLocationIface == nullptr) {
+        ALOGE("%s: Flp batching interface is unavailable", __func__);
+        return Void();
+    }
+
+    mFlpLocationIface->cleanup();
+
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssBatching.h b/src/connectivity/gps/service/1.1/GnssBatching.h
new file mode 100644
index 0000000..001c27d
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssBatching.h
@@ -0,0 +1,67 @@
+#ifndef ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
+#define ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
+
+#include <android/hardware/gnss/1.0/IGnssBatching.h>
+#include <hardware/fused_location.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+struct GnssBatching : public IGnssBatching {
+    GnssBatching(const FlpLocationInterface* flpLocationIface);
+
+    // 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;
+
+    /*
+     * Callback methods to be passed into the conventional FLP HAL by the default
+     * implementation. These methods are not part of the IGnssBatching base class.
+     */
+    static void locationCb(int32_t locationsCount, FlpLocation** locations);
+    static void acquireWakelockCb();
+    static void releaseWakelockCb();
+    static int32_t setThreadEventCb(ThreadEvent event);
+    static void flpCapabilitiesCb(int32_t capabilities);
+    static void flpStatusCb(int32_t status);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static FlpCallbacks sFlpCb;
+
+ private:
+    const FlpLocationInterface* mFlpLocationIface = nullptr;
+    static sp<IGnssBatchingCallback> sGnssBatchingCbIface;
+    static bool sFlpSupportsBatching;
+};
+
+extern "C" IGnssBatching* HIDL_FETCH_IGnssBatching(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GNSS_V1_0_GNSSBATCHING_H
diff --git a/src/connectivity/gps/service/1.1/GnssConfiguration.cpp b/src/connectivity/gps/service/1.1/GnssConfiguration.cpp
new file mode 100644
index 0000000..be57d24
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssConfiguration.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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_GnssConfigurationInterface"
+
+#include <log/log.h>
+
+#include "GnssConfiguration.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+GnssConfiguration::GnssConfiguration(const GnssConfigurationInterface_ext* gnssConfigInfc)
+    : mGnssConfigIface(gnssConfigInfc) {}
+
+// Methods from ::android::hardware::gps::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_ES=" + std::to_string(enabled ? 1 : 0) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_VER=" + std::to_string(version) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+
+    return true;
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode)  {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "SUPL_MODE=" + std::to_string(mode) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "LPP_PROFILE=" + std::to_string(lppProfile) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "A_GLONASS_POS_PROTOCOL_SELECT=" +
+            std::to_string(protocol) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "GPS_LOCK=" + std::to_string(lock) + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+    if (mGnssConfigIface == nullptr) {
+        ALOGE("%s: GNSS Configuration interface is not available.", __func__);
+        return false;
+    }
+
+    std::string config = "USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=" + std::to_string(enabled ? 1 : 0)
+            + "\n";
+    mGnssConfigIface->configuration_update(config.c_str(), config.size());
+    return true;
+}
+
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(const hidl_vec<BlacklistedSource>& sourceList) {
+    size_t listSize = sourceList.size();
+    long long blackSvid[7];  /// V1_0::GnssConstellationType size is 7
+    memset(blackSvid, 0x00, sizeof(long long)*7);
+
+    for (size_t i = 0; i < listSize; i++) {
+        int idx = (int) sourceList[i].constellation;
+        if (idx > 6) {
+            ALOGE("%s: GnssConstellation type is out of boundary.", __func__);
+            continue;
+        } else if (sourceList[i].svid == 0) { /// all sv are blocked
+            blackSvid[idx] = (long long)(((long long)0xFFFFFFFFL << 32) | 0xFFFFFFFFL);
+        } else {
+            blackSvid[idx] |= (long long)((long long)0x01L << (sourceList[i].svid -1));
+        }
+    }
+
+    mGnssConfigIface->setBlacklist(blackSvid, 7);
+    return true;
+}
+
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssConfiguration.h b/src/connectivity/gps/service/1.1/GnssConfiguration.h
new file mode 100644
index 0000000..8b6c781
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssConfiguration.h
@@ -0,0 +1,73 @@
+/*
+ * 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_V1_1_GnssConfiguration_H_
+#define android_hardware_gnss_V1_1_GnssConfiguration_H_
+
+#include <android/hardware/gnss/1.1/IGnssConfiguration.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_1::IGnssConfiguration;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using BlacklistedSource = V1_1::IGnssConfiguration::BlacklistedSource;
+
+/*
+ * Interface for passing GNSS configuration info from platform to HAL.
+ */
+struct GnssConfiguration : public IGnssConfiguration {
+    GnssConfiguration(const GnssConfigurationInterface_ext* gnssConfigIface);
+
+    /*
+     * 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<BlacklistedSource>& blacklist) override;
+
+ private:
+    const GnssConfigurationInterface_ext* mGnssConfigIface = nullptr;
+
+};
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_1_GnssConfiguration_H_
diff --git a/src/connectivity/gps/service/1.1/GnssDebug.cpp b/src/connectivity/gps/service/1.1/GnssDebug.cpp
new file mode 100644
index 0000000..d2d64b5
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssDebug.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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_GnssDebugInterface"
+
+#include <log/log.h>
+
+#include "GnssDebug.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+GnssDebug::GnssDebug(const GpsDebugInterface_ext* gpsDebugIface) : mGnssDebugIface(gpsDebugIface) {}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+Return<void> GnssDebug::getDebugData(getDebugData_cb _hidl_cb)  {
+    /*
+     * This is a new interface and hence there is no way to retrieve the
+     * debug data from the HAL.
+     */
+    if (mGnssDebugIface) {
+        ::DebugData debugData;
+        IGnssDebug::DebugData data;
+        bool ret = mGnssDebugIface->get_internal_state(&debugData);
+        if (ret) {
+            data.position = (IGnssDebug::PositionDebug){
+                .valid = debugData.position.valid,
+                .latitudeDegrees = debugData.position.latitudeDegrees,
+                .longitudeDegrees = debugData.position.longitudeDegrees,
+                .altitudeMeters = debugData.position.altitudeMeters,
+                .speedMetersPerSec = debugData.position.speedMetersPerSec,
+                .bearingDegrees = debugData.position.bearingDegrees,
+                .horizontalAccuracyMeters = debugData.position.horizontalAccuracyMeters,
+                .verticalAccuracyMeters = debugData.position.verticalAccuracyMeters,
+                .speedAccuracyMetersPerSecond = debugData.position.speedAccuracyMetersPerSecond,
+                .bearingAccuracyDegrees = debugData.position.bearingAccuracyDegrees,
+                .ageSeconds = debugData.position.ageSeconds
+            };
+            data.time = (IGnssDebug::TimeDebug){
+                .timeEstimate = debugData.time.timeEstimate,
+                .timeUncertaintyNs = debugData.time.timeUncertaintyNs,
+                .frequencyUncertaintyNsPerSec = debugData.time.frequencyUncertaintyNsPerSec,
+            };
+
+            int count = 0;
+            for (; count < GNSS_MAX_SVS; count++) {
+                if (debugData.satelliteDataArray[count].svid == 0) {
+                    break;
+                }
+            }
+            data.satelliteDataArray.resize(count);
+            for (int i = 0; i < count; i++) {
+                auto entry = debugData.satelliteDataArray[i];
+                data.satelliteDataArray[i] = (IGnssDebug::SatelliteData) {
+                    .svid = entry.svid,
+                    .constellation = (V1_0::GnssConstellationType) entry.constellation,
+                    .ephemerisType = (IGnssDebug::SatelliteEphemerisType) entry.ephemerisType,
+                    .ephemerisSource = (IGnssDebug::SatelliteEphemerisSource)entry.ephemerisSource,
+                    .ephemerisHealth = (IGnssDebug::SatelliteEphemerisHealth)entry.ephemerisHealth,
+                    .ephemerisAgeSeconds = entry.ephemerisAgeSeconds,
+                    .serverPredictionIsAvailable = entry.serverPredictionIsAvailable,
+                    .serverPredictionAgeSeconds = entry.serverPredictionAgeSeconds
+                };
+            }
+            _hidl_cb(data);
+        }
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssDebug.h b/src/connectivity/gps/service/1.1/GnssDebug.h
new file mode 100644
index 0000000..7a2c6e9
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssDebug.h
@@ -0,0 +1,62 @@
+/*
+ * 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_V1_0_GnssDebug_H_
+#define android_hardware_gnss_V1_0_GnssDebug_H_
+
+#include <android/hardware/gnss/1.0/IGnssDebug.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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 GnssDebug : public IGnssDebug {
+    GnssDebug(const GpsDebugInterface_ext* gpsDebugIface);
+
+    /*
+     * 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:
+    /*
+     * Constant added for backward compatibility to conventional GPS Hals which
+     * returned a debug string.
+     */
+    const GpsDebugInterface_ext* mGnssDebugIface = nullptr;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssDebug_H_
diff --git a/src/connectivity/gps/service/1.1/GnssGeofencing.cpp b/src/connectivity/gps/service/1.1/GnssGeofencing.cpp
new file mode 100644
index 0000000..3d51140
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssGeofencing.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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 "GnssGeofencing.h"
+#include <GnssUtils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssGeofencing::sThreadFuncArgsList;
+sp<IGnssGeofenceCallback> GnssGeofencing::mGnssGeofencingCbIface = nullptr;
+bool GnssGeofencing::sInterfaceExists = false;
+
+GpsGeofenceCallbacks_ext GnssGeofencing::sGnssGfCb = {
+    .geofence_transition_callback = gnssGfTransitionCb,
+    .geofence_status_callback = gnssGfStatusCb,
+    .geofence_add_callback = gnssGfAddCb,
+    .geofence_remove_callback = gnssGfRemoveCb,
+    .geofence_pause_callback = gnssGfPauseCb,
+    .geofence_resume_callback = gnssGfResumeCb,
+    .create_thread_cb = createThreadCb
+};
+
+GnssGeofencing::GnssGeofencing(const GpsGeofencingInterface_ext* gpsGeofencingIface)
+    : mGnssGeofencingIface(gpsGeofencingIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+GnssGeofencing::~GnssGeofencing() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+void GnssGeofencing::gnssGfTransitionCb(int32_t geofenceId,
+                                        GpsLocation_ext* location,
+                                        int32_t transition,
+                                        GpsUtcTime timestamp) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (location == nullptr) {
+        ALOGE("%s : Invalid location from GNSS HAL", __func__);
+        return;
+    }
+
+    GnssLocation gnssLocation = convertToGnssLocation(location);
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
+            geofenceId,
+            gnssLocation,
+            static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
+            timestamp);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfStatusCb(int32_t status, GpsLocation_ext* location) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    GnssLocation gnssLocation;
+
+    if (location != nullptr) {
+        gnssLocation = convertToGnssLocation(location);
+    } else {
+        gnssLocation = {};
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceStatusCb(
+            static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfAddCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceAddCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfRemoveCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfPauseCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofencePauseCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+void GnssGeofencing::gnssGfResumeCb(int32_t geofenceId, int32_t status) {
+    if (mGnssGeofencingCbIface == nullptr) {
+        ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = mGnssGeofencingCbIface->gnssGeofenceResumeCb(
+            geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+pthread_t GnssGeofencing::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
+Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback)  {
+    mGnssGeofencingCbIface = callback;
+
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->init(&sGnssGfCb);
+    }
+
+    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 (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+        return Void();
+    } else {
+        mGnssGeofencingIface->add_geofence_area(
+                geofenceId,
+                latitudeDegrees,
+                longitudeDegrees,
+                radiusMeters,
+                static_cast<int32_t>(lastTransition),
+                monitorTransitions,
+                notificationResponsivenessMs,
+                unknownTimerMs);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->pause_geofence(geofenceId);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->resume_geofence(geofenceId, monitorTransitions);
+    }
+    return Void();
+}
+
+Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId)  {
+    if (mGnssGeofencingIface == nullptr) {
+        ALOGE("%s: GnssGeofencing interface is not available", __func__);
+    } else {
+        mGnssGeofencingIface->remove_geofence_area(geofenceId);
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssGeofencing.h b/src/connectivity/gps/service/1.1/GnssGeofencing.h
new file mode 100644
index 0000000..1615d8f
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssGeofencing.h
@@ -0,0 +1,98 @@
+/*
+ * 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_V1_0_GnssGeofencing_H_
+#define android_hardware_gnss_V1_0_GnssGeofencing_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssGeofencing.h>
+#include <hidl/Status.h>
+#include <hardware/gps_mtk.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+/*
+ * Interface for GNSS Geofencing support. It also contains wrapper methods to allow
+ * methods from IGnssGeofenceCallback interface to be passed into the
+ * conventional implementation of the GNSS HAL.
+ */
+struct GnssGeofencing : public IGnssGeofencing {
+    GnssGeofencing(const GpsGeofencingInterface_ext* gpsGeofencingIface);
+    ~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;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssGeofencing base class.
+     */
+    static void gnssGfTransitionCb(int32_t geofence_id, GpsLocation_ext* location,
+                                   int32_t transition, GpsUtcTime timestamp);
+    static void gnssGfStatusCb(int32_t status, GpsLocation_ext* last_location);
+    static void gnssGfAddCb(int32_t geofence_id, int32_t status);
+    static void gnssGfRemoveCb(int32_t geofence_id, int32_t status);
+    static void gnssGfPauseCb(int32_t geofence_id, int32_t status);
+    static void gnssGfResumeCb(int32_t geofence_id, int32_t status);
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsGeofenceCallbacks_ext sGnssGfCb;
+
+ private:
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static sp<IGnssGeofenceCallback> mGnssGeofencingCbIface;
+    const GpsGeofencingInterface_ext* mGnssGeofencingIface = nullptr;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssGeofencing_H_
diff --git a/src/connectivity/gps/service/1.1/GnssMeasurement.cpp b/src/connectivity/gps/service/1.1/GnssMeasurement.cpp
new file mode 100644
index 0000000..b474ed9
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssMeasurement.cpp
@@ -0,0 +1,283 @@
+/*
+ * 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_GnssMeasurementInterface"
+
+#include "GnssMeasurement.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+sp<V1_1::IGnssMeasurementCallback>
+        GnssMeasurement::sGnssMeasureCbIface = nullptr;
+GpsMeasurementCallbacks_ext GnssMeasurement::sGnssMeasurementCbs = {
+    .size = sizeof(GpsMeasurementCallbacks_ext),
+    .measurement_callback = gpsMeasurementCb,
+    .gnss_measurement_callback = gnssMeasurementCb
+};
+
+GnssMeasurement::GnssMeasurement(const GpsMeasurementInterface_ext* gpsMeasurementIface)
+    : mGnssMeasureIface(gpsMeasurementIface) {}
+
+void GnssMeasurement::gnssMeasurementCb(GnssData_ext* halGnssData) {
+    if (sGnssMeasureCbIface == nullptr) {
+        ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (halGnssData == nullptr) {
+        ALOGE("%s: Invalid GnssData from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssMeasurementCallback::GnssData gnssData;
+    size_t measurementCount = std::min(halGnssData->measurement_count,
+                                         static_cast<size_t>(V1_0::GnssMax::SVS_COUNT));
+    gnssData.measurements.resize(measurementCount);
+
+    for (size_t i = 0; i < measurementCount; i++) {
+        auto entry = halGnssData->measurements[i];
+        auto state = static_cast<GnssMeasurementState>(entry.legacyMeasurement.state);
+        if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED) {
+          state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_KNOWN;
+        }
+        if (state & IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED) {
+          state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_KNOWN;
+        }
+
+        gnssData.measurements[i].v1_0 = (V1_0::IGnssMeasurementCallback::GnssMeasurement){
+            .flags = entry.legacyMeasurement.flags,
+            .svid = entry.legacyMeasurement.svid,
+            .constellation = static_cast<V1_0::GnssConstellationType>(
+                    entry.legacyMeasurement.constellation),
+            .timeOffsetNs = entry.legacyMeasurement.time_offset_ns,
+            .state = state,
+            .receivedSvTimeInNs = entry.legacyMeasurement.received_sv_time_in_ns,
+            .receivedSvTimeUncertaintyInNs =
+                    entry.legacyMeasurement.received_sv_time_uncertainty_in_ns,
+            .cN0DbHz = entry.legacyMeasurement.c_n0_dbhz,
+            .pseudorangeRateMps = entry.legacyMeasurement.pseudorange_rate_mps,
+            .pseudorangeRateUncertaintyMps =
+                    entry.legacyMeasurement.pseudorange_rate_uncertainty_mps,
+            .accumulatedDeltaRangeState = entry.legacyMeasurement.accumulated_delta_range_state,
+            .accumulatedDeltaRangeM = entry.legacyMeasurement.accumulated_delta_range_m,
+            .accumulatedDeltaRangeUncertaintyM =
+                    entry.legacyMeasurement.accumulated_delta_range_uncertainty_m,
+            .carrierFrequencyHz = entry.legacyMeasurement.carrier_frequency_hz,
+            .carrierCycles = entry.legacyMeasurement.carrier_cycles,
+            .carrierPhase = entry.legacyMeasurement.carrier_phase,
+            .carrierPhaseUncertainty = entry.legacyMeasurement.carrier_phase_uncertainty,
+            .multipathIndicator = static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+                    entry.legacyMeasurement.multipath_indicator),
+            .snrDb = entry.legacyMeasurement.snr_db,
+            .agcLevelDb = entry.agc_level_db
+        };
+        gnssData.measurements[i].accumulatedDeltaRangeState =
+                    entry.legacyMeasurement.accumulated_delta_range_state;
+    }
+
+    auto clockVal = halGnssData->clock;
+    gnssData.clock = {
+        .gnssClockFlags = clockVal.flags,
+        .leapSecond = clockVal.leap_second,
+        .timeNs = clockVal.time_ns,
+        .timeUncertaintyNs = clockVal.time_uncertainty_ns,
+        .fullBiasNs = clockVal.full_bias_ns,
+        .biasNs = clockVal.bias_ns,
+        .biasUncertaintyNs = clockVal.bias_uncertainty_ns,
+        .driftNsps = clockVal.drift_nsps,
+        .driftUncertaintyNsps = clockVal.drift_uncertainty_nsps,
+        .hwClockDiscontinuityCount = clockVal.hw_clock_discontinuity_count
+    };
+
+    auto ret = sGnssMeasureCbIface->gnssMeasurementCb(gnssData);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+/*
+ * The code in the following method has been moved here from GnssLocationProvider.
+ * It converts GpsData to GnssData. This code is no longer required in
+ * GnssLocationProvider since GpsData is deprecated and no longer part of the
+ * GNSS interface.
+ */
+void GnssMeasurement::gpsMeasurementCb(GpsData* gpsData) {
+    if (sGnssMeasureCbIface == nullptr) {
+        ALOGE("%s: GNSSMeasurement Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (gpsData == nullptr) {
+        ALOGE("%s: Invalid GpsData from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssMeasurementCallback::GnssData gnssData;
+    size_t measurementCount = std::min(gpsData->measurement_count,
+                                         static_cast<size_t>(V1_0::GnssMax::SVS_COUNT));
+    gnssData.measurements.resize(measurementCount);
+
+    for (size_t i = 0; i < measurementCount; i++) {
+        auto entry = gpsData->measurements[i];
+        gnssData.measurements[i].v1_0.flags = entry.flags;
+        gnssData.measurements[i].v1_0.svid = static_cast<int32_t>(entry.prn);
+        if (entry.prn >= 1 && entry.prn <= 32) {
+            gnssData.measurements[i].v1_0.constellation = V1_0::GnssConstellationType::GPS;
+        } else {
+            gnssData.measurements[i].v1_0.constellation =
+                  V1_0::GnssConstellationType::UNKNOWN;
+        }
+
+        gnssData.measurements[i].v1_0.timeOffsetNs = entry.time_offset_ns;
+        gnssData.measurements[i].v1_0.state = entry.state;
+        gnssData.measurements[i].v1_0.receivedSvTimeInNs = entry.received_gps_tow_ns;
+        gnssData.measurements[i].v1_0.receivedSvTimeUncertaintyInNs =
+            entry.received_gps_tow_uncertainty_ns;
+        gnssData.measurements[i].v1_0.cN0DbHz = entry.c_n0_dbhz;
+        gnssData.measurements[i].v1_0.pseudorangeRateMps = entry.pseudorange_rate_mps;
+        gnssData.measurements[i].v1_0.pseudorangeRateUncertaintyMps =
+                entry.pseudorange_rate_uncertainty_mps;
+        gnssData.measurements[i].v1_0.accumulatedDeltaRangeState =
+                entry.accumulated_delta_range_state;
+        gnssData.measurements[i].v1_0.accumulatedDeltaRangeM =
+                entry.accumulated_delta_range_m;
+        gnssData.measurements[i].v1_0.accumulatedDeltaRangeUncertaintyM =
+                entry.accumulated_delta_range_uncertainty_m;
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
+            gnssData.measurements[i].v1_0.carrierFrequencyHz = entry.carrier_frequency_hz;
+        } else {
+            gnssData.measurements[i].v1_0.carrierFrequencyHz = 0;
+        }
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE) {
+            gnssData.measurements[i].v1_0.carrierPhase = entry.carrier_phase;
+        } else {
+            gnssData.measurements[i].v1_0.carrierPhase = 0;
+        }
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
+            gnssData.measurements[i].v1_0.carrierPhaseUncertainty = entry.carrier_phase_uncertainty;
+        } else {
+            gnssData.measurements[i].v1_0.carrierPhaseUncertainty = 0;
+        }
+
+        gnssData.measurements[i].v1_0.multipathIndicator =
+                static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(
+                        entry.multipath_indicator);
+
+        if (entry.flags & GNSS_MEASUREMENT_HAS_SNR) {
+            gnssData.measurements[i].v1_0.snrDb = entry.snr_db;
+        } else {
+            gnssData.measurements[i].v1_0.snrDb = 0;
+        }
+
+        gnssData.measurements[i].v1_0.agcLevelDb = 0;
+        gnssData.measurements[i].accumulatedDeltaRangeState = entry.accumulated_delta_range_state;
+    }
+
+    auto clockVal = gpsData->clock;
+    static uint32_t discontinuity_count_to_handle_old_clock_type = 0;
+
+    gnssData.clock.leapSecond = clockVal.leap_second;
+    /*
+     * GnssClock only supports the more effective HW_CLOCK type, so type
+     * handling and documentation complexity has been removed.  To convert the
+     * old GPS_CLOCK types (active only in a limited number of older devices),
+     * the GPS time information is handled as an always discontinuous HW clock,
+     * with the GPS time information put into the full_bias_ns instead - so that
+     * time_ns - full_bias_ns = local estimate of GPS time. Additionally, the
+     * sign of full_bias_ns and bias_ns has flipped between GpsClock &
+     * GnssClock, so that is also handled below.
+     */
+    switch (clockVal.type) {
+        case GPS_CLOCK_TYPE_UNKNOWN:
+            // Clock type unsupported.
+            ALOGE("Unknown clock type provided.");
+            break;
+        case GPS_CLOCK_TYPE_LOCAL_HW_TIME:
+            // Already local hardware time. No need to do anything.
+            break;
+        case GPS_CLOCK_TYPE_GPS_TIME:
+            // GPS time, need to convert.
+            clockVal.flags |= GPS_CLOCK_HAS_FULL_BIAS;
+            clockVal.full_bias_ns = clockVal.time_ns;
+            clockVal.time_ns = 0;
+            gnssData.clock.hwClockDiscontinuityCount =
+                    discontinuity_count_to_handle_old_clock_type++;
+            break;
+    }
+
+    gnssData.clock.timeNs = clockVal.time_ns;
+    gnssData.clock.timeUncertaintyNs = clockVal.time_uncertainty_ns;
+    /*
+     * Definition of sign for full_bias_ns & bias_ns has been changed since N,
+     * so flip signs here.
+     */
+    gnssData.clock.fullBiasNs = -(clockVal.full_bias_ns);
+    gnssData.clock.biasNs = -(clockVal.bias_ns);
+    gnssData.clock.biasUncertaintyNs = clockVal.bias_uncertainty_ns;
+    gnssData.clock.driftNsps = clockVal.drift_nsps;
+    gnssData.clock.driftUncertaintyNsps = clockVal.drift_uncertainty_nsps;
+    gnssData.clock.gnssClockFlags = clockVal.flags;
+
+    auto ret = sGnssMeasureCbIface->gnssMeasurementCb(gnssData);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus>
+GnssMeasurement::setCallback(const sp<V1_0::IGnssMeasurementCallback>&) {
+    return V1_0::IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
+}
+
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+Return<V1_0::IGnssMeasurement::GnssMeasurementStatus>
+GnssMeasurement::setCallback_1_1(
+        const sp<V1_1::IGnssMeasurementCallback>& callback,
+        bool enableFullTracking) {
+
+    if (mGnssMeasureIface == nullptr) {
+        ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+        return GnssMeasurementStatus::ERROR_GENERIC;
+    }
+    sGnssMeasureCbIface = callback;
+
+    return static_cast<GnssMeasurement::GnssMeasurementStatus>(
+            mGnssMeasureIface->init(&sGnssMeasurementCbs, enableFullTracking));
+}
+
+Return<void> GnssMeasurement::close()  {
+    if (mGnssMeasureIface == nullptr) {
+        ALOGE("%s: GnssMeasure interface is unavailable", __func__);
+    } else {
+        mGnssMeasureIface->close();
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssMeasurement.h b/src/connectivity/gps/service/1.1/GnssMeasurement.h
new file mode 100644
index 0000000..4fa5426
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssMeasurement.h
@@ -0,0 +1,89 @@
+/*
+ * 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_V1_1_GnssMeasurement_H_
+#define android_hardware_gnss_V1_1_GnssMeasurement_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_1::IGnssMeasurement;
+using ::android::hardware::gnss::V1_1::IGnssMeasurementCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+
+/*
+ * Extended interface for GNSS Measurements support. Also contains wrapper methods to allow methods
+ * from IGnssMeasurementCallback interface to be passed into the conventional implementation of the
+ * GNSS HAL.
+ */
+struct GnssMeasurement : public IGnssMeasurement {
+    GnssMeasurement(const GpsMeasurementInterface_ext* gpsMeasurementIface);
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
+     * These declarations were generated from IGnssMeasurement.hal.
+     */
+    Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback(
+        const sp<::android::hardware::gnss::V1_0::IGnssMeasurementCallback>& callback) override;
+    Return<void> close() override;
+
+    // Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow.
+    Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus>
+    setCallback_1_1(const sp<::android::hardware::gnss::V1_1::IGnssMeasurementCallback>& callback,
+            bool enableFullTracking) override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssMeasurement base class.
+     */
+    static void gnssMeasurementCb(GnssData_ext* data);
+     /*
+      * Deprecated callback added for backward compatibity for devices that do
+      * not support GnssData measurements.
+      */
+    static void gpsMeasurementCb(GpsData* data);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsMeasurementCallbacks_ext sGnssMeasurementCbs;
+
+ private:
+    const GpsMeasurementInterface_ext* mGnssMeasureIface = nullptr;
+    static sp<IGnssMeasurementCallback> sGnssMeasureCbIface;
+};
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssMeasurement_H_
diff --git a/src/connectivity/gps/service/1.1/GnssNavigationMessage.cpp b/src/connectivity/gps/service/1.1/GnssNavigationMessage.cpp
new file mode 100644
index 0000000..6f509d0
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssNavigationMessage.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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_GnssNavigationMessageInterface"
+
+#include <log/log.h>
+
+#include "GnssNavigationMessage.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+sp<IGnssNavigationMessageCallback> GnssNavigationMessage::sGnssNavigationMsgCbIface = nullptr;
+
+GpsNavigationMessageCallbacks GnssNavigationMessage::sGnssNavigationMessageCb = {
+    .size = sizeof(GpsNavigationMessageCallbacks),
+    .navigation_message_callback = nullptr,
+    .gnss_navigation_message_callback = gnssNavigationMessageCb
+};
+
+GnssNavigationMessage::GnssNavigationMessage(
+        const GpsNavigationMessageInterface* gpsNavigationMessageIface) :
+    mGnssNavigationMessageIface(gpsNavigationMessageIface) {}
+
+void GnssNavigationMessage::gnssNavigationMessageCb(LegacyGnssNavigationMessage* message) {
+    if (sGnssNavigationMsgCbIface == nullptr) {
+        ALOGE("%s: GnssNavigation Message Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (message == nullptr) {
+        ALOGE("%s, received invalid GnssNavigationMessage from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssNavigationMessageCallback::GnssNavigationMessage navigationMsg;
+
+    navigationMsg.svid = message->svid;
+    navigationMsg.type =
+            static_cast<IGnssNavigationMessageCallback::GnssNavigationMessageType>(message->type);
+    navigationMsg.status = message->status;
+    navigationMsg.messageId = message->message_id;
+    navigationMsg.submessageId = message->submessage_id;
+    navigationMsg.data.setToExternal(message->data, message->data_length);
+
+    auto ret = sGnssNavigationMsgCbIface->gnssNavigationMessageCb(navigationMsg);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+Return<GnssNavigationMessage::GnssNavigationMessageStatus> GnssNavigationMessage::setCallback(
+        const sp<IGnssNavigationMessageCallback>& callback)  {
+    if (mGnssNavigationMessageIface == nullptr) {
+        ALOGE("%s: GnssNavigationMessage not available", __func__);
+        return GnssNavigationMessageStatus::ERROR_GENERIC;
+    }
+
+    sGnssNavigationMsgCbIface = callback;
+
+    return static_cast<GnssNavigationMessage::GnssNavigationMessageStatus>(
+            mGnssNavigationMessageIface->init(&sGnssNavigationMessageCb));
+}
+
+Return<void> GnssNavigationMessage::close()  {
+    if (mGnssNavigationMessageIface == nullptr) {
+        ALOGE("%s: GnssNavigationMessage not available", __func__);
+    } else {
+        mGnssNavigationMessageIface->close();
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssNavigationMessage.h b/src/connectivity/gps/service/1.1/GnssNavigationMessage.h
new file mode 100644
index 0000000..882854b
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssNavigationMessage.h
@@ -0,0 +1,77 @@
+/*
+ * 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_V1_0_GnssNavigationMessage_H_
+#define android_hardware_gnss_V1_0_GnssNavigationMessage_H_
+
+#include <android/hardware/gnss/1.0/IGnssNavigationMessage.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessage;
+using ::android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssNavigationMessage = ::GnssNavigationMessage;
+
+/*
+ * Extended interface for GNSS navigation message reporting support. Also contains wrapper methods
+ * to allow methods from IGnssNavigationMessageCallback interface to be passed into the conventional
+ * implementation of the GNSS HAL.
+ */
+struct GnssNavigationMessage : public IGnssNavigationMessage {
+    GnssNavigationMessage(const GpsNavigationMessageInterface* gpsNavigationMessageIface);
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssNavigationMessage follow.
+     * These declarations were generated from IGnssNavigationMessage.hal.
+     */
+    Return<GnssNavigationMessageStatus> setCallback(
+        const sp<IGnssNavigationMessageCallback>& callback) override;
+    Return<void> close() override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+     * These methods are not part of the IGnssNavigationMessage base class.
+     */
+    static void gnssNavigationMessageCb(LegacyGnssNavigationMessage* message);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsNavigationMessageCallbacks sGnssNavigationMessageCb;
+ private:
+    const GpsNavigationMessageInterface* mGnssNavigationMessageIface = nullptr;
+    static sp<IGnssNavigationMessageCallback> sGnssNavigationMsgCbIface;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssNavigationMessage_H_
diff --git a/src/connectivity/gps/service/1.1/GnssNi.cpp b/src/connectivity/gps/service/1.1/GnssNi.cpp
new file mode 100644
index 0000000..d17891d
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssNi.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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_GnssNiInterface"
+
+#include "GnssNi.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssNi::sThreadFuncArgsList;
+sp<IGnssNiCallback> GnssNi::sGnssNiCbIface = nullptr;
+bool GnssNi::sInterfaceExists = false;
+
+GpsNiCallbacks GnssNi::sGnssNiCb = {
+    .notify_cb = niNotifyCb,
+    .create_thread_cb = createThreadCb
+};
+
+GnssNi::GnssNi(const GpsNiInterface* gpsNiIface) : mGnssNiIface(gpsNiIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+GnssNi::~GnssNi() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+pthread_t GnssNi::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void GnssNi::niNotifyCb(GpsNiNotification* notification) {
+    if (sGnssNiCbIface == nullptr) {
+        ALOGE("%s: GNSS NI Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    if (notification == nullptr) {
+        ALOGE("%s: Invalid GpsNotification callback from GNSS HAL", __func__);
+        return;
+    }
+
+    IGnssNiCallback::GnssNiNotification notificationGnss = {
+        .notificationId =  notification->notification_id,
+        .niType = static_cast<IGnssNiCallback::GnssNiType>(notification->ni_type),
+        .notifyFlags = notification->notify_flags,
+        .timeoutSec = static_cast<uint32_t>(notification->timeout),
+        .defaultResponse =
+                static_cast<IGnssNiCallback::GnssUserResponseType>(notification->default_response),
+        .requestorId = notification->requestor_id,
+        .notificationMessage = notification->text,
+        .requestorIdEncoding =
+                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->requestor_id_encoding),
+        .notificationIdEncoding =
+                static_cast<IGnssNiCallback::GnssNiEncodingType>(notification->text_encoding)
+    };
+
+    auto ret = sGnssNiCbIface->niNotifyCb(notificationGnss);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
+Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback)  {
+    if (mGnssNiIface == nullptr) {
+       ALOGE("%s: GnssNi interface is unavailable", __func__);
+       return Void();
+    }
+
+    sGnssNiCbIface = callback;
+
+    mGnssNiIface->init(&sGnssNiCb);
+    return Void();
+}
+
+Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse)  {
+    if (mGnssNiIface == nullptr) {
+        ALOGE("%s: GnssNi interface is unavailable", __func__);
+    } else {
+        mGnssNiIface->respond(notifId, static_cast<GpsUserResponseType>(userResponse));
+    }
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssNi.h b/src/connectivity/gps/service/1.1/GnssNi.h
new file mode 100644
index 0000000..fe850b1
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssNi.h
@@ -0,0 +1,81 @@
+/*
+ * 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_V1_0_GnssNi_H_
+#define android_hardware_gnss_V1_0_GnssNi_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssNi.h>
+#include <hidl/Status.h>
+#include <hardware/gps.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_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;
+
+/*
+ * Extended interface for Network-initiated (NI) support. This interface is used to respond to
+ * NI notifications originating from the HAL. Also contains wrapper methods to allow methods from
+ * IGnssNiCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+struct GnssNi : public IGnssNi {
+    GnssNi(const GpsNiInterface* gpsNiIface);
+    ~GnssNi();
+
+    /*
+     * 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;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnssNi base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void niNotifyCb(GpsNiNotification* notification);
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsNiCallbacks sGnssNiCb;
+
+ private:
+    const GpsNiInterface* mGnssNiIface = nullptr;
+    static sp<IGnssNiCallback> sGnssNiCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssNi_H_
diff --git a/src/connectivity/gps/service/1.1/GnssUtils.cpp b/src/connectivity/gps/service/1.1/GnssUtils.cpp
new file mode 100644
index 0000000..0234aa3
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssUtils.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#include "GnssUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using android::hardware::gnss::V1_0::GnssLocation;
+
+GnssLocation convertToGnssLocation(GpsLocation_ext* location) {
+    GnssLocation gnssLocation = {};
+    if (location != nullptr) {
+        gnssLocation = {
+            .gnssLocationFlags = static_cast<uint16_t>(location->legacyLocation.flags & 0xff),
+            .latitudeDegrees = location->legacyLocation.latitude,
+            .longitudeDegrees = location->legacyLocation.longitude,
+            .altitudeMeters = location->legacyLocation.altitude,
+            .speedMetersPerSec = location->legacyLocation.speed,
+            .bearingDegrees = location->legacyLocation.bearing,
+            .horizontalAccuracyMeters = location->horizontalAccuracyMeters,
+            .verticalAccuracyMeters = location->verticalAccuracyMeters,
+            .speedAccuracyMetersPerSecond = location->speedAccuracyMetersPerSecond,
+            .bearingAccuracyDegrees = location->bearingAccuracyDegrees,
+            .timestamp = location->legacyLocation.timestamp
+        };
+    }
+
+    return gnssLocation;
+}
+
+GnssLocation convertToGnssLocation(FlpLocation* flpLocation) {
+    GnssLocation gnssLocation = {};
+    if (flpLocation != nullptr) {
+        gnssLocation = {.gnssLocationFlags = 0,  // clear here and set below
+                        .latitudeDegrees = flpLocation->latitude,
+                        .longitudeDegrees = flpLocation->longitude,
+                        .altitudeMeters = flpLocation->altitude,
+                        .speedMetersPerSec = flpLocation->speed,
+                        .bearingDegrees = flpLocation->bearing,
+                        .horizontalAccuracyMeters = flpLocation->accuracy,
+                        .verticalAccuracyMeters = 0,
+                        .speedAccuracyMetersPerSecond = 0,
+                        .bearingAccuracyDegrees = 0,
+                        .timestamp = flpLocation->timestamp};
+        // FlpLocation flags different from GnssLocation flags
+        if (flpLocation->flags & FLP_LOCATION_HAS_LAT_LONG) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_LAT_LONG;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_ALTITUDE) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_ALTITUDE;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_SPEED) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_SPEED;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_BEARING) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_BEARING;
+        }
+        if (flpLocation->flags & FLP_LOCATION_HAS_ACCURACY) {
+            gnssLocation.gnssLocationFlags |= GPS_LOCATION_HAS_HORIZONTAL_ACCURACY;
+        }
+    }
+
+    return gnssLocation;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssUtils.h b/src/connectivity/gps/service/1.1/GnssUtils.h
new file mode 100644
index 0000000..7cfef2e
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssUtils.h
@@ -0,0 +1,48 @@
+/*
+ * 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_V1_0_GnssUtil_H_
+#define android_hardware_gnss_V1_0_GnssUtil_H_
+
+#include <hardware/fused_location.h>
+#include <hardware/gps.h>
+#include <hardware/gps_mtk.h>
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+/*
+ * This method converts a GpsLocation struct to a GnssLocation
+ * struct.
+ */
+GnssLocation convertToGnssLocation(GpsLocation_ext* location);
+
+/*
+ * This method converts an FlpLocation struct to a GnssLocation
+ * struct.
+ */
+GnssLocation convertToGnssLocation(FlpLocation* location);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif
diff --git a/src/connectivity/gps/service/1.1/GnssXtra.cpp b/src/connectivity/gps/service/1.1/GnssXtra.cpp
new file mode 100644
index 0000000..d124ce1
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssXtra.cpp
@@ -0,0 +1,95 @@
+/*
+ * 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_GnssXtraInterface"
+
+#include "GnssXtra.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> GnssXtra::sThreadFuncArgsList;
+sp<IGnssXtraCallback> GnssXtra::sGnssXtraCbIface = nullptr;
+bool GnssXtra::sInterfaceExists = false;
+
+GpsXtraCallbacks GnssXtra::sGnssXtraCb = {
+    .download_request_cb = gnssXtraDownloadRequestCb,
+    .create_thread_cb = createThreadCb,
+};
+
+GnssXtra::~GnssXtra() {
+    sThreadFuncArgsList.clear();
+    sInterfaceExists = false;
+}
+
+pthread_t GnssXtra::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+GnssXtra::GnssXtra(const GpsXtraInterface* xtraIface) : mGnssXtraIface(xtraIface) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+}
+
+void GnssXtra::gnssXtraDownloadRequestCb() {
+    if (sGnssXtraCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    auto ret = sGnssXtraCbIface->downloadRequestCb();
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+Return<bool> GnssXtra::setCallback(const sp<IGnssXtraCallback>& callback)  {
+    if (mGnssXtraIface == nullptr) {
+        ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+        return false;
+    }
+
+    sGnssXtraCbIface = callback;
+
+    return (mGnssXtraIface->init(&sGnssXtraCb) == 0);
+}
+
+Return<bool> GnssXtra::injectXtraData(const hidl_string& xtraData)  {
+    if (mGnssXtraIface == nullptr) {
+        ALOGE("%s: Gnss Xtra interface is unavailable", __func__);
+        return false;
+    }
+
+    char* buf = new char[xtraData.size()];
+    const char* data = xtraData.c_str();
+
+    memcpy(buf, data, xtraData.size());
+
+    int ret = mGnssXtraIface->inject_xtra_data(buf, xtraData.size());
+    delete[] buf;
+    return (ret == 0);
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/src/connectivity/gps/service/1.1/GnssXtra.h b/src/connectivity/gps/service/1.1/GnssXtra.h
new file mode 100644
index 0000000..7a0733a
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/GnssXtra.h
@@ -0,0 +1,80 @@
+/*
+ * 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_V1_0_GnssXtra_H_
+#define android_hardware_gnss_V1_0_GnssXtra_H_
+
+#include <ThreadCreationWrapper.h>
+#include <android/hardware/gnss/1.0/IGnssXtra.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::IGnssXtra;
+using ::android::hardware::gnss::V1_0::IGnssXtraCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+/*
+ * This interface is used by the GNSS HAL to request the framework to download XTRA data.
+ * Also contains wrapper methods to allow methods from IGnssXtraCallback interface to be passed
+ * into the conventional implementation of the GNSS HAL.
+ */
+struct GnssXtra : public IGnssXtra {
+    GnssXtra(const GpsXtraInterface* xtraIface);
+    ~GnssXtra();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnssXtra follow.
+     * These declarations were generated from IGnssXtra.hal.
+     */
+    Return<bool> setCallback(const sp<IGnssXtraCallback>& callback) override;
+    Return<bool> injectXtraData(const hidl_string& xtraData) override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default implementation.
+     * These methods are not part of the IGnssXtra base class.
+     */
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void gnssXtraDownloadRequestCb();
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsXtraCallbacks sGnssXtraCb;
+
+ private:
+    const GpsXtraInterface* mGnssXtraIface = nullptr;
+    static sp<IGnssXtraCallback> sGnssXtraCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_V1_0_GnssXtra_H_
diff --git a/src/connectivity/gps/service/1.1/MtkGnss.cpp b/src/connectivity/gps/service/1.1/MtkGnss.cpp
new file mode 100644
index 0000000..f0ebcc5
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/MtkGnss.cpp
@@ -0,0 +1,840 @@
+/*
+ * 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 "MtkGnssHAL_GnssInterface"
+
+#include "MtkGnss.h"
+#include <GnssUtils.h>
+#include "hardware/gps_mtk.h"
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+std::vector<std::unique_ptr<ThreadFuncArgs>> MtkGnss::sThreadFuncArgsList;
+sp<IGnssCallback> MtkGnss::sGnssCbIface = nullptr;
+bool MtkGnss::sInterfaceExists = false;
+bool MtkGnss::sWakelockHeldGnss = false;
+bool MtkGnss::sWakelockHeldFused = false;
+
+GpsCallbacks MtkGnss::sGnssCb = {
+    .size = sizeof(GpsCallbacks),
+    .location_cb = locationCb,
+    .status_cb = statusCb,
+    .sv_status_cb = gpsSvStatusCb,
+    .nmea_cb = nmeaCb,
+    .set_capabilities_cb = setCapabilitiesCb,
+    .acquire_wakelock_cb = acquireWakelockCb,
+    .release_wakelock_cb = releaseWakelockCb,
+    .create_thread_cb = createThreadCb,
+    .request_utc_time_cb = requestUtcTimeCb,
+    .set_system_info_cb = setSystemInfoCb,
+    .gnss_sv_status_cb = gnssSvStatusCb,
+};
+
+uint32_t MtkGnss::sCapabilitiesCached = 0;
+uint16_t MtkGnss::sYearOfHwCached = 0;
+sem_t MtkGnss::sSem;
+
+
+MtkGnss::MtkGnss(gps_device_t* gnssDevice) :
+        mDeathRecipient(new GnssHidlDeathRecipient(this)) {
+    /* Error out if an instance of the interface already exists. */
+    LOG_ALWAYS_FATAL_IF(sInterfaceExists);
+    sInterfaceExists = true;
+
+    if (gnssDevice == nullptr) {
+        ALOGE("%s: Invalid device_t handle", __func__);
+        return;
+    }
+
+    mGnssIface = gnssDevice->get_gps_interface(gnssDevice);
+    sem_init(&sSem, 0, 1);
+}
+
+MtkGnss::~MtkGnss() {
+    sInterfaceExists = false;
+    sThreadFuncArgsList.clear();
+    sem_destroy(&sSem);
+}
+
+void MtkGnss::locationCb(GpsLocation* location) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (location == nullptr) {
+        ALOGE("%s: Invalid location from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    android::hardware::gnss::V1_0::GnssLocation gnssLocation = convertToGnssLocation(location);
+    auto ret = sGnssCbIface->gnssLocationCb(gnssLocation);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void MtkGnss::statusCb(GpsStatus* gnssStatus) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (gnssStatus == nullptr) {
+        ALOGE("%s: Invalid GpsStatus from GNSS HAL", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssStatusValue status =
+            static_cast<IGnssCallback::GnssStatusValue>(gnssStatus->status);
+
+    auto ret = sGnssCbIface->gnssStatusCb(status);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void MtkGnss::gnssSvStatusCb(GnssSvStatus* status) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (status == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = status->num_svs;
+
+    if (svStatus.numSvs > static_cast<uint32_t>(GnssMax::SVS_COUNT)) {
+        ALOGW("Too many satellites %zd. Clamps to %d.", svStatus.numSvs, GnssMax::SVS_COUNT);
+        svStatus.numSvs = static_cast<uint32_t>(GnssMax::SVS_COUNT);
+    }
+
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        auto svInfo = status->gnss_sv_list[i];
+        IGnssCallback::GnssSvInfo gnssSvInfo = {
+            .svid = svInfo.svid,
+            .constellation = static_cast<
+                android::hardware::gnss::V1_0::GnssConstellationType>(
+                svInfo.constellation),
+            .cN0Dbhz = svInfo.c_n0_dbhz,
+            .elevationDegrees = svInfo.elevation,
+            .azimuthDegrees = svInfo.azimuth,
+            // Older chipsets do not provide carrier frequency, hence
+            // HAS_CARRIER_FREQUENCY flag and the carrierFrequencyHz fields
+            // are not set. So we are resetting both fields here.
+            .svFlag = static_cast<uint8_t>(
+                svInfo.flags &= ~(static_cast<uint8_t>(
+                    IGnssCallback::GnssSvFlags::HAS_CARRIER_FREQUENCY))),
+            .carrierFrequencyHz = 0};
+        svStatus.gnssSvList[i] = gnssSvInfo;
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+/*
+ * This enum is used by gpsSvStatusCb() method below to convert GpsSvStatus
+ * to GnssSvStatus for backward compatibility. It is only used by the default
+ * implementation and is not part of the GNSS interface.
+ */
+enum SvidValues : uint16_t {
+    GLONASS_SVID_OFFSET = 64,
+    GLONASS_SVID_COUNT = 24,
+    BEIDOU_SVID_OFFSET = 200,
+    BEIDOU_SVID_COUNT = 35,
+    SBAS_SVID_MIN = 33,
+    SBAS_SVID_MAX = 64,
+    SBAS_SVID_ADD = 87,
+    QZSS_SVID_MIN = 193,
+    QZSS_SVID_MAX = 200
+};
+
+/*
+ * The following code that converts GpsSvStatus to GnssSvStatus is moved here from
+ * GnssLocationProvider. GnssLocationProvider does not require it anymore since GpsSvStatus is
+ * being deprecated and is no longer part of the GNSS interface.
+ */
+void MtkGnss::gpsSvStatusCb(GpsSvStatus* svInfo) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (svInfo == nullptr) {
+        ALOGE("Invalid status from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSvStatus svStatus;
+    svStatus.numSvs = svInfo->num_svs;
+    /*
+     * Clamp the list size since GnssSvStatus can support a maximum of
+     * GnssMax::SVS_COUNT entries.
+     */
+    ///M: fix max numSvs as GPS_MAX_SVS
+    if (svStatus.numSvs > static_cast<uint32_t>(GPS_MAX_SVS)) {
+        ALOGW("Too many satellites %zd. Clamps to %d.", svStatus.numSvs, GPS_MAX_SVS);
+        svStatus.numSvs = static_cast<uint32_t>(GPS_MAX_SVS);
+    }
+    /// M: mtk update end
+
+    uint32_t ephemerisMask = svInfo->ephemeris_mask;
+    uint32_t almanacMask = svInfo->almanac_mask;
+    uint32_t usedInFixMask = svInfo->used_in_fix_mask;
+    /*
+     * Conversion from GpsSvInfo to IGnssCallback::GnssSvInfo happens below.
+     */
+    for (size_t i = 0; i < svStatus.numSvs; i++) {
+        IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList[i];
+        info.svid = svInfo->sv_list[i].prn;
+        if (info.svid >= 1 && info.svid <= 32) {
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::GPS;
+        } else if (info.svid > GLONASS_SVID_OFFSET &&
+                   info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::GLONASS;
+            info.svid -= GLONASS_SVID_OFFSET;
+        } else if (info.svid > BEIDOU_SVID_OFFSET &&
+                 info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::BEIDOU;
+            info.svid -= BEIDOU_SVID_OFFSET;
+        } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::SBAS;
+            info.svid += SBAS_SVID_ADD;
+        } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::QZSS;
+        } else {
+            ALOGD("Unknown constellation type with Svid = %d.", info.svid);
+            /// Mtk added to specify namespace
+            info.constellation = android::hardware::gnss::V1_0::GnssConstellationType::UNKNOWN;
+        }
+
+        info.cN0Dbhz = svInfo->sv_list[i].snr;
+        info.elevationDegrees = svInfo->sv_list[i].elevation;
+        info.azimuthDegrees = svInfo->sv_list[i].azimuth;
+        // TODO: b/31702236
+        info.svFlag = static_cast<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
+
+        /*
+         * Only GPS info is valid for these fields, as these masks are just 32
+         * bits, by GPS prn.
+         */
+        /// Mtk added to specify namespace
+        if (info.constellation == android::hardware::gnss::V1_0::GnssConstellationType::GPS) {
+            int32_t svidMask = (1 << (info.svid - 1));
+            if ((ephemerisMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
+            }
+            if ((almanacMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
+            }
+            if ((usedInFixMask & svidMask) != 0) {
+                info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
+            }
+        }
+    }
+
+    auto ret = sGnssCbIface->gnssSvStatusCb(svStatus);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void MtkGnss::nmeaCb(GpsUtcTime timestamp, const char* nmea, int length) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    android::hardware::hidl_string nmeaString;
+    nmeaString.setToExternal(nmea, length);
+    auto ret = sGnssCbIface->gnssNmeaCb(timestamp, nmeaString);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+void MtkGnss::setCapabilitiesCb(uint32_t capabilities) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssSetCapabilitesCb(capabilities);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sCapabilitiesCached = capabilities;
+    sem_post(&sSem);
+}
+
+void MtkGnss::acquireWakelockCb() {
+    acquireWakelockGnss();
+}
+
+void MtkGnss::releaseWakelockCb() {
+    releaseWakelockGnss();
+}
+
+
+void MtkGnss::acquireWakelockGnss() {
+    sWakelockHeldGnss = true;
+    updateWakelock();
+}
+
+void MtkGnss::releaseWakelockGnss() {
+    sWakelockHeldGnss = false;
+    updateWakelock();
+}
+
+void MtkGnss::acquireWakelockFused() {
+    sWakelockHeldFused = true;
+    updateWakelock();
+}
+
+void MtkGnss::releaseWakelockFused() {
+    sWakelockHeldFused = false;
+    updateWakelock();
+}
+
+void MtkGnss::updateWakelock() {
+    // Track the state of the last request - in case the wake lock in the layer above is reference
+    // counted.
+    static bool sWakelockHeld = false;
+
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (sWakelockHeldGnss || sWakelockHeldFused) {
+        if (!sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock acquired due to gps: %d, fused: %d", __func__,
+                    sWakelockHeldGnss, sWakelockHeldFused);
+            sWakelockHeld = true;
+            auto ret = sGnssCbIface->gnssAcquireWakelockCb();
+            if (!ret.isOk()) {
+                ALOGE("%s: Unable to invoke callback", __func__);
+            }
+        }
+    } else {
+        if (sWakelockHeld) {
+            ALOGI("%s: GNSS HAL Wakelock released", __func__);
+        } else  {
+            // To avoid burning power, always release, even if logic got here with sWakelock false
+            // which it shouldn't, unless underlying *.h implementation makes duplicate requests.
+            ALOGW("%s: GNSS HAL Wakelock released, duplicate request", __func__);
+        }
+        sWakelockHeld = false;
+        auto ret = sGnssCbIface->gnssReleaseWakelockCb();
+        if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+        }
+    }
+    sem_post(&sSem);
+}
+
+void MtkGnss::requestUtcTimeCb() {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    auto ret = sGnssCbIface->gnssRequestTimeCb();
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    sem_post(&sSem);
+}
+
+pthread_t MtkGnss::createThreadCb(const char* name, void (*start)(void*), void* arg) {
+    return createPthread(name, start, arg, &sThreadFuncArgsList);
+}
+
+void MtkGnss::setSystemInfoCb(const LegacyGnssSystemInfo* info) {
+    sem_wait(&sSem);
+    if (sGnssCbIface == nullptr) {
+        ALOGE("%s: GNSS Callback Interface configured incorrectly", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    if (info == nullptr) {
+        ALOGE("Invalid GnssSystemInfo from GNSS HAL %s", __func__);
+        sem_post(&sSem);
+        return;
+    }
+
+    IGnssCallback::GnssSystemInfo gnssInfo = {
+        .yearOfHw = info->year_of_hw
+    };
+
+    auto ret = sGnssCbIface->gnssSetSystemInfoCb(gnssInfo);
+    if (!ret.isOk()) {
+            ALOGE("%s: Unable to invoke callback", __func__);
+    }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sYearOfHwCached = info->year_of_hw;
+    sem_post(&sSem);
+}
+
+
+// Methods from ::android::hardware::MtkGnss::V1_0::IGnss follow.
+Return<bool> MtkGnss::setCallback(const sp<IGnssCallback>& callback)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    if (callback == nullptr)  {
+        ALOGE("%s: Null callback ignored", __func__);
+        return false;
+    }
+
+    sem_wait(&sSem);
+    if (sGnssCbIface != NULL) {
+        ALOGW("%s called more than once. Unexpected unless test.", __func__);
+        sGnssCbIface->unlinkToDeath(mDeathRecipient);
+    }
+
+    sGnssCbIface = callback;
+    callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+    sem_post(&sSem);
+
+    // If this was received in the past, send it up again to refresh caller.
+    // mGnssIface will override after init() is called below, if needed
+    // (though it's unlikely the gps.h capabilities or system info will change.)
+    if (sCapabilitiesCached != 0) {
+        setCapabilitiesCb(sCapabilitiesCached);
+    }
+    if (sYearOfHwCached != 0) {
+        LegacyGnssSystemInfo info;
+        info.year_of_hw = sYearOfHwCached;
+        setSystemInfoCb(&info);
+    }
+
+    return (mGnssIface->init(&sGnssCb) == 0);
+}
+
+Return<bool> MtkGnss::start()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->start() == 0);
+}
+
+Return<bool> MtkGnss::stop()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->stop() == 0);
+}
+
+Return<void> MtkGnss::cleanup()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->cleanup();
+    }
+    return Void();
+}
+
+Return<bool> MtkGnss::injectLocation(double latitudeDegrees,
+                                  double longitudeDegrees,
+                                  float accuracyMeters)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters) == 0);
+}
+
+Return<bool> MtkGnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                              int32_t uncertaintyMs) {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->inject_time(timeMs, timeReferenceMs, uncertaintyMs) == 0);
+}
+
+Return<void> MtkGnss::deleteAidingData(IMtkGnss::GnssAidingData aidingDataFlags)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+    } else {
+        mGnssIface->delete_aiding_data(static_cast<GpsAidingData>(aidingDataFlags));
+    }
+    return Void();
+}
+
+Return<bool> MtkGnss::setPositionMode(IMtkGnss::GnssPositionMode mode,
+                                   IMtkGnss::GnssPositionRecurrence recurrence,
+                                   uint32_t minIntervalMs,
+                                   uint32_t preferredAccuracyMeters,
+                                   uint32_t preferredTimeMs)  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return false;
+    }
+
+    return (mGnssIface->set_position_mode(static_cast<GpsPositionMode>(mode),
+                                          static_cast<GpsPositionRecurrence>(recurrence),
+                                          minIntervalMs,
+                                          preferredAccuracyMeters,
+                                          preferredTimeMs) == 0);
+}
+
+Return<sp<IAGnssRil>> MtkGnss::getExtensionAGnssRil()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssRil == nullptr) {
+        const AGpsRilInterface* agpsRilIface = static_cast<const AGpsRilInterface*>(
+                mGnssIface->get_extension(AGPS_RIL_INTERFACE));
+        if (agpsRilIface == nullptr) {
+            ALOGE("%s GnssRil interface not implemented by GNSS HAL", __func__);
+        } else {
+            mGnssRil = new AGnssRil(agpsRilIface);
+        }
+    }
+    return mGnssRil;
+}
+
+Return<sp<IGnssConfiguration>> MtkGnss::getExtensionGnssConfiguration()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssConfig == nullptr) {
+        const GnssConfigurationInterface* gnssConfigIface =
+                static_cast<const GnssConfigurationInterface*>(
+                        mGnssIface->get_extension(GNSS_CONFIGURATION_INTERFACE));
+
+        if (gnssConfigIface == nullptr) {
+            ALOGW("%s GnssConfiguration interface not implemented by GNSS HAL", __func__);
+        } else {
+            mGnssConfig = new GnssConfiguration(gnssConfigIface);
+        }
+    }
+    return mGnssConfig;
+}
+
+Return<sp<IGnssGeofencing>> MtkGnss::getExtensionGnssGeofencing()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssGeofencingIface == nullptr) {
+        const GpsGeofencingInterface* gpsGeofencingIface =
+                static_cast<const GpsGeofencingInterface*>(
+                        mGnssIface->get_extension(GPS_GEOFENCING_INTERFACE));
+
+        if (gpsGeofencingIface == nullptr) {
+            ALOGE("%s GnssGeofencing interface not implemented by GNSS HAL", __func__);
+        } else {
+            mGnssGeofencingIface = new GnssGeofencing(gpsGeofencingIface);
+        }
+    }
+
+    return mGnssGeofencingIface;
+}
+
+Return<sp<IAGnss>> MtkGnss::getExtensionAGnss()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mAGnssIface == nullptr) {
+        const AGpsInterface* agpsIface = static_cast<const AGpsInterface*>(
+                mGnssIface->get_extension(AGPS_INTERFACE));
+        if (agpsIface == nullptr) {
+            ALOGE("%s AGnss interface not implemented by GNSS HAL", __func__);
+        } else {
+            mAGnssIface = new AGnss(agpsIface);
+        }
+    }
+    return mAGnssIface;
+}
+
+Return<sp<IGnssNi>> MtkGnss::getExtensionGnssNi()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNi == nullptr) {
+        const GpsNiInterface* gpsNiIface = static_cast<const GpsNiInterface*>(
+                mGnssIface->get_extension(GPS_NI_INTERFACE));
+        if (gpsNiIface == nullptr) {
+            ALOGE("%s GnssNi interface not implemented by GNSS HAL", __func__);
+        } else {
+            mGnssNi = new GnssNi(gpsNiIface);
+        }
+    }
+    return mGnssNi;
+}
+
+Return<sp<IGnssMeasurement>> MtkGnss::getExtensionGnssMeasurement() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssMeasurement == nullptr) {
+        const GpsMeasurementInterface* gpsMeasurementIface =
+                static_cast<const GpsMeasurementInterface*>(
+                        mGnssIface->get_extension(GPS_MEASUREMENT_INTERFACE));
+
+        if (gpsMeasurementIface == nullptr) {
+            ALOGE("%s GnssMeasurement interface not implemented by GNSS HAL", __func__);
+        } else {
+            /// Mtk added to specify namespace
+            mGnssMeasurement = new implementation::GnssMeasurement(gpsMeasurementIface);
+        }
+    }
+    return mGnssMeasurement;
+}
+
+Return<sp<IGnssNavigationMessage>> MtkGnss::getExtensionGnssNavigationMessage() {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssNavigationMessage == nullptr) {
+        const GpsNavigationMessageInterface* gpsNavigationMessageIface =
+                static_cast<const GpsNavigationMessageInterface*>(
+                        mGnssIface->get_extension(GPS_NAVIGATION_MESSAGE_INTERFACE));
+
+        if (gpsNavigationMessageIface == nullptr) {
+            ALOGE("%s GnssNavigationMessage interface not implemented by GNSS HAL",
+                  __func__);
+        } else {
+            /// Mtk added to specify namespace
+            mGnssNavigationMessage = new implementation::GnssNavigationMessage(gpsNavigationMessageIface);
+        }
+    }
+
+    return mGnssNavigationMessage;
+}
+
+Return<sp<IGnssXtra>> MtkGnss::getExtensionXtra()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssXtraIface == nullptr) {
+        const GpsXtraInterface* gpsXtraIface = static_cast<const GpsXtraInterface*>(
+                mGnssIface->get_extension(GPS_XTRA_INTERFACE));
+
+        if (gpsXtraIface == nullptr) {
+            ALOGW("%s GnssXtra interface not implemented by HAL", __func__);
+        } else {
+            mGnssXtraIface = new GnssXtra(gpsXtraIface);
+        }
+    }
+
+    return mGnssXtraIface;
+}
+
+Return<sp<IGnssDebug>> MtkGnss::getExtensionGnssDebug()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssDebug == nullptr) {
+        const GpsDebugInterface* gpsDebugIface = static_cast<const GpsDebugInterface*>(
+                mGnssIface->get_extension(GPS_DEBUG_INTERFACE));
+
+        if (gpsDebugIface == nullptr) {
+            ALOGW("%s: GnssDebug interface is not implemented by HAL", __func__);
+        } else {
+            mGnssDebug = new GnssDebug(gpsDebugIface);
+        }
+    }
+
+    return mGnssDebug;
+}
+
+Return<sp<IGnssBatching>> MtkGnss::getExtensionGnssBatching()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mGnssBatching == nullptr) {
+        hw_module_t* module;
+        const FlpLocationInterface* flpLocationIface = nullptr;
+        int err = hw_get_module(FUSED_LOCATION_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+        if (err != 0) {
+            ALOGE("gnss flp hw_get_module failed: %d", err);
+        } else if (module == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null module");
+        } else if (module->methods == nullptr) {
+            ALOGE("Fused Location hw_get_module returned null methods");
+        } else {
+            hw_device_t* device;
+            err = module->methods->open(module, FUSED_LOCATION_HARDWARE_MODULE_ID, &device);
+            if (err != 0) {
+                ALOGE("flpDevice open failed: %d", err);
+            } else {
+                flp_device_t * flpDevice = reinterpret_cast<flp_device_t*>(device);
+                flpLocationIface = flpDevice->get_flp_interface(flpDevice);
+            }
+        }
+
+        if (flpLocationIface == nullptr) {
+            ALOGE("%s: GnssBatching interface is not implemented by HAL", __func__);
+        } else {
+            mGnssBatching = new GnssBatching(flpLocationIface);
+        }
+    }
+    return mGnssBatching;
+}
+
+void MtkGnss::handleHidlDeath() {
+    ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+    /// M: move here! Do not callback to system_server to avoid gnss hidl service NE
+    /*
+     * This has died, so close it off in case (race condition) callbacks happen
+     * before HAL processes above messages.
+     */
+    sem_wait(&sSem);
+    sGnssCbIface = nullptr;
+    sem_post(&sSem);
+
+    // commands down to the HAL implementation
+    stop(); // stop ongoing GPS tracking
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+    if (mGnssNavigationMessage != nullptr) {
+        mGnssNavigationMessage->close();
+    }
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+    cleanup();
+
+}
+
+
+Return<sp<IVzwDebug>> MtkGnss::getExtensionVzwDebug()  {
+    if (mGnssIface == nullptr) {
+        ALOGE("%s: Gnss interface is unavailable", __func__);
+        return nullptr;
+    }
+
+    if (mVzwDebug == nullptr) {
+        const VzwDebugInterface* vzwDebugIface = static_cast<const VzwDebugInterface*>(
+                mGnssIface->get_extension(VZW_DEBUG_INTERFACE));
+
+        if (vzwDebugIface == nullptr) {
+            ALOGE("%s: VzwDebug interface is not implemented by HAL", __func__);
+        } else {
+            mVzwDebug = new VzwDebug(vzwDebugIface);
+        }
+    }
+
+    return mVzwDebug;
+}
+
+
+IMtkGnss* HIDL_FETCH_IMtkGnss(const char* /* hal */) {
+    hw_module_t* module;
+    IMtkGnss* iface = nullptr;
+    int err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
+
+    if (err == 0) {
+        hw_device_t* device;
+        err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
+        if (err == 0) {
+            iface = new MtkGnss(reinterpret_cast<gps_device_t*>(device));
+        } else {
+            ALOGE("gnssDevice open %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+        }
+    } else {
+      ALOGE("gnss hw_get_module %s failed: %d", GPS_HARDWARE_MODULE_ID, err);
+    }
+    return iface;
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace mediatek
+}  // namespace vendor
diff --git a/src/connectivity/gps/service/1.1/MtkGnss.h b/src/connectivity/gps/service/1.1/MtkGnss.h
new file mode 100644
index 0000000..bc211b4
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/MtkGnss.h
@@ -0,0 +1,207 @@
+/*
+ * 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 VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_MTKGNSS_H
+#define VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_MTKGNSS_H
+
+#include <AGnss.h>
+#include <AGnssRil.h>
+#include <GnssBatching.h>
+#include <GnssConfiguration.h>
+#include <GnssDebug.h>
+#include <GnssGeofencing.h>
+#include <GnssMeasurement.h>
+#include <GnssNavigationMessage.h>
+#include <GnssNi.h>
+#include <GnssXtra.h>
+
+#include <ThreadCreationWrapper.h>
+//#include <android/hardware/gnss/1.0/IGnss.h>
+#include <vendor/mediatek/hardware/gnss/1.1/IMtkGnss.h>
+#include <hardware/fused_location.h>
+#include <hardware/gps.h>
+#include <hidl/Status.h>
+
+#include <VzwDebug.h>
+#include <semaphore.h>
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+/// Mtk added to include more namespaces
+using namespace android::hardware::gnss::V1_0;
+using namespace android::hardware::gnss::V1_0::implementation;
+using ::vendor::mediatek::hardware::gnss::V1_1::IMtkGnss;
+using ::vendor::mediatek::hardware::gnss::V1_1::IVzwDebug;
+using ::android::wp;
+/// Mtk add end
+using ::android::hardware::hidl_death_recipient;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+using LegacyGnssSystemInfo = ::GnssSystemInfo;
+
+/*
+ * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
+ * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
+ */
+class MtkGnss : public IMtkGnss {
+  public:
+    MtkGnss(gps_device_t* gnss_device);
+    ~MtkGnss();
+
+    /*
+     * Methods from ::android::hardware::gnss::V1_0::IGnss follow.
+     * These declarations were generated from Gnss.hal.
+     */
+    Return<bool> setCallback(const sp<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(IGnss::GnssAidingData aidingDataFlags)  override;
+    Return<bool> setPositionMode(IGnss::GnssPositionMode mode,
+                                 IGnss::GnssPositionRecurrence recurrence,
+                                 uint32_t minIntervalMs,
+                                 uint32_t preferredAccuracyMeters,
+                                 uint32_t preferredTimeMs)  override;
+    Return<sp<IAGnssRil>> getExtensionAGnssRil() override;
+    Return<sp<IGnssGeofencing>> getExtensionGnssGeofencing() override;
+    Return<sp<IAGnss>> getExtensionAGnss() override;
+    Return<sp<IGnssNi>> getExtensionGnssNi() override;
+    Return<sp<IGnssMeasurement>> getExtensionGnssMeasurement() override;
+    Return<sp<IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override;
+    Return<sp<IGnssXtra>> getExtensionXtra() override;
+    Return<sp<IGnssConfiguration>> getExtensionGnssConfiguration() override;
+    Return<sp<IGnssDebug>> getExtensionGnssDebug() override;
+    Return<sp<IGnssBatching>> getExtensionGnssBatching() override;
+    ///M: add to get and wrap hal vzw debug interface
+    Return<sp<IVzwDebug>> getExtensionVzwDebug() override;
+
+    /*
+     * Callback methods to be passed into the conventional GNSS HAL by the default
+     * implementation. These methods are not part of the IGnss base class.
+     */
+    static void locationCb(GpsLocation* location);
+    static void statusCb(GpsStatus* gnss_status);
+    static void nmeaCb(GpsUtcTime timestamp, const char* nmea, int length);
+    static void setCapabilitiesCb(uint32_t capabilities);
+    static void acquireWakelockCb();
+    static void releaseWakelockCb();
+    static void requestUtcTimeCb();
+    static pthread_t createThreadCb(const char* name, void (*start)(void*), void* arg);
+    static void gnssSvStatusCb(GnssSvStatus* status);
+    /*
+     * Deprecated callback added for backward compatibility to devices that do
+     * not support GnssSvStatus.
+     */
+    static void gpsSvStatusCb(GpsSvStatus* status);
+    static void setSystemInfoCb(const LegacyGnssSystemInfo* info);
+
+    /*
+     * Wakelock consolidation, only needed for dual use of a gps.h & fused_location.h HAL
+     *
+     * Ensures that if the last call from either legacy .h was to acquire a wakelock, that a
+     * wakelock is held.  Otherwise releases it.
+     */
+    static void acquireWakelockFused();
+    static void releaseWakelockFused();
+
+    /*
+     * Holds function pointers to the callback methods.
+     */
+    static GpsCallbacks sGnssCb;
+
+ private:
+    /*
+     * For handling system-server death while GNSS service lives on.
+     */
+    class GnssHidlDeathRecipient : public hidl_death_recipient {
+      public:
+        GnssHidlDeathRecipient(const sp<MtkGnss> gnss) : mGnss(gnss) {
+        }
+
+        virtual void serviceDied(uint64_t /*cookie*/,
+                const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+            mGnss->handleHidlDeath();
+        }
+      private:
+        sp<MtkGnss> mGnss;
+    };
+
+    // for wakelock consolidation, see above
+    static void acquireWakelockGnss();
+    static void releaseWakelockGnss();
+    static void updateWakelock();
+    static bool sWakelockHeldGnss;
+    static bool sWakelockHeldFused;
+
+    /*
+     * Cleanup for death notification
+     */
+    void handleHidlDeath();
+
+    sp<GnssXtra> mGnssXtraIface = nullptr;
+    sp<AGnssRil> mGnssRil = nullptr;
+    sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
+    sp<AGnss> mAGnssIface = nullptr;
+    sp<GnssNi> mGnssNi = nullptr;
+    /// Mtk added to specify namespace
+    sp<implementation::GnssMeasurement> mGnssMeasurement = nullptr;
+    sp<implementation::GnssNavigationMessage> mGnssNavigationMessage = nullptr;
+    /// Mtk add end
+    sp<GnssDebug> mGnssDebug = nullptr;
+    sp<GnssConfiguration> mGnssConfig = nullptr;
+    sp<GnssBatching> mGnssBatching = nullptr;
+
+    ///M: add for vzw debug hidl imlementation instance
+    sp<VzwDebug> mVzwDebug = nullptr;
+    static sem_t sSem;
+
+    sp<GnssHidlDeathRecipient> mDeathRecipient;
+
+    const GpsInterface* mGnssIface = nullptr;
+    static sp<IGnssCallback> sGnssCbIface;
+    static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
+    static bool sInterfaceExists;
+
+    // Values saved for resend
+    static uint32_t sCapabilitiesCached;
+    static uint16_t sYearOfHwCached;
+};
+
+extern "C" IMtkGnss* HIDL_FETCH_IMtkGnss(const char* name);
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace mediatek
+}  // namespace vendor
+
+#endif  // VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_MTKGNSS_H
diff --git a/src/connectivity/gps/service/1.1/NOTICE b/src/connectivity/gps/service/1.1/NOTICE
new file mode 100644
index 0000000..bf532e5
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/NOTICE
@@ -0,0 +1,182 @@
+
+Copyright (C) 2016 The Android Open Source Project
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+
+
diff --git a/src/connectivity/gps/service/1.1/OWNERS b/src/connectivity/gps/service/1.1/OWNERS
new file mode 100644
index 0000000..6c25bd7
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/OWNERS
@@ -0,0 +1,3 @@
+wyattriley@google.com
+gomo@google.com
+smalkos@google.com
diff --git a/src/connectivity/gps/service/1.1/ThreadCreationWrapper.cpp b/src/connectivity/gps/service/1.1/ThreadCreationWrapper.cpp
new file mode 100644
index 0000000..2a5638f
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/ThreadCreationWrapper.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include <ThreadCreationWrapper.h>
+
+void* threadFunc(void* arg) {
+    ThreadFuncArgs* threadArgs = reinterpret_cast<ThreadFuncArgs*>(arg);
+    threadArgs->fptr(threadArgs->args);
+    return nullptr;
+}
+
+pthread_t createPthread(const char* name,
+                        void (*start)(void*),
+                        void* arg, std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs) {
+    pthread_t threadId;
+    auto threadArgs = new ThreadFuncArgs(start, arg);
+    auto argPtr = std::unique_ptr<ThreadFuncArgs>(threadArgs);
+
+    listArgs->push_back(std::move(argPtr));
+
+    int ret = pthread_create(&threadId, nullptr, threadFunc, reinterpret_cast<void*>(
+            threadArgs));
+    if (ret != 0) {
+        ALOGE("pthread creation unsuccessful");
+    } else {
+        pthread_setname_np(threadId, name);
+    }
+    return threadId;
+}
diff --git a/src/connectivity/gps/service/1.1/ThreadCreationWrapper.h b/src/connectivity/gps/service/1.1/ThreadCreationWrapper.h
new file mode 100644
index 0000000..99c8670
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/ThreadCreationWrapper.h
@@ -0,0 +1,58 @@
+/*
+ * 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_THREADCREATIONWRAPPER_H
+#define ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
+
+#include <pthread.h>
+#include <vector>
+#include <log/log.h>
+
+typedef void (*threadEntryFunc)(void* ret);
+
+/*
+ * This class facilitates createThreadCb methods in various GNSS interfaces to wrap
+ * pthread_create() from libc since its function signature differs from what is required by the
+ * conventional GNSS HAL. The arguments passed to pthread_create() need to be on heap and not on
+ * the stack of createThreadCb.
+ */
+struct ThreadFuncArgs {
+    ThreadFuncArgs(void (*start)(void*), void* arg) : fptr(start), args(arg) {}
+
+    /* pointer to the function of type void()(void*) that needs to be wrapped */
+    threadEntryFunc fptr;
+    /* argument for fptr to be called with */
+    void* args;
+};
+
+/*
+ * This method is simply a wrapper. It is required since pthread_create() requires an entry
+ * function pointer of type void*()(void*) and the GNSS hal requires as input a function pointer of
+ * type void()(void*).
+ */
+void* threadFunc(void* arg);
+
+/*
+ * This method is called by createThreadCb with a pointer to the vector that
+ * holds the pointers to the thread arguments. The arg and start parameters are
+ * first used to create a ThreadFuncArgs object which is then saved in the
+ * listArgs parameters. The created ThreadFuncArgs object is then used to invoke
+ * threadFunc() method which in-turn invokes pthread_create.
+ */
+pthread_t createPthread(const char* name, void (*start)(void*), void* arg,
+                        std::vector<std::unique_ptr<ThreadFuncArgs>> * listArgs);
+
+#endif
diff --git a/src/connectivity/gps/service/1.1/VzwDebug.cpp b/src/connectivity/gps/service/1.1/VzwDebug.cpp
new file mode 100644
index 0000000..24ae0c2
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/VzwDebug.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "VzwDebugInterface"
+
+#include <log/log.h>
+
+#include "VzwDebug.h"
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+sp<IVzwDebugCallback> VzwDebug::sVzwDebugCbIface = nullptr;
+VzwDebugCallbacks VzwDebug::sHalVzwDeubgCb = {
+    .vzw_debug_cb = vzwDebugMessageCb,
+};
+
+
+VzwDebug::VzwDebug(const VzwDebugInterface* vzwDebugIface) : mHalVzwDebugIface(vzwDebugIface) {}
+
+
+// Methods from ::vendor::mediatek::hardware::gnss::V1_1::IVzwDebug follow.
+Return<bool> VzwDebug::init(const sp<IVzwDebugCallback>& callback)  {
+    ALOGE("%s: Vzw debug init, to set callback", __func__);
+    if (mHalVzwDebugIface == nullptr) {
+        ALOGE("%s: Vzw debug HAL interface is unavailable", __func__);
+        return false;
+    }
+
+    sVzwDebugCbIface = callback;
+
+    return (mHalVzwDebugIface->init(&sHalVzwDeubgCb) == 0);
+}
+
+
+void VzwDebug::vzwDebugMessageCb(VzwDebugData* vzw_message) {
+    if (sVzwDebugCbIface == nullptr) {
+        ALOGE("%s: Vzw Debug Callback Interface configured incorrectly", __func__);
+        return;
+    }
+
+    IVzwDebugCallback::VzwDebugData* pMsg = new IVzwDebugCallback::VzwDebugData();
+    pMsg->size = strlen(vzw_message->vzw_msg_data);
+    if (pMsg->size >= VZW_DEBUG_STRING_MAXLEN) {
+        pMsg->size = VZW_DEBUG_STRING_MAXLEN - 1;
+    }
+
+    uint8_t *dst = reinterpret_cast<uint8_t *>(&pMsg->vzw_msg_data[0]);
+    const uint8_t *src = reinterpret_cast<uint8_t *>(&vzw_message->vzw_msg_data[0]);
+    memcpy(dst, src, pMsg->size + 1);
+
+    auto ret = sVzwDebugCbIface->vzwDebugCb(*pMsg);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+    delete pMsg;
+}
+
+
+
+// Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow.
+Return<void> VzwDebug::setVzwDebugScreen(bool enabled)  {
+    if (mHalVzwDebugIface == nullptr) {
+        ALOGE("%s: Vzw debug HAL interface is unavailable", __func__);
+        return Void();
+    }
+
+    mHalVzwDebugIface->set_vzw_debug_screen(enabled);
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace mediatek
+}  // namespace vendor
diff --git a/src/connectivity/gps/service/1.1/VzwDebug.h b/src/connectivity/gps/service/1.1/VzwDebug.h
new file mode 100644
index 0000000..3a87081
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/VzwDebug.h
@@ -0,0 +1,69 @@
+/*
+ * 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 VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_VZWDEBUG_H
+#define VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_VZWDEBUG_H
+
+#include <vendor/mediatek/hardware/gnss/1.1/IVzwDebug.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <hardware/gps_mtk.h>
+
+namespace vendor {
+namespace mediatek {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::vendor::mediatek::hardware::gnss::V1_1::IVzwDebug;
+using ::vendor::mediatek::hardware::gnss::V1_1::IVzwDebugCallback;
+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;
+
+/* Interface for GNSS Debug support. */
+struct VzwDebug : public IVzwDebug {
+    VzwDebug(const VzwDebugInterface* vzwDebugIface);
+
+    // Methods from ::vendor::mediatek::hardware::gnss::V1_1::IVzwDebug follow.
+    Return<bool> init(const sp<IVzwDebugCallback>& callback) override;
+    Return<void> setVzwDebugScreen(bool enabled) override;
+
+    static void vzwDebugMessageCb(VzwDebugData* vzw_message);
+
+    static VzwDebugCallbacks sHalVzwDeubgCb;           // local call back function
+
+ private:
+    const VzwDebugInterface* mHalVzwDebugIface = nullptr;   // HAL interface pointer
+    static sp<IVzwDebugCallback> sVzwDebugCbIface;   // framework JNI callback interface
+
+};
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace mediatek
+}  // namespace vendor
+
+#endif  // VENDOR_MEDIATEK_HARDWARE_GNSS_V1_1_VZWDEBUG_H
diff --git a/src/connectivity/gps/service/1.1/android.hardware.gnss@1.1-service-mediatek.rc b/src/connectivity/gps/service/1.1/android.hardware.gnss@1.1-service-mediatek.rc
new file mode 100644
index 0000000..6486b6e
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/android.hardware.gnss@1.1-service-mediatek.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/android.hardware.gnss@1.1-service-mediatek
+    class hal
+    user system
+    group system gps
diff --git a/src/connectivity/gps/service/1.1/hardware/gps_mtk.h b/src/connectivity/gps/service/1.1/hardware/gps_mtk.h
new file mode 100644
index 0000000..b32199e
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/hardware/gps_mtk.h
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2010 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_INCLUDE_HARDWARE_GPS_MTK_H
+#define ANDROID_INCLUDE_HARDWARE_GPS_MTK_H
+
+#include <hardware/gps_internal.h>
+
+__BEGIN_DECLS
+
+// MTK extended GpsAidingData values.
+#define GPS_DELETE_HOT_STILL 0x2000
+#define GPS_DELETE_EPO      0x4000
+
+// ====================vzw debug screen API =================
+/**
+ * Name for the VZW debug interface.
+ */
+#define VZW_DEBUG_INTERFACE      "vzw-debug"
+
+#define VZW_DEBUG_STRING_MAXLEN      200
+
+/** Represents data of VzwDebugData. */
+typedef struct {
+    /** set to sizeof(VzwDebugData) */
+    size_t size;
+
+    char  vzw_msg_data[VZW_DEBUG_STRING_MAXLEN];
+} VzwDebugData;
+
+
+typedef void (* vzw_debug_callback)(VzwDebugData* vzw_message);
+
+/** Callback structure for the Vzw debug interface. */
+typedef struct {
+    vzw_debug_callback vzw_debug_cb;
+} VzwDebugCallbacks;
+
+
+/** Extended interface for VZW DEBUG support. */
+typedef struct {
+    /** set to sizeof(VzwDebugInterface) */
+    size_t          size;
+
+    /** Registers the callbacks for Vzw debug message. */
+    int  (*init)( VzwDebugCallbacks* callbacks );
+
+    /** Set Vzw debug screen enable/disable **/
+    void (*set_vzw_debug_screen)(bool enabled);
+} VzwDebugInterface;
+
+////////////////////// GNSS HIDL v1.0 ////////////////////////////
+
+/** Represents a location. */
+typedef struct {
+    GpsLocation legacyLocation;
+    /**
+    * Represents expected horizontal position accuracy, radial, in meters
+    * (68% confidence).
+    */
+    float           horizontalAccuracyMeters;
+
+    /**
+    * Represents expected vertical position accuracy in meters
+    * (68% confidence).
+    */
+    float           verticalAccuracyMeters;
+
+    /**
+    * Represents expected speed accuracy in meter per seconds
+    * (68% confidence).
+    */
+    float           speedAccuracyMetersPerSecond;
+
+    /**
+    * Represents expected bearing accuracy in degrees
+    * (68% confidence).
+    */
+    float           bearingAccuracyDegrees;
+
+} GpsLocation_ext;
+
+
+typedef struct {
+    GnssSvInfo legacySvInfo;
+
+    /// v1.0 ///
+    float carrier_frequency;
+
+} GnssSvInfo_ext;
+
+/**
+ * Represents SV status.
+ */
+typedef struct {
+    /** set to sizeof(GnssSvStatus) */
+    size_t size;
+
+    /** Number of GPS SVs currently visible, refers to the SVs stored in sv_list */
+    int num_svs;
+    /**
+     * Pointer to an array of SVs information for all GNSS constellations,
+     * except GPS, which is reported using sv_list
+     */
+    GnssSvInfo_ext gnss_sv_list[GNSS_MAX_SVS];
+
+} GnssSvStatus_ext;
+
+/**
+ * Callback with location information. Can only be called from a thread created
+ * by create_thread_cb.
+ */
+typedef void (* gps_location_ext_callback)(GpsLocation_ext* location);
+
+/**
+ * Callback with SV status information.
+ * Can only be called from a thread created by create_thread_cb.
+ */
+typedef void (* gnss_sv_status_ext_callback)(GnssSvStatus_ext* sv_info);
+
+/**
+ * The callback associated with the geofence.
+ * Parameters:
+ *      geofence_id - The id associated with the add_geofence_area.
+ *      location    - The current GPS location.
+ *      transition  - Can be one of GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED,
+ *                    GPS_GEOFENCE_UNCERTAIN.
+ *      timestamp   - Timestamp when the transition was detected.
+ *
+ * The callback should only be called when the caller is interested in that
+ * particular transition. For instance, if the caller is interested only in
+ * ENTERED transition, then the callback should NOT be called with the EXITED
+ * transition.
+ *
+ * IMPORTANT: If a transition is triggered resulting in this callback, the GPS
+ * subsystem will wake up the application processor, if its in suspend state.
+ */
+typedef void (*gps_geofence_transition_ext_callback) (int32_t geofence_id,
+        GpsLocation_ext* location, int32_t transition, GpsUtcTime timestamp);
+
+/**
+ * The callback associated with the availability of the GPS system for geofencing
+ * monitoring. If the GPS system determines that it cannot monitor geofences
+ * because of lack of reliability or unavailability of the GPS signals, it will
+ * call this callback with GPS_GEOFENCE_UNAVAILABLE parameter.
+ *
+ * Parameters:
+ *  status - GPS_GEOFENCE_UNAVAILABLE or GPS_GEOFENCE_AVAILABLE.
+ *  last_location - Last known location.
+ */
+typedef void (*gps_geofence_status_ext_callback) (int32_t status,
+        GpsLocation_ext* last_location);
+
+typedef struct {
+    gps_geofence_transition_ext_callback geofence_transition_callback;
+    gps_geofence_status_ext_callback geofence_status_callback;
+    gps_geofence_add_callback geofence_add_callback;
+    gps_geofence_remove_callback geofence_remove_callback;
+    gps_geofence_pause_callback geofence_pause_callback;
+    gps_geofence_resume_callback geofence_resume_callback;
+    gps_create_thread create_thread_cb;
+} GpsGeofenceCallbacks_ext;
+
+/** Extended interface for GPS_Geofencing support */
+typedef struct {
+   /** set to sizeof(GpsGeofencingInterface) */
+   size_t          size;
+
+   /**
+    * Opens the geofence interface and provides the callback routines
+    * to the implementation of this interface.
+    */
+   void  (*init)( GpsGeofenceCallbacks_ext* callbacks );
+
+   /**
+    * Add a geofence area. This api currently supports circular geofences.
+    * Parameters:
+    *    geofence_id - The id for the geofence. If a geofence with this id
+    *       already exists, an error value (GPS_GEOFENCE_ERROR_ID_EXISTS)
+    *       should be returned.
+    *    latitude, longtitude, radius_meters - The lat, long and radius
+    *       (in meters) for the geofence
+    *    last_transition - The current state of the geofence. For example, if
+    *       the system already knows that the user is inside the geofence,
+    *       this will be set to GPS_GEOFENCE_ENTERED. In most cases, it
+    *       will be GPS_GEOFENCE_UNCERTAIN.
+    *    monitor_transition - Which transitions to monitor. Bitwise OR of
+    *       GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and
+    *       GPS_GEOFENCE_UNCERTAIN.
+    *    notification_responsiveness_ms - Defines the best-effort description
+    *       of how soon should the callback be called when the transition
+    *       associated with the Geofence is triggered. For instance, if set
+    *       to 1000 millseconds with GPS_GEOFENCE_ENTERED, the callback
+    *       should be called 1000 milliseconds within entering the geofence.
+    *       This parameter is defined in milliseconds.
+    *       NOTE: This is not to be confused with the rate that the GPS is
+    *       polled at. It is acceptable to dynamically vary the rate of
+    *       sampling the GPS for power-saving reasons; thus the rate of
+    *       sampling may be faster or slower than this.
+    *    unknown_timer_ms - The time limit after which the UNCERTAIN transition
+    *       should be triggered. This parameter is defined in milliseconds.
+    *       See above for a detailed explanation.
+    */
+   void (*add_geofence_area) (int32_t geofence_id, double latitude, double longitude,
+       double radius_meters, int last_transition, int monitor_transitions,
+       int notification_responsiveness_ms, int unknown_timer_ms);
+
+   /**
+    * Pause monitoring a particular geofence.
+    * Parameters:
+    *   geofence_id - The id for the geofence.
+    */
+   void (*pause_geofence) (int32_t geofence_id);
+
+   /**
+    * Resume monitoring a particular geofence.
+    * Parameters:
+    *   geofence_id - The id for the geofence.
+    *   monitor_transitions - Which transitions to monitor. Bitwise OR of
+    *       GPS_GEOFENCE_ENTERED, GPS_GEOFENCE_EXITED and
+    *       GPS_GEOFENCE_UNCERTAIN.
+    *       This supersedes the value associated provided in the
+    *       add_geofence_area call.
+    */
+   void (*resume_geofence) (int32_t geofence_id, int monitor_transitions);
+
+   /**
+    * Remove a geofence area. After the function returns, no notifications
+    * should be sent.
+    * Parameter:
+    *   geofence_id - The id for the geofence.
+    */
+   void (*remove_geofence_area) (int32_t geofence_id);
+} GpsGeofencingInterface_ext;
+
+typedef struct {
+    GnssMeasurement legacyMeasurement;
+
+    /**
+     * Automatic gain control (AGC) level. AGC acts as a variable gain
+     * amplifier adjusting the power of the incoming signal. The AGC level
+     * may be used to indicate potential interference. When AGC is at a
+     * nominal level, this value must be set as 0. Higher gain (and/or lower
+     * input power) must be output as a positive number. Hence in cases of
+     * strong jamming, in the band of this signal, this value must go more
+     * negative.
+     *
+     * Note: Different hardware designs (e.g. antenna, pre-amplification, or
+     * other RF HW components) may also affect the typical output of of this
+     * value on any given hardware design in an open sky test - the
+     * important aspect of this output is that changes in this value are
+     * indicative of changes on input signal power in the frequency band for
+     * this measurement.
+     */
+    double agc_level_db;
+} GnssMeasurement_ext;
+
+/**
+ * Represents a reading of GNSS measurements. For devices where GnssSystemInfo's
+ * year_of_hw is set to 2016+, it is mandatory that these be provided, on
+ * request, when the GNSS receiver is searching/tracking signals.
+ *
+ * - Reporting of GPS constellation measurements is mandatory.
+ * - Reporting of all tracked constellations are encouraged.
+ */
+typedef struct {
+    /** set to sizeof(GnssData) */
+    size_t size;
+
+    /** Number of measurements. */
+    size_t measurement_count;
+
+    /** The array of measurements. */
+    GnssMeasurement_ext measurements[GNSS_MAX_MEASUREMENT];
+
+    /** The GPS clock time reading. */
+    GnssClock clock;
+} GnssData_ext;
+
+/**
+ * The callback for to report measurements from the HAL.
+ *
+ * Parameters:
+ *    data - A data structure containing the measurements.
+ */
+typedef void (*gnss_measurement_ext_callback) (GnssData_ext* data);
+
+typedef struct {
+    /** set to sizeof(GpsMeasurementCallbacks) */
+    size_t size;
+    gps_measurement_callback measurement_callback;
+    gnss_measurement_ext_callback gnss_measurement_callback;
+} GpsMeasurementCallbacks_ext;
+
+
+/////// Gnss debug ////
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t GnssUtcTime;
+
+typedef enum {
+    /** Ephemeris is known for this satellite. */
+    EPHEMERIS,
+    /**
+     * Ephemeris is not known, but Almanac (approximate location) is known.
+     */
+    ALMANAC_ONLY,
+    /**
+     * Both ephemeris & almanac are not known (e.g. during a cold start
+     * blind search.)
+     */
+    NOT_AVAILABLE
+} SatelliteEphemerisType;
+
+typedef enum {
+    /**
+     * The ephemeris (or almanac only) information was demodulated from the
+     * signal received on the device
+     */
+    DEMODULATED,
+    /**
+     * The ephemeris (or almanac only) information was received from a SUPL
+     * server.
+     */
+    SUPL_PROVIDED,
+    /**
+     * The ephemeris (or almanac only) information was provided by another
+     * server.
+     */
+    OTHER_SERVER_PROVIDED,
+    /**
+     * The ephemeris (or almanac only) information was provided by another
+     * method, e.g. injected via a local debug tool, from build defaults
+     * (e.g. almanac), or is from a satellite
+     * with SatelliteEphemerisType::NOT_AVAILABLE.
+     */
+    OTHER
+} SatelliteEphemerisSource;
+
+typedef enum {
+    /** The ephemeris is known good. */
+    GOOD,
+    /** The ephemeris is known bad. */
+    BAD,
+    /** The ephemeris is unknown to be good or bad. */
+    UNKNOWN
+} SatelliteEphemerisHealth;
+
+/**
+ * Provides the current best known position from any
+ * source (GNSS or injected assistance).
+ */
+typedef struct {
+    /**
+     * Validity of the data in this struct. False only if no
+     * latitude/longitude information is known.
+     */
+    bool valid;
+    /** Latitude expressed in degrees */
+    double latitudeDegrees;
+    /** Longitude expressed in degrees */
+    double longitudeDegrees;
+    /** Altitude above ellipsoid expressed in meters */
+    float altitudeMeters;
+    /** Represents horizontal speed in meters per second. */
+    float speedMetersPerSec;
+    /** Represents heading in degrees. */
+    float bearingDegrees;
+    /**
+     * Estimated horizontal accuracy of position expressed in meters,
+     * radial, 68% confidence.
+     */
+    double horizontalAccuracyMeters;
+    /**
+     * Estimated vertical accuracy of position expressed in meters, with
+     * 68% confidence.
+     */
+    double verticalAccuracyMeters;
+    /**
+     * Estimated speed accuracy in meters per second with 68% confidence.
+     */
+    double speedAccuracyMetersPerSecond;
+    /**
+     * estimated bearing accuracy degrees with 68% confidence.
+     */
+    double bearingAccuracyDegrees;
+    /**
+     * Time duration before this report that this position information was
+     * valid.  This can, for example, be a previous injected location with
+     * an age potentially thousands of seconds old, or
+     * extrapolated to the current time (with appropriately increased
+     * accuracy estimates), with a (near) zero age.
+     */
+    float ageSeconds;
+} PositionDebug;
+
+/**
+ * Provides the current best known UTC time estimate.
+ * If no fresh information is available, e.g. after a delete all,
+ * then whatever the effective defaults are on the device must be
+ * provided (e.g. Jan. 1, 2017, with an uncertainty of 5 years) expressed
+ * in the specified units.
+ */
+typedef struct {
+    /** UTC time estimate. */
+    GnssUtcTime timeEstimate;
+    /** 68% error estimate in time. */
+    float timeUncertaintyNs;
+    /**
+     * 68% error estimate in local clock drift,
+     * in nanoseconds per second (also known as parts per billion - ppb.)
+     */
+    float frequencyUncertaintyNsPerSec;
+} TimeDebug;
+
+/**
+ * Provides a single satellite info that has decoded navigation data.
+ */
+typedef struct {
+    /** Satellite vehicle ID number */
+    int16_t svid;
+    /** Defines the constellation type of the given SV. */
+    GnssConstellationType constellation;
+
+    /**
+     * Defines the standard broadcast ephemeris or almanac availability for
+     * the satellite.  To report status of predicted orbit and clock
+     * information, see the serverPrediction fields below.
+     */
+    SatelliteEphemerisType ephemerisType;
+    /** Defines the ephemeris source of the satellite. */
+    SatelliteEphemerisSource ephemerisSource;
+    /**
+     * Defines whether the satellite is known healthy
+     * (safe for use in location calculation.)
+     */
+    SatelliteEphemerisHealth ephemerisHealth;
+    /**
+     * Time duration from this report (current time), minus the
+     * effective time of the ephemeris source (e.g. TOE, TOA.)
+     * Set to 0 when ephemerisType is NOT_AVAILABLE.
+     */
+    float ephemerisAgeSeconds;
+
+    /**
+     * True if a server has provided a predicted orbit and clock model for
+     * this satellite.
+     */
+    bool serverPredictionIsAvailable;
+    /**
+     * Time duration from this report (current time) minus the time of the
+     * start of the server predicted information.  For example, a 1 day
+     * old prediction would be reported as 86400 seconds here.
+     */
+    float serverPredictionAgeSeconds;
+} SatelliteData;
+
+/**
+ * Provides a set of debug information that is filled by the GNSS chipset
+ * when the method getDebugData() is invoked.
+ */
+typedef struct {
+    /** Current best known position. */
+    PositionDebug position;
+    /** Current best know time estimate */
+    TimeDebug time;
+    /**
+     * Provides a list of the available satellite data, for all
+     * satellites and constellations the device can track,
+     * including GnssConstellationType UNKNOWN.
+     */
+    SatelliteData satelliteDataArray[GNSS_MAX_SVS];
+} DebugData;
+
+
+/** Extended interface for DEBUG support. */
+typedef struct {
+    /** set to sizeof(GpsDebugInterface) */
+    size_t          size;
+
+    /**
+     * This function should return any information that the native
+     * implementation wishes to include in a bugreport.
+     */
+    // size_t (*get_internal_state)(char* buffer, size_t bufferSize);
+    /// v1.0 ///
+    bool (*get_internal_state)(DebugData* debugData);
+} GpsDebugInterface_ext;
+
+
+////////////////////// GNSS HIDL v1.1 ////////////////////////////
+
+/**
+ * Callback for reporting driver name information.
+ */
+typedef void (* gnss_set_name_callback)(const char* name, int length);
+
+/**
+ * Callback for requesting framework NLP or Fused location injection.
+ */
+typedef void (* gnss_request_location_callback)(bool independentFromGnss);
+
+/** New GPS callback structure. */
+typedef struct {
+    /** set to sizeof(GpsCallbacks) */
+    size_t      size;
+    gps_location_ext_callback location_cb;
+    gps_status_callback status_cb;
+    gps_sv_status_callback sv_status_cb;
+    gps_nmea_callback nmea_cb;
+    gps_set_capabilities set_capabilities_cb;
+    gps_acquire_wakelock acquire_wakelock_cb;
+    gps_release_wakelock release_wakelock_cb;
+    gps_create_thread create_thread_cb;
+    gps_request_utc_time request_utc_time_cb;
+
+    gnss_set_system_info set_system_info_cb;
+    gnss_sv_status_ext_callback gnss_sv_status_cb;
+
+    /////v1.1////
+    gnss_set_name_callback set_name_cb;
+    gnss_request_location_callback request_location_cb;
+} GpsCallbacks_ext;
+
+
+/** Represents the standard GPS interface. */
+typedef struct {
+    /** set to sizeof(GpsInterface) */
+    size_t          size;
+    /**
+     * Opens the interface and provides the callback routines
+     * to the implementation of this interface.
+     */
+    /// v1.0 ///
+//    int   (*init)( GpsCallbacks* callbacks );
+    /// v1.1 ///
+    int   (*init)( GpsCallbacks_ext* callbacks );
+
+    /** Starts navigating. */
+    int   (*start)( void );
+
+    /** Stops navigating. */
+    int   (*stop)( void );
+
+    /** Closes the interface. */
+    void  (*cleanup)( void );
+
+    /** Injects the current time. */
+    int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
+                         int uncertainty);
+
+    /**
+     * Injects current location from another location provider (typically cell
+     * ID). Latitude and longitude are measured in degrees expected accuracy is
+     * measured in meters
+     */
+    int  (*inject_location)(double latitude, double longitude, float accuracy);
+
+    /**
+     * Specifies that the next call to start will not use the
+     * information defined in the flags. GPS_DELETE_ALL is passed for
+     * a cold start.
+     */
+    void  (*delete_aiding_data)(GpsAidingData flags);
+
+    /**
+     * min_interval represents the time between fixes in milliseconds.
+     * preferred_accuracy represents the requested fix accuracy in meters.
+     * preferred_time represents the requested time to first fix in milliseconds.
+     *
+     * 'mode' parameter should be one of GPS_POSITION_MODE_MS_BASED
+     * or GPS_POSITION_MODE_STANDALONE.
+     * It is allowed by the platform (and it is recommended) to fallback to
+     * GPS_POSITION_MODE_MS_BASED if GPS_POSITION_MODE_MS_ASSISTED is passed in, and
+     * GPS_POSITION_MODE_MS_BASED is supported.
+     */
+     /// v1.0 ///
+//    int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+//            uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
+    /// v1.1 ///
+    int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
+            uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time,
+            bool lowPowerMode);
+
+
+    /** Get a pointer to extension information. */
+    const void* (*get_extension)(const char* name);
+
+    /// v1.1 ///
+    int  (*inject_fused_location)(double latitude, double longitude, float accuracy);
+
+} GpsInterface_ext;
+
+
+/**
+ * Extended interface for GPS Measurements support.
+ */
+typedef struct {
+    /** Set to sizeof(GpsMeasurementInterface_ext) */
+    size_t size;
+
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     * After a successful call to 'init' the HAL must begin to provide updates at its own phase.
+     *
+     * Status:
+     *    GPS_MEASUREMENT_OPERATION_SUCCESS
+     *    GPS_MEASUREMENT_ERROR_ALREADY_INIT - if a callback has already been registered without a
+     *              corresponding call to 'close'
+     *    GPS_MEASUREMENT_ERROR_GENERIC - if any other error occurred, it is expected that the HAL
+     *              will not generate any updates upon returning this error code.
+     */
+    /// v1.0 ///
+//    int (*init) (GpsMeasurementCallbacks* callbacks);
+    /// v1.1 ///
+    int (*init) (GpsMeasurementCallbacks_ext* callbacks, bool enableFullTracking);
+
+    /**
+     * Stops updates from the HAL, and unregisters the callback routines.
+     * After a call to stop, the previously registered callbacks must be considered invalid by the
+     * HAL.
+     * If stop is invoked without a previous 'init', this function should perform no work.
+     */
+    void (*close) ();
+
+} GpsMeasurementInterface_ext;
+
+
+/**
+ * Interface for passing GNSS configuration contents from platform to HAL.
+ */
+typedef struct {
+    /** Set to sizeof(GnssConfigurationInterface) */
+    size_t size;
+
+    /**
+     * Deliver GNSS configuration contents to HAL.
+     * Parameters:
+     *     config_data - a pointer to a char array which holds what usually is expected from
+                         file(/etc/gps.conf), i.e., a sequence of UTF8 strings separated by '\n'.
+     *     length - total number of UTF8 characters in configuraiton data.
+     *
+     * IMPORTANT:
+     *      GPS HAL should expect this function can be called multiple times. And it may be
+     *      called even when GpsLocationProvider is already constructed and enabled. GPS HAL
+     *      should maintain the existing requests for various callback regardless the change
+     *      in configuration data.
+     */
+    void (*configuration_update) (const char* config_data, int32_t length);
+
+   //// v1.1 ////
+   void (*setBlacklist) (long long* blacklist, int32_t size);
+} GnssConfigurationInterface_ext;
+
+struct gps_device_t_ext {
+    struct hw_device_t common;
+
+    /**
+     * Set the provided lights to the provided values.
+     *
+     * Returns: 0 on succes, error code on failure.
+     */
+    const GpsInterface_ext* (*get_gps_interface)(struct gps_device_t_ext* dev);
+};
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_HARDWARE_GPS_MTK_H */
+
diff --git a/src/connectivity/gps/service/1.1/service.cpp b/src/connectivity/gps/service/1.1/service.cpp
new file mode 100644
index 0000000..bdb84cb
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/service.cpp
@@ -0,0 +1,17 @@
+#define LOG_TAG "vendor.mediatek.hardware.gnss@1.1-service"
+
+#include <android/hardware/gnss/1.1/IGnss.h>
+
+#include <hidl/LegacySupport.h>
+
+#include <binder/ProcessState.h>
+
+using android::hardware::gnss::V1_1::IGnss;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    // The GNSS HAL may communicate to other vendor components via
+    // /dev/vndbinder
+    android::ProcessState::initWithDriver("/dev/vndbinder");
+    return defaultPassthroughServiceImplementation<IGnss>();
+}
diff --git a/src/connectivity/gps/service/1.1/vendor.mediatek.hardware.gnss@1.1-service.rc b/src/connectivity/gps/service/1.1/vendor.mediatek.hardware.gnss@1.1-service.rc
new file mode 100644
index 0000000..40547f9
--- /dev/null
+++ b/src/connectivity/gps/service/1.1/vendor.mediatek.hardware.gnss@1.1-service.rc
@@ -0,0 +1,4 @@
+service gnss_service /vendor/bin/hw/vendor.mediatek.hardware.gnss@1.1-service
+    class main
+    user system
+    group system gps
diff --git a/src/connectivity/gps/service/Android.backup b/src/connectivity/gps/service/Android.backup
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/src/connectivity/gps/service/Android.backup
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/src/connectivity/gps/service/Android.bp b/src/connectivity/gps/service/Android.bp
new file mode 100644
index 0000000..bbb3e4b
--- /dev/null
+++ b/src/connectivity/gps/service/Android.bp
@@ -0,0 +1,4 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+]
diff --git a/src/connectivity/gps/service/Android.mk b/src/connectivity/gps/service/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/src/connectivity/gps/service/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)