Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.car.hardware;
     18 
     19 import android.os.Parcel;
     20 import android.os.Parcelable;
     21 
     22 /**
     23  * A CarSensorEvent object corresponds to a single sensor event coming from the car. The sensor
     24  * data is stored in a sensor-type specific format in the object's float and byte arrays.
     25  *
     26  * To aid unmarshalling the object's data arrays, this class provides static nested classes and
     27  * conversion methods, for example {@link EnvironmentData} and {@link #getEnvironmentData}. The
     28  * conversion methods each have an optional data parameter which, if not null, will be used and
     29  * returned. This parameter should be used to avoid unnecessary object churn whenever possible.
     30  * Additionally, calling a conversion method on a CarSensorEvent object with an inappropriate type
     31  * will result in an {@code UnsupportedOperationException} being thrown.
     32  */
     33 public class CarSensorEvent implements Parcelable {
     34 
     35     /**
     36      *  GEAR_* represents meaning of intValues[0] for {@link CarSensorManager#SENSOR_TYPE_GEAR}
     37      *  sensor type.
     38      *  GEAR_NEUTRAL means transmission gear is in neutral state, and the car may be moving.
     39      */
     40     public static final int GEAR_NEUTRAL    = 0x0001;
     41     /**
     42      * intValues[0] from 1 to 99 represents transmission gear number for moving forward.
     43      * GEAR_FIRST is for gear number 1.
     44      */
     45     public static final int GEAR_FIRST      = 0x0010;
     46     /** Gear number 2. */
     47     public static final int GEAR_SECOND     = 0x0020;
     48     /** Gear number 3. */
     49     public static final int GEAR_THIRD      = 0x0040;
     50     /** Gear number 4. */
     51     public static final int GEAR_FOURTH     = 0x0080;
     52     /** Gear number 5. */
     53     public static final int GEAR_FIFTH      = 0x0100;
     54     /** Gear number 6. */
     55     public static final int GEAR_SIXTH      = 0x0200;
     56     /** Gear number 7. */
     57     public static final int GEAR_SEVENTH    = 0x0400;
     58     /** Gear number 8. */
     59     public static final int GEAR_EIGHTH     = 0x0800;
     60     /** Gear number 9. */
     61     public static final int GEAR_NINTH      = 0x1000;
     62     /** Gear number 10. */
     63     public static final int GEAR_TENTH      = 0x2000;
     64     /**
     65      * This is for transmission without specific gear number for moving forward like CVT. It tells
     66      * that car is in a transmission state to move it forward.
     67      */
     68     public static final int GEAR_DRIVE      = 0x0008;
     69     /** Gear in parking state */
     70     public static final int GEAR_PARK       = 0x0004;
     71     /** Gear in reverse */
     72     public static final int GEAR_REVERSE    = 0x0002;
     73 
     74     /**
     75      * Ignition state is unknown.
     76      *
     77      * The constants that starts with IGNITION_STATE_ represent values for
     78      * {@link CarSensorManager#SENSOR_TYPE_IGNITION_STATE} sensor.
     79      * */
     80     public static final int IGNITION_STATE_UNDEFINED = 0;
     81     /**
     82      * Steering wheel is locked.
     83      */
     84     public static final int IGNITION_STATE_LOCK = 1;
     85     /** Typically engine is off, but steering wheel is unlocked. */
     86     public static final int IGNITION_STATE_OFF = 2;
     87     /** Accessory is turned off, but engine is not running yet (for EV car is not ready to move). */
     88     public static final int IGNITION_STATE_ACC = 3;
     89     /** In this state engine typically is running (for EV, car is ready to move). */
     90     public static final int IGNITION_STATE_ON = 4;
     91     /** In this state engine is typically starting (cranking). */
     92     public static final int IGNITION_STATE_START = 5;
     93 
     94     /**
     95      * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
     96      * Temperature in Celsius degrees.
     97      */
     98     public static final int INDEX_ENVIRONMENT_TEMPERATURE = 0;
     99     /**
    100      * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
    101      * Pressure in kPa.
    102      */
    103     public static final int INDEX_ENVIRONMENT_PRESSURE = 1;
    104     /**
    105      * Index for {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE} in longValues. RESET_COUNT
    106      * is incremented whenever the HAL detects that a sensor reset has occurred.  It represents to
    107      * the upper layer that the WHEEL_DISTANCE values will not be contiguous with other values
    108      * reported with a different RESET_COUNT.
    109      */
    110     public static final int INDEX_WHEEL_DISTANCE_RESET_COUNT = 0;
    111     public static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1;
    112     public static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2;
    113     public static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3;
    114     public static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4;
    115 
    116     private static final long MILLI_IN_NANOS = 1000000L;
    117 
    118     /** Sensor type for this event like {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}. */
    119     public int sensorType;
    120 
    121     /**
    122      * When this data was received from car. It is elapsed real-time of data reception from car in
    123      * nanoseconds since system boot.
    124      */
    125     public long timestamp;
    126     /**
    127      * array holding float type of sensor data. If the sensor has single value, only floatValues[0]
    128      * should be used. */
    129     public final float[] floatValues;
    130     /** array holding int type of sensor data */
    131     public final int[] intValues;
    132     /** array holding long int type of sensor data */
    133     public final long[] longValues;
    134 
    135     /** @hide */
    136     public CarSensorEvent(Parcel in) {
    137         sensorType = in.readInt();
    138         timestamp = in.readLong();
    139         int len = in.readInt();
    140         floatValues = new float[len];
    141         in.readFloatArray(floatValues);
    142         len = in.readInt();
    143         intValues = new int[len];
    144         in.readIntArray(intValues);
    145         // version 1 up to here
    146         len = in.readInt();
    147         longValues = new long[len];
    148         in.readLongArray(longValues);
    149     }
    150 
    151     @Override
    152     public int describeContents() {
    153         return 0;
    154     }
    155 
    156     @Override
    157     public void writeToParcel(Parcel dest, int flags) {
    158         dest.writeInt(sensorType);
    159         dest.writeLong(timestamp);
    160         dest.writeInt(floatValues.length);
    161         dest.writeFloatArray(floatValues);
    162         dest.writeInt(intValues.length);
    163         dest.writeIntArray(intValues);
    164         dest.writeInt(longValues.length);
    165         dest.writeLongArray(longValues);
    166     }
    167 
    168     public static final Parcelable.Creator<CarSensorEvent> CREATOR
    169     = new Parcelable.Creator<CarSensorEvent>() {
    170         public CarSensorEvent createFromParcel(Parcel in) {
    171             return new CarSensorEvent(in);
    172         }
    173 
    174         public CarSensorEvent[] newArray(int size) {
    175             return new CarSensorEvent[size];
    176         }
    177     };
    178 
    179     /** @hide */
    180     public CarSensorEvent(int sensorType, long timestamp, int floatValueSize, int intValueSize,
    181                           int longValueSize) {
    182         this.sensorType = sensorType;
    183         this.timestamp = timestamp;
    184         floatValues = new float[floatValueSize];
    185         intValues = new int[intValueSize];
    186         longValues = new long[longValueSize];
    187     }
    188 
    189     /** @hide */
    190     CarSensorEvent(int sensorType, long timestamp, float[] floatValues, int[] intValues,
    191                    long[] longValues) {
    192         this.sensorType = sensorType;
    193         this.timestamp = timestamp;
    194         this.floatValues = floatValues;
    195         this.intValues = intValues;
    196         this.longValues = longValues;
    197     }
    198 
    199     private void checkType(int type) {
    200         if (sensorType == type) {
    201             return;
    202         }
    203         throw new UnsupportedOperationException(String.format(
    204                 "Invalid sensor type: expected %d, got %d", type, sensorType));
    205     }
    206 
    207     public static class EnvironmentData {
    208         public long timestamp;
    209         /** If unsupported by the car, this value is NaN. */
    210         public float temperature;
    211         /** If unsupported by the car, this value is NaN. */
    212         public float pressure;
    213 
    214         /** @hide */
    215         private EnvironmentData() {};
    216     }
    217 
    218     /**
    219      * Convenience method for obtaining an {@link EnvironmentData} object from a CarSensorEvent
    220      * object with type {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT}.
    221      *
    222      * @param data an optional output parameter which, if non-null, will be used by this method
    223      *     instead of a newly created object.
    224      * @return an EnvironmentData object corresponding to the data contained in the CarSensorEvent.
    225      * @hide
    226      */
    227     public EnvironmentData getEnvironmentData(EnvironmentData data) {
    228         checkType(CarSensorManager.SENSOR_TYPE_ENVIRONMENT);
    229         if (data == null) {
    230             data = new EnvironmentData();
    231         }
    232         data.timestamp = timestamp;
    233         data.temperature = floatValues[INDEX_ENVIRONMENT_TEMPERATURE];
    234         data.pressure = floatValues[INDEX_ENVIRONMENT_PRESSURE];
    235         return data;
    236     }
    237 
    238     /** @hide */
    239     public static class NightData {
    240         public long timestamp;
    241         public boolean isNightMode;
    242 
    243         /** @hide */
    244         private NightData() {};
    245     }
    246 
    247     /**
    248      * Convenience method for obtaining a {@link NightData} object from a CarSensorEvent
    249      * object with type {@link CarSensorManager#SENSOR_TYPE_NIGHT}.
    250      *
    251      * @param data an optional output parameter which, if non-null, will be used by this method
    252      *     instead of a newly created object.
    253      * @return a NightData object corresponding to the data contained in the CarSensorEvent.
    254      * @hide
    255      */
    256     public NightData getNightData(NightData data) {
    257         checkType(CarSensorManager.SENSOR_TYPE_NIGHT);
    258         if (data == null) {
    259             data = new NightData();
    260         }
    261         data.timestamp = timestamp;
    262         data.isNightMode = intValues[0] == 1;
    263         return data;
    264     }
    265 
    266     /** @hide */
    267     public static class GearData {
    268         public long timestamp;
    269         public int gear;
    270 
    271         /** @hide */
    272         private GearData() {};
    273     }
    274 
    275     /**
    276      * Convenience method for obtaining a {@link GearData} object from a CarSensorEvent
    277      * object with type {@link CarSensorManager#SENSOR_TYPE_GEAR}.
    278      *
    279      * @param data an optional output parameter which, if non-null, will be used by this method
    280      *     instead of a newly created object.
    281      * @return a GearData object corresponding to the data contained in the CarSensorEvent.
    282      * @hide
    283      */
    284     public GearData getGearData(GearData data) {
    285         checkType(CarSensorManager.SENSOR_TYPE_GEAR);
    286         if (data == null) {
    287             data = new GearData();
    288         }
    289         data.timestamp = timestamp;
    290         data.gear = intValues[0];
    291         return data;
    292     }
    293 
    294     /** @hide */
    295     public static class ParkingBrakeData {
    296         public long timestamp;
    297         public boolean isEngaged;
    298 
    299         /** @hide */
    300         private ParkingBrakeData() {}
    301     }
    302 
    303     /**
    304      * Convenience method for obtaining a {@link ParkingBrakeData} object from a CarSensorEvent
    305      * object with type {@link CarSensorManager#SENSOR_TYPE_PARKING_BRAKE}.
    306      *
    307      * @param data an optional output parameter which, if non-null, will be used by this method
    308      *     instead of a newly created object.
    309      * @return a ParkingBreakData object corresponding to the data contained in the CarSensorEvent.
    310      * @hide
    311      */
    312     public ParkingBrakeData getParkingBrakeData(ParkingBrakeData data) {
    313         checkType(CarSensorManager.SENSOR_TYPE_PARKING_BRAKE);
    314         if (data == null) {
    315             data = new ParkingBrakeData();
    316         }
    317         data.timestamp = timestamp;
    318         data.isEngaged = intValues[0] == 1;
    319         return data;
    320     }
    321 
    322     /** @hide */
    323     public static class FuelLevelData {
    324         public long timestamp;
    325         /** Fuel level in milliliters.  Negative values indicate this property is unsupported. */
    326         public float level;
    327 
    328         /** @hide */
    329         private FuelLevelData() {};
    330     }
    331 
    332     /**
    333      * Convenience method for obtaining a {@link FuelLevelData} object from a CarSensorEvent
    334      * object with type {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL}.
    335      *
    336      * @param data an optional output parameter which, if non-null, will be used by this method
    337      *     instead of a newly created object.
    338      * @return a FuelLevel object corresponding to the data contained in the CarSensorEvent.
    339      * @hide
    340      */
    341     public FuelLevelData getFuelLevelData(FuelLevelData data) {
    342         checkType(CarSensorManager.SENSOR_TYPE_FUEL_LEVEL);
    343         if (data == null) {
    344             data = new FuelLevelData();
    345         }
    346         data.timestamp = timestamp;
    347         if (floatValues == null) {
    348             data.level = -1.0f;
    349         } else {
    350             if (floatValues[0] < 0) {
    351                 data.level = -1.0f;
    352             } else {
    353                 data.level = floatValues[0];
    354             }
    355         }
    356         return data;
    357     }
    358 
    359     /** @hide */
    360     public static class OdometerData {
    361         public long timestamp;
    362         public float kms;
    363 
    364         /** @hide */
    365         private OdometerData() {};
    366     }
    367 
    368     /**
    369      * Convenience method for obtaining an {@link OdometerData} object from a CarSensorEvent
    370      * object with type {@link CarSensorManager#SENSOR_TYPE_ODOMETER}.
    371      *
    372      * @param data an optional output parameter which, if non-null, will be used by this method
    373      *     instead of a newly created object.
    374      * @return an OdometerData object corresponding to the data contained in the CarSensorEvent.
    375      * @hide
    376      */
    377     public OdometerData getOdometerData(OdometerData data) {
    378         checkType(CarSensorManager.SENSOR_TYPE_ODOMETER);
    379         if (data == null) {
    380             data = new OdometerData();
    381         }
    382         data.timestamp = timestamp;
    383         data.kms = floatValues[0];
    384         return data;
    385     }
    386 
    387     /** @hide */
    388     public static class RpmData {
    389         public long timestamp;
    390         public float rpm;
    391 
    392         /** @hide */
    393         private RpmData() {};
    394     }
    395 
    396     /**
    397      * Convenience method for obtaining a {@link RpmData} object from a CarSensorEvent
    398      * object with type {@link CarSensorManager#SENSOR_TYPE_RPM}.
    399      *
    400      * @param data an optional output parameter which, if non-null, will be used by this method
    401      *     instead of a newly created object.
    402      * @return a RpmData object corresponding to the data contained in the CarSensorEvent.
    403      * @hide
    404      */
    405     public RpmData getRpmData(RpmData data) {
    406         checkType(CarSensorManager.SENSOR_TYPE_RPM);
    407         if (data == null) {
    408             data = new RpmData();
    409         }
    410         data.timestamp = timestamp;
    411         data.rpm = floatValues[0];
    412         return data;
    413     }
    414 
    415     /** @hide */
    416     public static class CarSpeedData {
    417         public long timestamp;
    418         public float carSpeed;
    419 
    420         /** @hide */
    421         private CarSpeedData() {};
    422     }
    423 
    424     /**
    425      * Convenience method for obtaining a {@link CarSpeedData} object from a CarSensorEvent
    426      * object with type {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}.
    427      *
    428      * @param data an optional output parameter which, if non-null, will be used by this method
    429      *     instead of a newly created object.
    430      * @return a CarSpeedData object corresponding to the data contained in the CarSensorEvent.
    431      * @hide
    432      */
    433     public CarSpeedData getCarSpeedData(CarSpeedData data) {
    434         checkType(CarSensorManager.SENSOR_TYPE_CAR_SPEED);
    435         if (data == null) {
    436             data = new CarSpeedData();
    437         }
    438         data.timestamp = timestamp;
    439         data.carSpeed = floatValues[0];
    440         return data;
    441     }
    442 
    443     /** @hide */
    444     public static class CarWheelTickDistanceData {
    445         public long timestamp;
    446         public long sensorResetCount;
    447         public long frontLeftWheelDistanceMm;
    448         public long frontRightWheelDistanceMm;
    449         public long rearRightWheelDistanceMm;
    450         public long rearLeftWheelDistanceMm;
    451 
    452         /** @hide */
    453         private CarWheelTickDistanceData() {};
    454     }
    455 
    456     /**
    457      * Convenience method for obtaining a {@link CarWheelTickDistanceData} object from a
    458      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_WHEEL_TICK_DISTANCE}.
    459      *
    460      * @param data an optional output parameter which, if non-null, will be used by this method
    461      *     instead of a newly created object.
    462      * @return CarWheelTickDistanceData object corresponding to data contained in the CarSensorEvent
    463      * @hide
    464      */
    465     public CarWheelTickDistanceData getCarWheelTickDistanceData(CarWheelTickDistanceData data) {
    466         checkType(CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE);
    467         if (data == null) {
    468             data = new CarWheelTickDistanceData();
    469         }
    470         data.timestamp = timestamp;
    471         data.sensorResetCount = longValues[INDEX_WHEEL_DISTANCE_RESET_COUNT];
    472         data.frontLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_LEFT];
    473         data.frontRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_FRONT_RIGHT];
    474         data.rearRightWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_RIGHT];
    475         data.rearLeftWheelDistanceMm = longValues[INDEX_WHEEL_DISTANCE_REAR_LEFT];
    476         return data;
    477     }
    478 
    479     /** @hide */
    480     public static class CarAbsActiveData {
    481         public long timestamp;
    482         public boolean absIsActive;
    483 
    484         /** @hide */
    485         private CarAbsActiveData() {};
    486     }
    487 
    488     /**
    489      * Convenience method for obtaining a {@link CarAbsActiveData} object from a CarSensorEvent
    490      * object with type {@link CarSensorManager#SENSOR_TYPE_ABS_ACTIVE}.
    491      *
    492      * @param data an optional output parameter which, if non-null, will be used by this method
    493      *     instead of a newly created object.
    494      * @return a CarAbsActiveData object corresponding to data contained in the CarSensorEvent.
    495      * @hide
    496      */
    497     public CarAbsActiveData getCarAbsActiveData(CarAbsActiveData data) {
    498         checkType(CarSensorManager.SENSOR_TYPE_ABS_ACTIVE);
    499         if (data == null) {
    500             data = new CarAbsActiveData();
    501         }
    502         data.timestamp = timestamp;
    503         data.absIsActive = intValues[0] == 1;
    504         return data;
    505     }
    506 
    507     /** @hide */
    508     public static class CarTractionControlActiveData {
    509         public long timestamp;
    510         public boolean tractionControlIsActive;
    511 
    512         /** @hide */
    513         private CarTractionControlActiveData() {};
    514     }
    515 
    516     /**
    517      * Convenience method for obtaining a {@link CarTractionControlActiveData} object from a
    518      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_TRACTION_CONTROL_ACTIVE}.
    519      *
    520      * @param data an optional output parameter which, if non-null, will be used by this method
    521      *     instead of a newly created object.
    522      * @return a CarTractionControlActiveData object corresponding to data contained in the
    523      *     CarSensorEvent.
    524      * @hide
    525      */
    526     public CarTractionControlActiveData getCarTractionControlActiveData(
    527             CarTractionControlActiveData data) {
    528         checkType(CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE);
    529         if (data == null) {
    530             data = new CarTractionControlActiveData();
    531         }
    532         data.timestamp = timestamp;
    533         data.tractionControlIsActive = intValues[0] == 1;
    534         return data;
    535     }
    536 
    537     /** @hide */
    538     public static class CarFuelDoorOpenData {
    539         public long timestamp;
    540         public boolean fuelDoorIsOpen;
    541 
    542         /** @hide */
    543         private CarFuelDoorOpenData() {};
    544     }
    545 
    546     /**
    547      * Convenience method for obtaining a {@link CarFuelDoorOpenData} object from a
    548      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_FUEL_DOOR_OPEN}.
    549      *
    550      * @param data an optional output parameter which, if non-null, will be used by this method
    551      *     instead of a newly created object.
    552      * @return a CarFuelDoorOpenData object corresponding to data contained in the
    553      *     CarSensorEvent.
    554      * @hide
    555      */
    556     public CarFuelDoorOpenData getCarFuelDoorOpenData(
    557         CarFuelDoorOpenData data) {
    558         checkType(CarSensorManager.SENSOR_TYPE_FUEL_DOOR_OPEN);
    559         if (data == null) {
    560             data = new CarFuelDoorOpenData();
    561         }
    562         data.timestamp = timestamp;
    563         data.fuelDoorIsOpen = intValues[0] == 1;
    564         return data;
    565     }
    566 
    567     /** @hide */
    568     public static class CarEvBatteryLevelData {
    569         public long timestamp;
    570         /** Battery Level in Watt-hours */
    571         public float evBatteryLevel;
    572 
    573         /** @hide */
    574         private CarEvBatteryLevelData() {};
    575     }
    576 
    577     /**
    578      * Convenience method for obtaining a {@link CarEvBatteryLevelData} object from a
    579      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_EV_BATTERY_LEVEL}.
    580      *
    581      * @param data an optional output parameter which, if non-null, will be used by this method
    582      *     instead of a newly created object.
    583      * @return a CarEvBatteryLevelData object corresponding to data contained in the
    584      *     CarSensorEvent.
    585      * @hide
    586      */
    587     public CarEvBatteryLevelData getCarEvBatteryLevelData(
    588         CarEvBatteryLevelData data) {
    589         checkType(CarSensorManager.SENSOR_TYPE_EV_BATTERY_LEVEL);
    590         if (data == null) {
    591             data = new CarEvBatteryLevelData();
    592         }
    593         data.timestamp = timestamp;
    594         if (floatValues == null) {
    595             data.evBatteryLevel = -1.0f;
    596         } else {
    597             if (floatValues[0] < 0) {
    598                 data.evBatteryLevel = -1.0f;
    599             } else {
    600                 data.evBatteryLevel = floatValues[0];
    601             }
    602         }
    603         return data;
    604     }
    605 
    606     /** @hide */
    607     public static class CarEvChargePortOpenData {
    608         public long timestamp;
    609         public boolean evChargePortIsOpen;
    610 
    611         /** @hide */
    612         private CarEvChargePortOpenData() {};
    613     }
    614 
    615     /**
    616      * Convenience method for obtaining a {@link CarEvChargePortOpenData} object from a
    617      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_EV_CHARGE_PORT_OPEN}.
    618      *
    619      * @param data an optional output parameter which, if non-null, will be used by this method
    620      *     instead of a newly created object.
    621      * @return a CarEvChargePortOpenData object corresponding to data contained in the
    622      *     CarSensorEvent.
    623      * @hide
    624      */
    625     public CarEvChargePortOpenData getCarEvChargePortOpenData(
    626         CarEvChargePortOpenData data) {
    627         checkType(CarSensorManager.SENSOR_TYPE_EV_CHARGE_PORT_OPEN);
    628         if (data == null) {
    629             data = new CarEvChargePortOpenData();
    630         }
    631         data.timestamp = timestamp;
    632         data.evChargePortIsOpen = intValues[0] == 1;
    633         return data;
    634     }
    635 
    636     /** @hide */
    637     public static class CarEvChargePortConnectedData {
    638         public long timestamp;
    639         public boolean evChargePortIsConnected;
    640 
    641         /** @hide */
    642         private CarEvChargePortConnectedData() {};
    643     }
    644 
    645     /**
    646      * Convenience method for obtaining a {@link CarEvChargePortConnectedData} object from a
    647      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_EV_CHARGE_PORT_CONNECTED}.
    648      *
    649      * @param data an optional output parameter which, if non-null, will be used by this method
    650      *     instead of a newly created object.
    651      * @return a CarEvChargePortConnectedData object corresponding to data contained in the
    652      *     CarSensorEvent.
    653      * @hide
    654      */
    655     public CarEvChargePortConnectedData getCarEvChargePortConnectedData(
    656         CarEvChargePortConnectedData data) {
    657         checkType(CarSensorManager.SENSOR_TYPE_EV_CHARGE_PORT_CONNECTED);
    658         if (data == null) {
    659             data = new CarEvChargePortConnectedData();
    660         }
    661         data.timestamp = timestamp;
    662         data.evChargePortIsConnected = intValues[0] == 1;
    663         return data;
    664     }
    665 
    666     /** @hide */
    667     public static class CarEvBatteryChargeRateData {
    668         public long timestamp;
    669         /** EV battery charging rate in mW.
    670          * Positive values indicates battery being charged.  Negative values indicate discharge */
    671         public float evChargeRate;
    672 
    673         /** @hide */
    674         private CarEvBatteryChargeRateData() {};
    675     }
    676 
    677     /**
    678      * Convenience method for obtaining a {@link CarEvBatteryChargeRateData} object from a
    679      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_EV_BATTERY_CHARGE_RATE}.
    680      *
    681      * @param data an optional output parameter which, if non-null, will be used by this method
    682      *     instead of a newly created object.
    683      * @return a CarEvBatteryChargeRateData object corresponding to data contained in the
    684      *     CarSensorEvent.
    685      * @hide
    686      */
    687     public CarEvBatteryChargeRateData getCarEvBatteryChargeRateData(
    688         CarEvBatteryChargeRateData data) {
    689         checkType(CarSensorManager.SENSOR_TYPE_EV_BATTERY_CHARGE_RATE);
    690         if (data == null) {
    691             data = new CarEvBatteryChargeRateData();
    692         }
    693         data.timestamp = timestamp;
    694         data.evChargeRate = floatValues[0];
    695         return data;
    696     }
    697 
    698     /** @hide */
    699     public static class CarEngineOilLevelData {
    700         public long timestamp;
    701         public int engineOilLevel;
    702 
    703         /** @hide */
    704         private CarEngineOilLevelData() {};
    705     }
    706 
    707     /**
    708      * Convenience method for obtaining a {@link CarEngineOilLevelData} object from a
    709      * CarSensorEvent object with type {@link CarSensorManager#SENSOR_TYPE_ENGINE_OIL_LEVEL}.
    710      *
    711      * @param data an optional output parameter, which, if non-null, will be used by this method
    712      *      instead of a newly created object.
    713      * @return a CarEngineOilLEvelData object corresponding to data contained in the CarSensorEvent.
    714      * @hide
    715      */
    716     public CarEngineOilLevelData getCarEngineOilLevelData(CarEngineOilLevelData data) {
    717         checkType(CarSensorManager.SENSOR_TYPE_ENGINE_OIL_LEVEL);
    718         if (data == null) {
    719             data = new CarEngineOilLevelData();
    720         }
    721         data.timestamp = timestamp;
    722         data.engineOilLevel = intValues[0];
    723         return data;
    724     }
    725 
    726     /** @hide */
    727     @Override
    728     public String toString() {
    729         StringBuilder sb = new StringBuilder();
    730         sb.append(getClass().getName() + "[");
    731         sb.append("type:" + Integer.toHexString(sensorType));
    732         if (floatValues != null && floatValues.length > 0) {
    733             sb.append(" float values:");
    734             for (float v: floatValues) {
    735                 sb.append(" " + v);
    736             }
    737         }
    738         if (intValues != null && intValues.length > 0) {
    739             sb.append(" int values:");
    740             for (int v: intValues) {
    741                 sb.append(" " + v);
    742             }
    743         }
    744         if (longValues != null && longValues.length > 0) {
    745             sb.append(" long values:");
    746             for (long v: longValues) {
    747                 sb.append(" " + v);
    748             }
    749         }
    750         sb.append("]");
    751         return sb.toString();
    752     }
    753 }
    754