1 /* 2 * Copyright (C) 2022 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 android.car.hardware.property; 18 19 import static android.car.feature.Flags.FLAG_AREA_ID_CONFIG_ACCESS; 20 import static android.car.feature.Flags.FLAG_CAR_PROPERTY_SUPPORTED_VALUE; 21 import static android.car.feature.Flags.FLAG_VARIABLE_UPDATE_RATE; 22 23 import static com.android.car.internal.util.DebugUtils.toAreaIdString; 24 25 import android.annotation.FlaggedApi; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.annotation.SystemApi; 29 import android.car.hardware.CarPropertyConfig; 30 import android.os.Parcel; 31 import android.os.Parcelable; 32 33 import com.android.car.internal.property.RawPropertyValue; 34 35 import java.util.ArrayList; 36 import java.util.Collections; 37 import java.util.List; 38 39 /** 40 * Represents area ID specific configuration information for a vehicle property. 41 * 42 * @param <T> matches the type for the {@link android.car.hardware.CarPropertyConfig}. 43 */ 44 public final class AreaIdConfig<T> implements Parcelable { 45 @NonNull 46 public static final Parcelable.Creator<AreaIdConfig<Object>> CREATOR = getCreator(); 47 48 private final @CarPropertyConfig.VehiclePropertyAccessType int mAccess; 49 private final int mAreaId; 50 @Nullable private final T mMinValue; 51 @Nullable private final T mMaxValue; 52 private final List<T> mSupportedEnumValues; 53 private final boolean mSupportVariableUpdateRate; 54 private final boolean mHasMinSupportedValue; 55 private final boolean mHasMaxSupportedValue; 56 private final boolean mHasSupportedValuesList; 57 AreaIdConfig( int areaId, @Nullable T minValue, @Nullable T maxValue, List<T> supportedEnumValues, @CarPropertyConfig.VehiclePropertyAccessType int access, boolean supportVariableUpdateRate, boolean hasMinSupportedValue, boolean hasMaxSupportedValue, boolean hasSupportedValuesList)58 private AreaIdConfig( 59 int areaId, @Nullable T minValue, @Nullable T maxValue, List<T> supportedEnumValues, 60 @CarPropertyConfig.VehiclePropertyAccessType int access, 61 boolean supportVariableUpdateRate, boolean hasMinSupportedValue, 62 boolean hasMaxSupportedValue, boolean hasSupportedValuesList) { 63 mAccess = access; 64 mAreaId = areaId; 65 mMinValue = minValue; 66 mMaxValue = maxValue; 67 mSupportedEnumValues = supportedEnumValues; 68 mSupportVariableUpdateRate = supportVariableUpdateRate; 69 mHasMinSupportedValue = hasMinSupportedValue; 70 mHasMaxSupportedValue = hasMaxSupportedValue; 71 mHasSupportedValuesList = hasSupportedValuesList; 72 } 73 74 @SuppressWarnings("unchecked") AreaIdConfig(Parcel in)75 private AreaIdConfig(Parcel in) { 76 mAccess = in.readInt(); 77 mAreaId = in.readInt(); 78 var minPropertyValue = (RawPropertyValue<T>) in.readParcelable( 79 RawPropertyValue.class.getClassLoader(), RawPropertyValue.class); 80 if (minPropertyValue != null) { 81 mMinValue = minPropertyValue.getTypedValue(); 82 } else { 83 mMinValue = null; 84 } 85 var maxPropertyValue = (RawPropertyValue<T>) in.readParcelable( 86 RawPropertyValue.class.getClassLoader(), RawPropertyValue.class); 87 if (maxPropertyValue != null) { 88 mMaxValue = maxPropertyValue.getTypedValue(); 89 } else { 90 mMaxValue = null; 91 } 92 List<RawPropertyValue> supportedEnumPropertyValues = new ArrayList<>(); 93 in.readParcelableList(supportedEnumPropertyValues, 94 RawPropertyValue.class.getClassLoader(), RawPropertyValue.class); 95 mSupportedEnumValues = new ArrayList<T>(); 96 for (int i = 0; i < supportedEnumPropertyValues.size(); i++) { 97 mSupportedEnumValues.add((T) supportedEnumPropertyValues.get(i).getTypedValue()); 98 } 99 mSupportVariableUpdateRate = in.readBoolean(); 100 mHasMinSupportedValue = in.readBoolean(); 101 mHasMaxSupportedValue = in.readBoolean(); 102 mHasSupportedValuesList = in.readBoolean(); 103 } 104 getCreator()105 private static <E> Parcelable.Creator<AreaIdConfig<E>> getCreator() { 106 return new Creator<AreaIdConfig<E>>() { 107 @Override 108 public AreaIdConfig<E> createFromParcel(Parcel source) { 109 return new AreaIdConfig<>(source); 110 } 111 112 @Override 113 @SuppressWarnings("unchecked") 114 public AreaIdConfig<E>[] newArray(int size) { 115 AreaIdConfig<E>[] areaIdConfigs = new AreaIdConfig[size]; 116 for (int i = 0; i < size; i++) { 117 areaIdConfigs[i] = null; 118 } 119 return areaIdConfigs; 120 } 121 }; 122 } 123 124 /** 125 * Return the access type of the car property at the current areaId. 126 * <p>The access type could be one of the following: 127 * <ul> 128 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_NONE}</li> 129 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ}</li> 130 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_WRITE}</li> 131 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}</li> 132 * </ul> 133 * 134 * @return the access type of the car property at the current areaId. 135 */ 136 @FlaggedApi(FLAG_AREA_ID_CONFIG_ACCESS) 137 public @CarPropertyConfig.VehiclePropertyAccessType int getAccess() { 138 return mAccess; 139 } 140 141 /** 142 * Returns the area ID for this configuration. 143 * 144 * @return area ID for this configuration. 145 */ 146 public int getAreaId() { 147 return mAreaId; 148 } 149 150 /** 151 * @deprecated use {@link CarPropertyManager#getMinMaxSupportedValue} instead. 152 * 153 * Returns the minimum supported value for the {@link #getAreaId()} reported by vehicle 154 * hardware at boot time. This value does not change even though the hardware may report a 155 * different value after boot. This value may not represent the currently supported min value. 156 * 157 * Use {@link CarPropertyManager#getMinMaxSupportedValue} for more accurate information. 158 * 159 * @return minimum value supported for the {@link #getAreaId()} at boot time. Will return 160 * {@code null} if no minimum value supported. 161 */ 162 @Deprecated 163 @Nullable 164 public T getMinValue() { 165 return mMinValue; 166 } 167 168 /** 169 * @deprecated use {@link CarPropertyManager#getMinMaxSupportedValue} instead. 170 * 171 * Returns the maximum supported value for the {@link #getAreaId()} reported by vehicle 172 * hardware at boot time. This value does not change even though the hardware may report a 173 * different value after boot. This value may not represent the currently supported max value. 174 * 175 * Use {@link CarPropertyManager#getMinMaxSupportedValue} for more accurate information. 176 * 177 * @return maximum value supported for the {@link #getAreaId()} at boot time. Will return 178 * {@code null} if no maximum value supported. 179 */ 180 @Deprecated 181 @Nullable 182 public T getMaxValue() { 183 return mMaxValue; 184 } 185 186 /** 187 * Returns whether variable update rate is supported. 188 * 189 * If this returns {@code false}, variable update rate is always disabled for this area ID. 190 * 191 * If this returns {@code true}, variable update rate will be disabled if client calls 192 * {@link Subscription.Builder#setVariableUpdateRateEnabled} with {@code false}, or enabled 193 * otherwise. 194 * 195 * @return whether variable update rate is supported. 196 */ 197 @FlaggedApi(FLAG_VARIABLE_UPDATE_RATE) 198 public boolean isVariableUpdateRateSupported() { 199 return mSupportVariableUpdateRate; 200 } 201 202 /** 203 * @deprecated use {@link CarPropertyManager#getSupportedValuesList} instead. 204 * 205 * Returns the supported enum values for the {@link #getAreaId()} reported by vehicle 206 * hardware at boot time. This list does not change even though the hardware may report a 207 * different list after boot. This list may not represent the currently supported enum values. 208 * 209 * Use {@link CarPropertyManager#getSupportedValuesList} for more accurate information. 210 * 211 * @return supported enum values for the {@link #getAreaId()} at boot time. If this list is 212 * empty, no enums are supported for this area at boot time. 213 */ 214 @Deprecated 215 @NonNull 216 public List<T> getSupportedEnumValues() { 217 return Collections.unmodifiableList(mSupportedEnumValues); 218 } 219 220 /** 221 * Whether [propertyId, areaId] has min supported value specified. 222 * 223 * <p>If this returns {@code true}, it means the hardware specifies a min supported value for 224 * this property. In normal cases, {@link CarPropertyManager#getMinMaxSupportedValue()} will 225 * return a structure whose 226 * {@link CarPropertyManager.MinMaxSupportedValue#getMinValue()} method returns a non-null result. 227 * 228 * In non-normal (error) cases, {@link CarPropertyManager.MinMaxSupportedValue#getMinValue()} 229 * may still return {@code null}. 230 * 231 * <p>If this returns {@code false}, 232 * {@link CarPropertyManager.MinMaxSupportedValue#getMinValue()} always returns {@code null}. 233 * 234 * <p>Unless otherwise specified in {@link VehiclePropertyIds} documentation, this function 235 * returns {@code false} for any system properties whose type is not int32, int64 or float. 236 * 237 * <p>For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this always return 238 * {@code true}. Check {@code VehiclePropertyIds} documentation for detail. 239 */ 240 @FlaggedApi(FLAG_CAR_PROPERTY_SUPPORTED_VALUE) 241 public boolean hasMinSupportedValue() { 242 return mHasMinSupportedValue; 243 } 244 245 /** 246 * Whether [propertyId, areaId] has max supported value specified. 247 * 248 * <p>If this returns {@code true}, it means the hardware specifies a min supported value for 249 * this property. In normal cases, {@link CarPropertyManager#getMinMaxSupportedValue()} will 250 * return a structure whose 251 * {@link CarPropertyManager.MinMaxSupportedValue#getMaxValue()} method returns a non-null 252 * result. 253 * 254 * In non-normal (error) cases, {@link CarPropertyManager.MinMaxSupportedValue#getMaxValue()} 255 * may still return {@code null}. 256 * 257 * <p>If this returns {@code false}, 258 * {@link CarPropertyManager.MinMaxSupportedValue#getMaxValue()} always returns {@code null}. 259 * 260 * <p>Unless otherwise specified in {@link VehiclePropertyIds} documentation, this function 261 * returns {@code false} for any system properties whose type is not int32, int64 or float. 262 * 263 * <p>For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this always return 264 * {@code true}. Check {@code VehiclePropertyIds} documentation for detail. 265 */ 266 @FlaggedApi(FLAG_CAR_PROPERTY_SUPPORTED_VALUE) 267 public boolean hasMaxSupportedValue() { 268 return mHasMaxSupportedValue; 269 } 270 271 /** 272 * Whether [propertyId, areaId] has supported value list specified. 273 * 274 * <p>If this returns {@code true}, it means the hardware specifies supported value list for 275 * this property. In normal cases, {@link CarPropertyManager#getSupportedValuesList()} will not 276 * return {@code null}. In non-normal (error) cases, it may return {@code null}. 277 * 278 * <p>If this returns {@code false}, {@link CarPropertyManager#getSupportedValuesList()} always 279 * returns {@code null}. 280 * 281 * <p>The supported value list is the superset for both the input value for writable property 282 * and the output value for readable property. 283 * 284 * <p>For certain properties, e.g. {@code GEAR_SELECTION}, this always returns {@code true}. 285 * Check {@code VehiclePropertyIds} documentation for detail. 286 */ 287 @FlaggedApi(FLAG_CAR_PROPERTY_SUPPORTED_VALUE) 288 public boolean hasSupportedValuesList() { 289 return mHasSupportedValuesList; 290 } 291 292 @Override 293 public int describeContents() { 294 return 0; 295 } 296 297 @Override 298 public void writeToParcel(@NonNull Parcel dest, int flags) { 299 dest.writeInt(mAccess); 300 dest.writeInt(mAreaId); 301 RawPropertyValue minPropertyValue = null; 302 if (mMinValue != null) { 303 minPropertyValue = new RawPropertyValue(mMinValue); 304 } 305 dest.writeParcelable(minPropertyValue, /* parcelableFlags= */ 0); 306 RawPropertyValue maxPropertyValue = null; 307 if (mMaxValue != null) { 308 maxPropertyValue = new RawPropertyValue(mMaxValue); 309 } 310 dest.writeParcelable(maxPropertyValue, /* parcelableFlags= */ 0); 311 List<RawPropertyValue> supportedEnumPropertyValues = new ArrayList<>(); 312 for (int i = 0; i < mSupportedEnumValues.size(); i++) { 313 supportedEnumPropertyValues.add(new RawPropertyValue(mSupportedEnumValues.get(i))); 314 } 315 dest.writeParcelableList(supportedEnumPropertyValues, /* parcelableFlags= */ 0); 316 dest.writeBoolean(mSupportVariableUpdateRate); 317 dest.writeBoolean(mHasMinSupportedValue); 318 dest.writeBoolean(mHasMaxSupportedValue); 319 dest.writeBoolean(mHasSupportedValuesList); 320 } 321 322 @Override 323 public String toString() { 324 return toString(null); 325 } 326 327 /** @hide */ 328 public String toString(@Nullable Integer propertyId) { 329 StringBuilder sb = new StringBuilder(); 330 sb.append("AreaIdConfig{").append("mAreaId=").append( 331 propertyId == null ? mAreaId : toAreaIdString(propertyId, mAreaId)) 332 .append("mAccess=").append(mAccess); 333 if (mMinValue != null) { 334 sb.append(", mMinValue=").append(mMinValue); 335 } 336 if (mMaxValue != null) { 337 sb.append(", mMaxValue=").append(mMaxValue); 338 } 339 if (!mSupportedEnumValues.isEmpty()) { 340 sb.append(", mSupportedEnumValues=").append(mSupportedEnumValues); 341 } 342 sb.append(", mHasMinSupportedValue=").append(mHasMinSupportedValue); 343 sb.append(", mHasMaxSupportedValue=").append(mHasMaxSupportedValue); 344 sb.append(", mHasSupportedValuesList=").append(mHasSupportedValuesList); 345 return sb.append("}").toString(); 346 } 347 348 /** 349 * @param <T> matches the type for the {@link android.car.hardware.CarPropertyConfig}. 350 * 351 * This is supposed to be called by CarService only. For history reason, we exposed 352 * this as system API, however, client must not use this builder and should use the getXXX 353 * method in {@code AreaIdConfig}. 354 * 355 * @hide 356 * @deprecated marked as deprecated because clients should not have direct access to the 357 * AreaIdConfig.Builder class 358 */ 359 @Deprecated 360 @SystemApi 361 public static final class Builder<T> { 362 private final @CarPropertyConfig.VehiclePropertyAccessType int mAccess; 363 private final int mAreaId; 364 private T mMinValue = null; 365 private T mMaxValue = null; 366 private List<T> mSupportedEnumValues = Collections.EMPTY_LIST; 367 private boolean mSupportVariableUpdateRate = false; 368 private boolean mHasMaxSupportedValue = false; 369 private boolean mHasMinSupportedValue = false; 370 private boolean mHasSupportedValuesList = false; 371 372 public Builder(int areaId) { 373 mAccess = CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_NONE; 374 mAreaId = areaId; 375 } 376 377 @FlaggedApi(FLAG_AREA_ID_CONFIG_ACCESS) 378 public Builder(@CarPropertyConfig.VehiclePropertyAccessType int access, int areaId) { 379 mAccess = access; 380 mAreaId = areaId; 381 } 382 383 /** Set the min value for the {@link AreaIdConfig}. */ 384 @NonNull 385 public Builder<T> setMinValue(T minValue) { 386 mMinValue = minValue; 387 mHasMinSupportedValue = true; 388 return this; 389 } 390 391 /** Set the max value for the {@link AreaIdConfig}. */ 392 @NonNull 393 public Builder<T> setMaxValue(T maxValue) { 394 mMaxValue = maxValue; 395 mHasMaxSupportedValue = true; 396 return this; 397 } 398 399 /** Set the supported enum values for the {@link AreaIdConfig}. */ 400 @NonNull 401 public Builder<T> setSupportedEnumValues(@NonNull List<T> supportedEnumValues) { 402 mSupportedEnumValues = supportedEnumValues; 403 mHasSupportedValuesList = true; 404 return this; 405 } 406 407 /** 408 * Sets whether variable update rate is supported. 409 * 410 * This is supposed to be called by CarService only. 411 * 412 * @hide 413 */ 414 @NonNull 415 public Builder<T> setSupportVariableUpdateRate(boolean supportVariableUpdateRate) { 416 mSupportVariableUpdateRate = supportVariableUpdateRate; 417 return this; 418 } 419 420 /** 421 * Sets whether this area has a specified min supported value. 422 * 423 * @hide 424 */ 425 @NonNull 426 public Builder<T> setHasMinSupportedValue(boolean hasMinSupportedValue) { 427 mHasMinSupportedValue = hasMinSupportedValue; 428 return this; 429 } 430 431 /** 432 * Sets whether this area has a specified max supported value. 433 * 434 * @hide 435 */ 436 @NonNull 437 public Builder<T> setHasMaxSupportedValue(boolean hasMaxSupportedValue) { 438 mHasMaxSupportedValue = hasMaxSupportedValue; 439 return this; 440 } 441 442 /** 443 * Sets whether this area has a specified supported value list. 444 * 445 * @hide 446 */ 447 @NonNull 448 public Builder<T> setHasSupportedValuesList(boolean hasSupportedValuesList) { 449 mHasSupportedValuesList = hasSupportedValuesList; 450 return this; 451 } 452 453 /** Builds a new {@link android.car.hardware.property.AreaIdConfig}. */ 454 @NonNull 455 public AreaIdConfig<T> build() { 456 return new AreaIdConfig<>(mAreaId, mMinValue, mMaxValue, mSupportedEnumValues, mAccess, 457 mSupportVariableUpdateRate, mHasMinSupportedValue, mHasMaxSupportedValue, 458 mHasSupportedValuesList); 459 } 460 } 461 } 462