Android CTS Verifier Sensor Test Cases (7)
2016-09-21 14:35
585 查看
6. CTS Sensor Tests
CTS Sensor Tests 会测试 HAL 上报的 SensorList 结构体中所包含的信息和对这些 sensor 进行基本的操作是否符合 Android 要求。
SensorList 结构体定义见 sensor_t 下面看两个例子:
CTS 会检查 SensorList 结构体里面各项的值是否符合 Android 定义。
具体的测试项:
1) testBatchAndFlush
2) testBatchAndFlushWithHandler
3)testBatchAndFlushWithMultipleSensors
4) testLegacySensorOperations
5) testCancelTriggerWithNonTriggerSensor, testGetDefaultSensorWithWakeUpFlag, testRegisterWithTriggerSensor, testRegisterTwiceWithSameSensor, testRequestTriggerWithNonTriggerSensor,testSensorStringTypes, 这个几个测试项一般不容易报错,如果报错,检查你的sensorList结构体内容是否按照 android 定义写的。
6) testSensorOperations
测试 Accelerometer, Step Counter, Step Detector, Heart Reate, Magnetic Field, Orientation, Temperature 是否符合 Android 定义。
有一种情况会报错,HAL少报了前面提到的几个 sensor 的某个, 而测试环境中却认为有这个 sensor。检查 HAL 的实现和测试环境的要求不一致在哪里。
7)testSensorTimeStamps
CTS Sensor Test 里最重要的,也是最容易出错的一项测试。
如果数据 Output Data Rate不稳定,某两个数据时间戳之间的 gap 大于要求,则报错:
// Number of event gaps to tolerate is 2% of total number of events received rounded up to next
// integer or 20, whichever is smaller.
private static final int EVENT_GAP_THRESHOLD_MAX = 20;
private static final double EVENT_GAP_TOLERANCE = 0.02;
EventOrderingVerification
检查 HAL 上报的数据顺序是否错乱,通过验证时间戳是否有回调。
EventTimestampSynchronizationVerication
时间戳同步验证,HAL 上报数据自带的时间戳跟系统收到数据时的时间戳之间的differ是否在规定范围内
总结:
这个测试项很容易出错,HAL/Driver 开发者需要确保
1)SensorList的准确性;
2)data quality: ODR 稳定,顺序,同步;
SensorTest.java
EventGapVerification.java
EventOrderingVerification.java
EventTimestampSynchronizationVerification.java
CTS Sensor Tests 会测试 HAL 上报的 SensorList 结构体中所包含的信息和对这些 sensor 进行基本的操作是否符合 Android 要求。
SensorList 结构体定义见 sensor_t 下面看两个例子:
/* Accelerometer SensorList Structure */ { // Sensor name name: "Accelerometer", // Vendor name vendor: "Company Name", // Sensor Version version: 1.0, // Sensor handle for HAL internal usage handle: SENSORS_ACCELERATION_HANDLE, // Sensor type for Android offical usage type: SENSOR_TYPE_ACCELEROMETER, // Maximum 4G range maxRange: 4.0f * 9.805, // Sensitivity = Range / Bitwidth resolution: 4.0f * 9.805 / 2^16, // Power consumption in mA from datasheet power: 0.1f, // Maximum Output data rate: 200Hz/5ms minDelay: 5000, // No hardware FIFO support fifoReservedEventCount: 0, // No hardware FIFO support fifoMaxEventCount: 0, // Sensor string stringType: SENSOR_STRING_TYPE_ACCELEROMETER, // no permission is required requiredPermission: "", // Minimum output data rate: 5Hz/200ms maxDelay: 200000, // report mode: continuous flags: SENSOR_FLAG_CONTINUOUS_MODE, reserved: {} }, /* Step Counter Sensor structure */ { name: "Step Counter", vendor: "Company Name", version: 1.0, handle: SENSORS_STEP_COUNTER_HANDLE, type: SENSOR_TYPE_STEP_COUNTER, maxRange: 10000.0f, resolution: 1.0f, power: 2.03f, minDelay: 0, fifoReservedEventCount: 0, fifoMaxEventCount: 0, stringType: SENSOR_STRING_TYPE_STEP_COUNTER, requiredPermission: "", maxDelay: 1000000, flags: SENSOR_FLAG_ON_CHANGE_MODE, reserved: {} },
CTS 会检查 SensorList 结构体里面各项的值是否符合 Android 定义。
private void assertSensorValues(Sensor sensor) { /* range 必须是正数 */ assertTrue("Max range must be positive. Range=" + sensor.getMaximumRange() + " " + sensor.getName(), sensor.getMaximumRange() >= 0); /* power 必须是正数 */ assertTrue("Max power must be positive. Power=" + sensor.getPower() + " " + sensor.getName(), sensor.getPower() >= 0); /* resolution 必须是正数 */ assertTrue("Max resolution must be positive. Resolution=" + sensor.getResolution() + " " + sensor.getName(), sensor.getResolution() >= 0); /* vendor name 不能个为空 */ assertNotNull("Vendor name must not be null " + sensor.getName(), sensor.getVendor()); /* Version 必须是正数 */ assertTrue("Version must be positive version=" + sensor.getVersion() + " " + sensor.getName(), sensor.getVersion() > 0); int fifoMaxEventCount = sensor.getFifoMaxEventCount(); int fifoReservedEventCount = sensor.getFifoReservedEventCount(); /* fifoMaxEventCount 和 fifoReservedEventCount 必须大于或等于0,且fifoMaxEventCount 要大于或等于fifoReservedEventCount */ assertTrue(fifoMaxEventCount >= 0); assertTrue(fifoReservedEventCount >= 0); assertTrue(fifoReservedEventCount <= fifoMaxEventCount); /* one shot类型的 sensor, fifoMaxEventCount 和 fifoReservedEventCount 都必须为0 */ if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { assertTrue("One shot sensors should have zero FIFO Size " + sensor.getName(), sensor.getFifoMaxEventCount() == 0); assertTrue("One shot sensors should have zero FIFO Size " + sensor.getName(), sensor.getFifoReservedEventCount() == 0); } }
public class SensorTest extends SensorTestCase { private static final String TAG = "SensorTest"; /* 自定义的 sensor 类型不在 SensorTest 测试范围内 */ // Test only SDK defined sensors. Any sensors with type > 100 are ignored. private static final int MAX_OFFICIAL_ANDROID_SENSOR_TYPE = 100; ... /* 检查 Acceleromter 的 type */ Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); boolean hasAccelerometer = getContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_SENSOR_ACCELEROMETER); // accelerometer sensor is optional if (hasAccelerometer) { assertEquals(Sensor.TYPE_ACCELEROMETER, sensor.getType()); assertSensorValues(sensor); } else { assertNull(sensor); } /* 检查 Step Counter, Step Detector, Heart Rate, Magnetic Field, Orientation, Temperature */ ... /* 检查 sensorlist 中所有的sensor 的结构体中的值是否合法 */ mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL); public void testValuesForAllSensors() { for (Sensor sensor : mSensorList) { assertSensorValues(sensor); e6ce } } /* 有些 sensor 只有wakeup类型 */ // Some sensors like proximity, significant motion etc. are defined as wake-up sensors by // default. Check if the wake-up flag is set correctly. public void testWakeUpFlags() { final int TYPE_WAKE_GESTURE = 23; final int TYPE_GLANCE_GESTURE = 24; final int TYPE_PICK_UP_GESTURE = 25; /* 下面这几个sensor 的 flag 必须定义成 wakeup */ hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(Sensor.TYPE_SIGNIFICANT_MOTION)); hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_WAKE_GESTURE)); hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_GLANCE_GESTURE)); hasOnlyOneWakeUpSensorOrEmpty(mSensorManager.getSensorList(TYPE_PICK_UP_GESTURE)); List<Sensor> proximity_sensors = mSensorManager.getSensorList(Sensor.TYPE_PROXIMITY); if (proximity_sensors.isEmpty()) return; boolean hasWakeUpProximitySensor = false; for (Sensor sensor : proximity_sensors) { if (sensor.isWakeUpSensor()) { hasWakeUpProximitySensor = true; break; } } assertTrue("No wake-up proximity sensors implemented", hasWakeUpProximitySensor); } /* 如果 flag 不是 wake up, 则不能是 wakeup sensor */ public void testGetDefaultSensorWithWakeUpFlag() { // With wake-up flags set to false, the sensor returned should be a non wake-up sensor. for (Sensor sensor : mSensorList) { Sensor curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), false); if (curr_sensor != null) { assertFalse("getDefaultSensor wakeup=false returns a wake-up sensor" + curr_sensor.getName(), curr_sensor.isWakeUpSensor()); } curr_sensor = mSensorManager.getDefaultSensor(sensor.getType(), true); if (curr_sensor != null) { assertTrue("getDefaultSensor wake-up returns non wake sensor" + curr_sensor.getName(), curr_sensor.isWakeUpSensor()); } } }
具体的测试项:
1) testBatchAndFlush
public void testBatchAndFlush() throws Exception { // TODO - replace this constant once method to do so is made available final int SENSOR_TYPE_DEVICE_PRIVATE_BASE = 0x10000; SensorCtsHelper.sleep(3, TimeUnit.SECONDS); ArrayList<Throwable> errorsFound = new ArrayList<>(); /* 遍历测试 SensorList 中所有的 sensor */ for (Sensor sensor : mSensorList) { if (sensor.getType() < SENSOR_TYPE_DEVICE_PRIVATE_BASE) { verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound); } } assertOnErrors(errorsFound); } ... private void verifyRegisterListenerCallFlush() throws InterruptedException { if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { /* 如果 sensor 是 one shot 类型,则不支持flush,返回成功 */ return; } ... 测试实际执行代码: /* 注册 listener,只检测 continuous 类型的 sensor: * 检测FIFO是否填充,如果规定时间内没有收到数据,assert;如果数据正常,再请求 flush;如果等待 flush complete 超时,也会assert */ if (sensorReportingMode == Sensor.REPORTING_MODE_CONTINUOUS) { listener.waitForEvents(eventLatch, mEventCount, true); } CountDownLatch flushLatch = sensorManager.requestFlush(); listener.waitForFlushComplete(flushLatch, true);
2) testBatchAndFlushWithHandler
跟1) testBatchAndFlush 不同之处是它有 hander /* 看下面代码,有 hander 就会申请一个 wakeLock,既这个测试中系统不会睡眠 */ public TestSensorEventListener(TestSensorEnvironment environment) { this(environment, null /* handler */); } public TestSensorEventListener(TestSensorEnvironment environment, Handler handler) { mEnvironment = environment; mHandler = handler; PowerManager pm = (PowerManager) environment.getContext().getSystemService( Context.POWER_SERVICE); mTestSensorEventListenerWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TestSensorEventListenerWakeLock"); }
3)testBatchAndFlushWithMultipleSensors
跟前两个比,多了个并行操作。同时测试多个 sensor 的 BatchAndFlush ParallelSensorOperation parallelSensorOperation = new ParallelSensorOperation();
4) testLegacySensorOperations
测试 Accelerometer , Magnetic Field, Orientation sensor 是否符合 Android 定义。
5) testCancelTriggerWithNonTriggerSensor, testGetDefaultSensorWithWakeUpFlag, testRegisterWithTriggerSensor, testRegisterTwiceWithSameSensor, testRequestTriggerWithNonTriggerSensor,testSensorStringTypes, 这个几个测试项一般不容易报错,如果报错,检查你的sensorList结构体内容是否按照 android 定义写的。
6) testSensorOperations
测试 Accelerometer, Step Counter, Step Detector, Heart Reate, Magnetic Field, Orientation, Temperature 是否符合 Android 定义。
有一种情况会报错,HAL少报了前面提到的几个 sensor 的某个, 而测试环境中却认为有这个 sensor。检查 HAL 的实现和测试环境的要求不一致在哪里。
7)testSensorTimeStamps
CTS Sensor Test 里最重要的,也是最容易出错的一项测试。
public void testSensorTimeStamps() throws Exception { ArrayList<Throwable> errorsFound = new ArrayList<>(); for (Sensor sensor : mSensorList) { // test both continuous and batching mode sensors verifyLongActivation(sensor, 0 /* maxReportLatencyUs */, errorsFound); verifyLongActivation(sensor, (int) TimeUnit.SECONDS.toMicros(10), errorsFound); } assertOnErrors(errorsFound); } /* 包含三项时间戳测试:数据时间间隔 EventGapVerification, 顺序 EventOrderingVerification, 同步EventTimestampSynchronizationVer*/ private void verifyLongActivation( operation.addVerification(EventGapVerification.getDefault(environment)); operation.addVerification(EventOrderingVerification.getDefault(environment)); operation.addVerification(EventTimestampSynchronizationVerification.getDefault(environment));
如果数据 Output Data Rate不稳定,某两个数据时间戳之间的 gap 大于要求,则报错:
// Number of event gaps to tolerate is 2% of total number of events received rounded up to next
// integer or 20, whichever is smaller.
private static final int EVENT_GAP_THRESHOLD_MAX = 20;
private static final double EVENT_GAP_TOLERANCE = 0.02;
EventOrderingVerification
检查 HAL 上报的数据顺序是否错乱,通过验证时间戳是否有回调。
void verify(SensorStats stats) { final int count = mOutOfOrderEvents.size(); stats.addValue(PASSED_KEY, count == 0); stats.addValue(SensorStats.EVENT_OUT_OF_ORDER_COUNT_KEY, count); stats.addValue( SensorStats.EVENT_OUT_OF_ORDER_POSITIONS_KEY, getIndexArray(mOutOfOrderEvents)); if (count > 0) { StringBuilder sb = new StringBuilder(); sb.append(count).append(" events out of order: "); for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) { IndexedEventPair info = mOutOfOrderEvents.get(i); sb.append(String.format("position=%d, previous_ts=%.2fms, current_ts=%.2fms", info.index, nanosToMillis(info.previousEvent.timestamp), nanosToMillis(info.event.timestamp))); } if (count > TRUNCATE_MESSAGE_LENGTH) { sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more"); } else { // Delete the trailing "; " sb.delete(sb.length() - 2, sb.length()); } Assert.fail(sb.toString()); } }
EventTimestampSynchronizationVerication
时间戳同步验证,HAL 上报数据自带的时间戳跟系统收到数据时的时间戳之间的differ是否在规定范围内
TestSensorEvent event = mCollectedEvents.get(i); long eventTimestampNs = event.timestamp; long receivedTimestampNs = event.receivedTimestamp; long upperThresholdNs = receivedTimestampNs; long lowerThresholdNs = receivedTimestampNs - mMaximumSynchronizationErrorNs - mExpectedSyncLatencyNs; if (eventTimestampNs < lowerThresholdNs || eventTimestampNs > upperThresholdNs) { if (failures.size() < TRUNCATE_MESSAGE_LENGTH) { builder.append("position=").append(i); builder.append(", timestamp=").append(String.format("%.2fms", nanosToMillis(eventTimestampNs))); builder.append(", expected=[").append(String.format("%.2fms", nanosToMillis(lowerThresholdNs))); builder.append(", ").append(String.format("%.2f]ms; ", nanosToMillis(upperThresholdNs))); } failures.add(new IndexedEvent(i, event)); } }
总结:
这个测试项很容易出错,HAL/Driver 开发者需要确保
1)SensorList的准确性;
2)data quality: ODR 稳定,顺序,同步;
SensorTest.java
EventGapVerification.java
EventOrderingVerification.java
EventTimestampSynchronizationVerification.java
相关文章推荐
- Android CTS Verifier Sensor Test Cases (2)
- Android CTS Verifier Sensor Test Cases (5)
- Android CTS Verifier Sensor Test Cases (3)
- Android CTS Verifier Sensor Test Cases (4)
- 【多线程问题】android8.1 cts测试原生bug多线程导致CtsJvmtiRedefineClassesHostTestCases中,testJvmti Fail
- CTS Verifier apk 测试失败Sensor Batching test failed(关于时间戳的问题)
- testBatchAndFlush(android.hardware.cts.SensorTest): WaitForFlush | sensor='PROXIMITY'
- CtsOsTestCasesTest android.os.cts.BuildVersionTest#testBuildFingerprint
- android.app.cts.SystemFeaturesTest#testCameraFeatures 测试失败
- How to add a test plan, package to Android CTS?
- Android CTS (Compatibility Test Suite) introduction
- cts-verifier Data Backup Test测试步骤
- CTS Verifier:Wi-Fi Direct Test
- 如何通过Android CTS测试—testPackageSignatures
- fails to pass the Accelerometer Test on CTS Verifier.
- How to add a test plan, package to Android CTS?
- 如何通过Android CTS测试—testPackageSignatures
- CTS: testSensorFeatures FAIL 的解决
- How to add CTS test cases