aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsudev <rasch@munin-soft.de>2011-08-25 23:04:29 +0200
committerrsudev <rasch@munin-soft.de>2011-08-25 23:04:29 +0200
commit6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24 (patch)
tree85e341486e79223904c38c9a71a3572143a68635
parent5db059cb2b0b3872490a1eefdac93fad4bb55a18 (diff)
downloadcgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.zip
cgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.tar.gz
cgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.tar.bz2
Fix for #209 (ArrayIndexOutOfBounds in google map
Implemented lock as suggested by BKFC
-rw-r--r--src/cgeo/geocaching/googlemaps/googleCacheOverlay.java15
-rw-r--r--src/cgeo/geocaching/googlemaps/googleOverlay.java14
-rw-r--r--src/cgeo/geocaching/googlemaps/googleUsersOverlay.java16
-rw-r--r--src/cgeo/geocaching/mapcommon/cgMapOverlay.java122
-rw-r--r--src/cgeo/geocaching/mapinterfaces/OverlayImpl.java4
-rw-r--r--src/cgeo/geocaching/mapsforge/mfCacheOverlay.java14
-rw-r--r--src/cgeo/geocaching/mapsforge/mfOverlay.java14
-rw-r--r--src/cgeo/geocaching/mapsforge/mfUsersOverlay.java14
8 files changed, 163 insertions, 50 deletions
diff --git a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
index 68929cf..02e8c04 100644
--- a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java
@@ -1,10 +1,12 @@
package cgeo.geocaching.googlemaps;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
-
import cgeo.geocaching.cgSettings;
import cgeo.geocaching.mapcommon.cgMapOverlay;
import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl;
@@ -22,6 +24,7 @@ import com.google.android.maps.MapView;
public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem> implements ItemizedOverlayImpl {
private cgMapOverlay base;
+ private Lock lock = new ReentrantLock();
public googleCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) {
super(boundCenterBottom(markerIn));
@@ -98,4 +101,14 @@ public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem>
// Nothing to do here...
}
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
}
diff --git a/src/cgeo/geocaching/googlemaps/googleOverlay.java b/src/cgeo/geocaching/googlemaps/googleOverlay.java
index 97909be..8473faa 100644
--- a/src/cgeo/geocaching/googlemaps/googleOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.googlemaps;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import android.app.Activity;
import android.graphics.Canvas;
import cgeo.geocaching.cgSettings;
@@ -15,6 +18,7 @@ import com.google.android.maps.Overlay;
public class googleOverlay extends Overlay implements OverlayImpl {
private OverlayBase overlayBase = null;
+ private Lock lock = new ReentrantLock();
public googleOverlay(Activity activityIn, cgSettings settingsIn, overlayType ovlType) {
switch (ovlType) {
@@ -38,4 +42,14 @@ public class googleOverlay extends Overlay implements OverlayImpl {
public OverlayBase getBase() {
return overlayBase;
}
+
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
}
diff --git a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java
index 5019e6e..f5f16a7 100644
--- a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java
+++ b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.googlemaps;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
@@ -15,6 +18,7 @@ import com.google.android.maps.MapView;
public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem> implements ItemizedOverlayImpl {
private cgUsersOverlay base;
+ private Lock lock = new ReentrantLock();
public googleUsersOverlay(Context contextIn, Drawable markerIn) {
super(boundCenter(markerIn));
@@ -91,4 +95,14 @@ public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem>
// Nothing to do here
}
-} \ No newline at end of file
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
+}
diff --git a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
index 293f0c7..d3f7c00 100644
--- a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
+++ b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
@@ -74,10 +74,16 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
item.setMarker(boundCenterBottom(item.getMarker(0)));
}
- items = new ArrayList<CacheOverlayItemImpl>(itemsPre);
-
- setLastFocusedItemIndex(-1); // to reset tap during data change
- populate();
+ // ensure no interference between the draw and content changing routines
+ getOverlayImpl().lock();
+ try {
+ items = new ArrayList<CacheOverlayItemImpl>(itemsPre);
+
+ setLastFocusedItemIndex(-1); // to reset tap during data change
+ populate();
+ } finally {
+ getOverlayImpl().unlock();
+ }
}
public boolean getCircles() {
@@ -107,51 +113,56 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
private void drawInternal(Canvas canvas, MapProjectionImpl projection) {
- if (displayCircles) {
- if (blockedCircle == null) {
- blockedCircle = new Paint();
- blockedCircle.setAntiAlias(true);
- blockedCircle.setStrokeWidth(1.0f);
- blockedCircle.setARGB(127, 0, 0, 0);
- blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0));
- }
-
- if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
- if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
-
- canvas.setDrawFilter(setfil);
-
- for (CacheOverlayItemImpl item : items) {
- final cgCoord itemCoord = item.getCoord();
- float[] result = new float[1];
-
- Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
- final float longitudeLineDistance = result[0];
-
- GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
- GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
-
- projection.toPixels(itemGeo, center);
- projection.toPixels(leftGeo, left);
- int radius = center.x - left.x;
-
- final String type = item.getType();
- if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) {
- blockedCircle.setColor(0x66000000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
- } else {
- blockedCircle.setColor(0x66BB0000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
-
- blockedCircle.setColor(0x44BB0000);
- blockedCircle.setStyle(Style.FILL);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ // prevent content changes
+ getOverlayImpl().lock();
+ try {
+ if (displayCircles) {
+ if (blockedCircle == null) {
+ blockedCircle = new Paint();
+ blockedCircle.setAntiAlias(true);
+ blockedCircle.setStrokeWidth(1.0f);
+ blockedCircle.setARGB(127, 0, 0, 0);
+ blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0));
}
+
+ if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
+ if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
+
+ canvas.setDrawFilter(setfil);
+
+ for (CacheOverlayItemImpl item : items) {
+ final cgCoord itemCoord = item.getCoord();
+ float[] result = new float[1];
+
+ Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
+ final float longitudeLineDistance = result[0];
+
+ GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
+ GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
+
+ projection.toPixels(itemGeo, center);
+ projection.toPixels(leftGeo, left);
+ int radius = center.x - left.x;
+
+ final String type = item.getType();
+ if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) {
+ blockedCircle.setColor(0x66000000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ } else {
+ blockedCircle.setColor(0x66BB0000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+
+ blockedCircle.setColor(0x44BB0000);
+ blockedCircle.setStyle(Style.FILL);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ }
+ }
+ canvas.setDrawFilter(remfil);
}
-
- canvas.setDrawFilter(remfil);
+ } finally {
+ getOverlayImpl().unlock();
}
}
@@ -170,7 +181,22 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
}
waitDialog.show();
- CacheOverlayItemImpl item = items.get(index);
+ CacheOverlayItemImpl item = null;
+
+ // prevent concurrent changes
+ getOverlayImpl().lock();
+ try {
+ if (index < items.size()) {
+ item = items.get(index);
+ }
+ } finally {
+ getOverlayImpl().unlock();
+ }
+
+ if (item == null) {
+ return false;
+ }
+
cgCoord coordinate = item.getCoord();
if (coordinate.type != null && coordinate.type.equalsIgnoreCase("cache") && coordinate.geocode != null && coordinate.geocode.length() > 0) {
diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
index bd5b8ef..ba45532 100644
--- a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
+++ b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java
@@ -12,5 +12,9 @@ public interface OverlayImpl {
PositionOverlay,
ScaleOverlay
}
+
+ void lock();
+
+ void unlock();
}
diff --git a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
index 6333133..1e3b287 100644
--- a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.ItemizedOverlay;
import org.mapsforge.android.maps.Projection;
@@ -17,6 +20,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl;
public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implements ItemizedOverlayImpl {
private cgMapOverlay base;
+ private Lock lock = new ReentrantLock();
public mfCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) {
super(boundCenterBottom(markerIn));
@@ -94,5 +98,15 @@ public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implemen
super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel);
}
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
}
diff --git a/src/cgeo/geocaching/mapsforge/mfOverlay.java b/src/cgeo/geocaching/mapsforge/mfOverlay.java
index 833d382..f764c6b 100644
--- a/src/cgeo/geocaching/mapsforge/mfOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.Overlay;
import org.mapsforge.android.maps.Projection;
@@ -15,6 +18,7 @@ import cgeo.geocaching.mapinterfaces.OverlayImpl;
public class mfOverlay extends Overlay implements OverlayImpl {
private OverlayBase overlayBase = null;
+ private Lock lock = new ReentrantLock();
public mfOverlay(Activity activityIn, cgSettings settingsIn, OverlayImpl.overlayType ovlType) {
@@ -39,4 +43,14 @@ public class mfOverlay extends Overlay implements OverlayImpl {
public OverlayBase getBase() {
return overlayBase;
}
+
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
}
diff --git a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java
index 8f3ba04..6e2819c 100644
--- a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java
+++ b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.mapsforge;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
import org.mapsforge.android.maps.ItemizedOverlay;
import org.mapsforge.android.maps.Projection;
@@ -15,6 +18,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl;
public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implements ItemizedOverlayImpl {
private cgUsersOverlay base;
+ private Lock lock = new ReentrantLock();
public mfUsersOverlay(Context contextIn, Drawable markerIn) {
super(boundCenter(markerIn));
@@ -94,4 +98,14 @@ public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implemen
super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel);
}
+ @Override
+ public void lock() {
+ lock.lock();
+ }
+
+ @Override
+ public void unlock() {
+ lock.unlock();
+ }
+
} \ No newline at end of file