diff options
Diffstat (limited to 'services')
5 files changed, 325 insertions, 82 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index a32699a..d039a5e 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -420,19 +420,7 @@ public class LocationManagerService extends ILocationManager.Stub { Slog.e(TAG, "no geocoder provider found"); } - // bind to geofence provider - GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, - com.android.internal.R.bool.config_enableGeofenceOverlay, - com.android.internal.R.string.config_geofenceProviderPackageName, - com.android.internal.R.array.config_locationProviderPackageNames, - mLocationHandler, - gpsProvider.getGpsGeofenceProxy()); - if (provider == null) { - Slog.e(TAG, "no geofence provider found"); - } - // bind to fused provider - // TODO: [GeofenceIntegration] bind #getGeofenceHardware() with the GeofenceProxy FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext); FusedProxy fusedProxy = FusedProxy.createAndBind( mContext, @@ -441,10 +429,21 @@ public class LocationManagerService extends ILocationManager.Stub { com.android.internal.R.bool.config_enableFusedLocationOverlay, com.android.internal.R.string.config_fusedLocationProviderPackageName, com.android.internal.R.array.config_locationProviderPackageNames); - if(fusedProxy == null) { Slog.e(TAG, "No FusedProvider found."); } + + // bind to geofence provider + GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, + com.android.internal.R.bool.config_enableGeofenceOverlay, + com.android.internal.R.string.config_geofenceProviderPackageName, + com.android.internal.R.array.config_locationProviderPackageNames, + mLocationHandler, + gpsProvider.getGpsGeofenceProxy(), + flpHardwareProvider.getGeofenceHardware()); + if (provider == null) { + Slog.e(TAG, "no geofence provider found"); + } } /** diff --git a/services/java/com/android/server/location/FlpHardwareProvider.java b/services/java/com/android/server/location/FlpHardwareProvider.java index 226c18c..ebeccfb 100644 --- a/services/java/com/android/server/location/FlpHardwareProvider.java +++ b/services/java/com/android/server/location/FlpHardwareProvider.java @@ -16,12 +16,13 @@ package com.android.server.location; +import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; +import android.hardware.location.GeofenceHardwareRequestParcelable; import android.hardware.location.IFusedLocationHardware; import android.hardware.location.IFusedLocationHardwareSink; import android.location.IFusedGeofenceHardware; import android.location.FusedBatchOptions; -import android.location.Geofence; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; @@ -49,6 +50,15 @@ public class FlpHardwareProvider { private final Context mContext; private final Object mLocationSinkLock = new Object(); + // FlpHal result codes, they must be equal to the ones in fused_location.h + private static final int FLP_RESULT_SUCCESS = 0; + private static final int FLP_RESULT_ERROR = -1; + private static final int FLP_RESULT_INSUFFICIENT_MEMORY = -2; + private static final int FLP_RESULT_TOO_MANY_GEOFENCES = -3; + private static final int FLP_RESULT_ID_EXISTS = -4; + private static final int FLP_RESULT_ID_UNKNOWN = -5; + private static final int FLP_RESULT_INVALID_GEOFENCE_TRANSITION = -6; + public static FlpHardwareProvider getInstance(Context context) { if (sSingletonInstance == null) { sSingletonInstance = new FlpHardwareProvider(context); @@ -120,29 +130,46 @@ public class FlpHardwareProvider { Location location, int transition, long timestamp, - int sourcesUsed - ) { - // TODO: [GeofenceIntegration] change GeofenceHardwareImpl to accept a location object + int sourcesUsed) { + getGeofenceHardwareSink().reportGeofenceTransition( + geofenceId, + updateLocationInformation(location), + transition, + timestamp, + GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, + sourcesUsed); } private void onGeofenceMonitorStatus(int status, int source, Location location) { - // TODO: [GeofenceIntegration] + getGeofenceHardwareSink().reportGeofenceMonitorStatus( + GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, + status, + updateLocationInformation(location), + source); } private void onGeofenceAdd(int geofenceId, int result) { - // TODO: [GeofenceIntegration] map between GPS and FLP results to pass a consistent status + getGeofenceHardwareSink().reportGeofenceAddStatus( + geofenceId, + translateToGeofenceHardwareStatus(result)); } private void onGeofenceRemove(int geofenceId, int result) { - // TODO: [GeofenceIntegration] map between GPS and FLP results to pass a consistent status + getGeofenceHardwareSink().reportGeofenceRemoveStatus( + geofenceId, + translateToGeofenceHardwareStatus(result)); } private void onGeofencePause(int geofenceId, int result) { - // TODO; [GeofenceIntegration] map between GPS and FLP results + getGeofenceHardwareSink().reportGeofencePauseStatus( + geofenceId, + translateToGeofenceHardwareStatus(result)); } private void onGeofenceResume(int geofenceId, int result) { - // TODO: [GeofenceIntegration] map between GPS and FLP results + getGeofenceHardwareSink().reportGeofenceResumeStatus( + geofenceId, + translateToGeofenceHardwareStatus(result)); } /** @@ -175,7 +202,8 @@ public class FlpHardwareProvider { // FlpGeofencingInterface members private native boolean nativeIsGeofencingSupported(); - private native void nativeAddGeofences(int[] geofenceIdsArray, Geofence[] geofencesArray); + private native void nativeAddGeofences( + GeofenceHardwareRequestParcelable[] geofenceRequestsArray); private native void nativePauseGeofence(int geofenceId); private native void nativeResumeGeofence(int geofenceId, int monitorTransitions); private native void nativeModifyGeofenceOption( @@ -281,8 +309,8 @@ public class FlpHardwareProvider { } @Override - public void addGeofences(int[] geofenceIdsArray, Geofence[] geofencesArray) { - nativeAddGeofences(geofenceIdsArray, geofencesArray); + public void addGeofences(GeofenceHardwareRequestParcelable[] geofenceRequestsArray) { + nativeAddGeofences(geofenceRequestsArray); } @Override @@ -305,17 +333,15 @@ public class FlpHardwareProvider { int lastTransition, int monitorTransitions, int notificationResponsiveness, - int unknownTimer - ) { - // TODO: [GeofenceIntegration] set sourcesToUse to the right value - // TODO: expose sourcesToUse externally when needed + int unknownTimer, + int sourcesToUse) { nativeModifyGeofenceOption( geofenceId, lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer, - /* sourcesToUse */ 0xFFFF); + sourcesToUse); } }; @@ -347,10 +373,39 @@ public class FlpHardwareProvider { private GeofenceHardwareImpl getGeofenceHardwareSink() { if (mGeofenceHardwareSink == null) { - // TODO: [GeofenceIntegration] we need to register ourselves with GeofenceHardwareImpl mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext); } return mGeofenceHardwareSink; } -}
\ No newline at end of file + + private static int translateToGeofenceHardwareStatus(int flpHalResult) { + switch(flpHalResult) { + case FLP_RESULT_SUCCESS: + return GeofenceHardware.GEOFENCE_SUCCESS; + case FLP_RESULT_ERROR: + return GeofenceHardware.GEOFENCE_FAILURE; + // TODO: uncomment this once the ERROR definition is marked public + //case FLP_RESULT_INSUFFICIENT_MEMORY: + // return GeofenceHardware.GEOFENCE_ERROR_INSUFFICIENT_MEMORY; + case FLP_RESULT_TOO_MANY_GEOFENCES: + return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES; + case FLP_RESULT_ID_EXISTS: + return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS; + case FLP_RESULT_ID_UNKNOWN: + return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN; + case FLP_RESULT_INVALID_GEOFENCE_TRANSITION: + return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION; + default: + Log.e(TAG, String.format("Invalid FlpHal result code: %d", flpHalResult)); + return GeofenceHardware.GEOFENCE_FAILURE; + } + } + + private Location updateLocationInformation(Location location) { + location.setProvider(LocationManager.FUSED_PROVIDER); + // set the elapsed time-stamp just as GPS provider does + location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); + return location; + } +} diff --git a/services/java/com/android/server/location/GeofenceProxy.java b/services/java/com/android/server/location/GeofenceProxy.java index f6be27b..a86c923 100644 --- a/services/java/com/android/server/location/GeofenceProxy.java +++ b/services/java/com/android/server/location/GeofenceProxy.java @@ -22,6 +22,7 @@ import android.hardware.location.GeofenceHardwareService; import android.hardware.location.IGeofenceHardware; import android.location.IGeofenceProvider; import android.location.IGpsGeofenceHardware; +import android.location.IFusedGeofenceHardware; import android.content.Context; import android.os.Handler; import android.os.IBinder; @@ -44,6 +45,7 @@ public final class GeofenceProxy { private Context mContext; private IGeofenceHardware mGeofenceHardware; private IGpsGeofenceHardware mGpsGeofenceHardware; + private IFusedGeofenceHardware mFusedGeofenceHardware; private static final int GEOFENCE_PROVIDER_CONNECTED = 1; private static final int GEOFENCE_HARDWARE_CONNECTED = 2; @@ -60,9 +62,11 @@ public final class GeofenceProxy { public static GeofenceProxy createAndBind(Context context, int overlaySwitchResId, int defaultServicePackageNameResId, - int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) { + int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence, + IFusedGeofenceHardware fusedGeofenceHardware) { GeofenceProxy proxy = new GeofenceProxy(context, overlaySwitchResId, - defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence); + defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence, + fusedGeofenceHardware); if (proxy.bindGeofenceProvider()) { return proxy; } else { @@ -72,11 +76,13 @@ public final class GeofenceProxy { private GeofenceProxy(Context context, int overlaySwitchResId, int defaultServicePackageNameResId, - int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) { + int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence, + IFusedGeofenceHardware fusedGeofenceHardware) { mContext = context; mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId, defaultServicePackageNameResId, initialPackageNamesResId, mRunnable, handler); mGpsGeofenceHardware = gpsGeofence; + mFusedGeofenceHardware = fusedGeofenceHardware; bindHardwareGeofence(); } @@ -123,6 +129,13 @@ public final class GeofenceProxy { } } + private void setFusedGeofence() { + try { + mGeofenceHardware.setFusedGeofenceHardware(mFusedGeofenceHardware); + } catch(RemoteException e) { + Log.e(TAG, "Error while connecting to GeofenceHardwareService"); + } + } // This needs to be reworked, when more services get added, // Might need a state machine or add a framework utility class, @@ -142,6 +155,7 @@ public final class GeofenceProxy { break; case GEOFENCE_HARDWARE_CONNECTED: setGpsGeofence(); + setFusedGeofence(); mGeofenceHardwareConnected = true; if (mGeofenceProviderConnected) { setGeofenceHardwareInProvider(); diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java index 38453c8..6053c61 100644 --- a/services/java/com/android/server/location/GpsLocationProvider.java +++ b/services/java/com/android/server/location/GpsLocationProvider.java @@ -24,9 +24,10 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; +import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; -import android.hardware.location.IGeofenceHardware; import android.location.Criteria; +import android.location.FusedBatchOptions; import android.location.IGpsGeofenceHardware; import android.location.IGpsStatusListener; import android.location.IGpsStatusProvider; @@ -195,6 +196,17 @@ public class GpsLocationProvider implements LocationProviderInterface { private static final String PROPERTIES_FILE = "/etc/gps.conf"; + private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L; + private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L; + + // GPS Geofence errors. Should match gps.h constants. + private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0; + private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100; + private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101; + private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102; + private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103; + private static final int GPS_GEOFENCE_ERROR_GENERIC = -149; + /** simpler wrapper for ProviderRequest + Worksource */ private static class GpsRequest { public ProviderRequest request; @@ -501,7 +513,7 @@ public class GpsLocationProvider implements LocationProviderInterface { LocationManager locManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, - 0, 0, new NetworkLocationListener(), mHandler.getLooper()); + 0, 0, new NetworkLocationListener(), mHandler.getLooper()); } }); } @@ -1405,6 +1417,62 @@ public class GpsLocationProvider implements LocationProviderInterface { } /** + * Helper method to construct a location object. + */ + private Location buildLocation( + int flags, + double latitude, + double longitude, + double altitude, + float speed, + float bearing, + float accuracy, + long timestamp) { + Location location = new Location(LocationManager.GPS_PROVIDER); + if((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { + location.setLatitude(latitude); + location.setLongitude(longitude); + location.setTime(timestamp); + location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); + } + if((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { + location.setAltitude(altitude); + } + if((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { + location.setSpeed(speed); + } + if((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { + location.setBearing(bearing); + } + if((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { + location.setAccuracy(accuracy); + } + return location; + } + + /** + * Converts the GPS HAL status to the internal Geofence Hardware status. + */ + private int getGeofenceStatus(int status) { + switch(status) { + case GPS_GEOFENCE_OPERATION_SUCCESS: + return GeofenceHardware.GEOFENCE_SUCCESS; + case GPS_GEOFENCE_ERROR_GENERIC: + return GeofenceHardware.GEOFENCE_FAILURE; + case GPS_GEOFENCE_ERROR_ID_EXISTS: + return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS; + case GPS_GEOFENCE_ERROR_INVALID_TRANSITION: + return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION; + case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES: + return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES; + case GPS_GEOFENCE_ERROR_ID_UNKNOWN: + return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN; + default: + return -1; + } + } + + /** * Called from native to report GPS Geofence transition * All geofence callbacks are called on the same thread */ @@ -1414,8 +1482,22 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofenceTransition(geofenceId, flags, latitude, longitude, - altitude, speed, bearing, accuracy, timestamp, transition, transitionTimestamp); + Location location = buildLocation( + flags, + latitude, + longitude, + altitude, + speed, + bearing, + accuracy, + timestamp); + mGeofenceHardwareImpl.reportGeofenceTransition( + geofenceId, + location, + transition, + transitionTimestamp, + GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, + FusedBatchOptions.SourceTechnologies.GNSS); } /** @@ -1427,8 +1509,24 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofenceStatus(status, flags, latitude, longitude, altitude, - speed, bearing, accuracy, timestamp); + Location location = buildLocation( + flags, + latitude, + longitude, + altitude, + speed, + bearing, + accuracy, + timestamp); + int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE; + if(status == GPS_GEOFENCE_AVAILABLE) { + monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE; + } + mGeofenceHardwareImpl.reportGeofenceMonitorStatus( + GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, + monitorStatus, + location, + FusedBatchOptions.SourceTechnologies.GNSS); } /** @@ -1438,7 +1536,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofenceAddStatus(geofenceId, status); + mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status)); } /** @@ -1448,7 +1546,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofenceRemoveStatus(geofenceId, status); + mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status)); } /** @@ -1458,7 +1556,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofencePauseStatus(geofenceId, status); + mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status)); } /** @@ -1468,7 +1566,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (mGeofenceHardwareImpl == null) { mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext); } - mGeofenceHardwareImpl.reportGpsGeofenceResumeStatus(geofenceId, status); + mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status)); } //============================================================= diff --git a/services/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/jni/com_android_server_location_FlpHardwareProvider.cpp index 48b86db..c871828 100644 --- a/services/jni/com_android_server_location_FlpHardwareProvider.cpp +++ b/services/jni/com_android_server_location_FlpHardwareProvider.cpp @@ -261,6 +261,75 @@ static void TranslateFromObject( } /* + * Helper function to unwrap Geofence structures from the Java Runtime calls. + */ +static void TranslateGeofenceFromGeofenceHardwareRequestParcelable( + JNIEnv* env, + jobject geofenceRequestObject, + Geofence& geofence) { + jclass geofenceRequestClass = env->GetObjectClass(geofenceRequestObject); + + jmethodID getId = env->GetMethodID(geofenceRequestClass, "getId", "()I"); + geofence.geofence_id = env->CallIntMethod(geofenceRequestObject, getId); + + jmethodID getType = env->GetMethodID(geofenceRequestClass, "getType", "()I"); + // this works because GeofenceHardwareRequest.java and fused_location.h have + // the same notion of geofence types + GeofenceType type = (GeofenceType)env->CallIntMethod(geofenceRequestObject, getType); + if(type != TYPE_CIRCLE) { + ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__); + } + geofence.data->type = type; + GeofenceCircle& circle = geofence.data->geofence.circle; + + jmethodID getLatitude = env->GetMethodID( + geofenceRequestClass, + "getLatitude", + "()D"); + circle.latitude = env->CallDoubleMethod(geofenceRequestObject, getLatitude); + + jmethodID getLongitude = env->GetMethodID( + geofenceRequestClass, + "getLongitude", + "()D"); + circle.longitude = env->CallDoubleMethod(geofenceRequestObject, getLongitude); + + jmethodID getRadius = env->GetMethodID(geofenceRequestClass, "getRadius", "()D"); + circle.radius_m = env->CallDoubleMethod(geofenceRequestObject, getRadius); + + GeofenceOptions* options = geofence.options; + jmethodID getMonitorTransitions = env->GetMethodID( + geofenceRequestClass, + "getMonitorTransitions", + "()I"); + options->monitor_transitions = env->CallIntMethod( + geofenceRequestObject, + getMonitorTransitions); + + jmethodID getUnknownTimer = env->GetMethodID( + geofenceRequestClass, + "getUnknownTimer", + "()I"); + options->unknown_timer_ms = env->CallIntMethod(geofenceRequestObject, getUnknownTimer); + + jmethodID getNotificationResponsiveness = env->GetMethodID( + geofenceRequestClass, + "getNotificationResponsiveness", + "()D"); + options->notification_responsivenes_ms = env->CallIntMethod( + geofenceRequestObject, + getNotificationResponsiveness); + + jmethodID getLastTransition = env->GetMethodID( + geofenceRequestClass, + "getLastTransition", + "()I"); + options->last_transition = env->CallIntMethod(geofenceRequestObject, getLastTransition); + + // TODO: set data.sources_to_use when available +} + +/* * Helper function to transform FlpLocation into a java object. */ static void TranslateToObject(const FlpLocation* location, jobject& locationObject) { @@ -559,7 +628,7 @@ static void Init(JNIEnv* env, jobject obj) { } err = module->methods->open( - module, + module, FUSED_LOCATION_HARDWARE_MODULE_ID, &sHardwareDevice); if(err != 0) { ALOGE("Error opening device '%s': %d", FUSED_LOCATION_HARDWARE_MODULE_ID, err); @@ -749,10 +818,9 @@ static jboolean IsGeofencingSupported() { static void AddGeofences( JNIEnv* env, jobject object, - jintArray geofenceIdsArray, - jobjectArray geofencesArray) { - if(geofencesArray == NULL) { - ALOGE("Invalid Geofences to add: %p", geofencesArray); + jobjectArray geofenceRequestsArray) { + if(geofenceRequestsArray == NULL) { + ALOGE("Invalid Geofences to add: %p", geofenceRequestsArray); ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__); } @@ -760,23 +828,32 @@ static void AddGeofences( ThrowOnError(env, FLP_RESULT_ERROR, __FUNCTION__); } - jint geofencesCount = env->GetArrayLength(geofenceIdsArray); - Geofence* geofences = new Geofence[geofencesCount]; + jint geofenceRequestsCount = env->GetArrayLength(geofenceRequestsArray); + if(geofenceRequestsCount == 0) { + return; + } + + Geofence* geofences = new Geofence[geofenceRequestsCount]; if (geofences == NULL) { ThrowOnError(env, FLP_RESULT_INSUFFICIENT_MEMORY, __FUNCTION__); } - jint* ids = env->GetIntArrayElements(geofenceIdsArray, /* isCopy */ NULL); - for (int i = 0; i < geofencesCount; ++i) { - geofences[i].geofence_id = ids[i]; + for (int i = 0; i < geofenceRequestsCount; ++i) { + geofences[i].data = new GeofenceData(); + geofences[i].options = new GeofenceOptions(); + jobject geofenceObject = env->GetObjectArrayElement(geofenceRequestsArray, i); - // TODO: fill in the GeofenceData - - // TODO: fill in the GeofenceOptions + TranslateGeofenceFromGeofenceHardwareRequestParcelable(env, geofenceObject, geofences[i]); } - sFlpGeofencingInterface->add_geofences(geofencesCount, &geofences); - if (geofences != NULL) delete[] geofences; + sFlpGeofencingInterface->add_geofences(geofenceRequestsCount, &geofences); + if (geofences != NULL) { + for(int i = 0; i < geofenceRequestsCount; ++i) { + delete geofences[i].data; + delete geofences[i].options; + } + delete[] geofences; + } } static void PauseGeofence(JNIEnv* env, jobject object, jint geofenceId) { @@ -847,41 +924,41 @@ static JNINativeMethod sMethods[] = { {"nativeCleanup", "()V", reinterpret_cast<void*>(Cleanup)}, {"nativeIsSupported", "()Z", reinterpret_cast<void*>(IsSupported)}, {"nativeGetBatchSize", "()I", reinterpret_cast<void*>(GetBatchSize)}, - {"nativeStartBatching", - "(ILandroid/location/FusedBatchOptions;)V", + {"nativeStartBatching", + "(ILandroid/location/FusedBatchOptions;)V", reinterpret_cast<void*>(StartBatching)}, - {"nativeUpdateBatchingOptions", - "(ILandroid/location/FusedBatchOptions;)V", + {"nativeUpdateBatchingOptions", + "(ILandroid/location/FusedBatchOptions;)V", reinterpret_cast<void*>(UpdateBatchingOptions)}, {"nativeStopBatching", "(I)V", reinterpret_cast<void*>(StopBatching)}, - {"nativeRequestBatchedLocation", - "(I)V", + {"nativeRequestBatchedLocation", + "(I)V", reinterpret_cast<void*>(GetBatchedLocation)}, - {"nativeInjectLocation", - "(Landroid/location/Location;)V", + {"nativeInjectLocation", + "(Landroid/location/Location;)V", reinterpret_cast<void*>(InjectLocation)}, - {"nativeIsDiagnosticSupported", - "()Z", + {"nativeIsDiagnosticSupported", + "()Z", reinterpret_cast<void*>(IsDiagnosticSupported)}, - {"nativeInjectDiagnosticData", - "(Ljava/lang/String;)V", + {"nativeInjectDiagnosticData", + "(Ljava/lang/String;)V", reinterpret_cast<void*>(InjectDiagnosticData)}, - {"nativeIsDeviceContextSupported", - "()Z", + {"nativeIsDeviceContextSupported", + "()Z", reinterpret_cast<void*>(IsDeviceContextSupported)}, - {"nativeInjectDeviceContext", - "(I)V", + {"nativeInjectDeviceContext", + "(I)V", reinterpret_cast<void*>(InjectDeviceContext)}, - {"nativeIsGeofencingSupported", - "()Z", + {"nativeIsGeofencingSupported", + "()Z", reinterpret_cast<void*>(IsGeofencingSupported)}, - {"nativeAddGeofences", - "([I[Landroid/location/Geofence;)V", + {"nativeAddGeofences", + "([Landroid/hardware/location/GeofenceHardwareRequestParcelable;)V", reinterpret_cast<void*>(AddGeofences)}, {"nativePauseGeofence", "(I)V", reinterpret_cast<void*>(PauseGeofence)}, {"nativeResumeGeofence", "(II)V", reinterpret_cast<void*>(ResumeGeofence)}, - {"nativeModifyGeofenceOption", - "(IIIIII)V", + {"nativeModifyGeofenceOption", + "(IIIIII)V", reinterpret_cast<void*>(ModifyGeofenceOption)}, {"nativeRemoveGeofences", "([I)V", reinterpret_cast<void*>(RemoveGeofences)} }; |