blob: b3de486e6fa99c423416c762aeec2ea385225e8c [file] [log] [blame]
/*
* Copyright (C) 2020 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_GNSSMEASUREMENTCALLBACK_H
#define _ANDROID_SERVER_GNSS_GNSSMEASUREMENTCALLBACK_H
#pragma once
#ifndef LOG_TAG
#error LOG_TAG must be defined before including this file.
#endif
#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <log/log.h>
#include "Utils.h"
#include "jni.h"
namespace android::gnss {
namespace {
extern jclass class_gnssMeasurementsEvent;
extern jclass class_gnssMeasurement;
extern jclass class_gnssClock;
extern jmethodID method_gnssMeasurementsEventCtor;
extern jmethodID method_gnssClockCtor;
extern jmethodID method_gnssMeasurementCtor;
extern jmethodID method_reportMeasurementData;
} // anonymous namespace
void GnssMeasurement_class_init_once(JNIEnv* env, jclass& clazz);
void setMeasurementData(JNIEnv* env, jobject& callbacksObj, jobject clock,
jobjectArray measurementArray, jobjectArray gnssAgcArray,
bool hasIsFullTracking, jboolean isFullTracking);
class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback {
public:
GnssMeasurementCallbackAidl() : mCallbacksObj(getCallbacksObj()) {}
android::binder::Status gnssMeasurementCb(const hardware::gnss::GnssData& data) override;
private:
void translateSingleGnssMeasurement(JNIEnv* env,
const hardware::gnss::GnssMeasurement& measurement,
JavaObject& object);
jobjectArray translateAllGnssMeasurements(
JNIEnv* env, const std::vector<hardware::gnss::GnssMeasurement>& measurements);
jobjectArray translateAllGnssAgcs(JNIEnv* env,
const std::vector<hardware::gnss::GnssData::GnssAgc>& agcs);
void translateAndSetGnssData(const hardware::gnss::GnssData& data);
void translateGnssClock(JNIEnv* env, const hardware::gnss::GnssData& data, JavaObject& object);
jobject& mCallbacksObj;
};
/*
* GnssMeasurementCallback implements the callback methods required for the
* GnssMeasurement interface.
*/
class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback {
public:
GnssMeasurementCallbackHidl() : mCallbacksObj(getCallbacksObj()) {}
hardware::Return<void> gnssMeasurementCb_2_1(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
hardware::Return<void> gnssMeasurementCb_2_0(
const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) override;
hardware::Return<void> gnssMeasurementCb(
const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) override;
hardware::Return<void> GnssMeasurementCb(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) override;
private:
template <class T>
void translateSingleGnssMeasurement(const T& measurement, JavaObject& object);
template <class T>
jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
template <class T>
void translateAndSetGnssData(const T& data);
template <class T>
size_t getMeasurementCount(const T& data);
template <class T>
void translateGnssClock(const T& data, JavaObject& object);
jobject& mCallbacksObj;
};
class GnssMeasurementCallback {
public:
GnssMeasurementCallback() {}
sp<GnssMeasurementCallbackAidl> getAidl() {
if (callbackAidl == nullptr) {
callbackAidl = sp<GnssMeasurementCallbackAidl>::make();
}
return callbackAidl;
}
sp<GnssMeasurementCallbackHidl> getHidl() {
if (callbackHidl == nullptr) {
callbackHidl = sp<GnssMeasurementCallbackHidl>::make();
}
return callbackHidl;
}
private:
sp<GnssMeasurementCallbackAidl> callbackAidl;
sp<GnssMeasurementCallbackHidl> callbackHidl;
};
template <class T>
void GnssMeasurementCallbackHidl::translateAndSetGnssData(const T& data) {
JNIEnv* env = getJniEnv();
JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
translateGnssClock(data, gnssClockJavaObject);
jobject clock = gnssClockJavaObject.get();
size_t count = getMeasurementCount(data);
jobjectArray measurementArray =
translateAllGnssMeasurements(env, data.measurements.data(), count);
setMeasurementData(env, mCallbacksObj, clock, measurementArray, /*gnssAgcArray=*/nullptr,
/*hasIsFullTracking=*/false,
/*isFullTracking=*/JNI_FALSE);
env->DeleteLocalRef(clock);
env->DeleteLocalRef(measurementArray);
}
template <>
size_t GnssMeasurementCallbackHidl::getMeasurementCount<
hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData>(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data);
template <class T>
size_t GnssMeasurementCallbackHidl::getMeasurementCount(const T& data) {
return data.measurements.size();
}
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement>(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssMeasurement& measurement,
JavaObject& object);
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement>(
const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V1_1,
JavaObject& object);
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement>(
const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_0,
JavaObject& object);
// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
template <>
void GnssMeasurementCallbackHidl::translateSingleGnssMeasurement<
hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement>(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssMeasurement& measurement_V2_1,
JavaObject& object);
template <class T>
void GnssMeasurementCallbackHidl::translateGnssClock(const T& data, JavaObject& object) {
translateGnssClock(data.clock, object);
}
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssClock& clock, JavaObject& object);
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data, JavaObject& object);
template <>
void GnssMeasurementCallbackHidl::translateGnssClock(
const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data, JavaObject& object);
template <class T>
jobjectArray GnssMeasurementCallbackHidl::translateAllGnssMeasurements(JNIEnv* env,
const T* measurements,
size_t count) {
if (count == 0) {
return nullptr;
}
jobjectArray gnssMeasurementArray =
env->NewObjectArray(count, class_gnssMeasurement, nullptr /* initialElement */);
for (uint16_t i = 0; i < count; ++i) {
JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
translateSingleGnssMeasurement(measurements[i], object);
jobject gnssMeasurement = object.get();
env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
env->DeleteLocalRef(gnssMeasurement);
}
return gnssMeasurementArray;
}
} // namespace android::gnss
#endif // _ANDROID_SERVER_GNSS_GNSSMEASUREMENTCALLBACK_H