• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.SystemApi;
25 import android.car.VehicleAreaType;
26 import android.car.VehicleAreaType.VehicleAreaTypeValue;
27 import android.car.VehiclePropertyType;
28 import android.car.annotation.AddedInOrBefore;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 import android.util.SparseArray;
32 
33 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.lang.reflect.Array;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
41 
42 /**
43  * Represents general information about car property such as data type and min/max ranges for car
44  * areas (if applicable). This class supposed to be immutable, parcelable and could be passed over.
45  *
46  * @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
47  * should be visible to framework as default class loader is being used here.
48  *
49  */
50 public final class CarPropertyConfig<T> implements Parcelable {
51     private final int mAccess;
52     private final int mAreaType;
53     private final int mChangeMode;
54     private final ArrayList<Integer> mConfigArray;
55     private final String mConfigString;
56     private final float mMaxSampleRate;
57     private final float mMinSampleRate;
58     private final int mPropertyId;
59     private final SparseArray<AreaConfig<T>> mSupportedAreas;
60     private final Class<T> mType;
61 
CarPropertyConfig(int access, int areaType, int changeMode, ArrayList<Integer> configArray, String configString, float maxSampleRate, float minSampleRate, int propertyId, SparseArray<AreaConfig<T>> supportedAreas, Class<T> type)62     private CarPropertyConfig(int access, int areaType, int changeMode,
63             ArrayList<Integer> configArray, String configString,
64             float maxSampleRate, float minSampleRate, int propertyId,
65             SparseArray<AreaConfig<T>> supportedAreas, Class<T> type) {
66         mAccess = access;
67         mAreaType = areaType;
68         mChangeMode = changeMode;
69         mConfigArray = configArray;
70         mConfigString = configString;
71         mMaxSampleRate = maxSampleRate;
72         mMinSampleRate = minSampleRate;
73         mPropertyId = propertyId;
74         mSupportedAreas = supportedAreas;
75         mType = type;
76     }
77 
78     /** @hide */
79     @IntDef(prefix = {"VEHICLE_PROPERTY_ACCESS"}, value = {
80         VEHICLE_PROPERTY_ACCESS_NONE,
81         VEHICLE_PROPERTY_ACCESS_READ,
82         VEHICLE_PROPERTY_ACCESS_WRITE,
83         VEHICLE_PROPERTY_ACCESS_READ_WRITE
84     })
85     @Retention(RetentionPolicy.SOURCE)
86     public @interface VehiclePropertyAccessType {}
87 
88     /** Property Access Unknown */
89     @AddedInOrBefore(majorVersion = 33)
90     public static final int VEHICLE_PROPERTY_ACCESS_NONE = 0;
91     /** The property is readable */
92     @AddedInOrBefore(majorVersion = 33)
93     public static final int VEHICLE_PROPERTY_ACCESS_READ = 1;
94     /** The property is writable */
95     @AddedInOrBefore(majorVersion = 33)
96     public static final int VEHICLE_PROPERTY_ACCESS_WRITE = 2;
97     /** The property is readable and writable */
98     @AddedInOrBefore(majorVersion = 33)
99     public static final int VEHICLE_PROPERTY_ACCESS_READ_WRITE = 3;
100 
101     /** @hide */
102     @IntDef(prefix = {"VEHICLE_PROPERTY_CHANGE_MODE"}, value = {
103         VEHICLE_PROPERTY_CHANGE_MODE_STATIC,
104         VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE,
105         VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS,
106     })
107     @Retention(RetentionPolicy.SOURCE)
108     public @interface VehiclePropertyChangeModeType {}
109 
110     /** Properties of this type must never be changed. */
111     @AddedInOrBefore(majorVersion = 33)
112     public static final int VEHICLE_PROPERTY_CHANGE_MODE_STATIC = 0;
113     /** Properties of this type must report when there is a change. */
114     @AddedInOrBefore(majorVersion = 33)
115     public static final int VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE = 1;
116     /** Properties of this type change continuously. */
117     @AddedInOrBefore(majorVersion = 33)
118     public static final int VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS = 2;
119 
120     /**
121      * Return the access type of the car property.
122      * <p>The access type could be one of the following:
123      * <ul>
124      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_NONE}</li>
125      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ}</li>
126      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_WRITE}</li>
127      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}</li>
128      * </ul>
129      *
130      * @return the access type of the car property.
131      */
132     @AddedInOrBefore(majorVersion = 33)
getAccess()133     public @VehiclePropertyAccessType int getAccess() {
134         return mAccess;
135     }
136 
137     /**
138      * Return the area type of the car property.
139      * <p>The area type could be one of the following:
140      * <ul>
141      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}</li>
142      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_WINDOW}</li>
143      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_SEAT}</li>
144      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_DOOR}</li>
145      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_MIRROR}</li>
146      *   <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_WHEEL}</li>
147      * </ul>
148      *
149      * @return the area type of the car property.
150      */
151     @AddedInOrBefore(majorVersion = 33)
getAreaType()152     public @VehicleAreaTypeValue int getAreaType() {
153         return mAreaType;
154     }
155 
156     /**
157      * Return the change mode of the car property.
158      *
159      * <p>The change mode could be one of the following:
160      * <ul>
161      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_STATIC }</li>
162      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}</li>
163      *   <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS}</li>
164      * </ul>
165      *
166      * @return the change mode of properties.
167      */
168     @AddedInOrBefore(majorVersion = 33)
getChangeMode()169     public @VehiclePropertyChangeModeType int getChangeMode() {
170         return mChangeMode;
171     }
172 
173     /**
174      *
175      * @return Additional configuration parameters. For different properties, configArrays have
176      * different information.
177      */
178     @NonNull
179     @AddedInOrBefore(majorVersion = 33)
getConfigArray()180     public List<Integer> getConfigArray() {
181         return Collections.unmodifiableList(mConfigArray);
182     }
183 
184     /**
185      *
186      * @return Some properties may require additional information passed over this
187      * string. Most properties do not need to set this.
188      * @hide
189      */
190     @AddedInOrBefore(majorVersion = 33)
getConfigString()191     public String getConfigString() {
192         return mConfigString;
193     }
194 
195     /**
196      *
197      * @return Max sample rate in Hz. Must be defined for VehiclePropertyChangeMode::CONTINUOUS
198      * return 0 if change mode is not continuous.
199      */
200     @AddedInOrBefore(majorVersion = 33)
getMaxSampleRate()201     public float getMaxSampleRate() {
202         return mMaxSampleRate;
203     }
204 
205     /**
206      *
207      * @return Min sample rate in Hz.Must be defined for VehiclePropertyChangeMode::CONTINUOUS
208      * return 0 if change mode is not continuous.
209      */
210     @AddedInOrBefore(majorVersion = 33)
getMinSampleRate()211     public float getMinSampleRate() {
212         return mMinSampleRate;
213     }
214 
215     /**
216      * @return Property identifier, must be one of enums in
217      *   {@link android.car.VehiclePropertyIds}.
218      */
219     @AddedInOrBefore(majorVersion = 33)
getPropertyId()220     public int getPropertyId() {
221         return mPropertyId;
222     }
223 
224     /**
225      * Returns the value type of the vehicle property.
226      * <p>The value type could be one of the following:
227      * <ul>
228      *   <li>Boolean</li>
229      *   <li>Float</li>
230      *   <li>Float[]</li>
231      *   <li>Integer</li>
232      *   <li>Integer[]</li>
233      *   <li>Long</li>
234      *   <li>Long[]</li>
235      *   <li>String</li>
236      *   <li>byte[]</li>
237      *   <li>Object[]</li>
238      * </ul>
239      *
240      * @return the value type of the vehicle property.
241      */
242     @NonNull
243     @AddedInOrBefore(majorVersion = 33)
getPropertyType()244     public Class<T> getPropertyType() {
245         return mType;
246     }
247 
248     /**
249      *
250      * @return true if this property doesn't hold car area-specific configuration.
251      */
252     @AddedInOrBefore(majorVersion = 33)
isGlobalProperty()253     public boolean isGlobalProperty() {
254         return mAreaType == VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
255     }
256 
257     /**
258      *
259      * @return the number of areaIds for properties.
260      * @hide
261      */
262     @AddedInOrBefore(majorVersion = 33)
getAreaCount()263     public int getAreaCount() {
264         return mSupportedAreas.size();
265     }
266 
267     /**
268      *
269      * @return Array of areaIds. An AreaID is a combination of one or more areas,
270      * and is represented using a bitmask of Area enums. Different AreaTypes may
271      * not be mixed in a single AreaID. For instance, a window area cannot be
272      * combined with a seat area in an AreaID.
273      * Rules for mapping a zoned property to AreaIDs:
274      *  - A property must be mapped to an array of AreaIDs that are impacted when
275      *    the property value changes.
276      *  - Each element in the array must represent an AreaID, in which, the
277      *    property value can only be changed together in all the areas within
278      *    an AreaID and never independently. That is, when the property value
279      *    changes in one of the areas in an AreaID in the array, then it must
280      *    automatically change in all other areas in the AreaID.
281      *  - The property value must be independently controllable in any two
282      *    different AreaIDs in the array.
283      *  - An area must only appear once in the array of AreaIDs. That is, an
284      *    area must only be part of a single AreaID in the array.
285      */
286     @NonNull
287     @AddedInOrBefore(majorVersion = 33)
getAreaIds()288     public int[] getAreaIds() {
289         int[] areaIds = new int[mSupportedAreas.size()];
290         for (int i = 0; i < areaIds.length; i++) {
291             areaIds[i] = mSupportedAreas.keyAt(i);
292         }
293         return areaIds;
294     }
295 
296     /**
297      * @return  the first areaId.
298      * Throws {@link IllegalStateException} if supported area count not equals to one.
299      * @hide
300      */
301     @AddedInOrBefore(majorVersion = 33)
getFirstAndOnlyAreaId()302     public int getFirstAndOnlyAreaId() {
303         if (mSupportedAreas.size() != 1) {
304             throw new IllegalStateException("Expected one and only area in this property. Prop: 0x"
305                     + Integer.toHexString(mPropertyId));
306         }
307         return mSupportedAreas.keyAt(0);
308     }
309 
310     /**
311      *
312      * @param areaId
313      * @return true if areaId is existing.
314      * @hide
315      */
316     @AddedInOrBefore(majorVersion = 33)
hasArea(int areaId)317     public boolean hasArea(int areaId) {
318         return mSupportedAreas.indexOfKey(areaId) >= 0;
319     }
320 
321     /**
322      *
323      * @param areaId
324      * @return Min value in given areaId. Null if not have min value in given area.
325      */
326     @Nullable
327     @AddedInOrBefore(majorVersion = 33)
getMinValue(int areaId)328     public T getMinValue(int areaId) {
329         AreaConfig<T> area = mSupportedAreas.get(areaId);
330         return area == null ? null : area.getMinValue();
331     }
332 
333     /**
334      *
335      * @param areaId
336      * @return Max value in given areaId. Null if not have max value in given area.
337      */
338     @Nullable
339     @AddedInOrBefore(majorVersion = 33)
getMaxValue(int areaId)340     public T getMaxValue(int areaId) {
341         AreaConfig<T> area = mSupportedAreas.get(areaId);
342         return area == null ? null : area.getMaxValue();
343     }
344 
345     /**
346      *
347      * @return Min value in areaId 0. Null if not have min value.
348      */
349     @Nullable
350     @AddedInOrBefore(majorVersion = 33)
getMinValue()351     public T getMinValue() {
352         AreaConfig<T> area = mSupportedAreas.get(0);
353         return area == null ? null : area.getMinValue();
354     }
355 
356     /**
357      *
358      * @return Max value in areaId 0. Null if not have max value.
359      */
360     @Nullable
361     @AddedInOrBefore(majorVersion = 33)
getMaxValue()362     public T getMaxValue() {
363         AreaConfig<T> area = mSupportedAreas.get(0);
364         return area == null ? null : area.getMaxValue();
365     }
366 
367     @Override
368     @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
369     @AddedInOrBefore(majorVersion = 33)
describeContents()370     public int describeContents() {
371         return 0;
372     }
373 
374     @Override
375     @AddedInOrBefore(majorVersion = 33)
writeToParcel(Parcel dest, int flags)376     public void writeToParcel(Parcel dest, int flags) {
377         dest.writeInt(mAccess);
378         dest.writeInt(mAreaType);
379         dest.writeInt(mChangeMode);
380         dest.writeInt(mConfigArray.size());
381         for (int i = 0; i < mConfigArray.size(); i++) {
382             dest.writeInt(mConfigArray.get(i));
383         }
384         dest.writeString(mConfigString);
385         dest.writeFloat(mMaxSampleRate);
386         dest.writeFloat(mMinSampleRate);
387         dest.writeInt(mPropertyId);
388         dest.writeInt(mSupportedAreas.size());
389         for (int i = 0; i < mSupportedAreas.size(); i++) {
390             dest.writeInt(mSupportedAreas.keyAt(i));
391             dest.writeParcelable(mSupportedAreas.valueAt(i), flags);
392         }
393         dest.writeString(mType.getName());
394     }
395 
396     @SuppressWarnings("unchecked")
CarPropertyConfig(Parcel in)397     private CarPropertyConfig(Parcel in) {
398         mAccess = in.readInt();
399         mAreaType = in.readInt();
400         mChangeMode = in.readInt();
401         int configArraySize = in.readInt();
402         mConfigArray = new ArrayList<Integer>(configArraySize);
403         for (int i = 0; i < configArraySize; i++) {
404             mConfigArray.add(in.readInt());
405         }
406         mConfigString = in.readString();
407         mMaxSampleRate = in.readFloat();
408         mMinSampleRate = in.readFloat();
409         mPropertyId = in.readInt();
410         int areaSize = in.readInt();
411         mSupportedAreas = new SparseArray<>(areaSize);
412         for (int i = 0; i < areaSize; i++) {
413             int areaId = in.readInt();
414             AreaConfig<T> area = in.readParcelable(getClass().getClassLoader());
415             mSupportedAreas.put(areaId, area);
416         }
417         String className = in.readString();
418         try {
419             mType = (Class<T>) Class.forName(className);
420         } catch (ClassNotFoundException e) {
421             throw new IllegalArgumentException("Class not found: " + className);
422         }
423     }
424 
425     @AddedInOrBefore(majorVersion = 33)
426     public static final Creator<CarPropertyConfig> CREATOR = new Creator<CarPropertyConfig>() {
427         @Override
428         public CarPropertyConfig createFromParcel(Parcel in) {
429             return new CarPropertyConfig(in);
430         }
431 
432         @Override
433         public CarPropertyConfig[] newArray(int size) {
434             return new CarPropertyConfig[size];
435         }
436     };
437 
438     /** @hide */
439     @Override
440     @AddedInOrBefore(majorVersion = 33)
toString()441     public String toString() {
442         return "CarPropertyConfig{"
443                 + "mPropertyId=" + mPropertyId
444                 + ", mAccess=" + mAccess
445                 + ", mAreaType=" + mAreaType
446                 + ", mChangeMode=" + mChangeMode
447                 + ", mConfigArray=" + mConfigArray
448                 + ", mConfigString=" + mConfigString
449                 + ", mMaxSampleRate=" + mMaxSampleRate
450                 + ", mMinSampleRate=" + mMinSampleRate
451                 + ", mSupportedAreas=" + mSupportedAreas
452                 + ", mType=" + mType
453                 + '}';
454     }
455 
456     /**
457      * Represents min/max value of car property.
458      * @param <T>
459      * @hide
460      */
461     public static class AreaConfig<T> implements Parcelable {
462         @Nullable private final T mMinValue;
463         @Nullable private final T mMaxValue;
464 
AreaConfig(T minValue, T maxValue)465         private AreaConfig(T minValue, T maxValue) {
466             mMinValue = minValue;
467             mMaxValue = maxValue;
468         }
469 
470         @AddedInOrBefore(majorVersion = 33)
471         public static final Parcelable.Creator<AreaConfig<Object>> CREATOR =
472                 getCreator(Object.class);
473 
getCreator(final Class<E> clazz)474         private static <E> Parcelable.Creator<AreaConfig<E>> getCreator(final Class<E> clazz) {
475             return new Creator<AreaConfig<E>>() {
476                 @Override
477                 public AreaConfig<E> createFromParcel(Parcel source) {
478                     return new AreaConfig<>(source);
479                 }
480 
481                 @Override @SuppressWarnings("unchecked")
482                 public AreaConfig<E>[] newArray(int size) {
483                     return (AreaConfig<E>[]) Array.newInstance(clazz, size);
484                 }
485             };
486         }
487 
488         @SuppressWarnings("unchecked")
AreaConfig(Parcel in)489         private AreaConfig(Parcel in) {
490             mMinValue = (T) in.readValue(getClass().getClassLoader());
491             mMaxValue = (T) in.readValue(getClass().getClassLoader());
492         }
493 
494         @AddedInOrBefore(majorVersion = 33)
getMinValue()495         @Nullable public T getMinValue() {
496             return mMinValue;
497         }
498 
499         @AddedInOrBefore(majorVersion = 33)
getMaxValue()500         @Nullable public T getMaxValue() {
501             return mMaxValue;
502         }
503 
504         @Override
505         @AddedInOrBefore(majorVersion = 33)
describeContents()506         public int describeContents() {
507             return 0;
508         }
509 
510         @Override
511         @AddedInOrBefore(majorVersion = 33)
writeToParcel(Parcel dest, int flags)512         public void writeToParcel(Parcel dest, int flags) {
513             dest.writeValue(mMinValue);
514             dest.writeValue(mMaxValue);
515         }
516 
517         @Override
518         @AddedInOrBefore(majorVersion = 33)
toString()519         public String toString() {
520             return "CarAreaConfig{"
521                     + "mMinValue=" + mMinValue
522                     + ", mMaxValue=" + mMaxValue
523                     + '}';
524         }
525     }
526 
527     /**
528      * Prepare an instance of CarPropertyConfig
529      *
530      * @return Builder<T>
531      * @hide
532      */
533     @SystemApi
534     @AddedInOrBefore(majorVersion = 33)
535     public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType,
536                                             int areaCapacity) {
537         return new Builder<>(areaCapacity, areaType, propertyId, type);
538     }
539 
540 
541     /**
542      * Prepare an instance of CarPropertyConfig
543      *
544      * @return Builder<T>
545      * @hide
546      */
547     @AddedInOrBefore(majorVersion = 33)
548     public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType) {
549         return new Builder<>(0, areaType, propertyId, type);
550     }
551 
552 
553     /**
554      * @param <T>
555      * @hide
556      * */
557     @SystemApi
558     public static class Builder<T> {
559         private int mAccess;
560         private final int mAreaType;
561         private int mChangeMode;
562         private final ArrayList<Integer> mConfigArray;
563         private String mConfigString;
564         private float mMaxSampleRate;
565         private float mMinSampleRate;
566         private final int mPropertyId;
567         private final SparseArray<AreaConfig<T>> mSupportedAreas;
568         private final Class<T> mType;
569 
570         private Builder(int areaCapacity, int areaType, int propertyId, Class<T> type) {
571             mAreaType = areaType;
572             mConfigArray = new ArrayList<>();
573             mPropertyId = propertyId;
574             if (areaCapacity != 0) {
575                 mSupportedAreas = new SparseArray<>(areaCapacity);
576             } else {
577                 mSupportedAreas = new SparseArray<>();
578             }
579             mType = type;
580         }
581 
582         /**
583          * Add supported areas parameter to CarPropertyConfig
584          *
585          * @return Builder<T>
586          */
587         @AddedInOrBefore(majorVersion = 33)
588         public Builder<T> addAreas(int[] areaIds) {
589             for (int id : areaIds) {
590                 mSupportedAreas.put(id, null);
591             }
592             return this;
593         }
594 
595         /**
596          * Add area to CarPropertyConfig
597          *
598          * @return Builder<T>
599          */
600         @AddedInOrBefore(majorVersion = 33)
601         public Builder<T> addArea(int areaId) {
602             return addAreaConfig(areaId, null, null);
603         }
604 
605         /**
606          * Add areaConfig to CarPropertyConfig
607          *
608          * @return Builder<T>
609          */
610         @AddedInOrBefore(majorVersion = 33)
611         public Builder<T> addAreaConfig(int areaId, T min, T max) {
612             if (!isRangeAvailable(min, max)) {
613                 mSupportedAreas.put(areaId, null);
614             } else {
615                 mSupportedAreas.put(areaId, new AreaConfig<>(min, max));
616             }
617             return this;
618         }
619 
620         /**
621          * Set access parameter to CarPropertyConfig
622          *
623          * @return Builder<T>
624          */
625         @AddedInOrBefore(majorVersion = 33)
626         public Builder<T> setAccess(int access) {
627             mAccess = access;
628             return this;
629         }
630 
631         /**
632          * Set changeMode parameter to CarPropertyConfig
633          *
634          * @return Builder<T>
635          */
636         @AddedInOrBefore(majorVersion = 33)
637         public Builder<T> setChangeMode(int changeMode) {
638             mChangeMode = changeMode;
639             return this;
640         }
641 
642         /**
643          * Set configArray parameter to CarPropertyConfig
644          *
645          * @return Builder<T>
646          */
647         @AddedInOrBefore(majorVersion = 33)
648         public Builder<T> setConfigArray(ArrayList<Integer> configArray) {
649             mConfigArray.clear();
650             mConfigArray.addAll(configArray);
651             return this;
652         }
653 
654         /**
655          * Set configString parameter to CarPropertyConfig
656          *
657          * @return Builder<T>
658          */
659         @AddedInOrBefore(majorVersion = 33)
660         public Builder<T> setConfigString(String configString) {
661             mConfigString = configString;
662             return this;
663         }
664 
665         /**
666          * Set maxSampleRate parameter to CarPropertyConfig
667          *
668          * @return Builder<T>
669          */
670         @AddedInOrBefore(majorVersion = 33)
671         public Builder<T> setMaxSampleRate(float maxSampleRate) {
672             mMaxSampleRate = maxSampleRate;
673             return this;
674         }
675 
676         /**
677          * Set minSampleRate parameter to CarPropertyConfig
678          *
679          * @return Builder<T>
680          */
681         @AddedInOrBefore(majorVersion = 33)
682         public Builder<T> setMinSampleRate(float minSampleRate) {
683             mMinSampleRate = minSampleRate;
684             return this;
685         }
686 
687         /**
688          * Builds a new {@link CarPropertyConfig}.
689          */
690         @AddedInOrBefore(majorVersion = 33)
691         public CarPropertyConfig<T> build() {
692             return new CarPropertyConfig<>(mAccess, mAreaType, mChangeMode, mConfigArray,
693                                            mConfigString, mMaxSampleRate, mMinSampleRate,
694                                            mPropertyId, mSupportedAreas, mType);
695         }
696 
697         private boolean isRangeAvailable(T min, T max) {
698             if (min == null || max == null) {
699                 return false;
700             }
701             int propertyType = mPropertyId & VehiclePropertyType.MASK;
702             switch (propertyType) {
703                 case VehiclePropertyType.INT32:
704                     return (Integer) min  != 0 || (Integer) max != 0;
705                 case VehiclePropertyType.INT64:
706                     return (Long) min != 0L || (Long) max != 0L;
707                 case VehiclePropertyType.FLOAT:
708                     return (Float) min != 0f || (Float) max != 0f;
709                 default:
710                     return false;
711             }
712         }
713     }
714 }
715