Home | History | Annotate | Download | only in vehiclehal
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.car.vehiclehal;
     18 
     19 import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
     20 import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
     21 import android.hardware.automotive.vehicle.V2_1.Obd2FloatSensorIndex;
     22 import android.hardware.automotive.vehicle.V2_1.Obd2IntegerSensorIndex;
     23 import android.util.SparseArray;
     24 import java.util.BitSet;
     25 import java.util.Iterator;
     26 
     27 /**
     28  * A builder class for a VehiclePropValue that encapsulates a diagnostic event. This is the Java
     29  * equivalent of Obd2SensorStore.cpp in the native layer.
     30  *
     31  * @hide
     32  */
     33 public class DiagnosticEventBuilder {
     34     /**
     35      * An array-like container that knows to return a default value for any unwritten-to index.
     36      *
     37      * @param <T> the element type
     38      */
     39     class DefaultedArray<T> implements Iterable<T> {
     40         private final SparseArray<T> mElements = new SparseArray<>();
     41         private final int mSize;
     42         private final T mDefaultValue;
     43 
     44         DefaultedArray(int size, T defaultValue) {
     45             mSize = size;
     46             mDefaultValue = defaultValue;
     47         }
     48 
     49         private int checkIndex(int index) {
     50             if (index < 0 || index >= mSize)
     51                 throw new IndexOutOfBoundsException(
     52                         String.format("Index: %d, Size: %d", index, mSize));
     53             return index;
     54         }
     55 
     56         DefaultedArray<T> set(int index, T element) {
     57             checkIndex(index);
     58             mElements.put(index, element);
     59             return this;
     60         }
     61 
     62         T get(int index) {
     63             checkIndex(index);
     64             return mElements.get(index, mDefaultValue);
     65         }
     66 
     67         int size() {
     68             return mSize;
     69         }
     70 
     71         void clear() {
     72             mElements.clear();
     73         }
     74 
     75         @Override
     76         public Iterator<T> iterator() {
     77             return new Iterator<T>() {
     78                 private int mIndex = 0;
     79 
     80                 @Override
     81                 public boolean hasNext() {
     82                     return (mIndex >= 0) && (mIndex < mSize);
     83                 }
     84 
     85                 @Override
     86                 public T next() {
     87                     int index = mIndex++;
     88                     return get(index);
     89                 }
     90             };
     91         }
     92     }
     93 
     94     private final int mPropertyId;
     95     private final int mNumIntSensors;
     96     private final DefaultedArray<Integer> mIntValues;
     97     private final DefaultedArray<Float> mFloatValues;
     98     private final BitSet mBitmask;
     99     private String mDtc = null;
    100 
    101     public DiagnosticEventBuilder(VehiclePropConfig propConfig) {
    102         this(propConfig.prop, propConfig.configArray.get(0), propConfig.configArray.get(1));
    103     }
    104 
    105     public DiagnosticEventBuilder(int propertyId) {
    106         this(propertyId, 0, 0);
    107     }
    108 
    109     public DiagnosticEventBuilder(
    110             int propertyId, int numVendorIntSensors, int numVendorFloatSensors) {
    111         mPropertyId = propertyId;
    112         mNumIntSensors = Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 1 + numVendorIntSensors;
    113         final int numFloatSensors =
    114                 Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 1 + numVendorFloatSensors;
    115         mBitmask = new BitSet(mNumIntSensors + numFloatSensors);
    116         mIntValues = new DefaultedArray<>(mNumIntSensors, 0);
    117         mFloatValues = new DefaultedArray<>(numFloatSensors, 0.0f);
    118     }
    119 
    120     public DiagnosticEventBuilder clear() {
    121         mIntValues.clear();
    122         mFloatValues.clear();
    123         mBitmask.clear();
    124         mDtc = null;
    125         return this;
    126     }
    127 
    128     public DiagnosticEventBuilder addIntSensor(int index, int value) {
    129         mIntValues.set(index, value);
    130         mBitmask.set(index);
    131         return this;
    132     }
    133 
    134     public DiagnosticEventBuilder addFloatSensor(int index, float value) {
    135         mFloatValues.set(index, value);
    136         mBitmask.set(mNumIntSensors + index);
    137         return this;
    138     }
    139 
    140     public DiagnosticEventBuilder setDTC(String dtc) {
    141         mDtc = dtc;
    142         return this;
    143     }
    144 
    145     public VehiclePropValue build() {
    146         return build(0);
    147     }
    148 
    149     public VehiclePropValue build(long timestamp) {
    150         VehiclePropValueBuilder propValueBuilder = VehiclePropValueBuilder.newBuilder(mPropertyId);
    151         if (0 == timestamp) {
    152             propValueBuilder.setTimestamp();
    153         } else {
    154             propValueBuilder.setTimestamp(timestamp);
    155         }
    156         mIntValues.forEach(propValueBuilder::addIntValue);
    157         mFloatValues.forEach(propValueBuilder::addFloatValue);
    158         return propValueBuilder.addByteValue(mBitmask.toByteArray()).setStringValue(mDtc).build();
    159     }
    160 }
    161