summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/LocationManagerService.java25
-rw-r--r--services/java/com/android/server/location/FlpHardwareProvider.java93
-rw-r--r--services/java/com/android/server/location/GeofenceProxy.java20
-rw-r--r--services/java/com/android/server/location/GpsLocationProvider.java118
-rw-r--r--services/jni/com_android_server_location_FlpHardwareProvider.cpp151
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)}
};