• 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 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 
28 /**
29  * Represents general information about car property such as data type and min/max ranges for car
30  * areas (if applicable). This class supposed to be immutable, parcelable and could be passed over.
31  *
32  * <p>Use {@link CarPropertyConfig#newBuilder} to create an instance of this class.
33  *
34  * @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
35  * should be visible to framework as default class loader is being used here.
36  *
37  * @hide
38  */
39 @SystemApi
40 public class CarPropertyConfig<T> implements Parcelable {
41     private final int mPropertyId;
42     private final Class<T> mType;
43     private final int mAreaType;
44     private final SparseArray<AreaConfig<T>> mSupportedAreas;
45 
CarPropertyConfig(Class<T> type, int propertyId, int areaType, SparseArray<AreaConfig<T>> supportedAreas)46     private CarPropertyConfig(Class<T> type, int propertyId, int areaType,
47             SparseArray<AreaConfig<T>> supportedAreas) {
48         mPropertyId = propertyId;
49         mType = type;
50         mAreaType = areaType;
51         mSupportedAreas = supportedAreas;
52     }
53 
getPropertyId()54     public int getPropertyId() { return mPropertyId; }
getPropertyType()55     public Class<T> getPropertyType() { return mType; }
getAreaType()56     public @VehicleAreaType.VehicleAreaTypeValue int getAreaType() { return mAreaType; }
57 
58     /** Returns true if this property doesn't hold car area-specific configuration */
isGlobalProperty()59     public boolean isGlobalProperty() {
60         return mAreaType == VehicleAreaType.VEHICLE_AREA_TYPE_NONE;
61     }
62 
getAreaCount()63     public int getAreaCount() {
64         return mSupportedAreas.size();
65     }
66 
getAreaIds()67     public int[] getAreaIds() {
68         int[] areaIds = new int[mSupportedAreas.size()];
69         for (int i = 0; i < areaIds.length; i++) {
70             areaIds[i] = mSupportedAreas.keyAt(i);
71         }
72         return areaIds;
73     }
74 
75     /**
76      * Returns the first areaId.
77      * Throws {@link IllegalStateException} if supported area count not equals to one.
78      * */
getFirstAndOnlyAreaId()79     public int getFirstAndOnlyAreaId() {
80         if (mSupportedAreas.size() != 1) {
81             throw new IllegalStateException("Expected one and only area in this property. Prop: 0x"
82                     + Integer.toHexString(mPropertyId));
83         }
84         return mSupportedAreas.keyAt(0);
85     }
86 
hasArea(int areaId)87     public boolean hasArea(int areaId) {
88         return mSupportedAreas.indexOfKey(areaId) >= 0;
89     }
90 
91     @Nullable
getMinValue(int areaId)92     public T getMinValue(int areaId) {
93         AreaConfig<T> area = mSupportedAreas.get(areaId);
94         return area == null ? null : area.getMinValue();
95     }
96 
97     @Nullable
getMaxValue(int areaId)98     public T getMaxValue(int areaId) {
99         AreaConfig<T> area = mSupportedAreas.get(areaId);
100         return area == null ? null : area.getMaxValue();
101     }
102 
103     @Nullable
getMinValue()104     public T getMinValue() {
105         AreaConfig<T> area = mSupportedAreas.valueAt(0);
106         return area == null ? null : area.getMinValue();
107     }
108 
109     @Nullable
getMaxValue()110     public T getMaxValue() {
111         AreaConfig<T> area = mSupportedAreas.valueAt(0);
112         return area == null ? null : area.getMaxValue();
113     }
114 
115     @Override
describeContents()116     public int describeContents() {
117         return 0;
118     }
119 
120     @Override
writeToParcel(Parcel dest, int flags)121     public void writeToParcel(Parcel dest, int flags) {
122         dest.writeInt(mPropertyId);
123         dest.writeString(mType.getName());
124         dest.writeInt(mAreaType);
125         dest.writeInt(mSupportedAreas.size());
126         for (int i = 0; i < mSupportedAreas.size(); i++) {
127             dest.writeInt(mSupportedAreas.keyAt(i));
128             dest.writeParcelable(mSupportedAreas.valueAt(i), flags);
129         }
130     }
131 
132     @SuppressWarnings("unchecked")
CarPropertyConfig(Parcel in)133     private CarPropertyConfig(Parcel in) {
134         mPropertyId = in.readInt();
135         String className = in.readString();
136         try {
137             mType = (Class<T>) Class.forName(className);
138         } catch (ClassNotFoundException e) {
139             throw new IllegalArgumentException("Class not found: " + className);
140         }
141         mAreaType = in.readInt();
142         int areaSize = in.readInt();
143         mSupportedAreas = new SparseArray<>(areaSize);
144         for (int i = 0; i < areaSize; i++) {
145             int areaId = in.readInt();
146             AreaConfig<T> area = in.readParcelable(getClass().getClassLoader());
147             mSupportedAreas.put(areaId, area);
148         }
149     }
150 
151     public static final Creator<CarPropertyConfig> CREATOR = new Creator<CarPropertyConfig>() {
152         @Override
153         public CarPropertyConfig createFromParcel(Parcel in) {
154             return new CarPropertyConfig(in);
155         }
156 
157         @Override
158         public CarPropertyConfig[] newArray(int size) {
159             return new CarPropertyConfig[size];
160         }
161     };
162 
163     @Override
toString()164     public String toString() {
165         return "CarPropertyConfig{" +
166                 "mPropertyId=" + mPropertyId +
167                 ", mType=" + mType +
168                 ", mAreaType=" + mAreaType +
169                 ", mSupportedAreas=" + mSupportedAreas +
170                 '}';
171     }
172 
173     public static class AreaConfig<T> implements Parcelable {
174         @Nullable private final T mMinValue;
175         @Nullable private final T mMaxValue;
176 
AreaConfig(T minValue, T maxValue)177         private AreaConfig(T minValue, T maxValue) {
178             mMinValue = minValue;
179             mMaxValue = maxValue;
180         }
181 
182         public static final Parcelable.Creator<AreaConfig<Object>> CREATOR
183                 = getCreator(Object.class);
184 
getCreator(final Class<E> clazz)185         private static <E> Parcelable.Creator<AreaConfig<E>> getCreator(final Class<E> clazz) {
186             return new Creator<AreaConfig<E>>() {
187                 @Override
188                 public AreaConfig<E> createFromParcel(Parcel source) {
189                     return new AreaConfig<>(source);
190                 }
191 
192                 @Override @SuppressWarnings("unchecked")
193                 public AreaConfig<E>[] newArray(int size) {
194                     return (AreaConfig<E>[]) Array.newInstance(clazz, size);
195                 }
196             };
197         }
198 
199         @SuppressWarnings("unchecked")
AreaConfig(Parcel in)200         private AreaConfig(Parcel in) {
201             mMinValue = (T) in.readValue(getClass().getClassLoader());
202             mMaxValue = (T) in.readValue(getClass().getClassLoader());
203         }
204 
getMinValue()205         @Nullable public T getMinValue() { return mMinValue; }
getMaxValue()206         @Nullable public T getMaxValue() { return mMaxValue; }
207 
208         @Override
describeContents()209         public int describeContents() {
210             return 0;
211         }
212 
213         @Override
writeToParcel(Parcel dest, int flags)214         public void writeToParcel(Parcel dest, int flags) {
215             dest.writeValue(mMinValue);
216             dest.writeValue(mMaxValue);
217         }
218 
219         @Override
toString()220         public String toString() {
221             return "CarAreaConfig{" +
222                     "mMinValue=" + mMinValue +
223                     ", mMaxValue=" + mMaxValue +
224                     '}';
225         }
226     }
227 
228     public static <T> Builder<T> newBuilder(Class<T> clazz, int propertyId, int areaType,
229             int areaCapacity) {
230         return new Builder<>(clazz, propertyId, areaType, areaCapacity);
231     }
232 
233 
234     public static <T> Builder<T> newBuilder(Class<T> clazz, int propertyId, int areaType) {
235         return newBuilder(clazz, propertyId, areaType, 0);
236     }
237 
238     public static class Builder<T> {
239         private final Class<T> mType;
240         private final int mPropertyId;
241         private final int mAreaType;
242         private final SparseArray<AreaConfig<T>> mAreas;
243 
244         private Builder(Class<T> type, int propertyId, int areaType, int areaCapacity) {
245             mType = type;
246             mPropertyId = propertyId;
247             mAreaType = areaType;
248             if (areaCapacity != 0) {
249                 mAreas = new SparseArray<>(areaCapacity);
250             } else {
251                 mAreas = new SparseArray<>();
252             }
253         }
254 
255         public Builder<T> addAreas(int[] areaIds) {
256             for (int id : areaIds) {
257                 mAreas.put(id, null);
258             }
259             return this;
260         }
261 
262         public Builder<T> addArea(int areaId) {
263             return addAreaConfig(areaId, null, null);
264         }
265 
266         public Builder<T> addAreaConfig(int areaId, T min, T max) {
267             if (min == null && max == null) {
268                 mAreas.put(areaId, null);
269             } else {
270                 mAreas.put(areaId, new AreaConfig<>(min, max));
271             }
272             return this;
273         }
274 
275         public CarPropertyConfig<T> build() {
276             return new CarPropertyConfig<>(mType, mPropertyId, mAreaType, mAreas);
277         }
278     }
279 }
280