use of android.location.Location in project android_frameworks_base by DirtyUnicorns.
the class GeofenceManager method updateFences.
/**
* The geofence update loop. This function removes expired fences, then tests the most
* recently-received {@link Location} against each registered {@link GeofenceState}, sending
* {@link Intent}s for geofences that have been tripped. It also adjusts the active location
* update request with {@link LocationManager} as appropriate for any active geofences.
*/
// Runs on the handler.
private void updateFences() {
List<PendingIntent> enterIntents = new LinkedList<PendingIntent>();
List<PendingIntent> exitIntents = new LinkedList<PendingIntent>();
synchronized (mLock) {
mPendingUpdate = false;
// Remove expired fences.
removeExpiredFencesLocked();
// Get a location to work with, either received via onLocationChanged() or
// via LocationManager.getLastLocation().
Location location = getFreshLocationLocked();
// Update all fences.
// Keep track of the distance to the nearest fence.
double minFenceDistance = Double.MAX_VALUE;
boolean needUpdates = false;
for (GeofenceState state : mFences) {
if (mBlacklist.isBlacklisted(state.mPackageName)) {
if (D) {
Slog.d(TAG, "skipping geofence processing for blacklisted app: " + state.mPackageName);
}
continue;
}
int op = LocationManagerService.resolutionLevelToOp(state.mAllowedResolutionLevel);
if (op >= 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, state.mUid, state.mPackageName) != AppOpsManager.MODE_ALLOWED) {
if (D) {
Slog.d(TAG, "skipping geofence processing for no op app: " + state.mPackageName);
}
continue;
}
}
needUpdates = true;
if (location != null) {
int event = state.processLocation(location);
if ((event & GeofenceState.FLAG_ENTER) != 0) {
enterIntents.add(state.mIntent);
}
if ((event & GeofenceState.FLAG_EXIT) != 0) {
exitIntents.add(state.mIntent);
}
// FIXME: Ideally this code should take into account the accuracy of the
// location fix that was used to calculate the distance in the first place.
// MAX_VALUE if unknown
double fenceDistance = state.getDistanceToBoundary();
if (fenceDistance < minFenceDistance) {
minFenceDistance = fenceDistance;
}
}
}
// Request or cancel location updates if needed.
if (needUpdates) {
// Request location updates.
// Compute a location update interval based on the distance to the nearest fence.
long intervalMs;
if (location != null && Double.compare(minFenceDistance, Double.MAX_VALUE) != 0) {
intervalMs = (long) Math.min(MAX_INTERVAL_MS, Math.max(MIN_INTERVAL_MS, minFenceDistance * 1000 / MAX_SPEED_M_S));
} else {
intervalMs = MIN_INTERVAL_MS;
}
if (!mReceivingLocationUpdates || mLocationUpdateInterval != intervalMs) {
mReceivingLocationUpdates = true;
mLocationUpdateInterval = intervalMs;
mLastLocationUpdate = location;
LocationRequest request = new LocationRequest();
request.setInterval(intervalMs).setFastestInterval(0);
mLocationManager.requestLocationUpdates(request, this, mHandler.getLooper());
}
} else {
// Cancel location updates.
if (mReceivingLocationUpdates) {
mReceivingLocationUpdates = false;
mLocationUpdateInterval = 0;
mLastLocationUpdate = null;
mLocationManager.removeUpdates(this);
}
}
if (D) {
Slog.d(TAG, "updateFences: location=" + location + ", mFences.size()=" + mFences.size() + ", mReceivingLocationUpdates=" + mReceivingLocationUpdates + ", mLocationUpdateInterval=" + mLocationUpdateInterval + ", mLastLocationUpdate=" + mLastLocationUpdate);
}
}
// release lock before sending intents
for (PendingIntent intent : exitIntents) {
sendIntentExit(intent);
}
for (PendingIntent intent : enterIntents) {
sendIntentEnter(intent);
}
}
use of android.location.Location in project android_frameworks_base by DirtyUnicorns.
the class GnssLocationProvider method reportGeofenceTransition.
/**
* Called from native to report GPS Geofence transition
* All geofence callbacks are called on the same thread
*/
private void reportGeofenceTransition(int geofenceId, int flags, double latitude, double longitude, double altitude, float speed, float bearing, float accuracy, long timestamp, int transition, long transitionTimestamp) {
if (mGeofenceHardwareImpl == null) {
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
}
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);
}
use of android.location.Location in project android_frameworks_base by DirtyUnicorns.
the class FlpHardwareProvider method onGeofenceMonitorStatus.
private void onGeofenceMonitorStatus(int status, int source, Location location) {
// allow the location to be optional in this event
Location updatedLocation = null;
if (location != null) {
updatedLocation = updateLocationInformation(location);
}
int monitorStatus;
switch(status) {
case FLP_GEOFENCE_MONITOR_STATUS_UNAVAILABLE:
monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
break;
case FLP_GEOFENCE_MONITOR_STATUS_AVAILABLE:
monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
break;
default:
Log.e(TAG, "Invalid FlpHal Geofence monitor status: " + status);
monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
break;
}
getGeofenceHardwareSink().reportGeofenceMonitorStatus(GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, monitorStatus, updatedLocation, source);
}
use of android.location.Location in project android_frameworks_base by DirtyUnicorns.
the class FlpHardwareProvider method onLocationReport.
/**
* Private callback functions used by FLP HAL.
*/
// FlpCallbacks members
private void onLocationReport(Location[] locations) {
for (Location location : locations) {
location.setProvider(LocationManager.FUSED_PROVIDER);
// set the elapsed time-stamp just as GPS provider does
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
IFusedLocationHardwareSink sink;
synchronized (mLocationSinkLock) {
sink = mLocationSink;
}
try {
if (sink != null) {
sink.onLocationAvailable(locations);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling onLocationAvailable");
}
}
use of android.location.Location in project android_frameworks_base by DirtyUnicorns.
the class GeofenceManager method getFreshLocationLocked.
/**
* Returns the location received most recently from {@link #onLocationChanged(Location)},
* or consult {@link LocationManager#getLastLocation()} if none has arrived. Does not return
* either if the location would be too stale to be useful.
*
* @return a fresh, valid Location, or null if none is available
*/
private Location getFreshLocationLocked() {
// Prefer mLastLocationUpdate to LocationManager.getLastLocation().
Location location = mReceivingLocationUpdates ? mLastLocationUpdate : null;
if (location == null && !mFences.isEmpty()) {
location = mLocationManager.getLastLocation();
}
// Early out for null location.
if (location == null) {
return null;
}
// Early out for stale location.
long now = SystemClock.elapsedRealtimeNanos();
if (now - location.getElapsedRealtimeNanos() > MAX_AGE_NANOS) {
return null;
}
// Made it this far? Return our fresh, valid location.
return location;
}
Aggregations