BearND has uploaded a new change for review.
https://gerrit.wikimedia.org/r/166714
Change subject: Fix crash in sorting of nearby pages
......................................................................
Fix crash in sorting of nearby pages
IllegalArgumentException: Comparison method violates its general contract
bug: 72066
Change-Id: Ife50b225797cf0a471ac29a6db1d676316a7a860
---
M wikipedia-it/src/main/java/org/wikipedia/nearby/NearbyUnitTests.java
M wikipedia/src/main/java/org/wikipedia/nearby/NearbyActivity.java
M wikipedia/src/main/java/org/wikipedia/nearby/NearbyPage.java
3 files changed, 75 insertions(+), 36 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/14/166714/1
diff --git
a/wikipedia-it/src/main/java/org/wikipedia/nearby/NearbyUnitTests.java
b/wikipedia-it/src/main/java/org/wikipedia/nearby/NearbyUnitTests.java
index 45f6d57..80db0f5 100644
--- a/wikipedia-it/src/main/java/org/wikipedia/nearby/NearbyUnitTests.java
+++ b/wikipedia-it/src/main/java/org/wikipedia/nearby/NearbyUnitTests.java
@@ -19,7 +19,8 @@
private static final int FOUR = 4;
private static final double SHORT_DISTANCE = 0.001d;
private static final double LONGER_DISTANCE = 0.01d;
- private static final int A_B_DISTANCE = 111320;
+ /** dist(origin, point a) */
+ private static final int A = 111319;
private Location nextLocation;
private List<NearbyPage> nearbyPages;
@@ -37,6 +38,7 @@
}
public void testSort() throws Exception {
+ calcDistances(nearbyPages);
Collections.sort(nearbyPages, new NearbyDistanceComparator());
assertEquals("a", nearbyPages.get(0).getTitle());
assertEquals("b", nearbyPages.get(1).getTitle());
@@ -46,6 +48,7 @@
public void testSortWithNullLocations() throws Exception {
nearbyPages.add(new NearbyPage(new JSONObject("{ \"title\": \"d\"
}")));
nearbyPages.add(new NearbyPage(new JSONObject("{ \"title\": \"e\"
}")));
+ calcDistances(nearbyPages);
Collections.sort(nearbyPages, new NearbyDistanceComparator());
assertEquals("a", nearbyPages.get(0).getTitle());
assertEquals("b", nearbyPages.get(1).getTitle());
@@ -57,10 +60,16 @@
public void testCompare() throws Exception {
NearbyPage nullLocPage = new NearbyPage(new JSONObject("{ \"title\":
\"nowhere\" }"));
+
+ calcDistances(nearbyPages);
+ nullLocPage.setDistance(getDistance(nullLocPage.getLocation()));
+ assertEquals(Integer.MAX_VALUE, nullLocPage.getDistance());
+
NearbyDistanceComparator comp = new NearbyDistanceComparator();
- assertEquals(A_B_DISTANCE, comp.compare(nearbyPages.get(0),
nearbyPages.get(1)));
- assertEquals(-1, comp.compare(nearbyPages.get(0), nullLocPage));
- assertEquals(1, comp.compare(nullLocPage, nearbyPages.get(0)));
+ assertEquals(A, comp.compare(nearbyPages.get(1), nearbyPages.get(2)));
+ assertEquals(-1 * A, comp.compare(nearbyPages.get(2),
nearbyPages.get(1)));
+ assertEquals(Integer.MAX_VALUE - A, comp.compare(nullLocPage,
nearbyPages.get(2)));
+ assertEquals((Integer.MIN_VALUE + 1) + A,
comp.compare(nearbyPages.get(2), nullLocPage)); // - (max - a)
assertEquals(0, comp.compare(nullLocPage, nullLocPage));
}
@@ -91,22 +100,30 @@
private class NearbyDistanceComparator implements Comparator<NearbyPage> {
public int compare(NearbyPage a, NearbyPage b) {
- if (a.getLocation() == null) {
- if (b.getLocation() == null) {
- return 0;
- } else {
- return 1;
- }
- } else if (b.getLocation() == null) {
- return -1;
- } else {
- return getDistance(a.getLocation()) -
getDistance(b.getLocation());
- }
+ return a.getDistance() - b.getDistance();
+ }
+ }
+
+ //
+ // UGLY: copy of production code
+ //
+
+ /**
+ * Calculates the distances from the origin to the given pages.
+ * This method should be called before sorting.
+ */
+ private void calcDistances(List<NearbyPage> pages) {
+ for (NearbyPage page : pages) {
+ page.setDistance(getDistance(page.getLocation()));
}
}
private int getDistance(Location otherLocation) {
- return (int) nextLocation.distanceTo(otherLocation);
+ if (otherLocation == null) {
+ return Integer.MAX_VALUE;
+ } else {
+ return (int) nextLocation.distanceTo(otherLocation);
+ }
}
private static final int ONE_KM = 1000;
diff --git a/wikipedia/src/main/java/org/wikipedia/nearby/NearbyActivity.java
b/wikipedia/src/main/java/org/wikipedia/nearby/NearbyActivity.java
index a4966ca..4a0bbe4 100644
--- a/wikipedia/src/main/java/org/wikipedia/nearby/NearbyActivity.java
+++ b/wikipedia/src/main/java/org/wikipedia/nearby/NearbyActivity.java
@@ -1,6 +1,5 @@
package org.wikipedia.nearby;
-import android.content.ActivityNotFoundException;
import org.wikipedia.PageTitle;
import org.wikipedia.R;
import org.wikipedia.Site;
@@ -14,6 +13,7 @@
import de.keyboardsurfer.android.widget.crouton.Crouton;
import de.keyboardsurfer.android.widget.crouton.Style;
import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -147,11 +147,11 @@
NearbyPage nearbyPage = adapter.getItem(position);
PageTitle title = new PageTitle(nearbyPage.getTitle(), site,
nearbyPage.getThumblUrl());
String geoUri = String.format(Locale.ENGLISH,
- "geo:0,0?q=%s,%s(%s)",
- nearbyPage.getLocation().getLatitude(),
- nearbyPage.getLocation().getLongitude(),
- title.getDisplayText()
- );
+ "geo:0,0?q=%s,%s(%s)",
+
nearbyPage.getLocation().getLatitude(),
+
nearbyPage.getLocation().getLongitude(),
+ title.getDisplayText()
+ );
Intent geoIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(geoUri));
try {
startActivity(geoIntent);
@@ -415,25 +415,31 @@
}
private void sortByDistance(List<NearbyPage> nearbyPages) {
+ calcDistances(nearbyPages);
+
Collections.sort(nearbyPages, new Comparator<NearbyPage>() {
public int compare(NearbyPage a, NearbyPage b) {
- if (a.getLocation() == null) {
- if (b.getLocation() == null) {
- return 0;
- } else {
- return 1;
- }
- } else if (b.getLocation() == null) {
- return -1;
- } else {
- return getDistance(a.getLocation()) -
getDistance(b.getLocation());
- }
+ return a.getDistance() - b.getDistance();
}
});
}
+ /**
+ * Calculates the distances from the origin to the given pages.
+ * This method should be called before sorting.
+ */
+ private void calcDistances(List<NearbyPage> pages) {
+ for (NearbyPage page : pages) {
+ page.setDistance(getDistance(page.getLocation()));
+ }
+ }
+
private int getDistance(Location otherLocation) {
- return (int) nextLocation.distanceTo(otherLocation);
+ if (otherLocation == null) {
+ return Integer.MAX_VALUE;
+ } else {
+ return (int) nextLocation.distanceTo(otherLocation);
+ }
}
private String getDistanceLabel(Location otherLocation) {
diff --git a/wikipedia/src/main/java/org/wikipedia/nearby/NearbyPage.java
b/wikipedia/src/main/java/org/wikipedia/nearby/NearbyPage.java
index 2a73c99..748528f 100644
--- a/wikipedia/src/main/java/org/wikipedia/nearby/NearbyPage.java
+++ b/wikipedia/src/main/java/org/wikipedia/nearby/NearbyPage.java
@@ -1,9 +1,9 @@
package org.wikipedia.nearby;
-import android.location.Location;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import android.location.Location;
/**
* Data object holding information about a nearby page.
@@ -30,6 +30,9 @@
private String title;
private String thumblUrl;
private Location location;
+
+ /** calculated externally */
+ private int distance;
public NearbyPage(JSONObject json) {
try {
@@ -76,7 +79,20 @@
return "NearbyPage{"
+ "title='" + title + '\''
+ ", thumblUrl='" + thumblUrl + '\''
- + ", location=" + location
+ + ", location=" + location + '\''
+ + ", distance='" + distance
+ '}';
}
+
+ /**
+ * Returns the distance from the point where the device is.
+ * Calculated later and can change. Needs to be set first by #setDistance!
+ */
+ public int getDistance() {
+ return distance;
+ }
+
+ public void setDistance(int distance) {
+ this.distance = distance;
+ }
}
--
To view, visit https://gerrit.wikimedia.org/r/166714
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ife50b225797cf0a471ac29a6db1d676316a7a860
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: BearND <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits