CarSensorEvent.java revision ca515079e9fc0c35b1498830f67378e9ccf949e5
1ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/*
2ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Copyright (C) 2015 The Android Open Source Project
3ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung *
4ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Licensed under the Apache License, Version 2.0 (the "License");
5ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * you may not use this file except in compliance with the License.
6ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * You may obtain a copy of the License at
7ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung *
8ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung *      http://www.apache.org/licenses/LICENSE-2.0
9ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung *
10ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Unless required by applicable law or agreed to in writing, software
11ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * distributed under the License is distributed on an "AS IS" BASIS,
12ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * See the License for the specific language governing permissions and
14ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * limitations under the License.
15ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */
16ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
17ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungpackage android.support.car;
18ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
19ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.location.GpsSatellite;
20ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.location.Location;
21ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.Parcel;
22ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.Parcelable;
23ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungimport android.os.SystemClock;
24ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
25ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
26ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung/**
27ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * A CarSensorEvent object corresponds to a single sensor event coming from the car. The sensor
28ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * data is stored in a sensor-type specific format in the object's float and byte arrays.
29ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung *
30ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * To aid unmarshalling the object's data arrays, this class provides static nested classes and
31ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * conversion methods, for example {@link EnvironmentData} and {@link #getEnvironmentData}. The
32ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * conversion methods each have an optional data parameter which, if not null, will be used and
33ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * returned. This parameter should be used to avoid unnecessary object churn whenever possible.
34ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * Additionally, calling a conversion method on a CarSensorEvent object with an inappropriate type
35ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung * will result in an {@code UnsupportedOperationException} being thrown.
36ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung */
37ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoungpublic class CarSensorEvent implements Parcelable {
38ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
39ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    private static final int VERSION = 1;
40ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
41ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    final int mVersionCode;
42ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
43ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
44ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
45ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * sensor. This value is fuel level in percentile.
46ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
47ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_FUEL_LEVEL_IN_PERCENTILE = 0;
48ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
49ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
50ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * sensor. This value is fuel level in coverable distance.
51ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
52ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_FUEL_LEVEL_IN_DISTANCE = 1;
53ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
54ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index in {@link #byteValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
55ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * sensor. This value is set to 0 if fuel low level warning is on.
56ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
57ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_FUEL_LOW_WARNING = 0;
58ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
59ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
60ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *  GEAR_* represents meaning of byteValues[0] for {@link CarSensorManager#SENSOR_TYPE_GEAR}
61ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *  sensor type.
62ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *  GEAR_NEUTRAL means transmission gear is in neutral state, and the car may be moving.
63ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
64ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_NEUTRAL    = 0;
65ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
66ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * intValues[0] from 1 to 99 represents transmission gear number for moving forward.
67ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * GEAR_FIRST is for gear number 1.
68ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
69ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_FIRST      = 1;
70ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 2. */
71ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_SECOND     = 2;
72ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 3. */
73ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_THIRD      = 3;
74ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 4. */
75ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_FOURTH     = 4;
76ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 5. */
77ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_FIFTH      = 5;
78ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 6. */
79ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_SIXTH      = 6;
80ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 7. */
81ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_SEVENTH    = 7;
82ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 8. */
83ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_EIGHTH     = 8;
84ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 9. */
85ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_NINTH      = 9;
86ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear number 10. */
87ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_TENTH      = 10;
88ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
89ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * This is for transmission without specific gear number for moving forward like CVT. It tells
90ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * that car is in a transmission state to move it forward.
91ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
92ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_DRIVE      = 100;
93ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear in parking state */
94ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_PARK       = 101;
95ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Gear in reverse */
96ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int GEAR_REVERSE    = 102;
97ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
98ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
99ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Bitmask of driving restrictions.
100ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
101ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** No restrictions. */
102ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_UNRESTRICTED = 0;
103ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** No video playback allowed. */
104ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_NO_VIDEO = 0x1;
105ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** No keyboard or rotary controller input allowed. */
106ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_NO_KEYBOARD_INPUT = 0x2;
107ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** No voice input allowed. */
108ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_NO_VOICE_INPUT = 0x4;
109ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** No setup / configuration allowed. */
110ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_NO_CONFIG = 0x8;
111ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Limit displayed message length. */
112ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_LIMIT_MESSAGE_LEN = 0x10;
113ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** represents case where all of the above items are restricted */
114ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int DRIVE_STATUS_FULLY_RESTRICTED = DRIVE_STATUS_NO_VIDEO |
115ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            DRIVE_STATUS_NO_KEYBOARD_INPUT | DRIVE_STATUS_NO_VOICE_INPUT | DRIVE_STATUS_NO_CONFIG |
116ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            DRIVE_STATUS_LIMIT_MESSAGE_LEN;
117ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
118ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index for {@link CarSensorManager#SENSOR_TYPE_LOCATION} in floatValues.
119ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Each bit byteValues[0] represents whether the corresponding data is present.
120ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
121ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_LATITUDE  = 0;
122ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_LONGITUDE = 1;
123ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_ACCURACY  = 2;
124ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_ALTITUDE  = 3;
125ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_SPEED     = 4;
126ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_BEARING   = 5;
127ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_MAX = INDEX_LOCATION_BEARING;
128ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_LATITUDE_BYTES = 1;
129ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_LOCATION_LONGITUDE_BYTES = 5;
130ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
131ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
132ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
133ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Temperature in Celsius degrees.
134ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
135ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_ENVIRONMENT_TEMPERATURE = 0;
136ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
137ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
138ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Pressure in kPa.
139ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
140ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_ENVIRONMENT_PRESSURE = 1;
141ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
142ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
143ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index for {@link CarSensorManager#SENSOR_TYPE_HVAC} in floatValues.
144ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Target temperature set in Celsius degrees.
145ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
146ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_HVAC_TARGET_TEMPERATURE = 0;
147ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
148ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Index for {@link CarSensorManager#SENSOR_TYPE_HVAC} in floatValues.
149ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * The current temperature set in Celsius degrees.
150ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
151ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_HVAC_CURRENT_TEMPERATURE = 1;
152ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
153ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
154ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Indices for {@link CarSensorManager#SENSOR_TYPE_COMPASS} in floatValues.
155ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Angles are in degrees. Pitch or/and roll can be NaN if it is not available.
156ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
157ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_COMPASS_BEARING = 0;
158ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_COMPASS_PITCH   = 1;
159ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_COMPASS_ROLL    = 2;
160ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
161ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
162ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Indices for {@link CarSensorManager#SENSOR_TYPE_ACCELEROMETER} in floatValues.
163ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Acceleration (gravity) is in m/s^2. Any component can be NaN if it is not available.
164ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
165ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_ACCELEROMETER_X = 0;
166ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_ACCELEROMETER_Y = 1;
167ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_ACCELEROMETER_Z = 2;
168ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
169ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
170ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Indices for {@link CarSensorManager#SENSOR_TYPE_GYROSCOPE} in floatValues.
171ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Rotation speed is in rad/s. Any component can be NaN if it is not available.
172ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
173ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GYROSCOPE_X = 0;
174ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GYROSCOPE_Y = 1;
175ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GYROSCOPE_Z = 2;
176ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
177ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
178ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Indices for {@link CarSensorManager#SENSOR_TYPE_GPS_SATELLITE}.
179ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Both byte values and float values are used.
180ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Two first bytes encode number of satellites in-use/in-view (or 0xFF if unavailable).
181ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Then optionally with INDEX_GPS_SATELLITE_ARRAY_BYTE_OFFSET offset and interval
182ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * INDEX_GPS_SATELLITE_ARRAY_BYTE_INTERVAL between elements are encoded boolean flags of whether
183ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * particular satellite from in-view participate in in-use subset.
184ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Float values with INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET offset and interval
185ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL between elements can optionally contain
186ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * per-satellite values of signal strength and other values or NaN if unavailable.
187ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
188ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_NUMBER_IN_USE = 0;
189ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_NUMBER_IN_VIEW = 1;
190ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_ARRAY_BYTE_OFFSET = 2;
191ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_ARRAY_BYTE_INTERVAL = 1;
192ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET = 0;
193ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL = 4;
194ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_PRN_OFFSET = 0;
195ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_SNR_OFFSET = 1;
196ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_AZIMUTH_OFFSET = 2;
197ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final int INDEX_GPS_SATELLITE_ELEVATION_OFFSET = 3;
198ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
199ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    private static final long MILLI_IN_NANOS = 1000000L;
200ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
201ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** Sensor type for this event like {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}. */
202ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public int sensorType;
203ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
204ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
205ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * When this data was acquired in car or received from car. It is elapsed real-time of data
206ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * reception from car in nanoseconds since system boot.
207ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
208ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public long timeStampNs;
209ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
210ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * array holding float type of sensor data. If the sensor has single value, only floatValues[0]
211ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * should be used. */
212ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public final float[] floatValues;
213ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** array holding byte type of sensor data */
214ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public final byte[] byteValues;
215ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
216ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public CarSensorEvent(
217ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            int versionCode,
218ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            int sensorType,
219ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            long timeStampNs,
220ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            float[] floatValues,
221ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            byte[] byteValues) {
222ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.mVersionCode = versionCode;
223ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.sensorType = sensorType;
224ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.timeStampNs = timeStampNs;
225ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.floatValues = floatValues;
226ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.byteValues = byteValues;
227ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
228ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
229ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public CarSensorEvent(Parcel in) {
230ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        mVersionCode = in.readInt();
231ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        sensorType = in.readInt();
232ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        timeStampNs = in.readLong();
233ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int len = in.readInt();
234ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        floatValues = new float[len];
235ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        in.readFloatArray(floatValues);
236ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        len = in.readInt();
237ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        byteValues = new byte[len];
238ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        in.readByteArray(byteValues);
239ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // version 1 up to here
240ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
241ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
242ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    @Override
243ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public int describeContents() {
244ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return 0;
245ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
246ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
247ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    @Override
248ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public void writeToParcel(Parcel dest, int flags) {
249ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeInt(mVersionCode);
250ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeInt(sensorType);
251ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeLong(timeStampNs);
252ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeInt(floatValues.length);
253ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeFloatArray(floatValues);
254ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeInt(byteValues.length);
255ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        dest.writeByteArray(byteValues);
256ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // version 1 up to here
257ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
258ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
259ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static final Parcelable.Creator<CarSensorEvent> CREATOR
260ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    = new Parcelable.Creator<CarSensorEvent>() {
261ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public CarSensorEvent createFromParcel(Parcel in) {
262ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            return new CarSensorEvent(in);
263ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
264ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
265ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public CarSensorEvent[] newArray(int size) {
266ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            return new CarSensorEvent[size];
267ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
268ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    };
269ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
270ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
271ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return version code of this Parcelable.
272ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
273ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public int getVersionCode() {
274ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return mVersionCode;
275ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
276ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
277ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public CarSensorEvent(int sensorType, long timeStampNs, int floatValueSize, int byteValueSize) {
278ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        mVersionCode = VERSION;
279ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.sensorType = sensorType;
280ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.timeStampNs = timeStampNs;
281ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        floatValues = new float[floatValueSize];
282ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        byteValues = new byte[byteValueSize];
283ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
284ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
285ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** @hide */
286ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    CarSensorEvent(int sensorType, long timeStampNs, float[] floatValues, byte[] byteValues) {
287ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        mVersionCode = VERSION;
288ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.sensorType = sensorType;
289ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.timeStampNs = timeStampNs;
290ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.floatValues = floatValues;
291ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        this.byteValues = byteValues;
292ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
293ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
294ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    private void checkType(int type) {
295ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (sensorType == type) {
296ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            return;
297ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
298ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        throw new UnsupportedOperationException(String.format(
299ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                "Invalid sensor type: expected %d, got %d", type, sensorType));
300ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
301ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
302ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class EnvironmentData {
303ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
304ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
305ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float temperature;
306ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
307ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float pressure;
308ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
309ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
310ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
311ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining an {@link EnvironmentData} object from a CarSensorEvent
312ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT}.
313ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
314ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
315ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
316ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return an EnvironmentData object corresponding to the data contained in the CarSensorEvent.
317ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
318ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public EnvironmentData getEnvironmentData(EnvironmentData data) {
319ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_ENVIRONMENT);
320ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
321ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new EnvironmentData();
322ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
323ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
324ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.temperature = floatValues[INDEX_ENVIRONMENT_TEMPERATURE];
325ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.pressure = floatValues[INDEX_ENVIRONMENT_PRESSURE];
326ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
327ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
328ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
329ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class HvacData {
330ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
331ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
332ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float targetTemperature;
333ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
334ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float currentTemperature;
335ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
336ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
337ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
338ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link HvacData} object from a CarSensorEvent
339ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_HVAC}.
340ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
341ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
342ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
343ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a HvacData object corresponding to the data contained in the CarSensorEvent.
344ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
345ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public HvacData getHvacData(HvacData data) {
346ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_HVAC);
347ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
348ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new HvacData();
349ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
350ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
351ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.targetTemperature = floatValues[INDEX_ENVIRONMENT_TEMPERATURE];
352ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.currentTemperature = floatValues[INDEX_ENVIRONMENT_PRESSURE];
353ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
354ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
355ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
356ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class NightData {
357ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
358ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public boolean isNightMode;
359ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
360ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
361ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
362ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link NightData} object from a CarSensorEvent
363ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_NIGHT}.
364ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
365ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
366ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
367ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a NightData object corresponding to the data contained in the CarSensorEvent.
368ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
369ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public NightData getNightData(NightData data) {
370ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_NIGHT);
371ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
372ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new NightData();
373ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
374ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
375ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.isNightMode = byteValues[0] == 1;
376ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
377ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
378ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
379ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class GearData {
380ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
381ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int gear;
382ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
383ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
384ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
385ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link GearData} object from a CarSensorEvent
386ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_GEAR}.
387ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
388ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
389ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
390ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a GearData object corresponding to the data contained in the CarSensorEvent.
391ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
392ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public GearData getGearData(GearData data) {
393ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_GEAR);
394ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
395ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new GearData();
396ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
397ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
398ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.gear = byteValues[0];
399ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
400ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
401ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
402ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class ParkingBrakeData {
403ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
404ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public boolean isEngaged;
405ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
406ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
407ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
408ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link ParkingBrakeData} object from a CarSensorEvent
409ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_PARKING_BRAKE}.
410ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
411ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
412ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
413ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a ParkingBreakData object corresponding to the data contained in the CarSensorEvent.
414ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
415ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public ParkingBrakeData getParkingBrakeData(ParkingBrakeData data) {
416ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_PARKING_BRAKE);
417ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
418ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new ParkingBrakeData();
419ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
420ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
421ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.isEngaged = byteValues[0] == 1;
422ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
423ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
424ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
425ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class FuelLevelData {
426ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
427ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is 0. */
428ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int level;
429ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is 0. */
430ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int range;
431ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is false. */
432ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public boolean lowFuelWarning;
433ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
434ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
435ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
436ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link FuelLevelData} object from a CarSensorEvent
437ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL}.
438ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
439ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
440ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
441ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a FuelLevel object corresponding to the data contained in the CarSensorEvent.
442ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
443ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public FuelLevelData getFuelLevelData(FuelLevelData data) {
444ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_FUEL_LEVEL);
445ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
446ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new FuelLevelData();
447ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
448ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
449ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.level = (int) floatValues[INDEX_FUEL_LEVEL_IN_PERCENTILE];
450ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.range = (int) floatValues[INDEX_FUEL_LEVEL_IN_DISTANCE];
451ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.lowFuelWarning = byteValues[0] == 1;
452ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
453ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
454ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
455ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class OdometerData {
456ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
457ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float kms;
458ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
459ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
460ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
461ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining an {@link OdometerData} object from a CarSensorEvent
462ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_ODOMETER}.
463ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
464ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
465ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
466ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return an OdometerData object corresponding to the data contained in the CarSensorEvent.
467ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
468ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public OdometerData getOdometerData(OdometerData data) {
469ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_ODOMETER);
470ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
471ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new OdometerData();
472ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
473ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
474ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.kms = floatValues[0];
475ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
476ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
477ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
478ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class RpmData {
479ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
480ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float rpm;
481ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
482ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
483ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
484ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link RpmData} object from a CarSensorEvent
485ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_RPM}.
486ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
487ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
488ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
489ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a RpmData object corresponding to the data contained in the CarSensorEvent.
490ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
491ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public RpmData getRpmData(RpmData data) {
492ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_RPM);
493ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
494ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new RpmData();
495ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
496ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
497ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.rpm = floatValues[0];
498ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
499ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
500ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
501ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class CarSpeedData {
502ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
503ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float carSpeed;
504ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
505ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
506ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
507ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link CarSpeedData} object from a CarSensorEvent
508ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}.
509ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
510ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
511ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
512ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a CarSpeedData object corresponding to the data contained in the CarSensorEvent.
513ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
514ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public CarSpeedData getCarSpeedData(CarSpeedData data) {
515ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_CAR_SPEED);
516ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
517ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new CarSpeedData();
518ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
519ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.timeStampNs = timeStampNs;
520ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.carSpeed = floatValues[0];
521ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
522ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
523ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
524ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class CompassData {
525ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
526ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
527ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float bearing;
528ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
529ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float pitch;
530ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
531ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float roll;
532ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
533ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
534ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
535ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link CompassData} object from a CarSensorEvent
536ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_COMPASS}.
537ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
538ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
539ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
540ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a CompassData object corresponding to the data contained in the CarSensorEvent.
541ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
542ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public CompassData getCompassData(CompassData data) {
543ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_COMPASS);
544ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
545ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new CompassData();
546ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
547ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.bearing = floatValues[INDEX_COMPASS_BEARING];
548ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.pitch = floatValues[INDEX_COMPASS_PITCH];
549ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.roll = floatValues[INDEX_COMPASS_ROLL];
550ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
551ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
552ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
553ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
554ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link Location} object from a CarSensorEvent
555ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_LOCATION}.
556ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
557ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param location an optional output parameter which, if non-null, will be used by this method
558ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
559ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a Location object corresponding to the data contained in the CarSensorEvent.
560ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
561ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public Location getLocation(Location location) {
562ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_LOCATION);
563ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (location == null) {
564ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location = new Location("Car-GPS");
565ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
566ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // byteValues[0]: bit flags for the presence of other values following.
567ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int presense = byteValues[0];
568ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_LATITUDE)) != 0) {
569ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            int latBytes = unpackBytes(byteValues, INDEX_LOCATION_LATITUDE_BYTES);
570ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setLatitude(latBytes * 1e-7);
571ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
572ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_LONGITUDE)) != 0) {
573ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            int longBytes = unpackBytes(byteValues, INDEX_LOCATION_LONGITUDE_BYTES);
574ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setLongitude(longBytes * 1e-7);
575ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
576ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_ACCURACY)) != 0) {
577ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setAccuracy(floatValues[INDEX_LOCATION_ACCURACY]);
578ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
579ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_ALTITUDE)) != 0) {
580ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setAltitude(floatValues[INDEX_LOCATION_ALTITUDE]);
581ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
582ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_SPEED)) != 0) {
583ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setSpeed(floatValues[INDEX_LOCATION_SPEED]);
584ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
585ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if ((presense & (0x1 << INDEX_LOCATION_BEARING)) != 0) {
586ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            location.setBearing(floatValues[INDEX_LOCATION_BEARING]);
587ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
588ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        location.setElapsedRealtimeNanos(timeStampNs);
589ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // There is a risk of scheduler delaying 2nd elapsedRealtimeNs value.
590ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // But will not try to fix it assuming that is acceptable as UTC time's accuracy is not
591ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        // guaranteed in Location data.
592ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        long currentTimeMs = System.currentTimeMillis();
593ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        long elapsedRealtimeNs = SystemClock.elapsedRealtimeNanos();
594ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        location.setTime(
595ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                currentTimeMs - (elapsedRealtimeNs - timeStampNs) / MILLI_IN_NANOS);
596ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return location;
597ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
598ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
599ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class DrivingStatusData {
600ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
601ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public byte status;
602ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
603ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
604ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
605ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link DrivingStatusData} object from a CarSensorEvent
606ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}.
607ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
608ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
609ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
610ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a DrivingStatusData object corresponding to the data contained in the CarSensorEvent.
611ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
612ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public DrivingStatusData getDrivingStatusData(DrivingStatusData data) {
613ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS);
614ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
615ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new DrivingStatusData();
616ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
617ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.status = byteValues[0];
618ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
619ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
620ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
621ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class AccelerometerData  {
622ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
623ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
624ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float x;
625ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
626ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float y;
627ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
628ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float z;
629ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
630ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
631ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
632ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining an {@link AccelerometerData} object from a CarSensorEvent
633ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_ACCELEROMETER}.
634ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
635ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
636ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
637ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a AccelerometerData object corresponding to the data contained in the CarSensorEvent.
638ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
639ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public AccelerometerData getAccelerometerData(AccelerometerData data) {
640ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_ACCELEROMETER);
641ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
642ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new AccelerometerData();
643ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
644ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.x = floatValues[INDEX_ACCELEROMETER_X];
645ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.y = floatValues[INDEX_ACCELEROMETER_Y];
646ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.z = floatValues[INDEX_ACCELEROMETER_Z];
647ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
648ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
649ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
650ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class GyroscopeData {
651ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
652ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
653ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float x;
654ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
655ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float y;
656ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /** If unsupported by the car, this value is NaN. */
657ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float z;
658ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
659ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
660ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
661ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link GyroscopeData} object from a CarSensorEvent
662ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_GYROSCOPE}.
663ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
664ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
665ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
666ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a GyroscopeData object corresponding to the data contained in the CarSensorEvent.
667ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
668ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public GyroscopeData getGyroscopeData(GyroscopeData data) {
669ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_GYROSCOPE);
670ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
671ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new GyroscopeData();
672ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
673ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.x = floatValues[INDEX_GYROSCOPE_X];
674ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.y = floatValues[INDEX_GYROSCOPE_Y];
675ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.z = floatValues[INDEX_GYROSCOPE_Z];
676ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
677ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
678ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
679ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    // android.location.GpsSatellite doesn't have a public constructor, so that can't be used.
680ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
681ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Class that contains GPS satellite status. For more info on meaning of these fields refer
682ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * to the documentation to the {@link GpsSatellite} class.
683ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
684ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static class GpsSatelliteData {
685ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public long timeStampNs;
686ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
687ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Number of satellites used in GPS fix or -1 of unavailable.
688ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
689ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int numberInUse = -1;
690ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
691ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Number of satellites in view or -1 of unavailable.
692ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
693ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int numberInView = -1;
694ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
695ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Per-satellite flag if this satellite was used for GPS fix.
696ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Can be null if per-satellite data is unavailable.
697ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
698ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public boolean[] usedInFix = null;
699ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
700ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Per-satellite pseudo-random id.
701ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Can be null if per-satellite data is unavailable.
702ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
703ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public int[] prn = null;
704ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
705ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Per-satellite signal to noise ratio.
706ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Can be null if per-satellite data is unavailable.
707ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
708ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float[] snr = null;
709ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
710ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Per-satellite azimuth.
711ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Can be null if per-satellite data is unavailable.
712ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
713ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float[] azimuth = null;
714ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        /**
715ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Per-satellite elevation.
716ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         * Can be null if per-satellite data is unavailable.
717ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung         */
718ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        public float[] elevation = null;
719ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
720ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
721ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /**
722ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * Convenience method for obtaining a {@link GpsSatelliteData} object from a CarSensorEvent
723ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * object with type {@link CarSensorManager#SENSOR_TYPE_HVAC} with optional per-satellite info.
724ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *
725ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param data an optional output parameter which, if non-null, will be used by this method
726ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     *     instead of a newly created object.
727ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @param withPerSatellite whether to include per-satellite data.
728ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     * @return a GpsSatelliteData object corresponding to the data contained in the CarSensorEvent.
729ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung     */
730ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public GpsSatelliteData getGpsSatelliteData(GpsSatelliteData data,
731ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            boolean withPerSatellite) {
732ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        checkType(CarSensorManager.SENSOR_TYPE_GPS_SATELLITE);
733ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (data == null) {
734ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data = new GpsSatelliteData();
735ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
736ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        final int byteOffset = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_BYTE_OFFSET;
737ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        final int byteInterval = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_BYTE_INTERVAL;
738ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        final int floatOffset = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_OFFSET;
739ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        final int floatInterval = CarSensorEvent.INDEX_GPS_SATELLITE_ARRAY_FLOAT_INTERVAL;
740ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        final int numberOfSats = (floatValues.length - floatOffset) / floatInterval;
741ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
742ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.numberInUse = byteValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_USE];
743ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        data.numberInView = byteValues[CarSensorEvent.INDEX_GPS_SATELLITE_NUMBER_IN_VIEW];
744ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (withPerSatellite && data.numberInView >= 0) {
745ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data.usedInFix = new boolean[numberOfSats];
746ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data.prn = new int[numberOfSats];
747ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data.snr = new float[numberOfSats];
748ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data.azimuth = new float[numberOfSats];
749ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            data.elevation = new float[numberOfSats];
750ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
751ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            for (int i = 0; i < numberOfSats; ++i) {
752ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                int iByte = byteOffset + byteInterval * i;
753ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                int iFloat = floatOffset + floatInterval * i;
754ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                data.usedInFix[i] = byteValues[iByte] != 0;
755ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                data.prn[i] = Math.round(
756ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                        floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_PRN_OFFSET]);
757ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                data.snr[i] =
758ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                        floatValues[iFloat + CarSensorEvent.INDEX_GPS_SATELLITE_SNR_OFFSET];
759ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                data.azimuth[i] = floatValues[iFloat
760ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                        + CarSensorEvent.INDEX_GPS_SATELLITE_AZIMUTH_OFFSET];
761ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                data.elevation[i] = floatValues[iFloat
762ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                        + CarSensorEvent.INDEX_GPS_SATELLITE_ELEVATION_OFFSET];
763ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            }
764ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
765ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return data;
766ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
767ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
768ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** @hide */
769ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static int unpackBytes(byte[] arr, int offset) {
770ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int b0 = arr[offset] & 0xff;
771ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int b1 = (arr[offset + 1] << 8) & 0xff00;
772ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int b2 = (arr[offset + 2] << 16) & 0xff0000;
773ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        int b3 = (arr[offset + 3] << 24) & 0xff000000;
774ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return b0 | b1 | b2 | b3;
775ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
776ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
777ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** @hide */
778ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public static void packBytes(byte[] arr, int offset, int value) {
779ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        arr[offset] = (byte) (value & 0xff);
780ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        arr[offset + 1] = (byte) ((value >> 8) & 0xff);
781ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        arr[offset + 2] = (byte) ((value >> 16) & 0xff);
782ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        arr[offset + 3] = (byte) ((value >> 24) & 0xff);
783ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
784ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung
785ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    /** @hide */
786ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    @Override
787ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    public String toString() {
788ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        StringBuilder sb = new StringBuilder();
789ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        sb.append(getClass().getName() + "[");
790ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        sb.append("type:" + Integer.toHexString(sensorType));
791ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (floatValues != null && floatValues.length > 0) {
792ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            sb.append(" float values:");
793ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            for (float v: floatValues) {
794ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                sb.append(" " + v);
795ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            }
796ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
797ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        if (byteValues != null && byteValues.length > 0) {
798ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            sb.append(" byte values:");
799ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            for (byte v: byteValues) {
800ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung                sb.append(" " + v);
801ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung            }
802ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        }
803ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        sb.append("]");
804ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung        return sb.toString();
805ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung    }
806ca515079e9fc0c35b1498830f67378e9ccf949e5keunyoung}
807