• 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 java.lang.Integer.toHexString;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.nio.charset.Charset;
29 
30 /**
31  * Stores values broken down by area for a vehicle property.
32  *
33  * @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
34  * should be visible to framework as default class loader is being used here.
35  *
36  */
37 public final class CarPropertyValue<T> implements Parcelable {
38     private final static Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
39 
40     private final int mPropertyId;
41     private final int mAreaId;
42     private final int mStatus;
43     private final long mTimestamp;
44     private final T mValue;
45 
46     @IntDef({
47         STATUS_AVAILABLE,
48         STATUS_UNAVAILABLE,
49         STATUS_ERROR
50     })
51     @Retention(RetentionPolicy.SOURCE)
52     public @interface PropertyStatus {}
53 
54     /**
55      * CarPropertyValue is available.
56      */
57     public static final int STATUS_AVAILABLE = 0;
58 
59     /**
60      * CarPropertyValue is unavailable.
61      */
62     public static final int STATUS_UNAVAILABLE = 1;
63 
64     /**
65      * CarPropertyVale has an error.
66      */
67     public static final int STATUS_ERROR = 2;
68 
69     /**
70      * Get an instance of CarPropertyValue
71      * @param propertyId Property ID
72      * @param areaId Area ID of Property
73      * @param value Value of Property
74      * @hide
75      */
CarPropertyValue(int propertyId, int areaId, T value)76     public CarPropertyValue(int propertyId, int areaId, T value) {
77         this(propertyId, areaId, 0, 0, value);
78     }
79 
80     /**
81      * Get an instance of CarPropertyValue
82      * @param propertyId Property ID
83      * @param areaId Area ID of Property
84      * @param status Status of Property
85      * @param timestamp Timestamp in nanosecond
86      * @param value Value of Property
87      * @hide
88      */
CarPropertyValue(int propertyId, int areaId, int status, long timestamp, T value)89     public CarPropertyValue(int propertyId, int areaId, int status, long timestamp, T value) {
90         mPropertyId = propertyId;
91         mAreaId = areaId;
92         mStatus = status;
93         mTimestamp = timestamp;
94         mValue = value;
95     }
96 
97     /**
98      * Get an instance of CarPropertyValue
99      * @param in Parcel to read
100      * @hide
101      */
102     @SuppressWarnings("unchecked")
CarPropertyValue(Parcel in)103     public CarPropertyValue(Parcel in) {
104         mPropertyId = in.readInt();
105         mAreaId = in.readInt();
106         mStatus = in.readInt();
107         mTimestamp = in.readLong();
108         String valueClassName = in.readString();
109         Class<?> valueClass;
110         try {
111             valueClass = Class.forName(valueClassName);
112         } catch (ClassNotFoundException e) {
113             throw new IllegalArgumentException("Class not found: " + valueClassName);
114         }
115 
116         if (String.class.equals(valueClass)) {
117             byte[] bytes = in.readBlob();
118             mValue = (T) new String(bytes, DEFAULT_CHARSET);
119         } else if (byte[].class.equals(valueClass)) {
120             mValue = (T) in.readBlob();
121         } else {
122             mValue = (T) in.readValue(valueClass.getClassLoader());
123         }
124     }
125 
126     public static final Creator<CarPropertyValue> CREATOR = new Creator<CarPropertyValue>() {
127         @Override
128         public CarPropertyValue createFromParcel(Parcel in) {
129             return new CarPropertyValue(in);
130         }
131 
132         @Override
133         public CarPropertyValue[] newArray(int size) {
134             return new CarPropertyValue[size];
135         }
136     };
137 
138     @Override
describeContents()139     public int describeContents() {
140         return 0;
141     }
142 
143     @Override
writeToParcel(Parcel dest, int flags)144     public void writeToParcel(Parcel dest, int flags) {
145         dest.writeInt(mPropertyId);
146         dest.writeInt(mAreaId);
147         dest.writeInt(mStatus);
148         dest.writeLong(mTimestamp);
149 
150         Class<?> valueClass = mValue == null ? null : mValue.getClass();
151         dest.writeString(valueClass == null ? null : valueClass.getName());
152 
153         // Special handling for String and byte[] to mitigate transaction buffer limitations.
154         if (String.class.equals(valueClass)) {
155             dest.writeBlob(((String)mValue).getBytes(DEFAULT_CHARSET));
156         } else if (byte[].class.equals(valueClass)) {
157             dest.writeBlob((byte[]) mValue);
158         } else {
159             dest.writeValue(mValue);
160         }
161     }
162 
163     /**
164      * @return Property id of CarPropertyValue
165      */
getPropertyId()166     public int getPropertyId() {
167         return mPropertyId;
168     }
169 
170     /**
171      * @return Area id of CarPropertyValue
172      */
getAreaId()173     public int getAreaId() {
174         return mAreaId;
175     }
176 
177     /**
178      * @return Status of CarPropertyValue
179      */
getStatus()180     public @PropertyStatus int getStatus() {
181         return mStatus;
182     }
183 
184     /**
185      * @return Timestamp of CarPropertyValue
186      */
getTimestamp()187     public long getTimestamp() {
188         return mTimestamp;
189     }
190 
191     /**
192      * @return Value of CarPropertyValue
193      */
194     @NonNull
getValue()195     public T getValue() {
196         return mValue;
197     }
198 
199     /** @hide */
200     @Override
toString()201     public String toString() {
202         return "CarPropertyValue{" +
203                 "mPropertyId=0x" + toHexString(mPropertyId) +
204                 ", mAreaId=0x" + toHexString(mAreaId) +
205                 ", mStatus=" + mStatus +
206                 ", mTimestamp=" + mTimestamp +
207                 ", mValue=" + mValue +
208                 '}';
209     }
210 }
211