Home | History | Annotate | Download | only in hal
      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 package com.android.car.hal;
     17 
     18 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_BOOLEAN;
     19 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT;
     20 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC2;
     21 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC3;
     22 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_FLOAT_VEC4;
     23 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32;
     24 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2;
     25 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC3;
     26 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4;
     27 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_STRING;
     28 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_BOOLEAN;
     29 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT;
     30 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2;
     31 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3;
     32 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4;
     33 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32;
     34 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2;
     35 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3;
     36 import static com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType.VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4;
     37 import static com.android.car.vehiclenetwork.VehiclePropValueUtil.getVectorValueType;
     38 import static java.lang.Integer.toHexString;
     39 
     40 import android.car.VehicleZoneUtil;
     41 import android.car.VehicleAreaType;
     42 import android.car.hardware.CarPropertyConfig;
     43 import android.car.hardware.CarPropertyValue;
     44 
     45 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropConfig;
     46 import com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
     47 
     48 import java.util.List;
     49 
     50 /**
     51  * Utility functions to work with {@link CarPropertyConfig} and {@link CarPropertyValue}
     52  */
     53 /*package*/ final class CarPropertyUtils {
     54 
     55     /* Utility class has no public constructor */
     56     private CarPropertyUtils() {}
     57 
     58     /** Converts {@link VehiclePropValue} to {@link CarPropertyValue} */
     59     static CarPropertyValue<?> toCarPropertyValue(
     60             VehiclePropValue halValue, int propertyId) {
     61         Class<?> clazz = getJavaClass(halValue.getValueType());
     62         int areaId = halValue.getZone();
     63         if (Boolean.class == clazz) {
     64             return new CarPropertyValue<>(propertyId, areaId, halValue.getInt32Values(0) == 1);
     65         } else if (String.class == clazz) {
     66             return new CarPropertyValue<>(propertyId, areaId, halValue.getStringValue());
     67         } else if (Long.class == clazz) {
     68             return new CarPropertyValue<>(propertyId, areaId, halValue.getInt64Value());
     69         } else /* All list properties */ {
     70             Object[] values = getRawValueList(clazz, halValue).toArray();
     71             return new CarPropertyValue<>(propertyId, areaId,
     72                     values.length == 1 ? values[0] : values);
     73         }
     74     }
     75 
     76     /** Converts {@link CarPropertyValue} to {@link VehiclePropValue} */
     77     static VehiclePropValue toVehiclePropValue(CarPropertyValue hvacProp, int halPropId) {
     78         VehiclePropValue.Builder builder = VehiclePropValue.newBuilder();
     79         builder.setProp(halPropId);
     80 
     81         if (hvacProp.getAreaId() != 0) {
     82             builder.setZone(hvacProp.getAreaId());
     83         }
     84 
     85         Object o = hvacProp.getValue();
     86 
     87         boolean hasArea = hvacProp.getAreaId() != 0;
     88         int vectorLength = (o instanceof Object[] ? ((Object[]) o).length : 0);
     89         int halType;
     90         if (o instanceof Boolean) {
     91             halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_BOOLEAN : VEHICLE_VALUE_TYPE_BOOLEAN;
     92             builder.addInt32Values(((Boolean )o) ? 1 : 0);
     93         } else if (o instanceof Integer) {
     94             halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_INT32;
     95             builder.addInt32Values((Integer) o);
     96         } else if (o instanceof Float) {
     97             halType = hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_FLOAT;
     98             builder.addFloatValues((Float) o);
     99         } else if (o instanceof Integer[]) {
    100             halType = getVectorValueType(
    101                     hasArea ? VEHICLE_VALUE_TYPE_ZONED_INT32 : VEHICLE_VALUE_TYPE_ZONED_INT32,
    102                     vectorLength);
    103             for (Integer i : (Integer[]) o) {
    104                 builder.addInt32Values(i);
    105             }
    106         } else if (o instanceof Float[]) {
    107             halType = getVectorValueType(
    108                     hasArea ? VEHICLE_VALUE_TYPE_ZONED_FLOAT : VEHICLE_VALUE_TYPE_ZONED_FLOAT,
    109                     vectorLength);
    110             for (Float f : (Float[]) o) {
    111                 builder.addFloatValues(f);
    112             }
    113         } else if (o instanceof String) {
    114             halType = VEHICLE_VALUE_TYPE_STRING;
    115             builder.setStringValue((String) o);
    116         } else {
    117             throw new IllegalArgumentException("Unexpected type in: " + hvacProp);
    118         }
    119         builder.setValueType(halType);
    120         return builder.build();
    121     }
    122 
    123     /**
    124      * Converts {@link VehiclePropConfig} to {@link CarPropertyConfig}.
    125      */
    126     static CarPropertyConfig<?> toCarPropertyConfig(VehiclePropConfig p, int propertyId) {
    127         int[] areas = VehicleZoneUtil.listAllZones(p.getZones());
    128 
    129         // TODO: handle other vehicle area types.
    130         int areaType = areas.length == 0
    131                 ? VehicleAreaType.VEHICLE_AREA_TYPE_NONE : VehicleAreaType.VEHICLE_AREA_TYPE_ZONE;
    132 
    133         Class<?> clazz = getJavaClass(p.getValueType());
    134         if (clazz == Boolean.class) {
    135             return CarPropertyConfig
    136                     .newBuilder(clazz, propertyId, areaType, /* capacity */ 1)
    137                     .addAreas(areas)
    138                     .build();
    139         } else {
    140             List mins;
    141             List maxs;
    142             if (classMatched(Integer.class, clazz)) {
    143                 mins = p.getInt32MinsList();
    144                 maxs = p.getInt32MaxsList();
    145             } else if (classMatched(Float.class, clazz)) {
    146                 mins = p.getFloatMinsList();
    147                 maxs = p.getFloatMaxsList();
    148             } else {
    149                 throw new IllegalArgumentException("Unexpected type: " + clazz);
    150             }
    151             CarPropertyConfig.Builder builder = CarPropertyConfig
    152                     .newBuilder(clazz, propertyId, areaType, /* capacity */ mins.size());
    153             for (int i = 0; i < mins.size(); i++) {
    154                 int areaId = areas.length == 0 ? 0 : areas[i];
    155                 builder.addAreaConfig(areaId, mins.get(i), maxs.get(i));
    156             }
    157             return builder.build();
    158         }
    159     }
    160 
    161     private static Class<?> getJavaClass(int halType) {
    162         switch (halType) {
    163             case VEHICLE_VALUE_TYPE_BOOLEAN:
    164             case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN:
    165                 return Boolean.class;
    166             case VEHICLE_VALUE_TYPE_FLOAT:
    167             case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
    168                 return Float.class;
    169             case VEHICLE_VALUE_TYPE_INT32:
    170             case VEHICLE_VALUE_TYPE_ZONED_INT32:
    171                 return Integer.class;
    172             case VEHICLE_VALUE_TYPE_INT32_VEC2:
    173             case VEHICLE_VALUE_TYPE_INT32_VEC3:
    174             case VEHICLE_VALUE_TYPE_INT32_VEC4:
    175             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
    176             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
    177             case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4:
    178                 return Integer[].class;
    179             case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
    180             case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
    181             case VEHICLE_VALUE_TYPE_FLOAT_VEC4:
    182             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
    183             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
    184             case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:
    185                 return Float[].class;
    186             case VEHICLE_VALUE_TYPE_STRING:
    187                 return String.class;
    188             default:
    189                 throw new IllegalArgumentException("Unexpected type: " + toHexString(halType));
    190         }
    191     }
    192 
    193     private static List getRawValueList(Class<?> clazz, VehiclePropValue vehiclePropValue) {
    194         if (classMatched(Float.class, clazz)) {
    195             return vehiclePropValue.getFloatValuesList();
    196         } else if (classMatched(Integer.class, clazz)) {
    197             return vehiclePropValue.getInt32ValuesList();
    198         } else {
    199             throw new IllegalArgumentException("Unexpected type: " + clazz);
    200         }
    201     }
    202 
    203     private static boolean classMatched(Class<?> class1, Class<?> class2) {
    204         return class1 == class2 || class1.getComponentType() == class2;
    205     }
    206 }
    207