diff --git a/android/AGnss.cpp b/android/AGnss.cpp new file mode 100644 index 00000000..3b40e604 --- /dev/null +++ b/android/AGnss.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LocSvc_AGnssInterface" + +#include +#include "Gnss.h" +#include "AGnss.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +AGnss::AGnss(Gnss* gnss) : mGnss(gnss) { +} + +Return AGnss::setServer(IAGnssCallback::AGnssType type, + const hidl_string& hostname, + int32_t port) { + 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_SET_ASSISTANCE_DATA_VALID_BIT; + config.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer); + if (type == IAGnssCallback::AGnssType::TYPE_SUPL) { + config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL; + } else if (type == IAGnssCallback::AGnssType::TYPE_C2K) { + config.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K; + } else { + LOC_LOGE("%s]: invalid AGnssType: %d", __FUNCTION__, static_cast(type)); + return false; + } + config.assistanceServer.hostName = strdup(hostname.c_str()); + config.assistanceServer.port = port; + return mGnss->updateConfiguration(config); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/AGnss.h b/android/AGnss.h new file mode 100644 index 00000000..54775c16 --- /dev/null +++ b/android/AGnss.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H +#define ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H + +#include +#include + +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; + +struct Gnss; +struct AGnss : public IAGnss { + AGnss(Gnss* gnss); + ~AGnss() = default; + /* + * Methods from ::android::hardware::gnss::V1_0::IAGnss interface follow. + * These declarations were generated from IAGnss.hal. + */ + inline Return setCallback(const sp& /*callback*/) override { + return Void(); + } + + inline Return dataConnClosed() override { + return false; + } + + inline Return dataConnFailed() override { + return false; + } + + inline Return dataConnOpen(const hidl_string& /*apn*/, + IAGnss::ApnIpType /*apnIpType*/) override { + return false; + } + + Return setServer(IAGnssCallback::AGnssType type, + const hidl_string& hostname, int32_t port) override; + + + private: + Gnss* mGnss = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_AGNSS_H diff --git a/android/Android.mk b/android/Android.mk index d36b4712..e359e88f 100644 --- a/android/Android.mk +++ b/android/Android.mk @@ -1,56 +1,76 @@ -ifneq ($(BUILD_TINY_ANDROID),true) - LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) - -LOCAL_MODULE := gps.$(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE) +LOCAL_MODULE := android.hardware.gnss@1.0-impl-qti LOCAL_MODULE_OWNER := qti +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SRC_FILES := \ + AGnss.cpp \ + Gnss.cpp \ + GnssBatching.cpp \ + GnssGeofencing.cpp \ + GnssMeasurement.cpp \ + GnssNi.cpp \ + GnssConfiguration.cpp \ -LOCAL_MODULE_TAGS := optional +LOCAL_SRC_FILES += \ + location_api/LocationUtil.cpp \ + location_api/GnssAPIClient.cpp \ + location_api/GeofenceAPIClient.cpp \ + location_api/FlpAPIClient.cpp \ + location_api/GnssMeasurementAPIClient.cpp \ -## Libs +LOCAL_C_INCLUDES:= \ + $(LOCAL_PATH)/location_api \ + $(TARGET_OUT_HEADERS)/gps.utils \ + $(TARGET_OUT_HEADERS)/libloc_core \ + $(TARGET_OUT_HEADERS)/libloc_pla \ + $(TARGET_OUT_HEADERS)/liblocation_api \ LOCAL_SHARED_LIBRARIES := \ - libutils \ - libcutils \ liblog \ + libhidlbase \ + libhidltransport \ + libhwbinder \ + libutils \ + android.hardware.gnss@1.0 \ + +LOCAL_SHARED_LIBRARIES += \ libloc_core \ libgps.utils \ libdl \ libloc_pla \ liblocation_api \ -LOCAL_SRC_FILES += \ - gps.c \ - loc.cpp \ - loc_geofence.cpp \ - GnssAPIClient.cpp \ - GeofenceAPIClient.cpp \ +include $(BUILD_SHARED_LIBRARY) -LOCAL_CFLAGS += \ - -Wunused-parameter \ - -fno-short-enums \ - -D_ANDROID_ \ +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.gnss@1.0-service-qti +LOCAL_MODULE_OWNER := qti +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc +LOCAL_SRC_FILES := \ + service.cpp \ -ifeq ($(TARGET_BUILD_VARIANT),user) - LOCAL_CFLAGS += -DTARGET_BUILD_VARIANT_USER -endif - -ifeq ($(TARGET_USES_QCOM_BSP), true) -LOCAL_CFLAGS += -DTARGET_USES_QCOM_BSP -endif - -## Includes LOCAL_C_INCLUDES:= \ + $(LOCAL_PATH)/location_api \ $(TARGET_OUT_HEADERS)/gps.utils \ $(TARGET_OUT_HEADERS)/libloc_core \ $(TARGET_OUT_HEADERS)/libloc_pla \ $(TARGET_OUT_HEADERS)/liblocation_api \ -LOCAL_PRELINK_MODULE := false -LOCAL_MODULE_RELATIVE_PATH := hw -include $(BUILD_SHARED_LIBRARY) +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libcutils \ + libdl \ + libbase \ + libutils \ -endif # not BUILD_TINY_ANDROID +LOCAL_SHARED_LIBRARIES += \ + libhwbinder \ + libhidlbase \ + libhidltransport \ + android.hardware.gnss@1.0 \ + +include $(BUILD_EXECUTABLE) diff --git a/android/Gnss.cpp b/android/Gnss.cpp new file mode 100644 index 00000000..1412883a --- /dev/null +++ b/android/Gnss.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LocSvc_GnssInterface" + +#include +#include +#include "Gnss.h" +typedef void* (getLocationInterface)(); + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void Gnss::GnssDeathRecipient::serviceDied(uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(cookie), &who); + if (mGnss != nullptr) { + mGnss->stop(); + mGnss->cleanup(); + } +} + +Gnss::Gnss() { + ENTRY_LOG_CALLFLOW(); + // clear pending GnssConfig + memset(&mPendingConfig, 0, sizeof(GnssConfig)); + + mGnssDeathRecipient = new GnssDeathRecipient(this); +} + +Gnss::~Gnss() { + ENTRY_LOG_CALLFLOW(); + if (mApi != nullptr) { + delete mApi; + mApi = nullptr; + } +} + +GnssAPIClient* Gnss::getApi() { + if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) { + mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface); + if (mApi == nullptr) { + LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__); + return mApi; + } + + if (mPendingConfig.size == sizeof(GnssConfig)) { + // we have pending GnssConfig + mApi->gnssConfigurationUpdate(mPendingConfig); + // clear size to invalid mPendingConfig + mPendingConfig.size = 0; + if (mPendingConfig.assistanceServer.hostName != nullptr) { + free((void*)mPendingConfig.assistanceServer.hostName); + } + } + } + if (mApi == nullptr) { + LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__); + } + return mApi; +} + +GnssInterface* Gnss::getGnssInterface() { + static bool getGnssInterfaceFailed = false; + if (nullptr == mGnssInterface && !getGnssInterfaceFailed) { + LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__); + getLocationInterface* getter = NULL; + const char *error; + dlerror(); + void *handle = dlopen("libgnss.so", RTLD_NOW); + if (NULL == handle || (error = dlerror()) != NULL) { + LOC_LOGW("dlopen for libgnss.so failed, error = %s", error); + } else { + getter = (getLocationInterface*)dlsym(handle, "getGnssInterface"); + if ((error = dlerror()) != NULL) { + LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error); + getter = NULL; + } + } + + if (NULL == getter) { + getGnssInterfaceFailed = true; + } else { + mGnssInterface = (GnssInterface*)(*getter)(); + } + } + return mGnssInterface; +} + +Return Gnss::setCallback(const sp& callback) { + ENTRY_LOG_CALLFLOW(); + if (mGnssCbIface != nullptr) { + mGnssCbIface->unlinkToDeath(mGnssDeathRecipient); + } + mGnssCbIface = callback; + if (mGnssCbIface != nullptr) { + mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/); + } + + GnssAPIClient* api = getApi(); + if (api != nullptr) { + api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); + api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); + } + return true; +} + +Return Gnss::setGnssNiCb(const sp& callback) { + ENTRY_LOG_CALLFLOW(); + mGnssNiCbIface = callback; + GnssAPIClient* api = getApi(); + if (api != nullptr) { + api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface); + } + return true; +} + +Return Gnss::updateConfiguration(GnssConfig& gnssConfig) { + ENTRY_LOG_CALLFLOW(); + GnssAPIClient* api = getApi(); + if (api) { + api->locAPIGnssUpdateConfig(gnssConfig); + } else if (gnssConfig.flags != 0) { + // api is not ready yet, update mPendingConfig with gnssConfig + mPendingConfig.size = sizeof(GnssConfig); + + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT; + mPendingConfig.gpsLock = gnssConfig.gpsLock; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT; + mPendingConfig.suplVersion = gnssConfig.suplVersion; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT; + mPendingConfig.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer); + mPendingConfig.assistanceServer.type = gnssConfig.assistanceServer.type; + if (mPendingConfig.assistanceServer.hostName != nullptr) { + free((void*)mPendingConfig.assistanceServer.hostName); + mPendingConfig.assistanceServer.hostName = + strdup(gnssConfig.assistanceServer.hostName); + } + mPendingConfig.assistanceServer.port = gnssConfig.assistanceServer.port; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; + mPendingConfig.lppProfile = gnssConfig.lppProfile; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; + mPendingConfig.lppeControlPlaneMask = gnssConfig.lppeControlPlaneMask; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT; + mPendingConfig.lppeUserPlaneMask = gnssConfig.lppeUserPlaneMask; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT; + mPendingConfig.aGlonassPositionProtocolMask = gnssConfig.aGlonassPositionProtocolMask; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT; + mPendingConfig.emergencyPdnForEmergencySupl = gnssConfig.emergencyPdnForEmergencySupl; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT; + mPendingConfig.suplEmergencyServices = gnssConfig.suplEmergencyServices; + } + if (gnssConfig.flags & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) { + mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT; + mPendingConfig.suplModeMask = gnssConfig.suplModeMask; + } + } + return true; +} + +Return Gnss::start() { + ENTRY_LOG_CALLFLOW(); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + retVal = api->gnssStart(); + } + return retVal; +} + +Return Gnss::stop() { + ENTRY_LOG_CALLFLOW(); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + retVal = api->gnssStop(); + } + return retVal; +} + +Return Gnss::cleanup() { + ENTRY_LOG_CALLFLOW(); + + if (mApi != nullptr) { + mApi->locAPIDisable(); + } + + return Void(); +} + +Return Gnss::injectLocation(double latitudeDegrees, + double longitudeDegrees, + float accuracyMeters) { + ENTRY_LOG_CALLFLOW(); + GnssInterface* gnssInterface = getGnssInterface(); + if (nullptr != gnssInterface) { + gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters); + return true; + } else { + return false; + } +} + +Return Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, + int32_t uncertaintyMs) { + ENTRY_LOG_CALLFLOW(); + GnssInterface* gnssInterface = getGnssInterface(); + if (nullptr != gnssInterface) { + gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs); + return true; + } else { + return false; + } +} + +Return Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) { + ENTRY_LOG_CALLFLOW(); + GnssAPIClient* api = getApi(); + if (api) { + api->gnssDeleteAidingData(aidingDataFlags); + } + return Void(); +} + +Return Gnss::setPositionMode(IGnss::GnssPositionMode mode, + IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, + uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs) { + ENTRY_LOG_CALLFLOW(); + bool retVal = false; + GnssAPIClient* api = getApi(); + if (api) { + retVal = api->gnssSetPositionMode(mode, recurrence, minIntervalMs, + preferredAccuracyMeters, preferredTimeMs); + } + return retVal; +} + +Return> Gnss::getExtensionAGnss() { + ENTRY_LOG_CALLFLOW(); + mAGnssIface = new AGnss(this); + return mAGnssIface; +} + +Return> Gnss::getExtensionGnssNi() { + ENTRY_LOG_CALLFLOW(); + mGnssNi = new GnssNi(this); + return mGnssNi; +} + +Return> Gnss::getExtensionGnssMeasurement() { + ENTRY_LOG_CALLFLOW(); + mGnssMeasurement = new GnssMeasurement(); + return mGnssMeasurement; +} + +Return> Gnss::getExtensionGnssConfiguration() { + ENTRY_LOG_CALLFLOW(); + mGnssConfig = new GnssConfiguration(this); + return mGnssConfig; +} + +Return> Gnss::getExtensionGnssGeofencing() { + ENTRY_LOG_CALLFLOW(); + mGnssGeofencingIface = new GnssGeofencing(); + return mGnssGeofencingIface; +} + +Return> Gnss::getExtensionGnssBatching() { + mGnssBatching = new GnssBatching(); + return mGnssBatching; +} + +IGnss* HIDL_FETCH_IGnss(const char* hal) { + ENTRY_LOG_CALLFLOW(); + IGnss* iface = nullptr; + iface = new Gnss(); + if (iface == nullptr) { + LOC_LOGE("%s]: failed to get %s", __FUNCTION__, hal); + } + return iface; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/Gnss.h b/android/Gnss.h new file mode 100644 index 00000000..b338b08e --- /dev/null +++ b/android/Gnss.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSS_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +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; + +struct Gnss : public IGnss { + Gnss(); + ~Gnss(); + + // registerAsService will call interfaceChain to determine the version of service + /* comment this out until we know really how to manipulate hidl version + using interfaceChain_cb = std::function< + void(const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& descriptors)>; + virtual ::android::hardware::Return interfaceChain(interfaceChain_cb _hidl_cb) override { + _hidl_cb({ + "android.hardware.gnss@1.1::IGnss", + ::android::hidl::base::V1_0::IBase::descriptor, + }); + return ::android::hardware::Void(); + } + */ + + /* + * Methods from ::android::hardware::gnss::V1_0::IGnss follow. + * These declarations were generated from Gnss.hal. + */ + Return setCallback(const sp& callback) override; + Return start() override; + Return stop() override; + Return cleanup() override; + Return injectLocation(double latitudeDegrees, + double longitudeDegrees, + float accuracyMeters) override; + Return injectTime(int64_t timeMs, + int64_t timeReferenceMs, + int32_t uncertaintyMs) override; + Return deleteAidingData(IGnss::GnssAidingData aidingDataFlags) override; + Return setPositionMode(IGnss::GnssPositionMode mode, + IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, + uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs) override; + Return> getExtensionAGnss() override; + Return> getExtensionGnssNi() override; + Return> getExtensionGnssMeasurement() override; + Return> getExtensionGnssConfiguration() override; + Return> getExtensionGnssGeofencing() override; + Return> getExtensionGnssBatching() override; + + inline Return> getExtensionAGnssRil() override { + return nullptr; + } + + inline Return> getExtensionGnssNavigationMessage() override { + return nullptr; + } + + inline Return> getExtensionXtra() override { + return nullptr; + } + + inline Return> getExtensionGnssDebug() override { + return nullptr; + } + + // These methods are not part of the IGnss base class. + GnssAPIClient* getApi(); + Return setGnssNiCb(const sp& niCb); + Return updateConfiguration(GnssConfig& gnssConfig); + GnssInterface* getGnssInterface(); + + private: + struct GnssDeathRecipient : hidl_death_recipient { + GnssDeathRecipient(sp gnss) : mGnss(gnss) { + } + ~GnssDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnss; + }; + + private: + sp mGnssDeathRecipient = nullptr; + + sp mAGnssIface = nullptr; + sp mGnssNi = nullptr; + sp mGnssMeasurement = nullptr; + sp mGnssConfig = nullptr; + sp mGnssGeofencingIface = nullptr; + sp mGnssBatching = nullptr; + + GnssAPIClient* mApi = nullptr; + sp mGnssCbIface = nullptr; + sp mGnssNiCbIface = nullptr; + GnssConfig mPendingConfig; + GnssInterface* mGnssInterface = nullptr; +}; + +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_1_GNSS_H diff --git a/android/GnssAPIClient.cpp b/android/GnssAPIClient.cpp deleted file mode 100644 index 915a82e7..00000000 --- a/android/GnssAPIClient.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#define LOG_NDDEBUG 0 -#define LOG_TAG "LocSvc_GnssAPIClient" - -#include -#include - -#include "GnssAPIClient.h" - -static void convertGpsLocation(Location& in, GpsLocation& out); -static void convertGpsSvStatus(GnssSvNotification& in, GpsSvStatus& out); -static void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out); -static void convertGnssSvStatus(GnssSvNotification& in, GnssSvStatus& out); -static void convertGpsMeasurement(GnssMeasurementsData& in, GpsMeasurement& out); -static void convertGpsClock(GnssMeasurementsClock& in, GpsClock& out); -static void convertGpsData(GnssMeasurementsNotification& in, GpsData& out); -static void convertGnssClock(GnssMeasurementsClock& in, GnssClock& out); -static void convertGnssData(GnssMeasurementsNotification& in, GnssData& out); - -GnssAPIClient::GnssAPIClient(GpsCallbacks* gpsCb, - GpsNiCallbacks* niCb, - GpsMeasurementCallbacks* measurementCb) : - LocationAPIClientBase(), - mGpsCallbacks(nullptr), - mGpsNiCallbacks(nullptr), - mLocationCapabilitiesMask(0), - mGpsMeasurementCallbacks(nullptr) -{ - LOC_LOGD("%s]: (%p %p %p)", __func__, gpsCb, niCb, measurementCb); - pthread_mutex_init(&mLock, nullptr); - - // set default LocationOptions. - memset(&mLocationOptions, 0, sizeof(LocationOptions)); - mLocationOptions.size = sizeof(LocationOptions); - mLocationOptions.minInterval = 1000; - mLocationOptions.minDistance = 0; - mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; - - gnssUpdateCallbacks(gpsCb, niCb, measurementCb); -} - -GnssAPIClient::~GnssAPIClient() -{ - LOC_LOGD("%s]: ()", __func__); - pthread_mutex_destroy(&mLock); -} - -// for GpsInterface -void GnssAPIClient::gnssUpdateCallbacks(GpsCallbacks* gpsCb, - GpsNiCallbacks* niCb, - GpsMeasurementCallbacks* measurementCb) -{ - LOC_LOGD("%s]: (%p %p %p)", __func__, gpsCb, niCb, measurementCb); - - mGpsCallbacks = gpsCb; - mGpsNiCallbacks = niCb; - mGpsMeasurementCallbacks = measurementCb; - - LocationCallbacks locationCallbacks; - locationCallbacks.size = sizeof(LocationCallbacks); - - locationCallbacks.trackingCb = nullptr; - if (mGpsCallbacks && mGpsCallbacks->location_cb) { - locationCallbacks.trackingCb = [this](Location location) { - onTrackingCb(location); - }; - } - - locationCallbacks.batchingCb = nullptr; - locationCallbacks.geofenceBreachCb = nullptr; - locationCallbacks.geofenceStatusCb = nullptr; - locationCallbacks.gnssLocationInfoCb = nullptr; - - locationCallbacks.gnssNiCb = nullptr; - if (mGpsNiCallbacks && mGpsNiCallbacks->notify_cb) { - locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) { - onGnssNiCb(id, gnssNiNotification); - }; - } - - locationCallbacks.gnssSvCb = nullptr; - if (mGpsCallbacks && mGpsCallbacks->sv_status_cb) { - locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { - onGnssSvCb(gnssSvNotification); - }; - } - - locationCallbacks.gnssNmeaCb = nullptr; - if (mGpsCallbacks && mGpsCallbacks->nmea_cb) { - locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { - onGnssNmeaCb(gnssNmeaNotification); - }; - } - - locationCallbacks.gnssMeasurementsCb = nullptr; - if (mGpsMeasurementCallbacks && - (mGpsMeasurementCallbacks->measurement_callback || - mGpsMeasurementCallbacks->gnss_measurement_callback)) { - locationCallbacks.gnssMeasurementsCb = - [this](GnssMeasurementsNotification gnssMeasurementsNotification) { - onGnssMeasurementsCb(gnssMeasurementsNotification); - }; - } - - locAPISetCallbacks(locationCallbacks); -} - -int GnssAPIClient::gnssStart() -{ - LOC_LOGD("%s]: ()", __func__); - int retVal = 0; - locAPIStartTracking(mLocationOptions); - return retVal; -} - -int GnssAPIClient::gnssStop() -{ - LOC_LOGD("%s]: ()", __func__); - int retVal = 0; - locAPIStopTracking(); - return retVal; -} - -void GnssAPIClient::gnssDeleteAidingData(GpsAidingData f) -{ - LOC_LOGD("%s]: (%02x)", __func__, f); - GnssAidingData data; - memset(&data, 0, sizeof (GnssAidingData)); - data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS | - GNSS_AIDING_DATA_SV_TYPE_GLONASS | - GNSS_AIDING_DATA_SV_TYPE_QZSS | - GNSS_AIDING_DATA_SV_TYPE_BEIDOU | - GNSS_AIDING_DATA_SV_TYPE_GALILEO; - - if (f == GPS_DELETE_ALL) - data.deleteAll = true; - else { - if (f & GPS_DELETE_EPHEMERIS) data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS; - if (f & GPS_DELETE_ALMANAC) data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC; - if (f & GPS_DELETE_POSITION) data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION; - if (f & GPS_DELETE_TIME) data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME; - if (f & GPS_DELETE_IONO) data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE; - if (f & GPS_DELETE_UTC) data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC; - if (f & GPS_DELETE_HEALTH) data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH; - if (f & GPS_DELETE_SVDIR) data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION; - if (f & GPS_DELETE_SVSTEER) data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER; - if (f & GPS_DELETE_SADATA) data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA; - if (f & GPS_DELETE_RTI) data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI; - if (f & GPS_DELETE_CELLDB_INFO) data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB; - } - locAPIGnssDeleteAidingData(data); -} - -int GnssAPIClient::gnssSetPositionMode(GpsPositionMode mode, GpsPositionRecurrence recurrence, - uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time) -{ - LOC_LOGD("%s]: (%d %d %d %d %d)", __func__, - mode, recurrence, min_interval, preferred_accuracy, preferred_time); - int retVal = 0; - memset(&mLocationOptions, 0, sizeof(LocationOptions)); - mLocationOptions.size = sizeof(LocationOptions); - mLocationOptions.minInterval = min_interval; - mLocationOptions.minDistance = preferred_accuracy; - if (mode == GPS_POSITION_MODE_STANDALONE) - mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; - else if (mode == GPS_POSITION_MODE_MS_BASED) - mLocationOptions.mode = GNSS_SUPL_MODE_MSB; - else if (mode == GPS_POSITION_MODE_MS_ASSISTED) - mLocationOptions.mode = GNSS_SUPL_MODE_MSA; - return retVal; -} - -// for AGpsInterface -void GnssAPIClient::gnssAgnssSetServer(AGpsType type, const char *hostname, int port) -{ - LOC_LOGD("%s]: (%d %s %d)", __func__, type, hostname, port); - GnssConfig data; - memset(&data, 0, sizeof(GnssConfig)); - data.size = sizeof(GnssConfig); - data.flags |= GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT; - - memset(&data.assistanceServer, 0, sizeof(GnssConfigSetAssistanceServer)); - data.assistanceServer.size = sizeof(GnssConfigSetAssistanceServer); - if (type == AGPS_TYPE_SUPL) - data.assistanceServer.type = GNSS_ASSISTANCE_TYPE_SUPL; - else if (type == AGPS_TYPE_C2K) - data.assistanceServer.type = GNSS_ASSISTANCE_TYPE_C2K; - data.assistanceServer.hostName = hostname; - data.assistanceServer.port = port; - - locAPIGnssUpdateConfig(data); -} - -// for GpsNiInterface -void GnssAPIClient::gnssNiRespond(int notif_id, GpsUserResponseType user_response) -{ - LOC_LOGD("%s]: (%d %d)", __func__, notif_id, user_response); - GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE; - if (user_response == GPS_NI_RESPONSE_ACCEPT) data = GNSS_NI_RESPONSE_ACCEPT; - else if (user_response == GPS_NI_RESPONSE_DENY) data = GNSS_NI_RESPONSE_DENY; - else if (user_response == GPS_NI_RESPONSE_NORESP) data = GNSS_NI_RESPONSE_NO_RESPONSE; - locAPIGnssNiResponse(notif_id, data); -} - -// for GpsMeasurementInterface -void GnssAPIClient::gnssMeasurementClose() { - LOC_LOGD("%s]: ()", __func__); - pthread_mutex_lock(&mLock); - mGpsMeasurementCallbacks = nullptr; - pthread_mutex_unlock(&mLock); -} - -// for GnssConfigurationInterface -void GnssAPIClient::gnssConfigurationUpdate(const char* config_data, int32_t length) -{ - LOC_LOGD("%s]: (%s %d)", __func__, config_data, length); - int n = 10; - uint8_t flags[n]; - memset(&flags, 0, sizeof(uint8_t) * n); - - GnssConfig data; - memset(&data, 0, sizeof(GnssConfig)); - data.size = sizeof(GnssConfig); - - const loc_param_s_type gnssConfTable[] = - { - {"GPS_LOCK", &data.gpsLock, flags+0, 'n'}, - {"SUPL_VER", &data.suplVersion, flags+1, 'n'}, - //{"ASSISTANCE_SERVER", &data.assistanceServer, nullptr, 's'}, - {"LPP_PROFILE", &data.lppProfile, flags+3, 'n'}, - {"LPPE_CP_TECHNOLOGY", &data.lppeControlPlaneMask, flags+4, 'n'}, - {"LPPE_UP_TECHNOLOGY", &data.lppeUserPlaneMask, flags+5, 'n'}, - {"A_GLONASS_POS_PROTOCOL_SELECT", &data.aGlonassPositionProtocolMask, flags+6, 'n'}, - {"USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",&data.emergencyPdnForEmergencySupl, flags+7, 'n'}, - {"SUPL_ES", &data.suplEmergencyServices, flags+8, 'n'}, - {"SUPL_MODE", &data.suplModeMask, flags+9, 'n'}, - }; - UTIL_UPDATE_CONF(config_data, length, gnssConfTable); - - for (int i = 0; i < n; i++) { - if (flags[i] != 0) - data.flags |= (0x1 << i); - } - locAPIGnssUpdateConfig(data); -} - -// callbacks -void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) -{ - LOC_LOGD("%s]: (%02x)", __func__, capabilitiesMask); - mLocationCapabilitiesMask = capabilitiesMask; - if (mGpsCallbacks && mGpsCallbacks->set_capabilities_cb) { - uint32_t data = 0; - if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || - (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || - (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) || - (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT)) - data |= GPS_CAPABILITY_SCHEDULING; - if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT) - data |= GPS_CAPABILITY_GEOFENCING; - if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) - data |= GPS_CAPABILITY_MEASUREMENTS; - if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) - data |= GPS_CAPABILITY_MSB; - if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) - data |= GPS_CAPABILITY_MSA; - mGpsCallbacks->set_capabilities_cb(data); - } - if (mGpsCallbacks && mGpsCallbacks->set_system_info_cb) { - GnssSystemInfo info; - info.size = sizeof(GnssSystemInfo); - info.year_of_hw = 2015; - if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) { - info.year_of_hw = 2017; - } - LOC_LOGV("%s:%d] set_system_info_cb (%d)", __func__, __LINE__, info.year_of_hw); - mGpsCallbacks->set_system_info_cb(&info); - } -} - -void GnssAPIClient::onTrackingCb(Location location) -{ - LOC_LOGD("%s]: (flags: %02x)", __func__, location.flags); - if (mGpsCallbacks && mGpsCallbacks->location_cb) { - GpsLocation data; - convertGpsLocation(location, data); - mGpsCallbacks->location_cb(&data); - } -} - -void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) -{ - LOC_LOGD("%s]: (id: %d)", __func__, id); - if (mGpsNiCallbacks && mGpsNiCallbacks->notify_cb) { - GpsNiNotification data; - memset(&data, 0, sizeof(GpsNiNotification)); - data.size = sizeof(GpsNiNotification); - data.notification_id = id; - - if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE) - data.ni_type = GPS_NI_TYPE_VOICE; - else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL) - data.ni_type = GPS_NI_TYPE_UMTS_SUPL; - else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE) - data.ni_type = GPS_NI_TYPE_UMTS_CTRL_PLANE; - // GNSS_NI_TYPE_EMERGENCY_SUPL not supported - - if (gnssNiNotification.options == GNSS_NI_OPTIONS_NOTIFICATION) - data.notify_flags = GPS_NI_NEED_NOTIFY; - else if (gnssNiNotification.options == GNSS_NI_OPTIONS_VERIFICATION) - data.notify_flags = GPS_NI_NEED_VERIFY; - else if (gnssNiNotification.options == GNSS_NI_OPTIONS_PRIVACY_OVERRIDE) - data.notify_flags = GPS_NI_PRIVACY_OVERRIDE; - - data.timeout = gnssNiNotification.timeout; - if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT) - data.default_response = GPS_NI_RESPONSE_ACCEPT; - else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY) - data.default_response = GPS_NI_RESPONSE_DENY; - else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE || - gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE) - data.default_response = GPS_NI_RESPONSE_NORESP; - - int len = GPS_NI_SHORT_STRING_MAXLEN < GNSS_NI_REQUESTOR_MAX - ? GPS_NI_SHORT_STRING_MAXLEN : GNSS_NI_REQUESTOR_MAX; - memcpy(data.requestor_id, gnssNiNotification.requestor, len); - - len = GPS_NI_LONG_STRING_MAXLEN < GNSS_NI_MESSAGE_ID_MAX - ? GPS_NI_LONG_STRING_MAXLEN : GNSS_NI_MESSAGE_ID_MAX; - memcpy(data.text, gnssNiNotification.message, len); - - if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE) - data.requestor_id_encoding = GPS_ENC_NONE; - else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) - data.requestor_id_encoding = GPS_ENC_SUPL_GSM_DEFAULT; - else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8) - data.requestor_id_encoding = GPS_ENC_SUPL_UTF8; - else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2) - data.requestor_id_encoding = GPS_ENC_SUPL_UCS2; - - if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE) - data.text_encoding = GPS_ENC_NONE; - else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) - data.text_encoding = GPS_ENC_SUPL_GSM_DEFAULT; - else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8) - data.text_encoding = GPS_ENC_SUPL_UTF8; - else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2) - data.text_encoding = GPS_ENC_SUPL_UCS2; - data.text_encoding = gnssNiNotification.messageEncoding; - - memcpy(data.extras, gnssNiNotification.extras, len); - - mGpsNiCallbacks->notify_cb(&data); - } -} - -void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) -{ - LOC_LOGD("%s]: (count: %zu)", __func__, gnssSvNotification.count); - if (mGpsCallbacks && mGpsCallbacks->sv_status_cb) { - GpsSvStatus data; - convertGpsSvStatus(gnssSvNotification, data); - mGpsCallbacks->sv_status_cb(&data); - } - if (mGpsCallbacks && mGpsCallbacks->gnss_sv_status_cb) { - GnssSvStatus data; - convertGnssSvStatus(gnssSvNotification, data); - mGpsCallbacks->gnss_sv_status_cb(&data); - } -} - -void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) -{ - if (mGpsCallbacks && mGpsCallbacks->nmea_cb) { - mGpsCallbacks->nmea_cb((GpsUtcTime)gnssNmeaNotification.timestamp, - gnssNmeaNotification.nmea, gnssNmeaNotification.length); - } -} - -void GnssAPIClient::onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) -{ - LOC_LOGD("%s]: (count: %zu)", __func__, gnssMeasurementsNotification.count); - // we don't need to lock the mutext - // if mGpsMeasurementCallbacks is set to nullptr - if (mGpsMeasurementCallbacks) { - pthread_mutex_lock(&mLock); - if (mGpsMeasurementCallbacks) { - if (mGpsMeasurementCallbacks->measurement_callback) { - GpsData data; - convertGpsData(gnssMeasurementsNotification, data); - mGpsMeasurementCallbacks->measurement_callback(&data); - } - if (mGpsMeasurementCallbacks->gnss_measurement_callback) { - GnssData data; - convertGnssData(gnssMeasurementsNotification, data); - mGpsMeasurementCallbacks->gnss_measurement_callback(&data); - } - } - pthread_mutex_unlock(&mLock); - } -} - -void GnssAPIClient::onStartTrackingCb(LocationError error) -{ - LOC_LOGD("%s]: (%d)", __func__, error); - if (error == LOCATION_ERROR_SUCCESS && mGpsCallbacks && mGpsCallbacks->status_cb) { - GpsStatus data; - data.size = sizeof(GpsStatus); - data.status = GPS_STATUS_ENGINE_ON; - mGpsCallbacks->status_cb(&data); - data.status = GPS_STATUS_SESSION_BEGIN; - mGpsCallbacks->status_cb(&data); - } -} - -void GnssAPIClient::onStopTrackingCb(LocationError error) -{ - LOC_LOGD("%s]: (%d)", __func__, error); - if (error == LOCATION_ERROR_SUCCESS && mGpsCallbacks && mGpsCallbacks->status_cb) { - GpsStatus data; - data.size = sizeof(GpsStatus); - data.status = GPS_STATUS_SESSION_END; - mGpsCallbacks->status_cb(&data); - data.status = GPS_STATUS_ENGINE_OFF; - mGpsCallbacks->status_cb(&data); - } -} - -static void convertGpsLocation(Location& in, GpsLocation& out) -{ - memset(&out, 0, sizeof(GpsLocation)); - out.size = sizeof(GpsLocation); - if (in.flags & LOCATION_HAS_LAT_LONG_BIT) - out.flags |= GPS_LOCATION_HAS_LAT_LONG; - if (in.flags & LOCATION_HAS_ALTITUDE_BIT) - out.flags |= GPS_LOCATION_HAS_ALTITUDE; - if (in.flags & LOCATION_HAS_SPEED_BIT) - out.flags |= GPS_LOCATION_HAS_SPEED; - if (in.flags & LOCATION_HAS_BEARING_BIT) - out.flags |= GPS_LOCATION_HAS_BEARING; - if (in.flags & LOCATION_HAS_ACCURACY_BIT) - out.flags |= GPS_LOCATION_HAS_ACCURACY; - out.latitude = in.latitude; - out.longitude = in.longitude; - out.altitude = in.altitude; - out.speed = in.speed; - out.bearing = in.bearing; - out.accuracy = in.accuracy; - out.timestamp = (GpsUtcTime)in.timestamp; -} - -static void convertGpsSvStatus(GnssSvNotification& in, GpsSvStatus& out) -{ - memset(&out, 0, sizeof(GpsSvStatus)); - out.size = sizeof(GpsSvStatus); - out.num_svs = in.count; - int len = GPS_MAX_SVS < GNSS_SV_MAX ? GPS_MAX_SVS : GNSS_SV_MAX; - for (int i = 0; i < len; i++) { - GpsSvInfo& info = out.sv_list[i]; - info.size = sizeof(GpsSvInfo); - info.prn = in.gnssSvs[i].svId; - info.snr = in.gnssSvs[i].cN0Dbhz; - info.elevation = in.gnssSvs[i].elevation; - info.azimuth = in.gnssSvs[i].azimuth; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) - out.ephemeris_mask |= 0x1 < i; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) - out.almanac_mask |= 0x1 < i; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) - out.used_in_fix_mask |= 0x1 < i; - } -} - -static void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out) -{ - switch(in) { - case GNSS_SV_TYPE_GPS: - out = GNSS_CONSTELLATION_GPS; - break; - case GNSS_SV_TYPE_SBAS: - out = GNSS_CONSTELLATION_SBAS; - break; - case GNSS_SV_TYPE_GLONASS: - out = GNSS_CONSTELLATION_GLONASS; - break; - case GNSS_SV_TYPE_QZSS: - out = GNSS_CONSTELLATION_QZSS; - break; - case GNSS_SV_TYPE_BEIDOU: - out = GNSS_CONSTELLATION_BEIDOU; - break; - case GNSS_SV_TYPE_GALILEO: - out = GNSS_CONSTELLATION_GALILEO; - break; - default: - out = GNSS_CONSTELLATION_UNKNOWN; - break; - } -} - -static void convertGnssSvStatus(GnssSvNotification& in, GnssSvStatus& out) -{ - memset(&out, 0, sizeof(GnssSvStatus)); - out.size = sizeof(GnssSvStatus); - out.num_svs = in.count; - int len = GNSS_MAX_SVS < GNSS_SV_MAX ? GNSS_MAX_SVS : GNSS_SV_MAX; - for (int i = 0; i < len; i++) { - GnssSvInfo& info = out.gnss_sv_list[i]; - info.size = sizeof(GnssSvInfo); - info.svid = in.gnssSvs[i].svId; - convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); - info.c_n0_dbhz = in.gnssSvs[i].cN0Dbhz; - info.elevation = in.gnssSvs[i].elevation; - info.azimuth = in.gnssSvs[i].azimuth; - info.flags = GNSS_SV_FLAGS_NONE; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) - info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) - info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA; - if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) - info.flags |= GNSS_SV_FLAGS_USED_IN_FIX; - } -} - -static void convertGpsMeasurement(GnssMeasurementsData& in, GpsMeasurement& out) -{ - memset(&out, 0, sizeof(GpsMeasurement)); - out.size = sizeof(GpsMeasurement); - if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT) - out.flags |= GPS_MEASUREMENT_HAS_SNR; - if (in.flags & GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_BIT) - out.flags |= GPS_MEASUREMENT_HAS_PSEUDORANGE; - if (in.flags & GNSS_MEASUREMENTS_DATA_PSEUDORANGE_RATE_UNCERTAINTY_BIT) - out.flags |= GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT) - out.flags |= GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT) - out.flags |= GPS_MEASUREMENT_HAS_CARRIER_CYCLES; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT) - out.flags |= GPS_MEASUREMENT_HAS_CARRIER_PHASE; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT) - out.flags |= GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY; - out.prn = in.svId; - out.time_offset_ns = in.timeOffsetNs; - out.state = GNSS_MEASUREMENT_STATE_UNKNOWN; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) - out.state |= GPS_MEASUREMENT_STATE_CODE_LOCK; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT) - out.state |= GPS_MEASUREMENT_STATE_BIT_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT) - out.state |= GPS_MEASUREMENT_STATE_SUBFRAME_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT) - out.state |= GPS_MEASUREMENT_STATE_TOW_DECODED; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT) - out.state |= GPS_MEASUREMENT_STATE_MSEC_AMBIGUOUS; - out.received_gps_tow_ns = in.receivedSvTimeNs; - out.received_gps_tow_uncertainty_ns = in.receivedSvTimeUncertaintyNs; - out.c_n0_dbhz = in.carrierToNoiseDbHz; - out.pseudorange_rate_mps = in.pseudorangeRateMps; - out.pseudorange_rate_uncertainty_mps = in.pseudorangeRateUncertaintyMps; - out.accumulated_delta_range_state = GNSS_ADR_STATE_UNKNOWN; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT) - out.accumulated_delta_range_state |= GPS_ADR_STATE_VALID; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT) - out.accumulated_delta_range_state |= GPS_ADR_STATE_RESET; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT) - out.accumulated_delta_range_state |= GPS_ADR_STATE_CYCLE_SLIP; - out.accumulated_delta_range_m = in.adrMeters; - out.accumulated_delta_range_uncertainty_m = in.adrUncertaintyMeters; - out.carrier_frequency_hz = in.carrierFrequencyHz; - out.carrier_cycles = in.carrierCycles; - out.carrier_phase = in.carrierPhase; - out.carrier_phase_uncertainty = in.carrierPhaseUncertainty; - out.loss_of_lock = GPS_LOSS_OF_LOCK_UNKNOWN; - out.multipath_indicator = GPS_MULTIPATH_INDICATOR_UNKNOWN; - if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT) - out.multipath_indicator |= GPS_MULTIPATH_INDICATOR_DETECTED; - if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT) - out.multipath_indicator |= GPS_MULTIPATH_INDICATOR_NOT_USED; - out.snr_db = in.signalToNoiseRatioDb; -} - -static void convertGpsClock(GnssMeasurementsClock& in, GpsClock& out) -{ - memset(&out, 0, sizeof(GpsClock)); - out.size = sizeof(GpsClock); - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT) - out.flags |= GPS_CLOCK_HAS_LEAP_SECOND; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT) - out.flags |= GPS_CLOCK_HAS_TIME_UNCERTAINTY; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT) - out.flags |= GPS_CLOCK_HAS_FULL_BIAS; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT) - out.flags |= GPS_CLOCK_HAS_BIAS; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) - out.flags |= GPS_CLOCK_HAS_BIAS_UNCERTAINTY; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT) - out.flags |= GPS_CLOCK_HAS_DRIFT; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT) - out.flags |= GPS_CLOCK_HAS_DRIFT_UNCERTAINTY; - out.leap_second = in.leapSecond; - out.type = GPS_CLOCK_TYPE_UNKNOWN; - out.time_ns = in.timeNs; - out.time_uncertainty_ns = in.timeUncertaintyNs; - out.full_bias_ns = in.fullBiasNs; - out.bias_ns = in.biasNs; - out.bias_uncertainty_ns = in.biasUncertaintyNs; - out.drift_nsps = in.driftNsps; - out.drift_uncertainty_nsps = in.driftUncertaintyNsps; -} - -static void convertGpsData(GnssMeasurementsNotification& in, GpsData& out) -{ - memset(&out, 0, sizeof(GpsData)); - out.size = sizeof(GpsData); - out.measurement_count = in.count; - int len = GPS_MAX_MEASUREMENT < GNSS_MEASUREMENTS_MAX - ? GPS_MAX_MEASUREMENT : GNSS_MEASUREMENTS_MAX; - for (int i = 0; i < len; i++) { - convertGpsMeasurement(in.measurements[i], out.measurements[i]); - } - convertGpsClock(in.clock, out.clock); -} - -static void convertGnssMeasurement(GnssMeasurementsData& in, GnssMeasurement& out) -{ - memset(&out, 0, sizeof(GnssMeasurement)); - out.size = sizeof(GnssMeasurement); - if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT) - out.flags |= GNSS_MEASUREMENT_HAS_SNR; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT) - out.flags |= GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT) - out.flags |= GNSS_MEASUREMENT_HAS_CARRIER_CYCLES; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT) - out.flags |= GNSS_MEASUREMENT_HAS_CARRIER_PHASE; - if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT) - out.flags |= GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY; - out.svid = in.svId; - convertGnssConstellationType(in.svType, out.constellation); - out.time_offset_ns = in.timeOffsetNs; - out.state = GNSS_MEASUREMENT_STATE_UNKNOWN; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) - out.state |= GNSS_MEASUREMENT_STATE_CODE_LOCK; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_BIT_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT) - out.state |= GNSS_MEASUREMENT_STATE_TOW_DECODED; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT) - out.state |= GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_SYMBOL_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT) - out.state |= GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT) - out.state |= GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT) - out.state |= GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC; - if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT) - out.state |= GNSS_MEASUREMENT_STATE_SBAS_SYNC; - out.received_sv_time_in_ns = in.receivedSvTimeNs; - out.received_sv_time_uncertainty_in_ns = in.receivedSvTimeUncertaintyNs; - out.c_n0_dbhz = in.carrierToNoiseDbHz; - out.pseudorange_rate_mps = in.pseudorangeRateMps; - out.pseudorange_rate_uncertainty_mps = in.pseudorangeRateUncertaintyMps; - out.accumulated_delta_range_state = GNSS_ADR_STATE_UNKNOWN; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT) - out.accumulated_delta_range_state |= GNSS_ADR_STATE_VALID; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT) - out.accumulated_delta_range_state |= GNSS_ADR_STATE_RESET; - if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT) - out.accumulated_delta_range_state |= GNSS_ADR_STATE_CYCLE_SLIP; - out.accumulated_delta_range_m = in.adrMeters; - out.accumulated_delta_range_uncertainty_m = in.adrUncertaintyMeters; - out.carrier_frequency_hz = in.carrierFrequencyHz; - out.carrier_cycles = in.carrierCycles; - out.carrier_phase = in.carrierPhase; - out.carrier_phase_uncertainty = in.carrierPhaseUncertainty; - out.multipath_indicator = GNSS_MULTIPATH_INDICATOR_UNKNOWN; - if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT) - out.multipath_indicator |= GNSS_MULTIPATH_INDICATOR_PRESENT; - if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT) - out.multipath_indicator |= GNSS_MULTIPATH_INDICATOR_NOT_PRESENT; - out.snr_db = in.signalToNoiseRatioDb; -} - -static void convertGnssClock(GnssMeasurementsClock& in, GnssClock& out) -{ - memset(&out, 0, sizeof(GnssClock)); - out.size = sizeof(GnssClock); - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT) - out.flags |= GNSS_CLOCK_HAS_LEAP_SECOND; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT) - out.flags |= GNSS_CLOCK_HAS_TIME_UNCERTAINTY; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT) - out.flags |= GNSS_CLOCK_HAS_FULL_BIAS; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT) - out.flags |= GNSS_CLOCK_HAS_BIAS; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) - out.flags |= GNSS_CLOCK_HAS_BIAS_UNCERTAINTY; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT) - out.flags |= GNSS_CLOCK_HAS_DRIFT; - if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT) - out.flags |= GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY; - out.leap_second = in.leapSecond; - out.time_ns = in.timeNs; - out.time_uncertainty_ns = in.timeUncertaintyNs; - out.full_bias_ns = in.fullBiasNs; - out.bias_ns = in.biasNs; - out.bias_uncertainty_ns = in.biasUncertaintyNs; - out.drift_nsps = in.driftNsps; - out.drift_uncertainty_nsps = in.driftUncertaintyNsps; - out.hw_clock_discontinuity_count = in.hwClockDiscontinuityCount; -} - -static void convertGnssData(GnssMeasurementsNotification& in, GnssData& out) -{ - memset(&out, 0, sizeof(GnssData)); - out.size = sizeof(GnssData); - out.measurement_count = in.count; - int len = GNSS_MAX_MEASUREMENT < GNSS_MEASUREMENTS_MAX - ? GNSS_MAX_MEASUREMENT : GNSS_MEASUREMENTS_MAX; - for (int i = 0; i < len; i++) { - convertGnssMeasurement(in.measurements[i], out.measurements[i]); - } - convertGnssClock(in.clock, out.clock); -} diff --git a/android/GnssBatching.cpp b/android/GnssBatching.cpp new file mode 100644 index 00000000..5eff8199 --- /dev/null +++ b/android/GnssBatching.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LocSvc_GnssBatchingInterface" + +#include +#include +#include "GnssBatching.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void GnssBatching::GnssBatchingDeathRecipient::serviceDied( + uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(cookie), &who); + if (mGnssBatching != nullptr) { + mGnssBatching->stop(); + mGnssBatching->cleanup(); + } +} + +GnssBatching::GnssBatching() : mApi(nullptr) { + mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this); +} + +GnssBatching::~GnssBatching() { + if (mApi != nullptr) { + delete mApi; + mApi = nullptr; + } +} + + +// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. +Return GnssBatching::init(const sp& callback) { + if (mApi != nullptr) { + LOC_LOGE("%s]: mApi is NOT nullptr", __FUNCTION__); + return false; + } + + mApi = new FlpAPIClient(callback); + if (mApi == nullptr) { + LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); + return false; + } + + if (mGnssBatchingCbIface != nullptr) { + mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient); + } + mGnssBatchingCbIface = callback; + if (mGnssBatchingCbIface != nullptr) { + mGnssBatchingCbIface->linkToDeath(mGnssBatchingDeathRecipient, 0 /*cookie*/); + } + + return true; +} + +Return GnssBatching::getBatchSize() { + uint16_t ret = 0; + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + ret = mApi->flpGetBatchSize(); + } + return ret; +} + +Return GnssBatching::start(const IGnssBatching::Options& options) { + bool ret = false; + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + ret = mApi->flpStartSession(options); + } + return ret; +} + +Return GnssBatching::flush() { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->flpFlushBatchedLocations(); + } + return Void(); +} + +Return GnssBatching::stop() { + bool ret = false; + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + ret = mApi->flpStopSession(); + } + return ret; +} + +Return GnssBatching::cleanup() { + if (mGnssBatchingCbIface != nullptr) { + mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient); + } + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssBatching.h b/android/GnssBatching.h new file mode 100644 index 00000000..b46fae8e --- /dev/null +++ b/android/GnssBatching.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H + +#include +#include + + +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; + +class FlpAPIClient; +struct GnssBatching : public IGnssBatching { + GnssBatching(); + ~GnssBatching(); + + // Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow. + Return init(const sp& callback) override; + Return getBatchSize() override; + Return start(const IGnssBatching::Options& options ) override; + Return flush() override; + Return stop() override; + Return cleanup() override; + + private: + struct GnssBatchingDeathRecipient : hidl_death_recipient { + GnssBatchingDeathRecipient(sp gnssBatching) : + mGnssBatching(gnssBatching) { + } + ~GnssBatchingDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssBatching; + }; + + private: + sp mGnssBatchingDeathRecipient = nullptr; + sp mGnssBatchingCbIface = nullptr; + FlpAPIClient* mApi = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H diff --git a/android/GnssConfiguration.cpp b/android/GnssConfiguration.cpp new file mode 100644 index 00000000..591a01a5 --- /dev/null +++ b/android/GnssConfiguration.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2017, 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 +#include "Gnss.h" +#include "GnssConfiguration.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) { +} + +// Methods from ::android::hardware::gps::V1_0::IGnssConfiguration follow. +Return 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 = static_cast(enabled); + + return mGnss->updateConfiguration(config); +} + +Return 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; + config.suplVersion = static_cast(version); + + return mGnss->updateConfiguration(config); +} + +Return 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; + config.suplModeMask = static_cast(mode); + + return mGnss->updateConfiguration(config); +} + +Return GnssConfiguration::setLppProfile(uint8_t lppProfile) { + if (mGnss == nullptr) { + LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); + return false; + } + + GnssConfig config; + memset(&config, 0, sizeof(GnssConfig)); + config.size = sizeof(GnssConfig); + config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT; + config.lppProfile = static_cast(lppProfile); + + return mGnss->updateConfiguration(config); +} + +Return 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; + config.aGlonassPositionProtocolMask = + static_cast(protocol); + + return mGnss->updateConfiguration(config); +} + +Return 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; + config.gpsLock = static_cast(lock); + + return mGnss->updateConfiguration(config); +} + +Return 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 = + static_cast(enabled); + + return mGnss->updateConfiguration(config); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssConfiguration.h b/android/GnssConfiguration.h new file mode 100644 index 00000000..f9ea4235 --- /dev/null +++ b/android/GnssConfiguration.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ + + /* Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H + +#include +#include + +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 Gnss; +struct GnssConfiguration : public IGnssConfiguration { + GnssConfiguration(Gnss* gnss); + ~GnssConfiguration() = default; + + /* + * Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. + * These declarations were generated from IGnssConfiguration.hal. + */ + Return setSuplVersion(uint32_t version) override; + Return setSuplMode(uint8_t mode) override; + Return setSuplEs(bool enabled) override; + Return setLppProfile(uint8_t lppProfile) override; + Return setGlonassPositioningProtocol(uint8_t protocol) override; + Return setEmergencySuplPdn(bool enable) override; + Return setGpsLock(uint8_t lock) override; + + private: + Gnss* mGnss = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H diff --git a/android/GnssGeofencing.cpp b/android/GnssGeofencing.cpp new file mode 100644 index 00000000..035a092f --- /dev/null +++ b/android/GnssGeofencing.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssHal_GnssGeofencing" + +#include +#include +#include "GnssGeofencing.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied( + uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(cookie), &who); + if (mGnssGeofencing != nullptr) { + mGnssGeofencing->removeAllGeofences(); + } +} + +GnssGeofencing::GnssGeofencing() : mApi(nullptr) { + mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this); +} + +GnssGeofencing::~GnssGeofencing() { + if (mApi != nullptr) { + delete mApi; + mApi = nullptr; + } +} + +// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. +Return GnssGeofencing::setCallback(const sp& callback) { + if (mApi != nullptr) { + LOC_LOGE("%s]: mApi is NOT nullptr", __FUNCTION__); + return Void(); + } + + mApi = new GeofenceAPIClient(callback); + if (mApi == nullptr) { + LOC_LOGE("%s]: failed to create mApi", __FUNCTION__); + } + + if (mGnssGeofencingCbIface != nullptr) { + mGnssGeofencingCbIface->unlinkToDeath(mGnssGeofencingDeathRecipient); + } + mGnssGeofencingCbIface = callback; + if (mGnssGeofencingCbIface != nullptr) { + mGnssGeofencingCbIface->linkToDeath(mGnssGeofencingDeathRecipient, 0 /*cookie*/); + } + + return Void(); +} + +Return GnssGeofencing::addGeofence( + int32_t geofenceId, + double latitudeDegrees, + double longitudeDegrees, + double radiusMeters, + IGnssGeofenceCallback::GeofenceTransition lastTransition, + int32_t monitorTransitions, + uint32_t notificationResponsivenessMs, + uint32_t unknownTimerMs) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofenceAdd( + geofenceId, + latitudeDegrees, + longitudeDegrees, + radiusMeters, + static_cast(lastTransition), + monitorTransitions, + notificationResponsivenessMs, + unknownTimerMs); + } + return Void(); +} + +Return GnssGeofencing::pauseGeofence(int32_t geofenceId) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofencePause(geofenceId); + } + return Void(); +} + +Return GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofenceResume(geofenceId, monitorTransitions); + } + return Void(); +} + +Return GnssGeofencing::removeGeofence(int32_t geofenceId) { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + } else { + mApi->geofenceRemove(geofenceId); + } + return Void(); +} + +Return GnssGeofencing::removeAllGeofences() { + if (mApi == nullptr) { + LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__); + } else { + mApi->geofenceRemoveAll(); + } + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssGeofencing.h b/android/GnssGeofencing.h new file mode 100644 index 00000000..7af5f91c --- /dev/null +++ b/android/GnssGeofencing.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H + +#include +#include + +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; + +class GeofenceAPIClient; +struct GnssGeofencing : public IGnssGeofencing { + GnssGeofencing(); + ~GnssGeofencing(); + + /* + * Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow. + * These declarations were generated from IGnssGeofencing.hal. + */ + Return setCallback(const sp& callback) override; + Return addGeofence(int32_t geofenceId, + double latitudeDegrees, + double longitudeDegrees, + double radiusMeters, + IGnssGeofenceCallback::GeofenceTransition lastTransition, + int32_t monitorTransitions, + uint32_t notificationResponsivenessMs, + uint32_t unknownTimerMs) override; + + Return pauseGeofence(int32_t geofenceId) override; + Return resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override; + Return removeGeofence(int32_t geofenceId) override; + + private: + // This method is not part of the IGnss base class. + // It is called by GnssGeofencingDeathRecipient to remove all geofences added so far. + Return removeAllGeofences(); + + private: + struct GnssGeofencingDeathRecipient : hidl_death_recipient { + GnssGeofencingDeathRecipient(sp gnssGeofencing) : + mGnssGeofencing(gnssGeofencing) { + } + ~GnssGeofencingDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssGeofencing; + }; + + private: + sp mGnssGeofencingDeathRecipient = nullptr; + sp mGnssGeofencingCbIface = nullptr; + GeofenceAPIClient* mApi = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H diff --git a/android/GnssMeasurement.cpp b/android/GnssMeasurement.cpp new file mode 100644 index 00000000..bc07265c --- /dev/null +++ b/android/GnssMeasurement.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LocSvc_GnssMeasurementInterface" + +#include +#include +#include "GnssMeasurement.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied( + uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(cookie), &who); + if (mGnssMeasurement != nullptr) { + mGnssMeasurement->close(); + } +} + +GnssMeasurement::GnssMeasurement() { + mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this); + mApi = new GnssMeasurementAPIClient(); +} + +GnssMeasurement::~GnssMeasurement() { + if (mApi) { + delete mApi; + mApi = nullptr; + } +} + +// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow. +Return GnssMeasurement::setCallback( + const sp& callback) { + + Return ret = + IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC; + if (mGnssMeasurementCbIface != nullptr) { + LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__); + return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT; + } + + if (callback == nullptr) { + LOC_LOGE("%s]: callback is nullptr", __FUNCTION__); + return ret; + } + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + return ret; + } + + mGnssMeasurementCbIface = callback; + mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0 /*cookie*/); + + return mApi->gnssMeasurementSetCallback(callback); +} + +Return GnssMeasurement::close() { + if (mApi == nullptr) { + LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__); + return Void(); + } + + if (mGnssMeasurementCbIface != nullptr) { + mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient); + mGnssMeasurementCbIface = nullptr; + } + mApi->gnssMeasurementClose(); + + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssMeasurement.h b/android/GnssMeasurement.h new file mode 100644 index 00000000..cd364c3a --- /dev/null +++ b/android/GnssMeasurement.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H + +#include +#include + +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; + +class GnssMeasurementAPIClient; +struct GnssMeasurement : public IGnssMeasurement { + GnssMeasurement(); + ~GnssMeasurement(); + + /* + * Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow. + * These declarations were generated from IGnssMeasurement.hal. + */ + Return setCallback( + const sp& callback) override; + Return close() override; + + private: + struct GnssMeasurementDeathRecipient : hidl_death_recipient { + GnssMeasurementDeathRecipient(sp gnssMeasurement) : + mGnssMeasurement(gnssMeasurement) { + } + ~GnssMeasurementDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssMeasurement; + }; + + private: + sp mGnssMeasurementDeathRecipient = nullptr; + sp mGnssMeasurementCbIface = nullptr; + GnssMeasurementAPIClient* mApi; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H diff --git a/android/GnssNi.cpp b/android/GnssNi.cpp new file mode 100644 index 00000000..4437932a --- /dev/null +++ b/android/GnssNi.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "LocSvc_GnssNiInterface" + +#include +#include "Gnss.h" +#include "GnssNi.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void GnssNi::GnssNiDeathRecipient::serviceDied(uint64_t cookie, const wp& who) { + LOC_LOGE("%s] service died. cookie: %llu, who: %p", + __FUNCTION__, static_cast(cookie), &who); + // we do nothing here + // Gnss::GnssDeathRecipient will stop the session +} + +GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) { + mGnssNiDeathRecipient = new GnssNiDeathRecipient(this); +} + +// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. +Return GnssNi::setCallback(const sp& callback) { + if (mGnss == nullptr) { + LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); + return Void(); + } + + mGnss->setGnssNiCb(callback); + + if (mGnssNiCbIface != nullptr) { + mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient); + } + mGnssNiCbIface = callback; + if (mGnssNiCbIface != nullptr) { + mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/); + } + + return Void(); +} + +Return GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) { + if (mGnss == nullptr) { + LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__); + return Void(); + } + + GnssAPIClient* api = mGnss->getApi(); + if (api == nullptr) { + LOC_LOGE("%s]: api is nullptr", __FUNCTION__); + return Void(); + } + + api->gnssNiRespond(notifId, userResponse); + + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssNi.h b/android/GnssNi.h new file mode 100644 index 00000000..f6fe0bb4 --- /dev/null +++ b/android/GnssNi.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H +#define ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H + +#include +#include + +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; + +struct Gnss; +struct GnssNi : public IGnssNi { + GnssNi(Gnss* gnss); + ~GnssNi() = default; + + /* + * Methods from ::android::hardware::gnss::V1_0::IGnssNi follow. + * These declarations were generated from IGnssNi.hal. + */ + Return setCallback(const sp& callback) override; + Return respond(int32_t notifId, + IGnssNiCallback::GnssUserResponseType userResponse) override; + + private: + struct GnssNiDeathRecipient : hidl_death_recipient { + GnssNiDeathRecipient(sp gnssNi) : mGnssNi(gnssNi) { + } + ~GnssNiDeathRecipient() = default; + virtual void serviceDied(uint64_t cookie, const wp& who) override; + sp mGnssNi; + }; + + private: + sp mGnssNiDeathRecipient = nullptr; + sp mGnssNiCbIface = nullptr; + Gnss* mGnss = nullptr; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H diff --git a/android/android.hardware.gnss@1.0-service-qti.rc b/android/android.hardware.gnss@1.0-service-qti.rc new file mode 100644 index 00000000..7ba64601 --- /dev/null +++ b/android/android.hardware.gnss@1.0-service-qti.rc @@ -0,0 +1,4 @@ +service gnss_service /system/bin/hw/android.hardware.gnss@1.0-service-qti + class main + user system + group system diff --git a/android/loc.cpp b/android/loc.cpp deleted file mode 100644 index 14d81263..00000000 --- a/android/loc.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#define LOG_NDDEBUG 0 -#define LOG_TAG "LocSvc_afw" - -#include -#include -#include - -#include "GnssAPIClient.h" - -extern "C" const GpsGeofencingInterface* get_gps_geofence_interface(); - -static GnssAPIClient* sClient = nullptr; -static GpsCallbacks sGpsCallbacks; -static GpsCallbacks* pGpsCallbacks = nullptr; - -static GpsNiCallbacks sGpsNiCallbacks; -static GpsNiCallbacks* pGpsNiCallbacks = nullptr; - -static GpsMeasurementCallbacks sGpsMeasurementCallbacks; -static GpsMeasurementCallbacks* pGpsMeasurementCallbacks = nullptr; - -typedef struct { - bool pending; - AGpsType type; - char *hostname; - int port; -} AgnssServerPack; -static AgnssServerPack pendingAgnssServer = { - false, - AGPS_TYPE_SUPL, - nullptr, - 0 -}; - -typedef struct { - bool pending; - char* config_data; - int32_t length; -} ConfigurationPack; -static ConfigurationPack pendingConfiguration = { - false, - nullptr, - 0 -}; - -static GnssAPIClient* getClient() { - if (!sClient && - // in order to create a GnssClient to call gnssUpdateConfig, - // one of pGpsCallbacks and pGpsNiCallbacks should not be nullptr. - (pGpsCallbacks != nullptr || pGpsNiCallbacks != nullptr)) { - sClient = new GnssAPIClient(pGpsCallbacks, pGpsNiCallbacks, pGpsMeasurementCallbacks); - if (sClient) { - sClient->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS); - if (pendingAgnssServer.pending && pendingAgnssServer.hostname) { - sClient->gnssAgnssSetServer(pendingAgnssServer.type, - pendingAgnssServer.hostname, - pendingAgnssServer.port); - pendingAgnssServer.pending = false; - free(pendingAgnssServer.hostname); - pendingAgnssServer.hostname = nullptr; - } - if (pendingConfiguration.pending && pendingConfiguration.config_data) { - sClient->gnssConfigurationUpdate(pendingConfiguration.config_data, - pendingConfiguration.length); - pendingConfiguration.pending = false; - free(pendingConfiguration.config_data); - pendingConfiguration.config_data = nullptr; - } - } - } - if (!sClient) { - LOC_LOGE("%s:%d] get GnssAPIClient failed", __func__, __LINE__); - } - return sClient; -} - -/*=========================================================================== - Functions and variables for sGpsInterface -===========================================================================*/ -static int loc_init(GpsCallbacks* callbacks) { - ENTRY_LOG_CALLFLOW(); - int retVal = -1; - if (callbacks) { - GnssAPIClient* client = getClient(); - // backup callbacks in case *callbacks is a stack variable - pGpsCallbacks = &sGpsCallbacks; - pGpsCallbacks->size = callbacks->size; - pGpsCallbacks->location_cb = callbacks->location_cb; - pGpsCallbacks->status_cb = callbacks->status_cb; - pGpsCallbacks->sv_status_cb = callbacks->sv_status_cb; - pGpsCallbacks->nmea_cb = callbacks->nmea_cb; - pGpsCallbacks->set_capabilities_cb = callbacks->set_capabilities_cb; - pGpsCallbacks->set_system_info_cb = callbacks->set_system_info_cb; - pGpsCallbacks->gnss_sv_status_cb = callbacks->gnss_sv_status_cb; - - // create MsgTask - pGpsCallbacks->create_thread_cb = callbacks->create_thread_cb; - loc_core::LocDualContext::getLocFgContext( - (LocThread::tCreate)pGpsCallbacks->create_thread_cb, - nullptr, loc_core::LocDualContext::mLocationHalName, false); - - // will never call these cbs - pGpsCallbacks->acquire_wakelock_cb = nullptr; - pGpsCallbacks->release_wakelock_cb = nullptr; - pGpsCallbacks->request_utc_time_cb = nullptr; - - // we can't create GnssAPIClient before GpsCallbacks or GpsNiCallbacks is set - if (client) { - client->gnssUpdateCallbacks(pGpsCallbacks, pGpsNiCallbacks, pGpsMeasurementCallbacks); - } - - retVal = 0; - } - return retVal; -} -static int loc_start() { - ENTRY_LOG_CALLFLOW(); - int retVal = -1; - GnssAPIClient* client = getClient(); - if (client) - retVal = client->gnssStart(); - return retVal; -} -static int loc_stop() { - ENTRY_LOG_CALLFLOW(); - int retVal = -1; - GnssAPIClient* client = getClient(); - if (client) - retVal = client->gnssStop(); - return retVal; -} -static void loc_cleanup() { - ENTRY_LOG_CALLFLOW(); - if (sClient) { - sClient->locAPIDisable(); - } - pGpsCallbacks = nullptr; - pGpsNiCallbacks = nullptr; - pGpsMeasurementCallbacks = nullptr; - - pendingAgnssServer.pending = false; - if (pendingAgnssServer.hostname) { - free(pendingAgnssServer.hostname); - pendingAgnssServer.hostname = nullptr; - } - pendingConfiguration.pending = false; - if (pendingConfiguration.config_data) { - free(pendingConfiguration.config_data); - pendingConfiguration.config_data = nullptr; - } -} -static int loc_inject_time(GpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/) { - return -1; -} -static int loc_inject_location(double /*latitude*/, double /*longitude*/, float /*accuracy*/) { - return -1; -} -static void loc_delete_aiding_data(GpsAidingData f) { - ENTRY_LOG_CALLFLOW(); - GnssAPIClient* client = getClient(); - if (client) - client->gnssDeleteAidingData(f); -} -static int loc_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence, - uint32_t min_interval, uint32_t preferred_accuracy, - uint32_t preferred_time) { - ENTRY_LOG_CALLFLOW(); - int retVal = -1; - GnssAPIClient* client = getClient(); - if (client) - retVal = client->gnssSetPositionMode(mode, recurrence, - min_interval, preferred_accuracy, preferred_time); - return retVal; -} -static const void* loc_get_extension(const char* name); - -static const GpsInterface sGpsInterface = { - sizeof(GpsInterface), - loc_init, - loc_start, - loc_stop, - loc_cleanup, - loc_inject_time, - loc_inject_location, - loc_delete_aiding_data, - loc_set_position_mode, - loc_get_extension -}; - -/*=========================================================================== - Functions and variables for sAGpsInterface -===========================================================================*/ -static void loc_agps_init(AGpsCallbacks* /*callbacks*/) { -} -static int loc_agps_open(const char* /*apn*/) { - return -1; -} -static int loc_agps_closed() { return -1; } -static int loc_agps_open_failed() { return -1; } -static int loc_agps_set_server(AGpsType type, const char *hostname, int port) { - GnssAPIClient* client = getClient(); - if (client) - client->gnssAgnssSetServer(type, hostname, port); - else { - // client is not ready yet - if (pendingAgnssServer.hostname) - free(pendingAgnssServer.hostname); - pendingAgnssServer.type = type; - pendingAgnssServer.hostname = strdup(hostname); - pendingAgnssServer.port = port; - pendingAgnssServer.pending = true; - } - return 0; -} -static int loc_agps_open_with_apniptype(const char* /*apn*/, ApnIpType /*apnIpType*/) { - return -1; -} - -static const AGpsInterface sAGpsInterface = { - sizeof(AGpsInterface), - loc_agps_init, - loc_agps_open, - loc_agps_closed, - loc_agps_open_failed, - loc_agps_set_server, - loc_agps_open_with_apniptype -}; - -/*=========================================================================== - Functions and variables for sGpsNiInterface -===========================================================================*/ -static void loc_ni_init(GpsNiCallbacks *callbacks) { - ENTRY_LOG_CALLFLOW(); - if (callbacks) { - GnssAPIClient* client = getClient(); - pGpsNiCallbacks = &sGpsNiCallbacks; - pGpsNiCallbacks->notify_cb = callbacks->notify_cb; - pGpsNiCallbacks->create_thread_cb = callbacks->create_thread_cb; - - if (client) { - client->gnssUpdateCallbacks(pGpsCallbacks, pGpsNiCallbacks, pGpsMeasurementCallbacks); - } - } -} -static void loc_ni_respond(int notif_id, GpsUserResponseType user_response) { - ENTRY_LOG_CALLFLOW(); - GnssAPIClient* client = getClient(); - if (client) - client->gnssNiRespond(notif_id, user_response); -} - -static const GpsNiInterface sGpsNiInterface = -{ - sizeof(GpsNiInterface), - loc_ni_init, - loc_ni_respond, -}; - -/*=========================================================================== - Functions and variables for sGpsMeasurementInterface -===========================================================================*/ -static int loc_gps_measurement_init(GpsMeasurementCallbacks* callbacks) { - ENTRY_LOG_CALLFLOW(); - int retVal = -1; - if (callbacks) { - GnssAPIClient* client = getClient(); - pGpsMeasurementCallbacks = &sGpsMeasurementCallbacks; - pGpsMeasurementCallbacks->size = sizeof(GpsMeasurementCallbacks); - pGpsMeasurementCallbacks->measurement_callback = callbacks->measurement_callback; - pGpsMeasurementCallbacks->gnss_measurement_callback = callbacks->gnss_measurement_callback; - - if (client) { - client->gnssUpdateCallbacks(pGpsCallbacks, pGpsNiCallbacks, pGpsMeasurementCallbacks); - } - - retVal = 0; - } - return retVal; -} -static void loc_gps_measurement_close() { - ENTRY_LOG_CALLFLOW(); - GnssAPIClient* client = getClient(); - if (client) - client->gnssMeasurementClose(); -} - -static const GpsMeasurementInterface sGpsMeasurementInterface = -{ - sizeof(GpsMeasurementInterface), - loc_gps_measurement_init, - loc_gps_measurement_close -}; - -/*=========================================================================== - Functions and variables for sGnssConfigurationInterface -===========================================================================*/ -static void loc_configuration_update(const char* config_data, int32_t length) { - ENTRY_LOG_CALLFLOW(); - GnssAPIClient* client = getClient(); - if (client) - client->gnssConfigurationUpdate(config_data, length); - else { - // client is not ready yet - if (pendingConfiguration.config_data) - free(pendingConfiguration.config_data); - pendingConfiguration.config_data = strdup(config_data); - pendingConfiguration.length = length; - pendingConfiguration.pending = true; - } -} - -static const GnssConfigurationInterface sGnssConfigurationInterface = -{ - sizeof(GnssConfigurationInterface), - loc_configuration_update -}; - -// Function exposed to gps hal -extern "C" const GpsInterface* get_gps_interface() -{ - unsigned int target = loc_get_target(); - int gnssType = getTargetGnssType(target); - if (gnssType == GNSS_NONE){ - LOC_LOGE("%s:%d] No GNSS HW on this target. Returning nullptr", __func__, __LINE__); - return nullptr; - } - return &sGpsInterface; -} - -const void* loc_get_extension(const char* name) -{ - const void* retVal = nullptr; - - LOC_LOGD("%s:%d] For Interface = %s\n", __func__, __LINE__, name); - if (strcmp(name, AGPS_INTERFACE) == 0) { - retVal = &sAGpsInterface; - } else if (strcmp(name, GPS_NI_INTERFACE) == 0) { - retVal = &sGpsNiInterface; - } else if (strcmp(name, GPS_GEOFENCING_INTERFACE) == 0) { - retVal = get_gps_geofence_interface(); - } else if (strcmp(name, GPS_MEASUREMENT_INTERFACE) == 0) { - retVal = &sGpsMeasurementInterface; - } else if (strcmp(name, GNSS_CONFIGURATION_INTERFACE) == 0) { - retVal = &sGnssConfigurationInterface; - } - - if (!retVal) { - LOC_LOGE ("%s:%d] %s is not supported", __func__, __LINE__, name); - } - return retVal; -} diff --git a/android/loc_geofence.cpp b/android/loc_geofence.cpp deleted file mode 100644 index 91a4be82..00000000 --- a/android/loc_geofence.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of The Linux Foundation, nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#define LOG_NDDEBUG 0 -#define LOG_TAG "LocSvc_geofence" - -#include -#include - -static GeofenceAPIClient* sClient = nullptr; - -/*=========================================================================== - Functions and variables for sGpsGeofencingInterface -===========================================================================*/ -static GpsGeofenceCallbacks sGpsGeofenceCbs; - -static void loc_geofence_init(GpsGeofenceCallbacks* callbacks) { - if (callbacks && !sClient) { - sGpsGeofenceCbs.geofence_transition_callback = callbacks->geofence_transition_callback; - sGpsGeofenceCbs.geofence_status_callback = callbacks->geofence_status_callback; - sGpsGeofenceCbs.geofence_add_callback = callbacks->geofence_add_callback; - sGpsGeofenceCbs.geofence_remove_callback = callbacks->geofence_remove_callback; - sGpsGeofenceCbs.geofence_pause_callback = callbacks->geofence_pause_callback; - sGpsGeofenceCbs.geofence_resume_callback = callbacks->geofence_resume_callback; - sGpsGeofenceCbs.create_thread_cb = callbacks->create_thread_cb; - - sClient = new GeofenceAPIClient(&sGpsGeofenceCbs); - } -} -static void loc_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) { - if (sClient) - sClient->geofenceAdd(geofence_id, latitude, longitude, - radius_meters, last_transition, monitor_transitions, - notification_responsiveness_ms, unknown_timer_ms); -} -static void loc_pause_geofence(int32_t geofence_id) { - if (sClient) - sClient->geofencePause(geofence_id); -} -static void loc_resume_geofence(int32_t geofence_id, int monitor_transitions) { - if (sClient) - sClient->geofenceResume(geofence_id, monitor_transitions); -} -static void loc_remove_geofence_area(int32_t geofence_id) { - if (sClient) - sClient->geofenceRemove(geofence_id); -} - -static const GpsGeofencingInterface sGpsGeofencingInterface = -{ - sizeof(GpsGeofencingInterface), - loc_geofence_init, - loc_add_geofence_area, - loc_pause_geofence, - loc_resume_geofence, - loc_remove_geofence_area -}; - -// Function exposed to gps hal -extern "C" const GpsGeofencingInterface* get_gps_geofence_interface() -{ - return &sGpsGeofencingInterface; -} diff --git a/android/location_api/FlpAPIClient.cpp b/android/location_api/FlpAPIClient.cpp new file mode 100644 index 00000000..2fb8caa4 --- /dev/null +++ b/android/location_api/FlpAPIClient.cpp @@ -0,0 +1,182 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define LOG_NDDEBUG 0 +#define LOG_TAG "LocSvc_FlpAPIClient" + +#include +#include + +#include "LocationUtil.h" +#include "FlpAPIClient.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out, + LocationCapabilitiesMask mask); + +FlpAPIClient::FlpAPIClient(const sp& callback) : + LocationAPIClientBase(), + mGnssBatchingCbIface(callback), + mDefaultId(42), + mLocationCapabilitiesMask(0) +{ + LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback); + + LocationCallbacks locationCallbacks; + locationCallbacks.size = sizeof(LocationCallbacks); + + locationCallbacks.trackingCb = nullptr; + locationCallbacks.batchingCb = nullptr; + if (mGnssBatchingCbIface != nullptr) { + locationCallbacks.batchingCb = [this](size_t count, Location* location) { + onBatchingCb(count, location); + }; + } + locationCallbacks.geofenceBreachCb = nullptr; + locationCallbacks.geofenceStatusCb = nullptr; + locationCallbacks.gnssLocationInfoCb = nullptr; + locationCallbacks.gnssNiCb = nullptr; + locationCallbacks.gnssSvCb = nullptr; + locationCallbacks.gnssNmeaCb = nullptr; + locationCallbacks.gnssMeasurementsCb = nullptr; + + locAPISetCallbacks(locationCallbacks); +} + +FlpAPIClient::~FlpAPIClient() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); +} + +int FlpAPIClient::flpGetBatchSize() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + return locAPIGetBatchSize(); +} + +int FlpAPIClient::flpStartSession(const IGnssBatching::Options& opts) +{ + LOC_LOGD("%s]: (%lld %d)", __FUNCTION__, + static_cast(opts.periodNanos), static_cast(opts.flags)); + int retVal = -1; + LocationOptions options; + convertBatchOption(opts, options, mLocationCapabilitiesMask); + uint32_t mode = 0; + if (opts.flags == static_cast(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) { + mode = SESSION_MODE_ON_FULL; + } + if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) { + retVal = 1; + } + return retVal; +} + +int FlpAPIClient::flpUpdateSessionOptions(const IGnssBatching::Options& opts) +{ + LOC_LOGD("%s]: (%lld %d)", __FUNCTION__, + static_cast(opts.periodNanos), static_cast(opts.flags)); + int retVal = -1; + LocationOptions options; + convertBatchOption(opts, options, mLocationCapabilitiesMask); + + uint32_t mode = 0; + if (opts.flags == static_cast(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) { + mode = SESSION_MODE_ON_FULL; + } + if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) { + retVal = 1; + } + return retVal; +} + +int FlpAPIClient::flpStopSession() +{ + LOC_LOGD("%s]: ", __FUNCTION__); + int retVal = -1; + if (locAPIStopSession(mDefaultId) == LOCATION_ERROR_SUCCESS) { + retVal = 1; + } + return retVal; +} + +void FlpAPIClient::flpGetBatchedLocation(int last_n_locations) +{ + LOC_LOGD("%s]: (%d)", __FUNCTION__, last_n_locations); + locAPIGetBatchedLocations(last_n_locations); +} + +void FlpAPIClient::flpFlushBatchedLocations() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + locAPIGetBatchedLocations(SIZE_MAX); +} + +void FlpAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) +{ + LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + mLocationCapabilitiesMask = capabilitiesMask; +} + +void FlpAPIClient::onBatchingCb(size_t count, Location* location) +{ + LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, count); + if (mGnssBatchingCbIface != nullptr && count > 0) { + hidl_vec locationVec; + locationVec.resize(count); + for (size_t i = 0; i < count; i++) { + convertGnssLocation(location[i], locationVec[i]); + } + mGnssBatchingCbIface->gnssLocationBatchCb(locationVec); + } +} + +static void convertBatchOption(const IGnssBatching::Options& in, LocationOptions& out, + LocationCapabilitiesMask mask) +{ + memset(&out, 0, sizeof(LocationOptions)); + out.size = sizeof(LocationOptions); + out.minInterval = (uint32_t)(in.periodNanos / 1000000L); + out.minDistance = 0; + out.mode = GNSS_SUPL_MODE_STANDALONE; + if (mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) + out.mode = GNSS_SUPL_MODE_MSA; + if (mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) + out.mode = GNSS_SUPL_MODE_MSB; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/location_api/FlpAPIClient.h b/android/location_api/FlpAPIClient.h new file mode 100644 index 00000000..9f9be1e3 --- /dev/null +++ b/android/location_api/FlpAPIClient.h @@ -0,0 +1,77 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef FLP_API_CLINET_H +#define FLP_API_CLINET_H + +#include +#include +#include + +#include + +#define FLP_CONF_FILE "/etc/flp.conf" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +class FlpAPIClient : public LocationAPIClientBase +{ +public: + FlpAPIClient(const sp& callback); + ~FlpAPIClient(); + int flpGetBatchSize(); + int flpStartSession(const IGnssBatching::Options& options); + int flpUpdateSessionOptions(const IGnssBatching::Options& options); + int flpStopSession(); + void flpGetBatchedLocation(int last_n_locations); + void flpFlushBatchedLocations(); + + inline LocationCapabilitiesMask flpGetCapabilities() { return mLocationCapabilitiesMask; } + + // callbacks + void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final; + void onBatchingCb(size_t count, Location* location) final; + +private: + sp mGnssBatchingCbIface; + uint32_t mDefaultId; + int mBatchSize; + LocationCapabilitiesMask mLocationCapabilitiesMask; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // FLP_API_CLINET_H diff --git a/android/GeofenceAPIClient.cpp b/android/location_api/GeofenceAPIClient.cpp similarity index 56% rename from android/GeofenceAPIClient.cpp rename to android/location_api/GeofenceAPIClient.cpp index aeb4fd5e..5be1cff2 100644 --- a/android/GeofenceAPIClient.cpp +++ b/android/location_api/GeofenceAPIClient.cpp @@ -33,36 +33,21 @@ #include #include +#include "LocationUtil.h" #include "GeofenceAPIClient.h" -static void convertGpsLocation(Location& in, GpsLocation& out) -{ - memset(&out, 0, sizeof(GpsLocation)); - out.size = sizeof(GpsLocation); - if (in.flags & LOCATION_HAS_LAT_LONG_BIT) - out.flags |= GPS_LOCATION_HAS_LAT_LONG; - if (in.flags & LOCATION_HAS_ALTITUDE_BIT) - out.flags |= GPS_LOCATION_HAS_ALTITUDE; - if (in.flags & LOCATION_HAS_SPEED_BIT) - out.flags |= GPS_LOCATION_HAS_SPEED; - if (in.flags & LOCATION_HAS_BEARING_BIT) - out.flags |= GPS_LOCATION_HAS_BEARING; - if (in.flags & LOCATION_HAS_ACCURACY_BIT) - out.flags |= GPS_LOCATION_HAS_ACCURACY; - out.latitude = in.latitude; - out.longitude = in.longitude; - out.altitude = in.altitude; - out.speed = in.speed; - out.bearing = in.bearing; - out.accuracy = in.accuracy; - out.timestamp = (GpsUtcTime)in.timestamp; -} +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { -GeofenceAPIClient::GeofenceAPIClient(GpsGeofenceCallbacks* cbs) : + +GeofenceAPIClient::GeofenceAPIClient(const sp& callback) : LocationAPIClientBase(), - mGpsGeofenceCallbacks(cbs) + mGnssGeofencingCbIface(callback) { - LOC_LOGD("%s]: (%p)", __func__, cbs); + LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback); LocationCallbacks locationCallbacks; locationCallbacks.size = sizeof(LocationCallbacks); @@ -71,15 +56,12 @@ GeofenceAPIClient::GeofenceAPIClient(GpsGeofenceCallbacks* cbs) : locationCallbacks.batchingCb = nullptr; locationCallbacks.geofenceBreachCb = nullptr; - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_transition_callback) { + if (mGnssGeofencingCbIface != nullptr) { locationCallbacks.geofenceBreachCb = [this](GeofenceBreachNotification geofenceBreachNotification) { onGeofenceBreachCb(geofenceBreachNotification); }; - } - locationCallbacks.geofenceStatusCb = nullptr; - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_status_callback) { locationCallbacks.geofenceStatusCb = [this](GeofenceStatusNotification geofenceStatusNotification) { onGeofenceStatusCb(geofenceStatusNotification); @@ -96,19 +78,19 @@ GeofenceAPIClient::GeofenceAPIClient(GpsGeofenceCallbacks* cbs) : } void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude, - double radius_meters, int last_transition, int monitor_transitions, - int notification_responsiveness_ms, int unknown_timer_ms) + double radius_meters, int32_t last_transition, int32_t monitor_transitions, + uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms) { - LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __func__, + LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__, geofence_id, latitude, longitude, radius_meters, last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms); GeofenceOption options; memset(&options, 0, sizeof(GeofenceOption)); options.size = sizeof(GeofenceOption); - if (monitor_transitions & GPS_GEOFENCE_ENTERED) + if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED) options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT; - if (monitor_transitions & GPS_GEOFENCE_EXITED) + if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED) options.breachTypeMask |= GEOFENCE_BREACH_EXIT_BIT; options.responsiveness = notification_responsiveness_ms; @@ -123,120 +105,141 @@ void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, doubl void GeofenceAPIClient::geofencePause(uint32_t geofence_id) { - LOC_LOGD("%s]: (%d)", __func__, geofence_id); + LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id); locAPIPauseGeofences(1, &geofence_id); } -void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int monitor_transitions) +void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions) { - LOC_LOGD("%s]: (%d %d)", __func__, geofence_id, monitor_transitions); + LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions); GeofenceBreachTypeMask mask = 0; - if (monitor_transitions & GPS_GEOFENCE_ENTERED) + if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED) mask |= GEOFENCE_BREACH_ENTER_BIT; - if (monitor_transitions & GPS_GEOFENCE_EXITED) + if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED) mask |= GEOFENCE_BREACH_EXIT_BIT; locAPIResumeGeofences(1, &geofence_id, &mask); } void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id) { - LOC_LOGD("%s]: (%d)", __func__, geofence_id); + LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id); locAPIRemoveGeofences(1, &geofence_id); } +void GeofenceAPIClient::geofenceRemoveAll() +{ + LOC_LOGD("%s]", __FUNCTION__); + // TODO locAPIRemoveAllGeofences(); +} + // callbacks void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) { - LOC_LOGD("%s]: (%zu)", __func__, geofenceBreachNotification.count); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_transition_callback) { + LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count); + if (mGnssGeofencingCbIface != nullptr) { for (size_t i = 0; i < geofenceBreachNotification.count; i++) { - GpsLocation location; - convertGpsLocation(geofenceBreachNotification.location, location); + GnssLocation gnssLocation; + convertGnssLocation(geofenceBreachNotification.location, gnssLocation); - uint32_t transition; + IGnssGeofenceCallback::GeofenceTransition transition; if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER) - transition = GPS_GEOFENCE_ENTERED; + transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED; else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT) - transition = GPS_GEOFENCE_EXITED; + transition = IGnssGeofenceCallback::GeofenceTransition::EXITED; else { // continue with other breach if transition is // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED continue; } - GpsUtcTime time = geofenceBreachNotification.timestamp; - mGpsGeofenceCallbacks->geofence_transition_callback(geofenceBreachNotification.ids[i], - &location, transition, time); + mGnssGeofencingCbIface->gnssGeofenceTransitionCb( + geofenceBreachNotification.ids[i], gnssLocation, transition, + static_cast(geofenceBreachNotification.timestamp)); } } } void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification) { - LOC_LOGD("%s]: (%d)", __func__, geofenceStatusNotification.available); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_status_callback) { - int32_t status = GPS_GEOFENCE_UNAVAILABLE; + LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available); + if (mGnssGeofencingCbIface != nullptr) { + IGnssGeofenceCallback::GeofenceAvailability status = + IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE; if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) { - status = GPS_GEOFENCE_AVAILABLE; + status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE; } - mGpsGeofenceCallbacks->geofence_status_callback(status, nullptr); + GnssLocation gnssLocation; + memset(&gnssLocation, 0, sizeof(GnssLocation)); + mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation); } } void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { - LOC_LOGD("%s]: (%zu)", __func__, count); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_add_callback) { + LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); + if (mGnssGeofencingCbIface != nullptr) { for (size_t i = 0; i < count; i++) { - int32_t status = GPS_GEOFENCE_ERROR_GENERIC; + IGnssGeofenceCallback::GeofenceStatus status = + IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; if (errors[i] == LOCATION_ERROR_SUCCESS) - status = GPS_GEOFENCE_OPERATION_SUCCESS; - mGpsGeofenceCallbacks->geofence_add_callback(ids[i], status); + status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; + else if (errors[i] == LOCATION_ERROR_ID_EXISTS) + status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS; + mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status); } } } void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { - LOC_LOGD("%s]: (%zu)", __func__, count); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_remove_callback) { + LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); + if (mGnssGeofencingCbIface != nullptr) { for (size_t i = 0; i < count; i++) { - int32_t status = GPS_GEOFENCE_ERROR_GENERIC; + IGnssGeofenceCallback::GeofenceStatus status = + IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; if (errors[i] == LOCATION_ERROR_SUCCESS) - status = GPS_GEOFENCE_OPERATION_SUCCESS; + status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) - status = GPS_GEOFENCE_ERROR_ID_UNKNOWN; - mGpsGeofenceCallbacks->geofence_remove_callback(ids[i], status); + status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; + mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status); } } } void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { - LOC_LOGD("%s]: (%zu)", __func__, count); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_pause_callback) { + LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); + if (mGnssGeofencingCbIface != nullptr) { for (size_t i = 0; i < count; i++) { - int32_t status = GPS_GEOFENCE_ERROR_GENERIC; + IGnssGeofenceCallback::GeofenceStatus status = + IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; if (errors[i] == LOCATION_ERROR_SUCCESS) - status = GPS_GEOFENCE_OPERATION_SUCCESS; + status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) - status = GPS_GEOFENCE_ERROR_ID_UNKNOWN; - mGpsGeofenceCallbacks->geofence_pause_callback(ids[i], status); + status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; + mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status); } } } void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) { - LOC_LOGD("%s]: (%zu)", __func__, count); - if (mGpsGeofenceCallbacks && mGpsGeofenceCallbacks->geofence_resume_callback) { + LOC_LOGD("%s]: (%zu)", __FUNCTION__, count); + if (mGnssGeofencingCbIface != nullptr) { for (size_t i = 0; i < count; i++) { - int32_t status = GPS_GEOFENCE_ERROR_GENERIC; + IGnssGeofenceCallback::GeofenceStatus status = + IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC; if (errors[i] == LOCATION_ERROR_SUCCESS) - status = GPS_GEOFENCE_OPERATION_SUCCESS; + status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS; else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN) - status = GPS_GEOFENCE_ERROR_ID_UNKNOWN; - mGpsGeofenceCallbacks->geofence_resume_callback(ids[i], status); + status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN; + mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status); } } } + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GeofenceAPIClient.h b/android/location_api/GeofenceAPIClient.h similarity index 78% rename from android/GeofenceAPIClient.h rename to android/location_api/GeofenceAPIClient.h index e99d6ba2..f779bcbc 100644 --- a/android/GeofenceAPIClient.h +++ b/android/location_api/GeofenceAPIClient.h @@ -30,21 +30,31 @@ #ifndef GEOFENCE_API_CLINET_H #define GEOFENCE_API_CLINET_H -#include + +#include #include +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +using ::android::sp; + class GeofenceAPIClient : public LocationAPIClientBase { public: - GeofenceAPIClient(GpsGeofenceCallbacks* cbs); + GeofenceAPIClient(const sp& callback); virtual ~GeofenceAPIClient() = default; void geofenceAdd(uint32_t geofence_id, double latitude, double longitude, - double radius_meters, int last_transition, int monitor_transitions, - int notification_responsiveness_ms, int unknown_timer_ms); + double radius_meters, int32_t last_transition, int32_t monitor_transitions, + uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms); void geofencePause(uint32_t geofence_id); - void geofenceResume(uint32_t geofence_id, int monitor_transitions); + void geofenceResume(uint32_t geofence_id, int32_t monitor_transitions); void geofenceRemove(uint32_t geofence_id); + void geofenceRemoveAll(); // callbacks void onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification) final; @@ -55,6 +65,12 @@ public: void onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids) final; private: - GpsGeofenceCallbacks* mGpsGeofenceCallbacks; + sp mGnssGeofencingCbIface; }; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android #endif // GEOFENCE_API_CLINET_H diff --git a/android/location_api/GnssAPIClient.cpp b/android/location_api/GnssAPIClient.cpp new file mode 100644 index 00000000..b4f04065 --- /dev/null +++ b/android/location_api/GnssAPIClient.cpp @@ -0,0 +1,406 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define LOG_NDDEBUG 0 +#define LOG_TAG "LocSvc_GnssAPIClient" + +#include +#include + +#include "LocationUtil.h" +#include "GnssAPIClient.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out); + +GnssAPIClient::GnssAPIClient(const sp& gpsCb, + const sp& niCb) : + LocationAPIClientBase(), + mGnssCbIface(nullptr), + mGnssNiCbIface(nullptr), + mLocationCapabilitiesMask(0) +{ + LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); + + // set default LocationOptions. + memset(&mLocationOptions, 0, sizeof(LocationOptions)); + mLocationOptions.size = sizeof(LocationOptions); + mLocationOptions.minInterval = 1000; + mLocationOptions.minDistance = 0; + mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; + + gnssUpdateCallbacks(gpsCb, niCb); +} + +GnssAPIClient::~GnssAPIClient() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); +} + +// for GpsInterface +void GnssAPIClient::gnssUpdateCallbacks(const sp& gpsCb, + const sp& niCb) +{ + LOC_LOGD("%s]: (%p %p)", __FUNCTION__, &gpsCb, &niCb); + + mGnssCbIface = gpsCb; + mGnssNiCbIface = niCb; + + LocationCallbacks locationCallbacks; + locationCallbacks.size = sizeof(LocationCallbacks); + + locationCallbacks.trackingCb = nullptr; + if (mGnssCbIface != nullptr) { + locationCallbacks.trackingCb = [this](Location location) { + onTrackingCb(location); + }; + } + + locationCallbacks.batchingCb = nullptr; + locationCallbacks.geofenceBreachCb = nullptr; + locationCallbacks.geofenceStatusCb = nullptr; + locationCallbacks.gnssLocationInfoCb = nullptr; + + locationCallbacks.gnssNiCb = nullptr; + if (mGnssNiCbIface != nullptr) { + locationCallbacks.gnssNiCb = [this](uint32_t id, GnssNiNotification gnssNiNotification) { + onGnssNiCb(id, gnssNiNotification); + }; + } + + locationCallbacks.gnssSvCb = nullptr; + if (mGnssCbIface != nullptr) { + locationCallbacks.gnssSvCb = [this](GnssSvNotification gnssSvNotification) { + onGnssSvCb(gnssSvNotification); + }; + } + + locationCallbacks.gnssNmeaCb = nullptr; + if (mGnssCbIface != nullptr) { + locationCallbacks.gnssNmeaCb = [this](GnssNmeaNotification gnssNmeaNotification) { + onGnssNmeaCb(gnssNmeaNotification); + }; + } + + locationCallbacks.gnssMeasurementsCb = nullptr; + + locAPISetCallbacks(locationCallbacks); +} + +bool GnssAPIClient::gnssStart() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + bool retVal = true; + locAPIStartTracking(mLocationOptions); + return retVal; +} + +bool GnssAPIClient::gnssStop() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + bool retVal = true; + locAPIStopTracking(); + return retVal; +} + +void GnssAPIClient::gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags) +{ + LOC_LOGD("%s]: (%02hx)", __FUNCTION__, aidingDataFlags); + GnssAidingData data; + memset(&data, 0, sizeof (GnssAidingData)); + data.sv.svTypeMask = GNSS_AIDING_DATA_SV_TYPE_GPS | + GNSS_AIDING_DATA_SV_TYPE_GLONASS | + GNSS_AIDING_DATA_SV_TYPE_QZSS | + GNSS_AIDING_DATA_SV_TYPE_BEIDOU | + GNSS_AIDING_DATA_SV_TYPE_GALILEO; + + if (aidingDataFlags == IGnss::GnssAidingData::DELETE_ALL) + data.deleteAll = true; + else { + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_EPHEMERIS) + data.sv.svMask |= GNSS_AIDING_DATA_SV_EPHEMERIS; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_ALMANAC) + data.sv.svMask |= GNSS_AIDING_DATA_SV_ALMANAC; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_POSITION) + data.common.mask |= GNSS_AIDING_DATA_COMMON_POSITION; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_TIME) + data.common.mask |= GNSS_AIDING_DATA_COMMON_TIME; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_IONO) + data.sv.svMask |= GNSS_AIDING_DATA_SV_IONOSPHERE; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_UTC) + data.common.mask |= GNSS_AIDING_DATA_COMMON_UTC; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_HEALTH) + data.sv.svMask |= GNSS_AIDING_DATA_SV_HEALTH; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVDIR) + data.sv.svMask |= GNSS_AIDING_DATA_SV_DIRECTION; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SVSTEER) + data.sv.svMask |= GNSS_AIDING_DATA_SV_STEER; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_SADATA) + data.sv.svMask |= GNSS_AIDING_DATA_SV_SA_DATA; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_RTI) + data.common.mask |= GNSS_AIDING_DATA_COMMON_RTI; + if (aidingDataFlags & IGnss::GnssAidingData::DELETE_CELLDB_INFO) + data.common.mask |= GNSS_AIDING_DATA_COMMON_CELLDB; + } + locAPIGnssDeleteAidingData(data); +} + +bool GnssAPIClient::gnssSetPositionMode(IGnss::GnssPositionMode mode, + IGnss::GnssPositionRecurrence recurrence, uint32_t minIntervalMs, + uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs) +{ + LOC_LOGD("%s]: (%d %d %d %d %d)", __FUNCTION__, + (int)mode, recurrence, minIntervalMs, preferredAccuracyMeters, preferredTimeMs); + bool retVal = true; + memset(&mLocationOptions, 0, sizeof(LocationOptions)); + mLocationOptions.size = sizeof(LocationOptions); + mLocationOptions.minInterval = minIntervalMs; + mLocationOptions.minDistance = preferredAccuracyMeters; + if (mode == IGnss::GnssPositionMode::STANDALONE) + mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; + else if (mode == IGnss::GnssPositionMode::MS_BASED) + mLocationOptions.mode = GNSS_SUPL_MODE_MSB; + else if (mode == IGnss::GnssPositionMode::MS_ASSISTED) + mLocationOptions.mode = GNSS_SUPL_MODE_MSA; + return retVal; +} + +// for GpsNiInterface +void GnssAPIClient::gnssNiRespond(int32_t notifId, + IGnssNiCallback::GnssUserResponseType userResponse) +{ + LOC_LOGD("%s]: (%d %d)", __FUNCTION__, notifId, static_cast(userResponse)); + GnssNiResponse data = GNSS_NI_RESPONSE_IGNORE; + if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT) + data = GNSS_NI_RESPONSE_ACCEPT; + else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY) + data = GNSS_NI_RESPONSE_DENY; + else if (userResponse == IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP) + data = GNSS_NI_RESPONSE_NO_RESPONSE; + locAPIGnssNiResponse(notifId, data); +} + +// for GnssConfigurationInterface +void GnssAPIClient::gnssConfigurationUpdate(const GnssConfig& gnssConfig) +{ + LOC_LOGD("%s]: (%02x)", __FUNCTION__, gnssConfig.flags); + locAPIGnssUpdateConfig(gnssConfig); +} + +// callbacks +void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) +{ + LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + mLocationCapabilitiesMask = capabilitiesMask; + if (mGnssCbIface != nullptr) { + uint32_t data = 0; + if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || + (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || + (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT) || + (capabilitiesMask & LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT)) + data |= IGnssCallback::Capabilities::SCHEDULING; + if (capabilitiesMask & LOCATION_CAPABILITIES_GEOFENCE_BIT) + data |= IGnssCallback::Capabilities::GEOFENCING; + if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) + data |= IGnssCallback::Capabilities::MEASUREMENTS; + if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) + data |= IGnssCallback::Capabilities::MSB; + if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) + data |= IGnssCallback::Capabilities::MSA; + mGnssCbIface->gnssSetCapabilitesCb(data); + } + if (mGnssCbIface != nullptr) { + IGnssCallback::GnssSystemInfo gnssInfo; + gnssInfo.yearOfHw = 2015; + if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT) { + gnssInfo.yearOfHw = 2017; + } + LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); + mGnssCbIface->gnssSetSystemInfoCb(gnssInfo); + } +} + +void GnssAPIClient::onTrackingCb(Location location) +{ + LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); + if (mGnssCbIface != nullptr) { + GnssLocation gnssLocation; + convertGnssLocation(location, gnssLocation); + mGnssCbIface->gnssLocationCb(gnssLocation); + } +} + +void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) +{ + LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); + + if (mGnssNiCbIface == nullptr) { + LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); + return; + } + + IGnssNiCallback::GnssNiNotification notificationGnss; + + notificationGnss.notificationId = id; + + if (gnssNiNotification.type == GNSS_NI_TYPE_VOICE) + notificationGnss.niType = IGnssNiCallback::GnssNiType::VOICE; + else if (gnssNiNotification.type == GNSS_NI_TYPE_SUPL) + notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_SUPL; + else if (gnssNiNotification.type == GNSS_NI_TYPE_CONTROL_PLANE) + notificationGnss.niType = IGnssNiCallback::GnssNiType::UMTS_CTRL_PLANE; + // GNSS_NI_TYPE_EMERGENCY_SUPL not supported + + if (gnssNiNotification.options == GNSS_NI_OPTIONS_NOTIFICATION) + notificationGnss.notifyFlags = + static_cast(IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY); + else if (gnssNiNotification.options == GNSS_NI_OPTIONS_VERIFICATION) + notificationGnss.notifyFlags = + static_cast(IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY); + else if (gnssNiNotification.options == GNSS_NI_OPTIONS_PRIVACY_OVERRIDE) + notificationGnss.notifyFlags = + static_cast(IGnssNiCallback::GnssNiNotifyFlags::PRIVACY_OVERRIDE); + + notificationGnss.timeoutSec = gnssNiNotification.timeout; + + if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_ACCEPT) + notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_ACCEPT; + else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_DENY) + notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_DENY; + else if (gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_NO_RESPONSE || + gnssNiNotification.timeoutResponse == GNSS_NI_RESPONSE_IGNORE) + notificationGnss.defaultResponse = IGnssNiCallback::GnssUserResponseType::RESPONSE_NORESP; + + notificationGnss.requestorId = gnssNiNotification.requestor; + + notificationGnss.notificationMessage = gnssNiNotification.message; + + if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_NONE) + notificationGnss.requestorIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_NONE; + else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) + notificationGnss.requestorIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; + else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UTF8) + notificationGnss.requestorIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; + else if (gnssNiNotification.requestorEncoding == GNSS_NI_ENCODING_TYPE_UCS2) + notificationGnss.requestorIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; + + if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_NONE) + notificationGnss.notificationIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_NONE; + else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_GSM_DEFAULT) + notificationGnss.notificationIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_GSM_DEFAULT; + else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UTF8) + notificationGnss.notificationIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UTF8; + else if (gnssNiNotification.messageEncoding == GNSS_NI_ENCODING_TYPE_UCS2) + notificationGnss.notificationIdEncoding = + IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; + + mGnssNiCbIface->niNotifyCb(notificationGnss); +} + +void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) +{ + LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); + if (mGnssCbIface != nullptr) { + IGnssCallback::GnssSvStatus svStatus; + convertGnssSvStatus(gnssSvNotification, svStatus); + mGnssCbIface->gnssSvStatusCb(svStatus); + } +} + +void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) +{ + if (mGnssCbIface != nullptr) { + android::hardware::hidl_string nmeaString; + nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); + mGnssCbIface->gnssNmeaCb(static_cast(gnssNmeaNotification.timestamp), + nmeaString); + } +} + +void GnssAPIClient::onStartTrackingCb(LocationError error) +{ + LOC_LOGD("%s]: (%d)", __FUNCTION__, error); + if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { + mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); + mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); + } +} + +void GnssAPIClient::onStopTrackingCb(LocationError error) +{ + LOC_LOGD("%s]: (%d)", __FUNCTION__, error); + if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { + mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); + mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); + } +} + +static void convertGnssSvStatus(GnssSvNotification& in, IGnssCallback::GnssSvStatus& out) +{ + memset(&out, 0, sizeof(IGnssCallback::GnssSvStatus)); + out.numSvs = in.count; + if (out.numSvs > static_cast(GnssMax::SVS_COUNT)) { + LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.", + __FUNCTION__, out.numSvs, GnssMax::SVS_COUNT); + out.numSvs = static_cast(GnssMax::SVS_COUNT); + } + for (size_t i = 0; i < out.numSvs; i++) { + IGnssCallback::GnssSvInfo& info = out.gnssSvList[i]; + info.svid = in.gnssSvs[i].svId; + convertGnssConstellationType(in.gnssSvs[i].type, info.constellation); + info.cN0Dbhz = in.gnssSvs[i].cN0Dbhz; + info.elevationDegrees = in.gnssSvs[i].elevation; + info.azimuthDegrees = in.gnssSvs[i].azimuth; + info.svFlag = static_cast(IGnssCallback::GnssSvFlags::NONE); + if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT) + info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA; + if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT) + info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA; + if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT) + info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX; + } +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/GnssAPIClient.h b/android/location_api/GnssAPIClient.h similarity index 69% rename from android/GnssAPIClient.h rename to android/location_api/GnssAPIClient.h index 77bfa527..1809c09d 100644 --- a/android/GnssAPIClient.h +++ b/android/location_api/GnssAPIClient.h @@ -30,42 +30,46 @@ #ifndef GNSS_API_CLINET_H #define GNSS_API_CLINET_H -#include +#include +#include +#include #include +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +using ::android::sp; + class GnssAPIClient : public LocationAPIClientBase { public: - GnssAPIClient(GpsCallbacks* gpsCb, - GpsNiCallbacks* niCb, - GpsMeasurementCallbacks* measurementCb); + GnssAPIClient(const sp& gpsCb, + const sp& niCb); virtual ~GnssAPIClient(); GnssAPIClient(const GnssAPIClient&) = delete; GnssAPIClient& operator=(const GnssAPIClient&) = delete; // for GpsInterface - void gnssUpdateCallbacks(GpsCallbacks* gpsCb, - GpsNiCallbacks* niCb, - GpsMeasurementCallbacks* measurementCb); - int gnssStart(); - int gnssStop(); - void gnssDeleteAidingData(GpsAidingData f); - int gnssSetPositionMode(GpsPositionMode mode, GpsPositionRecurrence recurrence, - uint32_t min_interval, uint32_t preferred_accuracy, - uint32_t preferred_time); - - // for AGpsInterface - void gnssAgnssSetServer(AGpsType type, const char *hostname, int port); + void gnssUpdateCallbacks(const sp& gpsCb, + const sp& niCb); + bool gnssStart(); + bool gnssStop(); + void gnssDeleteAidingData(IGnss::GnssAidingData aidingDataFlags); + bool gnssSetPositionMode(IGnss::GnssPositionMode mode, + IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, + uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs); // for GpsNiInterface - void gnssNiRespond(int notif_id, GpsUserResponseType user_response); - - // for GpsMeasurementInterface - void gnssMeasurementClose(); + void gnssNiRespond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse); // for GnssConfigurationInterface - void gnssConfigurationUpdate(const char* config_data, int32_t length); + void gnssConfigurationUpdate(const GnssConfig& gnssConfig); inline LocationCapabilitiesMask gnssGetCapabilities() const { return mLocationCapabilitiesMask; @@ -77,21 +81,22 @@ public: void onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) final; void onGnssSvCb(GnssSvNotification gnssSvNotification) final; void onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) final; - void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final; void onStartTrackingCb(LocationError error) final; void onStopTrackingCb(LocationError error) final; private: - pthread_mutex_t mLock; - - GpsCallbacks* mGpsCallbacks; - GpsNiCallbacks* mGpsNiCallbacks; + sp mGnssCbIface; + sp mGnssNiCbIface; LocationCapabilitiesMask mLocationCapabilitiesMask; - GpsMeasurementCallbacks* mGpsMeasurementCallbacks; - LocationOptions mLocationOptions; }; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android #endif // GNSS_API_CLINET_H diff --git a/android/location_api/GnssMeasurementAPIClient.cpp b/android/location_api/GnssMeasurementAPIClient.cpp new file mode 100644 index 00000000..32016251 --- /dev/null +++ b/android/location_api/GnssMeasurementAPIClient.cpp @@ -0,0 +1,278 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#define LOG_NDDEBUG 0 +#define LOG_TAG "LocSvc_GnssMeasurementAPIClient" + +#include +#include + +#include "LocationUtil.h" +#include "GnssMeasurementAPIClient.h" + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +static void convertGnssData(GnssMeasurementsNotification& in, + IGnssMeasurementCallback::GnssData& out); +static void convertGnssMeasurement(GnssMeasurementsData& in, + IGnssMeasurementCallback::GnssMeasurement& out); +static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out); + +GnssMeasurementAPIClient::GnssMeasurementAPIClient() : + mGnssMeasurementCbIface(nullptr), + mLocationCapabilitiesMask(0) +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + pthread_mutex_init(&mLock, nullptr); + pthread_cond_init (&mCond, nullptr); + + // set default LocationOptions. + memset(&mLocationOptions, 0, sizeof(LocationOptions)); + mLocationOptions.size = sizeof(LocationOptions); + mLocationOptions.minInterval = 1000; + mLocationOptions.minDistance = 0; + mLocationOptions.mode = GNSS_SUPL_MODE_STANDALONE; +} + +GnssMeasurementAPIClient::~GnssMeasurementAPIClient() +{ + LOC_LOGD("%s]: ()", __FUNCTION__); + pthread_cond_destroy(&mCond); + pthread_mutex_destroy(&mLock); +} + +// for GpsInterface +Return +GnssMeasurementAPIClient::gnssMeasurementSetCallback(const sp& callback) +{ + LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback); + + mGnssMeasurementCbIface = callback; + + LocationCallbacks locationCallbacks; + locationCallbacks.size = sizeof(LocationCallbacks); + + locationCallbacks.trackingCb = nullptr; + locationCallbacks.batchingCb = nullptr; + locationCallbacks.geofenceBreachCb = nullptr; + locationCallbacks.geofenceStatusCb = nullptr; + locationCallbacks.gnssLocationInfoCb = nullptr; + locationCallbacks.gnssNiCb = nullptr; + locationCallbacks.gnssSvCb = nullptr; + locationCallbacks.gnssNmeaCb = nullptr; + + locationCallbacks.gnssMeasurementsCb = nullptr; + if (mGnssMeasurementCbIface != nullptr) { + locationCallbacks.gnssMeasurementsCb = + [this](GnssMeasurementsNotification gnssMeasurementsNotification) { + onGnssMeasurementsCb(gnssMeasurementsNotification); + }; + } + + locAPISetCallbacks(locationCallbacks); + + while (!mLocationCapabilitiesMask) { + LOC_LOGD("%s]: wait for capabilities...", __FUNCTION__); + pthread_mutex_lock(&mLock); + pthread_cond_wait(&mCond, &mLock); + pthread_mutex_unlock(&mLock); + } + if (mLocationCapabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) + mLocationOptions.mode = GNSS_SUPL_MODE_MSB; + else if (mLocationCapabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) + mLocationOptions.mode = GNSS_SUPL_MODE_MSA; + LOC_LOGD("%s]: start tracking session", __FUNCTION__); + locAPIStartTracking(mLocationOptions); + + return IGnssMeasurement::GnssMeasurementStatus::SUCCESS; +} + +// for GpsMeasurementInterface +void GnssMeasurementAPIClient::gnssMeasurementClose() { + LOC_LOGD("%s]: ()", __FUNCTION__); + pthread_mutex_lock(&mLock); + mGnssMeasurementCbIface = nullptr; + pthread_mutex_unlock(&mLock); +} + +// callbacks +void GnssMeasurementAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) +{ + LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); + mLocationCapabilitiesMask = capabilitiesMask; + pthread_mutex_lock(&mLock); + pthread_cond_signal(&mCond); + pthread_mutex_unlock(&mLock); +} + +void GnssMeasurementAPIClient::onGnssMeasurementsCb( + GnssMeasurementsNotification gnssMeasurementsNotification) +{ + LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssMeasurementsNotification.count); + // we don't need to lock the mutext + // if mGnssMeasurementCbIface is set to nullptr + if (mGnssMeasurementCbIface != nullptr) { + pthread_mutex_lock(&mLock); + if (mGnssMeasurementCbIface != nullptr) { + IGnssMeasurementCallback::GnssData gnssData; + convertGnssData(gnssMeasurementsNotification, gnssData); + mGnssMeasurementCbIface->GnssMeasurementCb(gnssData); + } + pthread_mutex_unlock(&mLock); + } +} + +static void convertGnssMeasurement(GnssMeasurementsData& in, + IGnssMeasurementCallback::GnssMeasurement& out) +{ + memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssMeasurement)); + if (in.flags & GNSS_MEASUREMENTS_DATA_SIGNAL_TO_NOISE_RATIO_BIT) + out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_SNR; + if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_FREQUENCY_BIT) + out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_FREQUENCY; + if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_CYCLES_BIT) + out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_CYCLES; + if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_BIT) + out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE; + if (in.flags & GNSS_MEASUREMENTS_DATA_CARRIER_PHASE_UNCERTAINTY_BIT) + out.flags |= IGnssMeasurementCallback::GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY; + out.svid = in.svId; + convertGnssConstellationType(in.svType, out.constellation); + out.timeOffsetNs = in.timeOffsetNs; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_CODE_LOCK_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_CODE_LOCK; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_BIT_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BIT_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_SUBFRAME_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SUBFRAME_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_TOW_DECODED_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_TOW_DECODED; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_MSEC_AMBIGUOUS_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_MSEC_AMBIGUOUS; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_SYMBOL_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SYMBOL_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_STRING_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_STRING_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_GLO_TOD_DECODED_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GLO_TOD_DECODED; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_BIT_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_BIT_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_BDS_D2_SUBFRAME_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_BDS_D2_SUBFRAME_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1BC_CODE_LOCK_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1BC_CODE_LOCK; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1C_2ND_CODE_LOCK_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1C_2ND_CODE_LOCK; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_GAL_E1B_PAGE_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_GAL_E1B_PAGE_SYNC; + if (in.stateMask & GNSS_MEASUREMENTS_STATE_SBAS_SYNC_BIT) + out.state |= IGnssMeasurementCallback::GnssMeasurementState::STATE_SBAS_SYNC; + out.receivedSvTimeInNs = in.receivedSvTimeNs; + out.receivedSvTimeUncertaintyInNs = in.receivedSvTimeUncertaintyNs; + out.cN0DbHz = in.carrierToNoiseDbHz; + out.pseudorangeRateMps = in.pseudorangeRateMps; + out.pseudorangeRateUncertaintyMps = in.pseudorangeRateUncertaintyMps; + if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_VALID_BIT) + out.accumulatedDeltaRangeState |= + IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_VALID; + if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_RESET_BIT) + out.accumulatedDeltaRangeState |= + IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_RESET; + if (in.adrStateMask & GNSS_MEASUREMENTS_ACCUMULATED_DELTA_RANGE_STATE_CYCLE_SLIP_BIT) + out.accumulatedDeltaRangeState |= + IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState::ADR_STATE_CYCLE_SLIP; + out.accumulatedDeltaRangeM = in.adrMeters; + out.accumulatedDeltaRangeUncertaintyM = in.adrUncertaintyMeters; + out.carrierFrequencyHz = in.carrierFrequencyHz; + out.carrierCycles = in.carrierCycles; + out.carrierPhase = in.carrierPhase; + out.carrierPhaseUncertainty = in.carrierPhaseUncertainty; + uint8_t indicator = + static_cast(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN); + if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT) + indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT; + if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT) + indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT; + out.multipathIndicator = + static_cast(indicator); + out.snrDb = in.signalToNoiseRatioDb; +} + +static void convertGnssClock(GnssMeasurementsClock& in, IGnssMeasurementCallback::GnssClock& out) +{ + memset(&out, 0, sizeof(IGnssMeasurementCallback::GnssClock)); + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_LEAP_SECOND_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_LEAP_SECOND; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_TIME_UNCERTAINTY_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_TIME_UNCERTAINTY; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_FULL_BIAS_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_FULL_BIAS; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_BIAS_UNCERTAINTY_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_BIAS_UNCERTAINTY; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT; + if (in.flags & GNSS_MEASUREMENTS_CLOCK_FLAGS_DRIFT_UNCERTAINTY_BIT) + out.gnssClockFlags |= IGnssMeasurementCallback::GnssClockFlags::HAS_DRIFT_UNCERTAINTY; + out.leapSecond = in.leapSecond; + out.timeNs = in.timeNs; + out.timeUncertaintyNs = in.timeUncertaintyNs; + out.fullBiasNs = in.fullBiasNs; + out.biasNs = in.biasNs; + out.biasUncertaintyNs = in.biasUncertaintyNs; + out.driftNsps = in.driftNsps; + out.driftUncertaintyNsps = in.driftUncertaintyNsps; + out.hwClockDiscontinuityCount = in.hwClockDiscontinuityCount; +} + +static void convertGnssData(GnssMeasurementsNotification& in, + IGnssMeasurementCallback::GnssData& out) +{ + out.measurementCount = in.count; + if (out.measurementCount > static_cast(GnssMax::SVS_COUNT)) { + LOC_LOGW("%s]: Too many measurement %zd. Clamps to %d.", + __FUNCTION__, out.measurementCount, GnssMax::SVS_COUNT); + out.measurementCount = static_cast(GnssMax::SVS_COUNT); + } + for (size_t i = 0; i < out.measurementCount; i++) { + convertGnssMeasurement(in.measurements[i], out.measurements[i]); + } + convertGnssClock(in.clock, out.clock); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/location_api/GnssMeasurementAPIClient.h b/android/location_api/GnssMeasurementAPIClient.h new file mode 100644 index 00000000..02fe89ae --- /dev/null +++ b/android/location_api/GnssMeasurementAPIClient.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GNSS_MEASUREMENT_API_CLINET_H +#define GNSS_MEASUREMENT_API_CLINET_H + + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::gnss::V1_0::IGnssMeasurement; +using ::android::sp; + +class GnssMeasurementAPIClient : public LocationAPIClientBase +{ +public: + GnssMeasurementAPIClient(); + virtual ~GnssMeasurementAPIClient(); + GnssMeasurementAPIClient(const GnssMeasurementAPIClient&) = delete; + GnssMeasurementAPIClient& operator=(const GnssMeasurementAPIClient&) = delete; + + // for GpsMeasurementInterface + Return gnssMeasurementSetCallback( + const sp& callback); + void gnssMeasurementClose(); + + // callbacks we are interested in + void onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) final; + void onGnssMeasurementsCb(GnssMeasurementsNotification gnssMeasurementsNotification) final; + +private: + pthread_mutex_t mLock; + pthread_cond_t mCond; + + sp mGnssMeasurementCbIface; + + LocationCapabilitiesMask mLocationCapabilitiesMask; + + LocationOptions mLocationOptions; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // GNSS_MEASUREMENT_API_CLINET_H diff --git a/android/location_api/LocationUtil.cpp b/android/location_api/LocationUtil.cpp new file mode 100644 index 00000000..dbafe5d3 --- /dev/null +++ b/android/location_api/LocationUtil.cpp @@ -0,0 +1,98 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { + +void convertGnssLocation(Location& in, GnssLocation& out) +{ + memset(&out, 0, sizeof(GnssLocation)); + if (in.flags & LOCATION_HAS_LAT_LONG_BIT) + out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG; + if (in.flags & LOCATION_HAS_ALTITUDE_BIT) + out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE; + if (in.flags & LOCATION_HAS_SPEED_BIT) + out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED; + if (in.flags & LOCATION_HAS_BEARING_BIT) + out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING; + if (in.flags & LOCATION_HAS_ACCURACY_BIT) { + out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY; + //out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY; + //out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY; + //out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY; + } + out.latitudeDegrees = in.latitude; + out.longitudeDegrees = in.longitude; + out.altitudeMeters = in.altitude; + out.speedMetersPerSec = in.speed; + out.bearingDegrees = in.bearing; + out.horizontalAccuracyMeters = in.accuracy; + //out.verticalAccuracyMeters = in.accuracy; + //out.speedAccuracyMetersPerSecond = in.accuracy; + //out.bearingAccuracyDegrees = in.accuracy; + out.timestamp = static_cast(in.timestamp); +} + +void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out) +{ + switch(in) { + case GNSS_SV_TYPE_GPS: + out = GnssConstellationType::UNKNOWN; + break; + case GNSS_SV_TYPE_SBAS: + out = GnssConstellationType::SBAS; + break; + case GNSS_SV_TYPE_GLONASS: + out = GnssConstellationType::GLONASS; + break; + case GNSS_SV_TYPE_QZSS: + out = GnssConstellationType::QZSS; + break; + case GNSS_SV_TYPE_BEIDOU: + out = GnssConstellationType::BEIDOU; + break; + case GNSS_SV_TYPE_GALILEO: + out = GnssConstellationType::GALILEO; + break; + default: + out = GnssConstellationType::UNKNOWN; + break; + } +} + +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/android/gps.c b/android/location_api/LocationUtil.h similarity index 52% rename from android/gps.c rename to android/location_api/LocationUtil.h index a7248551..de098b11 100644 --- a/android/gps.c +++ b/android/location_api/LocationUtil.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2015-2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -9,7 +9,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * * Neither the name of The Linux Foundation nor the names of its + * * Neither the name of The Linux Foundation, nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,51 +27,24 @@ * */ -#include +#ifndef LOCATION_UTIL_H +#define LOCATION_UTIL_H -#include -#include +#include +#include -#define UNUSED(...) (void)(__VA_ARGS__) +namespace android { +namespace hardware { +namespace gnss { +namespace V1_0 { +namespace implementation { -extern const GpsInterface* get_gps_interface(); +void convertGnssLocation(Location& in, GnssLocation& out); +void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out); -const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev) -{ - UNUSED(dev); - return get_gps_interface(); -} - -static int open_gps(const struct hw_module_t* module, char const* name, - struct hw_device_t** device) -{ - UNUSED(name); - struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t)); - - if(dev == NULL) - return -1; - - memset(dev, 0, sizeof(*dev)); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t*)module; - dev->get_gps_interface = gps__get_gps_interface; - - *device = (struct hw_device_t*)dev; - return 0; -} - -static struct hw_module_methods_t gps_module_methods = { - .open = open_gps -}; - -struct hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = 1, - .hal_api_version = 0, - .id = GPS_HARDWARE_MODULE_ID, - .name = "loc_api GPS Module", - .author = "Qualcomm USA, Inc.", - .methods = &gps_module_methods, -}; +} // namespace implementation +} // namespace V1_0 +} // namespace gnss +} // namespace hardware +} // namespace android +#endif // LOCATION_UTIL_H diff --git a/android/service.cpp b/android/service.cpp new file mode 100644 index 00000000..bfa0d884 --- /dev/null +++ b/android/service.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Not a Contribution + */ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.gnss@1.0-service-qti" + +#include +#include + +using android::hardware::gnss::V1_0::IGnss; +using android::hardware::defaultPassthroughServiceImplementation; + +int main() { + return defaultPassthroughServiceImplementation("gnss"); +} diff --git a/core/Android.mk b/core/Android.mk index 53dcb6bd..b260b1dc 100644 --- a/core/Android.mk +++ b/core/Android.mk @@ -17,6 +17,7 @@ LOCAL_CFLAGS += -DPDK_FEATURE_SET endif LOCAL_SHARED_LIBRARIES := \ + liblog \ libutils \ libcutils \ libgps.utils \ diff --git a/utils/platform_lib_abstractions/loc_pla/src/Android.mk b/utils/platform_lib_abstractions/loc_pla/src/Android.mk index f3cedd5b..ad07197b 100644 --- a/utils/platform_lib_abstractions/loc_pla/src/Android.mk +++ b/utils/platform_lib_abstractions/loc_pla/src/Android.mk @@ -11,7 +11,8 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ liblog \ - libloc_stub + libloc_stub \ + libandroid_runtime LOCAL_SRC_FILES += \ platform_lib_android_runtime.cpp \ @@ -26,9 +27,6 @@ LOCAL_CFLAGS += \ -D_ANDROID_ \ -std=c++11 - -LOCAL_LDFLAGS += -Wl,--export-dynamic - ## Includes LOCAL_C_INCLUDES:= \ $(LOCAL_PATH)/../include \