1 /* 2 * Copyright (C) 2017 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 com.android.car; 18 19 import static android.car.test.mocks.JavaMockitoHelper.silentAwait; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assert.assertFalse; 25 import static org.junit.Assert.assertTrue; 26 27 import android.car.Car; 28 import android.car.diagnostic.CarDiagnosticEvent; 29 import android.car.diagnostic.CarDiagnosticEvent.CommonIgnitionMonitors; 30 import android.car.diagnostic.CarDiagnosticEvent.CompressionIgnitionMonitors; 31 import android.car.diagnostic.CarDiagnosticEvent.FuelSystemStatus; 32 import android.car.diagnostic.CarDiagnosticEvent.FuelType; 33 import android.car.diagnostic.CarDiagnosticEvent.SecondaryAirStatus; 34 import android.car.diagnostic.CarDiagnosticEvent.SparkIgnitionMonitors; 35 import android.car.diagnostic.CarDiagnosticManager; 36 import android.car.diagnostic.FloatSensorIndex; 37 import android.car.diagnostic.IntegerSensorIndex; 38 import android.car.hardware.property.VehicleHalStatusCode; 39 import android.hardware.automotive.vehicle.VehiclePropValue; 40 import android.hardware.automotive.vehicle.VehicleProperty; 41 import android.os.ServiceSpecificException; 42 import android.os.SystemClock; 43 import android.util.JsonReader; 44 import android.util.JsonWriter; 45 import android.util.Log; 46 47 import androidx.test.ext.junit.runners.AndroidJUnit4; 48 import androidx.test.filters.FlakyTest; 49 import androidx.test.filters.MediumTest; 50 51 import com.android.car.hal.test.AidlMockedVehicleHal.ErrorCodeHandler; 52 import com.android.car.hal.test.AidlMockedVehicleHal.VehicleHalPropertyHandler; 53 import com.android.car.hal.test.AidlVehiclePropValueBuilder; 54 import com.android.car.hal.test.DiagnosticEventBuilder; 55 import com.android.car.hal.test.DiagnosticJson; 56 import com.android.internal.annotations.GuardedBy; 57 58 import org.junit.Rule; 59 import org.junit.Test; 60 import org.junit.rules.TestName; 61 import org.junit.runner.RunWith; 62 63 import static java.lang.Integer.toHexString; 64 65 import java.io.StringReader; 66 import java.io.StringWriter; 67 import java.util.ArrayList; 68 import java.util.Arrays; 69 import java.util.Collection; 70 import java.util.Collections; 71 import java.util.HashMap; 72 import java.util.HashSet; 73 import java.util.List; 74 import java.util.Objects; 75 import java.util.Set; 76 import java.util.concurrent.CountDownLatch; 77 78 /** Test the public entry points for the CarDiagnosticManager */ 79 @RunWith(AndroidJUnit4.class) 80 @MediumTest 81 public class CarDiagnosticManagerTest extends MockedCarTestBase { 82 private static final String TAG = CarDiagnosticManagerTest.class.getSimpleName(); 83 84 private final DiagnosticEventBuilder mLiveFrameEventBuilder = 85 new DiagnosticEventBuilder(VehicleProperty.OBD2_LIVE_FRAME); 86 private final DiagnosticEventBuilder mFreezeFrameEventBuilder = 87 new DiagnosticEventBuilder(VehicleProperty.OBD2_FREEZE_FRAME); 88 private final FreezeFrameProperties mFreezeFrameProperties = new FreezeFrameProperties(); 89 90 private CarDiagnosticManager mCarDiagnosticManager; 91 92 private static final String DTC = "P1010"; 93 private static final float EPS = 1e-9f; 94 95 @Rule public TestName mTestName = new TestName(); 96 97 /** 98 * This class is a central repository for freeze frame data. It ensures that timestamps and 99 * events are kept in sync and provides a consistent access model for diagnostic properties. 100 */ 101 class FreezeFrameProperties { 102 private final HashMap<Long, VehiclePropValue> mEvents = new HashMap<>(); 103 104 public final FreezeFramePropertyHandler mFreezeFrameInfoHandler = 105 new FreezeFrameInfoHandler(); 106 public final FreezeFramePropertyHandler mFreezeFrameHandler = new FreezeFrameHandler(); 107 public final FreezeFramePropertyHandler mFreezeFrameClearHandler = 108 new FreezeFrameClearHandler(); 109 addNewEvent(DiagnosticEventBuilder builder)110 synchronized VehiclePropValue addNewEvent(DiagnosticEventBuilder builder) { 111 long timestamp = SystemClock.elapsedRealtimeNanos(); 112 return addNewEvent(builder, timestamp); 113 } 114 addNewEvent(DiagnosticEventBuilder builder, long timestamp)115 synchronized VehiclePropValue addNewEvent(DiagnosticEventBuilder builder, long timestamp) { 116 VehiclePropValue newEvent = builder.build(timestamp); 117 mEvents.put(timestamp, newEvent); 118 return newEvent; 119 } 120 removeEvent(long timestamp)121 synchronized VehiclePropValue removeEvent(long timestamp) { 122 return mEvents.remove(timestamp); 123 } 124 removeEvents()125 synchronized void removeEvents() { 126 mEvents.clear(); 127 } 128 getTimestamps()129 synchronized long[] getTimestamps() { 130 return mEvents.keySet().stream().mapToLong(Long::longValue).toArray(); 131 } 132 getEvent(long timestamp)133 synchronized VehiclePropValue getEvent(long timestamp) { 134 return mEvents.get(timestamp); 135 } 136 137 class FreezeFramePropertyHandler implements VehicleHalPropertyHandler { 138 private boolean mSubscribed = false; 139 private int mStatus; 140 141 protected final int VEHICLE_PROPERTY; 142 FreezeFramePropertyHandler(int propertyId)143 protected FreezeFramePropertyHandler(int propertyId) { 144 VEHICLE_PROPERTY = propertyId; 145 } 146 setStatus(int status)147 public void setStatus(int status) { 148 mStatus = status; 149 } 150 151 @Override onPropertySet(VehiclePropValue value)152 public synchronized void onPropertySet(VehiclePropValue value) { 153 if (mStatus != VehicleHalStatusCode.STATUS_OK) { 154 throw new ServiceSpecificException(mStatus); 155 } 156 assertEquals(VEHICLE_PROPERTY, value.prop); 157 } 158 159 @Override onPropertyGet(VehiclePropValue value)160 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { 161 if (mStatus != VehicleHalStatusCode.STATUS_OK) { 162 throw new ServiceSpecificException(mStatus); 163 } 164 assertEquals(VEHICLE_PROPERTY, value.prop); 165 return null; 166 } 167 168 @Override onPropertySubscribe(int property, float sampleRate)169 public synchronized void onPropertySubscribe(int property, float sampleRate) { 170 assertEquals(VEHICLE_PROPERTY, property); 171 mSubscribed = true; 172 } 173 174 @Override onPropertyUnsubscribe(int property)175 public synchronized void onPropertyUnsubscribe(int property) { 176 assertEquals(VEHICLE_PROPERTY, property); 177 if (!mSubscribed) { 178 throw new IllegalArgumentException( 179 "Property was not subscribed 0x" + toHexString(property)); 180 } 181 mSubscribed = false; 182 } 183 } 184 185 class FreezeFrameInfoHandler extends FreezeFramePropertyHandler { FreezeFrameInfoHandler()186 FreezeFrameInfoHandler() { 187 super(VehicleProperty.OBD2_FREEZE_FRAME_INFO); 188 } 189 190 @Override onPropertyGet(VehiclePropValue value)191 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { 192 super.onPropertyGet(value); 193 AidlVehiclePropValueBuilder builder = 194 AidlVehiclePropValueBuilder.newBuilder(VEHICLE_PROPERTY); 195 builder.addInt64Values(getTimestamps()); 196 return builder.build(); 197 } 198 } 199 200 class FreezeFrameHandler extends FreezeFramePropertyHandler { FreezeFrameHandler()201 FreezeFrameHandler() { 202 super(VehicleProperty.OBD2_FREEZE_FRAME); 203 } 204 205 @Override onPropertyGet(VehiclePropValue value)206 public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) { 207 super.onPropertyGet(value); 208 long timestamp = value.value.int64Values[0]; 209 return getEvent(timestamp); 210 } 211 } 212 213 class FreezeFrameClearHandler extends FreezeFramePropertyHandler { FreezeFrameClearHandler()214 FreezeFrameClearHandler() { 215 super(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR); 216 } 217 218 @Override onPropertySet(VehiclePropValue value)219 public synchronized void onPropertySet(VehiclePropValue value) { 220 super.onPropertySet(value); 221 if (0 == value.value.int64Values.length) { 222 removeEvents(); 223 } else { 224 for (long timestamp : value.value.int64Values) { 225 removeEvent(timestamp); 226 } 227 } 228 } 229 } 230 } 231 232 @Override configureResourceOverrides(MockResources resources)233 protected void configureResourceOverrides(MockResources resources) { 234 super.configureResourceOverrides(resources); 235 resources.overrideResource(com.android.car.R.array.config_allowed_optional_car_features, 236 new String[]{Car.DIAGNOSTIC_SERVICE}); 237 } 238 239 @Override configureMockedHal()240 protected void configureMockedHal() { 241 Collection<Integer> numVendorSensors = Arrays.asList(0, 0); 242 Collection<Integer> selectiveClear = Collections.singletonList(1); 243 Log.i(TAG, mTestName.getMethodName()); 244 String methodName = mTestName.getMethodName(); 245 ErrorCodeHandler handler = new ErrorCodeHandler(); 246 if (Objects.equals(methodName, "testInitialLiveFrameException_Invalid_Arg")) { 247 handler.setStatus(VehicleHalStatusCode.STATUS_INVALID_ARG); 248 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, handler) 249 .setConfigArray(numVendorSensors); 250 } else if (Objects.equals(methodName, "testInitialLiveFrameException_NOT_AVAILABLE")) { 251 handler.setStatus(VehicleHalStatusCode.STATUS_NOT_AVAILABLE); 252 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, handler) 253 .setConfigArray(numVendorSensors); 254 } else if (Objects.equals(methodName, "testInitialLiveFrameException_ACCESS_DENIED")) { 255 handler.setStatus(VehicleHalStatusCode.STATUS_ACCESS_DENIED); 256 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, handler) 257 .setConfigArray(numVendorSensors); 258 } else if (Objects.equals(methodName, "testInitialLiveFrameException_TRY_AGAIN")) { 259 handler.setStatus(VehicleHalStatusCode.STATUS_TRY_AGAIN); 260 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, handler) 261 .setConfigArray(numVendorSensors); 262 } else if (Objects.equals(methodName, "testInitialLiveFrameException_INTERNAL_ERROR")) { 263 handler.setStatus(VehicleHalStatusCode.STATUS_INTERNAL_ERROR); 264 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, handler) 265 .setConfigArray(numVendorSensors); 266 } else { 267 addAidlProperty(VehicleProperty.OBD2_LIVE_FRAME, mLiveFrameEventBuilder.build()) 268 .setConfigArray(numVendorSensors); 269 } 270 if (Objects.equals(methodName, "testInitialFreezeFrameInfoException_Invalid_Arg")) { 271 mFreezeFrameProperties.mFreezeFrameInfoHandler.setStatus( 272 VehicleHalStatusCode.STATUS_INVALID_ARG); 273 } else if (Objects.equals(methodName, 274 "testInitialFreezeFrameInfoException_NOT_AVAILABLE")) { 275 mFreezeFrameProperties.mFreezeFrameInfoHandler.setStatus( 276 VehicleHalStatusCode.STATUS_NOT_AVAILABLE); 277 } else if (Objects.equals(methodName, 278 "testInitialFreezeFrameInfoException_ACCESS_DENIED")) { 279 mFreezeFrameProperties.mFreezeFrameInfoHandler.setStatus( 280 VehicleHalStatusCode.STATUS_ACCESS_DENIED); 281 } else if (Objects.equals(methodName, "testInitialFreezeFrameInfoException_TRY_AGAIN")) { 282 mFreezeFrameProperties.mFreezeFrameInfoHandler.setStatus( 283 VehicleHalStatusCode.STATUS_TRY_AGAIN); 284 } else if (Objects.equals(methodName, 285 "testInitialFreezeFrameInfoException_INTERNAL_ERROR")) { 286 mFreezeFrameProperties.mFreezeFrameInfoHandler.setStatus( 287 VehicleHalStatusCode.STATUS_INTERNAL_ERROR); 288 } 289 addAidlProperty( 290 VehicleProperty.OBD2_FREEZE_FRAME_INFO, 291 mFreezeFrameProperties.mFreezeFrameInfoHandler); 292 293 if (Objects.equals(methodName, "testInitialFreezeFrameException_Invalid_Arg")) { 294 mFreezeFrameProperties.mFreezeFrameHandler.setStatus( 295 VehicleHalStatusCode.STATUS_INVALID_ARG); 296 } else if (Objects.equals(methodName, "testInitialFreezeFrameException_NOT_AVAILABLE")) { 297 mFreezeFrameProperties.mFreezeFrameHandler.setStatus( 298 VehicleHalStatusCode.STATUS_NOT_AVAILABLE); 299 } else if (Objects.equals(methodName, "testInitialFreezeFrameException_ACCESS_DENIED")) { 300 mFreezeFrameProperties.mFreezeFrameHandler.setStatus( 301 VehicleHalStatusCode.STATUS_ACCESS_DENIED); 302 } else if (Objects.equals(methodName, "testInitialFreezeFrameException_TRY_AGAIN")) { 303 mFreezeFrameProperties.mFreezeFrameHandler.setStatus( 304 VehicleHalStatusCode.STATUS_TRY_AGAIN); 305 } else if (Objects.equals(methodName, "testInitialFreezeFrameException_INTERNAL_ERROR")) { 306 mFreezeFrameProperties.mFreezeFrameHandler.setStatus( 307 VehicleHalStatusCode.STATUS_INTERNAL_ERROR); 308 } 309 addAidlProperty(VehicleProperty.OBD2_FREEZE_FRAME, 310 mFreezeFrameProperties.mFreezeFrameHandler).setConfigArray(numVendorSensors); 311 312 addAidlProperty( 313 VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, 314 mFreezeFrameProperties.mFreezeFrameClearHandler) 315 .setConfigArray(selectiveClear); 316 } 317 318 @Override setUp()319 public void setUp() throws Exception { 320 mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE, 30); 321 mLiveFrameEventBuilder.addIntSensor( 322 IntegerSensorIndex.FUEL_SYSTEM_STATUS, 323 FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION); 324 mLiveFrameEventBuilder.addIntSensor( 325 IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5000); 326 mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE, 2); 327 mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.CALCULATED_ENGINE_LOAD, 0.125f); 328 mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.VEHICLE_SPEED, 12.5f); 329 330 mFreezeFrameEventBuilder.addIntSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE, 30); 331 mFreezeFrameEventBuilder.addIntSensor( 332 IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5000); 333 mFreezeFrameEventBuilder.addIntSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE, 2); 334 mFreezeFrameEventBuilder.addFloatSensor( 335 FloatSensorIndex.CALCULATED_ENGINE_LOAD, 0.125f); 336 mFreezeFrameEventBuilder.addFloatSensor(FloatSensorIndex.VEHICLE_SPEED, 12.5f); 337 mFreezeFrameEventBuilder.setDTC(DTC); 338 339 super.setUp(); 340 341 Log.i(TAG, "attempting to get DIAGNOSTIC_SERVICE"); 342 mCarDiagnosticManager = 343 (CarDiagnosticManager) getCar().getCarManager(Car.DIAGNOSTIC_SERVICE); 344 } 345 testInitialLiveFrameException_Invalid_Arg()346 @Test public void testInitialLiveFrameException_Invalid_Arg() { 347 // Do nothing, this test is to test the exception returned by VHAL during initialization 348 // should not be propagated. 349 assertThat(mCarDiagnosticManager.getLatestLiveFrame()).isNull(); 350 } 351 testInitialLiveFrameException_NOT_AVAILABLE()352 @Test public void testInitialLiveFrameException_NOT_AVAILABLE() { 353 // Do nothing, this test is to test the exception returned by VHAL during initialization 354 // should not be propagated. 355 assertThat(mCarDiagnosticManager.getLatestLiveFrame()).isNull(); 356 } 357 testInitialLiveFrameException_ACCESS_DENIED()358 @Test public void testInitialLiveFrameException_ACCESS_DENIED() { 359 // Do nothing, this test is to test the exception returned by VHAL during initialization 360 // should not be propagated. 361 assertThat(mCarDiagnosticManager.getLatestLiveFrame()).isNull(); 362 } 363 testInitialLiveFrameException_TRY_AGAIN()364 @Test public void testInitialLiveFrameException_TRY_AGAIN() { 365 // Do nothing, this test is to test the exception returned by VHAL during initialization 366 // should not be propagated. 367 assertThat(mCarDiagnosticManager.getLatestLiveFrame()).isNull(); 368 } 369 testInitialLiveFrameException_INTERNAL_ERROR()370 @Test public void testInitialLiveFrameException_INTERNAL_ERROR() { 371 // Do nothing, this test is to test the exception returned by VHAL during initialization 372 // should not be propagated. 373 assertThat(mCarDiagnosticManager.getLatestLiveFrame()).isNull(); 374 } 375 testInitialFreezeFrameInfoException_Invalid_Arg()376 @Test public void testInitialFreezeFrameInfoException_Invalid_Arg() { 377 // Do nothing, this test is to test the exception returned by VHAL during initialization 378 // should not be propagated. 379 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 380 } 381 testInitialFreezeFrameInfoException_NOT_AVAILABLE()382 @Test public void testInitialFreezeFrameInfoException_NOT_AVAILABLE() { 383 // Do nothing, this test is to test the exception returned by VHAL during initialization 384 // should not be propagated. 385 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 386 } 387 testInitialFreezeFrameInfoException_ACCESS_DENIED()388 @Test public void testInitialFreezeFrameInfoException_ACCESS_DENIED() { 389 // Do nothing, this test is to test the exception returned by VHAL during initialization 390 // should not be propagated. 391 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 392 } 393 testInitialFreezeFrameInfoException_TRY_AGAIN()394 @Test public void testInitialFreezeFrameInfoException_TRY_AGAIN() { 395 // Do nothing, this test is to test the exception returned by VHAL during initialization 396 // should not be propagated. 397 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 398 } 399 testInitialFreezeFrameInfoException_INTERNAL_ERROR()400 @Test public void testInitialFreezeFrameInfoException_INTERNAL_ERROR() { 401 // Do nothing, this test is to test the exception returned by VHAL during initialization 402 // should not be propagated. 403 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 404 } 405 testInitialFreezeFrameException_Invalid_Arg()406 @Test public void testInitialFreezeFrameException_Invalid_Arg() { 407 // Do nothing, this test is to test the exception returned by VHAL during initialization 408 // should not be propagated. 409 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 410 } 411 testInitialFreezeFrameException_NOT_AVAILABLE()412 @Test public void testInitialFreezeFrameException_NOT_AVAILABLE() { 413 // Do nothing, this test is to test the exception returned by VHAL during initialization 414 // should not be propagated. 415 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 416 } 417 testInitialFreezeFrameException_ACCESS_DENIED()418 @Test public void testInitialFreezeFrameException_ACCESS_DENIED() { 419 // Do nothing, this test is to test the exception returned by VHAL during initialization 420 // should not be propagated. 421 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 422 } 423 testInitialFreezeFrameException_TRY_AGAIN()424 @Test public void testInitialFreezeFrameException_TRY_AGAIN() { 425 // Do nothing, this test is to test the exception returned by VHAL during initialization 426 // should not be propagated. 427 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 428 } 429 testInitialFreezeFrameException_INTERNAL_ERROR()430 @Test public void testInitialFreezeFrameException_INTERNAL_ERROR() { 431 // Do nothing, this test is to test the exception returned by VHAL during initialization 432 // should not be propagated. 433 assertEquals(mCarDiagnosticManager.getFreezeFrameTimestamps().length, 0); 434 } 435 436 testLiveFrameRead()437 @Test public void testLiveFrameRead() throws Exception { 438 CarDiagnosticEvent liveFrame = mCarDiagnosticManager.getLatestLiveFrame(); 439 440 assertThat(liveFrame).isNotNull(); 441 assertTrue(liveFrame.isLiveFrame()); 442 assertFalse(liveFrame.isFreezeFrame()); 443 assertFalse(liveFrame.isEmptyFrame()); 444 445 assertEquals( 446 5000, 447 liveFrame 448 .getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START) 449 .intValue()); 450 assertEquals( 451 30, 452 liveFrame 453 .getSystemIntegerSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE) 454 .intValue()); 455 assertEquals( 456 2, 457 liveFrame 458 .getSystemIntegerSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE) 459 .intValue()); 460 assertEquals( 461 0.125f, 462 liveFrame.getSystemFloatSensor(FloatSensorIndex.CALCULATED_ENGINE_LOAD), 463 EPS); 464 assertEquals( 465 12.5f, 466 liveFrame.getSystemFloatSensor(FloatSensorIndex.VEHICLE_SPEED), 467 EPS); 468 } 469 testLiveFrameEvent()470 @Test public void testLiveFrameEvent() throws Exception { 471 Listener listener = new Listener(); 472 mCarDiagnosticManager.registerListener( 473 listener, 474 CarDiagnosticManager.FRAME_TYPE_LIVE, 475 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 476 477 listener.reset(); 478 long time = SystemClock.elapsedRealtimeNanos(); 479 mLiveFrameEventBuilder.addIntSensor( 480 IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5100); 481 482 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time)); 483 CarDiagnosticEvent liveFrame = listener.waitForEvent(time); 484 485 assertThat(liveFrame).isNotNull(); 486 487 assertEquals( 488 5100, 489 liveFrame 490 .getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START) 491 .intValue()); 492 } 493 testMissingSensorRead()494 @Test public void testMissingSensorRead() throws Exception { 495 Listener listener = new Listener(); 496 mCarDiagnosticManager.registerListener( 497 listener, 498 CarDiagnosticManager.FRAME_TYPE_LIVE, 499 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 500 501 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build()); 502 CarDiagnosticEvent liveFrame = listener.waitForEvent(); 503 504 assertThat(liveFrame).isNotNull(); 505 506 assertThat( 507 liveFrame.getSystemIntegerSensor( 508 IntegerSensorIndex.DRIVER_DEMAND_PERCENT_TORQUE)).isNull(); 509 assertEquals( 510 -1, 511 liveFrame.getSystemIntegerSensor( 512 IntegerSensorIndex.DRIVER_DEMAND_PERCENT_TORQUE, -1)); 513 514 assertThat( 515 liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR6_VOLTAGE)).isNull(); 516 assertEquals( 517 0.25f, 518 liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR5_VOLTAGE, 0.25f), EPS); 519 520 assertThat(liveFrame.getVendorIntegerSensor(IntegerSensorIndex.VENDOR_START)).isNull(); 521 assertEquals(-1, liveFrame.getVendorIntegerSensor(IntegerSensorIndex.VENDOR_START, -1)); 522 523 assertThat(liveFrame.getVendorFloatSensor(FloatSensorIndex.VENDOR_START)).isNull(); 524 assertEquals( 525 0.25f, liveFrame.getVendorFloatSensor(FloatSensorIndex.VENDOR_START, 0.25f), EPS); 526 } 527 testFuelSystemStatus()528 @Test public void testFuelSystemStatus() throws Exception { 529 Listener listener = new Listener(); 530 mCarDiagnosticManager.registerListener( 531 listener, 532 CarDiagnosticManager.FRAME_TYPE_LIVE, 533 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 534 535 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build()); 536 CarDiagnosticEvent liveFrame = listener.waitForEvent(); 537 538 assertThat(liveFrame).isNotNull(); 539 540 assertEquals( 541 FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION, 542 liveFrame 543 .getSystemIntegerSensor(IntegerSensorIndex.FUEL_SYSTEM_STATUS) 544 .intValue()); 545 assertEquals( 546 FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION, 547 liveFrame.getFuelSystemStatus().intValue()); 548 } 549 testSecondaryAirStatus()550 @Test public void testSecondaryAirStatus() throws Exception { 551 Listener listener = new Listener(); 552 mCarDiagnosticManager.registerListener( 553 listener, 554 CarDiagnosticManager.FRAME_TYPE_LIVE, 555 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 556 557 mLiveFrameEventBuilder.addIntSensor( 558 IntegerSensorIndex.COMMANDED_SECONDARY_AIR_STATUS, 559 SecondaryAirStatus.FROM_OUTSIDE_OR_OFF); 560 long timestamp = SystemClock.elapsedRealtimeNanos(); 561 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp)); 562 563 CarDiagnosticEvent liveFrame = listener.waitForEvent(timestamp); 564 565 assertThat(liveFrame).isNotNull(); 566 567 assertEquals( 568 SecondaryAirStatus.FROM_OUTSIDE_OR_OFF, 569 liveFrame 570 .getSystemIntegerSensor( 571 IntegerSensorIndex.COMMANDED_SECONDARY_AIR_STATUS) 572 .intValue()); 573 assertEquals( 574 SecondaryAirStatus.FROM_OUTSIDE_OR_OFF, 575 liveFrame.getSecondaryAirStatus().intValue()); 576 } 577 testIgnitionMonitors()578 @Test public void testIgnitionMonitors() throws Exception { 579 Listener listener = new Listener(); 580 mCarDiagnosticManager.registerListener( 581 listener, 582 CarDiagnosticManager.FRAME_TYPE_LIVE, 583 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 584 585 // cfr. CarDiagnosticEvent for the meaning of the several bits 586 final int sparkMonitorsValue = 587 0x1 | (0x1 << 2) | (0x1 << 3) | (0x1 << 6) | (0x1 << 10) | (0x1 << 11); 588 589 final int compressionMonitorsValue = 590 (0x1 << 2) | (0x1 << 3) | (0x1 << 6) | (0x1 << 12) | (0x1 << 13); 591 592 mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.IGNITION_MONITORS_SUPPORTED, 0); 593 mLiveFrameEventBuilder.addIntSensor( 594 IntegerSensorIndex.IGNITION_SPECIFIC_MONITORS, sparkMonitorsValue); 595 596 long timestamp = SystemClock.elapsedRealtimeNanos(); 597 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp)); 598 599 CarDiagnosticEvent liveFrame = listener.waitForEvent(timestamp); 600 601 assertThat(liveFrame).isNotNull(); 602 603 CommonIgnitionMonitors commonIgnitionMonitors = liveFrame.getIgnitionMonitors(); 604 assertThat(commonIgnitionMonitors).isNotNull(); 605 assertTrue(commonIgnitionMonitors.components.available); 606 assertFalse(commonIgnitionMonitors.components.incomplete); 607 assertTrue(commonIgnitionMonitors.fuelSystem.available); 608 assertTrue(commonIgnitionMonitors.fuelSystem.incomplete); 609 assertFalse(commonIgnitionMonitors.misfire.available); 610 assertFalse(commonIgnitionMonitors.misfire.incomplete); 611 612 SparkIgnitionMonitors sparkIgnitionMonitors = 613 commonIgnitionMonitors.asSparkIgnitionMonitors(); 614 assertThat(sparkIgnitionMonitors).isNotNull(); 615 assertThat(commonIgnitionMonitors.asCompressionIgnitionMonitors()).isNull(); 616 617 assertTrue(sparkIgnitionMonitors.EGR.available); 618 assertFalse(sparkIgnitionMonitors.EGR.incomplete); 619 assertFalse(sparkIgnitionMonitors.oxygenSensorHeater.available); 620 assertFalse(sparkIgnitionMonitors.oxygenSensorHeater.incomplete); 621 assertTrue(sparkIgnitionMonitors.oxygenSensor.available); 622 assertTrue(sparkIgnitionMonitors.oxygenSensor.incomplete); 623 assertFalse(sparkIgnitionMonitors.ACRefrigerant.available); 624 assertFalse(sparkIgnitionMonitors.ACRefrigerant.incomplete); 625 assertFalse(sparkIgnitionMonitors.secondaryAirSystem.available); 626 assertFalse(sparkIgnitionMonitors.secondaryAirSystem.incomplete); 627 assertFalse(sparkIgnitionMonitors.evaporativeSystem.available); 628 assertFalse(sparkIgnitionMonitors.evaporativeSystem.incomplete); 629 assertFalse(sparkIgnitionMonitors.heatedCatalyst.available); 630 assertFalse(sparkIgnitionMonitors.heatedCatalyst.incomplete); 631 assertFalse(sparkIgnitionMonitors.catalyst.available); 632 assertFalse(sparkIgnitionMonitors.catalyst.incomplete); 633 634 mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.IGNITION_MONITORS_SUPPORTED, 1); 635 mLiveFrameEventBuilder.addIntSensor( 636 IntegerSensorIndex.IGNITION_SPECIFIC_MONITORS, compressionMonitorsValue); 637 638 timestamp += 1000; 639 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp)); 640 641 liveFrame = listener.waitForEvent(timestamp); 642 643 assertThat(liveFrame).isNotNull(); 644 assertEquals(timestamp, liveFrame.timestamp); 645 646 commonIgnitionMonitors = liveFrame.getIgnitionMonitors(); 647 assertThat(commonIgnitionMonitors).isNotNull(); 648 assertFalse(commonIgnitionMonitors.components.available); 649 assertFalse(commonIgnitionMonitors.components.incomplete); 650 assertTrue(commonIgnitionMonitors.fuelSystem.available); 651 assertTrue(commonIgnitionMonitors.fuelSystem.incomplete); 652 assertFalse(commonIgnitionMonitors.misfire.available); 653 assertFalse(commonIgnitionMonitors.misfire.incomplete); 654 CompressionIgnitionMonitors compressionIgnitionMonitors = 655 commonIgnitionMonitors.asCompressionIgnitionMonitors(); 656 assertThat(commonIgnitionMonitors.asSparkIgnitionMonitors()).isNull(); 657 assertThat(compressionIgnitionMonitors).isNotNull(); 658 659 assertTrue(compressionIgnitionMonitors.EGROrVVT.available); 660 assertFalse(compressionIgnitionMonitors.EGROrVVT.incomplete); 661 assertFalse(compressionIgnitionMonitors.PMFilter.available); 662 assertFalse(compressionIgnitionMonitors.PMFilter.incomplete); 663 assertFalse(compressionIgnitionMonitors.exhaustGasSensor.available); 664 assertFalse(compressionIgnitionMonitors.exhaustGasSensor.incomplete); 665 assertTrue(compressionIgnitionMonitors.boostPressure.available); 666 assertTrue(compressionIgnitionMonitors.boostPressure.incomplete); 667 assertFalse(compressionIgnitionMonitors.NOxSCR.available); 668 assertFalse(compressionIgnitionMonitors.NOxSCR.incomplete); 669 assertFalse(compressionIgnitionMonitors.NMHCCatalyst.available); 670 assertFalse(compressionIgnitionMonitors.NMHCCatalyst.incomplete); 671 } 672 673 @Test 674 @FlakyTest testFuelType()675 public void testFuelType() throws Exception { 676 Listener listener = new Listener(); 677 mCarDiagnosticManager.registerListener( 678 listener, 679 CarDiagnosticManager.FRAME_TYPE_LIVE, 680 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 681 682 mLiveFrameEventBuilder.addIntSensor( 683 IntegerSensorIndex.FUEL_TYPE, FuelType.BIFUEL_RUNNING_LPG); 684 long timestamp = SystemClock.elapsedRealtimeNanos(); 685 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp)); 686 687 CarDiagnosticEvent liveFrame = listener.waitForEvent(timestamp); 688 689 assertThat(liveFrame).isNotNull(); 690 691 assertEquals( 692 FuelType.BIFUEL_RUNNING_LPG, 693 liveFrame.getSystemIntegerSensor(IntegerSensorIndex.FUEL_TYPE).intValue()); 694 assertEquals(FuelType.BIFUEL_RUNNING_LPG, liveFrame.getFuelType().intValue()); 695 } 696 testDiagnosticJson()697 @Test public void testDiagnosticJson() throws Exception { 698 Listener listener = new Listener(); 699 mCarDiagnosticManager.registerListener( 700 listener, 701 CarDiagnosticManager.FRAME_TYPE_LIVE, 702 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 703 704 mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE, 74); 705 mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE, 0.125f); 706 707 long timestamp = SystemClock.elapsedRealtimeNanos(); 708 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp)); 709 710 CarDiagnosticEvent liveFrame = listener.waitForEvent(timestamp); 711 712 assertThat(liveFrame).isNotNull(); 713 714 assertEquals( 715 74, 716 liveFrame 717 .getSystemIntegerSensor(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE) 718 .intValue()); 719 assertEquals( 720 0.125f, 721 liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE), 722 EPS); 723 724 StringWriter stringWriter = new StringWriter(); 725 JsonWriter jsonWriter = new JsonWriter(stringWriter); 726 727 liveFrame.writeToJson(jsonWriter); 728 jsonWriter.flush(); 729 730 StringReader stringReader = new StringReader(stringWriter.toString()); 731 JsonReader jsonReader = new JsonReader(stringReader); 732 DiagnosticJson diagnosticJson = DiagnosticJson.build(jsonReader); 733 734 assertEquals( 735 74, 736 diagnosticJson 737 .intValues 738 .get(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE) 739 .intValue()); 740 assertEquals( 741 0.125f, 742 diagnosticJson.floatValues.get(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE), 743 EPS); 744 } 745 746 @Test testMultipleListeners()747 public void testMultipleListeners() throws Exception { 748 Listener listener1 = new Listener(); 749 Listener listener2 = new Listener(); 750 751 mCarDiagnosticManager.registerListener( 752 listener1, 753 CarDiagnosticManager.FRAME_TYPE_LIVE, 754 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 755 mCarDiagnosticManager.registerListener( 756 listener2, 757 CarDiagnosticManager.FRAME_TYPE_LIVE, 758 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 759 760 listener1.reset(); 761 listener2.reset(); 762 763 long time = SystemClock.elapsedRealtimeNanos(); 764 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time)); 765 CarDiagnosticEvent event1 = listener1.waitForEvent(time); 766 assertThat(event1).isNotNull(); 767 CarDiagnosticEvent event2 = listener2.waitForEvent(time); 768 assertThat(event2).isNotNull(); 769 770 assertTrue(event1.equals(event1)); 771 assertTrue(event2.equals(event2)); 772 assertTrue(event1.equals(event2)); 773 assertTrue(event2.equals(event1)); 774 775 assertTrue(event1.hashCode() == event1.hashCode()); 776 assertTrue(event1.hashCode() == event2.hashCode()); 777 778 assertEquals( 779 5000, 780 event1.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START) 781 .intValue()); 782 assertEquals( 783 5000, 784 event2.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START) 785 .intValue()); 786 787 listener1.reset(); 788 listener2.reset(); 789 790 mCarDiagnosticManager.unregisterListener(listener1); 791 792 time += 1000; 793 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time)); 794 assertThat(listener1.waitForEvent(time)).isNull(); 795 796 event2 = listener2.waitForEvent(time); 797 assertThat(event2).isNotNull(); 798 799 assertTrue(event1.isEarlierThan(event2)); 800 assertFalse(event1.equals(event2)); 801 assertFalse(event2.equals(event1)); 802 803 assertEquals( 804 5000, 805 event2.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START) 806 .intValue()); 807 } 808 809 @Test testFreezeFrameEvent()810 public void testFreezeFrameEvent() throws Exception { 811 Listener listener = new Listener(); 812 mCarDiagnosticManager.registerListener( 813 listener, 814 CarDiagnosticManager.FRAME_TYPE_FREEZE, 815 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 816 817 listener.reset(); 818 VehiclePropValue injectedEvent = 819 mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder); 820 getAidlMockedVehicleHal().injectEvent(injectedEvent); 821 CarDiagnosticEvent freezeFrame = listener.waitForEvent(injectedEvent.timestamp); 822 823 assertThat(freezeFrame).isNotNull(); 824 assertEquals(DTC, freezeFrame.dtc); 825 826 mFreezeFrameEventBuilder.addIntSensor( 827 IntegerSensorIndex.ABSOLUTE_BAROMETRIC_PRESSURE, 22); 828 injectedEvent = mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder); 829 getAidlMockedVehicleHal().injectEvent(injectedEvent); 830 freezeFrame = listener.waitForEvent(injectedEvent.timestamp); 831 832 assertThat(freezeFrame).isNotNull(); 833 assertThat(freezeFrame).isNotNull(); 834 assertFalse(freezeFrame.isLiveFrame()); 835 assertTrue(freezeFrame.isFreezeFrame()); 836 assertFalse(freezeFrame.isEmptyFrame()); 837 838 assertEquals(DTC, freezeFrame.dtc); 839 assertEquals( 840 22, 841 freezeFrame 842 .getSystemIntegerSensor(IntegerSensorIndex.ABSOLUTE_BAROMETRIC_PRESSURE) 843 .intValue()); 844 } 845 846 @Test testFreezeFrameTimestamps()847 public void testFreezeFrameTimestamps() throws Exception { 848 Listener listener = new Listener(); 849 mCarDiagnosticManager.registerListener( 850 listener, 851 CarDiagnosticManager.FRAME_TYPE_FREEZE, 852 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 853 854 Set<Long> generatedTimestamps = new HashSet<>(); 855 856 VehiclePropValue injectedEvent = 857 mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder); 858 getAidlMockedVehicleHal().injectEvent(injectedEvent); 859 generatedTimestamps.add(injectedEvent.timestamp); 860 assertThat(listener.waitForEvent(injectedEvent.timestamp)).isNotNull(); 861 862 injectedEvent = 863 mFreezeFrameProperties.addNewEvent( 864 mFreezeFrameEventBuilder, injectedEvent.timestamp + 1000); 865 getAidlMockedVehicleHal().injectEvent(injectedEvent); 866 generatedTimestamps.add(injectedEvent.timestamp); 867 assertThat(listener.waitForEvent(injectedEvent.timestamp)).isNotNull(); 868 869 long[] acquiredTimestamps = mCarDiagnosticManager.getFreezeFrameTimestamps(); 870 assertEquals(generatedTimestamps.size(), acquiredTimestamps.length); 871 for (long acquiredTimestamp : acquiredTimestamps) { 872 assertTrue(generatedTimestamps.contains(acquiredTimestamp)); 873 } 874 } 875 876 @Test testClearFreezeFrameTimestamps()877 public void testClearFreezeFrameTimestamps() throws Exception { 878 Listener listener = new Listener(); 879 mCarDiagnosticManager.registerListener( 880 listener, 881 CarDiagnosticManager.FRAME_TYPE_FREEZE, 882 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 883 884 VehiclePropValue injectedEvent = 885 mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder); 886 getAidlMockedVehicleHal().injectEvent(injectedEvent); 887 assertThat(listener.waitForEvent(injectedEvent.timestamp)).isNotNull(); 888 889 assertThat(mCarDiagnosticManager.getFreezeFrame(injectedEvent.timestamp)).isNotNull(); 890 mCarDiagnosticManager.clearFreezeFrames(injectedEvent.timestamp); 891 assertThat(mCarDiagnosticManager.getFreezeFrame(injectedEvent.timestamp)).isNull(); 892 } 893 894 @Test testClearFreezeFrameTimestamps_ErrorCodeFromHal()895 public void testClearFreezeFrameTimestamps_ErrorCodeFromHal() { 896 long timestamp = SystemClock.elapsedRealtimeNanos(); 897 // All the exceptions from the HAL should not be propagated up. 898 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus( 899 VehicleHalStatusCode.STATUS_TRY_AGAIN); 900 mCarDiagnosticManager.clearFreezeFrames(timestamp); 901 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus( 902 VehicleHalStatusCode.STATUS_INVALID_ARG); 903 mCarDiagnosticManager.clearFreezeFrames(timestamp); 904 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus( 905 VehicleHalStatusCode.STATUS_NOT_AVAILABLE); 906 mCarDiagnosticManager.clearFreezeFrames(timestamp); 907 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus( 908 VehicleHalStatusCode.STATUS_ACCESS_DENIED); 909 mCarDiagnosticManager.clearFreezeFrames(timestamp); 910 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus( 911 VehicleHalStatusCode.STATUS_INTERNAL_ERROR); 912 mCarDiagnosticManager.clearFreezeFrames(timestamp); 913 914 // Clear the status code. 915 mFreezeFrameProperties.mFreezeFrameClearHandler.setStatus(VehicleHalStatusCode.STATUS_OK); 916 } 917 918 @Test testListenerUnregister()919 public void testListenerUnregister() throws Exception { 920 Listener listener1 = new Listener(); 921 Listener listener2 = new Listener(); 922 mCarDiagnosticManager.registerListener( 923 listener1, 924 CarDiagnosticManager.FRAME_TYPE_LIVE, 925 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 926 mCarDiagnosticManager.registerListener( 927 listener1, 928 CarDiagnosticManager.FRAME_TYPE_FREEZE, 929 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 930 931 mCarDiagnosticManager.unregisterListener(listener1); 932 933 // you need a listener to be registered before MockedVehicleHal will actually dispatch 934 // your events - add one, but do it *after* unregistering the first listener 935 mCarDiagnosticManager.registerListener( 936 listener2, 937 CarDiagnosticManager.FRAME_TYPE_LIVE, 938 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 939 mCarDiagnosticManager.registerListener( 940 listener2, 941 CarDiagnosticManager.FRAME_TYPE_FREEZE, 942 android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL); 943 944 VehiclePropValue injectedEvent = 945 mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder); 946 long time = injectedEvent.timestamp; 947 getAidlMockedVehicleHal().injectEvent(injectedEvent); 948 assertThat(listener1.waitForEvent(time)).isNull(); 949 assertThat(listener2.waitForEvent(time)).isNotNull(); 950 951 time += 1000; 952 getAidlMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time)); 953 assertThat(listener1.waitForEvent(time)).isNull(); 954 assertThat(listener2.waitForEvent(time)).isNotNull(); 955 } 956 957 @Test testIsSupportedApiCalls()958 public void testIsSupportedApiCalls() throws Exception { 959 assertTrue(mCarDiagnosticManager.isLiveFrameSupported()); 960 assertTrue(mCarDiagnosticManager.isFreezeFrameNotificationSupported()); 961 assertTrue(mCarDiagnosticManager.isGetFreezeFrameSupported()); 962 assertTrue(mCarDiagnosticManager.isClearFreezeFramesSupported()); 963 assertTrue(mCarDiagnosticManager.isSelectiveClearFreezeFramesSupported()); 964 } 965 966 class Listener implements CarDiagnosticManager.OnDiagnosticEventListener { 967 private final Object mLock = new Object(); 968 969 @GuardedBy("mLock") 970 private final List<CarDiagnosticEvent> mEvents = new ArrayList<>(); 971 @GuardedBy("mLock") 972 private long mEventTimestamp; 973 // By default we are not waiting for any event. When we start waiting for an event, a new 974 // CountDownLatch with count 1 will be used. 975 @GuardedBy("mLock") 976 private CountDownLatch mCountDownLatch; 977 978 @GuardedBy("mLock") checkReceivedEventsLocked(long eventTimeStamp)979 private CarDiagnosticEvent checkReceivedEventsLocked(long eventTimeStamp) { 980 for (int i = 0; i < mEvents.size(); i++) { 981 if (mEventTimestamp == 0 || mEvents.get(i).timestamp == eventTimeStamp) { 982 return mEvents.get(i); 983 } 984 } 985 return null; 986 } 987 reset()988 void reset() { 989 synchronized (mLock) { 990 mEvents.clear(); 991 } 992 } 993 waitForEvent()994 CarDiagnosticEvent waitForEvent() { 995 return waitForEvent(0); 996 } 997 998 // Wait for a event with certain eventTimeStamp to happen. waitForEvent(long eventTimeStamp)999 CarDiagnosticEvent waitForEvent(long eventTimeStamp) { 1000 CountDownLatch countDownlatch; 1001 synchronized (mLock) { 1002 mEventTimestamp = eventTimeStamp; 1003 mCountDownLatch = new CountDownLatch(1); 1004 CarDiagnosticEvent matchedEvent = checkReceivedEventsLocked(eventTimeStamp); 1005 if (matchedEvent != null) { 1006 return matchedEvent; 1007 } 1008 countDownlatch = mCountDownLatch; 1009 } 1010 silentAwait(countDownlatch, DEFAULT_WAIT_TIMEOUT_MS); 1011 synchronized (mLock) { 1012 // Set the latch to null to indicate we are not waiting for an event any more. 1013 mCountDownLatch = null; 1014 return checkReceivedEventsLocked(eventTimeStamp); 1015 } 1016 } 1017 1018 @Override onDiagnosticEvent(CarDiagnosticEvent event)1019 public void onDiagnosticEvent(CarDiagnosticEvent event) { 1020 synchronized (mLock) { 1021 mEvents.add(event); 1022 if (mCountDownLatch == null) { 1023 return; 1024 } 1025 // If we are currently waiting for an event, check whether we have a match. 1026 if (mEventTimestamp == 0 || event.timestamp == mEventTimestamp) { 1027 mCountDownLatch.countDown(); 1028 } 1029 } 1030 } 1031 } 1032 } 1033