FP4: Import GPS HAL from LA.UM.9.12.r1-13800-SMxx50.0

Change-Id: Ia11d98eaa5191f923299950e8eb166d0e8fd67f8
diff --git a/gps/android/1.1/GnssConfiguration.cpp b/gps/android/1.1/GnssConfiguration.cpp
new file mode 100644
index 0000000..ad255d1
--- /dev/null
+++ b/gps/android/1.1/GnssConfiguration.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution
+ */
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "LocSvc_GnssConfigurationInterface"
+
+#include <log_util.h>
+#include "Gnss.h"
+#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
+GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
+}
+
+// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setSuplEs(bool enabled)  {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
+    config.suplEmergencyServices = (enabled ?
+            GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_YES :
+            GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO);
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplVersion(uint32_t version)  {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
+    switch (version) {
+        case 0x00020004:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_4;
+            break;
+        case 0x00020002:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_2;
+            break;
+        case 0x00020000:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_2_0_0;
+            break;
+        case 0x00010000:
+            config.suplVersion = GNSS_CONFIG_SUPL_VERSION_1_0_0;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid version: 0x%x.", __FUNCTION__, version);
+            return false;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setSuplMode(uint8_t mode)  {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
+    switch (mode) {
+        case 0:
+            config.suplModeMask = 0; // STANDALONE ONLY
+            break;
+        case 1:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT;
+            break;
+        case 2:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+            break;
+        case 3:
+            config.suplModeMask = GNSS_CONFIG_SUPL_MODE_MSB_BIT | GNSS_CONFIG_SUPL_MODE_MSA_BIT;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid mode: %d.", __FUNCTION__, mode);
+            return false;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfileMask) {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config = {};
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
+    config.lppProfileMask = GNSS_CONFIG_LPP_PROFILE_RRLP_ON_LTE; //default
+
+    if (lppProfileMask & (1<<0)) {
+        config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_BIT;
+    }
+    if (lppProfileMask & (1<<1)) {
+        config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_BIT;
+    }
+    if (lppProfileMask & (1<<2)) {
+        config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_USER_PLANE_OVER_NR5G_SA_BIT;
+    }
+    if (lppProfileMask & (1<<3)) {
+        config.lppProfileMask |= GNSS_CONFIG_LPP_PROFILE_CONTROL_PLANE_OVER_NR5G_SA_BIT;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+
+    config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
+    if (protocol & (1<<0)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRC_CONTROL_PLANE_BIT;
+    }
+    if (protocol & (1<<1)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_RRLP_USER_PLANE_BIT;
+    }
+    if (protocol & (1<<2)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_USER_PLANE_BIT;
+    }
+    if (protocol & (1<<3)) {
+        config.aGlonassPositionProtocolMask |= GNSS_CONFIG_LLP_CONTROL_PLANE_BIT;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
+    switch (lock) {
+        case 0:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_NONE;
+            break;
+        case 1:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO;
+            break;
+        case 2:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_NI;
+            break;
+        case 3:
+            config.gpsLock = GNSS_CONFIG_GPS_LOCK_MO_AND_NI;
+            break;
+        default:
+            LOC_LOGE("%s]: invalid lock: %d.", __FUNCTION__, lock);
+            return false;
+    }
+
+    return mGnss->updateConfiguration(config);
+}
+
+Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
+    if (mGnss == nullptr) {
+        LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
+        return false;
+    }
+
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
+    config.emergencyPdnForEmergencySupl = (enabled ?
+            GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_YES :
+            GNSS_CONFIG_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_NO);
+
+    return mGnss->updateConfiguration(config);
+}
+
+// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
+Return<bool> GnssConfiguration::setBlacklist(
+            const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
+
+    ENTRY_LOG_CALLFLOW();
+    if (nullptr == mGnss) {
+        LOC_LOGe("mGnss is null");
+        return false;
+    }
+
+    // blValid is true if blacklist is empty, i.e. clearing the BL;
+    // if blacklist is not empty, blValid is initialied to false, and later
+    // updated in the for loop to become true only if there is at least
+    // one {constellation, svid} in the list that is valid.
+    bool blValid = (0 == blacklist.size());
+    GnssConfig config;
+    memset(&config, 0, sizeof(GnssConfig));
+    config.size = sizeof(GnssConfig);
+    config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+    config.blacklistedSvIds.clear();
+
+    GnssSvIdSource source = {};
+    for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+        // Set blValid true if any one source is valid
+        blValid = setBlacklistedSource(source, blacklist[idx]) || blValid;
+        config.blacklistedSvIds.push_back(source);
+    }
+
+    // Update configuration only if blValid is true
+    // i.e. only if atleast one source is valid for blacklisting
+    return (blValid && mGnss->updateConfiguration(config));
+}
+
+bool GnssConfiguration::setBlacklistedSource(
+        GnssSvIdSource& copyToSource,
+        const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+    bool retVal = true;
+    uint16_t svIdOffset = 0;
+    copyToSource.size = sizeof(GnssSvIdSource);
+    copyToSource.svId = copyFromSource.svid;
+
+    switch(copyFromSource.constellation) {
+    case GnssConstellationType::GPS:
+        copyToSource.constellation = GNSS_SV_TYPE_GPS;
+        LOC_LOGe("GPS SVs can't be blacklisted.");
+        retVal = false;
+        break;
+    case GnssConstellationType::SBAS:
+        copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+        LOC_LOGe("SBAS SVs can't be blacklisted.");
+        retVal = false;
+        break;
+    case GnssConstellationType::GLONASS:
+        copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+        svIdOffset = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID - 1;
+        break;
+    case GnssConstellationType::QZSS:
+        copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+        svIdOffset = 0;
+        break;
+    case GnssConstellationType::BEIDOU:
+        copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+        svIdOffset = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID - 1;
+        break;
+    case GnssConstellationType::GALILEO:
+        copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+        svIdOffset = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID - 1;
+        break;
+    default:
+        copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+        LOC_LOGe("Invalid constellation %d", copyFromSource.constellation);
+        retVal = false;
+        break;
+    }
+
+    if (copyToSource.svId > 0 && svIdOffset > 0) {
+        copyToSource.svId += svIdOffset;
+    }
+
+    return retVal;
+}
+
+}  // namespace implementation
+}  // namespace V1_1
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android