diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 2ccef9a61ffb8..45048530603aa 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -55,6 +55,7 @@ #include "gnss/GnssAntennaInfoCallback.h" #include "gnss/GnssBatching.h" #include "gnss/GnssConfiguration.h" +#include "gnss/GnssGeofence.h" #include "gnss/GnssMeasurement.h" #include "gnss/GnssNavigationMessage.h" #include "gnss/Utils.h" @@ -79,12 +80,6 @@ static jmethodID method_requestLocation; static jmethodID method_requestRefLocation; static jmethodID method_requestSetID; static jmethodID method_requestUtcTime; -static jmethodID method_reportGeofenceTransition; -static jmethodID method_reportGeofenceStatus; -static jmethodID method_reportGeofenceAddStatus; -static jmethodID method_reportGeofenceRemoveStatus; -static jmethodID method_reportGeofencePauseStatus; -static jmethodID method_reportGeofenceResumeStatus; static jmethodID method_reportGnssServiceDied; static jmethodID method_reportGnssPowerStats; static jmethodID method_setSubHalMeasurementCorrectionsCapabilities; @@ -133,8 +128,6 @@ using android::hardware::hidl_death_recipient; using android::hardware::gnss::V1_0::GnssLocationFlags; using android::hardware::gnss::V1_0::IAGnssRilCallback; -using android::hardware::gnss::V1_0::IGnssGeofenceCallback; -using android::hardware::gnss::V1_0::IGnssGeofencing; using android::hardware::gnss::V1_0::IGnssNavigationMessage; using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback; using android::hardware::gnss::V1_0::IGnssNi; @@ -192,8 +185,6 @@ using android::hardware::gnss::PsdsType; using IGnssAidl = android::hardware::gnss::IGnss; using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback; using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching; -using IGnssGeofenceAidl = android::hardware::gnss::IGnssGeofence; -using IGnssGeofenceCallbackAidl = android::hardware::gnss::IGnssGeofenceCallback; using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds; using IGnssPsdsCallbackAidl = android::hardware::gnss::IGnssPsdsCallback; using IGnssConfigurationAidl = android::hardware::gnss::IGnssConfiguration; @@ -220,12 +211,10 @@ sp gnssHal_V2_0 = nullptr; sp gnssHal_V2_1 = nullptr; sp gnssHalAidl = nullptr; sp gnssBatchingAidlIface = nullptr; -sp gnssGeofenceAidlIface = nullptr; sp gnssPsdsAidlIface = nullptr; sp gnssXtraIface = nullptr; sp agnssRilIface = nullptr; sp agnssRilIface_V2_0 = nullptr; -sp gnssGeofencingIface = nullptr; sp agnssIface = nullptr; sp agnssIface_V2_0 = nullptr; sp gnssDebugIface = nullptr; @@ -241,6 +230,7 @@ std::unique_ptr gnssConfigurationIface = nullptr; std::unique_ptr gnssMeasurementIface = nullptr; std::unique_ptr gnssNavigationMessageIface = nullptr; std::unique_ptr gnssBatchingIface = nullptr; +std::unique_ptr gnssGeofencingIface = nullptr; #define WAKE_LOCK_NAME "GPS" @@ -714,199 +704,6 @@ Return GnssXtraCallback::downloadRequestCb() { return Void(); } -/** Util class for GnssGeofenceCallback methods. */ -struct GnssGeofenceCallbackUtil { - template - static void gnssGeofenceTransitionCb(int geofenceId, const T& location, int transition, - int64_t timestampMillis); - template - static void gnssGeofenceStatusCb(int availability, const T& lastLocation); - static void gnssGeofenceAddCb(int geofenceId, int status); - static void gnssGeofenceRemoveCb(int geofenceId, int status); - static void gnssGeofencePauseCb(int geofenceId, int status); - static void gnssGeofenceResumeCb(int geofenceId, int status); - -private: - GnssGeofenceCallbackUtil() = delete; -}; - -template -void GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(int geofenceId, const T& location, - int transition, int64_t timestamp) { - JNIEnv* env = getJniEnv(); - - jobject jLocation = translateGnssLocation(env, location); - - env->CallVoidMethod(mCallbacksObj, - method_reportGeofenceTransition, - geofenceId, - jLocation, - transition, - timestamp); - - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(jLocation); -} - -template -void GnssGeofenceCallbackUtil::gnssGeofenceStatusCb(int availability, const T& lastLocation) { - JNIEnv* env = getJniEnv(); - - jobject jLocation = translateGnssLocation(env, lastLocation); - - env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, availability, jLocation); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - env->DeleteLocalRef(jLocation); -} - -void GnssGeofenceCallbackUtil::gnssGeofenceAddCb(int geofenceId, int status) { - JNIEnv* env = getJniEnv(); - if (status != IGnssGeofenceCallbackAidl::OPERATION_SUCCESS) { - ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status); - } - - env->CallVoidMethod(mCallbacksObj, - method_reportGeofenceAddStatus, - geofenceId, - status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - -void GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(int geofenceId, int status) { - JNIEnv* env = getJniEnv(); - if (status != IGnssGeofenceCallbackAidl::OPERATION_SUCCESS) { - ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status); - } - - env->CallVoidMethod(mCallbacksObj, - method_reportGeofenceRemoveStatus, - geofenceId, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - -void GnssGeofenceCallbackUtil::gnssGeofencePauseCb(int geofenceId, int status) { - JNIEnv* env = getJniEnv(); - if (status != IGnssGeofenceCallbackAidl::OPERATION_SUCCESS) { - ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status); - } - - env->CallVoidMethod(mCallbacksObj, - method_reportGeofencePauseStatus, - geofenceId, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - -void GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(int geofenceId, int status) { - JNIEnv* env = getJniEnv(); - if (status != IGnssGeofenceCallbackAidl::OPERATION_SUCCESS) { - ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status); - } - - env->CallVoidMethod(mCallbacksObj, - method_reportGeofenceResumeStatus, - geofenceId, status); - checkAndClearExceptionFromCallback(env, __FUNCTION__); -} - -/* - * GnssGeofenceCallbackAidl class implements the callback methods for the IGnssGeofence AIDL - * interface. - */ -struct GnssGeofenceCallbackAidl : public android::hardware::gnss::BnGnssGeofenceCallback { - Status gnssGeofenceTransitionCb(int geofenceId, const GnssLocationAidl& location, - int transition, int64_t timestampMillis) override; - Status gnssGeofenceStatusCb(int availability, const GnssLocationAidl& lastLocation) override; - Status gnssGeofenceAddCb(int geofenceId, int status) override; - Status gnssGeofenceRemoveCb(int geofenceId, int status) override; - Status gnssGeofencePauseCb(int geofenceId, int status) override; - Status gnssGeofenceResumeCb(int geofenceId, int status) override; -}; - -Status GnssGeofenceCallbackAidl::gnssGeofenceTransitionCb(int geofenceId, - const GnssLocationAidl& location, - int transition, int64_t timestampMillis) { - GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(geofenceId, location, transition, - timestampMillis); - return Status::ok(); -} - -Status GnssGeofenceCallbackAidl::gnssGeofenceStatusCb(int availability, - const GnssLocationAidl& lastLocation) { - GnssGeofenceCallbackUtil::gnssGeofenceStatusCb(availability, lastLocation); - return Status::ok(); -} - -Status GnssGeofenceCallbackAidl::gnssGeofenceAddCb(int geofenceId, int status) { - GnssGeofenceCallbackUtil::gnssGeofenceAddCb(geofenceId, status); - return Status::ok(); -} - -Status GnssGeofenceCallbackAidl::gnssGeofenceRemoveCb(int geofenceId, int status) { - GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(geofenceId, status); - return Status::ok(); -} - -Status GnssGeofenceCallbackAidl::gnssGeofencePauseCb(int geofenceId, int status) { - GnssGeofenceCallbackUtil::gnssGeofencePauseCb(geofenceId, status); - return Status::ok(); -} - -Status GnssGeofenceCallbackAidl::gnssGeofenceResumeCb(int geofenceId, int status) { - GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(geofenceId, status); - return Status::ok(); -} - -/* - * GnssGeofenceCallback class implements the callback methods for the - * IGnssGeofence HIDL interface. - */ -struct GnssGeofenceCallback : public IGnssGeofenceCallback { - // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow. - Return gnssGeofenceTransitionCb(int32_t geofenceId, const GnssLocation_V1_0& location, - GeofenceTransition transition, - hardware::gnss::V1_0::GnssUtcTime timestamp) override; - Return gnssGeofenceStatusCb(GeofenceAvailability status, - const GnssLocation_V1_0& location) override; - Return gnssGeofenceAddCb(int32_t geofenceId, GeofenceStatus status) override; - Return gnssGeofenceRemoveCb(int32_t geofenceId, GeofenceStatus status) override; - Return gnssGeofencePauseCb(int32_t geofenceId, GeofenceStatus status) override; - Return gnssGeofenceResumeCb(int32_t geofenceId, GeofenceStatus status) override; -}; - -Return GnssGeofenceCallback::gnssGeofenceTransitionCb( - int32_t geofenceId, const GnssLocation_V1_0& location, GeofenceTransition transition, - hardware::gnss::V1_0::GnssUtcTime timestamp) { - GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(geofenceId, location, (int)transition, - (int64_t)timestamp); - return Void(); -} - -Return GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability availability, - const GnssLocation_V1_0& location) { - GnssGeofenceCallbackUtil::gnssGeofenceStatusCb((int)availability, location); - return Void(); -} - -Return GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId, GeofenceStatus status) { - GnssGeofenceCallbackUtil::gnssGeofenceAddCb(geofenceId, (int)status); - return Void(); -} - -Return GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId, GeofenceStatus status) { - GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(geofenceId, (int)status); - return Void(); -} - -Return GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId, GeofenceStatus status) { - GnssGeofenceCallbackUtil::gnssGeofencePauseCb(geofenceId, (int)status); - return Void(); -} - -Return GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId, GeofenceStatus status) { - GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(geofenceId, (int)status); - return Void(); -} - /* * MeasurementCorrectionsCallback implements callback methods of interface * IMeasurementCorrectionsCallback.hal. @@ -1206,18 +1003,6 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); - method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition", - "(ILandroid/location/Location;IJ)V"); - method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus", - "(ILandroid/location/Location;)V"); - method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus", - "(II)V"); - method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus", - "(II)V"); - method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus", - "(II)V"); - method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus", - "(II)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"); @@ -1522,27 +1307,27 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject if (checkHidlReturn(gnssConfiguration, "Unable to get a handle to GnssConfiguration_V1_1")) { gnssConfigurationIface = - std::make_unique(gnssConfiguration); + std::make_unique(gnssConfiguration); } } else { auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration(); if (checkHidlReturn(gnssConfiguration, "Unable to get a handle to GnssConfiguration_V1_0")) { gnssConfigurationIface = - std::make_unique(gnssConfiguration); + std::make_unique(gnssConfiguration); } } if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) { - sp gnssGeofenceAidl; - auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofenceAidl); - if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence interface.")) { - gnssGeofenceAidlIface = gnssGeofenceAidl; + sp gnssGeofence; + auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofence); + if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence AIDL interface.")) { + gnssGeofencingIface = std::make_unique(gnssGeofence); } } else if (gnssHal != nullptr) { auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing(); if (checkHidlReturn(gnssGeofencing, "Unable to get a handle to GnssGeofencing")) { - gnssGeofencingIface = gnssGeofencing; + gnssGeofencingIface = std::make_unique(gnssGeofencing); } } @@ -1680,19 +1465,9 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl ALOGI("Unable to initialize IAGnss interface."); } - // Set IGnssGeofencing.hal callback. - if (gnssGeofenceAidlIface != nullptr) { - sp gnssGeofenceCallbackAidl = new GnssGeofenceCallbackAidl(); - auto status = gnssGeofenceAidlIface->setCallback(gnssGeofenceCallbackAidl); - if (!checkAidlStatus(status, "IGnssGeofenceAidl setCallback() failed.")) { - gnssGeofenceAidlIface = nullptr; - } - } else if (gnssGeofencingIface != nullptr) { - sp gnssGeofencingCbIface = new GnssGeofenceCallback(); - auto status = gnssGeofencingIface->setCallback(gnssGeofencingCbIface); - if (!checkHidlReturn(status, "IGnssGeofencing setCallback() failed.")) { - gnssGeofencingIface = nullptr; - } + // Set GnssGeofence callback. + if (gnssGeofencingIface != nullptr) { + gnssGeofencingIface->setCallback(std::make_unique()); } else { ALOGI("Unable to initialize IGnssGeofencing interface."); } @@ -2239,7 +2014,7 @@ static void android_location_GnssNetworkConnectivityHandler_update_network_state static jboolean android_location_gnss_hal_GnssNative_is_geofence_supported(JNIEnv* /* env */, jclass) { - if (gnssGeofencingIface == nullptr && gnssGeofenceAidlIface == nullptr) { + if (gnssGeofencingIface == nullptr) { return JNI_FALSE; } return JNI_TRUE; @@ -2249,75 +2024,41 @@ static jboolean android_location_gnss_hal_GnssNative_add_geofence( JNIEnv* /* env */, jclass, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius, jint last_transition, jint monitor_transition, jint notification_responsiveness, jint unknown_timer) { - if (gnssGeofenceAidlIface != nullptr) { - auto status = - gnssGeofenceAidlIface->addGeofence(geofenceId, latitude, longitude, radius, - last_transition, monitor_transition, - notification_responsiveness, unknown_timer); - return checkAidlStatus(status, "IGnssGeofenceAidl addGeofence() failed."); + if (gnssGeofencingIface == nullptr) { + ALOGE("%s: IGnssGeofencing interface not available.", __func__); + return JNI_FALSE; } - - if (gnssGeofencingIface != nullptr) { - auto result = gnssGeofencingIface - ->addGeofence(geofenceId, latitude, longitude, radius, - static_cast( - last_transition), - monitor_transition, notification_responsiveness, - unknown_timer); - return checkHidlReturn(result, "IGnssGeofencing addGeofence() failed."); - } - - ALOGE("%s: IGnssGeofencing interface not available.", __func__); - return JNI_FALSE; + return gnssGeofencingIface->addGeofence(geofenceId, latitude, longitude, radius, + last_transition, monitor_transition, + notification_responsiveness, unknown_timer); } static jboolean android_location_gnss_hal_GnssNative_remove_geofence(JNIEnv* /* env */, jclass, jint geofenceId) { - if (gnssGeofenceAidlIface != nullptr) { - auto status = gnssGeofenceAidlIface->removeGeofence(geofenceId); - return checkAidlStatus(status, "IGnssGeofenceAidl removeGeofence() failed."); + if (gnssGeofencingIface == nullptr) { + ALOGE("%s: IGnssGeofencing interface not available.", __func__); + return JNI_FALSE; } - - if (gnssGeofencingIface != nullptr) { - auto result = gnssGeofencingIface->removeGeofence(geofenceId); - return checkHidlReturn(result, "IGnssGeofencing removeGeofence() failed."); - } - - ALOGE("%s: IGnssGeofencing interface not available.", __func__); - return JNI_FALSE; + return gnssGeofencingIface->removeGeofence(geofenceId); } static jboolean android_location_gnss_hal_GnssNative_pause_geofence(JNIEnv* /* env */, jclass, jint geofenceId) { - if (gnssGeofenceAidlIface != nullptr) { - auto status = gnssGeofenceAidlIface->pauseGeofence(geofenceId); - return checkAidlStatus(status, "IGnssGeofenceAidl pauseGeofence() failed."); + if (gnssGeofencingIface == nullptr) { + ALOGE("%s: IGnssGeofencing interface not available.", __func__); + return JNI_FALSE; } - - if (gnssGeofencingIface != nullptr) { - auto result = gnssGeofencingIface->pauseGeofence(geofenceId); - return checkHidlReturn(result, "IGnssGeofencing pauseGeofence() failed."); - } - - ALOGE("%s: IGnssGeofencing interface not available.", __func__); - return JNI_FALSE; + return gnssGeofencingIface->pauseGeofence(geofenceId); } static jboolean android_location_gnss_hal_GnssNative_resume_geofence(JNIEnv* /* env */, jclass, jint geofenceId, jint monitor_transition) { - if (gnssGeofenceAidlIface != nullptr) { - auto status = gnssGeofenceAidlIface->resumeGeofence(geofenceId, monitor_transition); - return checkAidlStatus(status, "IGnssGeofenceAidl resumeGeofence() failed."); + if (gnssGeofencingIface == nullptr) { + ALOGE("%s: IGnssGeofencing interface not available.", __func__); + return JNI_FALSE; } - - if (gnssGeofencingIface != nullptr) { - auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition); - return checkHidlReturn(result, "IGnssGeofencing resumeGeofence() failed."); - } - - ALOGE("%s: IGnssGeofencing interface not available.", __func__); - return JNI_FALSE; + return gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition); } static jboolean android_location_gnss_hal_GnssNative_is_antenna_info_supported(JNIEnv* env, diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp index 6c6b30405ab37..ac50bfa5c4429 100644 --- a/services/core/jni/gnss/Android.bp +++ b/services/core/jni/gnss/Android.bp @@ -27,6 +27,8 @@ cc_library_shared { "GnssBatching.cpp", "GnssBatchingCallback.cpp", "GnssConfiguration.cpp", + "GnssGeofence.cpp", + "GnssGeofenceCallback.cpp", "GnssMeasurement.cpp", "GnssMeasurementCallback.cpp", "GnssNavigationMessage.cpp", diff --git a/services/core/jni/gnss/GnssGeofence.cpp b/services/core/jni/gnss/GnssGeofence.cpp new file mode 100644 index 0000000000000..01d134dc4859d --- /dev/null +++ b/services/core/jni/gnss/GnssGeofence.cpp @@ -0,0 +1,108 @@ +/* + * 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 to overwrite the default value. +#define LOG_TAG "GnssGeofenceJni" + +#include "GnssGeofence.h" + +#include "Utils.h" + +using android::hardware::hidl_bitfield; +using GeofenceTransition = android::hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceTransition; +using IGnssGeofenceAidl = android::hardware::gnss::IGnssGeofence; +using IGnssGeofenceHidl = android::hardware::gnss::V1_0::IGnssGeofencing; + +namespace android::gnss { + +// Implementation of GnssGeofence (AIDL HAL) + +GnssGeofenceAidl::GnssGeofenceAidl(const sp& iGnssGeofence) + : mIGnssGeofenceAidl(iGnssGeofence) { + assert(mIGnssGeofenceAidl != nullptr); +} + +jboolean GnssGeofenceAidl::setCallback(const std::unique_ptr& callback) { + auto status = mIGnssGeofenceAidl->setCallback(callback->getAidl()); + return checkAidlStatus(status, "IGnssGeofenceAidl init() failed."); +} + +jboolean GnssGeofenceAidl::addGeofence(int geofenceId, double latitudeDegrees, + double longitudeDegrees, double radiusMeters, + int lastTransition, int monitorTransitions, + int notificationResponsivenessMs, int unknownTimerMs) { + auto status = mIGnssGeofenceAidl->addGeofence(geofenceId, latitudeDegrees, longitudeDegrees, + radiusMeters, lastTransition, monitorTransitions, + notificationResponsivenessMs, unknownTimerMs); + return checkAidlStatus(status, "IGnssGeofenceAidl addGeofence() failed"); +} + +jboolean GnssGeofenceAidl::removeGeofence(int geofenceId) { + auto status = mIGnssGeofenceAidl->removeGeofence(geofenceId); + return checkAidlStatus(status, "IGnssGeofenceAidl removeGeofence() failed."); +} + +jboolean GnssGeofenceAidl::pauseGeofence(int geofenceId) { + auto status = mIGnssGeofenceAidl->pauseGeofence(geofenceId); + return checkAidlStatus(status, "IGnssGeofenceAidl pauseGeofence() failed."); +} + +jboolean GnssGeofenceAidl::resumeGeofence(int geofenceId, int monitorTransitions) { + auto status = mIGnssGeofenceAidl->resumeGeofence(geofenceId, monitorTransitions); + return checkAidlStatus(status, "IGnssGeofenceAidl resumeGeofence() failed."); +} + +// Implementation of GnssGeofenceHidl + +GnssGeofenceHidl::GnssGeofenceHidl(const sp& iGnssGeofence) + : mIGnssGeofenceHidl(iGnssGeofence) { + assert(mIGnssGeofenceHidl != nullptr); +} + +jboolean GnssGeofenceHidl::setCallback(const std::unique_ptr& callback) { + auto result = mIGnssGeofenceHidl->setCallback(callback->getHidl()); + return checkHidlReturn(result, "IGnssGeofenceHidl setCallback() failed."); +} + +jboolean GnssGeofenceHidl::addGeofence(int geofenceId, double latitudeDegrees, + double longitudeDegrees, double radiusMeters, + int lastTransition, int monitorTransitions, + int notificationResponsivenessMs, int unknownTimerMs) { + auto result = mIGnssGeofenceHidl->addGeofence(geofenceId, latitudeDegrees, longitudeDegrees, + radiusMeters, + static_cast(lastTransition), + static_cast>( + monitorTransitions), + notificationResponsivenessMs, unknownTimerMs); + return checkHidlReturn(result, "IGnssGeofence addGeofence() failed."); +} + +jboolean GnssGeofenceHidl::removeGeofence(int geofenceId) { + auto result = mIGnssGeofenceHidl->removeGeofence(geofenceId); + return checkHidlReturn(result, "IGnssGeofence removeGeofence() failed."); +} + +jboolean GnssGeofenceHidl::pauseGeofence(int geofenceId) { + auto result = mIGnssGeofenceHidl->pauseGeofence(geofenceId); + return checkHidlReturn(result, "IGnssGeofence pauseGeofence() failed."); +} + +jboolean GnssGeofenceHidl::resumeGeofence(int geofenceId, int monitorTransitions) { + auto result = mIGnssGeofenceHidl->resumeGeofence(geofenceId, monitorTransitions); + return checkHidlReturn(result, "IGnssGeofence resumeGeofence() failed."); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssGeofence.h b/services/core/jni/gnss/GnssGeofence.h new file mode 100644 index 0000000000000..31478eaac7a6c --- /dev/null +++ b/services/core/jni/gnss/GnssGeofence.h @@ -0,0 +1,79 @@ +/* + * 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_GNSSGEOFENCE_H +#define _ANDROID_SERVER_GNSS_GNSSGEOFENCE_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include "GnssGeofenceCallback.h" +#include "jni.h" + +namespace android::gnss { + +class GnssGeofenceInterface { +public: + virtual ~GnssGeofenceInterface() {} + virtual jboolean setCallback(const std::unique_ptr& callback); + virtual jboolean addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees, + double radiusMeters, int lastTransition, int monitorTransitions, + int notificationResponsivenessMs, int unknownTimerMs); + virtual jboolean pauseGeofence(int geofenceId); + virtual jboolean resumeGeofence(int geofenceId, int monitorTransitions); + virtual jboolean removeGeofence(int geofenceId); +}; + +class GnssGeofenceAidl : public GnssGeofenceInterface { +public: + GnssGeofenceAidl(const sp& iGnssGeofence); + jboolean setCallback(const std::unique_ptr& callback) override; + jboolean addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees, + double radiusMeters, int lastTransition, int monitorTransitions, + int notificationResponsivenessMs, int unknownTimerMs) override; + jboolean pauseGeofence(int geofenceId) override; + jboolean resumeGeofence(int geofenceId, int monitorTransitions) override; + jboolean removeGeofence(int geofenceId) override; + +private: + const sp mIGnssGeofenceAidl; +}; + +class GnssGeofenceHidl : public GnssGeofenceInterface { +public: + GnssGeofenceHidl(const sp& iGnssGeofence); + jboolean setCallback(const std::unique_ptr& callback) override; + jboolean addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees, + double radiusMeters, int lastTransition, int monitorTransitions, + int notificationResponsivenessMs, int unknownTimerMs) override; + jboolean pauseGeofence(int geofenceId) override; + jboolean resumeGeofence(int geofenceId, int monitorTransitions) override; + jboolean removeGeofence(int geofenceId) override; + +private: + const sp mIGnssGeofenceHidl; +}; + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSGEOFENCE_H diff --git a/services/core/jni/gnss/GnssGeofenceCallback.cpp b/services/core/jni/gnss/GnssGeofenceCallback.cpp new file mode 100644 index 0000000000000..2cdf9730871d4 --- /dev/null +++ b/services/core/jni/gnss/GnssGeofenceCallback.cpp @@ -0,0 +1,171 @@ +/* + * 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 "GnssGeofenceCbJni" + +#include "GnssGeofenceCallback.h" + +namespace android::gnss { + +namespace { + +jmethodID method_reportGeofenceTransition; +jmethodID method_reportGeofenceStatus; +jmethodID method_reportGeofenceAddStatus; +jmethodID method_reportGeofenceRemoveStatus; +jmethodID method_reportGeofencePauseStatus; +jmethodID method_reportGeofenceResumeStatus; + +} // anonymous namespace + +using binder::Status; +using hardware::Return; +using hardware::Void; +using GeofenceAvailability = + android::hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceAvailability; +using GeofenceStatus = android::hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus; +using GeofenceTransition = android::hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceTransition; + +using GnssLocationAidl = android::hardware::gnss::GnssLocation; +using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation; + +void GnssGeofence_class_init_once(JNIEnv* env, jclass clazz) { + method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition", + "(ILandroid/location/Location;IJ)V"); + method_reportGeofenceStatus = + env->GetMethodID(clazz, "reportGeofenceStatus", "(ILandroid/location/Location;)V"); + method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus", "(II)V"); + method_reportGeofenceRemoveStatus = + env->GetMethodID(clazz, "reportGeofenceRemoveStatus", "(II)V"); + method_reportGeofenceResumeStatus = + env->GetMethodID(clazz, "reportGeofenceResumeStatus", "(II)V"); + method_reportGeofencePauseStatus = + env->GetMethodID(clazz, "reportGeofencePauseStatus", "(II)V"); +} + +Status GnssGeofenceCallbackAidl::gnssGeofenceTransitionCb(int geofenceId, + const GnssLocationAidl& location, + int transition, int64_t timestampMillis) { + GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(geofenceId, location, transition, + timestampMillis); + return Status::ok(); +} + +Status GnssGeofenceCallbackAidl::gnssGeofenceStatusCb(int availability, + const GnssLocationAidl& lastLocation) { + GnssGeofenceCallbackUtil::gnssGeofenceStatusCb(availability, lastLocation); + return Status::ok(); +} + +Status GnssGeofenceCallbackAidl::gnssGeofenceAddCb(int geofenceId, int status) { + GnssGeofenceCallbackUtil::gnssGeofenceAddCb(geofenceId, status); + return Status::ok(); +} + +Status GnssGeofenceCallbackAidl::gnssGeofenceRemoveCb(int geofenceId, int status) { + GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(geofenceId, status); + return Status::ok(); +} + +Status GnssGeofenceCallbackAidl::gnssGeofencePauseCb(int geofenceId, int status) { + GnssGeofenceCallbackUtil::gnssGeofencePauseCb(geofenceId, status); + return Status::ok(); +} + +Status GnssGeofenceCallbackAidl::gnssGeofenceResumeCb(int geofenceId, int status) { + GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(geofenceId, status); + return Status::ok(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofenceTransitionCb( + int32_t geofenceId, const GnssLocation_V1_0& location, GeofenceTransition transition, + hardware::gnss::V1_0::GnssUtcTime timestamp) { + GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(geofenceId, location, (int)transition, + (int64_t)timestamp); + return Void(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofenceStatusCb(GeofenceAvailability availability, + const GnssLocation_V1_0& location) { + GnssGeofenceCallbackUtil::gnssGeofenceStatusCb((int)availability, location); + return Void(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofenceAddCb(int32_t geofenceId, + GeofenceStatus status) { + GnssGeofenceCallbackUtil::gnssGeofenceAddCb(geofenceId, (int)status); + return Void(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofenceRemoveCb(int32_t geofenceId, + GeofenceStatus status) { + GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(geofenceId, (int)status); + return Void(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofencePauseCb(int32_t geofenceId, + GeofenceStatus status) { + GnssGeofenceCallbackUtil::gnssGeofencePauseCb(geofenceId, (int)status); + return Void(); +} + +Return GnssGeofenceCallbackHidl::gnssGeofenceResumeCb(int32_t geofenceId, + GeofenceStatus status) { + GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(geofenceId, (int)status); + return Void(); +} + +void GnssGeofenceCallbackUtil::gnssGeofenceAddCb(int geofenceId, int status) { + JNIEnv* env = getJniEnv(); + if (status != hardware::gnss::IGnssGeofenceCallback::OPERATION_SUCCESS) { + ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status); + } + + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceAddStatus, geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +void GnssGeofenceCallbackUtil::gnssGeofenceRemoveCb(int geofenceId, int status) { + JNIEnv* env = getJniEnv(); + if (status != hardware::gnss::IGnssGeofenceCallback::OPERATION_SUCCESS) { + ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status); + } + + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceRemoveStatus, geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +void GnssGeofenceCallbackUtil::gnssGeofencePauseCb(int geofenceId, int status) { + JNIEnv* env = getJniEnv(); + if (status != hardware::gnss::IGnssGeofenceCallback::OPERATION_SUCCESS) { + ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status); + } + + env->CallVoidMethod(mCallbacksObj, method_reportGeofencePauseStatus, geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +void GnssGeofenceCallbackUtil::gnssGeofenceResumeCb(int geofenceId, int status) { + JNIEnv* env = getJniEnv(); + if (status != hardware::gnss::IGnssGeofenceCallback::OPERATION_SUCCESS) { + ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status); + } + + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceResumeStatus, geofenceId, status); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + +} // namespace android::gnss diff --git a/services/core/jni/gnss/GnssGeofenceCallback.h b/services/core/jni/gnss/GnssGeofenceCallback.h new file mode 100644 index 0000000000000..b6a8a368c4c3a --- /dev/null +++ b/services/core/jni/gnss/GnssGeofenceCallback.h @@ -0,0 +1,151 @@ +/* + * 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_GNSSGEOFENCECALLBACK_H +#define _ANDROID_SERVER_GNSS_GNSSGEOFENCECALLBACK_H + +#pragma once + +#ifndef LOG_TAG +#error LOG_TAG must be defined before including this file. +#endif + +#include +#include +#include + +#include + +#include "Utils.h" +#include "jni.h" + +namespace android::gnss { + +namespace { +extern jmethodID method_reportGeofenceTransition; +extern jmethodID method_reportGeofenceStatus; +extern jmethodID method_reportGeofenceAddStatus; +extern jmethodID method_reportGeofenceRemoveStatus; +extern jmethodID method_reportGeofencePauseStatus; +extern jmethodID method_reportGeofenceResumeStatus; +} // anonymous namespace + +void GnssGeofence_class_init_once(JNIEnv* env, jclass clazz); + +class GnssGeofenceCallbackAidl : public hardware::gnss::BnGnssGeofenceCallback { +public: + GnssGeofenceCallbackAidl() {} + binder::Status gnssGeofenceTransitionCb(int geofenceId, + const hardware::gnss::GnssLocation& location, + int transition, int64_t timestampMillis) override; + binder::Status gnssGeofenceStatusCb(int availability, + const hardware::gnss::GnssLocation& lastLocation) override; + binder::Status gnssGeofenceAddCb(int geofenceId, int status) override; + binder::Status gnssGeofenceRemoveCb(int geofenceId, int status) override; + binder::Status gnssGeofencePauseCb(int geofenceId, int status) override; + binder::Status gnssGeofenceResumeCb(int geofenceId, int status) override; +}; + +class GnssGeofenceCallbackHidl : public hardware::gnss::V1_0::IGnssGeofenceCallback { +public: + GnssGeofenceCallbackHidl() {} + hardware::Return gnssGeofenceTransitionCb( + int32_t geofenceId, const hardware::gnss::V1_0::GnssLocation& location, + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceTransition transition, + hardware::gnss::V1_0::GnssUtcTime timestamp) override; + hardware::Return gnssGeofenceStatusCb( + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceAvailability status, + const hardware::gnss::V1_0::GnssLocation& location) override; + hardware::Return gnssGeofenceAddCb( + int32_t geofenceId, + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override; + hardware::Return gnssGeofenceRemoveCb( + int32_t geofenceId, + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override; + hardware::Return gnssGeofencePauseCb( + int32_t geofenceId, + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override; + hardware::Return gnssGeofenceResumeCb( + int32_t geofenceId, + hardware::gnss::V1_0::IGnssGeofenceCallback::GeofenceStatus status) override; +}; + +class GnssGeofenceCallback { +public: + GnssGeofenceCallback() {} + sp getAidl() { + if (callbackAidl == nullptr) { + callbackAidl = sp::make(); + } + return callbackAidl; + } + + sp getHidl() { + if (callbackHidl == nullptr) { + callbackHidl = sp::make(); + } + return callbackHidl; + } + +private: + sp callbackAidl; + sp callbackHidl; +}; + +/** Util class for GnssGeofenceCallback methods. */ +struct GnssGeofenceCallbackUtil { + template + static void gnssGeofenceTransitionCb(int geofenceId, const T& location, int transition, + int64_t timestampMillis); + template + static void gnssGeofenceStatusCb(int availability, const T& lastLocation); + static void gnssGeofenceAddCb(int geofenceId, int status); + static void gnssGeofenceRemoveCb(int geofenceId, int status); + static void gnssGeofencePauseCb(int geofenceId, int status); + static void gnssGeofenceResumeCb(int geofenceId, int status); + +private: + GnssGeofenceCallbackUtil() = delete; +}; + +template +void GnssGeofenceCallbackUtil::gnssGeofenceTransitionCb(int geofenceId, const T& location, + int transition, int64_t timestamp) { + JNIEnv* env = getJniEnv(); + + jobject jLocation = translateGnssLocation(env, location); + + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofenceId, jLocation, + transition, timestamp); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(jLocation); +} + +template +void GnssGeofenceCallbackUtil::gnssGeofenceStatusCb(int availability, const T& lastLocation) { + JNIEnv* env = getJniEnv(); + + jobject jLocation = translateGnssLocation(env, lastLocation); + + env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, availability, jLocation); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(jLocation); +} + +} // namespace android::gnss + +#endif // _ANDROID_SERVER_GNSS_GNSSGEOFENCECALLBACK_H \ No newline at end of file