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; |