Home | History | Annotate | Download | only in sensorverification
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package android.hardware.cts.helpers.sensorverification;
     18 
     19 import junit.framework.Assert;
     20 
     21 import com.android.compatibility.common.util.ApiLevelUtil;
     22 
     23 import android.os.Build;
     24 import android.hardware.Sensor;
     25 import android.hardware.SensorEvent;
     26 import android.hardware.cts.helpers.SensorStats;
     27 import android.hardware.cts.helpers.TestSensorEnvironment;
     28 import android.hardware.cts.helpers.TestSensorEvent;
     29 import android.os.SystemClock;
     30 
     31 import java.util.concurrent.TimeUnit;
     32 
     33 /**
     34  * A {@link ISensorVerification} which verifies if the collected sensor events have any obvious
     35  * problems, such as no sample, wrong sensor type, etc.
     36  */
     37 public class EventBasicVerification extends AbstractSensorVerification {
     38 
     39     public static final String PASSED_KEY = "event_basic_passed";
     40     // allowed time from registration to sensor start sampling
     41     private static final long ALLOWED_SENSOR_START_DELAY_US =
     42             TimeUnit.MILLISECONDS.toMicros(1000);
     43 
     44     // allowed time for entire sensor system to send sample to test app
     45     private static final long ALLOWED_SENSOR_EVENT_LATENCY_US =
     46             TimeUnit.MILLISECONDS.toMicros(1000);
     47 
     48     // mercy added for recently added test. remove this mercy factor for next letter release.
     49     private final float NUM_EVENT_MERCY_FACTOR; // 0~1, 0 means most strict
     50 
     51     private final long mExpectedMinNumEvent;
     52     private final Object mSensor;
     53     private long  mNumEvent;
     54     private boolean mWrongSensorObserved;
     55 
     56     /**
     57      * Constructs an instance of {@link EventBasicVerification}.
     58      *
     59      * @param maximumSynchronizationErrorNs The valid threshold for timestamp synchronization.
     60      * @param reportLatencyNs The latency on which batching events are received
     61      */
     62     public EventBasicVerification(
     63             long expectedMinNumEvent,
     64             Sensor sensor) {
     65         mExpectedMinNumEvent = expectedMinNumEvent;
     66         mSensor = sensor;
     67 
     68         mNumEvent = 0;
     69         mWrongSensorObserved = false;
     70 
     71         if (ApiLevelUtil.isAfter(Build.VERSION_CODES.M)) {
     72             NUM_EVENT_MERCY_FACTOR = 0;
     73         } else {
     74             NUM_EVENT_MERCY_FACTOR = 0.3f;
     75         }
     76     }
     77 
     78     /**
     79      * Gets a default {@link EventBasicVerification}.
     80      *
     81      * @param environment The test environment
     82      * @return The verification or null if the verification is not supported in the given
     83      *         environment.
     84      */
     85     public static EventBasicVerification getDefault(
     86             TestSensorEnvironment environment,
     87             long testDurationUs) {
     88 
     89         // The calculation is still OK if sampleUs is not the actual sensor hardware
     90         // sample period since the actual sample period by definition only goes smaller, which
     91         // result in more samples.
     92         long sampleUs = environment.getExpectedSamplingPeriodUs();
     93 
     94         long askedBatchUs = environment.getMaxReportLatencyUs();
     95 
     96         long reservedFifoUs = sampleUs * environment.getSensor().getFifoReservedEventCount(); //>=0
     97 
     98         // max() prevent loop-hole if HAL specify smaller max fifo than reserved fifo.
     99         long maximumFifoUs = Math.max(
    100                 sampleUs * environment.getSensor().getFifoMaxEventCount(), reservedFifoUs); //>=0
    101 
    102         long effectiveDurationUs = Math.max(testDurationUs -
    103                 Math.max(ALLOWED_SENSOR_START_DELAY_US, environment.getAllowedSensorStartDelay()) -
    104                 ALLOWED_SENSOR_EVENT_LATENCY_US, 0);
    105 
    106         boolean isSingleSensorTest = !environment.isIntegrationTest();
    107 
    108         long expectedMinUs;
    109         if (isSingleSensorTest) {
    110             // When the sensor under test is the only one active, max fifo size is assumed to be
    111             // available.
    112             long expectedBatchUs = Math.min(maximumFifoUs, askedBatchUs);
    113             if (expectedBatchUs > 0) {
    114                 // This sensor should be running in batching mode.
    115                 expectedMinUs =
    116                         effectiveDurationUs / expectedBatchUs * expectedBatchUs
    117                         - expectedBatchUs / 5;
    118             } else {
    119                 // streaming, allow actual rate to be as slow as 80% of the asked rate.
    120                 expectedMinUs = effectiveDurationUs * 4 / 5;
    121             }
    122         } else {
    123             // More convoluted case. Batch size can vary from reserved fifo length to max fifo size.
    124             long minBatchUs = Math.min(reservedFifoUs, askedBatchUs);
    125             long maxBatchUs = Math.min(maximumFifoUs, askedBatchUs);
    126 
    127             // The worst scenario happens when the sensor batch time being just above half of the
    128             // test time, then the test can only receive one batch which halves the expected number
    129             // of samples. The expected number of samples received have a lower bound like the
    130             // figure below.
    131             //
    132             // expected samples
    133             //  ^
    134             //  |                          ______
    135             //  |\                        /
    136             //  |  \                    /
    137             //  |    \                /
    138             //  |      \            /
    139             //  |        \        /
    140             //  |          \    /
    141             //  |            \/
    142             //  |
    143             //  |
    144             //  |
    145             //  |
    146             //  +------------+-----------+------->  actual batch size in time
    147             //  0   1/2*testDuration   testDuration
    148             //
    149             long worstBatchUs = effectiveDurationUs / 2 + 1;
    150             if ((minBatchUs > worstBatchUs) ==  (maxBatchUs > worstBatchUs)) {
    151                 // same side
    152                 double ratio = Math.min(Math.abs(worstBatchUs - minBatchUs),
    153                         Math.abs(worstBatchUs - maxBatchUs)) / (double)worstBatchUs;
    154                 expectedMinUs = (long)((ratio + 1) / 2 * testDurationUs) * 4 / 5;
    155             } else {
    156                 // the worst case is possible
    157                 expectedMinUs = worstBatchUs * 4 / 5;
    158             }
    159         }
    160         long expectedMinNumEvent = expectedMinUs/sampleUs;
    161 
    162         return new EventBasicVerification(expectedMinNumEvent, environment.getSensor());
    163     }
    164 
    165     @Override
    166     public void verify(TestSensorEnvironment environment, SensorStats stats) {
    167         verify(stats);
    168     }
    169 
    170     /* visible to unit test */
    171     void verify(SensorStats stats) {
    172 
    173         stats.addValue(SensorStats.EVENT_COUNT_KEY, mNumEvent);
    174         stats.addValue(SensorStats.EVENT_COUNT_EXPECTED_KEY, mExpectedMinNumEvent);
    175         stats.addValue(SensorStats.WRONG_SENSOR_KEY, mWrongSensorObserved);
    176 
    177         boolean enoughSample = mNumEvent >= mExpectedMinNumEvent * ( 1 - NUM_EVENT_MERCY_FACTOR );
    178         boolean noWrongSensor = !mWrongSensorObserved;
    179 
    180         boolean success = enoughSample && noWrongSensor;
    181         stats.addValue(PASSED_KEY, success);
    182 
    183         if (!success) {
    184             Assert.fail(String.format("Failed due to (%s%s)",
    185                         enoughSample?"":"insufficient events " + mNumEvent + "/" +
    186                                 mExpectedMinNumEvent + ", ",
    187                         noWrongSensor?"":"wrong sensor observed, "));
    188         }
    189     }
    190 
    191     /**
    192      * {@inheritDoc}
    193      */
    194     @Override
    195     public EventBasicVerification clone() {
    196         return new EventBasicVerification( mExpectedMinNumEvent, (Sensor)mSensor );
    197     }
    198 
    199     /**
    200      * {@inheritDoc}
    201      */
    202     @Override
    203     protected void addSensorEventInternal(TestSensorEvent event) {
    204         if (event.sensor == mSensor) {
    205             ++mNumEvent;
    206         } else {
    207             mWrongSensorObserved = true;
    208         }
    209     }
    210 
    211 }
    212