Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2016 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.annotation.Nullable;
     20 import android.annotation.SystemApi;
     21 import android.car.VehicleAreaType;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.util.SparseArray;
     25 
     26 import java.lang.reflect.Array;
     27 import java.util.ArrayList;
     28 import java.util.Collections;
     29 import java.util.List;
     30 
     31 /**
     32  * Represents general information about car property such as data type and min/max ranges for car
     33  * areas (if applicable). This class supposed to be immutable, parcelable and could be passed over.
     34  *
     35  * <p>Use {@link CarPropertyConfig#newBuilder} to create an instance of this class.
     36  *
     37  * @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
     38  * should be visible to framework as default class loader is being used here.
     39  *
     40  * @hide
     41  */
     42 @SystemApi
     43 public class CarPropertyConfig<T> implements Parcelable {
     44     private final int mAccess;
     45     private final int mAreaType;
     46     private final int mChangeMode;
     47     private final ArrayList<Integer> mConfigArray;
     48     private final String mConfigString;
     49     private final float mMaxSampleRate;
     50     private final float mMinSampleRate;
     51     private final int mPropertyId;
     52     private final SparseArray<AreaConfig<T>> mSupportedAreas;
     53     private final Class<T> mType;
     54 
     55     private CarPropertyConfig(int access, int areaType, int changeMode,
     56             ArrayList<Integer> configArray, String configString,
     57             float maxSampleRate, float minSampleRate, int propertyId,
     58             SparseArray<AreaConfig<T>> supportedAreas, Class<T> type) {
     59         mAccess = access;
     60         mAreaType = areaType;
     61         mChangeMode = changeMode;
     62         mConfigArray = configArray;
     63         mConfigString = configString;
     64         mMaxSampleRate = maxSampleRate;
     65         mMinSampleRate = minSampleRate;
     66         mPropertyId = propertyId;
     67         mSupportedAreas = supportedAreas;
     68         mType = type;
     69     }
     70 
     71     public int getAccess() {
     72         return mAccess;
     73     }
     74     public @VehicleAreaType.VehicleAreaTypeValue int getAreaType() {
     75         return mAreaType;
     76     }
     77     public int getChangeMode() {
     78         return mChangeMode;
     79     }
     80     public List<Integer> getConfigArray() {
     81         return Collections.unmodifiableList(mConfigArray);
     82     }
     83     public String getConfigString() {
     84         return mConfigString;
     85     }
     86     public float getMaxSampleRate() {
     87         return mMaxSampleRate;
     88     }
     89     public float getMinSampleRate() {
     90         return mMinSampleRate;
     91     }
     92     public int getPropertyId() {
     93         return mPropertyId;
     94     }
     95     public Class<T> getPropertyType() {
     96         return mType;
     97     }
     98 
     99     /** Returns true if this property doesn't hold car area-specific configuration */
    100     public boolean isGlobalProperty() {
    101         return mAreaType == VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
    102     }
    103 
    104     public int getAreaCount() {
    105         return mSupportedAreas.size();
    106     }
    107 
    108     public int[] getAreaIds() {
    109         int[] areaIds = new int[mSupportedAreas.size()];
    110         for (int i = 0; i < areaIds.length; i++) {
    111             areaIds[i] = mSupportedAreas.keyAt(i);
    112         }
    113         return areaIds;
    114     }
    115 
    116     /**
    117      * Returns the first areaId.
    118      * Throws {@link IllegalStateException} if supported area count not equals to one.
    119      * */
    120     public int getFirstAndOnlyAreaId() {
    121         if (mSupportedAreas.size() != 1) {
    122             throw new IllegalStateException("Expected one and only area in this property. Prop: 0x"
    123                     + Integer.toHexString(mPropertyId));
    124         }
    125         return mSupportedAreas.keyAt(0);
    126     }
    127 
    128     public boolean hasArea(int areaId) {
    129         return mSupportedAreas.indexOfKey(areaId) >= 0;
    130     }
    131 
    132     @Nullable
    133     public T getMinValue(int areaId) {
    134         AreaConfig<T> area = mSupportedAreas.get(areaId);
    135         return area == null ? null : area.getMinValue();
    136     }
    137 
    138     @Nullable
    139     public T getMaxValue(int areaId) {
    140         AreaConfig<T> area = mSupportedAreas.get(areaId);
    141         return area == null ? null : area.getMaxValue();
    142     }
    143 
    144     @Nullable
    145     public T getMinValue() {
    146         AreaConfig<T> area = mSupportedAreas.valueAt(0);
    147         return area == null ? null : area.getMinValue();
    148     }
    149 
    150     @Nullable
    151     public T getMaxValue() {
    152         AreaConfig<T> area = mSupportedAreas.valueAt(0);
    153         return area == null ? null : area.getMaxValue();
    154     }
    155 
    156     @Override
    157     public int describeContents() {
    158         return 0;
    159     }
    160 
    161     @Override
    162     public void writeToParcel(Parcel dest, int flags) {
    163         dest.writeInt(mAccess);
    164         dest.writeInt(mAreaType);
    165         dest.writeInt(mChangeMode);
    166         dest.writeInt(mConfigArray.size());
    167         for (int i = 0; i < mConfigArray.size(); i++) {
    168             dest.writeInt(mConfigArray.get(i));
    169         }
    170         dest.writeString(mConfigString);
    171         dest.writeFloat(mMaxSampleRate);
    172         dest.writeFloat(mMinSampleRate);
    173         dest.writeInt(mPropertyId);
    174         dest.writeInt(mSupportedAreas.size());
    175         for (int i = 0; i < mSupportedAreas.size(); i++) {
    176             dest.writeInt(mSupportedAreas.keyAt(i));
    177             dest.writeParcelable(mSupportedAreas.valueAt(i), flags);
    178         }
    179         dest.writeString(mType.getName());
    180     }
    181 
    182     @SuppressWarnings("unchecked")
    183     private CarPropertyConfig(Parcel in) {
    184         mAccess = in.readInt();
    185         mAreaType = in.readInt();
    186         mChangeMode = in.readInt();
    187         int configArraySize = in.readInt();
    188         mConfigArray = new ArrayList<Integer>(configArraySize);
    189         for (int i = 0; i < configArraySize; i++) {
    190             mConfigArray.add(in.readInt());
    191         }
    192         mConfigString = in.readString();
    193         mMaxSampleRate = in.readFloat();
    194         mMinSampleRate = in.readFloat();
    195         mPropertyId = in.readInt();
    196         int areaSize = in.readInt();
    197         mSupportedAreas = new SparseArray<>(areaSize);
    198         for (int i = 0; i < areaSize; i++) {
    199             int areaId = in.readInt();
    200             AreaConfig<T> area = in.readParcelable(getClass().getClassLoader());
    201             mSupportedAreas.put(areaId, area);
    202         }
    203         String className = in.readString();
    204         try {
    205             mType = (Class<T>) Class.forName(className);
    206         } catch (ClassNotFoundException e) {
    207             throw new IllegalArgumentException("Class not found: " + className);
    208         }
    209     }
    210 
    211     public static final Creator<CarPropertyConfig> CREATOR = new Creator<CarPropertyConfig>() {
    212         @Override
    213         public CarPropertyConfig createFromParcel(Parcel in) {
    214             return new CarPropertyConfig(in);
    215         }
    216 
    217         @Override
    218         public CarPropertyConfig[] newArray(int size) {
    219             return new CarPropertyConfig[size];
    220         }
    221     };
    222 
    223     @Override
    224     public String toString() {
    225         return "CarPropertyConfig{"
    226                 + "mPropertyId=" + mPropertyId
    227                 + ", mAccess=" + mAccess
    228                 + ", mAreaType=" + mAreaType
    229                 + ", mChangeMode=" + mChangeMode
    230                 + ", mConfigArray=" + mConfigArray
    231                 + ", mConfigString=" + mConfigString
    232                 + ", mMaxSampleRate=" + mMaxSampleRate
    233                 + ", mMinSampleRate=" + mMinSampleRate
    234                 + ", mSupportedAreas=" + mSupportedAreas
    235                 + ", mType=" + mType
    236                 + '}';
    237     }
    238 
    239     public static class AreaConfig<T> implements Parcelable {
    240         @Nullable private final T mMinValue;
    241         @Nullable private final T mMaxValue;
    242 
    243         private AreaConfig(T minValue, T maxValue) {
    244             mMinValue = minValue;
    245             mMaxValue = maxValue;
    246         }
    247 
    248         public static final Parcelable.Creator<AreaConfig<Object>> CREATOR
    249                 = getCreator(Object.class);
    250 
    251         private static <E> Parcelable.Creator<AreaConfig<E>> getCreator(final Class<E> clazz) {
    252             return new Creator<AreaConfig<E>>() {
    253                 @Override
    254                 public AreaConfig<E> createFromParcel(Parcel source) {
    255                     return new AreaConfig<>(source);
    256                 }
    257 
    258                 @Override @SuppressWarnings("unchecked")
    259                 public AreaConfig<E>[] newArray(int size) {
    260                     return (AreaConfig<E>[]) Array.newInstance(clazz, size);
    261                 }
    262             };
    263         }
    264 
    265         @SuppressWarnings("unchecked")
    266         private AreaConfig(Parcel in) {
    267             mMinValue = (T) in.readValue(getClass().getClassLoader());
    268             mMaxValue = (T) in.readValue(getClass().getClassLoader());
    269         }
    270 
    271         @Nullable public T getMinValue() { return mMinValue; }
    272         @Nullable public T getMaxValue() { return mMaxValue; }
    273 
    274         @Override
    275         public int describeContents() {
    276             return 0;
    277         }
    278 
    279         @Override
    280         public void writeToParcel(Parcel dest, int flags) {
    281             dest.writeValue(mMinValue);
    282             dest.writeValue(mMaxValue);
    283         }
    284 
    285         @Override
    286         public String toString() {
    287             return "CarAreaConfig{" +
    288                     "mMinValue=" + mMinValue +
    289                     ", mMaxValue=" + mMaxValue +
    290                     '}';
    291         }
    292     }
    293 
    294     /**
    295      * Prepare an instance of CarPropertyConfig
    296      *
    297      * @return Builder<T>
    298      */
    299     public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType,
    300                                             int areaCapacity) {
    301         return new Builder<>(areaCapacity, areaType, propertyId, type);
    302     }
    303 
    304 
    305     /**
    306      * Prepare an instance of CarPropertyConfig
    307      *
    308      * @return Builder<T>
    309      */
    310     public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType) {
    311         return new Builder<>(0, areaType, propertyId, type);
    312     }
    313 
    314     public static class Builder<T> {
    315         private int mAccess;
    316         private final int mAreaType;
    317         private int mChangeMode;
    318         private final ArrayList<Integer> mConfigArray;
    319         private String mConfigString;
    320         private float mMaxSampleRate;
    321         private float mMinSampleRate;
    322         private final int mPropertyId;
    323         private final SparseArray<AreaConfig<T>> mSupportedAreas;
    324         private final Class<T> mType;
    325 
    326         private Builder(int areaCapacity, int areaType, int propertyId, Class<T> type) {
    327             mAreaType = areaType;
    328             mConfigArray = new ArrayList<>();
    329             mPropertyId = propertyId;
    330             if (areaCapacity != 0) {
    331                 mSupportedAreas = new SparseArray<>(areaCapacity);
    332             } else {
    333                 mSupportedAreas = new SparseArray<>();
    334             }
    335             mType = type;
    336         }
    337 
    338         /**
    339          * Add supported areas parameter to CarPropertyConfig
    340          *
    341          * @return Builder<T>
    342          */
    343         public Builder<T> addAreas(int[] areaIds) {
    344             for (int id : areaIds) {
    345                 mSupportedAreas.put(id, null);
    346             }
    347             return this;
    348         }
    349 
    350         /**
    351          * Add area to CarPropertyConfig
    352          *
    353          * @return Builder<T>
    354          */
    355         public Builder<T> addArea(int areaId) {
    356             return addAreaConfig(areaId, null, null);
    357         }
    358 
    359         /**
    360          * Add areaConfig to CarPropertyConfig
    361          *
    362          * @return Builder<T>
    363          */
    364         public Builder<T> addAreaConfig(int areaId, T min, T max) {
    365             if (min == null && max == null) {
    366                 mSupportedAreas.put(areaId, null);
    367             } else {
    368                 mSupportedAreas.put(areaId, new AreaConfig<>(min, max));
    369             }
    370             return this;
    371         }
    372 
    373         /**
    374          * Set access parameter to CarPropertyConfig
    375          *
    376          * @return Builder<T>
    377          */
    378         public Builder<T> setAccess(int access) {
    379             mAccess = access;
    380             return this;
    381         }
    382 
    383         /**
    384          * Set changeMode parameter to CarPropertyConfig
    385          *
    386          * @return Builder<T>
    387          */
    388         public Builder<T> setChangeMode(int changeMode) {
    389             mChangeMode = changeMode;
    390             return this;
    391         }
    392 
    393         /**
    394          * Set configArray parameter to CarPropertyConfig
    395          *
    396          * @return Builder<T>
    397          */
    398         public Builder<T> setConfigArray(ArrayList<Integer> configArray) {
    399             mConfigArray.clear();
    400             mConfigArray.addAll(configArray);
    401             return this;
    402         }
    403 
    404         /**
    405          * Set configString parameter to CarPropertyConfig
    406          *
    407          * @return Builder<T>
    408          */
    409         public Builder<T> setConfigString(String configString) {
    410             mConfigString = configString;
    411             return this;
    412         }
    413 
    414         /**
    415          * Set maxSampleRate parameter to CarPropertyConfig
    416          *
    417          * @return Builder<T>
    418          */
    419         public Builder<T> setMaxSampleRate(float maxSampleRate) {
    420             mMaxSampleRate = maxSampleRate;
    421             return this;
    422         }
    423 
    424         /**
    425          * Set minSampleRate parameter to CarPropertyConfig
    426          *
    427          * @return Builder<T>
    428          */
    429         public Builder<T> setMinSampleRate(float minSampleRate) {
    430             mMinSampleRate = minSampleRate;
    431             return this;
    432         }
    433 
    434         public CarPropertyConfig<T> build() {
    435             return new CarPropertyConfig<>(mAccess, mAreaType, mChangeMode, mConfigArray,
    436                                            mConfigString, mMaxSampleRate, mMinSampleRate,
    437                                            mPropertyId, mSupportedAreas, mType);
    438         }
    439     }
    440 }
    441