Merge "Fixed race conditions in GeofenceHardwareImpl." into jb-mr2-dev
This commit is contained in:
@@ -48,11 +48,11 @@ public final class GeofenceHardwareImpl {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private static GeofenceHardwareImpl sInstance;
|
private static GeofenceHardwareImpl sInstance;
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
private SparseArray<IGeofenceHardwareCallback> mGeofences =
|
private final SparseArray<IGeofenceHardwareCallback> mGeofences =
|
||||||
new SparseArray<IGeofenceHardwareCallback>();
|
new SparseArray<IGeofenceHardwareCallback>();
|
||||||
private ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks =
|
private final ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks =
|
||||||
new ArrayList[GeofenceHardware.NUM_MONITORS];
|
new ArrayList[GeofenceHardware.NUM_MONITORS];
|
||||||
private ArrayList<Reaper> mReapers = new ArrayList<Reaper>();
|
private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>();
|
||||||
|
|
||||||
private IGpsGeofenceHardware mGpsService;
|
private IGpsGeofenceHardware mGpsService;
|
||||||
|
|
||||||
@@ -64,9 +64,7 @@ public final class GeofenceHardwareImpl {
|
|||||||
private static final int REMOVE_GEOFENCE_CALLBACK = 3;
|
private static final int REMOVE_GEOFENCE_CALLBACK = 3;
|
||||||
private static final int PAUSE_GEOFENCE_CALLBACK = 4;
|
private static final int PAUSE_GEOFENCE_CALLBACK = 4;
|
||||||
private static final int RESUME_GEOFENCE_CALLBACK = 5;
|
private static final int RESUME_GEOFENCE_CALLBACK = 5;
|
||||||
private static final int ADD_GEOFENCE = 6;
|
private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6;
|
||||||
private static final int REMOVE_GEOFENCE = 7;
|
|
||||||
private static final int GEOFENCE_CALLBACK_BINDER_DIED = 8;
|
|
||||||
|
|
||||||
// mCallbacksHandler message types
|
// mCallbacksHandler message types
|
||||||
private static final int GPS_GEOFENCE_STATUS = 1;
|
private static final int GPS_GEOFENCE_STATUS = 1;
|
||||||
@@ -194,9 +192,14 @@ public final class GeofenceHardwareImpl {
|
|||||||
|
|
||||||
}
|
}
|
||||||
boolean result;
|
boolean result;
|
||||||
Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE, callback);
|
|
||||||
m.arg1 = geofenceId;
|
// The callback must be added before addCircularHardwareGeofence is called otherwise the
|
||||||
mGeofenceHandler.sendMessage(m);
|
// callback might not be called after the geofence is added in the geofence hardware.
|
||||||
|
// This also means that the callback must be removed if the addCircularHardwareGeofence
|
||||||
|
// operations is not called or fails.
|
||||||
|
synchronized (mGeofences) {
|
||||||
|
mGeofences.put(geofenceId, callback);
|
||||||
|
}
|
||||||
|
|
||||||
switch (monitoringType) {
|
switch (monitoringType) {
|
||||||
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
||||||
@@ -214,13 +217,13 @@ public final class GeofenceHardwareImpl {
|
|||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback);
|
Message m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback);
|
||||||
m.arg1 = monitoringType;
|
m.arg1 = monitoringType;
|
||||||
mReaperHandler.sendMessage(m);
|
mReaperHandler.sendMessage(m);
|
||||||
} else {
|
} else {
|
||||||
m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE);
|
synchronized (mGeofences) {
|
||||||
m.arg1 = geofenceId;
|
mGeofences.remove(geofenceId);
|
||||||
mGeofenceHandler.sendMessage(m);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result);
|
if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result);
|
||||||
@@ -232,6 +235,12 @@ public final class GeofenceHardwareImpl {
|
|||||||
// by upper layers
|
// by upper layers
|
||||||
if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId);
|
if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId);
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
|
|
||||||
|
synchronized (mGeofences) {
|
||||||
|
if (mGeofences.get(geofenceId) == null) {
|
||||||
|
throw new IllegalArgumentException("Geofence " + geofenceId + " not registered.");
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (monitoringType) {
|
switch (monitoringType) {
|
||||||
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
||||||
if (mGpsService == null) return false;
|
if (mGpsService == null) return false;
|
||||||
@@ -254,6 +263,11 @@ public final class GeofenceHardwareImpl {
|
|||||||
// by upper layers
|
// by upper layers
|
||||||
if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId);
|
if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId);
|
||||||
boolean result;
|
boolean result;
|
||||||
|
synchronized (mGeofences) {
|
||||||
|
if (mGeofences.get(geofenceId) == null) {
|
||||||
|
throw new IllegalArgumentException("Geofence " + geofenceId + " not registered.");
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (monitoringType) {
|
switch (monitoringType) {
|
||||||
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
||||||
if (mGpsService == null) return false;
|
if (mGpsService == null) return false;
|
||||||
@@ -277,6 +291,11 @@ public final class GeofenceHardwareImpl {
|
|||||||
// by upper layers
|
// by upper layers
|
||||||
if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId);
|
if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId);
|
||||||
boolean result;
|
boolean result;
|
||||||
|
synchronized (mGeofences) {
|
||||||
|
if (mGeofences.get(geofenceId) == null) {
|
||||||
|
throw new IllegalArgumentException("Geofence " + geofenceId + " not registered.");
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (monitoringType) {
|
switch (monitoringType) {
|
||||||
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
|
||||||
if (mGpsService == null) return false;
|
if (mGpsService == null) return false;
|
||||||
@@ -446,18 +465,11 @@ public final class GeofenceHardwareImpl {
|
|||||||
int status;
|
int status;
|
||||||
IGeofenceHardwareCallback callback;
|
IGeofenceHardwareCallback callback;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case ADD_GEOFENCE:
|
|
||||||
geofenceId = msg.arg1;
|
|
||||||
callback = (IGeofenceHardwareCallback) msg.obj;
|
|
||||||
mGeofences.put(geofenceId, callback);
|
|
||||||
break;
|
|
||||||
case REMOVE_GEOFENCE:
|
|
||||||
geofenceId = msg.arg1;
|
|
||||||
mGeofences.remove(geofenceId);
|
|
||||||
break;
|
|
||||||
case ADD_GEOFENCE_CALLBACK:
|
case ADD_GEOFENCE_CALLBACK:
|
||||||
geofenceId = msg.arg1;
|
geofenceId = msg.arg1;
|
||||||
|
synchronized (mGeofences) {
|
||||||
callback = mGeofences.get(geofenceId);
|
callback = mGeofences.get(geofenceId);
|
||||||
|
}
|
||||||
if (callback == null) return;
|
if (callback == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -467,19 +479,25 @@ public final class GeofenceHardwareImpl {
|
|||||||
break;
|
break;
|
||||||
case REMOVE_GEOFENCE_CALLBACK:
|
case REMOVE_GEOFENCE_CALLBACK:
|
||||||
geofenceId = msg.arg1;
|
geofenceId = msg.arg1;
|
||||||
|
synchronized (mGeofences) {
|
||||||
callback = mGeofences.get(geofenceId);
|
callback = mGeofences.get(geofenceId);
|
||||||
|
}
|
||||||
if (callback == null) return;
|
if (callback == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
callback.onGeofenceRemove(geofenceId, msg.arg2);
|
callback.onGeofenceRemove(geofenceId, msg.arg2);
|
||||||
} catch (RemoteException e) {}
|
} catch (RemoteException e) {}
|
||||||
|
synchronized (mGeofences) {
|
||||||
mGeofences.remove(geofenceId);
|
mGeofences.remove(geofenceId);
|
||||||
|
}
|
||||||
releaseWakeLock();
|
releaseWakeLock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAUSE_GEOFENCE_CALLBACK:
|
case PAUSE_GEOFENCE_CALLBACK:
|
||||||
geofenceId = msg.arg1;
|
geofenceId = msg.arg1;
|
||||||
|
synchronized (mGeofences) {
|
||||||
callback = mGeofences.get(geofenceId);
|
callback = mGeofences.get(geofenceId);
|
||||||
|
}
|
||||||
if (callback == null) return;
|
if (callback == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -490,7 +508,9 @@ public final class GeofenceHardwareImpl {
|
|||||||
|
|
||||||
case RESUME_GEOFENCE_CALLBACK:
|
case RESUME_GEOFENCE_CALLBACK:
|
||||||
geofenceId = msg.arg1;
|
geofenceId = msg.arg1;
|
||||||
|
synchronized (mGeofences) {
|
||||||
callback = mGeofences.get(geofenceId);
|
callback = mGeofences.get(geofenceId);
|
||||||
|
}
|
||||||
if (callback == null) return;
|
if (callback == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -501,7 +521,9 @@ public final class GeofenceHardwareImpl {
|
|||||||
|
|
||||||
case GEOFENCE_TRANSITION_CALLBACK:
|
case GEOFENCE_TRANSITION_CALLBACK:
|
||||||
GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj);
|
GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj);
|
||||||
|
synchronized (mGeofences) {
|
||||||
callback = mGeofences.get(geofenceTransition.mGeofenceId);
|
callback = mGeofences.get(geofenceTransition.mGeofenceId);
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " +
|
if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " +
|
||||||
geofenceTransition.mGeofenceId +
|
geofenceTransition.mGeofenceId +
|
||||||
@@ -521,6 +543,7 @@ public final class GeofenceHardwareImpl {
|
|||||||
callback = (IGeofenceHardwareCallback) (msg.obj);
|
callback = (IGeofenceHardwareCallback) (msg.obj);
|
||||||
if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback);
|
if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback);
|
||||||
int monitoringType = msg.arg1;
|
int monitoringType = msg.arg1;
|
||||||
|
synchronized (mGeofences) {
|
||||||
for (int i = 0; i < mGeofences.size(); i++) {
|
for (int i = 0; i < mGeofences.size(); i++) {
|
||||||
if (mGeofences.valueAt(i).equals(callback)) {
|
if (mGeofences.valueAt(i).equals(callback)) {
|
||||||
geofenceId = mGeofences.keyAt(i);
|
geofenceId = mGeofences.keyAt(i);
|
||||||
@@ -530,6 +553,7 @@ public final class GeofenceHardwareImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// All operations on mCallbacks
|
// All operations on mCallbacks
|
||||||
|
|||||||
Reference in New Issue
Block a user