/* * 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 #include #include #include #include #include #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(int version) : mCallbacksObj(getCallbacksObj()), interfaceVersion(version) {} 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& measurements); jobjectArray translateAllGnssAgcs(JNIEnv* env, const std::vector& agcs); void translateAndSetGnssData(const hardware::gnss::GnssData& data); void translateGnssClock(JNIEnv* env, const hardware::gnss::GnssData& data, JavaObject& object); jobject& mCallbacksObj; const int interfaceVersion; }; /* * GnssMeasurementCallback implements the callback methods required for the * GnssMeasurement interface. */ class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback { public: GnssMeasurementCallbackHidl() : mCallbacksObj(getCallbacksObj()) {} hardware::Return gnssMeasurementCb_2_1( const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override; hardware::Return gnssMeasurementCb_2_0( const hardware::gnss::V2_0::IGnssMeasurementCallback::GnssData& data) override; hardware::Return gnssMeasurementCb( const hardware::gnss::V1_1::IGnssMeasurementCallback::GnssData& data) override; hardware::Return GnssMeasurementCb( const hardware::gnss::V1_0::IGnssMeasurementCallback::GnssData& data) override; private: template void translateSingleGnssMeasurement(const T& measurement, JavaObject& object); template jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count); template void translateAndSetGnssData(const T& data); template size_t getMeasurementCount(const T& data); template void translateGnssClock(const T& data, JavaObject& object); jobject& mCallbacksObj; }; class GnssMeasurementCallback { public: GnssMeasurementCallback(int version) : interfaceVersion(version) {} sp getAidl() { if (callbackAidl == nullptr) { callbackAidl = sp::make(interfaceVersion); } return callbackAidl; } sp getHidl() { if (callbackHidl == nullptr) { callbackHidl = sp::make(); } return callbackHidl; } private: sp callbackAidl; sp callbackHidl; const int interfaceVersion; }; template 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 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 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 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