am 5c7e6460: Merge "Add support in the platform for Flp Geofencing." into klp-dev
* commit '5c7e64609c4de93cd70c2cbe238a5fc3ff3c6078': Add support in the platform for Flp Geofencing.
This commit is contained in:
@@ -355,6 +355,7 @@ aidl_files := \
|
||||
frameworks/base/core/java/android/content/SyncStats.aidl \
|
||||
frameworks/base/core/java/android/content/res/Configuration.aidl \
|
||||
frameworks/base/core/java/android/database/CursorWindow.aidl \
|
||||
frameworks/base/core/java/android/hardware/location/GeofenceHardwareRequestParcelable.aidl \
|
||||
frameworks/base/core/java/android/net/Uri.aidl \
|
||||
frameworks/base/core/java/android/nfc/NdefMessage.aidl \
|
||||
frameworks/base/core/java/android/nfc/NdefRecord.aidl \
|
||||
|
||||
@@ -15,16 +15,11 @@
|
||||
*/
|
||||
package android.hardware.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* This class handles geofences managed by various hardware subsystems. It contains
|
||||
@@ -52,13 +47,20 @@ public final class GeofenceHardware {
|
||||
private IGeofenceHardware mService;
|
||||
|
||||
// Hardware systems that do geofence monitoring.
|
||||
static final int NUM_MONITORS = 1;
|
||||
static final int NUM_MONITORS = 2;
|
||||
|
||||
/**
|
||||
* Constant for geofence monitoring done by the GPS hardware.
|
||||
*/
|
||||
public static final int MONITORING_TYPE_GPS_HARDWARE = 0;
|
||||
|
||||
/**
|
||||
* Constant for geofence monitoring done by the Fused hardware.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int MONITORING_TYPE_FUSED_HARDWARE = 1;
|
||||
|
||||
/**
|
||||
* Constant to indiciate that the monitoring system is currently
|
||||
* available for monitoring geofences.
|
||||
@@ -124,8 +126,12 @@ public final class GeofenceHardware {
|
||||
*/
|
||||
public static final int GEOFENCE_FAILURE = 5;
|
||||
|
||||
static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
|
||||
static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
|
||||
/**
|
||||
* The constant used to indicate that the operation failed due to insufficient memory.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int GEOFENCE_ERROR_INSUFFICIENT_MEMORY = 6;
|
||||
|
||||
private HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>
|
||||
mCallbacks = new HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>();
|
||||
|
||||
@@ -18,23 +18,21 @@ package android.hardware.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.FusedBatchOptions;
|
||||
import android.location.IFusedGeofenceHardware;
|
||||
import android.location.IGpsGeofenceHardware;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class manages the geofences which are handled by hardware.
|
||||
@@ -54,6 +52,7 @@ public final class GeofenceHardwareImpl {
|
||||
new ArrayList[GeofenceHardware.NUM_MONITORS];
|
||||
private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>();
|
||||
|
||||
private IFusedGeofenceHardware mFusedService;
|
||||
private IGpsGeofenceHardware mGpsService;
|
||||
|
||||
private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
|
||||
@@ -67,7 +66,7 @@ public final class GeofenceHardwareImpl {
|
||||
private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6;
|
||||
|
||||
// mCallbacksHandler message types
|
||||
private static final int GPS_GEOFENCE_STATUS = 1;
|
||||
private static final int GEOFENCE_STATUS = 1;
|
||||
private static final int CALLBACK_ADD = 2;
|
||||
private static final int CALLBACK_REMOVE = 3;
|
||||
private static final int MONITOR_CALLBACK_BINDER_DIED = 4;
|
||||
@@ -91,16 +90,6 @@ public final class GeofenceHardwareImpl {
|
||||
private static final int RESOLUTION_LEVEL_COARSE = 2;
|
||||
private static final int RESOLUTION_LEVEL_FINE = 3;
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
|
||||
public synchronized static GeofenceHardwareImpl getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GeofenceHardwareImpl(context);
|
||||
@@ -113,6 +102,9 @@ public final class GeofenceHardwareImpl {
|
||||
// Init everything to unsupported.
|
||||
setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
|
||||
GeofenceHardware.MONITOR_UNSUPPORTED);
|
||||
setMonitorAvailability(
|
||||
GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
|
||||
GeofenceHardware.MONITOR_UNSUPPORTED);
|
||||
|
||||
}
|
||||
|
||||
@@ -147,6 +139,22 @@ public final class GeofenceHardwareImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFusedHardwareAvailability() {
|
||||
boolean fusedSupported;
|
||||
try {
|
||||
fusedSupported = mFusedService.isSupported();
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoteException calling LocationManagerService");
|
||||
fusedSupported = false;
|
||||
}
|
||||
|
||||
if(fusedSupported) {
|
||||
setMonitorAvailability(
|
||||
GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE,
|
||||
GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setGpsHardwareGeofence(IGpsGeofenceHardware service) {
|
||||
if (mGpsService == null) {
|
||||
mGpsService = service;
|
||||
@@ -159,12 +167,39 @@ public final class GeofenceHardwareImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
|
||||
if(mFusedService == null) {
|
||||
mFusedService = service;
|
||||
updateFusedHardwareAvailability();
|
||||
} else if(service == null) {
|
||||
mFusedService = null;
|
||||
Log.w(TAG, "Fused Geofence Hardware service seems to have crashed");
|
||||
} else {
|
||||
Log.e(TAG, "Error: FusedService being set again");
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getMonitoringTypes() {
|
||||
boolean gpsSupported;
|
||||
boolean fusedSupported;
|
||||
synchronized (mSupportedMonitorTypes) {
|
||||
if (mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE] !=
|
||||
GeofenceHardware.MONITOR_UNSUPPORTED) {
|
||||
return new int[] {GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE};
|
||||
gpsSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE]
|
||||
!= GeofenceHardware.MONITOR_UNSUPPORTED;
|
||||
fusedSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE]
|
||||
!= GeofenceHardware.MONITOR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if(gpsSupported) {
|
||||
if(fusedSupported) {
|
||||
return new int[] {
|
||||
GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
|
||||
GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE };
|
||||
} else {
|
||||
return new int[] { GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE };
|
||||
}
|
||||
} else if (fusedSupported) {
|
||||
return new int[] { GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE };
|
||||
} else {
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
@@ -213,6 +248,30 @@ public final class GeofenceHardwareImpl {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
|
||||
if(mFusedService == null) {
|
||||
return false;
|
||||
}
|
||||
GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
|
||||
latitude,
|
||||
longitude,
|
||||
radius);
|
||||
request.setUnknownTimer(unknownTimer);
|
||||
request.setNotificationResponsiveness(notificationResponsivenes);
|
||||
request.setMonitorTransitions(monitorTransitions);
|
||||
request.setLastTransition(lastTransition);
|
||||
|
||||
GeofenceHardwareRequestParcelable parcelableRequest =
|
||||
new GeofenceHardwareRequestParcelable(geofenceId, request);
|
||||
try {
|
||||
mFusedService.addGeofences(
|
||||
new GeofenceHardwareRequestParcelable[] { parcelableRequest });
|
||||
result = true;
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "AddGeofence: RemoteException calling LocationManagerService");
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
@@ -251,6 +310,18 @@ public final class GeofenceHardwareImpl {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
|
||||
if(mFusedService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
mFusedService.removeGeofences(new int[] { geofenceId });
|
||||
result = true;
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "RemoveGeofence: RemoteException calling LocationManagerService");
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
@@ -278,6 +349,18 @@ public final class GeofenceHardwareImpl {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
|
||||
if(mFusedService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
mFusedService.pauseMonitoringGeofence(geofenceId);
|
||||
result = true;
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "PauseGeofence: RemoteException calling LocationManagerService");
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
@@ -306,6 +389,18 @@ public final class GeofenceHardwareImpl {
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
|
||||
if(mFusedService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
mFusedService.resumeMonitoringGeofence(geofenceId, monitorTransition);
|
||||
result = true;
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "ResumeGeofence: RemoteException calling LocationManagerService");
|
||||
result = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
@@ -334,127 +429,106 @@ public final class GeofenceHardwareImpl {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Location getLocation(int flags, double latitude,
|
||||
double longitude, double altitude, float speed, float bearing, float accuracy,
|
||||
long timestamp) {
|
||||
if (DEBUG) Log.d(TAG, "GetLocation: " + flags + ":" + latitude);
|
||||
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);
|
||||
// It would be nice to push the elapsed real-time timestamp
|
||||
// further down the stack, but this is still useful
|
||||
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
|
||||
/**
|
||||
* Used to report geofence transitions
|
||||
*/
|
||||
public void reportGeofenceTransition(
|
||||
int geofenceId,
|
||||
Location location,
|
||||
int transition,
|
||||
long transitionTimestamp,
|
||||
int monitoringType,
|
||||
int sourcesUsed) {
|
||||
if(location == null) {
|
||||
Log.e(TAG, String.format("Invalid Geofence Transition: location=%p", location));
|
||||
return;
|
||||
}
|
||||
if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
|
||||
location.setAltitude(altitude);
|
||||
} else {
|
||||
location.removeAltitude();
|
||||
if(DEBUG) {
|
||||
Log.d(
|
||||
TAG,
|
||||
"GeofenceTransition| " + location + ", transition:" + transition +
|
||||
", transitionTimestamp:" + transitionTimestamp + ", monitoringType:" +
|
||||
monitoringType + ", sourcesUsed:" + sourcesUsed);
|
||||
}
|
||||
if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
|
||||
location.setSpeed(speed);
|
||||
} else {
|
||||
location.removeSpeed();
|
||||
}
|
||||
if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
|
||||
location.setBearing(bearing);
|
||||
} else {
|
||||
location.removeBearing();
|
||||
}
|
||||
if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
|
||||
location.setAccuracy(accuracy);
|
||||
} else {
|
||||
location.removeAccuracy();
|
||||
}
|
||||
return location;
|
||||
|
||||
GeofenceTransition geofenceTransition = new GeofenceTransition(
|
||||
geofenceId,
|
||||
transition,
|
||||
transitionTimestamp,
|
||||
location,
|
||||
monitoringType,
|
||||
sourcesUsed);
|
||||
acquireWakeLock();
|
||||
|
||||
Message message = mGeofenceHandler.obtainMessage(
|
||||
GEOFENCE_TRANSITION_CALLBACK,
|
||||
geofenceTransition);
|
||||
message.sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider to report geofence transition
|
||||
* Used to report Monitor status changes.
|
||||
*/
|
||||
public void reportGpsGeofenceTransition(int geofenceId, int flags, double latitude,
|
||||
double longitude, double altitude, float speed, float bearing, float accuracy,
|
||||
long timestamp, int transition, long transitionTimestamp) {
|
||||
if (DEBUG) Log.d(TAG, "GeofenceTransition: Flags: " + flags + " Lat: " + latitude +
|
||||
" Long: " + longitude + " Altitude: " + altitude + " Speed: " + speed + " Bearing: " +
|
||||
bearing + " Accuracy: " + accuracy + " Timestamp: " + timestamp + " Transition: " +
|
||||
transition + " TransitionTimestamp: " + transitionTimestamp);
|
||||
Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
|
||||
accuracy, timestamp);
|
||||
GeofenceTransition t = new GeofenceTransition(geofenceId, transition, timestamp, location);
|
||||
public void reportGeofenceMonitorStatus(
|
||||
int monitoringType,
|
||||
int monitoringStatus,
|
||||
Location location,
|
||||
int source) {
|
||||
// TODO: use the source if needed in the future
|
||||
setMonitorAvailability(monitoringType, monitoringStatus);
|
||||
acquireWakeLock();
|
||||
Message m = mGeofenceHandler.obtainMessage(GEOFENCE_TRANSITION_CALLBACK, t);
|
||||
mGeofenceHandler.sendMessage(m);
|
||||
Message message = mCallbacksHandler.obtainMessage(GEOFENCE_STATUS, location);
|
||||
message.arg1 = monitoringStatus;
|
||||
message.arg2 = monitoringType;
|
||||
message.sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider to report GPS status change.
|
||||
* Internal generic status report function for Geofence operations.
|
||||
*
|
||||
* @param operation The operation to be reported as defined internally.
|
||||
* @param geofenceId The id of the geofence the operation is related to.
|
||||
* @param operationStatus The status of the operation as defined in GeofenceHardware class. This
|
||||
* status is independent of the statuses reported by different HALs.
|
||||
*/
|
||||
public void reportGpsGeofenceStatus(int status, int flags, double latitude,
|
||||
double longitude, double altitude, float speed, float bearing, float accuracy,
|
||||
long timestamp) {
|
||||
Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
|
||||
accuracy, timestamp);
|
||||
boolean available = false;
|
||||
if (status == GeofenceHardware.GPS_GEOFENCE_AVAILABLE) available = true;
|
||||
|
||||
int val = (available ? GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE :
|
||||
GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE);
|
||||
setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, val);
|
||||
|
||||
private void reportGeofenceOperationStatus(int operation, int geofenceId, int operationStatus) {
|
||||
acquireWakeLock();
|
||||
Message m = mCallbacksHandler.obtainMessage(GPS_GEOFENCE_STATUS, location);
|
||||
m.arg1 = val;
|
||||
mCallbacksHandler.sendMessage(m);
|
||||
Message message = mGeofenceHandler.obtainMessage(operation);
|
||||
message.arg1 = geofenceId;
|
||||
message.arg2 = operationStatus;
|
||||
message.sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider add geofence callback.
|
||||
* Used to report the status of a Geofence Add operation.
|
||||
*/
|
||||
public void reportGpsGeofenceAddStatus(int geofenceId, int status) {
|
||||
if (DEBUG) Log.d(TAG, "Add Callback: GPS : Id: " + geofenceId + " Status: " + status);
|
||||
acquireWakeLock();
|
||||
Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE_CALLBACK);
|
||||
m.arg1 = geofenceId;
|
||||
m.arg2 = getGeofenceStatus(status);
|
||||
mGeofenceHandler.sendMessage(m);
|
||||
public void reportGeofenceAddStatus(int geofenceId, int status) {
|
||||
if(DEBUG) Log.d(TAG, "AddCallback| id:" + geofenceId + ", status:" + status);
|
||||
reportGeofenceOperationStatus(ADD_GEOFENCE_CALLBACK, geofenceId, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider remove geofence callback.
|
||||
* Used to report the status of a Geofence Remove operation.
|
||||
*/
|
||||
public void reportGpsGeofenceRemoveStatus(int geofenceId, int status) {
|
||||
if (DEBUG) Log.d(TAG, "Remove Callback: GPS : Id: " + geofenceId + " Status: " + status);
|
||||
acquireWakeLock();
|
||||
Message m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE_CALLBACK);
|
||||
m.arg1 = geofenceId;
|
||||
m.arg2 = getGeofenceStatus(status);
|
||||
mGeofenceHandler.sendMessage(m);
|
||||
public void reportGeofenceRemoveStatus(int geofenceId, int status) {
|
||||
if(DEBUG) Log.d(TAG, "RemoveCallback| id:" + geofenceId + ", status:" + status);
|
||||
reportGeofenceOperationStatus(REMOVE_GEOFENCE_CALLBACK, geofenceId, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider pause geofence callback.
|
||||
* Used to report the status of a Geofence Pause operation.
|
||||
*/
|
||||
public void reportGpsGeofencePauseStatus(int geofenceId, int status) {
|
||||
if (DEBUG) Log.d(TAG, "Pause Callback: GPS : Id: " + geofenceId + " Status: " + status);
|
||||
acquireWakeLock();
|
||||
Message m = mGeofenceHandler.obtainMessage(PAUSE_GEOFENCE_CALLBACK);
|
||||
m.arg1 = geofenceId;
|
||||
m.arg2 = getGeofenceStatus(status);
|
||||
mGeofenceHandler.sendMessage(m);
|
||||
public void reportGeofencePauseStatus(int geofenceId, int status) {
|
||||
if(DEBUG) Log.d(TAG, "PauseCallbac| id:" + geofenceId + ", status" + status);
|
||||
reportGeofenceOperationStatus(PAUSE_GEOFENCE_CALLBACK, geofenceId, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* called from GpsLocationProvider resume geofence callback.
|
||||
* Used to report the status of a Geofence Resume operation.
|
||||
*/
|
||||
public void reportGpsGeofenceResumeStatus(int geofenceId, int status) {
|
||||
if (DEBUG) Log.d(TAG, "Resume Callback: GPS : Id: " + geofenceId + " Status: " + status);
|
||||
acquireWakeLock();
|
||||
Message m = mGeofenceHandler.obtainMessage(RESUME_GEOFENCE_CALLBACK);
|
||||
m.arg1 = geofenceId;
|
||||
m.arg2 = getGeofenceStatus(status);
|
||||
mGeofenceHandler.sendMessage(m);
|
||||
public void reportGeofenceResumeStatus(int geofenceId, int status) {
|
||||
if(DEBUG) Log.d(TAG, "ResumeCallback| id:" + geofenceId + ", status:" + status);
|
||||
reportGeofenceOperationStatus(RESUME_GEOFENCE_CALLBACK, geofenceId, status);
|
||||
}
|
||||
|
||||
// All operations on mGeofences
|
||||
@@ -539,7 +613,7 @@ public final class GeofenceHardwareImpl {
|
||||
callback.onGeofenceTransition(
|
||||
geofenceTransition.mGeofenceId, geofenceTransition.mTransition,
|
||||
geofenceTransition.mLocation, geofenceTransition.mTimestamp,
|
||||
GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE);
|
||||
geofenceTransition.mMonitoringType);
|
||||
} catch (RemoteException e) {}
|
||||
}
|
||||
releaseWakeLock();
|
||||
@@ -571,21 +645,20 @@ public final class GeofenceHardwareImpl {
|
||||
IGeofenceHardwareMonitorCallback callback;
|
||||
|
||||
switch (msg.what) {
|
||||
case GPS_GEOFENCE_STATUS:
|
||||
case GEOFENCE_STATUS:
|
||||
Location location = (Location) msg.obj;
|
||||
int val = msg.arg1;
|
||||
monitoringType = msg.arg2;
|
||||
boolean available;
|
||||
available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ?
|
||||
true : false);
|
||||
callbackList = mCallbacks[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE];
|
||||
callbackList = mCallbacks[monitoringType];
|
||||
if (callbackList != null) {
|
||||
if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available);
|
||||
|
||||
for (IGeofenceHardwareMonitorCallback c: callbackList) {
|
||||
try {
|
||||
c.onMonitoringSystemChange(
|
||||
GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available,
|
||||
location);
|
||||
c.onMonitoringSystemChange(monitoringType, available, location);
|
||||
} catch (RemoteException e) {}
|
||||
}
|
||||
}
|
||||
@@ -666,12 +739,22 @@ public final class GeofenceHardwareImpl {
|
||||
private int mGeofenceId, mTransition;
|
||||
private long mTimestamp;
|
||||
private Location mLocation;
|
||||
private int mMonitoringType;
|
||||
private int mSourcesUsed;
|
||||
|
||||
GeofenceTransition(int geofenceId, int transition, long timestamp, Location location) {
|
||||
GeofenceTransition(
|
||||
int geofenceId,
|
||||
int transition,
|
||||
long timestamp,
|
||||
Location location,
|
||||
int monitoringType,
|
||||
int sourcesUsed) {
|
||||
mGeofenceId = geofenceId;
|
||||
mTransition = transition;
|
||||
mTimestamp = timestamp;
|
||||
mLocation = location;
|
||||
mMonitoringType = monitoringType;
|
||||
mSourcesUsed = sourcesUsed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,6 +769,8 @@ public final class GeofenceHardwareImpl {
|
||||
switch (monitoringType) {
|
||||
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
||||
return RESOLUTION_LEVEL_FINE;
|
||||
case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE:
|
||||
return RESOLUTION_LEVEL_FINE;
|
||||
}
|
||||
return RESOLUTION_LEVEL_NONE;
|
||||
}
|
||||
@@ -752,22 +837,4 @@ public final class GeofenceHardwareImpl {
|
||||
return RESOLUTION_LEVEL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2013, 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.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
parcelable GeofenceHardwareRequestParcelable;
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Geofence Hardware Request used for internal location services communication.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class GeofenceHardwareRequestParcelable implements Parcelable {
|
||||
private GeofenceHardwareRequest mRequest;
|
||||
private int mId;
|
||||
|
||||
public GeofenceHardwareRequestParcelable(int id, GeofenceHardwareRequest request) {
|
||||
mId = id;
|
||||
mRequest = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of this request.
|
||||
*/
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latitude of this geofence.
|
||||
*/
|
||||
public double getLatitude() {
|
||||
return mRequest.getLatitude();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the longitude of this geofence.
|
||||
*/
|
||||
public double getLongitude() {
|
||||
return mRequest.getLongitude();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the radius of this geofence.
|
||||
*/
|
||||
public double getRadius() {
|
||||
return mRequest.getRadius();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns transitions monitored for this geofence.
|
||||
*/
|
||||
public int getMonitorTransitions() {
|
||||
return mRequest.getMonitorTransitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unknownTimer of this geofence.
|
||||
*/
|
||||
public int getUnknownTimer() {
|
||||
return mRequest.getUnknownTimer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notification responsiveness of this geofence.
|
||||
*/
|
||||
public int getNotificationResponsiveness() {
|
||||
return mRequest.getNotificationResponsiveness();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last transition of this geofence.
|
||||
*/
|
||||
public int getLastTransition() {
|
||||
return mRequest.getLastTransition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the geofence for the current request.
|
||||
*/
|
||||
int getType() {
|
||||
return mRequest.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method definitions to support Parcelable operations.
|
||||
*/
|
||||
public static final Parcelable.Creator<GeofenceHardwareRequestParcelable> CREATOR =
|
||||
new Parcelable.Creator<GeofenceHardwareRequestParcelable>() {
|
||||
@Override
|
||||
public GeofenceHardwareRequestParcelable createFromParcel(Parcel parcel) {
|
||||
int geofenceType = parcel.readInt();
|
||||
if(geofenceType != GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
|
||||
Log.e(
|
||||
"GeofenceHardwareRequest",
|
||||
String.format("Invalid Geofence type: %d", geofenceType));
|
||||
return null;
|
||||
}
|
||||
|
||||
GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence(
|
||||
parcel.readDouble(),
|
||||
parcel.readDouble(),
|
||||
parcel.readDouble());
|
||||
request.setLastTransition(parcel.readInt());
|
||||
request.setMonitorTransitions(parcel.readInt());
|
||||
request.setUnknownTimer(parcel.readInt());
|
||||
request.setNotificationResponsiveness(parcel.readInt());
|
||||
|
||||
int id = parcel.readInt();
|
||||
return new GeofenceHardwareRequestParcelable(id, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeofenceHardwareRequestParcelable[] newArray(int size) {
|
||||
return new GeofenceHardwareRequestParcelable[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeInt(getType());
|
||||
parcel.writeDouble(getLatitude());
|
||||
parcel.writeDouble(getLongitude());
|
||||
parcel.writeDouble(getRadius());
|
||||
parcel.writeInt(getLastTransition());
|
||||
parcel.writeInt(getMonitorTransitions());
|
||||
parcel.writeInt(getUnknownTimer());
|
||||
parcel.writeInt(getNotificationResponsiveness());
|
||||
parcel.writeInt(getId());
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import android.Manifest;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.IFusedGeofenceHardware;
|
||||
import android.location.IGpsGeofenceHardware;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
@@ -68,6 +69,10 @@ public class GeofenceHardwareService extends Service {
|
||||
mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
|
||||
}
|
||||
|
||||
public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
|
||||
mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
|
||||
}
|
||||
|
||||
public int[] getMonitoringTypes() {
|
||||
mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
|
||||
"Location Hardware permission not granted to access hardware geofence");
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.location.IFusedGeofenceHardware;
|
||||
import android.location.IGpsGeofenceHardware;
|
||||
import android.hardware.location.IGeofenceHardwareCallback;
|
||||
import android.hardware.location.IGeofenceHardwareMonitorCallback;
|
||||
@@ -23,6 +24,7 @@ import android.hardware.location.IGeofenceHardwareMonitorCallback;
|
||||
/** @hide */
|
||||
interface IGeofenceHardware {
|
||||
void setGpsGeofenceHardware(in IGpsGeofenceHardware service);
|
||||
void setFusedGeofenceHardware(in IFusedGeofenceHardware service);
|
||||
int[] getMonitoringTypes();
|
||||
int getStatusOfMonitoringType(int monitoringType);
|
||||
boolean addCircularFence(int id, int monitoringType, double lat, double longitude,
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package android.location;
|
||||
|
||||
import android.location.Geofence;
|
||||
|
||||
import android.hardware.location.GeofenceHardwareRequestParcelable;
|
||||
|
||||
/**
|
||||
* Fused Geofence Hardware interface.
|
||||
*
|
||||
@@ -39,11 +39,9 @@ interface IFusedGeofenceHardware {
|
||||
/**
|
||||
* Adds a given list of geofences to the system.
|
||||
*
|
||||
* @param geofenceIdsArray The list of geofence Ids to add.
|
||||
* @param geofencesArray the list of geofences to add.
|
||||
* @param geofenceRequestsArray The list of geofences to add.
|
||||
*/
|
||||
// TODO: [GeofenceIntegration] GeofenceHardwareRequest is not a parcelable class exposed in aidl
|
||||
void addGeofences(in int[] geofenceIdsArray, in Geofence[] geofencesArray);
|
||||
void addGeofences(in GeofenceHardwareRequestParcelable[] geofenceRequestsArray);
|
||||
|
||||
/**
|
||||
* Removes a give list of geofences from the system.
|
||||
@@ -79,7 +77,8 @@ interface IFusedGeofenceHardware {
|
||||
* the geofence.
|
||||
* @param monitorTransitions The set of transitions to monitor.
|
||||
* @param notificationResponsiveness The notification responsivness needed.
|
||||
* @param unknownTimer The time span associated with the
|
||||
* @param unknownTimer The time span associated with the.
|
||||
* @param sourcesToUse The source technologies to use.
|
||||
*
|
||||
* Remarks: keep the options as separate fields to be able to leverage the class
|
||||
* GeofenceHardwareRequest without any changes
|
||||
@@ -89,5 +88,6 @@ interface IFusedGeofenceHardware {
|
||||
in int lastTransition,
|
||||
in int monitorTransitions,
|
||||
in int notificationResponsiveness,
|
||||
in int unknownTimer);
|
||||
in int unknownTimer,
|
||||
in int sourcesToUse);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1404,6 +1416,62 @@ public class GpsLocationProvider implements LocationProviderInterface {
|
||||
sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
//=============================================================
|
||||
|
||||
@@ -260,6 +260,75 @@ static void TranslateFromObject(
|
||||
batchOptions.flags = env->CallIntMethod(batchOptionsObject, getFlags);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@@ -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)}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user