1fb5f6232486612413b129a2100bac720589dee0dSteve Paik/*
2fb5f6232486612413b129a2100bac720589dee0dSteve Paik * Copyright (C) 2016 The Android Open Source Project
3fb5f6232486612413b129a2100bac720589dee0dSteve Paik *
4fb5f6232486612413b129a2100bac720589dee0dSteve Paik * Licensed under the Apache License, Version 2.0 (the "License");
5fb5f6232486612413b129a2100bac720589dee0dSteve Paik * you may not use this file except in compliance with the License.
6fb5f6232486612413b129a2100bac720589dee0dSteve Paik * You may obtain a copy of the License at
7fb5f6232486612413b129a2100bac720589dee0dSteve Paik *
8fb5f6232486612413b129a2100bac720589dee0dSteve Paik *      http://www.apache.org/licenses/LICENSE-2.0
9fb5f6232486612413b129a2100bac720589dee0dSteve Paik *
10fb5f6232486612413b129a2100bac720589dee0dSteve Paik * Unless required by applicable law or agreed to in writing, software
11fb5f6232486612413b129a2100bac720589dee0dSteve Paik * distributed under the License is distributed on an "AS IS" BASIS,
12fb5f6232486612413b129a2100bac720589dee0dSteve Paik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb5f6232486612413b129a2100bac720589dee0dSteve Paik * See the License for the specific language governing permissions and
14fb5f6232486612413b129a2100bac720589dee0dSteve Paik * limitations under the License.
15fb5f6232486612413b129a2100bac720589dee0dSteve Paik */
16fb5f6232486612413b129a2100bac720589dee0dSteve Paik
17fb5f6232486612413b129a2100bac720589dee0dSteve Paikpackage android.car.hardware;
18fb5f6232486612413b129a2100bac720589dee0dSteve Paik
19fb5f6232486612413b129a2100bac720589dee0dSteve Paikimport static java.lang.Integer.toHexString;
20fb5f6232486612413b129a2100bac720589dee0dSteve Paik
21fb5f6232486612413b129a2100bac720589dee0dSteve Paikimport android.annotation.SystemApi;
22fb5f6232486612413b129a2100bac720589dee0dSteve Paikimport android.os.Parcel;
23fb5f6232486612413b129a2100bac720589dee0dSteve Paikimport android.os.Parcelable;
24fb5f6232486612413b129a2100bac720589dee0dSteve Paik
25437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsevimport java.nio.charset.Charset;
26437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
27fb5f6232486612413b129a2100bac720589dee0dSteve Paik/**
28fb5f6232486612413b129a2100bac720589dee0dSteve Paik * Stores values broken down by area for a vehicle property.
29fb5f6232486612413b129a2100bac720589dee0dSteve Paik *
30fb5f6232486612413b129a2100bac720589dee0dSteve Paik * @param <T> refer to Parcel#writeValue(Object) to get a list of all supported types. The class
31fb5f6232486612413b129a2100bac720589dee0dSteve Paik * should be visible to framework as default class loader is being used here.
32fb5f6232486612413b129a2100bac720589dee0dSteve Paik *
33fb5f6232486612413b129a2100bac720589dee0dSteve Paik * @hide
34fb5f6232486612413b129a2100bac720589dee0dSteve Paik */
35fb5f6232486612413b129a2100bac720589dee0dSteve Paik@SystemApi
36fb5f6232486612413b129a2100bac720589dee0dSteve Paikpublic class CarPropertyValue<T> implements Parcelable {
37437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
38437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev    private final static Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
39437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
40fb5f6232486612413b129a2100bac720589dee0dSteve Paik    private final int mPropertyId;
41fb5f6232486612413b129a2100bac720589dee0dSteve Paik    private final int mAreaId;
42fb5f6232486612413b129a2100bac720589dee0dSteve Paik    private final T mValue;
43fb5f6232486612413b129a2100bac720589dee0dSteve Paik
44fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public CarPropertyValue(int propertyId, T value) {
45fb5f6232486612413b129a2100bac720589dee0dSteve Paik        this(propertyId, 0, value);
46fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
47fb5f6232486612413b129a2100bac720589dee0dSteve Paik
48fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public CarPropertyValue(int propertyId, int areaId, T value) {
49fb5f6232486612413b129a2100bac720589dee0dSteve Paik        mPropertyId = propertyId;
50fb5f6232486612413b129a2100bac720589dee0dSteve Paik        mAreaId = areaId;
51fb5f6232486612413b129a2100bac720589dee0dSteve Paik        mValue = value;
52fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
53fb5f6232486612413b129a2100bac720589dee0dSteve Paik
54fb5f6232486612413b129a2100bac720589dee0dSteve Paik    @SuppressWarnings("unchecked")
55fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public CarPropertyValue(Parcel in) {
56fb5f6232486612413b129a2100bac720589dee0dSteve Paik        mPropertyId = in.readInt();
57fb5f6232486612413b129a2100bac720589dee0dSteve Paik        mAreaId = in.readInt();
58437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        String valueClassName = in.readString();
59437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        Class<?> valueClass;
60437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        try {
61437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            valueClass = Class.forName(valueClassName);
62437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        } catch (ClassNotFoundException e) {
63437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            throw new IllegalArgumentException("Class not found: " + valueClassName);
64437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        }
65437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
66437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        if (String.class.equals(valueClass)) {
67437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            byte[] bytes = in.readBlob();
68437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            mValue = (T) new String(bytes, DEFAULT_CHARSET);
69437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        } else if (byte[].class.equals(valueClass)) {
70437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            mValue = (T) in.readBlob();
71437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        } else {
72437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            mValue = (T) in.readValue(valueClass.getClassLoader());
73437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        }
74fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
75fb5f6232486612413b129a2100bac720589dee0dSteve Paik
76fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public static final Creator<CarPropertyValue> CREATOR = new Creator<CarPropertyValue>() {
77fb5f6232486612413b129a2100bac720589dee0dSteve Paik        @Override
78fb5f6232486612413b129a2100bac720589dee0dSteve Paik        public CarPropertyValue createFromParcel(Parcel in) {
79fb5f6232486612413b129a2100bac720589dee0dSteve Paik            return new CarPropertyValue(in);
80fb5f6232486612413b129a2100bac720589dee0dSteve Paik        }
81fb5f6232486612413b129a2100bac720589dee0dSteve Paik
82fb5f6232486612413b129a2100bac720589dee0dSteve Paik        @Override
83fb5f6232486612413b129a2100bac720589dee0dSteve Paik        public CarPropertyValue[] newArray(int size) {
84fb5f6232486612413b129a2100bac720589dee0dSteve Paik            return new CarPropertyValue[size];
85fb5f6232486612413b129a2100bac720589dee0dSteve Paik        }
86fb5f6232486612413b129a2100bac720589dee0dSteve Paik    };
87fb5f6232486612413b129a2100bac720589dee0dSteve Paik
88fb5f6232486612413b129a2100bac720589dee0dSteve Paik    @Override
89fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public int describeContents() {
90fb5f6232486612413b129a2100bac720589dee0dSteve Paik        return 0;
91fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
92fb5f6232486612413b129a2100bac720589dee0dSteve Paik
93fb5f6232486612413b129a2100bac720589dee0dSteve Paik    @Override
94fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public void writeToParcel(Parcel dest, int flags) {
95fb5f6232486612413b129a2100bac720589dee0dSteve Paik        dest.writeInt(mPropertyId);
96fb5f6232486612413b129a2100bac720589dee0dSteve Paik        dest.writeInt(mAreaId);
97437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
98437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        Class<?> valueClass = mValue == null ? null : mValue.getClass();
99437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        dest.writeString(valueClass == null ? null : valueClass.getName());
100437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev
101437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        // Special handling for String and byte[] to mitigate transaction buffer limitations.
102437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        if (String.class.equals(valueClass)) {
103437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            dest.writeBlob(((String)mValue).getBytes(DEFAULT_CHARSET));
104437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        } else if (byte[].class.equals(valueClass)) {
105437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            dest.writeBlob((byte[]) mValue);
106437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        } else {
107437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev            dest.writeValue(mValue);
108437ab41da9003adc6ebe0ea639d42f32b0d0904cPavel Maltsev        }
109fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
110fb5f6232486612413b129a2100bac720589dee0dSteve Paik
111fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public int getPropertyId() {
112fb5f6232486612413b129a2100bac720589dee0dSteve Paik        return mPropertyId;
113fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
114fb5f6232486612413b129a2100bac720589dee0dSteve Paik
115fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public int getAreaId() {
116fb5f6232486612413b129a2100bac720589dee0dSteve Paik        return mAreaId;
117fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
118fb5f6232486612413b129a2100bac720589dee0dSteve Paik
119fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public T getValue() {
120fb5f6232486612413b129a2100bac720589dee0dSteve Paik        return mValue;
121fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
122fb5f6232486612413b129a2100bac720589dee0dSteve Paik
123fb5f6232486612413b129a2100bac720589dee0dSteve Paik    @Override
124fb5f6232486612413b129a2100bac720589dee0dSteve Paik    public String toString() {
125fb5f6232486612413b129a2100bac720589dee0dSteve Paik        return "CarPropertyValue{" +
126fb5f6232486612413b129a2100bac720589dee0dSteve Paik                "mPropertyId=0x" + toHexString(mPropertyId) +
127fb5f6232486612413b129a2100bac720589dee0dSteve Paik                ", mAreaId=0x" + toHexString(mAreaId) +
128fb5f6232486612413b129a2100bac720589dee0dSteve Paik                ", mValue=" + mValue +
129fb5f6232486612413b129a2100bac720589dee0dSteve Paik                '}';
130fb5f6232486612413b129a2100bac720589dee0dSteve Paik    }
131fb5f6232486612413b129a2100bac720589dee0dSteve Paik}
132