CarSensorManagerTest.java revision 80ebb3f9f9c380b120e3e239bca25af505ec4556
1/* 2 * Copyright (C) 2015 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 17package com.android.car.test; 18 19import android.car.Car; 20import android.car.hardware.CarSensorEvent; 21import android.car.hardware.CarSensorManager; 22import android.test.suitebuilder.annotation.MediumTest; 23import android.util.Log; 24 25import com.android.car.vehiclenetwork.VehicleNetworkConsts; 26import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue; 27import com.android.car.vehiclenetwork.VehiclePropValueUtil; 28 29import java.util.concurrent.Semaphore; 30import java.util.concurrent.TimeUnit; 31 32/** 33 * Test the public entry points for the CarSensorManager 34 */ 35@MediumTest 36public class CarSensorManagerTest extends MockedCarTestBase { 37 private static final String TAG = CarSensorManagerTest.class.getSimpleName(); 38 39 private CarSensorManager mCarSensorManager; 40 41 @Override 42 protected void setUp() throws Exception { 43 super.setUp(); 44 45 // Our tests simply rely on the properties already added by default in the 46 // VehilceHalEmulator. We don't actually need to add any of our own. 47 48 // Start the HAL layer and set up the sensor manager service 49 getVehicleHalEmulator().start(); 50 mCarSensorManager = (CarSensorManager) getCar().getCarManager(Car.SENSOR_SERVICE); 51 } 52 53 /** 54 * Test single sensor availability entry point 55 * @throws Exception 56 */ 57 public void testSensorAvailability() throws Exception { 58 // NOTE: Update this test if/when the reserved values put into use. For now, we 59 // expect them to never be supported. 60 assertFalse(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_RESERVED1)); 61 assertFalse(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_RESERVED13)); 62 assertFalse(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_RESERVED21)); 63 64 // We expect these sensors to always be available 65 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_CAR_SPEED)); 66 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_FUEL_LEVEL)); 67 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_PARKING_BRAKE)); 68 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_GEAR)); 69 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_NIGHT)); 70 assertTrue(mCarSensorManager.isSensorSupported(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS)); 71 } 72 73 /** 74 * Test sensor enumeration entry point 75 * @throws Exception 76 */ 77 public void testSensorEnumeration() throws Exception { 78 int[] supportedSensors = mCarSensorManager.getSupportedSensors(); 79 assertNotNull(supportedSensors); 80 81 Log.i(TAG, "Found " + supportedSensors.length + " supported sensors."); 82 83 // Unfortunately, we don't have a definitive range for legal sensor values, 84 // so we have set a "reasonable" range here. The ending value, in particular, 85 // will need to be updated if/when new sensor types are allowed. 86 // Here we are ensuring that all the enumerated sensors also return supported. 87 for (int candidate = 0; candidate <= CarSensorManager.SENSOR_TYPE_RESERVED21; ++candidate) { 88 boolean supported = mCarSensorManager.isSensorSupported(candidate); 89 boolean found = false; 90 for (int sensor : supportedSensors) { 91 if (candidate == sensor) { 92 found = true; 93 Log.i(TAG, "Sensor type " + sensor + " is supported."); 94 break; 95 } 96 } 97 98 // Make sure the individual query on a sensor type is consistent 99 assertEquals(found, supported); 100 } 101 102 // Here we simply ensure that one specific expected sensor is always available to help 103 // ensure we don't have a trivially broken test finding nothing. 104 boolean found = false; 105 for (int sensor : supportedSensors) { 106 if (sensor == CarSensorManager.SENSOR_TYPE_DRIVING_STATUS) { 107 found = true; 108 break; 109 } 110 } 111 assertTrue("We expect at least DRIVING_STATUS to be available", found); 112 } 113 114 /** 115 * Test senor notification registration, delivery, and unregistration 116 * @throws Exception 117 */ 118 public void testEvents() throws Exception { 119 // Set up our listener callback 120 SensorListener listener = new SensorListener(); 121 mCarSensorManager.registerListener(listener, 122 CarSensorManager.SENSOR_TYPE_NIGHT, 123 CarSensorManager.SENSOR_RATE_NORMAL); 124 125 VehiclePropValue value = null; 126 CarSensorEvent.NightData data = null; 127 CarSensorEvent event = null; 128 129 // Consume any sensor events queued up on startup 130 while (listener.waitForSensorChange()) {}; 131 132 // Validate that no events are now pending 133 listener.checkNoSensorChangePosted(); 134 135 136 // Set the value TRUE and wait for the event to arrive 137 value = VehiclePropValueUtil.createBooleanValue( 138 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, true, 1); 139 getVehicleHalEmulator().injectEvent(value); 140 assertTrue(listener.waitForSensorChange()); 141 142 // Validate that no events remain pending 143 listener.checkNoSensorChangePosted(); 144 145 // Ensure we got the expected event 146 assertEquals(listener.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 147 148 // Ensure we got the expected value in our callback 149 data = listener.getLastEvent().getNightData(data); 150 Log.d(TAG, "NightMode " + data.isNightMode + " at " + data.timestamp); 151 assertTrue(data.isNightMode); 152 153 // Ensure we have the expected value in the sensor manager's cache 154 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 155 data = event.getNightData(data); 156 assertEquals("Unexpected event timestamp", data.timestamp, 1); 157 assertTrue("Unexpected value", data.isNightMode); 158 159 160 // Set the value FALSE 161 value = VehiclePropValueUtil.createBooleanValue( 162 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, false, 1001); 163 getVehicleHalEmulator().injectEvent(value); 164 assertTrue(listener.waitForSensorChange()); 165 166 // Ensure we got the expected event 167 assertEquals(listener.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 168 169 // Ensure we got the expected value in our callback 170 data = listener.getLastEvent().getNightData(data); 171 assertEquals("Unexpected event timestamp", data.timestamp, 1001); 172 assertFalse("Unexpected value", data.isNightMode); 173 174 // Ensure we have the expected value in the sensor manager's cache 175 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 176 data = event.getNightData(data); 177 assertFalse(data.isNightMode); 178 179 180 // Unregister our handler (from all sensor types) 181 mCarSensorManager.unregisterListener(listener); 182 183 // Set the value TRUE again 184 value = VehiclePropValueUtil.createBooleanValue( 185 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, true, 2001); 186 listener.checkNoSensorChangePosted(); 187 getVehicleHalEmulator().injectEvent(value); 188 189 // Ensure we did not get a callback (should timeout) 190 Log.i(TAG, "waiting for unexpected callback -- should timeout."); 191 assertFalse(listener.waitForSensorChange()); 192 listener.checkNoSensorChangePosted(); 193 194 // Despite us not having a callback registered, the Sensor Manager should see the update 195 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 196 data = event.getNightData(data); 197 assertEquals("Unexpected event timestamp", data.timestamp, 2001); 198 assertTrue("Unexpected value", data.isNightMode); 199 } 200 201 202 /** 203 * Callback function we register for sensor update notifications. 204 * This tracks the number of times it has been called via the mAvailable semaphore, 205 * and keeps a reference to the most recent event delivered. 206 */ 207 class SensorListener implements CarSensorManager.OnSensorChangedListener { 208 209 // Initialize the semaphore with ZERO callback events indicated 210 private Semaphore mAvailable = new Semaphore(0); 211 212 private CarSensorEvent mLastEvent = null; 213 214 public CarSensorEvent getLastEvent() { 215 return mLastEvent; 216 } 217 218 public void checkNoSensorChangePosted() { 219 // Verify that no permits are available (ie: the callback has not fired) 220 assertEquals("No events expected at this point.", 0, mAvailable.availablePermits()); 221 } 222 223 // Returns True to indicate receipt of a sensor event. False indicates a timeout. 224 public boolean waitForSensorChange() throws InterruptedException { 225 Log.i(TAG, "Waiting to for sensor update..."); 226 227 long startTime = System.currentTimeMillis(); 228 boolean result = mAvailable.tryAcquire(2L, TimeUnit.SECONDS); 229 long duration = System.currentTimeMillis() - startTime; 230 231 Log.d(TAG, "tryAcquire returned " + result + " in " + duration + "ms"); 232 233 return result; 234 } 235 236 @Override 237 public void onSensorChanged(CarSensorEvent event) { 238 Log.d(TAG, "onSensorChanged: " + event); 239 240 // We're going to hold a reference to this object 241 mLastEvent = event; 242 243 // Add one to the semaphore, indicating that we have run 244 mAvailable.release(); 245 } 246 } 247 248} 249