1 /* 2 * Copyright (C) 2016 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; 18 19 import android.content.Context; 20 import android.hardware.Sensor; 21 import android.hardware.SensorAdditionalInfo; 22 import android.hardware.SensorEventCallback; 23 import android.hardware.SensorManager; 24 import android.hardware.cts.helpers.SensorCtsHelper; 25 import android.util.Log; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 import java.util.concurrent.CountDownLatch; 30 import java.util.concurrent.TimeUnit; 31 32 /** 33 * Checks Sensor Additional Information feature functionality. 34 */ 35 public class SensorAdditionalInfoTest extends SensorTestCase { 36 private static final String TAG = "SensorAdditionalInfoTest"; 37 private static final int ALLOWED_ADDITIONAL_INFO_DELIVER_SEC = 3; 38 private static final int REST_PERIOD_BEFORE_TEST_SEC = 3; 39 40 private SensorManager mSensorManager; 41 42 @Override setUp()43 protected void setUp() throws Exception { 44 mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); 45 } 46 testSensorAdditionalInfo()47 public void testSensorAdditionalInfo() { 48 if (mSensorManager == null) { 49 return; 50 } 51 52 List<Sensor> list = mSensorManager.getSensorList(Sensor.TYPE_ALL); 53 List<String> errors = new ArrayList<String>(); 54 for (Sensor s : list) { 55 // skip vendor sensor types and those that do not support additional info 56 // one-shot and on-change sensors are not supported as well 57 if (s.getType() >= Sensor.TYPE_DEVICE_PRIVATE_BASE || 58 !s.isAdditionalInfoSupported() || 59 s.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT || 60 s.getReportingMode() == Sensor.REPORTING_MODE_ON_CHANGE) { 61 continue; 62 } 63 try { 64 runSensorAdditionalInfoTest(s); 65 } catch (AssertionError e) { 66 errors.add("Sensor: " + s.getName() + ", error: " + e.getMessage()); 67 } 68 } 69 if (errors.size() > 0) { 70 StringBuilder sb = new StringBuilder(); 71 sb.append("Failed for following reasons: ["); 72 int i = 0; 73 for (String error : errors) { 74 sb.append(String.format("%d. %s; ", i++, error)); 75 } 76 sb.append("]"); 77 fail(sb.toString()); 78 } 79 } 80 runSensorAdditionalInfoTest(Sensor s)81 private void runSensorAdditionalInfoTest(Sensor s) throws AssertionError { 82 waitBeforeTestStarts(); 83 84 AdditionalInfoVerifier verifier = new AdditionalInfoVerifier(s); 85 verifier.reset(false /*flushPending*/); 86 87 assertTrue(String.format("Register sensor listener for %s failed.", s.getName()), 88 mSensorManager.registerListener(verifier, s, SensorManager.SENSOR_DELAY_NORMAL)); 89 try { 90 assertTrue("Missing additional info at registration: (" + verifier.getState() + ")", 91 verifier.verify()); 92 93 verifier.reset(true /*flushPending*/); 94 assertTrue("Flush sensor failed.", mSensorManager.flush(verifier)); 95 assertTrue("Missing additional info after flushing: (" + verifier.getState() + ")", 96 verifier.verify()); 97 } finally { 98 mSensorManager.unregisterListener(verifier); 99 } 100 } 101 waitBeforeTestStarts()102 private void waitBeforeTestStarts() { 103 // wait for sensor system to come to a rest after previous test to avoid flakiness. 104 try { 105 SensorCtsHelper.sleep(REST_PERIOD_BEFORE_TEST_SEC, TimeUnit.SECONDS); 106 } catch (InterruptedException e) { 107 Thread.currentThread().interrupt(); 108 } 109 } 110 111 private class AdditionalInfoVerifier extends SensorEventCallback { 112 private boolean mBeginFrame = false; 113 private boolean mEndFrame = false; 114 private boolean mFlushPending = false; 115 private CountDownLatch mDone; 116 private final Sensor mSensor; 117 AdditionalInfoVerifier(Sensor s)118 public AdditionalInfoVerifier(Sensor s) { 119 mSensor = s; 120 } 121 122 @Override onFlushCompleted(Sensor sensor)123 public void onFlushCompleted(Sensor sensor) { 124 if (sensor == mSensor) { 125 mFlushPending = false; 126 } 127 } 128 129 @Override onSensorAdditionalInfo(SensorAdditionalInfo info)130 public void onSensorAdditionalInfo(SensorAdditionalInfo info) { 131 if (info.sensor == mSensor && !mFlushPending) { 132 if (info.type == SensorAdditionalInfo.TYPE_FRAME_BEGIN) { 133 mBeginFrame = true; 134 } else if (info.type == SensorAdditionalInfo.TYPE_FRAME_END && mBeginFrame) { 135 mEndFrame = true; 136 mDone.countDown(); 137 } 138 } 139 } 140 reset(boolean flushPending)141 public void reset(boolean flushPending) { 142 mFlushPending = flushPending; 143 mBeginFrame = false; 144 mEndFrame = false; 145 mDone = new CountDownLatch(1); 146 } 147 verify()148 public boolean verify() { 149 boolean ret; 150 try { 151 ret = mDone.await(ALLOWED_ADDITIONAL_INFO_DELIVER_SEC, TimeUnit.SECONDS); 152 } catch (InterruptedException e) { 153 ret = false; 154 } 155 return ret; 156 } 157 getState()158 public String getState() { 159 return "fp=" + mFlushPending +", b=" + mBeginFrame + ", e=" + mEndFrame; 160 } 161 } 162 } 163 164