summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareImpl.java27
-rw-r--r--core/java/android/hardware/location/GeofenceHardwareService.java11
-rw-r--r--core/java/android/hardware/location/IFusedLocationHardwareSink.aidl10
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardware.java40
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java33
-rw-r--r--services/core/java/com/android/server/location/FlpHardwareProvider.java35
-rw-r--r--services/core/jni/com_android_server_location_FlpHardwareProvider.cpp42
7 files changed, 184 insertions, 14 deletions
diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java
index 4696b2a..5d40e94 100644
--- a/core/java/android/hardware/location/GeofenceHardwareImpl.java
+++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java
@@ -53,6 +53,7 @@ public final class GeofenceHardwareImpl {
private IFusedGeofenceHardware mFusedService;
private IGpsGeofenceHardware mGpsService;
+ private int mCapabilities;
private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
@@ -89,6 +90,9 @@ public final class GeofenceHardwareImpl {
private static final int RESOLUTION_LEVEL_COARSE = 2;
private static final int RESOLUTION_LEVEL_FINE = 3;
+ // Capability constant corresponding to fused_location.h entry when geofencing supports GNNS.
+ private static final int CAPABILITY_GNSS = 1;
+
public synchronized static GeofenceHardwareImpl getInstance(Context context) {
if (sInstance == null) {
sInstance = new GeofenceHardwareImpl(context);
@@ -141,7 +145,9 @@ public final class GeofenceHardwareImpl {
private void updateFusedHardwareAvailability() {
boolean fusedSupported;
try {
- fusedSupported = (mFusedService != null ? mFusedService.isSupported() : false);
+ fusedSupported = (mFusedService != null
+ ? mFusedService.isSupported() && (mCapabilities & CAPABILITY_GNSS) != 0
+ : false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling LocationManagerService");
fusedSupported = false;
@@ -166,6 +172,11 @@ public final class GeofenceHardwareImpl {
}
}
+ public void onCapabilities(int capabilities) {
+ mCapabilities = capabilities;
+ updateFusedHardwareAvailability();
+ }
+
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
if(mFusedService == null) {
mFusedService = service;
@@ -212,6 +223,20 @@ public final class GeofenceHardwareImpl {
}
}
+ public int getCapabilitiesForMonitoringType(int monitoringType) {
+ switch (mSupportedMonitorTypes[monitoringType]) {
+ case GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE:
+ switch (monitoringType) {
+ case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+ return CAPABILITY_GNSS;
+ case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
+ return mCapabilities;
+ }
+ break;
+ }
+ return 0;
+ }
+
public boolean addCircularFence(
int monitoringType,
GeofenceHardwareRequestParcelable request,
diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java
index 4816c5f..c0bcb27 100644
--- a/core/java/android/hardware/location/GeofenceHardwareService.java
+++ b/core/java/android/hardware/location/GeofenceHardwareService.java
@@ -65,14 +65,17 @@ public class GeofenceHardwareService extends Service {
}
private IBinder mBinder = new IGeofenceHardware.Stub() {
+ @Override
public void setGpsGeofenceHardware(IGpsGeofenceHardware service) {
mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
}
+ @Override
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
}
+ @Override
public int[] getMonitoringTypes() {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -80,12 +83,15 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.getMonitoringTypes();
}
+ @Override
public int getStatusOfMonitoringType(int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType);
}
+
+ @Override
public boolean addCircularFence(
int monitoringType,
GeofenceHardwareRequestParcelable request,
@@ -96,6 +102,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.addCircularFence(monitoringType, request, callback);
}
+ @Override
public boolean removeGeofence(int id, int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -104,6 +111,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
}
+ @Override
public boolean pauseGeofence(int id, int monitoringType) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -112,6 +120,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
}
+ @Override
public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
"Location Hardware permission not granted to access hardware geofence");
@@ -120,6 +129,7 @@ public class GeofenceHardwareService extends Service {
return mGeofenceHardwareImpl.resumeGeofence(id, monitoringType, monitorTransitions);
}
+ @Override
public boolean registerForMonitorStateChangeCallback(int monitoringType,
IGeofenceHardwareMonitorCallback callback) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
@@ -130,6 +140,7 @@ public class GeofenceHardwareService extends Service {
callback);
}
+ @Override
public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
IGeofenceHardwareMonitorCallback callback) {
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
diff --git a/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
index a11d8ab..2107ae8 100644
--- a/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
+++ b/core/java/android/hardware/location/IFusedLocationHardwareSink.aidl
@@ -30,12 +30,18 @@ interface IFusedLocationHardwareSink {
*
* @param locations The batch of location information available.
*/
- void onLocationAvailable(in Location[] locations);
+ void onLocationAvailable(in Location[] locations) = 0;
/**
* Event generated from FLP HAL to provide diagnostic data to the platform.
*
* @param data The diagnostic data provided by FLP HAL.
*/
- void onDiagnosticDataAvailable(in String data);
+ void onDiagnosticDataAvailable(in String data) = 1;
+
+ /**
+ * Event generated from FLP HAL to provide a mask of supported
+ * capabilities. Should be called immediatly after init.
+ */
+ void onCapabilities(int capabilities) = 2;
} \ No newline at end of file
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardware.java b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
index bc5a8a1..44cb199 100644
--- a/location/lib/java/com/android/location/provider/FusedLocationHardware.java
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
@@ -34,7 +34,7 @@ import java.util.Map;
* Class that exposes IFusedLocationHardware functionality to unbundled services.
*/
public final class FusedLocationHardware {
- private final String TAG = "FusedLocationHardware";
+ private static final String TAG = "FusedLocationHardware";
private IFusedLocationHardware mLocationHardware;
@@ -52,6 +52,11 @@ public final class FusedLocationHardware {
public void onDiagnosticDataAvailable(String data) {
dispatchDiagnosticData(data);
}
+
+ @Override
+ public void onCapabilities(int capabilities) {
+ dispatchCapabilities(capabilities);
+ }
};
/**
@@ -204,6 +209,7 @@ public final class FusedLocationHardware {
private class DispatcherHandler extends Handler {
public static final int DISPATCH_LOCATION = 1;
public static final int DISPATCH_DIAGNOSTIC_DATA = 2;
+ public static final int DISPATCH_CAPABILITIES = 3;
public DispatcherHandler(Looper looper) {
super(looper, null /*callback*/ , true /*async*/);
@@ -218,6 +224,10 @@ public final class FusedLocationHardware {
break;
case DISPATCH_DIAGNOSTIC_DATA:
command.dispatchDiagnosticData();
+ break;
+ case DISPATCH_CAPABILITIES:
+ command.dispatchCapabilities();
+ break;
default:
Log.e(TAG, "Invalid dispatch message");
break;
@@ -229,14 +239,17 @@ public final class FusedLocationHardware {
private final FusedLocationHardwareSink mSink;
private final Location[] mLocations;
private final String mData;
+ private final int mCapabilities;
public MessageCommand(
FusedLocationHardwareSink sink,
Location[] locations,
- String data) {
+ String data,
+ int capabilities) {
mSink = sink;
mLocations = locations;
mData = data;
+ mCapabilities = capabilities;
}
public void dispatchLocation() {
@@ -246,6 +259,10 @@ public final class FusedLocationHardware {
public void dispatchDiagnosticData() {
mSink.onDiagnosticDataAvailable(mData);
}
+
+ public void dispatchCapabilities() {
+ mSink.onCapabilities(mCapabilities);
+ }
}
private void dispatchLocations(Location[] locations) {
@@ -258,7 +275,7 @@ public final class FusedLocationHardware {
Message message = Message.obtain(
entry.getValue(),
DispatcherHandler.DISPATCH_LOCATION,
- new MessageCommand(entry.getKey(), locations, null /*data*/));
+ new MessageCommand(entry.getKey(), locations, null /*data*/, 0));
message.sendToTarget();
}
}
@@ -273,7 +290,22 @@ public final class FusedLocationHardware {
Message message = Message.obtain(
entry.getValue(),
DispatcherHandler.DISPATCH_DIAGNOSTIC_DATA,
- new MessageCommand(entry.getKey(), null /*locations*/, data));
+ new MessageCommand(entry.getKey(), null /*locations*/, data, 0));
+ message.sendToTarget();
+ }
+ }
+
+ private void dispatchCapabilities(int capabilities) {
+ HashMap<FusedLocationHardwareSink, DispatcherHandler> sinks;
+ synchronized(mSinkList) {
+ sinks = mSinkList;
+ }
+
+ for(Map.Entry<FusedLocationHardwareSink, DispatcherHandler> entry : sinks.entrySet()) {
+ Message message = Message.obtain(
+ entry.getValue(),
+ DispatcherHandler.DISPATCH_CAPABILITIES,
+ new MessageCommand(entry.getKey(), null /*locations*/, null, capabilities));
message.sendToTarget();
}
}
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
index 2c39fa8..aaef773 100644
--- a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
@@ -20,11 +20,34 @@ import android.location.Location;
/**
* Base class for sinks to interact with FusedLocationHardware.
+ *
+ * <p>Default implementations allow new methods to be added without crashing
+ * clients compiled against an old library version.
*/
-public abstract class FusedLocationHardwareSink {
- /*
- * Methods to provide a facade for IFusedLocationHardware
+public class FusedLocationHardwareSink {
+ /**
+ * Called when one or more locations are available from the FLP
+ * HAL.
+ */
+ public void onLocationAvailable(Location[] locations) {
+ // default do nothing
+ }
+
+ /**
+ * Called when diagnostic data is available from the FLP HAL.
+ */
+ public void onDiagnosticDataAvailable(String data) {
+ // default do nothing
+ }
+
+ /**
+ * Called when capabilities are available from the FLP HAL.
+ * Should be called once right after initialization.
+ *
+ * @param capabilities A bitmask of capabilities defined in
+ * fused_location.h.
*/
- public abstract void onLocationAvailable(Location[] locations);
- public abstract void onDiagnosticDataAvailable(String data);
+ public void onCapabilities(int capabilities) {
+ // default do nothing
+ }
} \ No newline at end of file
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 530ad4b..94a1cd8 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -44,6 +44,9 @@ import android.util.Log;
public class FlpHardwareProvider {
private GeofenceHardwareImpl mGeofenceHardwareSink = null;
private IFusedLocationHardwareSink mLocationSink = null;
+ // Capabilities provided by FlpCallbacks
+ private boolean mHaveBatchingCapabilities;
+ private int mBatchingCapabilities;
private static FlpHardwareProvider sSingletonInstance = null;
@@ -124,6 +127,33 @@ public class FlpHardwareProvider {
}
}
+ private void onBatchingCapabilities(int capabilities) {
+ synchronized (mLocationSinkLock) {
+ mHaveBatchingCapabilities = true;
+ mBatchingCapabilities = capabilities;
+ }
+
+ maybeSendCapabilities();
+ }
+
+ private void maybeSendCapabilities() {
+ IFusedLocationHardwareSink sink;
+ boolean haveBatchingCapabilities;
+ int batchingCapabilities;
+ synchronized (mLocationSinkLock) {
+ sink = mLocationSink;
+ haveBatchingCapabilities = mHaveBatchingCapabilities;
+ batchingCapabilities = mBatchingCapabilities;
+ }
+ try {
+ if (sink != null && haveBatchingCapabilities) {
+ sink.onCapabilities(batchingCapabilities);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling onLocationAvailable");
+ }
+ }
+
// FlpDiagnosticCallbacks members
private void onDataReport(String data) {
IFusedLocationHardwareSink sink;
@@ -209,6 +239,10 @@ public class FlpHardwareProvider {
translateToGeofenceHardwareStatus(result));
}
+ private void onGeofencingCapabilities(int capabilities) {
+ getGeofenceHardwareSink().onCapabilities(capabilities);
+ }
+
/**
* Private native methods accessing FLP HAL.
*/
@@ -277,6 +311,7 @@ public class FlpHardwareProvider {
mLocationSink = eventSink;
}
+ maybeSendCapabilities();
}
@Override
diff --git a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
index d5508bc..5b5634b 100644
--- a/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
+++ b/services/core/jni/com_android_server_location_FlpHardwareProvider.cpp
@@ -33,12 +33,14 @@ static hw_device_t* sHardwareDevice = NULL;
static jmethodID sOnLocationReport = NULL;
static jmethodID sOnDataReport = NULL;
+static jmethodID sOnBatchingCapabilities = NULL;
static jmethodID sOnGeofenceTransition = NULL;
static jmethodID sOnGeofenceMonitorStatus = NULL;
static jmethodID sOnGeofenceAdd = NULL;
static jmethodID sOnGeofenceRemove = NULL;
static jmethodID sOnGeofencePause = NULL;
static jmethodID sOnGeofenceResume = NULL;
+static jmethodID sOnGeofencingCapabilities = NULL;
static const FlpLocationInterface* sFlpInterface = NULL;
static const FlpDiagnosticInterface* sFlpDiagnosticInterface = NULL;
@@ -85,6 +87,19 @@ static bool IsValidCallbackThread() {
return true;
}
+static void BatchingCapabilitiesCallback(int32_t capabilities) {
+ if(!IsValidCallbackThread()) {
+ return;
+ }
+
+ sCallbackEnv->CallVoidMethod(
+ sCallbacksObj,
+ sOnBatchingCapabilities,
+ capabilities
+ );
+ CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
static int SetThreadEvent(ThreadEvent event) {
JavaVM* javaVm = AndroidRuntime::getJavaVM();
@@ -156,6 +171,14 @@ static void ClassInit(JNIEnv* env, jclass clazz) {
"onDataReport",
"(Ljava/lang/String;)V"
);
+ sOnBatchingCapabilities = env->GetMethodID(
+ clazz,
+ "onBatchingCapabilities",
+ "(I)V");
+ sOnGeofencingCapabilities = env->GetMethodID(
+ clazz,
+ "onGeofencingCapabilities",
+ "(I)V");
sOnGeofenceTransition = env->GetMethodID(
clazz,
"onGeofenceTransition",
@@ -534,7 +557,8 @@ FlpCallbacks sFlpCallbacks = {
LocationCallback,
AcquireWakelock,
ReleaseWakelock,
- SetThreadEvent
+ SetThreadEvent,
+ BatchingCapabilitiesCallback
};
static void ReportData(char* data, int length) {
@@ -670,6 +694,19 @@ static void GeofenceResumeCallback(int32_t geofenceId, int32_t result) {
CheckExceptions(sCallbackEnv, __FUNCTION__);
}
+static void GeofencingCapabilitiesCallback(int32_t capabilities) {
+ if(!IsValidCallbackThread()) {
+ return;
+ }
+
+ sCallbackEnv->CallVoidMethod(
+ sCallbacksObj,
+ sOnGeofencingCapabilities,
+ capabilities
+ );
+ CheckExceptions(sCallbackEnv, __FUNCTION__);
+}
+
FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
sizeof(FlpGeofenceCallbacks),
GeofenceTransitionCallback,
@@ -678,7 +715,8 @@ FlpGeofenceCallbacks sFlpGeofenceCallbacks = {
GeofenceRemoveCallback,
GeofencePauseCallback,
GeofenceResumeCallback,
- SetThreadEvent
+ SetThreadEvent,
+ GeofencingCapabilitiesCallback
};
/*