blob: c584f31f3d2b71f1b1bd933632210a101867ca03 [file] [log] [blame]
Steve Paikfb5f6232016-03-28 10:31:25 -07001/*
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 */
16package com.android.car.hal;
17
18import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN;
Pavel Maltsev1bfbaef2016-07-25 14:23:51 -070019import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_BYTES;
Steve Paikfb5f6232016-03-28 10:31:25 -070020import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT;
21import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2;
22import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3;
23import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4;
24import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32;
25import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2;
26import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3;
27import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4;
28import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_STRING;
29import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN;
30import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT;
31import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2;
32import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3;
33import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4;
34import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32;
35import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2;
36import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3;
37import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4;
Vitalii Tomkiv5f537ee2016-10-11 14:26:44 -070038import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_NONE;
39import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_ZONE;
40import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_SEAT;
41import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_DOOR;
42import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_WINDOW;
43import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleZoneType.VEHICLE_ZONE_TYPE_MIRROR;
Steve Paikfb5f6232016-03-28 10:31:25 -070044import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorValueType;
45import static java.lang.Integer.toHexString;
46
Steve Paikfb5f6232016-03-28 10:31:25 -070047import android.car.VehicleAreaType;
Pavel Maltsev1bfbaef2016-07-25 14:23:51 -070048import android.car.VehicleZoneUtil;
Steve Paikfb5f6232016-03-28 10:31:25 -070049import android.car.hardware.CarPropertyConfig;
50import android.car.hardware.CarPropertyValue;
51
Pavel Maltsev1bfbaef2016-07-25 14:23:51 -070052import com.google.protobuf.ByteString;
53
Vitalii Tomkiv5f537ee2016-10-11 14:26:44 -070054import com.android.car.vehiclenetwork.VehicleNetworkConsts;
Steve Paikfb5f6232016-03-28 10:31:25 -070055import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
56import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
57
58import java.util.List;
59
60/**
61 * Utility functions to work with {@link CarPropertyConfig} and {@link CarPropertyValue}
62 */
63/*package*/ final class CarPropertyUtils {
64
65 /* Utility class has no public constructor */
66 private CarPropertyUtils() {}
67
68 /** Converts {@link VehiclePropValue} to {@link CarPropertyValue} */
69 static CarPropertyValue<?> toCarPropertyValue(
70 VehiclePropValue halValue, int propertyId) {
71 Class<?> clazz = getJavaClass(halValue.getValueType());
72 int areaId = halValue.getZone();
73 if (Boolean.class == clazz) {
74 return new CarPropertyValue<>(propertyId, areaId, halValue.getInt32Values(0) == 1);
75 } else if (String.class == clazz) {
76 return new CarPropertyValue<>(propertyId, areaId, halValue.getStringValue());
77 } else if (Long.class == clazz) {
78 return new CarPropertyValue<>(propertyId, areaId, halValue.getInt64Value());
Pavel Maltsev437ab412016-08-15 15:41:06 -070079 } else if (byte[].class == clazz) {
Pavel Maltsev1bfbaef2016-07-25 14:23:51 -070080 byte[] halData = halValue.getBytesValue().toByteArray();
Pavel Maltsev437ab412016-08-15 15:41:06 -070081 return new CarPropertyValue<>(propertyId, areaId, halData);
Steve Paikfb5f6232016-03-28 10:31:25 -070082 } else /* All list properties */ {
83 Object[] values = getRawValueList(clazz, halValue).toArray();
84 return new CarPropertyValue<>(propertyId, areaId,
85 values.length == 1 ? values[0] : values);
86 }
87 }
88
89 /** Converts {@link CarPropertyValue} to {@link VehiclePropValue} */
90 static VehiclePropValue toVehiclePropValue(CarPropertyValue hvacProp, int halPropId) {
91 VehiclePropValue.Builder builder = VehiclePropValue.newBuilder();
92 builder.setProp(halPropId);
93
94 if (hvacProp.getAreaId() != 0) {
95 builder.setZone(hvacProp.getAreaId());
96 }
97
98 Object o = hvacProp.getValue();
99
100 boolean hasArea = hvacProp.getAreaId() != 0;
101 int vectorLength = (o instanceof Object[] ? ((Object[]) o).length : 0);
102 int halType;
103 if (o instanceof Boolean) {
104 halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_BOOLEAN : VEHICLE_VALUE_TYPE_BOOLEAN;
105 builder.addInt32Values(((Boolean )o) ? 1 : 0);
106 } else if (o instanceof Integer) {
107 halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_INT32;
108 builder.addInt32Values((Integer) o);
109 } else if (o instanceof Float) {
110 halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_FLOAT;
111 builder.addFloatValues((Float) o);
112 } else if (o instanceof Integer[]) {
113 halType = getVectorValueType(
114 hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_ZONED_INT32,
115 vectorLength);
116 for (Integer i : (Integer[]) o) {
117 builder.addInt32Values(i);
118 }
119 } else if (o instanceof Float[]) {
120 halType = getVectorValueType(
121 hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_ZONED_FLOAT,
122 vectorLength);
123 for (Float f : (Float[]) o) {
124 builder.addFloatValues(f);
125 }
126 } else if (o instanceof String) {
127 halType = VEHICLE_VALUE_TYPE_STRING;
128 builder.setStringValue((String) o);
Pavel Maltsev437ab412016-08-15 15:41:06 -0700129 } else if (o instanceof byte[]) {
Keun-young Parkf9215202016-10-10 12:34:08 -0700130 halType = VEHICLE_VALUE_TYPE_BYTES; // We don't have zoned type in vehicle.h
Pavel Maltsev437ab412016-08-15 15:41:06 -0700131 builder.setBytesValue(ByteString.copyFrom((byte[]) o));
Steve Paikfb5f6232016-03-28 10:31:25 -0700132 } else {
133 throw new IllegalArgumentException("Unexpected type in: " + hvacProp);
134 }
135 builder.setValueType(halType);
136 return builder.build();
137 }
138
139 /**
140 * Converts {@link VehiclePropConfig} to {@link CarPropertyConfig}.
141 */
142 static CarPropertyConfig<?> toCarPropertyConfig(VehiclePropConfig p, int propertyId) {
143 int[] areas = VehicleZoneUtil.listAllZones(p.getZones());
144
Keun-young Park1a0d6542016-10-14 12:38:43 -0700145 int areaType = getVehicleAreaType(VehicleNetworkConsts.getVehicleZoneType(p.getProp()));
Steve Paikfb5f6232016-03-28 10:31:25 -0700146
147 Class<?> clazz = getJavaClass(p.getValueType());
Pavel Maltsev437ab412016-08-15 15:41:06 -0700148 if (clazz == Boolean.class || clazz == byte[].class || clazz == String.class) {
Steve Paikfb5f6232016-03-28 10:31:25 -0700149 return CarPropertyConfig
150 .newBuilder(clazz, propertyId, areaType, /* capacity */ 1)
151 .addAreas(areas)
152 .build();
153 } else {
154 List mins;
155 List maxs;
156 if (classMatched(Integer.class, clazz)) {
157 mins = p.getInt32MinsList();
158 maxs = p.getInt32MaxsList();
159 } else if (classMatched(Float.class, clazz)) {
160 mins = p.getFloatMinsList();
161 maxs = p.getFloatMaxsList();
162 } else {
163 throw new IllegalArgumentException("Unexpected type: " + clazz);
164 }
165 CarPropertyConfig.Builder builder = CarPropertyConfig
166 .newBuilder(clazz, propertyId, areaType, /* capacity */ mins.size());
167 for (int i = 0; i < mins.size(); i++) {
168 int areaId = areas.length == 0 ? 0 : areas[i];
169 builder.addAreaConfig(areaId, mins.get(i), maxs.get(i));
170 }
171 return builder.build();
172 }
173 }
174
Vitalii Tomkiv5f537ee2016-10-11 14:26:44 -0700175 private static @VehicleAreaType.VehicleAreaTypeValue int getVehicleAreaType(int zoneType) {
176 switch (zoneType) {
177 case VEHICLE_ZONE_TYPE_NONE:
178 return VehicleAreaType.VEHICLE_AREA_TYPE_NONE;
179 case VEHICLE_ZONE_TYPE_ZONE:
180 return VehicleAreaType.VEHICLE_AREA_TYPE_ZONE;
181 case VEHICLE_ZONE_TYPE_SEAT:
182 return VehicleAreaType.VEHICLE_AREA_TYPE_SEAT;
183 case VEHICLE_ZONE_TYPE_DOOR:
184 return VehicleAreaType.VEHICLE_AREA_TYPE_DOOR;
185 case VEHICLE_ZONE_TYPE_WINDOW:
186 return VehicleAreaType.VEHICLE_AREA_TYPE_WINDOW;
187 case VEHICLE_ZONE_TYPE_MIRROR:
188 return VehicleAreaType.VEHICLE_AREA_TYPE_MIRROR;
189 default:
190 throw new RuntimeException("Unsupported zone type " + zoneType);
191 }
192 }
193
Steve Paikfb5f6232016-03-28 10:31:25 -0700194 private static Class<?> getJavaClass(int halType) {
195 switch (halType) {
196 case VEHICLE_VALUE_TYPE_BOOLEAN:
197 case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
198 return Boolean.class;
199 case VEHICLE_VALUE_TYPE_FLOAT:
200 case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
201 return Float.class;
202 case VEHICLE_VALUE_TYPE_INT32:
203 case VEHICLE_VALUE_TYPE_ZONED_INT32:
204 return Integer.class;
205 case VEHICLE_VALUE_TYPE_INT32_VEC2:
206 case VEHICLE_VALUE_TYPE_INT32_VEC3:
207 case VEHICLE_VALUE_TYPE_INT32_VEC4:
208 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
209 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
210 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
211 return Integer[].class;
212 case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
213 case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
214 case VEHICLE_VALUE_TYPE_FLOAT_VEC4:
215 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
216 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
217 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
218 return Float[].class;
219 case VEHICLE_VALUE_TYPE_STRING:
220 return String.class;
Pavel Maltsev1bfbaef2016-07-25 14:23:51 -0700221 case VEHICLE_VALUE_TYPE_BYTES:
Pavel Maltsev437ab412016-08-15 15:41:06 -0700222 return byte[].class;
Steve Paikfb5f6232016-03-28 10:31:25 -0700223 default:
224 throw new IllegalArgumentException("Unexpected type: " + toHexString(halType));
225 }
226 }
227
228 private static List getRawValueList(Class<?> clazz, VehiclePropValue vehiclePropValue) {
229 if (classMatched(Float.class, clazz)) {
230 return vehiclePropValue.getFloatValuesList();
231 } else if (classMatched(Integer.class, clazz)) {
232 return vehiclePropValue.getInt32ValuesList();
233 } else {
234 throw new IllegalArgumentException("Unexpected type: " + clazz);
235 }
236 }
237
238 private static boolean classMatched(Class<?> class1, Class<?> class2) {
239 return class1 == class2 || class1.getComponentType() == class2;
240 }
241}