blob: a84b0b1c4335d54577f5f66171dc0612f7af1bd5 [file] [log] [blame]
package com.android.server.location;
import android.location.IGpsGeofenceHardware;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
/**
* Manages GNSS Geofence operations.
*/
class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
private static final String TAG = "GnssGeofenceProvider";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
/** Holds the parameters of a geofence. */
private static class GeofenceEntry {
public int geofenceId;
public double latitude;
public double longitude;
public double radius;
public int lastTransition;
public int monitorTransitions;
public int notificationResponsiveness;
public int unknownTimer;
public boolean paused;
}
private final Object mLock = new Object();
@GuardedBy("mLock")
private final GnssGeofenceProviderNative mNative;
@GuardedBy("mLock")
private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();
GnssGeofenceProvider() {
this(new GnssGeofenceProviderNative());
}
@VisibleForTesting
GnssGeofenceProvider(GnssGeofenceProviderNative gnssGeofenceProviderNative) {
mNative = gnssGeofenceProviderNative;
}
void resumeIfStarted() {
if (DEBUG) {
Log.d(TAG, "resumeIfStarted");
}
synchronized (mLock) {
for (int i = 0; i < mGeofenceEntries.size(); i++) {
GeofenceEntry entry = mGeofenceEntries.valueAt(i);
boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
entry.longitude,
entry.radius,
entry.lastTransition, entry.monitorTransitions,
entry.notificationResponsiveness, entry.unknownTimer);
if (added && entry.paused) {
mNative.pauseGeofence(entry.geofenceId);
}
}
}
}
@Override
public boolean isHardwareGeofenceSupported() {
synchronized (mLock) {
return mNative.isGeofenceSupported();
}
}
@Override
public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
double longitude, double radius, int lastTransition, int monitorTransitions,
int notificationResponsiveness, int unknownTimer) {
synchronized (mLock) {
boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
lastTransition, monitorTransitions, notificationResponsiveness,
unknownTimer);
if (added) {
GeofenceEntry entry = new GeofenceEntry();
entry.geofenceId = geofenceId;
entry.latitude = latitude;
entry.longitude = longitude;
entry.radius = radius;
entry.lastTransition = lastTransition;
entry.monitorTransitions = monitorTransitions;
entry.notificationResponsiveness = notificationResponsiveness;
entry.unknownTimer = unknownTimer;
mGeofenceEntries.put(geofenceId, entry);
}
return added;
}
}
@Override
public boolean removeHardwareGeofence(int geofenceId) {
synchronized (mLock) {
boolean removed = mNative.removeGeofence(geofenceId);
if (removed) {
mGeofenceEntries.remove(geofenceId);
}
return removed;
}
}
@Override
public boolean pauseHardwareGeofence(int geofenceId) {
synchronized (mLock) {
boolean paused = mNative.pauseGeofence(geofenceId);
if (paused) {
GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
if (entry != null) {
entry.paused = true;
}
}
return paused;
}
}
@Override
public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
synchronized (mLock) {
boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
if (resumed) {
GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
if (entry != null) {
entry.paused = false;
entry.monitorTransitions = monitorTransitions;
}
}
return resumed;
}
}
@VisibleForTesting
static class GnssGeofenceProviderNative {
public boolean isGeofenceSupported() {
return native_is_geofence_supported();
}
public boolean addGeofence(int geofenceId, double latitude, double longitude, double radius,
int lastTransition, int monitorTransitions, int notificationResponsiveness,
int unknownTimer) {
return native_add_geofence(geofenceId, latitude, longitude, radius, lastTransition,
monitorTransitions, notificationResponsiveness, unknownTimer);
}
public boolean removeGeofence(int geofenceId) {
return native_remove_geofence(geofenceId);
}
public boolean resumeGeofence(int geofenceId, int transitions) {
return native_resume_geofence(geofenceId, transitions);
}
public boolean pauseGeofence(int geofenceId) {
return native_pause_geofence(geofenceId);
}
}
private static native boolean native_is_geofence_supported();
private static native boolean native_add_geofence(int geofenceId, double latitude,
double longitude, double radius, int lastTransition, int monitorTransitions,
int notificationResponsivenes, int unknownTimer);
private static native boolean native_remove_geofence(int geofenceId);
private static native boolean native_resume_geofence(int geofenceId, int transitions);
private static native boolean native_pause_geofence(int geofenceId);
}