| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.device.sensors; | 5 package org.chromium.device.sensors; |
| 6 | 6 |
| 7 import static org.junit.Assert.assertEquals; | 7 import static org.junit.Assert.assertEquals; |
| 8 import static org.junit.Assert.assertNotNull; | 8 import static org.junit.Assert.assertNotNull; |
| 9 import static org.junit.Assert.assertNull; | 9 import static org.junit.Assert.assertNull; |
| 10 import static org.mockito.ArgumentMatchers.any; | 10 import static org.mockito.ArgumentMatchers.any; |
| 11 import static org.mockito.ArgumentMatchers.anyInt; | 11 import static org.mockito.ArgumentMatchers.anyInt; |
| 12 import static org.mockito.Mockito.doAnswer; | 12 import static org.mockito.Mockito.doAnswer; |
| 13 import static org.mockito.Mockito.doReturn; | 13 import static org.mockito.Mockito.doReturn; |
| 14 import static org.mockito.Mockito.mock; | 14 import static org.mockito.Mockito.mock; |
| 15 import static org.mockito.Mockito.never; | |
| 16 import static org.mockito.Mockito.spy; | 15 import static org.mockito.Mockito.spy; |
| 17 import static org.mockito.Mockito.times; | 16 import static org.mockito.Mockito.times; |
| 18 import static org.mockito.Mockito.verify; | 17 import static org.mockito.Mockito.verify; |
| 19 | 18 |
| 20 import android.content.Context; | 19 import android.content.Context; |
| 21 import android.hardware.Sensor; | 20 import android.hardware.Sensor; |
| 22 import android.hardware.SensorEvent; | 21 import android.hardware.SensorEvent; |
| 23 import android.hardware.SensorEventListener; | 22 import android.hardware.SensorEventListener; |
| 24 import android.hardware.SensorManager; | 23 import android.hardware.SensorManager; |
| 25 import android.os.Handler; | 24 import android.os.Handler; |
| 26 import android.util.SparseArray; | 25 import android.util.SparseArray; |
| 27 | 26 |
| 28 import org.chromium.base.test.util.Feature; | 27 import org.chromium.base.test.util.Feature; |
| 29 import org.chromium.device.mojom.ReportingMode; | 28 import org.chromium.device.mojom.ReportingMode; |
| 30 import org.chromium.device.mojom.SensorInitParams; | |
| 31 import org.chromium.device.mojom.SensorType; | 29 import org.chromium.device.mojom.SensorType; |
| 32 import org.chromium.testing.local.LocalRobolectricTestRunner; | 30 import org.chromium.testing.local.LocalRobolectricTestRunner; |
| 33 | 31 |
| 34 import org.junit.Before; | 32 import org.junit.Before; |
| 35 import org.junit.Test; | 33 import org.junit.Test; |
| 36 import org.junit.runner.RunWith; | 34 import org.junit.runner.RunWith; |
| 37 import org.mockito.Mock; | 35 import org.mockito.Mock; |
| 38 import org.mockito.MockitoAnnotations; | 36 import org.mockito.MockitoAnnotations; |
| 39 import org.mockito.invocation.InvocationOnMock; | 37 import org.mockito.invocation.InvocationOnMock; |
| 40 import org.mockito.stubbing.Answer; | 38 import org.mockito.stubbing.Answer; |
| 41 import org.robolectric.annotation.Config; | 39 import org.robolectric.annotation.Config; |
| 42 | 40 |
| 43 import java.lang.reflect.Constructor; | 41 import java.lang.reflect.Constructor; |
| 44 import java.lang.reflect.InvocationTargetException; | 42 import java.lang.reflect.InvocationTargetException; |
| 45 import java.nio.ByteBuffer; | |
| 46 import java.nio.ByteOrder; | |
| 47 import java.util.ArrayList; | 43 import java.util.ArrayList; |
| 48 import java.util.List; | 44 import java.util.List; |
| 49 | 45 |
| 50 /** | 46 /** |
| 51 * Unit tests for PlatformSensor and PlatformSensorProvider. | 47 * Unit tests for PlatformSensor and PlatformSensorProvider. |
| 52 */ | 48 */ |
| 53 @RunWith(LocalRobolectricTestRunner.class) | 49 @RunWith(LocalRobolectricTestRunner.class) |
| 54 @Config(manifest = Config.NONE) | 50 @Config(manifest = Config.NONE) |
| 55 public class PlatformSensorAndProviderTest { | 51 public class PlatformSensorAndProviderTest { |
| 56 @Mock | 52 @Mock |
| 57 private Context mContext; | 53 private Context mContext; |
| 58 @Mock | 54 @Mock |
| 59 private SensorManager mSensorManager; | 55 private SensorManager mSensorManager; |
| 60 @Mock | 56 @Mock |
| 61 private PlatformSensorProvider mPlatformSensorProvider; | 57 private PlatformSensorProvider mPlatformSensorProvider; |
| 62 private ByteBuffer mSharedBuffer; | |
| 63 private final SparseArray<List<Sensor>> mMockSensors = new SparseArray<>(); | 58 private final SparseArray<List<Sensor>> mMockSensors = new SparseArray<>(); |
| 64 private static final long PLATFORM_SENSOR_ANDROID = 123456789L; | 59 private static final long PLATFORM_SENSOR_ANDROID = 123456789L; |
| 65 private static final long PLATFORM_SENSOR_TIMESTAMP = 314159265358979L; | 60 private static final long PLATFORM_SENSOR_TIMESTAMP = 314159265358979L; |
| 66 private static final double MILLISECONDS_IN_NANOSECOND = 0.000001d; | 61 private static final double SECONDS_IN_NANOSECOND = 0.000000001d; |
| 67 | 62 |
| 68 /** | 63 /** |
| 69 * Class that overrides thread management callbacks for testing purposes. | 64 * Class that overrides thread management callbacks for testing purposes. |
| 70 */ | 65 */ |
| 71 private static class TestPlatformSensorProvider extends PlatformSensorProvid
er { | 66 private static class TestPlatformSensorProvider extends PlatformSensorProvid
er { |
| 72 public TestPlatformSensorProvider(Context context) { | 67 public TestPlatformSensorProvider(Context context) { |
| 73 super(context); | 68 super(context); |
| 74 } | 69 } |
| 75 | 70 |
| 76 @Override | 71 @Override |
| (...skipping 11 matching lines...) Expand all Loading... |
| 88 /** | 83 /** |
| 89 * Class that overrides native callbacks for testing purposes. | 84 * Class that overrides native callbacks for testing purposes. |
| 90 */ | 85 */ |
| 91 private static class TestPlatformSensor extends PlatformSensor { | 86 private static class TestPlatformSensor extends PlatformSensor { |
| 92 public TestPlatformSensor( | 87 public TestPlatformSensor( |
| 93 Sensor sensor, int readingCount, PlatformSensorProvider provider
) { | 88 Sensor sensor, int readingCount, PlatformSensorProvider provider
) { |
| 94 super(sensor, readingCount, provider); | 89 super(sensor, readingCount, provider); |
| 95 } | 90 } |
| 96 | 91 |
| 97 @Override | 92 @Override |
| 98 protected void sensorReadingChanged() {} | 93 protected void updateSensorReading( |
| 94 double timestamp, double value1, double value2, double value3) {
} |
| 99 @Override | 95 @Override |
| 100 protected void sensorError() {} | 96 protected void sensorError() {} |
| 101 } | 97 } |
| 102 | 98 |
| 103 @Before | 99 @Before |
| 104 public void setUp() { | 100 public void setUp() { |
| 105 MockitoAnnotations.initMocks(this); | 101 MockitoAnnotations.initMocks(this); |
| 106 // Remove all mock sensors before the test. | 102 // Remove all mock sensors before the test. |
| 107 mMockSensors.clear(); | 103 mMockSensors.clear(); |
| 108 doReturn(mSensorManager).when(mContext).getSystemService(Context.SENSOR_
SERVICE); | 104 doReturn(mSensorManager).when(mContext).getSystemService(Context.SENSOR_
SERVICE); |
| 109 doAnswer( | 105 doAnswer(new Answer<List<Sensor>>() { |
| 110 new Answer<List<Sensor>>() { | 106 @Override |
| 111 @Override | 107 public List<Sensor> answer(final InvocationOnMock invocation) throws
Throwable { |
| 112 public List<Sensor> answer(final InvocationOnMock invocation
) | 108 return getMockSensors((int) (Integer) (invocation.getArguments()
)[0]); |
| 113 throws Throwable { | 109 } |
| 114 return getMockSensors((int) (Integer) (invocation.getArg
uments())[0]); | 110 }) |
| 115 } | |
| 116 }) | |
| 117 .when(mSensorManager) | 111 .when(mSensorManager) |
| 118 .getSensorList(anyInt()); | 112 .getSensorList(anyInt()); |
| 119 doReturn(mSensorManager).when(mPlatformSensorProvider).getSensorManager(
); | 113 doReturn(mSensorManager).when(mPlatformSensorProvider).getSensorManager(
); |
| 120 doReturn(new Handler()).when(mPlatformSensorProvider).getHandler(); | 114 doReturn(new Handler()).when(mPlatformSensorProvider).getHandler(); |
| 121 // By default, allow successful registration of SensorEventListeners. | 115 // By default, allow successful registration of SensorEventListeners. |
| 122 doReturn(true) | 116 doReturn(true) |
| 123 .when(mSensorManager) | 117 .when(mSensorManager) |
| 124 .registerListener(any(SensorEventListener.class), any(Sensor.cla
ss), anyInt(), | 118 .registerListener(any(SensorEventListener.class), any(Sensor.cla
ss), anyInt(), |
| 125 any(Handler.class)); | 119 any(Handler.class)); |
| 126 } | 120 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 */ | 250 */ |
| 257 @Test | 251 @Test |
| 258 @Feature({"PlatformSensor"}) | 252 @Feature({"PlatformSensor"}) |
| 259 public void testSensorOnChangeReportingMode() { | 253 public void testSensorOnChangeReportingMode() { |
| 260 PlatformSensor sensor = createPlatformSensor(50000, Sensor.TYPE_LIGHT, | 254 PlatformSensor sensor = createPlatformSensor(50000, Sensor.TYPE_LIGHT, |
| 261 SensorType.AMBIENT_LIGHT, Sensor.REPORTING_MODE_ON_CHANGE); | 255 SensorType.AMBIENT_LIGHT, Sensor.REPORTING_MODE_ON_CHANGE); |
| 262 assertEquals(ReportingMode.ON_CHANGE, sensor.getReportingMode()); | 256 assertEquals(ReportingMode.ON_CHANGE, sensor.getReportingMode()); |
| 263 } | 257 } |
| 264 | 258 |
| 265 /** | 259 /** |
| 266 * Test that PlatformSensor doesn't notify client about sensor reading chang
es when | |
| 267 * sensor reporting mode is ReportingMode.CONTINUOUS. | |
| 268 */ | |
| 269 @Test | |
| 270 @Feature({"PlatformSensor"}) | |
| 271 public void testSensorNotifierIsNotCalled() { | |
| 272 TestPlatformSensor sensor = createTestPlatformSensor( | |
| 273 50000, Sensor.TYPE_ACCELEROMETER, 3, Sensor.REPORTING_MODE_CONTI
NUOUS); | |
| 274 initPlatformSensor(sensor, SensorInitParams.READ_BUFFER_SIZE); | |
| 275 TestPlatformSensor spySensor = spy(sensor); | |
| 276 SensorEvent event = createFakeEvent(3); | |
| 277 assertNotNull(event); | |
| 278 spySensor.onSensorChanged(event); | |
| 279 verify(spySensor, never()).sensorReadingChanged(); | |
| 280 } | |
| 281 | |
| 282 /** | |
| 283 * Test that shared buffer is correctly populated from SensorEvent. | 260 * Test that shared buffer is correctly populated from SensorEvent. |
| 284 */ | 261 */ |
| 285 @Test | 262 @Test |
| 286 @Feature({"PlatformSensor"}) | 263 @Feature({"PlatformSensor"}) |
| 287 public void testSensorBufferFromEvent() { | 264 public void testSensorReadingFromEvent() { |
| 288 TestPlatformSensor sensor = createTestPlatformSensor( | 265 TestPlatformSensor sensor = createTestPlatformSensor( |
| 289 50000, Sensor.TYPE_LIGHT, 1, Sensor.REPORTING_MODE_ON_CHANGE); | 266 50000, Sensor.TYPE_LIGHT, 1, Sensor.REPORTING_MODE_ON_CHANGE); |
| 290 initPlatformSensor(sensor, SensorInitParams.READ_BUFFER_SIZE); | 267 initPlatformSensor(sensor); |
| 291 TestPlatformSensor spySensor = spy(sensor); | 268 TestPlatformSensor spySensor = spy(sensor); |
| 292 SensorEvent event = createFakeEvent(1); | 269 SensorEvent event = createFakeEvent(1); |
| 293 assertNotNull(event); | 270 assertNotNull(event); |
| 294 spySensor.onSensorChanged(event); | 271 spySensor.onSensorChanged(event); |
| 295 verify(spySensor, times(1)).sensorReadingChanged(); | 272 |
| 296 // Verify that timestamp correctly stored in buffer. | 273 double timestamp = PLATFORM_SENSOR_TIMESTAMP * SECONDS_IN_NANOSECOND; |
| 297 assertEquals(MILLISECONDS_IN_NANOSECOND * PLATFORM_SENSOR_TIMESTAMP, | 274 |
| 298 mSharedBuffer.getDouble(), MILLISECONDS_IN_NANOSECOND); | 275 verify(spySensor, times(1)) |
| 299 // Verify illuminance value is correctly stored in buffer and precision
is not lost. | 276 .updateSensorReading(timestamp, getFakeReadingValue(1), 0.0, 0.0
); |
| 300 assertEquals(1.0d + MILLISECONDS_IN_NANOSECOND, mSharedBuffer.getDouble(
), | |
| 301 MILLISECONDS_IN_NANOSECOND); | |
| 302 } | 277 } |
| 303 | 278 |
| 304 /** | 279 /** |
| 305 * Test that PlatformSensor notifies client when there is an error. | 280 * Test that PlatformSensor notifies client when there is an error. |
| 306 */ | 281 */ |
| 307 @Test | 282 @Test |
| 308 @Feature({"PlatformSensor"}) | 283 @Feature({"PlatformSensor"}) |
| 309 public void testSensorInvalidReadingSize() { | 284 public void testSensorInvalidReadingSize() { |
| 310 TestPlatformSensor sensor = createTestPlatformSensor( | 285 TestPlatformSensor sensor = createTestPlatformSensor( |
| 311 50000, Sensor.TYPE_ACCELEROMETER, 3, Sensor.REPORTING_MODE_CONTI
NUOUS); | 286 50000, Sensor.TYPE_ACCELEROMETER, 3, Sensor.REPORTING_MODE_CONTI
NUOUS); |
| 312 initPlatformSensor(sensor, SensorInitParams.READ_BUFFER_SIZE); | 287 initPlatformSensor(sensor); |
| 313 TestPlatformSensor spySensor = spy(sensor); | 288 TestPlatformSensor spySensor = spy(sensor); |
| 314 // Accelerometer requires 3 reading values x,y and z, create fake event
with 1 reading | 289 // Accelerometer requires 3 reading values x,y and z, create fake event
with 1 reading |
| 315 // value. | 290 // value. |
| 316 SensorEvent event = createFakeEvent(1); | 291 SensorEvent event = createFakeEvent(1); |
| 317 assertNotNull(event); | 292 assertNotNull(event); |
| 318 spySensor.onSensorChanged(event); | 293 spySensor.onSensorChanged(event); |
| 319 verify(spySensor, times(1)).sensorError(); | 294 verify(spySensor, times(1)).sensorError(); |
| 320 } | 295 } |
| 321 | 296 |
| 322 /** | 297 /** |
| 323 * Test that PlatformSensor notifies client when there is an error. | |
| 324 */ | |
| 325 @Test | |
| 326 @Feature({"PlatformSensor"}) | |
| 327 public void testSensorInvalidBufferSize() { | |
| 328 TestPlatformSensor sensor = createTestPlatformSensor( | |
| 329 50000, Sensor.TYPE_ACCELEROMETER, 3, Sensor.REPORTING_MODE_CONTI
NUOUS); | |
| 330 // Create buffer that doesn't have enough capacity to hold sensor readin
g values. | |
| 331 initPlatformSensor(sensor, 2); | |
| 332 TestPlatformSensor spySensor = spy(sensor); | |
| 333 SensorEvent event = createFakeEvent(3); | |
| 334 assertNotNull(event); | |
| 335 spySensor.onSensorChanged(event); | |
| 336 verify(spySensor, times(1)).sensorError(); | |
| 337 } | |
| 338 | |
| 339 /** | |
| 340 * Test that multiple PlatformSensor instances correctly register (unregiste
r) to | 298 * Test that multiple PlatformSensor instances correctly register (unregiste
r) to |
| 341 * sensor manager and notify PlatformSensorProvider when they start (stop) p
olling for data. | 299 * sensor manager and notify PlatformSensorProvider when they start (stop) p
olling for data. |
| 342 */ | 300 */ |
| 343 @Test | 301 @Test |
| 344 @Feature({"PlatformSensor"}) | 302 @Feature({"PlatformSensor"}) |
| 345 public void testMultipleSensorTypeInstances() { | 303 public void testMultipleSensorTypeInstances() { |
| 346 addMockSensor(200000, Sensor.TYPE_LIGHT, Sensor.REPORTING_MODE_ON_CHANGE
); | 304 addMockSensor(200000, Sensor.TYPE_LIGHT, Sensor.REPORTING_MODE_ON_CHANGE
); |
| 347 addMockSensor(50000, Sensor.TYPE_ACCELEROMETER, Sensor.REPORTING_MODE_CO
NTINUOUS); | 305 addMockSensor(50000, Sensor.TYPE_ACCELEROMETER, Sensor.REPORTING_MODE_CO
NTINUOUS); |
| 348 | 306 |
| 349 TestPlatformSensorProvider spyProvider = spy(new TestPlatformSensorProvi
der(mContext)); | 307 TestPlatformSensorProvider spyProvider = spy(new TestPlatformSensorProvi
der(mContext)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 379 * SensorEvent instance. | 337 * SensorEvent instance. |
| 380 */ | 338 */ |
| 381 private SensorEvent createFakeEvent(int readingValuesNum) { | 339 private SensorEvent createFakeEvent(int readingValuesNum) { |
| 382 try { | 340 try { |
| 383 Constructor<SensorEvent> sensorEventConstructor = | 341 Constructor<SensorEvent> sensorEventConstructor = |
| 384 SensorEvent.class.getDeclaredConstructor(Integer.TYPE); | 342 SensorEvent.class.getDeclaredConstructor(Integer.TYPE); |
| 385 sensorEventConstructor.setAccessible(true); | 343 sensorEventConstructor.setAccessible(true); |
| 386 SensorEvent event = sensorEventConstructor.newInstance(readingValues
Num); | 344 SensorEvent event = sensorEventConstructor.newInstance(readingValues
Num); |
| 387 event.timestamp = PLATFORM_SENSOR_TIMESTAMP; | 345 event.timestamp = PLATFORM_SENSOR_TIMESTAMP; |
| 388 for (int i = 0; i < readingValuesNum; ++i) { | 346 for (int i = 0; i < readingValuesNum; ++i) { |
| 389 event.values[i] = (float) (i + 1.0f + MILLISECONDS_IN_NANOSECOND
); | 347 event.values[i] = getFakeReadingValue(i + 1); |
| 390 } | 348 } |
| 391 return event; | 349 return event; |
| 392 } catch (InvocationTargetException | NoSuchMethodException | Instantiati
onException | 350 } catch (InvocationTargetException | NoSuchMethodException | Instantiati
onException |
| 393 | IllegalAccessException e) { | 351 | IllegalAccessException e) { |
| 394 return null; | 352 return null; |
| 395 } | 353 } |
| 396 } | 354 } |
| 397 | 355 |
| 398 private void initPlatformSensor(PlatformSensor sensor, long readingSize) { | 356 private void initPlatformSensor(PlatformSensor sensor) { |
| 399 mSharedBuffer = ByteBuffer.allocate((int) readingSize); | 357 sensor.initPlatformSensorAndroid(PLATFORM_SENSOR_ANDROID); |
| 400 mSharedBuffer.order(ByteOrder.nativeOrder()); | |
| 401 sensor.initPlatformSensorAndroid(PLATFORM_SENSOR_ANDROID, mSharedBuffer)
; | |
| 402 } | 358 } |
| 403 | 359 |
| 404 private void addMockSensor(long minDelayUsec, int sensorType, int reportingM
ode) { | 360 private void addMockSensor(long minDelayUsec, int sensorType, int reportingM
ode) { |
| 405 List<Sensor> mockSensorList = new ArrayList<Sensor>(); | 361 List<Sensor> mockSensorList = new ArrayList<Sensor>(); |
| 406 mockSensorList.add(createMockSensor(minDelayUsec, sensorType, reportingM
ode)); | 362 mockSensorList.add(createMockSensor(minDelayUsec, sensorType, reportingM
ode)); |
| 407 mMockSensors.put(sensorType, mockSensorList); | 363 mMockSensors.put(sensorType, mockSensorList); |
| 408 } | 364 } |
| 409 | 365 |
| 410 private Sensor createMockSensor(long minDelayUsec, int sensorType, int repor
tingMode) { | 366 private Sensor createMockSensor(long minDelayUsec, int sensorType, int repor
tingMode) { |
| 411 Sensor mockSensor = mock(Sensor.class); | 367 Sensor mockSensor = mock(Sensor.class); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 428 PlatformSensorProvider provider = PlatformSensorProvider.create(mContext
); | 384 PlatformSensorProvider provider = PlatformSensorProvider.create(mContext
); |
| 429 return provider.createSensor(mojoSensorType); | 385 return provider.createSensor(mojoSensorType); |
| 430 } | 386 } |
| 431 | 387 |
| 432 private TestPlatformSensor createTestPlatformSensor( | 388 private TestPlatformSensor createTestPlatformSensor( |
| 433 long minDelayUsec, int androidSensorType, int readingCount, int repo
rtingMode) { | 389 long minDelayUsec, int androidSensorType, int readingCount, int repo
rtingMode) { |
| 434 return new TestPlatformSensor( | 390 return new TestPlatformSensor( |
| 435 createMockSensor(minDelayUsec, androidSensorType, reportingMode)
, readingCount, | 391 createMockSensor(minDelayUsec, androidSensorType, reportingMode)
, readingCount, |
| 436 mPlatformSensorProvider); | 392 mPlatformSensorProvider); |
| 437 } | 393 } |
| 394 |
| 395 private float getFakeReadingValue(int valueNum) { |
| 396 return (float) (valueNum + SECONDS_IN_NANOSECOND); |
| 397 } |
| 438 } | 398 } |
| OLD | NEW |