Merge "Add GnssNavigationMessage AIDL HAL (frameworks/base)"

This commit is contained in:
Yu-Han Yang
2021-11-27 17:47:34 +00:00
committed by Android (Google) Code Review
6 changed files with 349 additions and 78 deletions

View File

@@ -56,13 +56,13 @@
#include "gnss/GnssBatching.h"
#include "gnss/GnssConfiguration.h"
#include "gnss/GnssMeasurement.h"
#include "gnss/GnssNavigationMessage.h"
#include "gnss/Utils.h"
#include "hardware_legacy/power.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
static jclass class_gnssNavigationMessage;
static jclass class_gnssPowerStats;
static jmethodID method_reportLocation;
@@ -85,7 +85,6 @@ static jmethodID method_reportGeofenceAddStatus;
static jmethodID method_reportGeofenceRemoveStatus;
static jmethodID method_reportGeofencePauseStatus;
static jmethodID method_reportGeofenceResumeStatus;
static jmethodID method_reportNavigationMessages;
static jmethodID method_reportGnssServiceDied;
static jmethodID method_reportGnssPowerStats;
static jmethodID method_setSubHalMeasurementCorrectionsCapabilities;
@@ -115,7 +114,6 @@ static jmethodID method_correctionPlaneAltDeg;
static jmethodID method_correctionPlaneAzimDeg;
static jmethodID method_reportNfwNotification;
static jmethodID method_isInEmergencySession;
static jmethodID method_gnssNavigationMessageCtor;
static jmethodID method_gnssPowerStatsCtor;
static jmethodID method_setSubHalPowerIndicationCapabilities;
@@ -233,7 +231,6 @@ sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
sp<IGnssDebug_V1_0> gnssDebugIface = nullptr;
sp<IGnssDebug_V2_0> gnssDebugIface_V2_0 = nullptr;
sp<IGnssNi> gnssNiIface = nullptr;
sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
sp<IGnssPowerIndication> gnssPowerIndicationIface = nullptr;
sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr;
sp<IMeasurementCorrections_V1_1> gnssCorrectionsIface_V1_1 = nullptr;
@@ -242,6 +239,7 @@ sp<IGnssAntennaInfo> gnssAntennaInfoIface = nullptr;
std::unique_ptr<GnssConfigurationInterface> gnssConfigurationIface = nullptr;
std::unique_ptr<android::gnss::GnssMeasurementInterface> gnssMeasurementIface = nullptr;
std::unique_ptr<android::gnss::GnssNavigationMessageInterface> gnssNavigationMessageIface = nullptr;
std::unique_ptr<android::gnss::GnssBatchingInterface> gnssBatchingIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
@@ -909,50 +907,6 @@ Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId, Geof
return Void();
}
/*
* GnssNavigationMessageCallback interface implements the callback methods
* required by the IGnssNavigationMessage interface.
*/
struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
/*
* Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
* follow.
*/
Return<void> gnssNavigationMessageCb(
const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
};
Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
JNIEnv* env = getJniEnv();
size_t dataLength = message.data.size();
std::vector<uint8_t> navigationData = message.data;
uint8_t* data = &(navigationData[0]);
if (dataLength == 0 || data == nullptr) {
ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
dataLength);
return Void();
}
JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor);
SET(Type, static_cast<int32_t>(message.type));
SET(Svid, static_cast<int32_t>(message.svid));
SET(MessageId, static_cast<int32_t>(message.messageId));
SET(SubmessageId, static_cast<int32_t>(message.submessageId));
object.callSetter("setData", data, dataLength);
SET(Status, static_cast<int32_t>(message.status));
jobject navigationMessage = object.get();
env->CallVoidMethod(mCallbacksObj,
method_reportNavigationMessages,
navigationMessage);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
env->DeleteLocalRef(navigationMessage);
return Void();
}
/*
* MeasurementCorrectionsCallback implements callback methods of interface
* IMeasurementCorrectionsCallback.hal.
@@ -1264,10 +1218,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
"(II)V");
method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
"(II)V");
method_reportNavigationMessages = env->GetMethodID(
clazz,
"reportNavigationMessage",
"(Landroid/location/GnssNavigationMessage;)V");
method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
"(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
@@ -1337,14 +1287,11 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass);
method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "<init>", "(IJDDDDDD[D)V");
jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass);
method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");
gnss::GnssAntennaInfo_class_init_once(env, clazz);
gnss::GnssBatching_class_init_once(env, clazz);
gnss::GnssConfiguration_class_init_once(env);
gnss::GnssMeasurement_class_init_once(env, clazz);
gnss::GnssNavigationMessage_class_init_once(env, clazz);
gnss::Utils_class_init_once(env);
}
@@ -1431,12 +1378,20 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject
}
}
if (gnssHal != nullptr) {
if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
sp<hardware::gnss::IGnssNavigationMessageInterface> gnssNavigationMessage;
auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage);
if (checkAidlStatus(status,
"Unable to get a handle to GnssNavigationMessage AIDL interface.")) {
gnssNavigationMessageIface =
std::make_unique<gnss::GnssNavigationMessageAidl>(gnssNavigationMessage);
}
} else if (gnssHal != nullptr) {
auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
if (!gnssNavigationMessage.isOk()) {
ALOGD("Unable to get a handle to GnssNavigationMessage");
} else {
gnssNavigationMessageIface = gnssNavigationMessage;
if (checkHidlReturn(gnssNavigationMessage,
"Unable to get a handle to GnssNavigationMessage interface.")) {
gnssNavigationMessageIface =
std::make_unique<gnss::GnssNavigationMessageHidl>(gnssNavigationMessage);
}
}
@@ -2624,20 +2579,8 @@ static jboolean android_location_gnss_hal_GnssNative_start_navigation_message_co
return JNI_FALSE;
}
sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
new GnssNavigationMessageCallback();
auto result = gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
if (!checkHidlReturn(result, "IGnssNavigationMessage setCallback() failed.")) {
return JNI_FALSE;
}
IGnssNavigationMessage::GnssNavigationMessageStatus initRet = result;
if (initRet != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(initRet));
return JNI_FALSE;
}
return JNI_TRUE;
return gnssNavigationMessageIface->setCallback(
std::make_unique<gnss::GnssNavigationMessageCallback>());
}
static jboolean android_location_gnss_hal_GnssNative_stop_navigation_message_collection(JNIEnv* env,
@@ -2646,9 +2589,7 @@ static jboolean android_location_gnss_hal_GnssNative_stop_navigation_message_col
ALOGE("%s: IGnssNavigationMessage interface not available.", __func__);
return JNI_FALSE;
}
auto result = gnssNavigationMessageIface->close();
return checkHidlReturn(result, "IGnssNavigationMessage close() failed.");
return gnssNavigationMessageIface->close();
}
static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,

View File

@@ -29,6 +29,8 @@ cc_library_shared {
"GnssConfiguration.cpp",
"GnssMeasurement.cpp",
"GnssMeasurementCallback.cpp",
"GnssNavigationMessage.cpp",
"GnssNavigationMessageCallback.cpp",
"Utils.cpp",
],
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2021 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 before <log/log.h> to overwrite the default value.
#define LOG_TAG "GnssNavigationMessageJni"
#include "GnssNavigationMessage.h"
#include "Utils.h"
namespace android::gnss {
using hardware::gnss::IGnssNavigationMessageInterface;
using IGnssNavigationMessageHidl = hardware::gnss::V1_0::IGnssNavigationMessage;
// Implementation of GnssNavigationMessage (AIDL HAL)
GnssNavigationMessageAidl::GnssNavigationMessageAidl(
const sp<IGnssNavigationMessageInterface>& iGnssNavigationMessage)
: mIGnssNavigationMessage(iGnssNavigationMessage) {
assert(mIGnssNavigationMessage != nullptr);
}
jboolean GnssNavigationMessageAidl::setCallback(
const std::unique_ptr<GnssNavigationMessageCallback>& callback) {
auto status = mIGnssNavigationMessage->setCallback(callback->getAidl());
return checkAidlStatus(status, "IGnssNavigationMessageAidl setCallback() failed.");
}
jboolean GnssNavigationMessageAidl::close() {
auto status = mIGnssNavigationMessage->close();
return checkAidlStatus(status, "IGnssNavigationMessageAidl close() failed");
}
// Implementation of GnssNavigationMessageHidl
GnssNavigationMessageHidl::GnssNavigationMessageHidl(
const sp<IGnssNavigationMessageHidl>& iGnssNavigationMessage)
: mIGnssNavigationMessageHidl(iGnssNavigationMessage) {
assert(mIGnssNavigationMessageHidl != nullptr);
}
jboolean GnssNavigationMessageHidl::setCallback(
const std::unique_ptr<GnssNavigationMessageCallback>& callback) {
auto result = mIGnssNavigationMessageHidl->setCallback(callback->getHidl());
IGnssNavigationMessageHidl::GnssNavigationMessageStatus initRet = result;
if (initRet != IGnssNavigationMessageHidl::GnssNavigationMessageStatus::SUCCESS) {
ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(initRet));
return JNI_FALSE;
}
return JNI_TRUE;
}
jboolean GnssNavigationMessageHidl::close() {
auto result = mIGnssNavigationMessageHidl->close();
return checkHidlReturn(result, "IGnssNavigationMessage close() failed.");
}
} // namespace android::gnss

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 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_SERVER_GNSS_GNSSNAVIGATIONMESSAGE_H
#define _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGE_H
#pragma once
#ifndef LOG_TAG
#error LOG_TAG must be defined before including this file.
#endif
#include <android/hardware/gnss/1.0/IGnssNavigationMessage.h>
#include <android/hardware/gnss/BnGnssNavigationMessageInterface.h>
#include <log/log.h>
#include "GnssNavigationMessageCallback.h"
#include "jni.h"
namespace android::gnss {
class GnssNavigationMessageInterface {
public:
virtual ~GnssNavigationMessageInterface() {}
virtual jboolean setCallback(
const std::unique_ptr<GnssNavigationMessageCallback>& callback) = 0;
virtual jboolean close() = 0;
};
class GnssNavigationMessageAidl : public GnssNavigationMessageInterface {
public:
GnssNavigationMessageAidl(const sp<android::hardware::gnss::IGnssNavigationMessageInterface>&
iGnssNavigationMessage);
jboolean setCallback(const std::unique_ptr<GnssNavigationMessageCallback>& callback) override;
jboolean close() override;
private:
const sp<android::hardware::gnss::IGnssNavigationMessageInterface> mIGnssNavigationMessage;
};
class GnssNavigationMessageHidl : public GnssNavigationMessageInterface {
public:
GnssNavigationMessageHidl(const sp<android::hardware::gnss::V1_0::IGnssNavigationMessage>&
iGnssNavigationMessage);
jboolean setCallback(const std::unique_ptr<GnssNavigationMessageCallback>& callback) override;
jboolean close() override;
private:
const sp<android::hardware::gnss::V1_0::IGnssNavigationMessage> mIGnssNavigationMessageHidl;
};
} // namespace android::gnss
#endif // _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGE_H

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2021 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 "GnssNavMsgCbJni"
#include "GnssNavigationMessageCallback.h"
namespace android::gnss {
namespace {
jclass class_gnssNavigationMessage;
jmethodID method_reportNavigationMessages;
jmethodID method_gnssNavigationMessageCtor;
} // anonymous namespace
using binder::Status;
using hardware::Return;
using hardware::Void;
using GnssNavigationMessageAidl =
android::hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage;
using GnssNavigationMessageHidl =
android::hardware::gnss::V1_0::IGnssNavigationMessageCallback::GnssNavigationMessage;
void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz) {
method_reportNavigationMessages =
env->GetMethodID(clazz, "reportNavigationMessage",
"(Landroid/location/GnssNavigationMessage;)V");
jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
class_gnssNavigationMessage = (jclass)env->NewGlobalRef(gnssNavigationMessageClass);
method_gnssNavigationMessageCtor =
env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");
}
Status GnssNavigationMessageCallbackAidl::gnssNavigationMessageCb(
const GnssNavigationMessageAidl& message) {
GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(message);
return Status::ok();
}
Return<void> GnssNavigationMessageCallbackHidl::gnssNavigationMessageCb(
const GnssNavigationMessageHidl& message) {
GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(message);
return Void();
}
} // namespace android::gnss

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2021 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_SERVER_GNSS_GNSSNAVIGATIONMESSAGECALLBACK_H
#define _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGECALLBACK_H
#pragma once
#ifndef LOG_TAG
#error LOG_TAG must be defined before including this file.
#endif
#include <android/hardware/gnss/1.0/IGnssNavigationMessage.h>
#include <android/hardware/gnss/BnGnssNavigationMessageCallback.h>
#include <log/log.h>
#include <vector>
#include "Utils.h"
#include "jni.h"
namespace android::gnss {
namespace {
extern jclass class_gnssNavigationMessage;
extern jmethodID method_reportNavigationMessages;
extern jmethodID method_gnssNavigationMessageCtor;
} // anonymous namespace
void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz);
class GnssNavigationMessageCallbackAidl : public hardware::gnss::BnGnssNavigationMessageCallback {
public:
GnssNavigationMessageCallbackAidl() {}
android::binder::Status gnssNavigationMessageCb(
const hardware::gnss::IGnssNavigationMessageCallback::GnssNavigationMessage& message)
override;
};
class GnssNavigationMessageCallbackHidl
: public hardware::gnss::V1_0::IGnssNavigationMessageCallback {
public:
GnssNavigationMessageCallbackHidl() {}
hardware::Return<void> gnssNavigationMessageCb(
const hardware::gnss::V1_0::IGnssNavigationMessageCallback::GnssNavigationMessage&
message) override;
};
class GnssNavigationMessageCallback {
public:
GnssNavigationMessageCallback() {}
sp<GnssNavigationMessageCallbackAidl> getAidl() {
if (callbackAidl == nullptr) {
callbackAidl = sp<GnssNavigationMessageCallbackAidl>::make();
}
return callbackAidl;
}
sp<GnssNavigationMessageCallbackHidl> getHidl() {
if (callbackHidl == nullptr) {
callbackHidl = sp<GnssNavigationMessageCallbackHidl>::make();
}
return callbackHidl;
}
private:
sp<GnssNavigationMessageCallbackAidl> callbackAidl;
sp<GnssNavigationMessageCallbackHidl> callbackHidl;
};
struct GnssNavigationMessageCallbackUtil {
template <class T>
static void gnssNavigationMessageCbImpl(const T& message);
private:
GnssNavigationMessageCallbackUtil() = delete;
};
template <class T>
void GnssNavigationMessageCallbackUtil::gnssNavigationMessageCbImpl(const T& message) {
JNIEnv* env = getJniEnv();
size_t dataLength = message.data.size();
std::vector<uint8_t> navigationData = message.data;
uint8_t* data = &(navigationData[0]);
if (dataLength == 0 || data == nullptr) {
ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
return;
}
JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor);
SET(Type, static_cast<int32_t>(message.type));
SET(Svid, static_cast<int32_t>(message.svid));
SET(MessageId, static_cast<int32_t>(message.messageId));
SET(SubmessageId, static_cast<int32_t>(message.submessageId));
object.callSetter("setData", data, dataLength);
SET(Status, static_cast<int32_t>(message.status));
jobject navigationMessage = object.get();
env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessage);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
env->DeleteLocalRef(navigationMessage);
return;
}
} // namespace android::gnss
#endif // _ANDROID_SERVER_GNSS_GNSSNAVIGATIONMESSAGECALLBACK_H