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 /**
     24  * A CarSensorEvent object corresponds to a single sensor event coming from the car. The sensor
     25  * data is stored in a sensor-type specific format in the object's float and byte arrays.
     26  *
     27  * To aid unmarshalling the object's data arrays, this class provides static nested classes and
     28  * conversion methods, for example {@link EnvironmentData} and {@link #getEnvironmentData}. The
     29  * conversion methods each have an optional data parameter which, if not null, will be used and
     30  * returned. This parameter should be used to avoid unnecessary object churn whenever possible.
     31  * Additionally, calling a conversion method on a CarSensorEvent object with an inappropriate type
     32  * will result in an {@code UnsupportedOperationException} being thrown.
     33  */
     34 public class CarSensorEvent implements Parcelable {
     35 
     36     /**
     37      * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
     38      * sensor. This value is fuel level in percentile.
     39      */
     40     public static final int INDEX_FUEL_LEVEL_IN_PERCENTILE = 0;
     41     /**
     42      * Index in {@link #floatValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
     43      * sensor. This value is fuel level in coverable distance. The unit is Km.
     44      */
     45     public static final int INDEX_FUEL_LEVEL_IN_DISTANCE = 1;
     46     /**
     47      * Index in {@link #intValues} for {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL} type of
     48      * sensor. This value is set to 1 if fuel low level warning is on.
     49      */
     50     public static final int INDEX_FUEL_LOW_WARNING = 0;
     51 
     52     /**
     53      *  GEAR_* represents meaning of intValues[0] for {@link CarSensorManager#SENSOR_TYPE_GEAR}
     54      *  sensor type.
     55      *  GEAR_NEUTRAL means transmission gear is in neutral state, and the car may be moving.
     56      */
     57     public static final int GEAR_NEUTRAL    = 0;
     58     /**
     59      * intValues[0] from 1 to 99 represents transmission gear number for moving forward.
     60      * GEAR_FIRST is for gear number 1.
     61      */
     62     public static final int GEAR_FIRST      = 1;
     63     /** Gear number 2. */
     64     public static final int GEAR_SECOND     = 2;
     65     /** Gear number 3. */
     66     public static final int GEAR_THIRD      = 3;
     67     /** Gear number 4. */
     68     public static final int GEAR_FOURTH     = 4;
     69     /** Gear number 5. */
     70     public static final int GEAR_FIFTH      = 5;
     71     /** Gear number 6. */
     72     public static final int GEAR_SIXTH      = 6;
     73     /** Gear number 7. */
     74     public static final int GEAR_SEVENTH    = 7;
     75     /** Gear number 8. */
     76     public static final int GEAR_EIGHTH     = 8;
     77     /** Gear number 9. */
     78     public static final int GEAR_NINTH      = 9;
     79     /** Gear number 10. */
     80     public static final int GEAR_TENTH      = 10;
     81     /**
     82      * This is for transmission without specific gear number for moving forward like CVT. It tells
     83      * that car is in a transmission state to move it forward.
     84      */
     85     public static final int GEAR_DRIVE      = 100;
     86     /** Gear in parking state */
     87     public static final int GEAR_PARK       = 101;
     88     /** Gear in reverse */
     89     public static final int GEAR_REVERSE    = 102;
     90 
     91     /**
     92      * Bitmask of driving restrictions.
     93      */
     94     /** No restrictions. */
     95     public static final int DRIVE_STATUS_UNRESTRICTED = 0;
     96     /** No video playback allowed. */
     97     public static final int DRIVE_STATUS_NO_VIDEO = 0x1;
     98     /** No keyboard or rotary controller input allowed. */
     99     public static final int DRIVE_STATUS_NO_KEYBOARD_INPUT = 0x2;
    100     /** No voice input allowed. */
    101     public static final int DRIVE_STATUS_NO_VOICE_INPUT = 0x4;
    102     /** No setup / configuration allowed. */
    103     public static final int DRIVE_STATUS_NO_CONFIG = 0x8;
    104     /** Limit displayed message length. */
    105     public static final int DRIVE_STATUS_LIMIT_MESSAGE_LEN = 0x10;
    106     /** represents case where all of the above items are restricted */
    107     public static final int DRIVE_STATUS_FULLY_RESTRICTED = DRIVE_STATUS_NO_VIDEO |
    108             DRIVE_STATUS_NO_KEYBOARD_INPUT | DRIVE_STATUS_NO_VOICE_INPUT | DRIVE_STATUS_NO_CONFIG |
    109             DRIVE_STATUS_LIMIT_MESSAGE_LEN;
    110 
    111     /**
    112      * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
    113      * Temperature in Celsius degrees.
    114      */
    115     public static final int INDEX_ENVIRONMENT_TEMPERATURE = 0;
    116     /**
    117      * Index for {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT} in floatValues.
    118      * Pressure in kPa.
    119      */
    120     public static final int INDEX_ENVIRONMENT_PRESSURE = 1;
    121 
    122     private static final long MILLI_IN_NANOS = 1000000L;
    123 
    124     /** Sensor type for this event like {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}. */
    125     public int sensorType;
    126 
    127     /**
    128      * When this data was acquired in car or received from car. It is elapsed real-time of data
    129      * reception from car in nanoseconds since system boot.
    130      */
    131     public long timeStampNs;
    132     /**
    133      * array holding float type of sensor data. If the sensor has single value, only floatValues[0]
    134      * should be used. */
    135     public final float[] floatValues;
    136     /** array holding int type of sensor data */
    137     public final int[] intValues;
    138 
    139     public CarSensorEvent(Parcel in) {
    140         sensorType = in.readInt();
    141         timeStampNs = in.readLong();
    142         int len = in.readInt();
    143         floatValues = new float[len];
    144         in.readFloatArray(floatValues);
    145         len = in.readInt();
    146         intValues = new int[len];
    147         in.readIntArray(intValues);
    148         // version 1 up to here
    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(timeStampNs);
    160         dest.writeInt(floatValues.length);
    161         dest.writeFloatArray(floatValues);
    162         dest.writeInt(intValues.length);
    163         dest.writeIntArray(intValues);
    164     }
    165 
    166     public static final Parcelable.Creator<CarSensorEvent> CREATOR
    167     = new Parcelable.Creator<CarSensorEvent>() {
    168         public CarSensorEvent createFromParcel(Parcel in) {
    169             return new CarSensorEvent(in);
    170         }
    171 
    172         public CarSensorEvent[] newArray(int size) {
    173             return new CarSensorEvent[size];
    174         }
    175     };
    176 
    177     public CarSensorEvent(int sensorType, long timeStampNs, int floatValueSize, int intValueSize) {
    178         this.sensorType = sensorType;
    179         this.timeStampNs = timeStampNs;
    180         floatValues = new float[floatValueSize];
    181         intValues = new int[intValueSize];
    182     }
    183 
    184     /** @hide */
    185     CarSensorEvent(int sensorType, long timeStampNs, float[] floatValues, int[] intValues) {
    186         this.sensorType = sensorType;
    187         this.timeStampNs = timeStampNs;
    188         this.floatValues = floatValues;
    189         this.intValues = intValues;
    190     }
    191 
    192     private void checkType(int type) {
    193         if (sensorType == type) {
    194             return;
    195         }
    196         throw new UnsupportedOperationException(String.format(
    197                 "Invalid sensor type: expected %d, got %d", type, sensorType));
    198     }
    199 
    200     public static class EnvironmentData {
    201         public long timeStampNs;
    202         /** If unsupported by the car, this value is NaN. */
    203         public float temperature;
    204         /** If unsupported by the car, this value is NaN. */
    205         public float pressure;
    206     }
    207 
    208     /**
    209      * Convenience method for obtaining an {@link EnvironmentData} object from a CarSensorEvent
    210      * object with type {@link CarSensorManager#SENSOR_TYPE_ENVIRONMENT}.
    211      *
    212      * @param data an optional output parameter which, if non-null, will be used by this method
    213      *     instead of a newly created object.
    214      * @return an EnvironmentData object corresponding to the data contained in the CarSensorEvent.
    215      */
    216     public EnvironmentData getEnvironmentData(EnvironmentData data) {
    217         checkType(CarSensorManager.SENSOR_TYPE_ENVIRONMENT);
    218         if (data == null) {
    219             data = new EnvironmentData();
    220         }
    221         data.timeStampNs = timeStampNs;
    222         data.temperature = floatValues[INDEX_ENVIRONMENT_TEMPERATURE];
    223         data.pressure = floatValues[INDEX_ENVIRONMENT_PRESSURE];
    224         return data;
    225     }
    226 
    227     public static class NightData {
    228         public long timeStampNs;
    229         public boolean isNightMode;
    230     }
    231 
    232     /**
    233      * Convenience method for obtaining a {@link NightData} object from a CarSensorEvent
    234      * object with type {@link CarSensorManager#SENSOR_TYPE_NIGHT}.
    235      *
    236      * @param data an optional output parameter which, if non-null, will be used by this method
    237      *     instead of a newly created object.
    238      * @return a NightData object corresponding to the data contained in the CarSensorEvent.
    239      */
    240     public NightData getNightData(NightData data) {
    241         checkType(CarSensorManager.SENSOR_TYPE_NIGHT);
    242         if (data == null) {
    243             data = new NightData();
    244         }
    245         data.timeStampNs = timeStampNs;
    246         data.isNightMode = intValues[0] == 1;
    247         return data;
    248     }
    249 
    250     public static class GearData {
    251         public long timeStampNs;
    252         public int gear;
    253     }
    254 
    255     /**
    256      * Convenience method for obtaining a {@link GearData} object from a CarSensorEvent
    257      * object with type {@link CarSensorManager#SENSOR_TYPE_GEAR}.
    258      *
    259      * @param data an optional output parameter which, if non-null, will be used by this method
    260      *     instead of a newly created object.
    261      * @return a GearData object corresponding to the data contained in the CarSensorEvent.
    262      */
    263     public GearData getGearData(GearData data) {
    264         checkType(CarSensorManager.SENSOR_TYPE_GEAR);
    265         if (data == null) {
    266             data = new GearData();
    267         }
    268         data.timeStampNs = timeStampNs;
    269         data.gear = intValues[0];
    270         return data;
    271     }
    272 
    273     public static class ParkingBrakeData {
    274         public long timeStampNs;
    275         public boolean isEngaged;
    276     }
    277 
    278     /**
    279      * Convenience method for obtaining a {@link ParkingBrakeData} object from a CarSensorEvent
    280      * object with type {@link CarSensorManager#SENSOR_TYPE_PARKING_BRAKE}.
    281      *
    282      * @param data an optional output parameter which, if non-null, will be used by this method
    283      *     instead of a newly created object.
    284      * @return a ParkingBreakData object corresponding to the data contained in the CarSensorEvent.
    285      */
    286     public ParkingBrakeData getParkingBrakeData(ParkingBrakeData data) {
    287         checkType(CarSensorManager.SENSOR_TYPE_PARKING_BRAKE);
    288         if (data == null) {
    289             data = new ParkingBrakeData();
    290         }
    291         data.timeStampNs = timeStampNs;
    292         data.isEngaged = intValues[0] == 1;
    293         return data;
    294     }
    295 
    296     public static class FuelLevelData {
    297         public long timeStampNs;
    298         /** Fuel level in %. If unsupported by the car, this value is -1. */
    299         public int level;
    300         /** Fuel as possible range in Km. If unsupported by the car, this value is -1. */
    301         public float range;
    302         /** If unsupported by the car, this value is false. */
    303         public boolean lowFuelWarning;
    304     }
    305 
    306     /**
    307      * Convenience method for obtaining a {@link FuelLevelData} object from a CarSensorEvent
    308      * object with type {@link CarSensorManager#SENSOR_TYPE_FUEL_LEVEL}.
    309      *
    310      * @param data an optional output parameter which, if non-null, will be used by this method
    311      *     instead of a newly created object.
    312      * @return a FuelLevel object corresponding to the data contained in the CarSensorEvent.
    313      */
    314     public FuelLevelData getFuelLevelData(FuelLevelData data) {
    315         checkType(CarSensorManager.SENSOR_TYPE_FUEL_LEVEL);
    316         if (data == null) {
    317             data = new FuelLevelData();
    318         }
    319         data.timeStampNs = timeStampNs;
    320         if (floatValues == null) {
    321             data.level = -1;
    322             data.range = -1;
    323         } else {
    324             if (floatValues[INDEX_FUEL_LEVEL_IN_PERCENTILE] < 0) {
    325                 data.level = -1;
    326             } else {
    327                 data.level = (int) floatValues[INDEX_FUEL_LEVEL_IN_PERCENTILE];
    328             }
    329             if (floatValues[INDEX_FUEL_LEVEL_IN_DISTANCE] < 0) {
    330                 data.range = -1;
    331             } else {
    332                 data.range = floatValues[INDEX_FUEL_LEVEL_IN_DISTANCE];
    333             }
    334         }
    335         data.lowFuelWarning = intValues[0] == 1;
    336         return data;
    337     }
    338 
    339     public static class OdometerData {
    340         public long timeStampNs;
    341         public float kms;
    342     }
    343 
    344     /**
    345      * Convenience method for obtaining an {@link OdometerData} object from a CarSensorEvent
    346      * object with type {@link CarSensorManager#SENSOR_TYPE_ODOMETER}.
    347      *
    348      * @param data an optional output parameter which, if non-null, will be used by this method
    349      *     instead of a newly created object.
    350      * @return an OdometerData object corresponding to the data contained in the CarSensorEvent.
    351      */
    352     public OdometerData getOdometerData(OdometerData data) {
    353         checkType(CarSensorManager.SENSOR_TYPE_ODOMETER);
    354         if (data == null) {
    355             data = new OdometerData();
    356         }
    357         data.timeStampNs = timeStampNs;
    358         data.kms = floatValues[0];
    359         return data;
    360     }
    361 
    362     public static class RpmData {
    363         public long timeStampNs;
    364         public float rpm;
    365     }
    366 
    367     /**
    368      * Convenience method for obtaining a {@link RpmData} object from a CarSensorEvent
    369      * object with type {@link CarSensorManager#SENSOR_TYPE_RPM}.
    370      *
    371      * @param data an optional output parameter which, if non-null, will be used by this method
    372      *     instead of a newly created object.
    373      * @return a RpmData object corresponding to the data contained in the CarSensorEvent.
    374      */
    375     public RpmData getRpmData(RpmData data) {
    376         checkType(CarSensorManager.SENSOR_TYPE_RPM);
    377         if (data == null) {
    378             data = new RpmData();
    379         }
    380         data.timeStampNs = timeStampNs;
    381         data.rpm = floatValues[0];
    382         return data;
    383     }
    384 
    385     public static class CarSpeedData {
    386         public long timeStampNs;
    387         public float carSpeed;
    388     }
    389 
    390     /**
    391      * Convenience method for obtaining a {@link CarSpeedData} object from a CarSensorEvent
    392      * object with type {@link CarSensorManager#SENSOR_TYPE_CAR_SPEED}.
    393      *
    394      * @param data an optional output parameter which, if non-null, will be used by this method
    395      *     instead of a newly created object.
    396      * @return a CarSpeedData object corresponding to the data contained in the CarSensorEvent.
    397      */
    398     public CarSpeedData getCarSpeedData(CarSpeedData data) {
    399         checkType(CarSensorManager.SENSOR_TYPE_CAR_SPEED);
    400         if (data == null) {
    401             data = new CarSpeedData();
    402         }
    403         data.timeStampNs = timeStampNs;
    404         data.carSpeed = floatValues[0];
    405         return data;
    406     }
    407 
    408     public static class DrivingStatusData {
    409         public long timeStampNs;
    410         public int status;
    411     }
    412 
    413     /**
    414      * Convenience method for obtaining a {@link DrivingStatusData} object from a CarSensorEvent
    415      * object with type {@link CarSensorManager#SENSOR_TYPE_DRIVING_STATUS}.
    416      *
    417      * @param data an optional output parameter which, if non-null, will be used by this method
    418      *     instead of a newly created object.
    419      * @return a DrivingStatusData object corresponding to the data contained in the CarSensorEvent.
    420      */
    421     public DrivingStatusData getDrivingStatusData(DrivingStatusData data) {
    422         checkType(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS);
    423         if (data == null) {
    424             data = new DrivingStatusData();
    425         }
    426         data.status = intValues[0];
    427         return data;
    428     }
    429 
    430     /** @hide */
    431     @Override
    432     public String toString() {
    433         StringBuilder sb = new StringBuilder();
    434         sb.append(getClass().getName() + "[");
    435         sb.append("type:" + Integer.toHexString(sensorType));
    436         if (floatValues != null && floatValues.length > 0) {
    437             sb.append(" float values:");
    438             for (float v: floatValues) {
    439                 sb.append(" " + v);
    440             }
    441         }
    442         if (intValues != null && intValues.length > 0) {
    443             sb.append(" int values:");
    444             for (int v: intValues) {
    445                 sb.append(" " + v);
    446             }
    447         }
    448         sb.append("]");
    449         return sb.toString();
    450     }
    451 }
    452