• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 com.android.car.hal;
18 
19 import android.car.VehicleAreaType;
20 import android.car.hardware.CarPropertyConfig;
21 import android.car.hardware.property.AreaIdConfig;
22 import android.hardware.automotive.vehicle.VehicleArea;
23 import android.hardware.automotive.vehicle.VehicleProperty;
24 import android.hardware.automotive.vehicle.VehiclePropertyChangeMode;
25 import android.hardware.automotive.vehicle.VehiclePropertyType;
26 
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Set;
30 
31 /**
32  * HalPropConfig represents a vehicle property config.
33  */
34 public abstract class HalPropConfig {
35     private static final Set<Integer> CONFIG_ARRAY_DEFINES_SUPPORTED_ENUM_VALUES =
36             Set.of(
37                     VehicleProperty.GEAR_SELECTION,
38                     VehicleProperty.CURRENT_GEAR,
39                     VehicleProperty.DISTANCE_DISPLAY_UNITS,
40                     VehicleProperty.EV_BATTERY_DISPLAY_UNITS,
41                     VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS,
42                     VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS,
43                     VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS,
44                     VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS);
45     /**
46      * Get the property ID.
47      */
getPropId()48     public abstract int getPropId();
49 
50     /**
51      * Get the access mode.
52      */
getAccess()53     public abstract int getAccess();
54 
55     /**
56      * Get the change mode.
57      */
getChangeMode()58     public abstract int getChangeMode();
59 
60     /**
61      * Get the area configs.
62      */
getAreaConfigs()63     public abstract HalAreaConfig[] getAreaConfigs();
64 
65     /**
66      * Get the config array.
67      */
getConfigArray()68     public abstract int[] getConfigArray();
69 
70     /**
71      * Get the config string.
72      */
getConfigString()73     public abstract String getConfigString();
74 
75     /**
76      * Get the min sample rate.
77      */
getMinSampleRate()78     public abstract float getMinSampleRate();
79 
80     /**
81      * Get the max sample rate.
82      */
getMaxSampleRate()83     public abstract float getMaxSampleRate();
84 
85     /**
86      * Converts to AIDL or HIDL VehiclePropConfig.
87      */
toVehiclePropConfig()88     public abstract Object toVehiclePropConfig();
89 
90     /**
91      * Converts {@link HalPropConfig} to {@link CarPropertyConfig}.
92      *
93      * @param mgrPropertyId The Property ID used by Car Property Manager, different from the
94      *                      property ID used by VHAL.
95      */
toCarPropertyConfig(int mgrPropertyId)96     public CarPropertyConfig<?> toCarPropertyConfig(int mgrPropertyId) {
97         int propId = getPropId();
98         int areaType = getVehicleAreaType(propId & VehicleArea.MASK);
99         Class<?> clazz = CarPropertyUtils.getJavaClass(propId & VehiclePropertyType.MASK);
100         CarPropertyConfig.Builder carPropertyConfigBuilder = CarPropertyConfig.newBuilder(clazz,
101                 mgrPropertyId, areaType).setAccess(getAccess()).setChangeMode(
102                 getChangeMode()).setConfigString(getConfigString());
103 
104         float maxSampleRate = 0f;
105         float minSampleRate = 0f;
106         if (getChangeMode() == CarPropertyConfig.VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS) {
107             maxSampleRate = getMaxSampleRate();
108             minSampleRate = getMinSampleRate();
109         }
110         carPropertyConfigBuilder.setMinSampleRate(minSampleRate).setMaxSampleRate(maxSampleRate);
111 
112         int[] configIntArray = getConfigArray();
113         ArrayList<Integer> configArray = new ArrayList<>(configIntArray.length);
114         long[] supportedEnumValues = null;
115         boolean shouldConfigArrayDefineSupportedEnumValues =
116                 CONFIG_ARRAY_DEFINES_SUPPORTED_ENUM_VALUES.contains(propId);
117         if (shouldConfigArrayDefineSupportedEnumValues) {
118             supportedEnumValues = new long[configIntArray.length];
119         }
120         for (int i = 0; i < configIntArray.length; i++) {
121             configArray.add(configIntArray[i]);
122             if (shouldConfigArrayDefineSupportedEnumValues) {
123                 supportedEnumValues[i] = (long) configIntArray[i];
124             }
125         }
126         carPropertyConfigBuilder.setConfigArray(configArray);
127 
128         HalAreaConfig[] halAreaConfigs = getAreaConfigs();
129         if (halAreaConfigs.length == 0) {
130             carPropertyConfigBuilder.addAreaIdConfig(generateAreaIdConfig(clazz, /*areaId=*/0,
131                     /*minInt32Value=*/0, /*maxInt32Value=*/0,
132                     /*minFloatValue=*/0, /*maxFloatValue=*/0,
133                     /*minInt64Value=*/0, /*maxInt64Value=*/0,
134                     supportedEnumValues));
135         } else {
136             for (HalAreaConfig halAreaConfig : halAreaConfigs) {
137                 if (!shouldConfigArrayDefineSupportedEnumValues) {
138                     supportedEnumValues = halAreaConfig.getSupportedEnumValues();
139                 }
140                 carPropertyConfigBuilder.addAreaIdConfig(
141                         generateAreaIdConfig(clazz, halAreaConfig.getAreaId(),
142                                 halAreaConfig.getMinInt32Value(), halAreaConfig.getMaxInt32Value(),
143                                 halAreaConfig.getMinFloatValue(), halAreaConfig.getMaxFloatValue(),
144                                 halAreaConfig.getMinInt64Value(), halAreaConfig.getMaxInt64Value(),
145                                 supportedEnumValues));
146             }
147         }
148         return carPropertyConfigBuilder.build();
149     }
150 
generateAreaIdConfig(Class<?> clazz, int areaId, int minInt32Value, int maxInt32Value, float minFloatValue, float maxFloatValue, long minInt64Value, long maxInt64Value, long[] supportedEnumValues)151     private AreaIdConfig generateAreaIdConfig(Class<?> clazz, int areaId, int minInt32Value,
152             int maxInt32Value, float minFloatValue, float maxFloatValue, long minInt64Value,
153             long maxInt64Value, long[] supportedEnumValues) {
154         AreaIdConfig.Builder areaIdConfigBuilder = new AreaIdConfig.Builder(areaId);
155         if (classMatched(Integer.class, clazz)) {
156             if ((minInt32Value != 0 || maxInt32Value != 0)) {
157                 areaIdConfigBuilder.setMinValue(minInt32Value).setMaxValue(maxInt32Value);
158             }
159             if (getChangeMode() == VehiclePropertyChangeMode.ON_CHANGE) {
160                 if (supportedEnumValues != null && supportedEnumValues.length > 0) {
161                     List<Integer> managerSupportedEnumValues = new ArrayList<>(
162                             supportedEnumValues.length);
163                     for (int i = 0; i < supportedEnumValues.length; i++) {
164                         managerSupportedEnumValues.add((int) supportedEnumValues[i]);
165                     }
166                     areaIdConfigBuilder.setSupportedEnumValues(managerSupportedEnumValues);
167                 } else if (PropertyHalServiceIds.getAllPossibleSupportedEnumValues(getPropId())
168                         != null) {
169                     areaIdConfigBuilder.setSupportedEnumValues(new ArrayList(
170                             PropertyHalServiceIds.getAllPossibleSupportedEnumValues(getPropId())));
171                 }
172             }
173         } else if (classMatched(Float.class, clazz) && (minFloatValue != 0 || maxFloatValue != 0)) {
174             areaIdConfigBuilder.setMinValue(minFloatValue).setMaxValue(maxFloatValue);
175         } else if (classMatched(Long.class, clazz) && (minInt64Value != 0 || maxInt64Value != 0)) {
176             areaIdConfigBuilder.setMinValue(minInt64Value).setMaxValue(maxInt64Value);
177         }
178         return areaIdConfigBuilder.build();
179     }
180 
getVehicleAreaType(int halArea)181     private static @VehicleAreaType.VehicleAreaTypeValue int getVehicleAreaType(int halArea) {
182         switch (halArea) {
183             case VehicleArea.GLOBAL:
184                 return VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
185             case VehicleArea.SEAT:
186                 return VehicleAreaType.VEHICLE_AREA_TYPE_SEAT;
187             case VehicleArea.DOOR:
188                 return VehicleAreaType.VEHICLE_AREA_TYPE_DOOR;
189             case VehicleArea.WINDOW:
190                 return VehicleAreaType.VEHICLE_AREA_TYPE_WINDOW;
191             case VehicleArea.MIRROR:
192                 return VehicleAreaType.VEHICLE_AREA_TYPE_MIRROR;
193             case VehicleArea.WHEEL:
194                 return VehicleAreaType.VEHICLE_AREA_TYPE_WHEEL;
195             default:
196                 throw new RuntimeException("Unsupported area type " + halArea);
197         }
198     }
199 
classMatched(Class<?> class1, Class<?> class2)200     private static boolean classMatched(Class<?> class1, Class<?> class2) {
201         return class1 == class2 || class1.getComponentType() == class2;
202     }
203 }
204