1 /*
2  * Copyright (C) 2015 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 package com.android.car.vehiclenetwork;
17 
18 import com.google.protobuf.ByteString;
19 
20 import com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
21 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
22 
23 import java.util.Arrays;
24 import java.util.List;
25 
26 /**
27  * Utility class to help creating VehiclePropValue.
28  */
29 public final class VehiclePropValueUtil {
30 
31     /** To prevent creating of utility class */
VehiclePropValueUtil()32     private VehiclePropValueUtil() {}
33 
createIntValue(int property, int value, long timestamp)34     public static VehiclePropValue createIntValue(int property, int value, long timestamp) {
35         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_INT32, timestamp).
36                 addInt32Values(value).
37                 build();
38     }
39 
createIntVectorValue(int property, int[] values, long timestamp)40     public static VehiclePropValue createIntVectorValue(int property, int[] values,
41             long timestamp) {
42         VehiclePropValue.Builder builder = createBuilder(property,
43                 getVectorValueType(VehicleValueType.VEHICLE_VALUE_TYPE_INT32, values.length),
44                 timestamp);
45         for (int v : values) {
46             builder.addInt32Values(v);
47         }
48         return builder.build();
49     }
50 
createFloatValue(int property, float value, long timestamp)51     public static VehiclePropValue createFloatValue(int property, float value, long timestamp) {
52         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT, timestamp).
53                 addFloatValues(value).
54                 build();
55     }
56 
createFloatVectorValue(int property, float[] values, long timestamp)57     public static VehiclePropValue createFloatVectorValue(int property, float[] values,
58             long timestamp) {
59         VehiclePropValue.Builder builder = createBuilder(property,
60                 getVectorValueType(VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT, values.length),
61                 timestamp);
62         for (float v : values) {
63             builder.addFloatValues(v);
64         }
65         return builder.build();
66     }
67 
createLongValue(int property, long value, long timestamp)68     public static VehiclePropValue createLongValue(int property, long value, long timestamp) {
69         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_INT64, timestamp).
70                 setInt64Value(value).
71                 build();
72     }
73 
createStringValue(int property, String value, long timestamp)74     public static VehiclePropValue createStringValue(int property, String value, long timestamp) {
75         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_STRING, timestamp).
76                 setStringValue(value).
77                 build();
78     }
79 
createBooleanValue(int property, boolean value, long timestamp)80     public static VehiclePropValue createBooleanValue(int property, boolean value, long timestamp) {
81         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN, timestamp).
82                 addInt32Values(value ? 1 : 0).
83                 build();
84     }
85 
createBytesValue(int property, byte[] value, long timestamp)86     public static VehiclePropValue createBytesValue(int property, byte[] value, long timestamp) {
87         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_BYTES, timestamp).
88                 setBytesValue(ByteString.copyFrom(value)).
89                 build();
90     }
91 
createZonedIntValue(int property, int zone, int value, long timestamp)92     public static VehiclePropValue createZonedIntValue(int property, int zone, int value,
93             long timestamp) {
94         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32, timestamp).
95                 setZone(zone).
96                 addInt32Values(value).
97                 build();
98     }
99 
createZonedIntVectorValue(int property, int zone, int[] values, long timestamp)100     public static VehiclePropValue createZonedIntVectorValue(int property, int zone, int[] values,
101             long timestamp) {
102         int valueType = getVectorValueType(
103                 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32, values.length);
104         VehiclePropValue.Builder builder = createBuilder(property, valueType, timestamp).
105                 setZone(zone);
106         for (int value : values) {
107             builder.addInt32Values(value);
108         }
109         return builder.build();
110     }
111 
createZonedFloatVectorValue(int property, int zone, float[] values, long timestamp)112     public static VehiclePropValue createZonedFloatVectorValue(int property, int zone,
113             float[] values, long timestamp) {
114         int valueType = getVectorValueType(
115                 VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT, values.length);
116         VehiclePropValue.Builder builder =  createBuilder(property, valueType, timestamp).
117                 setZone(zone);
118         for (float value : values) {
119             builder.addFloatValues(value);
120         }
121         return builder.build();
122     }
123 
124 
createZonedBooleanValue(int property, int zone, boolean value, long timestamp)125     public static VehiclePropValue createZonedBooleanValue(int property, int zone, boolean value,
126             long timestamp) {
127         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN,timestamp).
128                 setZone(zone).
129                 addInt32Values(value ? 1 : 0).
130                 build();
131     }
132 
createZonedFloatValue(int property, int zone, float value, long timestamp)133     public static VehiclePropValue createZonedFloatValue(int property, int zone, float value,
134             long timestamp) {
135         return createBuilder(property, VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT,timestamp).
136                 setZone(zone).
137                 addFloatValues(value).
138                 build();
139     }
140 
createDummyValue(int property, int valueType)141     public static VehiclePropValue createDummyValue(int property, int valueType) {
142         switch (valueType) {
143             case VehicleValueType.VEHICLE_VALUE_TYPE_STRING: {
144                 return createStringValue(property, "dummy", 0);
145             }
146             case VehicleValueType.VEHICLE_VALUE_TYPE_BYTES: {
147                 return createBytesValue(property, new byte[1], 0);
148             }
149             case VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN: {
150                 return createBooleanValue(property, false, 0);
151             }
152             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32: {
153                 return createZonedIntValue(property, 0, 0, 0);
154             }
155             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT: {
156                 return createZonedFloatValue(property, 0, 0, 0);
157             }
158             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN: {
159                 return createZonedBooleanValue(property, 0, false, 0);
160             }
161             case VehicleValueType.VEHICLE_VALUE_TYPE_INT64: {
162                 return createLongValue(property, 0, 0);
163             }
164             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT: {
165                 return createFloatValue(property, 0, 0);
166             }
167             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2:
168             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3:
169             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4:
170             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
171             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
172             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:{
173                 return createFloatVectorValue(property, new float[getVectorLength(valueType)], 0);
174             }
175             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32: {
176                 return createIntValue(property, 0, 0);
177             }
178             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2:
179             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3:
180             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4:
181             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
182             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
183             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
184                 return createIntVectorValue(property, new int[getVectorLength(valueType)], 0);
185             }
186 
187         }
188         return null;
189     }
190 
createBuilder(int property, int valueType, long timestamp)191     public static VehiclePropValue.Builder createBuilder(int property, int valueType,
192             long timestamp) {
193         return VehiclePropValue.newBuilder().
194                 setProp(property).
195                 setValueType(valueType).
196                 setTimestamp(timestamp);
197     }
198 
getVectorLength(int vehicleValueType)199     public static int getVectorLength(int vehicleValueType) {
200         switch (vehicleValueType) {
201             case VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN:
202             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32:
203             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT:
204             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32:
205             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
206             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT:
207                 return 1;
208             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2:
209             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2:
210             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
211             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
212                 return 2;
213             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3:
214             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3:
215             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
216             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
217                 return 3;
218             case VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4:
219             case VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4:
220             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
221             case VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
222                 return 4;
223             default:
224                 throw new IllegalArgumentException("Unknown value type: " + vehicleValueType);
225         }
226     }
227 
isCustomProperty(int property)228     public static boolean isCustomProperty(int property) {
229         return property >= VehicleNetworkConsts.VEHICLE_PROPERTY_CUSTOM_START &&
230                 property <= VehicleNetworkConsts.VEHICLE_PROPERTY_CUSTOM_END;
231     }
232 
233     /** Converts {@link VehiclePropValue} to string just for debug purpose. */
toString(VehiclePropValue value)234     public static String toString(VehiclePropValue value) {
235         if (value == null) {
236             return String.valueOf(null);
237         }
238         return new StringBuilder()
239                 .append("prop: " + value.getProp() + "\n")
240                 .append("valueType: " + value.getValueType() + "\n")
241                 .append("timestamp: " + value.getTimestamp() + "\n")
242                 .append("int32Values: " + Arrays.toString(toIntArray(value.getInt32ValuesList()))
243                         + "\n")
244                 .append("int64Value: " + value.getInt64Value() + "\n")
245                 .append("floatValues: " + Arrays.toString(toFloatArray(value.getFloatValuesList()))
246                         + "\n")
247                 .append("stringValue: " + value.getStringValue() + "\n")
248                 .append("byteValue: " + Arrays.toString(value.getBytesValue().toByteArray()) + "\n")
249                 .append("zone: {" + value.getZone() + "}")
250                 .toString();
251     }
252 
toIntArray(List<Integer> collection)253     public static int[] toIntArray(List<Integer> collection) {
254         int[] array = new int[collection.size()];
255         int i = 0;
256         for (int value : collection) {
257             array[i++] = value;
258         }
259         return array;
260     }
261 
toFloatArray(List<Float> collection)262     public static float[] toFloatArray(List<Float> collection) {
263         float[] array = new float[collection.size()];
264         int i = 0;
265         for (float value : collection) {
266             array[i++] = value;
267         }
268         return array;
269     }
270 
getVectorValueType(int vehicleValueType, int length)271     public static int getVectorValueType(int vehicleValueType, int length) {
272         return vehicleValueType + length - 1;
273     }
274 }
275