Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java

Issue 661413003: Android: add support for Device Orientation on devices where ROTATION_VECTOR is not availabl… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add test when rotation vector is not available Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
index 7437e165e92721b029f121f559139fd1ee89cd8d..81eab0f244906f4698487d9af5ae9a7ab7bdbce1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
+++ b/content/public/android/java/src/org/chromium/content/browser/DeviceSensors.java
@@ -49,6 +49,12 @@ class DeviceSensors implements SensorEventListener {
// The lock to access the mNativePtr.
private final Object mNativePtrLock = new Object();
+ // The acceleration vector including gravity expressed in the body frame.
+ private float[] mAccelerationIncludingGravityVector;
+
+ // The geomagnetic vector expressed in the body frame.
+ private float[] mMagneticFieldVector;
+
// Holds a shortened version of the rotation vector for compatibility purposes.
private float[] mTruncatedRotationVector;
@@ -67,9 +73,12 @@ class DeviceSensors implements SensorEventListener {
static final int DEVICE_MOTION = 1;
static final int DEVICE_LIGHT = 2;
- static final Set<Integer> DEVICE_ORIENTATION_SENSORS = CollectionUtil.newHashSet(
+ static final Set<Integer> DEVICE_ORIENTATION_DEFAULT_SENSORS = CollectionUtil.newHashSet(
Sensor.TYPE_ROTATION_VECTOR);
-
+ // Backup sensors are used when Sensor.TYPE_ROTATION_VECTOR is not available.
+ static final Set<Integer> DEVICE_ORIENTATION_BACKUP_SENSORS = CollectionUtil.newHashSet(
+ Sensor.TYPE_ACCELEROMETER,
+ Sensor.TYPE_MAGNETIC_FIELD);
static final Set<Integer> DEVICE_MOTION_SENSORS = CollectionUtil.newHashSet(
Sensor.TYPE_ACCELEROMETER,
Sensor.TYPE_LINEAR_ACCELERATION,
@@ -79,9 +88,11 @@ class DeviceSensors implements SensorEventListener {
@VisibleForTesting
final Set<Integer> mActiveSensors = new HashSet<Integer>();
+ Set<Integer> mDeviceOrientationSensors = DEVICE_ORIENTATION_DEFAULT_SENSORS;
boolean mDeviceLightIsActive = false;
boolean mDeviceMotionIsActive = false;
boolean mDeviceOrientationIsActive = false;
+ boolean mUseBackupOrientationSensors = false;
protected DeviceSensors(Context context) {
mAppContext = context.getApplicationContext();
@@ -104,8 +115,14 @@ class DeviceSensors implements SensorEventListener {
synchronized (mNativePtrLock) {
switch (eventType) {
case DEVICE_ORIENTATION:
- success = registerSensors(DEVICE_ORIENTATION_SENSORS, rateInMicroseconds,
- true);
+ success = registerSensors(mDeviceOrientationSensors, rateInMicroseconds,
+ true);
+ if (!success) {
+ mDeviceOrientationSensors = DEVICE_ORIENTATION_BACKUP_SENSORS;
+ success = registerSensors(mDeviceOrientationSensors, rateInMicroseconds,
+ true);
+ mUseBackupOrientationSensors = success;
+ }
break;
case DEVICE_MOTION:
// note: device motion spec does not require all sensors to be available
@@ -133,6 +150,11 @@ class DeviceSensors implements SensorEventListener {
return DEVICE_MOTION_SENSORS.size() - deviceMotionSensors.size();
}
+ @CalledByNative
+ public boolean isUsingBackupSensorsForOrientation() {
+ return mUseBackupOrientationSensors;
+ }
+
/**
* Stop listening to sensors for a given event type. Ensures that sensors are not disabled
* if they are still in use by a different event type.
@@ -157,7 +179,7 @@ class DeviceSensors implements SensorEventListener {
break;
case DEVICE_MOTION:
if (mDeviceOrientationIsActive) {
- sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
+ sensorsToRemainActive.addAll(mDeviceOrientationSensors);
}
if (mDeviceLightIsActive) {
sensorsToRemainActive.addAll(DEVICE_LIGHT_SENSORS);
@@ -168,7 +190,7 @@ class DeviceSensors implements SensorEventListener {
sensorsToRemainActive.addAll(DEVICE_MOTION_SENSORS);
}
if (mDeviceOrientationIsActive) {
- sensorsToRemainActive.addAll(DEVICE_ORIENTATION_SENSORS);
+ sensorsToRemainActive.addAll(mDeviceOrientationSensors);
}
break;
default:
@@ -203,6 +225,9 @@ class DeviceSensors implements SensorEventListener {
if (mDeviceMotionIsActive) {
gotAccelerationIncludingGravity(values[0], values[1], values[2]);
}
+ if (mDeviceOrientationIsActive && mUseBackupOrientationSensors) {
+ getOrientationFromGeomagneticVectors(values, mMagneticFieldVector);
+ }
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
if (mDeviceMotionIsActive) {
@@ -231,6 +256,15 @@ class DeviceSensors implements SensorEventListener {
}
}
break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ if (mDeviceOrientationIsActive && mUseBackupOrientationSensors) {
+ if (mMagneticFieldVector == null) {
+ mMagneticFieldVector = new float[3];
+ }
+ System.arraycopy(values, 0, mMagneticFieldVector, 0,
+ mMagneticFieldVector.length);
+ }
+ break;
case Sensor.TYPE_LIGHT:
if (mDeviceLightIsActive) {
gotLight(values[0]);
@@ -338,6 +372,23 @@ class DeviceSensors implements SensorEventListener {
Math.toDegrees(rotationAngles[2]));
}
+ private void getOrientationFromGeomagneticVectors(float[] acceleration, float[] magnetic) {
+ float[] deviceRotationMatrix = new float[9];
+ if (acceleration == null || magnetic == null) {
+ return;
+ }
+ if (!SensorManager.getRotationMatrix(deviceRotationMatrix, null, acceleration, magnetic)) {
+ return;
+ }
+
+ double[] rotationAngles = new double[3];
+ computeDeviceOrientationFromRotationMatrix(deviceRotationMatrix, rotationAngles);
+
+ gotOrientation(Math.toDegrees(rotationAngles[0]),
+ Math.toDegrees(rotationAngles[1]),
+ Math.toDegrees(rotationAngles[2]));
+ }
+
private SensorManagerProxy getSensorManagerProxy() {
if (mSensorManagerProxy != null) {
return mSensorManagerProxy;

Powered by Google App Engine
This is Rietveld 408576698