hidl gnss hal 1.0 implementation

Overwrites the default hidl gnss hal implementation
to interface directly to LocationAPI

CRs-fixed: 1112712

Change-Id: I3385911956c0c6c457202a8584b108046c587b36
This commit is contained in:
Dante Russo 2017-02-28 16:45:59 -08:00
parent c85c8ff673
commit 52b413eb44
32 changed files with 2982 additions and 1429 deletions

66
android/AGnss.cpp Normal file
View file

@ -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 <log_util.h>
#include "Gnss.h"
#include "AGnss.h"
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
AGnss::AGnss(Gnss* gnss) : mGnss(gnss) {
}
Return<bool> 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<int>(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

80
android/AGnss.h Normal file
View file

@ -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 <android/hardware/gnss/1.0/IAGnss.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IAGnss;
using ::android::hardware::gnss::V1_0::IAGnssCallback;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
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<void> setCallback(const sp<IAGnssCallback>& /*callback*/) override {
return Void();
}
inline Return<bool> dataConnClosed() override {
return false;
}
inline Return<bool> dataConnFailed() override {
return false;
}
inline Return<bool> dataConnOpen(const hidl_string& /*apn*/,
IAGnss::ApnIpType /*apnIpType*/) override {
return false;
}
Return<bool> 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

View file

@ -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)

326
android/Gnss.cpp Normal file
View file

@ -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 <log_util.h>
#include <dlfcn.h>
#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<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnss != nullptr) {
mGnss->stop();
mGnss->cleanup();
}
}
Gnss::Gnss() {
ENTRY_LOG_CALLFLOW();
// clear pending GnssConfig
memset(&mPendingConfig, 0, sizeof(GnssConfig));
mGnssDeathRecipient = new GnssDeathRecipient(this);
}
Gnss::~Gnss() {
ENTRY_LOG_CALLFLOW();
if (mApi != nullptr) {
delete mApi;
mApi = nullptr;
}
}
GnssAPIClient* Gnss::getApi() {
if (mApi == nullptr && (mGnssCbIface != nullptr || mGnssNiCbIface != nullptr)) {
mApi = new GnssAPIClient(mGnssCbIface, mGnssNiCbIface);
if (mApi == nullptr) {
LOC_LOGE("%s] faild to create GnssAPIClient", __FUNCTION__);
return mApi;
}
if (mPendingConfig.size == sizeof(GnssConfig)) {
// we have pending GnssConfig
mApi->gnssConfigurationUpdate(mPendingConfig);
// clear size to invalid mPendingConfig
mPendingConfig.size = 0;
if (mPendingConfig.assistanceServer.hostName != nullptr) {
free((void*)mPendingConfig.assistanceServer.hostName);
}
}
}
if (mApi == nullptr) {
LOC_LOGW("%s] GnssAPIClient is not ready", __FUNCTION__);
}
return mApi;
}
GnssInterface* Gnss::getGnssInterface() {
static bool getGnssInterfaceFailed = false;
if (nullptr == mGnssInterface && !getGnssInterfaceFailed) {
LOC_LOGD("%s]: loading libgnss.so::getGnssInterface ...", __func__);
getLocationInterface* getter = NULL;
const char *error;
dlerror();
void *handle = dlopen("libgnss.so", RTLD_NOW);
if (NULL == handle || (error = dlerror()) != NULL) {
LOC_LOGW("dlopen for libgnss.so failed, error = %s", error);
} else {
getter = (getLocationInterface*)dlsym(handle, "getGnssInterface");
if ((error = dlerror()) != NULL) {
LOC_LOGW("dlsym for libgnss.so::getGnssInterface failed, error = %s", error);
getter = NULL;
}
}
if (NULL == getter) {
getGnssInterfaceFailed = true;
} else {
mGnssInterface = (GnssInterface*)(*getter)();
}
}
return mGnssInterface;
}
Return<bool> Gnss::setCallback(const sp<IGnssCallback>& callback) {
ENTRY_LOG_CALLFLOW();
if (mGnssCbIface != nullptr) {
mGnssCbIface->unlinkToDeath(mGnssDeathRecipient);
}
mGnssCbIface = callback;
if (mGnssCbIface != nullptr) {
mGnssCbIface->linkToDeath(mGnssDeathRecipient, 0 /*cookie*/);
}
GnssAPIClient* api = getApi();
if (api != nullptr) {
api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
api->locAPIEnable(LOCATION_TECHNOLOGY_TYPE_GNSS);
}
return true;
}
Return<bool> Gnss::setGnssNiCb(const sp<IGnssNiCallback>& callback) {
ENTRY_LOG_CALLFLOW();
mGnssNiCbIface = callback;
GnssAPIClient* api = getApi();
if (api != nullptr) {
api->gnssUpdateCallbacks(mGnssCbIface, mGnssNiCbIface);
}
return true;
}
Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
ENTRY_LOG_CALLFLOW();
GnssAPIClient* api = getApi();
if (api) {
api->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<bool> Gnss::start() {
ENTRY_LOG_CALLFLOW();
bool retVal = false;
GnssAPIClient* api = getApi();
if (api) {
retVal = api->gnssStart();
}
return retVal;
}
Return<bool> Gnss::stop() {
ENTRY_LOG_CALLFLOW();
bool retVal = false;
GnssAPIClient* api = getApi();
if (api) {
retVal = api->gnssStop();
}
return retVal;
}
Return<void> Gnss::cleanup() {
ENTRY_LOG_CALLFLOW();
if (mApi != nullptr) {
mApi->locAPIDisable();
}
return Void();
}
Return<bool> Gnss::injectLocation(double latitudeDegrees,
double longitudeDegrees,
float accuracyMeters) {
ENTRY_LOG_CALLFLOW();
GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectLocation(latitudeDegrees, longitudeDegrees, accuracyMeters);
return true;
} else {
return false;
}
}
Return<bool> Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs,
int32_t uncertaintyMs) {
ENTRY_LOG_CALLFLOW();
GnssInterface* gnssInterface = getGnssInterface();
if (nullptr != gnssInterface) {
gnssInterface->injectTime(timeMs, timeReferenceMs, uncertaintyMs);
return true;
} else {
return false;
}
}
Return<void> Gnss::deleteAidingData(IGnss::GnssAidingData aidingDataFlags) {
ENTRY_LOG_CALLFLOW();
GnssAPIClient* api = getApi();
if (api) {
api->gnssDeleteAidingData(aidingDataFlags);
}
return Void();
}
Return<bool> 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<sp<IAGnss>> Gnss::getExtensionAGnss() {
ENTRY_LOG_CALLFLOW();
mAGnssIface = new AGnss(this);
return mAGnssIface;
}
Return<sp<IGnssNi>> Gnss::getExtensionGnssNi() {
ENTRY_LOG_CALLFLOW();
mGnssNi = new GnssNi(this);
return mGnssNi;
}
Return<sp<IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
ENTRY_LOG_CALLFLOW();
mGnssMeasurement = new GnssMeasurement();
return mGnssMeasurement;
}
Return<sp<IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
ENTRY_LOG_CALLFLOW();
mGnssConfig = new GnssConfiguration(this);
return mGnssConfig;
}
Return<sp<IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
ENTRY_LOG_CALLFLOW();
mGnssGeofencingIface = new GnssGeofencing();
return mGnssGeofencingIface;
}
Return<sp<IGnssBatching>> 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

149
android/Gnss.h Normal file
View file

@ -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 <AGnss.h>
#include <GnssBatching.h>
#include <GnssConfiguration.h>
#include <GnssGeofencing.h>
#include <GnssMeasurement.h>
#include <GnssNi.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/Status.h>
#include <GnssAPIClient.h>
#include <location_interface.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
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<void> 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<bool> setCallback(const sp<IGnssCallback>& callback) override;
Return<bool> start() override;
Return<bool> stop() override;
Return<void> cleanup() override;
Return<bool> injectLocation(double latitudeDegrees,
double longitudeDegrees,
float accuracyMeters) override;
Return<bool> injectTime(int64_t timeMs,
int64_t timeReferenceMs,
int32_t uncertaintyMs) override;
Return<void> deleteAidingData(IGnss::GnssAidingData aidingDataFlags) override;
Return<bool> setPositionMode(IGnss::GnssPositionMode mode,
IGnss::GnssPositionRecurrence recurrence,
uint32_t minIntervalMs,
uint32_t preferredAccuracyMeters,
uint32_t preferredTimeMs) override;
Return<sp<IAGnss>> getExtensionAGnss() override;
Return<sp<IGnssNi>> getExtensionGnssNi() override;
Return<sp<IGnssMeasurement>> getExtensionGnssMeasurement() override;
Return<sp<IGnssConfiguration>> getExtensionGnssConfiguration() override;
Return<sp<IGnssGeofencing>> getExtensionGnssGeofencing() override;
Return<sp<IGnssBatching>> getExtensionGnssBatching() override;
inline Return<sp<IAGnssRil>> getExtensionAGnssRil() override {
return nullptr;
}
inline Return<sp<IGnssNavigationMessage>> getExtensionGnssNavigationMessage() override {
return nullptr;
}
inline Return<sp<IGnssXtra>> getExtensionXtra() override {
return nullptr;
}
inline Return<sp<IGnssDebug>> getExtensionGnssDebug() override {
return nullptr;
}
// These methods are not part of the IGnss base class.
GnssAPIClient* getApi();
Return<bool> setGnssNiCb(const sp<IGnssNiCallback>& niCb);
Return<bool> updateConfiguration(GnssConfig& gnssConfig);
GnssInterface* getGnssInterface();
private:
struct GnssDeathRecipient : hidl_death_recipient {
GnssDeathRecipient(sp<Gnss> gnss) : mGnss(gnss) {
}
~GnssDeathRecipient() = default;
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
sp<Gnss> mGnss;
};
private:
sp<GnssDeathRecipient> mGnssDeathRecipient = nullptr;
sp<AGnss> mAGnssIface = nullptr;
sp<GnssNi> mGnssNi = nullptr;
sp<GnssMeasurement> mGnssMeasurement = nullptr;
sp<GnssConfiguration> mGnssConfig = nullptr;
sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
sp<GnssBatching> mGnssBatching = nullptr;
GnssAPIClient* mApi = nullptr;
sp<IGnssCallback> mGnssCbIface = nullptr;
sp<IGnssNiCallback> 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

View file

@ -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 <log_util.h>
#include <loc_cfg.h>
#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);
}

129
android/GnssBatching.cpp Normal file
View file

@ -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 <log_util.h>
#include <FlpAPIClient.h>
#include "GnssBatching.h"
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
void GnssBatching::GnssBatchingDeathRecipient::serviceDied(
uint64_t cookie, const wp<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnssBatching != nullptr) {
mGnssBatching->stop();
mGnssBatching->cleanup();
}
}
GnssBatching::GnssBatching() : mApi(nullptr) {
mGnssBatchingDeathRecipient = new GnssBatchingDeathRecipient(this);
}
GnssBatching::~GnssBatching() {
if (mApi != nullptr) {
delete mApi;
mApi = nullptr;
}
}
// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
if (mApi != nullptr) {
LOC_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<uint16_t> GnssBatching::getBatchSize() {
uint16_t ret = 0;
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
ret = mApi->flpGetBatchSize();
}
return ret;
}
Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
bool ret = false;
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
ret = mApi->flpStartSession(options);
}
return ret;
}
Return<void> GnssBatching::flush() {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
mApi->flpFlushBatchedLocations();
}
return Void();
}
Return<bool> GnssBatching::stop() {
bool ret = false;
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
ret = mApi->flpStopSession();
}
return ret;
}
Return<void> GnssBatching::cleanup() {
if (mGnssBatchingCbIface != nullptr) {
mGnssBatchingCbIface->unlinkToDeath(mGnssBatchingDeathRecipient);
}
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

80
android/GnssBatching.h Normal file
View file

@ -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 <android/hardware/gnss/1.0/IGnssBatching.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssBatching;
using ::android::hardware::gnss::V1_0::IGnssBatchingCallback;
using ::android::hidl::base::V1_0::IBase;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
class FlpAPIClient;
struct GnssBatching : public IGnssBatching {
GnssBatching();
~GnssBatching();
// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
Return<bool> init(const sp<IGnssBatchingCallback>& callback) override;
Return<uint16_t> getBatchSize() override;
Return<bool> start(const IGnssBatching::Options& options ) override;
Return<void> flush() override;
Return<bool> stop() override;
Return<void> cleanup() override;
private:
struct GnssBatchingDeathRecipient : hidl_death_recipient {
GnssBatchingDeathRecipient(sp<GnssBatching> gnssBatching) :
mGnssBatching(gnssBatching) {
}
~GnssBatchingDeathRecipient() = default;
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
sp<GnssBatching> mGnssBatching;
};
private:
sp<GnssBatchingDeathRecipient> mGnssBatchingDeathRecipient = nullptr;
sp<IGnssBatchingCallback> mGnssBatchingCbIface = nullptr;
FlpAPIClient* mApi = nullptr;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSBATCHING_H

View file

@ -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 <log_util.h>
#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<bool> GnssConfiguration::setSuplEs(bool enabled) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT;
config.suplEmergencyServices = static_cast<GnssConfigSuplEmergencyServices>(enabled);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setSuplVersion(uint32_t version) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT;
config.suplVersion = static_cast<GnssConfigSuplVersion>(version);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setSuplMode(uint8_t mode) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
config.suplModeMask = static_cast<GnssConfigSuplModeMask>(mode);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setLppProfile(uint8_t lppProfile) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT;
config.lppProfile = static_cast<GnssConfigLppProfile>(lppProfile);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setGlonassPositioningProtocol(uint8_t protocol) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT;
config.aGlonassPositionProtocolMask =
static_cast<GnssConfigAGlonassPositionProtocolMask>(protocol);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setGpsLock(uint8_t lock) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT;
config.gpsLock = static_cast<GnssConfigGpsLock>(lock);
return mGnss->updateConfiguration(config);
}
Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return false;
}
GnssConfig config;
memset(&config, 0, sizeof(GnssConfig));
config.size = sizeof(GnssConfig);
config.flags = GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT;
config.emergencyPdnForEmergencySupl =
static_cast<GnssConfigEmergencyPdnForEmergencySupl>(enabled);
return mGnss->updateConfiguration(config);
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

View file

@ -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 <android/hardware/gnss/1.0/IGnssConfiguration.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssConfiguration;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
/*
* Interface for passing GNSS configuration info from platform to HAL.
*/
struct 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<bool> setSuplVersion(uint32_t version) override;
Return<bool> setSuplMode(uint8_t mode) override;
Return<bool> setSuplEs(bool enabled) override;
Return<bool> setLppProfile(uint8_t lppProfile) override;
Return<bool> setGlonassPositioningProtocol(uint8_t protocol) override;
Return<bool> setEmergencySuplPdn(bool enable) override;
Return<bool> setGpsLock(uint8_t lock) override;
private:
Gnss* mGnss = nullptr;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H

141
android/GnssGeofencing.cpp Normal file
View file

@ -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 <log_util.h>
#include <GeofenceAPIClient.h>
#include "GnssGeofencing.h"
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
void GnssGeofencing::GnssGeofencingDeathRecipient::serviceDied(
uint64_t cookie, const wp<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnssGeofencing != nullptr) {
mGnssGeofencing->removeAllGeofences();
}
}
GnssGeofencing::GnssGeofencing() : mApi(nullptr) {
mGnssGeofencingDeathRecipient = new GnssGeofencingDeathRecipient(this);
}
GnssGeofencing::~GnssGeofencing() {
if (mApi != nullptr) {
delete mApi;
mApi = nullptr;
}
}
// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
if (mApi != nullptr) {
LOC_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<void> GnssGeofencing::addGeofence(
int32_t geofenceId,
double latitudeDegrees,
double longitudeDegrees,
double radiusMeters,
IGnssGeofenceCallback::GeofenceTransition lastTransition,
int32_t monitorTransitions,
uint32_t notificationResponsivenessMs,
uint32_t unknownTimerMs) {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
mApi->geofenceAdd(
geofenceId,
latitudeDegrees,
longitudeDegrees,
radiusMeters,
static_cast<int32_t>(lastTransition),
monitorTransitions,
notificationResponsivenessMs,
unknownTimerMs);
}
return Void();
}
Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
mApi->geofencePause(geofenceId);
}
return Void();
}
Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
mApi->geofenceResume(geofenceId, monitorTransitions);
}
return Void();
}
Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
} else {
mApi->geofenceRemove(geofenceId);
}
return Void();
}
Return<void> GnssGeofencing::removeAllGeofences() {
if (mApi == nullptr) {
LOC_LOGD("%s]: mApi is nullptr, do nothing", __FUNCTION__);
} else {
mApi->geofenceRemoveAll();
}
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

91
android/GnssGeofencing.h Normal file
View file

@ -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 <android/hardware/gnss/1.0/IGnssGeofencing.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssGeofenceCallback;
using ::android::hardware::gnss::V1_0::IGnssGeofencing;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
class GeofenceAPIClient;
struct GnssGeofencing : public IGnssGeofencing {
GnssGeofencing();
~GnssGeofencing();
/*
* Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
* These declarations were generated from IGnssGeofencing.hal.
*/
Return<void> setCallback(const sp<IGnssGeofenceCallback>& callback) override;
Return<void> addGeofence(int32_t geofenceId,
double latitudeDegrees,
double longitudeDegrees,
double radiusMeters,
IGnssGeofenceCallback::GeofenceTransition lastTransition,
int32_t monitorTransitions,
uint32_t notificationResponsivenessMs,
uint32_t unknownTimerMs) override;
Return<void> pauseGeofence(int32_t geofenceId) override;
Return<void> resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) override;
Return<void> removeGeofence(int32_t geofenceId) override;
private:
// This method is not part of the IGnss base class.
// It is called by GnssGeofencingDeathRecipient to remove all geofences added so far.
Return<void> removeAllGeofences();
private:
struct GnssGeofencingDeathRecipient : hidl_death_recipient {
GnssGeofencingDeathRecipient(sp<GnssGeofencing> gnssGeofencing) :
mGnssGeofencing(gnssGeofencing) {
}
~GnssGeofencingDeathRecipient() = default;
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
sp<GnssGeofencing> mGnssGeofencing;
};
private:
sp<GnssGeofencingDeathRecipient> mGnssGeofencingDeathRecipient = nullptr;
sp<IGnssGeofenceCallback> mGnssGeofencingCbIface = nullptr;
GeofenceAPIClient* mApi = nullptr;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSGEOFENCING_H

View file

@ -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 <log_util.h>
#include <GnssMeasurementAPIClient.h>
#include "GnssMeasurement.h"
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
void GnssMeasurement::GnssMeasurementDeathRecipient::serviceDied(
uint64_t cookie, const wp<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
if (mGnssMeasurement != nullptr) {
mGnssMeasurement->close();
}
}
GnssMeasurement::GnssMeasurement() {
mGnssMeasurementDeathRecipient = new GnssMeasurementDeathRecipient(this);
mApi = new GnssMeasurementAPIClient();
}
GnssMeasurement::~GnssMeasurement() {
if (mApi) {
delete mApi;
mApi = nullptr;
}
}
// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow.
Return<IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
const sp<IGnssMeasurementCallback>& callback) {
Return<IGnssMeasurement::GnssMeasurementStatus> ret =
IGnssMeasurement::GnssMeasurementStatus::ERROR_GENERIC;
if (mGnssMeasurementCbIface != nullptr) {
LOC_LOGE("%s]: GnssMeasurementCallback is already set", __FUNCTION__);
return IGnssMeasurement::GnssMeasurementStatus::ERROR_ALREADY_INIT;
}
if (callback == nullptr) {
LOC_LOGE("%s]: callback is nullptr", __FUNCTION__);
return ret;
}
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
return ret;
}
mGnssMeasurementCbIface = callback;
mGnssMeasurementCbIface->linkToDeath(mGnssMeasurementDeathRecipient, 0 /*cookie*/);
return mApi->gnssMeasurementSetCallback(callback);
}
Return<void> GnssMeasurement::close() {
if (mApi == nullptr) {
LOC_LOGE("%s]: mApi is nullptr", __FUNCTION__);
return Void();
}
if (mGnssMeasurementCbIface != nullptr) {
mGnssMeasurementCbIface->unlinkToDeath(mGnssMeasurementDeathRecipient);
mGnssMeasurementCbIface = nullptr;
}
mApi->gnssMeasurementClose();
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

76
android/GnssMeasurement.h Normal file
View file

@ -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 <android/hardware/gnss/1.0/IGnssMeasurement.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssMeasurement;
using ::android::hardware::gnss::V1_0::IGnssMeasurementCallback;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
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<GnssMeasurementStatus> setCallback(
const sp<IGnssMeasurementCallback>& callback) override;
Return<void> close() override;
private:
struct GnssMeasurementDeathRecipient : hidl_death_recipient {
GnssMeasurementDeathRecipient(sp<GnssMeasurement> gnssMeasurement) :
mGnssMeasurement(gnssMeasurement) {
}
~GnssMeasurementDeathRecipient() = default;
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
sp<GnssMeasurement> mGnssMeasurement;
};
private:
sp<GnssMeasurementDeathRecipient> mGnssMeasurementDeathRecipient = nullptr;
sp<IGnssMeasurementCallback> mGnssMeasurementCbIface = nullptr;
GnssMeasurementAPIClient* mApi;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H

85
android/GnssNi.cpp Normal file
View file

@ -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 <log_util.h>
#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<IBase>& who) {
LOC_LOGE("%s] service died. cookie: %llu, who: %p",
__FUNCTION__, static_cast<unsigned long long>(cookie), &who);
// we do nothing here
// Gnss::GnssDeathRecipient will stop the session
}
GnssNi::GnssNi(Gnss* gnss) : mGnss(gnss) {
mGnssNiDeathRecipient = new GnssNiDeathRecipient(this);
}
// Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
Return<void> GnssNi::setCallback(const sp<IGnssNiCallback>& callback) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return Void();
}
mGnss->setGnssNiCb(callback);
if (mGnssNiCbIface != nullptr) {
mGnssNiCbIface->unlinkToDeath(mGnssNiDeathRecipient);
}
mGnssNiCbIface = callback;
if (mGnssNiCbIface != nullptr) {
mGnssNiCbIface->linkToDeath(mGnssNiDeathRecipient, 0 /*cookie*/);
}
return Void();
}
Return<void> GnssNi::respond(int32_t notifId, IGnssNiCallback::GnssUserResponseType userResponse) {
if (mGnss == nullptr) {
LOC_LOGE("%s]: mGnss is nullptr", __FUNCTION__);
return Void();
}
GnssAPIClient* api = mGnss->getApi();
if (api == nullptr) {
LOC_LOGE("%s]: api is nullptr", __FUNCTION__);
return Void();
}
api->gnssNiRespond(notifId, userResponse);
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

75
android/GnssNi.h Normal file
View file

@ -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 <android/hardware/gnss/1.0/IGnssNi.h>
#include <hidl/Status.h>
namespace android {
namespace hardware {
namespace gnss {
namespace V1_0 {
namespace implementation {
using ::android::hardware::gnss::V1_0::IGnssNi;
using ::android::hardware::gnss::V1_0::IGnssNiCallback;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
struct Gnss;
struct GnssNi : public IGnssNi {
GnssNi(Gnss* gnss);
~GnssNi() = default;
/*
* Methods from ::android::hardware::gnss::V1_0::IGnssNi follow.
* These declarations were generated from IGnssNi.hal.
*/
Return<void> setCallback(const sp<IGnssNiCallback>& callback) override;
Return<void> respond(int32_t notifId,
IGnssNiCallback::GnssUserResponseType userResponse) override;
private:
struct GnssNiDeathRecipient : hidl_death_recipient {
GnssNiDeathRecipient(sp<GnssNi> gnssNi) : mGnssNi(gnssNi) {
}
~GnssNiDeathRecipient() = default;
virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override;
sp<GnssNi> mGnssNi;
};
private:
sp<GnssNiDeathRecipient> mGnssNiDeathRecipient = nullptr;
sp<IGnssNiCallback> mGnssNiCbIface = nullptr;
Gnss* mGnss = nullptr;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSNI_H

View file

@ -0,0 +1,4 @@
service gnss_service /system/bin/hw/android.hardware.gnss@1.0-service-qti
class main
user system
group system

View file

@ -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 <hardware/gps.h>
#include <LocDualContext.h>
#include <loc_target.h>
#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;
}

View file

@ -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 <hardware/gps.h>
#include <GeofenceAPIClient.h>
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;
}

View file

@ -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 <log_util.h>
#include <loc_cfg.h>
#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<IGnssBatchingCallback>& 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<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
int retVal = -1;
LocationOptions options;
convertBatchOption(opts, options, mLocationCapabilitiesMask);
uint32_t mode = 0;
if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
mode = SESSION_MODE_ON_FULL;
}
if (locAPIStartSession(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
retVal = 1;
}
return retVal;
}
int FlpAPIClient::flpUpdateSessionOptions(const IGnssBatching::Options& opts)
{
LOC_LOGD("%s]: (%lld %d)", __FUNCTION__,
static_cast<long long>(opts.periodNanos), static_cast<uint8_t>(opts.flags));
int retVal = -1;
LocationOptions options;
convertBatchOption(opts, options, mLocationCapabilitiesMask);
uint32_t mode = 0;
if (opts.flags == static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL)) {
mode = SESSION_MODE_ON_FULL;
}
if (locAPIUpdateSessionOptions(mDefaultId, mode, options) == LOCATION_ERROR_SUCCESS) {
retVal = 1;
}
return retVal;
}
int 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<GnssLocation> 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

View file

@ -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 <android/hardware/gnss/1.0/IGnssBatching.h>
#include <android/hardware/gnss/1.0/IGnssBatchingCallback.h>
#include <pthread.h>
#include <LocationAPIClientBase.h>
#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<IGnssBatchingCallback>& 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<IGnssBatchingCallback> mGnssBatchingCbIface;
uint32_t mDefaultId;
int mBatchSize;
LocationCapabilitiesMask mLocationCapabilitiesMask;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // FLP_API_CLINET_H

View file

@ -33,36 +33,21 @@
#include <log_util.h>
#include <loc_cfg.h>
#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<IGnssGeofenceCallback>& 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<GnssUtcTime>(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

View file

@ -30,21 +30,31 @@
#ifndef GEOFENCE_API_CLINET_H
#define GEOFENCE_API_CLINET_H
#include <hardware/gps.h>
#include <android/hardware/gnss/1.0/IGnssGeofenceCallback.h>
#include <LocationAPIClientBase.h>
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<IGnssGeofenceCallback>& 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<IGnssGeofenceCallback> mGnssGeofencingCbIface;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // GEOFENCE_API_CLINET_H

View file

@ -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 <log_util.h>
#include <loc_cfg.h>
#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<IGnssCallback>& gpsCb,
const sp<IGnssNiCallback>& 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<IGnssCallback>& gpsCb,
const sp<IGnssNiCallback>& 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<int>(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<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_NOTIFY);
else if (gnssNiNotification.options == GNSS_NI_OPTIONS_VERIFICATION)
notificationGnss.notifyFlags =
static_cast<uint32_t>(IGnssNiCallback::GnssNiNotifyFlags::NEED_VERIFY);
else if (gnssNiNotification.options == GNSS_NI_OPTIONS_PRIVACY_OVERRIDE)
notificationGnss.notifyFlags =
static_cast<uint32_t>(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<GnssUtcTime>(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<uint32_t>(GnssMax::SVS_COUNT)) {
LOC_LOGW("%s]: Too many satellites %zd. Clamps to %d.",
__FUNCTION__, out.numSvs, GnssMax::SVS_COUNT);
out.numSvs = static_cast<uint32_t>(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<uint8_t>(IGnssCallback::GnssSvFlags::NONE);
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_EPHEMER_BIT)
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_EPHEMERIS_DATA;
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_HAS_ALMANAC_BIT)
info.svFlag |= IGnssCallback::GnssSvFlags::HAS_ALMANAC_DATA;
if (in.gnssSvs[i].gnssSvOptionsMask & GNSS_SV_OPTIONS_USED_IN_FIX_BIT)
info.svFlag |= IGnssCallback::GnssSvFlags::USED_IN_FIX;
}
}
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android

View file

@ -30,42 +30,46 @@
#ifndef GNSS_API_CLINET_H
#define GNSS_API_CLINET_H
#include <hardware/gps.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/1.0/IGnssCallback.h>
#include <android/hardware/gnss/1.0/IGnssNiCallback.h>
#include <LocationAPIClientBase.h>
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<IGnssCallback>& gpsCb,
const sp<IGnssNiCallback>& 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<IGnssCallback>& gpsCb,
const sp<IGnssNiCallback>& 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<IGnssCallback> mGnssCbIface;
sp<IGnssNiCallback> mGnssNiCbIface;
LocationCapabilitiesMask mLocationCapabilitiesMask;
GpsMeasurementCallbacks* mGpsMeasurementCallbacks;
LocationOptions mLocationOptions;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // GNSS_API_CLINET_H

View file

@ -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 <log_util.h>
#include <loc_cfg.h>
#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<IGnssMeasurement::GnssMeasurementStatus>
GnssMeasurementAPIClient::gnssMeasurementSetCallback(const sp<IGnssMeasurementCallback>& 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<uint8_t>(IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN);
if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_PRESENT)
indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_PRESENT;
if (in.multipathIndicator & GNSS_MEASUREMENTS_MULTIPATH_INDICATOR_NOT_PRESENT)
indicator |= IGnssMeasurementCallback::GnssMultipathIndicator::INDICATIOR_NOT_PRESENT;
out.multipathIndicator =
static_cast<IGnssMeasurementCallback::GnssMultipathIndicator>(indicator);
out.snrDb = in.signalToNoiseRatioDb;
}
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<uint32_t>(GnssMax::SVS_COUNT)) {
LOC_LOGW("%s]: Too many measurement %zd. Clamps to %d.",
__FUNCTION__, out.measurementCount, GnssMax::SVS_COUNT);
out.measurementCount = static_cast<uint32_t>(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

View file

@ -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 <android/hardware/gnss/1.0/IGnssMeasurement.h>
#include <android/hardware/gnss/1.0/IGnssMeasurementCallback.h>
#include <LocationAPIClientBase.h>
#include <hidl/Status.h>
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<IGnssMeasurement::GnssMeasurementStatus> gnssMeasurementSetCallback(
const sp<IGnssMeasurementCallback>& 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<IGnssMeasurementCallback> mGnssMeasurementCbIface;
LocationCapabilitiesMask mLocationCapabilitiesMask;
LocationOptions mLocationOptions;
};
} // namespace implementation
} // namespace V1_0
} // namespace gnss
} // namespace hardware
} // namespace android
#endif // GNSS_MEASUREMENT_API_CLINET_H

View file

@ -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 <LocationUtil.h>
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<GnssUtcTime>(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

View file

@ -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 <hardware/gps.h>
#ifndef LOCATION_UTIL_H
#define LOCATION_UTIL_H
#include <stdlib.h>
#include <string.h>
#include <android/hardware/gnss/1.0/types.h>
#include <LocationAPI.h>
#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

31
android/service.cpp Normal file
View file

@ -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 <android/hardware/gnss/1.0/IGnss.h>
#include <hidl/LegacySupport.h>
using android::hardware::gnss::V1_0::IGnss;
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
return defaultPassthroughServiceImplementation<IGnss>("gnss");
}

View file

@ -17,6 +17,7 @@ LOCAL_CFLAGS += -DPDK_FEATURE_SET
endif
LOCAL_SHARED_LIBRARIES := \
liblog \
libutils \
libcutils \
libgps.utils \

View file

@ -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 \