CarSensorManagerTest.java revision e44e0fb7baee22d677b6a78b815832bbfc353122
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 // Unregister our handler (from all sensor types) 180 mCarSensorManager.unregisterListener(listener); 181 182 // Set the value TRUE again 183 value = VehiclePropValueUtil.createBooleanValue( 184 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, true, 2001); 185 listener.checkNoSensorChangePosted(); 186 getVehicleHalEmulator().injectEvent(value); 187 188 // Ensure we did not get a callback (should timeout) 189 Log.i(TAG, "waiting for unexpected callback -- should timeout."); 190 assertFalse(listener.waitForSensorChange()); 191 listener.checkNoSensorChangePosted(); 192 193 // Despite us not having a callback registered, the Sensor Manager should see the update 194 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 195 data = event.getNightData(data); 196 assertEquals("Unexpected event timestamp", data.timestamp, 2001); 197 assertTrue("Unexpected value", data.isNightMode); 198 } 199 200 201 /** 202 * Test senor multiple liseners notification registration, delivery and unregistration. 203 * @throws Exception 204 */ 205 public void testEventsWithMultipleListeners() throws Exception { 206 // Set up our listeners callback 207 SensorListener listener1 = new SensorListener("1"); 208 SensorListener listener2 = new SensorListener("2"); 209 SensorListener listener3 = new SensorListener("3"); 210 211 mCarSensorManager.registerListener(listener1, 212 CarSensorManager.SENSOR_TYPE_NIGHT, 213 CarSensorManager.SENSOR_RATE_NORMAL); 214 215 mCarSensorManager.registerListener(listener2, 216 CarSensorManager.SENSOR_TYPE_NIGHT, 217 CarSensorManager.SENSOR_RATE_NORMAL); 218 219 mCarSensorManager.registerListener(listener3, 220 CarSensorManager.SENSOR_TYPE_NIGHT, 221 CarSensorManager.SENSOR_RATE_FASTEST); 222 223 VehiclePropValue value = null; 224 CarSensorEvent.NightData data = null; 225 CarSensorEvent event = null; 226 227 // Consume any sensor events queued up on startup 228 while (listener1.waitForSensorChange()) {}; 229 230 // Consume any sensor events queued up on startup 231 while (listener2.waitForSensorChange()) {}; 232 233 // Consume any sensor events queued up on startup 234 while (listener3.waitForSensorChange()) {}; 235 236 // Validate that no events are now pending 237 listener1.checkNoSensorChangePosted(); 238 239 // Validate that no events are now pending 240 listener2.checkNoSensorChangePosted(); 241 242 // Validate that no events are now pending 243 listener3.checkNoSensorChangePosted(); 244 245 // Set the value TRUE and wait for the event to arrive 246 value = VehiclePropValueUtil.createBooleanValue( 247 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, true, 1); 248 getVehicleHalEmulator().injectEvent(value); 249 assertTrue(listener1.waitForSensorChange()); 250 assertTrue(listener2.waitForSensorChange()); 251 assertTrue(listener3.waitForSensorChange()); 252 253 // Validate that no events remain pending 254 listener1.checkNoSensorChangePosted(); 255 256 // Validate that no events remain pending 257 listener2.checkNoSensorChangePosted(); 258 259 // Validate that no events remain pending 260 listener3.checkNoSensorChangePosted(); 261 262 // Ensure we got the expected event 263 assertEquals(listener1.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 264 assertEquals(listener2.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 265 assertEquals(listener3.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 266 267 // Ensure we got the expected value in our callback 268 data = listener1.getLastEvent().getNightData(data); 269 Log.d(TAG, "NightMode " + data.isNightMode + " at " + data.timestamp); 270 assertTrue(data.isNightMode); 271 272 data = listener2.getLastEvent().getNightData(data); 273 Log.d(TAG, "NightMode " + data.isNightMode + " at " + data.timestamp); 274 assertTrue(data.isNightMode); 275 276 data = listener3.getLastEvent().getNightData(data); 277 Log.d(TAG, "NightMode " + data.isNightMode + " at " + data.timestamp); 278 assertTrue(data.isNightMode); 279 280 // Ensure we have the expected value in the sensor manager's cache 281 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 282 data = event.getNightData(data); 283 assertEquals("Unexpected event timestamp", data.timestamp, 1); 284 assertTrue("Unexpected value", data.isNightMode); 285 286 // Set the value FALSE 287 value = VehiclePropValueUtil.createBooleanValue( 288 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, false, 1001); 289 getVehicleHalEmulator().injectEvent(value); 290 assertTrue(listener1.waitForSensorChange()); 291 assertTrue(listener2.waitForSensorChange()); 292 assertTrue(listener3.waitForSensorChange()); 293 294 // Validate that no events remain pending 295 listener1.checkNoSensorChangePosted(); 296 297 // Validate that no events remain pending 298 listener2.checkNoSensorChangePosted(); 299 300 // Validate that no events remain pending 301 listener3.checkNoSensorChangePosted(); 302 303 // Ensure we got the expected event 304 assertEquals(listener1.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 305 assertEquals(listener2.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 306 assertEquals(listener3.getLastEvent().sensorType, CarSensorManager.SENSOR_TYPE_NIGHT); 307 308 // Ensure we got the expected value in our callback 309 data = listener1.getLastEvent().getNightData(data); 310 assertEquals("Unexpected event timestamp", data.timestamp, 1001); 311 assertFalse("Unexpected value", data.isNightMode); 312 313 data = listener2.getLastEvent().getNightData(data); 314 assertEquals("Unexpected event timestamp", data.timestamp, 1001); 315 assertFalse("Unexpected value", data.isNightMode); 316 317 data = listener3.getLastEvent().getNightData(data); 318 assertEquals("Unexpected event timestamp", data.timestamp, 1001); 319 assertFalse("Unexpected value", data.isNightMode); 320 321 // Ensure we have the expected value in the sensor manager's cache 322 event = mCarSensorManager.getLatestSensorEvent(CarSensorManager.SENSOR_TYPE_NIGHT); 323 data = event.getNightData(data); 324 assertFalse(data.isNightMode); 325 326 Log.d(TAG, "Unregistering listener3"); 327 mCarSensorManager.unregisterListener(listener3); 328 329 Log.d(TAG, "Rate changed - expect sensor restart and change event sent."); 330 assertTrue(listener1.waitForSensorChange()); 331 assertTrue(listener2.waitForSensorChange()); 332 assertFalse(listener2.waitForSensorChange()); 333 334 // Set the value TRUE again 335 value = VehiclePropValueUtil.createBooleanValue( 336 VehicleNetworkConsts.VEHICLE_PROPERTY_NIGHT_MODE, true, 2001); 337 listener1.checkNoSensorChangePosted(); 338 listener2.checkNoSensorChangePosted(); 339 listener3.checkNoSensorChangePosted(); 340 getVehicleHalEmulator().injectEvent(value); 341 342 assertTrue(listener1.waitForSensorChange()); 343 assertTrue(listener2.waitForSensorChange()); 344 345 // Ensure we did not get a callback (should timeout) 346 Log.i(TAG, "waiting for unexpected callback -- should timeout."); 347 assertFalse(listener3.waitForSensorChange()); 348 349 listener1.checkNoSensorChangePosted(); 350 listener2.checkNoSensorChangePosted(); 351 listener3.checkNoSensorChangePosted(); 352 353 Log.d(TAG, "Unregistering listener2"); 354 mCarSensorManager.unregisterListener(listener3); 355 356 Log.d(TAG, "Rate did nor change - dont expect sensor restart and change event sent."); 357 assertFalse(listener1.waitForSensorChange()); 358 assertFalse(listener2.waitForSensorChange()); 359 assertFalse(listener2.waitForSensorChange()); 360 } 361 362 363 /** 364 * Callback function we register for sensor update notifications. 365 * This tracks the number of times it has been called via the mAvailable semaphore, 366 * and keeps a reference to the most recent event delivered. 367 */ 368 class SensorListener implements CarSensorManager.OnSensorChangedListener { 369 private final String mTag; 370 371 SensorListener(String tag) { 372 mTag = tag; 373 } 374 375 SensorListener() { 376 this(""); 377 } 378 379 // Initialize the semaphore with ZERO callback events indicated 380 private Semaphore mAvailable = new Semaphore(0); 381 382 private CarSensorEvent mLastEvent = null; 383 384 public CarSensorEvent getLastEvent() { 385 return mLastEvent; 386 } 387 388 public void checkNoSensorChangePosted() { 389 // Verify that no permits are available (ie: the callback has not fired) 390 assertEquals("No events expected at this point for " + mTag + ".", 391 0, mAvailable.availablePermits()); 392 } 393 394 // Returns True to indicate receipt of a sensor event. False indicates a timeout. 395 public boolean waitForSensorChange() throws InterruptedException { 396 Log.i(TAG, mTag + ":Waiting to for sensor update..."); 397 398 long startTime = System.currentTimeMillis(); 399 boolean result = mAvailable.tryAcquire(2L, TimeUnit.SECONDS); 400 long duration = System.currentTimeMillis() - startTime; 401 402 Log.d(TAG, mTag + ": tryAcquire returned " + result + " in " + duration + "ms"); 403 404 return result; 405 } 406 407 @Override 408 public void onSensorChanged(CarSensorEvent event) { 409 Log.d(TAG, mTag + ": onSensorChanged: " + event); 410 411 // We're going to hold a reference to this object 412 mLastEvent = event; 413 414 // Add one to the semaphore, indicating that we have run 415 mAvailable.release(); 416 } 417 } 418 419} 420