1093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata/*
2093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * Copyright (C) 2017 The Android Open Source Project
3093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata *
4093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * Licensed under the Apache License, Version 2.0 (the "License");
5093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * you may not use this file except in compliance with the License.
6093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * You may obtain a copy of the License at
7093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata *
8093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata *      http://www.apache.org/licenses/LICENSE-2.0
9093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata *
10093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * Unless required by applicable law or agreed to in writing, software
11093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * distributed under the License is distributed on an "AS IS" BASIS,
12093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * See the License for the specific language governing permissions and
14093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata * limitations under the License.
15093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata */
16093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
17093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granatapackage com.android.car.test;
18093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
19093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport static java.lang.Integer.toHexString;
20093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
21093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport android.car.Car;
2225e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent;
2325e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.FuelSystemStatus;
2425e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.FuelType;
2525e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.CommonIgnitionMonitors;
2625e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.CompressionIgnitionMonitors;
2725e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.SparkIgnitionMonitors;
2825e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticEvent.SecondaryAirStatus;
2925e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.CarDiagnosticManager;
3025e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.FloatSensorIndex;
3125e89468119cd0b109f62c751446dfdd8e903143Enrico Granataimport android.car.diagnostic.IntegerSensorIndex;
32093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
3399e1a7555a9521c33203b68c5ab5bd1c039ee712Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehicleProperty;
34093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport android.os.SystemClock;
35093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport android.test.suitebuilder.annotation.MediumTest;
36ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granataimport android.util.JsonReader;
37ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granataimport android.util.JsonWriter;
384514e96614b219235037cb724787ed74d6f7e080Enrico Granataimport android.util.Log;
3987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granataimport com.android.car.vehiclehal.DiagnosticEventBuilder;
40ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granataimport com.android.car.vehiclehal.DiagnosticJson;
41093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport com.android.car.vehiclehal.VehiclePropValueBuilder;
42093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
43ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granataimport java.io.StringReader;
44ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granataimport java.io.StringWriter;
45093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport java.util.Arrays;
46093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport java.util.HashMap;
47093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport java.util.HashSet;
48093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granataimport java.util.Set;
49093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
50093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata/** Test the public entry points for the CarDiagnosticManager */
51093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata@MediumTest
52093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granatapublic class CarDiagnosticManagerTest extends MockedCarTestBase {
53093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private static final String TAG = CarDiagnosticManagerTest.class.getSimpleName();
54093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
55093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private final DiagnosticEventBuilder mLiveFrameEventBuilder =
56093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            new DiagnosticEventBuilder(VehicleProperty.OBD2_LIVE_FRAME);
57093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private final DiagnosticEventBuilder mFreezeFrameEventBuilder =
58093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            new DiagnosticEventBuilder(VehicleProperty.OBD2_FREEZE_FRAME);
59093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private final FreezeFrameProperties mFreezeFrameProperties = new FreezeFrameProperties();
60093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
61093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private CarDiagnosticManager mCarDiagnosticManager;
62093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
63093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    private static final String DTC = "P1010";
64093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
65093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    /**
66093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata     * This class is a central repository for freeze frame data. It ensures that timestamps and
67093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata     * events are kept in sync and provides a consistent access model for diagnostic properties.
68093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata     */
69093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    class FreezeFrameProperties {
70093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        private final HashMap<Long, VehiclePropValue> mEvents = new HashMap<>();
71093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
72093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        public final VehicleHalPropertyHandler mFreezeFrameInfoHandler =
73093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                new FreezeFrameInfoHandler();
74093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        public final VehicleHalPropertyHandler mFreezeFrameHandler = new FreezeFrameHandler();
75093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        public final VehicleHalPropertyHandler mFreezeFrameClearHandler =
76093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                new FreezeFrameClearHandler();
77093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
78093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized VehiclePropValue addNewEvent(DiagnosticEventBuilder builder) {
79093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            long timestamp = SystemClock.elapsedRealtimeNanos();
80093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return addNewEvent(builder, timestamp);
81093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
82093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
83093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized VehiclePropValue addNewEvent(DiagnosticEventBuilder builder, long timestamp) {
84093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            VehiclePropValue newEvent = builder.build(timestamp);
85093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            mEvents.put(timestamp, newEvent);
86093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return newEvent;
87093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
88093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
89093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized VehiclePropValue removeEvent(long timestamp) {
90093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return mEvents.remove(timestamp);
91093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
92093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
93093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized void removeEvents() {
94093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            mEvents.clear();
95093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
96093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
97093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized long[] getTimestamps() {
98093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return mEvents.keySet().stream().mapToLong(Long::longValue).toArray();
99093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
100093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
101093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        synchronized VehiclePropValue getEvent(long timestamp) {
102093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return mEvents.get(timestamp);
103093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
104093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
105093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        class FreezeFramePropertyHandler implements VehicleHalPropertyHandler {
106093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            private boolean mSubscribed = false;
107093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
108093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            protected final int VEHICLE_PROPERTY;
109093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
110093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            protected FreezeFramePropertyHandler(int propertyId) {
111093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                VEHICLE_PROPERTY = propertyId;
112093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
113093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
114093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
115093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized void onPropertySet(VehiclePropValue value) {
116093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                assertEquals(VEHICLE_PROPERTY, value.prop);
117093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
118093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
119093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
120093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
121093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                assertEquals(VEHICLE_PROPERTY, value.prop);
122093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                return null;
123093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
124093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
125093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
126093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized void onPropertySubscribe(
127093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    int property, int zones, float sampleRate) {
128093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                assertEquals(VEHICLE_PROPERTY, property);
129093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mSubscribed = true;
130093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
131093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
132093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
133093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized void onPropertyUnsubscribe(int property) {
134093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                assertEquals(VEHICLE_PROPERTY, property);
135093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                if (!mSubscribed) {
136093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    throw new IllegalArgumentException(
137093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                            "Property was not subscribed 0x" + toHexString(property));
138093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                }
139093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mSubscribed = false;
140093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
141093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
142093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
143093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        class FreezeFrameInfoHandler extends FreezeFramePropertyHandler {
144093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            FreezeFrameInfoHandler() {
145093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super(VehicleProperty.OBD2_FREEZE_FRAME_INFO);
146093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
147093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
148093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
149093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
150093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super.onPropertyGet(value);
151093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                VehiclePropValueBuilder builder =
152093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        VehiclePropValueBuilder.newBuilder(VEHICLE_PROPERTY);
153093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                builder.setInt64Value(getTimestamps());
154093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                return builder.build();
155093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
156093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
157093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
158093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        class FreezeFrameHandler extends FreezeFramePropertyHandler {
159093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            FreezeFrameHandler() {
160093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super(VehicleProperty.OBD2_FREEZE_FRAME);
161093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
162093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
163093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
164093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized VehiclePropValue onPropertyGet(VehiclePropValue value) {
165093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super.onPropertyGet(value);
166093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                long timestamp = value.value.int64Values.get(0);
167093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                return getEvent(timestamp);
168093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
169093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
170093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
171093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        class FreezeFrameClearHandler extends FreezeFramePropertyHandler {
172093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            FreezeFrameClearHandler() {
173093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR);
174093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
175093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
176093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            @Override
177093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            public synchronized void onPropertySet(VehiclePropValue value) {
178093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                super.onPropertySet(value);
179093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                if (0 == value.value.int64Values.size()) {
180093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    removeEvents();
181093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                } else {
182093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    for (long timestamp : value.value.int64Values) {
183093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        removeEvent(timestamp);
184093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    }
185093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                }
186093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
187093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
188093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
189093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
190093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    @Override
191093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    protected synchronized void configureMockedHal() {
192093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        java.util.Collection<Integer> numVendorSensors = Arrays.asList(0, 0);
193093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        addProperty(VehicleProperty.OBD2_LIVE_FRAME, mLiveFrameEventBuilder.build())
194093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                .setConfigArray(numVendorSensors);
195093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        addProperty(
196093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                VehicleProperty.OBD2_FREEZE_FRAME_INFO,
197093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.mFreezeFrameInfoHandler);
198093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        addProperty(VehicleProperty.OBD2_FREEZE_FRAME, mFreezeFrameProperties.mFreezeFrameHandler)
199093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                .setConfigArray(numVendorSensors);
200093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        addProperty(
201093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                VehicleProperty.OBD2_FREEZE_FRAME_CLEAR,
202093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.mFreezeFrameClearHandler);
203093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
204093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
205093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    @Override
206093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    protected void setUp() throws Exception {
207976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE, 30);
20887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        mLiveFrameEventBuilder.addIntSensor(
209976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.FUEL_SYSTEM_STATUS,
21087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION);
211093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mLiveFrameEventBuilder.addIntSensor(
212976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5000);
213976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE, 2);
214976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.CALCULATED_ENGINE_LOAD, 0.125f);
215976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.VEHICLE_SPEED, 12.5f);
216093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
217976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mFreezeFrameEventBuilder.addIntSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE, 30);
218093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mFreezeFrameEventBuilder.addIntSensor(
219976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5000);
220976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mFreezeFrameEventBuilder.addIntSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE, 2);
221093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mFreezeFrameEventBuilder.addFloatSensor(
222976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                FloatSensorIndex.CALCULATED_ENGINE_LOAD, 0.125f);
223976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mFreezeFrameEventBuilder.addFloatSensor(FloatSensorIndex.VEHICLE_SPEED, 12.5f);
224093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mFreezeFrameEventBuilder.setDTC(DTC);
225093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
226093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        super.setUp();
227093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
228b3634e209ebcfe2cb987f70cea264bf8b07c3e15Enrico Granata        Log.i(TAG, "attempting to get DIAGNOSTIC_SERVICE");
229b3634e209ebcfe2cb987f70cea264bf8b07c3e15Enrico Granata        mCarDiagnosticManager =
230b3634e209ebcfe2cb987f70cea264bf8b07c3e15Enrico Granata                (CarDiagnosticManager) getCar().getCarManager(Car.DIAGNOSTIC_SERVICE);
231093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
232093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
233093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testLiveFrameRead() throws Exception {
234093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = mCarDiagnosticManager.getLatestLiveFrame();
235093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
236093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
237093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(liveFrame.isLiveFrame());
238093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(liveFrame.isFreezeFrame());
239093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(liveFrame.isEmptyFrame());
240093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
241093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
242093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                5000,
243093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame
244976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START)
245093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .intValue());
246093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
247093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                30,
248093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame
249976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.AMBIENT_AIR_TEMPERATURE)
250093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .intValue());
251093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
252093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                2,
253093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame
254976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.CONTROL_MODULE_VOLTAGE)
255093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .intValue());
256093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
257093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                0.125f,
258093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame
259976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemFloatSensor(FloatSensorIndex.CALCULATED_ENGINE_LOAD)
260093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .floatValue());
26187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
26287c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                12.5f,
263976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                liveFrame.getSystemFloatSensor(FloatSensorIndex.VEHICLE_SPEED).floatValue());
264093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
265093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
266093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testLiveFrameEvent() throws Exception {
267093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
268093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
269093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                listener,
2705e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
271093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
272093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
273093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener.reset();
274093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long time = SystemClock.elapsedRealtimeNanos();
275093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mLiveFrameEventBuilder.addIntSensor(
276976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START, 5100);
277093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
278093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time));
279093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(time));
280093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
281093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
282093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
283093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
284093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                5100,
285093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame
286976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START)
287093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .intValue());
288093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
289093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
290093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testMissingSensorRead() throws Exception {
291093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
292093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
29387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener,
2945e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
29587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
296093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
297093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build());
298093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent());
299093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
300093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
301093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
302093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
30387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertNull(
30487c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                liveFrame.getSystemIntegerSensor(
305976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        IntegerSensorIndex.DRIVER_DEMAND_PERCENT_TORQUE));
30687c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
30787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                -1,
30887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                liveFrame.getSystemIntegerSensor(
309976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        IntegerSensorIndex.DRIVER_DEMAND_PERCENT_TORQUE, -1));
310093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
311976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        assertNull(liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR6_VOLTAGE));
31287c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
31387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                0.25f,
314976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR5_VOLTAGE, 0.25f));
315093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
316976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        assertNull(liveFrame.getVendorIntegerSensor(IntegerSensorIndex.VENDOR_START));
317976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        assertEquals(-1, liveFrame.getVendorIntegerSensor(IntegerSensorIndex.VENDOR_START, -1));
318093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
319976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        assertNull(liveFrame.getVendorFloatSensor(FloatSensorIndex.VENDOR_START));
32087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
321976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                0.25f, liveFrame.getVendorFloatSensor(FloatSensorIndex.VENDOR_START, 0.25f));
322093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
323093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
324093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testFuelSystemStatus() throws Exception {
325093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
326093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
32787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener,
3285e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
32987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
330093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
331093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build());
332093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent());
333093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
334093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
335093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
336093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
33787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
33887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION,
33987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                liveFrame
340976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.FUEL_SYSTEM_STATUS)
34187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .intValue());
34287c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
34387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                FuelSystemStatus.OPEN_ENGINE_LOAD_OR_DECELERATION,
344093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                liveFrame.getFuelSystemStatus().intValue());
345093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
346093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
347093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testSecondaryAirStatus() throws Exception {
348093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
349093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
35087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener,
3515e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
35287c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
353093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
35487c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        mLiveFrameEventBuilder.addIntSensor(
355976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.COMMANDED_SECONDARY_AIR_STATUS,
35687c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                SecondaryAirStatus.FROM_OUTSIDE_OR_OFF);
357093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long timestamp = SystemClock.elapsedRealtimeNanos();
358093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp));
359093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
360093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(timestamp));
361093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
362093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
363093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
364093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
36587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
36687c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                SecondaryAirStatus.FROM_OUTSIDE_OR_OFF,
36787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                liveFrame
36887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .getSystemIntegerSensor(
369976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                                IntegerSensorIndex.COMMANDED_SECONDARY_AIR_STATUS)
37087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .intValue());
37187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
37287c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                SecondaryAirStatus.FROM_OUTSIDE_OR_OFF,
37387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                liveFrame.getSecondaryAirStatus().intValue());
374093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
375093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
376093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testIgnitionMonitors() throws Exception {
377093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
378093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
37987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener,
3805e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
38187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
382093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
383093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        // cfr. CarDiagnosticEvent for the meaning of the several bits
38487c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        final int sparkMonitorsValue =
38587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                0x1 | (0x1 << 2) | (0x1 << 3) | (0x1 << 6) | (0x1 << 10) | (0x1 << 11);
386093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
38787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        final int compressionMonitorsValue =
38887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                (0x1 << 2) | (0x1 << 3) | (0x1 << 6) | (0x1 << 12) | (0x1 << 13);
389093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
390976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.IGNITION_MONITORS_SUPPORTED, 0);
39187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        mLiveFrameEventBuilder.addIntSensor(
392976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.IGNITION_SPECIFIC_MONITORS, sparkMonitorsValue);
393093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
394093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long timestamp = SystemClock.elapsedRealtimeNanos();
395093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp));
396093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
397093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(timestamp));
398093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
399093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
400093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
401093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
402093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CommonIgnitionMonitors commonIgnitionMonitors = liveFrame.getIgnitionMonitors();
403093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(commonIgnitionMonitors);
404093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(commonIgnitionMonitors.components.available);
405093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.components.incomplete);
406093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(commonIgnitionMonitors.fuelSystem.available);
407093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(commonIgnitionMonitors.fuelSystem.incomplete);
408093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.misfire.available);
409093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.misfire.incomplete);
410093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
411093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        SparkIgnitionMonitors sparkIgnitionMonitors =
412093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                commonIgnitionMonitors.asSparkIgnitionMonitors();
413093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(sparkIgnitionMonitors);
414093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNull(commonIgnitionMonitors.asCompressionIgnitionMonitors());
415093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
416093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(sparkIgnitionMonitors.EGR.available);
417093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.EGR.incomplete);
418093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.oxygenSensorHeater.available);
419093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.oxygenSensorHeater.incomplete);
420093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(sparkIgnitionMonitors.oxygenSensor.available);
421093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(sparkIgnitionMonitors.oxygenSensor.incomplete);
422093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.ACRefrigerant.available);
423093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.ACRefrigerant.incomplete);
424093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.secondaryAirSystem.available);
425093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.secondaryAirSystem.incomplete);
426093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.evaporativeSystem.available);
427093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.evaporativeSystem.incomplete);
428093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.heatedCatalyst.available);
429093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.heatedCatalyst.incomplete);
430093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.catalyst.available);
431093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(sparkIgnitionMonitors.catalyst.incomplete);
432093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
433976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.IGNITION_MONITORS_SUPPORTED, 1);
43487c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        mLiveFrameEventBuilder.addIntSensor(
435976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.IGNITION_SPECIFIC_MONITORS, compressionMonitorsValue);
436093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
437093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        timestamp += 1000;
438093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp));
439093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
440093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(timestamp));
441093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
442093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        liveFrame = listener.getLastEvent();
443093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
444093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(timestamp, liveFrame.timestamp);
445093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
446093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        commonIgnitionMonitors = liveFrame.getIgnitionMonitors();
447093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(commonIgnitionMonitors);
448093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.components.available);
449093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.components.incomplete);
450093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(commonIgnitionMonitors.fuelSystem.available);
451093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(commonIgnitionMonitors.fuelSystem.incomplete);
452093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.misfire.available);
453093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(commonIgnitionMonitors.misfire.incomplete);
454093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CompressionIgnitionMonitors compressionIgnitionMonitors =
45587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                commonIgnitionMonitors.asCompressionIgnitionMonitors();
456093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNull(commonIgnitionMonitors.asSparkIgnitionMonitors());
457093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(compressionIgnitionMonitors);
458093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
459093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(compressionIgnitionMonitors.EGROrVVT.available);
460093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.EGROrVVT.incomplete);
461093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.PMFilter.available);
462093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.PMFilter.incomplete);
463093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.exhaustGasSensor.available);
464093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.exhaustGasSensor.incomplete);
465093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(compressionIgnitionMonitors.boostPressure.available);
466093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(compressionIgnitionMonitors.boostPressure.incomplete);
467093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.NOxSCR.available);
468093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.NOxSCR.incomplete);
469093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.NMHCCatalyst.available);
470093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(compressionIgnitionMonitors.NMHCCatalyst.incomplete);
471093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
472093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
473093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testFuelType() throws Exception {
474093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
475093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
47687c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener,
4775e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
47887c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
479093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
48087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        mLiveFrameEventBuilder.addIntSensor(
481976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.FUEL_TYPE, FuelType.BIFUEL_RUNNING_LPG);
482093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long timestamp = SystemClock.elapsedRealtimeNanos();
483093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp));
484093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
485093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(timestamp));
486093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
487093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
488093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(liveFrame);
489093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
49087c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(
49187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                FuelType.BIFUEL_RUNNING_LPG,
492976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                liveFrame.getSystemIntegerSensor(IntegerSensorIndex.FUEL_TYPE).intValue());
49387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata        assertEquals(FuelType.BIFUEL_RUNNING_LPG, liveFrame.getFuelType().intValue());
494093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
495093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
496ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata    public void testDiagnosticJson() throws Exception {
497ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        Listener listener = new Listener();
498ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        mCarDiagnosticManager.registerListener(
499ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                listener,
5005e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
501ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
502ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
503976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addIntSensor(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE, 74);
504976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata        mLiveFrameEventBuilder.addFloatSensor(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE, 0.125f);
505ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
506ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        long timestamp = SystemClock.elapsedRealtimeNanos();
507ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(timestamp));
508ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
509ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertTrue(listener.waitForEvent(timestamp));
510ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
511ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        CarDiagnosticEvent liveFrame = listener.getLastEvent();
512ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertNotNull(liveFrame);
513ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
514ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertEquals(
515ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                74,
516ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                liveFrame
517976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE)
518ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                        .intValue());
519ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertEquals(
520ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                0.125f,
521976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                liveFrame.getSystemFloatSensor(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE));
522ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
523ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        StringWriter stringWriter = new StringWriter();
524ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        JsonWriter jsonWriter = new JsonWriter(stringWriter);
525ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
526ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        liveFrame.writeToJson(jsonWriter);
527ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        jsonWriter.flush();
528ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
529ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        StringReader stringReader = new StringReader(stringWriter.toString());
530ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        JsonReader jsonReader = new JsonReader(stringReader);
531ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        DiagnosticJson diagnosticJson = DiagnosticJson.build(jsonReader);
532ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
533ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertEquals(
534ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                74,
535ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                diagnosticJson
536ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                        .intValues
537976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .get(IntegerSensorIndex.ENGINE_OIL_TEMPERATURE)
538ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                        .intValue());
539ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata        assertEquals(
540ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata                0.125f,
541976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                diagnosticJson.floatValues.get(FloatSensorIndex.OXYGEN_SENSOR1_VOLTAGE));
542ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata    }
543ce7ee20db58fd3816dcdd19dc1e2f6c8f26b0d5aEnrico Granata
544093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testMultipleListeners() throws Exception {
545093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener1 = new Listener();
546093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener2 = new Listener();
547093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
548093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
54987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener1,
5505e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
55187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
552093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
55387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                listener2,
5545e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_LIVE,
55587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
556093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
557093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener1.reset();
558093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener2.reset();
559093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
560093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long time = SystemClock.elapsedRealtimeNanos();
561093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time));
562093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener1.waitForEvent(time));
563093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener2.waitForEvent(time));
564093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
565093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent event1 = listener1.getLastEvent();
566093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent event2 = listener2.getLastEvent();
567101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata
568101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event1.equals(event1));
569101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event2.equals(event2));
570101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event1.equals(event2));
571101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event2.equals(event1));
572101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata
573101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event1.hashCode() == event1.hashCode());
574101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertTrue(event1.hashCode() == event2.hashCode());
575101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata
576093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
57787c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                5000,
578976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                event1.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START)
57987c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .intValue());
580093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
58187c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                5000,
582976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                event2.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START)
58387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .intValue());
584093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
585093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener1.reset();
586093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener2.reset();
587093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
588093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.unregisterListener(listener1);
589093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
590093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        time += 1000;
591093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time));
592093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(listener1.waitForEvent(time));
593093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener2.waitForEvent(time));
594093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
595093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNull(listener1.getLastEvent());
596093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        event2 = listener2.getLastEvent();
597093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
598093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(event1.isEarlierThan(event2));
599101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertFalse(event1.equals(event2));
600101675784689f94cfc2a7c238e38fb84debcc527Enrico Granata        assertFalse(event2.equals(event1));
601093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
602093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
60387c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                5000,
604976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                event2.getSystemIntegerSensor(IntegerSensorIndex.RUNTIME_SINCE_ENGINE_START)
60587c0545b6f0814657df555902300d7b3dfe6b96fEnrico Granata                        .intValue());
606093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
607093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
608093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testFreezeFrameEvent() throws Exception {
609093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
610093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
611093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                listener,
6125e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_FREEZE,
613093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
614093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
615093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        listener.reset();
616093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        VehiclePropValue injectedEvent =
617093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder);
618093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
619093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(injectedEvent.timestamp));
620093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
621093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent freezeFrame = listener.getLastEvent();
622093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
623093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(DTC, freezeFrame.dtc);
624093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
625093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mFreezeFrameEventBuilder.addIntSensor(
626976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                IntegerSensorIndex.ABSOLUTE_BAROMETRIC_PRESSURE, 22);
627093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        injectedEvent = mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder);
628093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
629093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(injectedEvent.timestamp));
630093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
631093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        freezeFrame = listener.getLastEvent();
632093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
633093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(freezeFrame);
634093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(freezeFrame.isLiveFrame());
635093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(freezeFrame.isFreezeFrame());
636093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertFalse(freezeFrame.isEmptyFrame());
637093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
638093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(DTC, freezeFrame.dtc);
639093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(
640093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                22,
641093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                freezeFrame
642976cee4a3583c66599e364badf9024df5022ee7aEnrico Granata                        .getSystemIntegerSensor(IntegerSensorIndex.ABSOLUTE_BAROMETRIC_PRESSURE)
643093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        .intValue());
644093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
645093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
646093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testFreezeFrameTimestamps() throws Exception {
647093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
648093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
649093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                listener,
6505e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_FREEZE,
651093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
652093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
653093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Set<Long> generatedTimestamps = new HashSet<>();
654093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
655093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        VehiclePropValue injectedEvent =
656093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder);
657093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
658093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        generatedTimestamps.add(injectedEvent.timestamp);
659093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(injectedEvent.timestamp));
660093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
661093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        injectedEvent =
662093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.addNewEvent(
663093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        mFreezeFrameEventBuilder, injectedEvent.timestamp + 1000);
664093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
665093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        generatedTimestamps.add(injectedEvent.timestamp);
666093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(injectedEvent.timestamp));
667093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
668093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        long[] acquiredTimestamps = mCarDiagnosticManager.getFreezeFrameTimestamps();
669093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertEquals(generatedTimestamps.size(), acquiredTimestamps.length);
670093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        for (long acquiredTimestamp : acquiredTimestamps) {
671093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            assertTrue(generatedTimestamps.contains(acquiredTimestamp));
672093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
673093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
674093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
675093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    public void testClearFreezeFrameTimestamps() throws Exception {
676093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        Listener listener = new Listener();
677093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.registerListener(
678093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                listener,
6795e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata                CarDiagnosticManager.FRAME_TYPE_FREEZE,
680093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
681093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
682093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        VehiclePropValue injectedEvent =
683093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder);
684093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
685093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertTrue(listener.waitForEvent(injectedEvent.timestamp));
686093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
687093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNotNull(mCarDiagnosticManager.getFreezeFrame(injectedEvent.timestamp));
688093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        mCarDiagnosticManager.clearFreezeFrames(injectedEvent.timestamp);
689093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        assertNull(mCarDiagnosticManager.getFreezeFrame(injectedEvent.timestamp));
690093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
691093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
692d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata    public void testListenerUnregister() throws Exception {
693d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        Listener listener1 = new Listener();
694d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        Listener listener2 = new Listener();
695d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        mCarDiagnosticManager.registerListener(
696d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            listener1,
6975e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata            CarDiagnosticManager.FRAME_TYPE_LIVE,
698d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
699d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        mCarDiagnosticManager.registerListener(
700d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            listener1,
7015e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata            CarDiagnosticManager.FRAME_TYPE_FREEZE,
702d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
703d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata
704d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        mCarDiagnosticManager.unregisterListener(listener1);
705d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata
706d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        // you need a listener to be registered before MockedVehicleHal will actually dispatch
707d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        // your events - add one, but do it *after* unregistering the first listener
708d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        mCarDiagnosticManager.registerListener(
709d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            listener2,
7105e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata            CarDiagnosticManager.FRAME_TYPE_LIVE,
711d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
712d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        mCarDiagnosticManager.registerListener(
713d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            listener2,
7145e075dac94101efe1bdcde105b8c4194eb9e70d0Enrico Granata            CarDiagnosticManager.FRAME_TYPE_FREEZE,
715d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            android.car.hardware.CarSensorManager.SENSOR_RATE_NORMAL);
716d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata
717d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        VehiclePropValue injectedEvent =
718d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata            mFreezeFrameProperties.addNewEvent(mFreezeFrameEventBuilder);
719d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        long time = injectedEvent.timestamp;
720d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        getMockedVehicleHal().injectEvent(injectedEvent);
721d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        assertFalse(listener1.waitForEvent(time));
722d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        assertTrue(listener2.waitForEvent(time));
723d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata
724d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        time += 1000;
725d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        getMockedVehicleHal().injectEvent(mLiveFrameEventBuilder.build(time));
726d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        assertFalse(listener1.waitForEvent(time));
727d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata        assertTrue(listener2.waitForEvent(time));
728d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata    }
729d5d01006420539d473cffe8e7e2087542374f3aeEnrico Granata
730c2393683cf3c144461fe2ba28f4fa8cd817d8cb1Enrico Granata    public void testIsSupportedApiCalls() throws Exception {
731c2393683cf3c144461fe2ba28f4fa8cd817d8cb1Enrico Granata        assertTrue(mCarDiagnosticManager.isLiveFrameSupported());
7322e3b49a9f99a0886d8e10832801022c223b3984dEnrico Granata        assertTrue(mCarDiagnosticManager.isFreezeFrameNotificationSupported());
7332e3b49a9f99a0886d8e10832801022c223b3984dEnrico Granata        assertTrue(mCarDiagnosticManager.isGetFreezeFrameSupported());
7342e3b49a9f99a0886d8e10832801022c223b3984dEnrico Granata        assertTrue(mCarDiagnosticManager.isClearFreezeFramesSupported());
735c2393683cf3c144461fe2ba28f4fa8cd817d8cb1Enrico Granata    }
736c2393683cf3c144461fe2ba28f4fa8cd817d8cb1Enrico Granata
737093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    class Listener implements CarDiagnosticManager.OnDiagnosticEventListener {
738093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        private final Object mSync = new Object();
739093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
740093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        private CarDiagnosticEvent mLastEvent = null;
741093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
742093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        CarDiagnosticEvent getLastEvent() {
743093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return mLastEvent;
744093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
745093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
746093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        void reset() {
747093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            synchronized (mSync) {
748093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mLastEvent = null;
749093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
750093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
751093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
752093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        boolean waitForEvent() throws InterruptedException {
753093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            return waitForEvent(0);
754093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
755093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
756093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        boolean waitForEvent(long eventTimeStamp) throws InterruptedException {
757093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            long start = SystemClock.elapsedRealtime();
758093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            boolean matchTimeStamp = eventTimeStamp != 0;
759093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            synchronized (mSync) {
760093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                while ((mLastEvent == null
761093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                                || (matchTimeStamp && mLastEvent.timestamp != eventTimeStamp))
762093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        && (start + SHORT_WAIT_TIMEOUT_MS > SystemClock.elapsedRealtime())) {
763093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                    mSync.wait(10L);
764093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                }
765093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                return mLastEvent != null
766093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                        && (!matchTimeStamp || mLastEvent.timestamp == eventTimeStamp);
767093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
768093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
769093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata
770093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        @Override
771093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        public void onDiagnosticEvent(CarDiagnosticEvent event) {
772093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            synchronized (mSync) {
773093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                // We're going to hold a reference to this object
774093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mLastEvent = event;
775093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata                mSync.notify();
776093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata            }
777093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata        }
778093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata    }
779093e2bcf82752dab9c0e6e4bb6f6cf31497f74a6Enrico Granata}
780