OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.content.browser; | 5 package org.chromium.device.sensors; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.hardware.Sensor; | 8 import android.hardware.Sensor; |
9 import android.hardware.SensorEvent; | 9 import android.hardware.SensorEvent; |
10 import android.hardware.SensorEventListener; | 10 import android.hardware.SensorEventListener; |
11 import android.hardware.SensorManager; | 11 import android.hardware.SensorManager; |
12 import android.os.Handler; | 12 import android.os.Handler; |
13 import android.os.HandlerThread; | 13 import android.os.HandlerThread; |
14 | 14 |
15 import org.chromium.base.CollectionUtil; | 15 import org.chromium.base.CollectionUtil; |
16 import org.chromium.base.Log; | 16 import org.chromium.base.Log; |
17 import org.chromium.base.ThreadUtils; | 17 import org.chromium.base.ThreadUtils; |
18 import org.chromium.base.VisibleForTesting; | 18 import org.chromium.base.VisibleForTesting; |
19 import org.chromium.base.annotations.CalledByNative; | 19 import org.chromium.base.annotations.CalledByNative; |
20 import org.chromium.base.annotations.JNINamespace; | 20 import org.chromium.base.annotations.JNINamespace; |
21 | 21 |
22 import java.util.HashSet; | 22 import java.util.HashSet; |
23 import java.util.List; | 23 import java.util.List; |
24 import java.util.Set; | 24 import java.util.Set; |
25 | 25 |
26 /** | 26 /** |
27 * Android implementation of the device {motion|orientation|light} APIs. | 27 * Android implementation of the device {motion|orientation|light} APIs. |
28 */ | 28 */ |
29 @JNINamespace("content") | 29 @JNINamespace("device") |
30 class DeviceSensors implements SensorEventListener { | 30 public class DeviceSensors implements SensorEventListener { |
31 | 31 private static final String TAG = "DeviceSensors"; |
32 private static final String TAG = "cr.DeviceSensors"; | |
33 | 32 |
34 // Matches kEnableExperimentalWebPlatformFeatures. | 33 // Matches kEnableExperimentalWebPlatformFeatures. |
35 private static final String EXPERIMENTAL_WEB_PLAFTORM_FEATURES = | 34 private static final String EXPERIMENTAL_WEB_PLAFTORM_FEATURES = |
36 "enable-experimental-web-platform-features"; | 35 "enable-experimental-web-platform-features"; |
37 | 36 |
38 // These fields are lazily initialized by getHandler(). | 37 // These fields are lazily initialized by getHandler(). |
39 private Thread mThread; | 38 private Thread mThread; |
40 private Handler mHandler; | 39 private Handler mHandler; |
41 | 40 |
42 // A reference to the application context in order to acquire the SensorServ ice. | 41 // A reference to the application context in order to acquire the SensorServ ice. |
(...skipping 21 matching lines...) Expand all Loading... | |
64 // Holds Euler angles corresponding to the rotation matrix. | 63 // Holds Euler angles corresponding to the rotation matrix. |
65 private double[] mRotationAngles; | 64 private double[] mRotationAngles; |
66 | 65 |
67 // Lazily initialized when registering for notifications. | 66 // Lazily initialized when registering for notifications. |
68 private SensorManagerProxy mSensorManagerProxy; | 67 private SensorManagerProxy mSensorManagerProxy; |
69 | 68 |
70 // The only instance of that class and its associated lock. | 69 // The only instance of that class and its associated lock. |
71 private static DeviceSensors sSingleton; | 70 private static DeviceSensors sSingleton; |
72 private static Object sSingletonLock = new Object(); | 71 private static Object sSingletonLock = new Object(); |
73 | 72 |
74 static final Set<Integer> DEVICE_ORIENTATION_SENSORS_A = CollectionUtil.newH ashSet( | 73 public static final Set<Integer> DEVICE_ORIENTATION_SENSORS_A = |
timvolodine
2017/01/26 14:01:15
why does this have to be public? also below and th
ke.he
2017/01/26 15:33:22
With this patch, the package name of this class is
timvolodine
2017/01/31 07:13:15
I assume this is a temporary situation? Is it poss
| |
75 Sensor.TYPE_GAME_ROTATION_VECTOR); | 74 CollectionUtil.newHashSet(Sensor.TYPE_GAME_ROTATION_VECTOR); |
76 static final Set<Integer> DEVICE_ORIENTATION_SENSORS_B = CollectionUtil.newH ashSet( | 75 public static final Set<Integer> DEVICE_ORIENTATION_SENSORS_B = |
77 Sensor.TYPE_ROTATION_VECTOR); | 76 CollectionUtil.newHashSet(Sensor.TYPE_ROTATION_VECTOR); |
78 // Option C backup sensors are used when options A and B are not available. | 77 // Option C backup sensors are used when options A and B are not available. |
79 static final Set<Integer> DEVICE_ORIENTATION_SENSORS_C = CollectionUtil.newH ashSet( | 78 public static final Set<Integer> DEVICE_ORIENTATION_SENSORS_C = |
80 Sensor.TYPE_ACCELEROMETER, | 79 CollectionUtil.newHashSet(Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_MAG NETIC_FIELD); |
81 Sensor.TYPE_MAGNETIC_FIELD); | 80 public static final Set<Integer> DEVICE_ORIENTATION_ABSOLUTE_SENSORS = |
82 static final Set<Integer> DEVICE_ORIENTATION_ABSOLUTE_SENSORS = CollectionUt il.newHashSet( | 81 CollectionUtil.newHashSet(Sensor.TYPE_ROTATION_VECTOR); |
83 Sensor.TYPE_ROTATION_VECTOR); | 82 public static final Set<Integer> DEVICE_MOTION_SENSORS = CollectionUtil.newH ashSet( |
84 static final Set<Integer> DEVICE_MOTION_SENSORS = CollectionUtil.newHashSet( | 83 Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_LINEAR_ACCELERATION, Sensor.T YPE_GYROSCOPE); |
85 Sensor.TYPE_ACCELEROMETER, | 84 public static final Set<Integer> DEVICE_LIGHT_SENSORS = |
86 Sensor.TYPE_LINEAR_ACCELERATION, | 85 CollectionUtil.newHashSet(Sensor.TYPE_LIGHT); |
87 Sensor.TYPE_GYROSCOPE); | |
88 static final Set<Integer> DEVICE_LIGHT_SENSORS = CollectionUtil.newHashSet( | |
89 Sensor.TYPE_LIGHT); | |
90 | 86 |
91 @VisibleForTesting | 87 @VisibleForTesting |
92 final Set<Integer> mActiveSensors = new HashSet<Integer>(); | 88 public final Set<Integer> mActiveSensors = new HashSet<Integer>(); |
93 final List<Set<Integer>> mOrientationSensorSets; | 89 public final List<Set<Integer>> mOrientationSensorSets; |
94 Set<Integer> mDeviceOrientationSensors; | 90 public Set<Integer> mDeviceOrientationSensors; |
95 boolean mDeviceLightIsActive; | 91 public boolean mDeviceLightIsActive; |
96 boolean mDeviceMotionIsActive; | 92 public boolean mDeviceMotionIsActive; |
97 boolean mDeviceOrientationIsActive; | 93 public boolean mDeviceOrientationIsActive; |
98 boolean mDeviceOrientationIsActiveWithBackupSensors; | 94 public boolean mDeviceOrientationIsActiveWithBackupSensors; |
99 boolean mDeviceOrientationAbsoluteIsActive; | 95 public boolean mDeviceOrientationAbsoluteIsActive; |
100 boolean mOrientationNotAvailable; | 96 public boolean mOrientationNotAvailable; |
101 | 97 |
102 protected DeviceSensors(Context context) { | 98 protected DeviceSensors(Context context) { |
103 mAppContext = context.getApplicationContext(); | 99 mAppContext = context.getApplicationContext(); |
104 | 100 |
105 mOrientationSensorSets = CollectionUtil.newArrayList(DEVICE_ORIENTATION_ SENSORS_A, | 101 mOrientationSensorSets = CollectionUtil.newArrayList(DEVICE_ORIENTATION_ SENSORS_A, |
106 DEVICE_ORIENTATION_ SENSORS_B, | 102 DEVICE_ORIENTATION_SENSORS_B, DEVICE_ORIENTATION_SENSORS_C); |
107 DEVICE_ORIENTATION_ SENSORS_C); | |
108 } | 103 } |
109 | 104 |
110 // For orientation we use a 3-way fallback approach where up to 3 different sets of sensors | 105 // For orientation we use a 3-way fallback approach where up to 3 different sets of sensors |
111 // are attempted if necessary. The sensors to be used for orientation are de termined in the | 106 // are attempted if necessary. The sensors to be used for orientation are de termined in the |
112 // following order: | 107 // following order: |
113 // A: GAME_ROTATION_VECTOR (relative) | 108 // A: GAME_ROTATION_VECTOR (relative) |
114 // B: ROTATION_VECTOR (absolute) | 109 // B: ROTATION_VECTOR (absolute) |
115 // C: combination of ACCELEROMETER and MAGNETIC_FIELD (absolute) | 110 // C: combination of ACCELEROMETER and MAGNETIC_FIELD (absolute) |
116 // Some of the sensors may not be available depending on the device and Andr oid version, so | 111 // Some of the sensors may not be available depending on the device and Andr oid version, so |
117 // the 3-way fallback ensures selection of the best possible option. | 112 // the 3-way fallback ensures selection of the best possible option. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 @CalledByNative | 148 @CalledByNative |
154 public boolean start(long nativePtr, int eventType, int rateInMicroseconds) { | 149 public boolean start(long nativePtr, int eventType, int rateInMicroseconds) { |
155 boolean success = false; | 150 boolean success = false; |
156 synchronized (mNativePtrLock) { | 151 synchronized (mNativePtrLock) { |
157 switch (eventType) { | 152 switch (eventType) { |
158 case ConsumerType.ORIENTATION: | 153 case ConsumerType.ORIENTATION: |
159 success = registerOrientationSensorsWithFallback(rateInMicro seconds); | 154 success = registerOrientationSensorsWithFallback(rateInMicro seconds); |
160 break; | 155 break; |
161 case ConsumerType.ORIENTATION_ABSOLUTE: | 156 case ConsumerType.ORIENTATION_ABSOLUTE: |
162 ensureRotationStructuresAllocated(); | 157 ensureRotationStructuresAllocated(); |
163 success = registerSensors(DEVICE_ORIENTATION_ABSOLUTE_SENSOR S, | 158 success = registerSensors( |
164 rateInMicroseconds, true); | 159 DEVICE_ORIENTATION_ABSOLUTE_SENSORS, rateInMicroseco nds, true); |
165 break; | 160 break; |
166 case ConsumerType.MOTION: | 161 case ConsumerType.MOTION: |
167 // note: device motion spec does not require all sensors to be available | 162 // note: device motion spec does not require all sensors to be available |
168 success = registerSensors(DEVICE_MOTION_SENSORS, rateInMicro seconds, false); | 163 success = registerSensors(DEVICE_MOTION_SENSORS, rateInMicro seconds, false); |
169 break; | 164 break; |
170 case ConsumerType.LIGHT: | 165 case ConsumerType.LIGHT: |
171 success = registerSensors(DEVICE_LIGHT_SENSORS, rateInMicros econds, true); | 166 success = registerSensors(DEVICE_LIGHT_SENSORS, rateInMicros econds, true); |
172 break; | 167 break; |
173 default: | 168 default: |
174 Log.e(TAG, "Unknown event type: %d", eventType); | 169 Log.e(TAG, "Unknown event type: %d", eventType); |
(...skipping 22 matching lines...) Expand all Loading... | |
197 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_A) { | 192 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_A) { |
198 return OrientationSensorType.GAME_ROTATION_VECTOR; | 193 return OrientationSensorType.GAME_ROTATION_VECTOR; |
199 } | 194 } |
200 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_B) { | 195 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_B) { |
201 return OrientationSensorType.ROTATION_VECTOR; | 196 return OrientationSensorType.ROTATION_VECTOR; |
202 } | 197 } |
203 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_C) { | 198 if (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSORS_C) { |
204 return OrientationSensorType.ACCELEROMETER_MAGNETIC; | 199 return OrientationSensorType.ACCELEROMETER_MAGNETIC; |
205 } | 200 } |
206 | 201 |
207 assert false; // should never happen | 202 assert false; // should never happen |
208 return OrientationSensorType.NOT_AVAILABLE; | 203 return OrientationSensorType.NOT_AVAILABLE; |
209 } | 204 } |
210 | 205 |
211 /** | 206 /** |
212 * Stop listening to sensors for a given event type. Ensures that sensors ar e not disabled | 207 * Stop listening to sensors for a given event type. Ensures that sensors ar e not disabled |
213 * if they are still in use by a different event type. | 208 * if they are still in use by a different event type. |
214 * | 209 * |
215 * @param eventType Type of event to listen to, can be either DEVICE_ORIENTA TION or | 210 * @param eventType Type of event to listen to, can be either DEVICE_ORIENTA TION or |
216 * DEVICE_MOTION or DEVICE_LIGHT. | 211 * DEVICE_MOTION or DEVICE_LIGHT. |
217 * We strictly guarantee that the corresponding native*() methods will not b e called | 212 * We strictly guarantee that the corresponding native*() methods will not b e called |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 public void onAccuracyChanged(Sensor sensor, int accuracy) { | 248 public void onAccuracyChanged(Sensor sensor, int accuracy) { |
254 // Nothing | 249 // Nothing |
255 } | 250 } |
256 | 251 |
257 @Override | 252 @Override |
258 public void onSensorChanged(SensorEvent event) { | 253 public void onSensorChanged(SensorEvent event) { |
259 sensorChanged(event.sensor.getType(), event.values); | 254 sensorChanged(event.sensor.getType(), event.values); |
260 } | 255 } |
261 | 256 |
262 @VisibleForTesting | 257 @VisibleForTesting |
263 void sensorChanged(int type, float[] values) { | 258 public void sensorChanged(int type, float[] values) { |
264 switch (type) { | 259 switch (type) { |
265 case Sensor.TYPE_ACCELEROMETER: | 260 case Sensor.TYPE_ACCELEROMETER: |
266 if (mDeviceMotionIsActive) { | 261 if (mDeviceMotionIsActive) { |
267 gotAccelerationIncludingGravity(values[0], values[1], values [2]); | 262 gotAccelerationIncludingGravity(values[0], values[1], values [2]); |
268 } | 263 } |
269 if (mDeviceOrientationIsActiveWithBackupSensors) { | 264 if (mDeviceOrientationIsActiveWithBackupSensors) { |
270 getOrientationFromGeomagneticVectors(values, mMagneticFieldV ector); | 265 getOrientationFromGeomagneticVectors(values, mMagneticFieldV ector); |
271 } | 266 } |
272 break; | 267 break; |
273 case Sensor.TYPE_LINEAR_ACCELERATION: | 268 case Sensor.TYPE_LINEAR_ACCELERATION: |
274 if (mDeviceMotionIsActive) { | 269 if (mDeviceMotionIsActive) { |
275 gotAcceleration(values[0], values[1], values[2]); | 270 gotAcceleration(values[0], values[1], values[2]); |
276 } | 271 } |
277 break; | 272 break; |
278 case Sensor.TYPE_GYROSCOPE: | 273 case Sensor.TYPE_GYROSCOPE: |
279 if (mDeviceMotionIsActive) { | 274 if (mDeviceMotionIsActive) { |
280 gotRotationRate(values[0], values[1], values[2]); | 275 gotRotationRate(values[0], values[1], values[2]); |
281 } | 276 } |
282 break; | 277 break; |
283 case Sensor.TYPE_ROTATION_VECTOR: | 278 case Sensor.TYPE_ROTATION_VECTOR: |
284 if (mDeviceOrientationAbsoluteIsActive) { | 279 if (mDeviceOrientationAbsoluteIsActive) { |
285 convertRotationVectorToAngles(values, mRotationAngles); | 280 convertRotationVectorToAngles(values, mRotationAngles); |
286 gotOrientationAbsolute(mRotationAngles[0], mRotationAngles[1 ], | 281 gotOrientationAbsolute( |
287 mRotationAngles[2]); | 282 mRotationAngles[0], mRotationAngles[1], mRotationAng les[2]); |
288 } | 283 } |
289 if (mDeviceOrientationIsActive | 284 if (mDeviceOrientationIsActive |
290 && mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSO RS_B) { | 285 && mDeviceOrientationSensors == DEVICE_ORIENTATION_SENSO RS_B) { |
291 if (!mDeviceOrientationAbsoluteIsActive) { | 286 if (!mDeviceOrientationAbsoluteIsActive) { |
292 // only compute if not already computed for absolute ori entation above. | 287 // only compute if not already computed for absolute ori entation above. |
293 convertRotationVectorToAngles(values, mRotationAngles); | 288 convertRotationVectorToAngles(values, mRotationAngles); |
294 } | 289 } |
295 gotOrientation(mRotationAngles[0], mRotationAngles[1], mRota tionAngles[2]); | 290 gotOrientation(mRotationAngles[0], mRotationAngles[1], mRota tionAngles[2]); |
296 } | 291 } |
297 break; | 292 break; |
298 case Sensor.TYPE_GAME_ROTATION_VECTOR: | 293 case Sensor.TYPE_GAME_ROTATION_VECTOR: |
299 if (mDeviceOrientationIsActive) { | 294 if (mDeviceOrientationIsActive) { |
300 convertRotationVectorToAngles(values, mRotationAngles); | 295 convertRotationVectorToAngles(values, mRotationAngles); |
301 gotOrientation(mRotationAngles[0], mRotationAngles[1], mRota tionAngles[2]); | 296 gotOrientation(mRotationAngles[0], mRotationAngles[1], mRota tionAngles[2]); |
302 } | 297 } |
303 break; | 298 break; |
304 case Sensor.TYPE_MAGNETIC_FIELD: | 299 case Sensor.TYPE_MAGNETIC_FIELD: |
305 if (mDeviceOrientationIsActiveWithBackupSensors) { | 300 if (mDeviceOrientationIsActiveWithBackupSensors) { |
306 if (mMagneticFieldVector == null) { | 301 if (mMagneticFieldVector == null) { |
307 mMagneticFieldVector = new float[3]; | 302 mMagneticFieldVector = new float[3]; |
308 } | 303 } |
309 System.arraycopy(values, 0, mMagneticFieldVector, 0, | 304 System.arraycopy( |
310 mMagneticFieldVector.length); | 305 values, 0, mMagneticFieldVector, 0, mMagneticFieldVe ctor.length); |
311 } | 306 } |
312 break; | 307 break; |
313 case Sensor.TYPE_LIGHT: | 308 case Sensor.TYPE_LIGHT: |
314 if (mDeviceLightIsActive) { | 309 if (mDeviceLightIsActive) { |
315 gotLight(values[0]); | 310 gotLight(values[0]); |
316 } | 311 } |
317 break; | 312 break; |
318 default: | 313 default: |
319 // Unexpected | 314 // Unexpected |
320 return; | 315 return; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 float[] matrixR, double[] values) { | 358 float[] matrixR, double[] values) { |
364 /* | 359 /* |
365 * 3x3 (length=9) case: | 360 * 3x3 (length=9) case: |
366 * / R[ 0] R[ 1] R[ 2] \ | 361 * / R[ 0] R[ 1] R[ 2] \ |
367 * | R[ 3] R[ 4] R[ 5] | | 362 * | R[ 3] R[ 4] R[ 5] | |
368 * \ R[ 6] R[ 7] R[ 8] / | 363 * \ R[ 6] R[ 7] R[ 8] / |
369 * | 364 * |
370 */ | 365 */ |
371 if (matrixR.length != 9) return values; | 366 if (matrixR.length != 9) return values; |
372 | 367 |
373 if (matrixR[8] > 0) { // cos(beta) > 0 | 368 if (matrixR[8] > 0) { // cos(beta) > 0 |
374 values[0] = Math.atan2(-matrixR[1], matrixR[4]); | 369 values[0] = Math.atan2(-matrixR[1], matrixR[4]); |
375 values[1] = Math.asin(matrixR[7]); // beta (-pi/2, p i/2) | 370 values[1] = Math.asin(matrixR[7]); // beta (-pi/2, pi/2) |
timvolodine
2017/01/26 14:01:15
the alignment here was actually done on purpose fo
ke.he
2017/01/26 15:33:22
The format is changed by "git cl format", I'll kee
| |
376 values[2] = Math.atan2(-matrixR[6], matrixR[8]); // gamma (-pi/2, pi/2) | 371 values[2] = Math.atan2(-matrixR[6], matrixR[8]); // gamma (-pi/2, pi /2) |
377 } else if (matrixR[8] < 0) { // cos(beta) < 0 | 372 } else if (matrixR[8] < 0) { // cos(beta) < 0 |
378 values[0] = Math.atan2(matrixR[1], -matrixR[4]); | 373 values[0] = Math.atan2(matrixR[1], -matrixR[4]); |
379 values[1] = -Math.asin(matrixR[7]); | 374 values[1] = -Math.asin(matrixR[7]); |
380 values[1] += (values[1] >= 0) ? -Math.PI : Math.PI; // beta [-pi,-pi /2) U (pi/2,pi) | 375 values[1] += (values[1] >= 0) ? -Math.PI : Math.PI; // beta [-pi,-pi /2) U (pi/2,pi) |
381 values[2] = Math.atan2(matrixR[6], -matrixR[8]); // gamma (-pi/2, pi/2) | 376 values[2] = Math.atan2(matrixR[6], -matrixR[8]); // gamma (-pi/2, pi /2) |
382 } else { // R[8] == 0 | 377 } else { // R[8] == 0 |
383 if (matrixR[6] > 0) { // cos(gamma) == 0, cos(beta) > 0 | 378 if (matrixR[6] > 0) { // cos(gamma) == 0, cos(beta) > 0 |
384 values[0] = Math.atan2(-matrixR[1], matrixR[4]); | 379 values[0] = Math.atan2(-matrixR[1], matrixR[4]); |
385 values[1] = Math.asin(matrixR[7]); // beta [-pi/2, pi/2] | 380 values[1] = Math.asin(matrixR[7]); // beta [-pi/2, pi/2] |
386 values[2] = -Math.PI / 2; // gamma = -pi/2 | 381 values[2] = -Math.PI / 2; // gamma = -pi/2 |
387 } else if (matrixR[6] < 0) { // cos(gamma) == 0, cos(beta) < 0 | 382 } else if (matrixR[6] < 0) { // cos(gamma) == 0, cos(beta) < 0 |
388 values[0] = Math.atan2(matrixR[1], -matrixR[4]); | 383 values[0] = Math.atan2(matrixR[1], -matrixR[4]); |
389 values[1] = -Math.asin(matrixR[7]); | 384 values[1] = -Math.asin(matrixR[7]); |
390 values[1] += (values[1] >= 0) ? -Math.PI : Math.PI; // beta [-pi ,-pi/2) U (pi/2,pi) | 385 values[1] += (values[1] >= 0) ? -Math.PI : Math.PI; // beta [-pi ,-pi/2) U (pi/2,pi) |
391 values[2] = -Math.PI / 2; // gamma = - pi/2 | 386 values[2] = -Math.PI / 2; // gamma = -pi/2 |
392 } else { // R[6] == 0, cos(beta) == 0 | 387 } else { // R[6] == 0, cos(beta) == 0 |
393 // gimbal lock discontinuity | 388 // gimbal lock discontinuity |
394 values[0] = Math.atan2(matrixR[3], matrixR[0]); | 389 values[0] = Math.atan2(matrixR[3], matrixR[0]); |
395 values[1] = (matrixR[7] > 0) ? Math.PI / 2 : -Math.PI / 2; // b eta = +-pi/2 | 390 values[1] = (matrixR[7] > 0) ? Math.PI / 2 : -Math.PI / 2; // be ta = +-pi/2 |
396 values[2] = 0; // g amma = 0 | 391 values[2] = 0; // gamma = 0 |
397 } | 392 } |
398 } | 393 } |
399 | 394 |
400 // alpha is in [-pi, pi], make sure it is in [0, 2*pi). | 395 // alpha is in [-pi, pi], make sure it is in [0, 2*pi). |
401 if (values[0] < 0) { | 396 if (values[0] < 0) { |
402 values[0] += 2 * Math.PI; // alpha [0, 2*pi) | 397 values[0] += 2 * Math.PI; // alpha [0, 2*pi) |
403 } | 398 } |
404 | 399 |
405 return values; | 400 return values; |
406 } | 401 } |
407 | 402 |
408 /* | 403 /* |
409 * Converts a given rotation vector to its Euler angles representation. The angles | 404 * Converts a given rotation vector to its Euler angles representation. The angles |
410 * are in degrees. | 405 * are in degrees. |
411 */ | 406 */ |
412 public void convertRotationVectorToAngles(float[] rotationVector, double[] a ngles) { | 407 public void convertRotationVectorToAngles(float[] rotationVector, double[] a ngles) { |
413 if (rotationVector.length > 4) { | 408 if (rotationVector.length > 4) { |
414 // On some Samsung devices SensorManager.getRotationMatrixFromVector | 409 // On some Samsung devices SensorManager.getRotationMatrixFromVector |
415 // appears to throw an exception if rotation vector has length > 4. | 410 // appears to throw an exception if rotation vector has length > 4. |
416 // For the purposes of this class the first 4 values of the | 411 // For the purposes of this class the first 4 values of the |
417 // rotation vector are sufficient (see crbug.com/335298 for details) . | 412 // rotation vector are sufficient (see crbug.com/335298 for details) . |
418 System.arraycopy(rotationVector, 0, mTruncatedRotationVector, 0, 4); | 413 System.arraycopy(rotationVector, 0, mTruncatedRotationVector, 0, 4); |
419 SensorManager.getRotationMatrixFromVector(mDeviceRotationMatrix, | 414 SensorManager.getRotationMatrixFromVector( |
420 mTruncatedRotationVector); | 415 mDeviceRotationMatrix, mTruncatedRotationVector); |
421 } else { | 416 } else { |
422 SensorManager.getRotationMatrixFromVector(mDeviceRotationMatrix, rot ationVector); | 417 SensorManager.getRotationMatrixFromVector(mDeviceRotationMatrix, rot ationVector); |
423 } | 418 } |
424 computeDeviceOrientationFromRotationMatrix(mDeviceRotationMatrix, angles ); | 419 computeDeviceOrientationFromRotationMatrix(mDeviceRotationMatrix, angles ); |
425 for (int i = 0; i < 3; i++) { | 420 for (int i = 0; i < 3; i++) { |
426 angles[i] = Math.toDegrees(angles[i]); | 421 angles[i] = Math.toDegrees(angles[i]); |
427 } | 422 } |
428 } | 423 } |
429 | 424 |
430 private void getOrientationFromGeomagneticVectors(float[] acceleration, floa t[] magnetic) { | 425 private void getOrientationFromGeomagneticVectors(float[] acceleration, floa t[] magnetic) { |
431 if (acceleration == null || magnetic == null) { | 426 if (acceleration == null || magnetic == null) { |
432 return; | 427 return; |
433 } | 428 } |
434 if (!SensorManager.getRotationMatrix(mDeviceRotationMatrix, null, accele ration, magnetic)) { | 429 if (!SensorManager.getRotationMatrix(mDeviceRotationMatrix, null, accele ration, magnetic)) { |
435 return; | 430 return; |
436 } | 431 } |
437 computeDeviceOrientationFromRotationMatrix(mDeviceRotationMatrix, mRotat ionAngles); | 432 computeDeviceOrientationFromRotationMatrix(mDeviceRotationMatrix, mRotat ionAngles); |
438 | 433 |
439 gotOrientation(Math.toDegrees(mRotationAngles[0]), | 434 gotOrientation(Math.toDegrees(mRotationAngles[0]), Math.toDegrees(mRotat ionAngles[1]), |
440 Math.toDegrees(mRotationAngles[1]), | 435 Math.toDegrees(mRotationAngles[2])); |
441 Math.toDegrees(mRotationAngles[2])); | |
442 } | 436 } |
443 | 437 |
444 private SensorManagerProxy getSensorManagerProxy() { | 438 private SensorManagerProxy getSensorManagerProxy() { |
445 if (mSensorManagerProxy != null) { | 439 if (mSensorManagerProxy != null) { |
446 return mSensorManagerProxy; | 440 return mSensorManagerProxy; |
447 } | 441 } |
448 | 442 |
449 ThreadUtils.assertOnUiThread(); | 443 ThreadUtils.assertOnUiThread(); |
450 SensorManager sensorManager = | 444 SensorManager sensorManager = |
451 (SensorManager) mAppContext.getSystemService(Context.SENSOR_SERV ICE); | 445 (SensorManager) mAppContext.getSystemService(Context.SENSOR_SERV ICE); |
452 | 446 |
453 if (sensorManager != null) { | 447 if (sensorManager != null) { |
454 mSensorManagerProxy = new SensorManagerProxyImpl(sensorManager); | 448 mSensorManagerProxy = new SensorManagerProxyImpl(sensorManager); |
455 } | 449 } |
456 return mSensorManagerProxy; | 450 return mSensorManagerProxy; |
457 } | 451 } |
458 | 452 |
459 @VisibleForTesting | 453 @VisibleForTesting |
460 void setSensorManagerProxy(SensorManagerProxy sensorManagerProxy) { | 454 public void setSensorManagerProxy(SensorManagerProxy sensorManagerProxy) { |
461 mSensorManagerProxy = sensorManagerProxy; | 455 mSensorManagerProxy = sensorManagerProxy; |
462 } | 456 } |
463 | 457 |
464 private void setEventTypeActive(int eventType, boolean active) { | 458 private void setEventTypeActive(int eventType, boolean active) { |
465 switch (eventType) { | 459 switch (eventType) { |
466 case ConsumerType.ORIENTATION: | 460 case ConsumerType.ORIENTATION: |
467 mDeviceOrientationIsActive = active; | 461 mDeviceOrientationIsActive = active; |
468 mDeviceOrientationIsActiveWithBackupSensors = active | 462 mDeviceOrientationIsActiveWithBackupSensors = |
469 && (mDeviceOrientationSensors == DEVICE_ORIENTATION_SENS ORS_C); | 463 active && (mDeviceOrientationSensors == DEVICE_ORIENTATI ON_SENSORS_C); |
470 return; | 464 return; |
471 case ConsumerType.ORIENTATION_ABSOLUTE: | 465 case ConsumerType.ORIENTATION_ABSOLUTE: |
472 mDeviceOrientationAbsoluteIsActive = active; | 466 mDeviceOrientationAbsoluteIsActive = active; |
473 return; | 467 return; |
474 case ConsumerType.MOTION: | 468 case ConsumerType.MOTION: |
475 mDeviceMotionIsActive = active; | 469 mDeviceMotionIsActive = active; |
476 return; | 470 return; |
477 case ConsumerType.LIGHT: | 471 case ConsumerType.LIGHT: |
478 mDeviceLightIsActive = active; | 472 mDeviceLightIsActive = active; |
479 return; | 473 return; |
(...skipping 12 matching lines...) Expand all Loading... | |
492 } | 486 } |
493 } | 487 } |
494 | 488 |
495 /** | 489 /** |
496 * @param sensorTypes List of sensors to activate. | 490 * @param sensorTypes List of sensors to activate. |
497 * @param rateInMicroseconds Intended delay (in microseconds) between sensor readings. | 491 * @param rateInMicroseconds Intended delay (in microseconds) between sensor readings. |
498 * @param failOnMissingSensor If true the method returns true only if all se nsors could be | 492 * @param failOnMissingSensor If true the method returns true only if all se nsors could be |
499 * activated. When false the method return true i f at least one | 493 * activated. When false the method return true i f at least one |
500 * sensor in sensorTypes could be activated. | 494 * sensor in sensorTypes could be activated. |
501 */ | 495 */ |
502 private boolean registerSensors(Set<Integer> sensorTypes, int rateInMicrosec onds, | 496 private boolean registerSensors( |
503 boolean failOnMissingSensor) { | 497 Set<Integer> sensorTypes, int rateInMicroseconds, boolean failOnMiss ingSensor) { |
504 Set<Integer> sensorsToActivate = new HashSet<Integer>(sensorTypes); | 498 Set<Integer> sensorsToActivate = new HashSet<Integer>(sensorTypes); |
505 sensorsToActivate.removeAll(mActiveSensors); | 499 sensorsToActivate.removeAll(mActiveSensors); |
506 if (sensorsToActivate.isEmpty()) return true; | 500 if (sensorsToActivate.isEmpty()) return true; |
507 | 501 |
508 boolean success = false; | 502 boolean success = false; |
509 for (Integer sensorType : sensorsToActivate) { | 503 for (Integer sensorType : sensorsToActivate) { |
510 boolean result = registerForSensorType(sensorType, rateInMicrosecond s); | 504 boolean result = registerForSensorType(sensorType, rateInMicrosecond s); |
511 if (!result && failOnMissingSensor) { | 505 if (!result && failOnMissingSensor) { |
512 // restore the previous state upon failure | 506 // restore the previous state upon failure |
513 unregisterSensors(sensorsToActivate); | 507 unregisterSensors(sensorsToActivate); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 } | 581 } |
588 | 582 |
589 private Handler getHandler() { | 583 private Handler getHandler() { |
590 // TODO(timvolodine): Remove the mHandlerLock when sure that getHandler is not called | 584 // TODO(timvolodine): Remove the mHandlerLock when sure that getHandler is not called |
591 // from multiple threads. This will be the case when device motion and d evice orientation | 585 // from multiple threads. This will be the case when device motion and d evice orientation |
592 // use the same polling thread (also see crbug/234282). | 586 // use the same polling thread (also see crbug/234282). |
593 synchronized (mHandlerLock) { | 587 synchronized (mHandlerLock) { |
594 if (mHandler == null) { | 588 if (mHandler == null) { |
595 HandlerThread thread = new HandlerThread("DeviceMotionAndOrienta tion"); | 589 HandlerThread thread = new HandlerThread("DeviceMotionAndOrienta tion"); |
596 thread.start(); | 590 thread.start(); |
597 mHandler = new Handler(thread.getLooper()); // blocks on thread start | 591 mHandler = new Handler(thread.getLooper()); // blocks on thread start |
598 } | 592 } |
599 return mHandler; | 593 return mHandler; |
600 } | 594 } |
601 } | 595 } |
602 | 596 |
603 @CalledByNative | 597 @CalledByNative |
604 static DeviceSensors getInstance(Context appContext) { | 598 static DeviceSensors getInstance(Context appContext) { |
605 synchronized (sSingletonLock) { | 599 synchronized (sSingletonLock) { |
606 if (sSingleton == null) { | 600 if (sSingleton == null) { |
607 sSingleton = new DeviceSensors(appContext); | 601 sSingleton = new DeviceSensors(appContext); |
608 } | 602 } |
609 return sSingleton; | 603 return sSingleton; |
610 } | 604 } |
611 } | 605 } |
612 | 606 |
613 /** | 607 /** |
614 * Native JNI calls, | 608 * Native JNI calls, |
615 * see content/browser/device_sensors/sensor_manager_android.cc | 609 * see device/sensors/sensor_manager_android.cc |
616 */ | 610 */ |
617 | 611 |
618 /** | 612 /** |
619 * Orientation of the device with respect to its reference frame. | 613 * Orientation of the device with respect to its reference frame. |
620 */ | 614 */ |
621 private native void nativeGotOrientation( | 615 private native void nativeGotOrientation( |
622 long nativeSensorManagerAndroid, | 616 long nativeSensorManagerAndroid, double alpha, double beta, double g amma); |
623 double alpha, double beta, double gamma); | |
624 | 617 |
625 /** | 618 /** |
626 * Absolute orientation of the device with respect to its reference frame. | 619 * Absolute orientation of the device with respect to its reference frame. |
627 */ | 620 */ |
628 private native void nativeGotOrientationAbsolute( | 621 private native void nativeGotOrientationAbsolute( |
629 long nativeSensorManagerAndroid, | 622 long nativeSensorManagerAndroid, double alpha, double beta, double g amma); |
630 double alpha, double beta, double gamma); | |
631 | 623 |
632 /** | 624 /** |
633 * Linear acceleration without gravity of the device with respect to its bod y frame. | 625 * Linear acceleration without gravity of the device with respect to its bod y frame. |
634 */ | 626 */ |
635 private native void nativeGotAcceleration( | 627 private native void nativeGotAcceleration( |
636 long nativeSensorManagerAndroid, | 628 long nativeSensorManagerAndroid, double x, double y, double z); |
637 double x, double y, double z); | |
638 | 629 |
639 /** | 630 /** |
640 * Acceleration including gravity of the device with respect to its body fra me. | 631 * Acceleration including gravity of the device with respect to its body fra me. |
641 */ | 632 */ |
642 private native void nativeGotAccelerationIncludingGravity( | 633 private native void nativeGotAccelerationIncludingGravity( |
643 long nativeSensorManagerAndroid, | 634 long nativeSensorManagerAndroid, double x, double y, double z); |
644 double x, double y, double z); | |
645 | 635 |
646 /** | 636 /** |
647 * Rotation rate of the device with respect to its body frame. | 637 * Rotation rate of the device with respect to its body frame. |
648 */ | 638 */ |
649 private native void nativeGotRotationRate( | 639 private native void nativeGotRotationRate( |
650 long nativeSensorManagerAndroid, | 640 long nativeSensorManagerAndroid, double alpha, double beta, double g amma); |
651 double alpha, double beta, double gamma); | |
652 | 641 |
653 /** | 642 /** |
654 * Device Light value from Ambient Light sensors. | 643 * Device Light value from Ambient Light sensors. |
655 */ | 644 */ |
656 private native void nativeGotLight( | 645 private native void nativeGotLight(long nativeSensorManagerAndroid, double v alue); |
657 long nativeSensorManagerAndroid, | |
658 double value); | |
659 | 646 |
660 /** | 647 /** |
661 * Need the an interface for SensorManager for testing. | 648 * Need the an interface for SensorManager for testing. |
662 */ | 649 */ |
663 interface SensorManagerProxy { | 650 public interface SensorManagerProxy { |
664 public boolean registerListener(SensorEventListener listener, int sensor Type, int rate, | 651 public boolean registerListener( |
665 Handler handler); | 652 SensorEventListener listener, int sensorType, int rate, Handler handler); |
666 public void unregisterListener(SensorEventListener listener, int sensorT ype); | 653 public void unregisterListener(SensorEventListener listener, int sensorT ype); |
667 } | 654 } |
668 | 655 |
669 static class SensorManagerProxyImpl implements SensorManagerProxy { | 656 static class SensorManagerProxyImpl implements SensorManagerProxy { |
670 private final SensorManager mSensorManager; | 657 private final SensorManager mSensorManager; |
671 | 658 |
672 SensorManagerProxyImpl(SensorManager sensorManager) { | 659 SensorManagerProxyImpl(SensorManager sensorManager) { |
673 mSensorManager = sensorManager; | 660 mSensorManager = sensorManager; |
674 } | 661 } |
675 | 662 |
676 @Override | 663 @Override |
677 public boolean registerListener(SensorEventListener listener, int sensor Type, int rate, | 664 public boolean registerListener( |
678 Handler handler) { | 665 SensorEventListener listener, int sensorType, int rate, Handler handler) { |
679 List<Sensor> sensors = mSensorManager.getSensorList(sensorType); | 666 List<Sensor> sensors = mSensorManager.getSensorList(sensorType); |
680 if (sensors.isEmpty()) { | 667 if (sensors.isEmpty()) { |
681 return false; | 668 return false; |
682 } | 669 } |
683 return mSensorManager.registerListener(listener, sensors.get(0), rat e, handler); | 670 return mSensorManager.registerListener(listener, sensors.get(0), rat e, handler); |
684 } | 671 } |
685 | 672 |
686 @Override | 673 @Override |
687 public void unregisterListener(SensorEventListener listener, int sensorT ype) { | 674 public void unregisterListener(SensorEventListener listener, int sensorT ype) { |
688 List<Sensor> sensors = mSensorManager.getSensorList(sensorType); | 675 List<Sensor> sensors = mSensorManager.getSensorList(sensorType); |
689 if (sensors.isEmpty()) { | 676 if (sensors.isEmpty()) { |
690 return; | 677 return; |
691 } | 678 } |
692 try { | 679 try { |
693 mSensorManager.unregisterListener(listener, sensors.get(0)); | 680 mSensorManager.unregisterListener(listener, sensors.get(0)); |
694 } catch (IllegalArgumentException e) { | 681 } catch (IllegalArgumentException e) { |
695 // Suppress occasional exception on Digma iDxD* devices: | 682 // Suppress occasional exception on Digma iDxD* devices: |
696 // Receiver not registered: android.hardware.SystemSensorManager $1 | 683 // Receiver not registered: android.hardware.SystemSensorManager $1 |
697 // See crbug.com/596453. | 684 // See crbug.com/596453. |
698 Log.w(TAG, "Failed to unregister device sensor " + sensors.get(0 ).getName()); | 685 Log.w(TAG, "Failed to unregister device sensor " + sensors.get(0 ).getName()); |
699 } | 686 } |
700 } | 687 } |
701 } | 688 } |
702 | |
703 } | 689 } |
OLD | NEW |