aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2015-08-31 13:33:57 +0200
committerSamuel Tardieu <sam@rfc1149.net>2015-08-31 13:33:57 +0200
commit54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6 (patch)
tree5fb52332d284bd3ca9acfe7f74a4bc19efa87430
parent554a4e8b87f187dba55450c57f6a1ae783e12e19 (diff)
downloadcgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.zip
cgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.tar.gz
cgeo-54c2a6c2ea1ca8440ea8ba3bd838d340509aa2f6.tar.bz2
Apply the workaround for Samsung devices only when strictly needed
Since Samsung firmware may have been fixed and accept more than 4 values in getRotationMatrixFromVector(), truncate the size of the rotation vector only when this is strictly needed.
-rw-r--r--main/src/cgeo/geocaching/sensors/RotationProvider.java28
1 files changed, 23 insertions, 5 deletions
diff --git a/main/src/cgeo/geocaching/sensors/RotationProvider.java b/main/src/cgeo/geocaching/sensors/RotationProvider.java
index 59be8f1..d0db113 100644
--- a/main/src/cgeo/geocaching/sensors/RotationProvider.java
+++ b/main/src/cgeo/geocaching/sensors/RotationProvider.java
@@ -18,6 +18,18 @@ import android.hardware.SensorManager;
public class RotationProvider {
+ /**
+ * On some Samsung devices, {@link SensorManager#getRotationMatrixFromVector} throws an exception if the rotation
+ * vector has more than 4 elements.
+ * <p/>
+ * This will be detected and remembered after the first occurrence of the exception. Concurrent access
+ * is not a problem as this variable can only go from {@code false} to {@code true} and being {@code false}
+ * instead of {@code true} is innocuous and will be changed immediately when needed.
+ *
+ * @see <a href="http://stackoverflow.com/a/22138449">this Stack Overflow answer</a>
+ */
+ private static boolean isTruncationNeeded = false;
+
private RotationProvider() {
// Utility class, not to be instantiated
}
@@ -43,14 +55,20 @@ public class RotationProvider {
@Override
public void onSensorChanged(final SensorEvent event) {
- // On some Samsung devices, SensorManager#getRotationMatrixFromVector throws an exception if the rotation
- // vector has more than 4 elements. Since only the four first elements are used, we can truncate the vector
- // without losing precision.
- if (event.values.length > 4) {
+ if (isTruncationNeeded) {
+ // Since only the four first elements are used (and accepted), we truncate the vector.
System.arraycopy(event.values, 0, values, 0, 4);
SensorManager.getRotationMatrixFromVector(rotationMatrix, values);
} else {
- SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
+ try {
+ SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
+ } catch (final IllegalArgumentException ignored) {
+ Log.d("installing workaround for mismatched number of values in rotation vector");
+ // Install workaround and retry
+ isTruncationNeeded = true;
+ onSensorChanged(event);
+ return;
+ }
}
SensorManager.getOrientation(rotationMatrix, orientation);
subscriber.onNext((float) (orientation[0] * 180 / Math.PI));