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 17 package android.car.hardware; 18 19 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE; 20 import static com.android.car.internal.util.DebugUtils.constantToString; 21 import static com.android.car.internal.util.DebugUtils.toAreaIdString; 22 23 import android.annotation.FlaggedApi; 24 import android.annotation.IntDef; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.SystemApi; 28 import android.car.VehicleAreaType; 29 import android.car.VehicleAreaType.VehicleAreaTypeValue; 30 import android.car.VehiclePropertyIds; 31 import android.car.builtin.os.BuildHelper; 32 import android.car.feature.Flags; 33 import android.car.hardware.property.AreaIdConfig; 34 import android.car.hardware.property.CarPropertySimulationManager; 35 import android.os.Parcel; 36 import android.os.Parcelable; 37 import android.util.SparseArray; 38 39 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.lang.reflect.Array; 44 import java.util.ArrayList; 45 import java.util.Collections; 46 import java.util.List; 47 48 /** 49 * Represents general information about car property such as data type and min/max ranges for car 50 * areas (if applicable). This class supposed to be immutable, parcelable and could be passed over. 51 * 52 * @param <T> refer to {@link Parcel#writeValue(java.lang.Object)} to get a list of all supported 53 * types. The class should be visible to framework as default class loader is being used here. 54 * 55 */ 56 public final class CarPropertyConfig<T> implements Parcelable { 57 private static final String TAG = CarPropertyConfig.class.getSimpleName(); 58 private final int mAccess; 59 private final int mAreaType; 60 private final int mChangeMode; 61 private final ArrayList<Integer> mConfigArray; 62 private final String mConfigString; 63 private final float mMaxSampleRate; 64 private final float mMinSampleRate; 65 private final int mPropertyId; 66 private final List<AreaIdConfig<T>> mAreaIdConfigs; 67 private final SparseArray<AreaIdConfig<T>> mAreaIdToAreaIdConfig; 68 private final Class<T> mType; 69 private boolean mIsPropertyIdSimulationPropId; 70 CarPropertyConfig(int access, int areaType, int changeMode, ArrayList<Integer> configArray, String configString, float maxSampleRate, float minSampleRate, int propertyId, List<AreaIdConfig<T>> areaIdConfigs, Class<T> type, boolean isPropertyIdSimulationPropId)71 private CarPropertyConfig(int access, int areaType, int changeMode, 72 ArrayList<Integer> configArray, String configString, 73 float maxSampleRate, float minSampleRate, int propertyId, 74 List<AreaIdConfig<T>> areaIdConfigs, Class<T> type, 75 boolean isPropertyIdSimulationPropId) { 76 mAccess = access; 77 mAreaType = areaType; 78 mChangeMode = changeMode; 79 mConfigArray = configArray; 80 mConfigString = configString; 81 mMaxSampleRate = maxSampleRate; 82 mMinSampleRate = minSampleRate; 83 mPropertyId = propertyId; 84 mAreaIdConfigs = areaIdConfigs; 85 mAreaIdToAreaIdConfig = generateAreaIdToAreaIdConfig(areaIdConfigs); 86 mType = type; 87 mIsPropertyIdSimulationPropId = isPropertyIdSimulationPropId; 88 } 89 90 /** @hide */ 91 @IntDef(prefix = {"VEHICLE_PROPERTY_ACCESS"}, value = { 92 VEHICLE_PROPERTY_ACCESS_NONE, 93 VEHICLE_PROPERTY_ACCESS_READ, 94 VEHICLE_PROPERTY_ACCESS_WRITE, 95 VEHICLE_PROPERTY_ACCESS_READ_WRITE 96 }) 97 @Retention(RetentionPolicy.SOURCE) 98 public @interface VehiclePropertyAccessType {} 99 100 /** Property Access Unknown */ 101 public static final int VEHICLE_PROPERTY_ACCESS_NONE = 0; 102 /** The property is readable */ 103 public static final int VEHICLE_PROPERTY_ACCESS_READ = 1; 104 /** The property is writable */ 105 public static final int VEHICLE_PROPERTY_ACCESS_WRITE = 2; 106 /** The property is readable and writable */ 107 public static final int VEHICLE_PROPERTY_ACCESS_READ_WRITE = 3; 108 109 /** @hide */ 110 @IntDef(prefix = {"VEHICLE_PROPERTY_CHANGE_MODE"}, value = { 111 VEHICLE_PROPERTY_CHANGE_MODE_STATIC, 112 VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE, 113 VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS, 114 }) 115 @Retention(RetentionPolicy.SOURCE) 116 public @interface VehiclePropertyChangeModeType {} 117 118 /** Properties of this type must never be changed. */ 119 public static final int VEHICLE_PROPERTY_CHANGE_MODE_STATIC = 0; 120 /** Properties of this type must report when there is a change. */ 121 public static final int VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE = 1; 122 /** Properties of this type change continuously. */ 123 public static final int VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS = 2; 124 125 /** 126 * Returns the access type of the car property. 127 * <p>The access type could be one of the following: 128 * <ul> 129 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_NONE}</li> 130 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ}</li> 131 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_WRITE}</li> 132 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ_WRITE}</li> 133 * </ul> 134 * 135 * @return the access type of the car property. 136 */ getAccess()137 public @VehiclePropertyAccessType int getAccess() { 138 return mAccess; 139 } 140 141 /** 142 * Returns the area type of the car property. 143 * <p>The area type could be one of the following: 144 * <ul> 145 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}</li> 146 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_WINDOW}</li> 147 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_SEAT}</li> 148 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_DOOR}</li> 149 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_MIRROR}</li> 150 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_WHEEL}</li> 151 * <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_VENDOR}</li> 152 * </ul> 153 * 154 * @return the area type of the car property. 155 */ getAreaType()156 public @VehicleAreaTypeValue int getAreaType() { 157 return mAreaType; 158 } 159 160 /** 161 * Returns the change mode of the car property. 162 * 163 * <p>The change mode could be one of the following: 164 * <ul> 165 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_STATIC }</li> 166 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}</li> 167 * <li>{@link CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS}</li> 168 * </ul> 169 * 170 * @return the change mode of properties. 171 */ getChangeMode()172 public @VehiclePropertyChangeModeType int getChangeMode() { 173 return mChangeMode; 174 } 175 176 /** 177 * Returns the optional additional configuration parameters. 178 * 179 * @return Additional configuration parameters. For different properties, configArrays have 180 * different information. 181 */ 182 @NonNull getConfigArray()183 public List<Integer> getConfigArray() { 184 return Collections.unmodifiableList(mConfigArray); 185 } 186 187 /** 188 * Returns the optional additional configuration information. 189 * 190 * @return Some properties may require additional information passed over this 191 * string. Most properties do not need to set this. 192 * @hide 193 */ getConfigString()194 public String getConfigString() { 195 return mConfigString; 196 } 197 198 /** 199 * Returns the max sample rate in Hz. 200 * 201 * @return Max sample rate in Hz. Must be defined for {@link 202 * #VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS} return 0 if change mode is not continuous. 203 */ getMaxSampleRate()204 public float getMaxSampleRate() { 205 return mMaxSampleRate; 206 } 207 208 /** 209 * Returns the min sample rate in Hz. 210 * 211 * @return Min sample rate in Hz. Must be defined for {@link 212 * #VEHICLE_PROPERTY_CHANGE_MODE_CONTINUOUS} return 0 if change mode is not continuous. 213 */ getMinSampleRate()214 public float getMinSampleRate() { 215 return mMinSampleRate; 216 } 217 218 /** 219 * Returns the property identifier. 220 * 221 * @return Property identifier, must be one of enums in 222 * {@link android.car.VehiclePropertyIds}. 223 */ getPropertyId()224 public int getPropertyId() { 225 return mPropertyId; 226 } 227 228 /** 229 * Returns the value type of the vehicle property. 230 * <p>The value type could be one of the following: 231 * <ul> 232 * <li>Boolean</li> 233 * <li>Float</li> 234 * <li>Float[]</li> 235 * <li>Integer</li> 236 * <li>Integer[]</li> 237 * <li>Long</li> 238 * <li>Long[]</li> 239 * <li>String</li> 240 * <li>byte[]</li> 241 * <li>Object[]</li> 242 * </ul> 243 * 244 * @return the value type of the vehicle property. 245 */ 246 @NonNull getPropertyType()247 public Class<T> getPropertyType() { 248 return mType; 249 } 250 251 /** 252 * Returns a list of {@link AreaIdConfig} for this property. 253 * 254 * @return list of {@link AreaIdConfig} instances for this property. 255 */ 256 @NonNull getAreaIdConfigs()257 public List<AreaIdConfig<T>> getAreaIdConfigs() { 258 return Collections.unmodifiableList(mAreaIdConfigs); 259 } 260 261 /** 262 * Returns the {@link AreaIdConfig} for the specified {@code areaId}. 263 * 264 * @return {@link AreaIdConfig} instance for passed {@code areaId} 265 * @throws IllegalArgumentException if {@code areaId} is not supported for property 266 */ 267 @NonNull getAreaIdConfig(int areaId)268 public AreaIdConfig<T> getAreaIdConfig(int areaId) { 269 if (!mAreaIdToAreaIdConfig.contains(areaId)) { 270 throw new IllegalArgumentException("Area ID: " + toAreaIdString(mPropertyId, areaId) 271 + " is not supported for property ID: " + propertyIdToString()); 272 } 273 return mAreaIdToAreaIdConfig.get(areaId); 274 } 275 276 /** 277 * Returns whether this property is area type {@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}. 278 * 279 * @return true if this property is area type {@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}. 280 */ isGlobalProperty()281 public boolean isGlobalProperty() { 282 return mAreaType == VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; 283 } 284 285 /** 286 * Returns the number of areaIds for the property. 287 * 288 * @return the number of areaIds for the property. 289 * @hide 290 */ getAreaCount()291 public int getAreaCount() { 292 return mAreaIdConfigs.size(); 293 } 294 295 /** 296 * Returns a list of area IDs supported for the vehicle property. 297 * 298 * <p>An area represents a unique element of a {@link VehicleAreaType}. For instance, if the 299 * {@link VehicleAreaType} is {@link VehicleAreaType#VEHICLE_AREA_TYPE_SEAT}, then an example 300 * area is {@link android.car.VehicleAreaSeat#SEAT_ROW_1_LEFT}. 301 * 302 * <p>An area ID is a combination of one or more areas, and is created by bitwise "OR"ing the 303 * areas together. Areas from different {@link VehicleAreaType} values will not be mixed in a 304 * single area ID. For example, a {@link android.car.VehicleAreaWheel} area cannot be combined 305 * with a {@link android.car.VehicleAreaSeat} area in an area ID. 306 * 307 * <p>For properties that return {@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL} for {@link 308 * #getAreaType()}, they only support a single area ID of {@code 0}. 309 * 310 * <p>Rules for mapping a non {@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL} property to area 311 * IDs: 312 * <ul> 313 * <li>A property is mapped to a set of area IDs that are impacted when the property value 314 * changes. 315 * <li>An area cannot be part of multiple area IDs, it will only be part of a single area ID. 316 * <li>When the property value changes in one of the areas in an area ID, then it will 317 * automatically change in all other areas in the area ID. 318 * <li>The property value will be independently controllable in any two different area IDs. 319 * </ul> 320 * 321 * @return the array of supported area IDs. 322 */ 323 @NonNull getAreaIds()324 public int[] getAreaIds() { 325 int[] areaIds = new int[mAreaIdConfigs.size()]; 326 for (int i = 0; i < areaIds.length; i++) { 327 areaIds[i] = mAreaIdConfigs.get(i).getAreaId(); 328 } 329 return areaIds; 330 } 331 332 /** 333 * Returns whether the propertyId is Simulation Property Id. 334 * 335 * <p>Simulation property is a property which is used by car service and vehicle hardware but 336 * is not defined in {@link android.car.VehiclePropertyIds} 337 * 338 * @return {@code true} when returned from 339 * {@link CarPropertySimulationManager#startRecordingVehicleProperties} {@code false} otherwise. 340 * 341 * @hide 342 */ 343 @SystemApi 344 @FlaggedApi(Flags.FLAG_CAR_PROPERTY_SIMULATION) isPropertyIdSimulationPropId()345 public boolean isPropertyIdSimulationPropId() { 346 if (!BuildHelper.isDebuggableBuild()) { 347 throw new IllegalStateException("Build is not eng or user-debug"); 348 } 349 return mIsPropertyIdSimulationPropId; 350 } 351 352 /** 353 * @return the first areaId. 354 * Throws {@link java.lang.IllegalStateException} if supported area count not equals to one. 355 * @hide 356 */ getFirstAndOnlyAreaId()357 public int getFirstAndOnlyAreaId() { 358 if (mAreaIdConfigs.size() != 1) { 359 throw new IllegalStateException("Expected one and only area in this property. PropId: " 360 + propertyIdToString()); 361 } 362 return mAreaIdConfigs.get(0).getAreaId(); 363 } 364 propertyIdToString()365 private String propertyIdToString() { 366 if (Flags.carPropertySimulation()) { 367 if (isPropertyIdSimulationPropId()) { 368 return "0x" + Integer.toHexString(mPropertyId); 369 } 370 } 371 return VehiclePropertyIds.toString(mPropertyId); 372 } 373 374 /** 375 * Verify if the areaId passed as a parameter exists. 376 * @hide 377 */ hasArea(int areaId)378 public boolean hasArea(int areaId) { 379 return mAreaIdToAreaIdConfig.indexOfKey(areaId) >= 0; 380 } 381 382 /** 383 * @deprecated - use {@link #getAreaIdConfigs()} or {@link #getAreaIdConfig(int)} instead. 384 * 385 * @param areaId the area ID 386 * @return min value in given areaId. Null if not have min value in given area 387 */ 388 @Deprecated 389 @Nullable getMinValue(int areaId)390 public T getMinValue(int areaId) { 391 AreaIdConfig<T> areaIdConfig = mAreaIdToAreaIdConfig.get(areaId); 392 return areaIdConfig == null ? null : areaIdConfig.getMinValue(); 393 } 394 395 /** 396 * @deprecated - use {@link #getAreaIdConfigs()} or {@link #getAreaIdConfig(int)} instead. 397 * 398 * @param areaId the area ID 399 * @return max value in given areaId. Null if not have max value in given area 400 */ 401 @Deprecated 402 @Nullable getMaxValue(int areaId)403 public T getMaxValue(int areaId) { 404 AreaIdConfig<T> areaIdConfig = mAreaIdToAreaIdConfig.get(areaId); 405 return areaIdConfig == null ? null : areaIdConfig.getMaxValue(); 406 } 407 408 /** 409 * @deprecated - use {@link #getAreaIdConfigs()} or {@link #getAreaIdConfig(int)} instead. 410 * 411 * @return Min value in areaId 0. Null if not have min value. 412 */ 413 @Deprecated 414 @Nullable getMinValue()415 public T getMinValue() { 416 AreaIdConfig<T> areaIdConfig = mAreaIdToAreaIdConfig.get(0); 417 return areaIdConfig == null ? null : areaIdConfig.getMinValue(); 418 } 419 420 /** 421 * @deprecated - use {@link #getAreaIdConfigs()} or {@link #getAreaIdConfig(int)} instead. 422 * 423 * @return Max value in areaId 0. Null if not have max value. 424 */ 425 @Deprecated 426 @Nullable getMaxValue()427 public T getMaxValue() { 428 AreaIdConfig<T> areaIdConfig = mAreaIdToAreaIdConfig.get(0); 429 return areaIdConfig == null ? null : areaIdConfig.getMaxValue(); 430 } 431 432 @Override 433 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE) describeContents()434 public int describeContents() { 435 return 0; 436 } 437 438 @Override writeToParcel(Parcel dest, int flags)439 public void writeToParcel(Parcel dest, int flags) { 440 dest.writeInt(mAccess); 441 dest.writeInt(mAreaType); 442 dest.writeInt(mChangeMode); 443 dest.writeInt(mConfigArray.size()); 444 for (int i = 0; i < mConfigArray.size(); i++) { 445 dest.writeInt(mConfigArray.get(i)); 446 } 447 dest.writeString(mConfigString); 448 dest.writeFloat(mMaxSampleRate); 449 dest.writeFloat(mMinSampleRate); 450 dest.writeInt(mPropertyId); 451 dest.writeList(mAreaIdConfigs); 452 dest.writeString(mType.getName()); 453 } 454 455 @SuppressWarnings("unchecked") CarPropertyConfig(Parcel in)456 private CarPropertyConfig(Parcel in) { 457 mAccess = in.readInt(); 458 mAreaType = in.readInt(); 459 mChangeMode = in.readInt(); 460 int configArraySize = in.readInt(); 461 mConfigArray = new ArrayList<Integer>(configArraySize); 462 for (int i = 0; i < configArraySize; i++) { 463 mConfigArray.add(in.readInt()); 464 } 465 mConfigString = in.readString(); 466 mMaxSampleRate = in.readFloat(); 467 mMinSampleRate = in.readFloat(); 468 mPropertyId = in.readInt(); 469 mAreaIdConfigs = in.readArrayList(getClass().getClassLoader()); 470 mAreaIdToAreaIdConfig = generateAreaIdToAreaIdConfig(mAreaIdConfigs); 471 String className = in.readString(); 472 try { 473 mType = (Class<T>) Class.forName(className); 474 } catch (ClassNotFoundException e) { 475 throw new IllegalArgumentException("Class not found: " + className, e); 476 } 477 } 478 479 public static final Creator<CarPropertyConfig> CREATOR = new Creator<CarPropertyConfig>() { 480 @Override 481 public CarPropertyConfig createFromParcel(Parcel in) { 482 return new CarPropertyConfig(in); 483 } 484 485 @Override 486 public CarPropertyConfig[] newArray(int size) { 487 return new CarPropertyConfig[size]; 488 } 489 }; 490 491 /** @hide */ 492 @Override toString()493 public String toString() { 494 String configString = "CarPropertyConfig{" 495 + "mPropertyId=" + propertyIdToString() 496 + ", mAccess=" + constantToString(CarPropertyConfig.class, 497 "VEHICLE_PROPERTY_ACCESS_", mAccess) 498 + ", mAreaType=" + constantToString(VehicleAreaType.class, "VEHICLE_AREA_TYPE_", 499 mAreaType) 500 + ", mChangeMode=" + constantToString(CarPropertyConfig.class, 501 "VEHICLE_PROPERTY_CHANGE_MODE_", mChangeMode) 502 + ", mConfigArray=" + mConfigArray 503 + ", mConfigString=" + mConfigString 504 + ", mMaxSampleRate(Hz)=" + mMaxSampleRate 505 + ", mMinSampleRate(Hz)=" + mMinSampleRate 506 + ", mAreaIdConfigs =" + mAreaIdConfigs.stream().map( 507 areaIdConfig -> areaIdConfig.toString(mPropertyId)).toList() 508 + ", mType=" + mType; 509 if (Flags.carPropertySimulation()) { 510 if (isPropertyIdSimulationPropId()) { 511 return configString 512 + ", mIsPropertyIdSimulationPropId=" + mIsPropertyIdSimulationPropId 513 + '}'; 514 } 515 } 516 return configString + '}'; 517 } 518 519 /** 520 * Represents min/max value of car property. 521 * 522 * @param <T> The property type 523 * @hide 524 * @deprecated This API is deprecated in favor of {@link 525 * android.car.hardware.property.AreaIdConfig} which allows properties to specify which enum 526 * values are supported. This API will be marked as {@code @removed} in the next major release 527 * and hard removed in the release after that. 528 */ 529 @Deprecated 530 public static class AreaConfig<T> implements Parcelable { 531 @Nullable private final T mMinValue; 532 @Nullable private final T mMaxValue; 533 534 @SuppressWarnings("unused") AreaConfig(T minValue, T maxValue)535 private AreaConfig(T minValue, T maxValue) { 536 mMinValue = minValue; 537 mMaxValue = maxValue; 538 } 539 540 public static final Parcelable.Creator<AreaConfig<Object>> CREATOR = 541 getCreator(Object.class); 542 getCreator(final Class<E> clazz)543 private static <E> Parcelable.Creator<AreaConfig<E>> getCreator(final Class<E> clazz) { 544 return new Creator<AreaConfig<E>>() { 545 @Override 546 public AreaConfig<E> createFromParcel(Parcel source) { 547 return new AreaConfig<>(source); 548 } 549 550 @Override @SuppressWarnings("unchecked") 551 public AreaConfig<E>[] newArray(int size) { 552 return (AreaConfig<E>[]) Array.newInstance(clazz, size); 553 } 554 }; 555 } 556 557 @SuppressWarnings("unchecked") AreaConfig(Parcel in)558 private AreaConfig(Parcel in) { 559 mMinValue = (T) in.readValue(getClass().getClassLoader()); 560 mMaxValue = (T) in.readValue(getClass().getClassLoader()); 561 } 562 getMinValue()563 @Nullable public T getMinValue() { 564 return mMinValue; 565 } 566 getMaxValue()567 @Nullable public T getMaxValue() { 568 return mMaxValue; 569 } 570 571 @Override describeContents()572 public int describeContents() { 573 return 0; 574 } 575 576 @Override writeToParcel(Parcel dest, int flags)577 public void writeToParcel(Parcel dest, int flags) { 578 dest.writeValue(mMinValue); 579 dest.writeValue(mMaxValue); 580 } 581 582 @Override toString()583 public String toString() { 584 return "CarAreaConfig{" 585 + "mMinValue=" + mMinValue 586 + ", mMaxValue=" + mMaxValue 587 + '}'; 588 } 589 } 590 591 /** 592 * Prepare an instance of {@link CarPropertyConfig} 593 * 594 * @return Builder<T> 595 * @hide 596 * @deprecated marked as deprecated because clients should not have direct access to the 597 * CarPropertyConfig.Builder class 598 */ 599 @Deprecated 600 @SystemApi 601 public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType, 602 int areaCapacity) { 603 return new Builder<>(areaType, propertyId, type); 604 } 605 606 607 /** 608 * Prepare an instance of {@link CarPropertyConfig} 609 * 610 * @return Builder<T> 611 * @hide 612 */ 613 public static <T> Builder<T> newBuilder(Class<T> type, int propertyId, int areaType) { 614 return new Builder<>(areaType, propertyId, type); 615 } 616 617 618 /** 619 * Builder for making new {@code CarPropertyConfig} objects. 620 * 621 * @param <T> 622 * @hide 623 * @deprecated marked as deprecated because clients should not have direct access to the 624 * CarPropertyConfig.Builder class 625 */ 626 @Deprecated 627 @SystemApi 628 public static class Builder<T> { 629 private int mAccess = VEHICLE_PROPERTY_ACCESS_NONE; 630 private final int mAreaType; 631 private int mChangeMode; 632 private final ArrayList<Integer> mConfigArray = new ArrayList<>(); 633 private String mConfigString; 634 private float mMaxSampleRate; 635 private float mMinSampleRate; 636 private final int mPropertyId; 637 private final List<AreaIdConfig<T>> mAreaIdConfigs = new ArrayList<>(); 638 private final Class<T> mType; 639 private boolean mIsPropertyIdSimulationPropId; 640 641 private Builder(int areaType, int propertyId, Class<T> type) { 642 mAreaType = areaType; 643 mPropertyId = propertyId; 644 mType = type; 645 } 646 647 /** 648 * Add supported areas parameter to {@link CarPropertyConfig} 649 * 650 * <p>This function uses the access set in the builder to define the area ID's access level. 651 * Make sure to call {@link CarPropertyConfig.Builder#setAccess(int)} before calling this 652 * function. 653 * 654 * @return Builder<T> 655 * @removed - use {@link #addAreaIdConfig(AreaIdConfig)} instead. 656 */ 657 @Deprecated 658 public Builder<T> addAreas(int[] areaIds) { 659 for (int areaId : areaIds) { 660 AreaIdConfig.Builder<T> areaIdConfigBuilder = Flags.areaIdConfigAccess() 661 ? new AreaIdConfig.Builder<T>(mAccess, areaId) 662 : new AreaIdConfig.Builder<T>(areaId); 663 mAreaIdConfigs.add(areaIdConfigBuilder.build()); 664 } 665 return this; 666 } 667 668 /** 669 * Add {@code areaId} to {@link CarPropertyConfig} 670 * 671 * <p>This function uses the access set in the builder to define the area's access level. 672 * Make sure to call {@link CarPropertyConfig.Builder#setAccess(int)} before calling this 673 * function. 674 * 675 * @return Builder<T> 676 * @removed - use {@link #addAreaIdConfig(AreaIdConfig)} instead. 677 */ 678 @Deprecated 679 public Builder<T> addArea(int areaId) { 680 AreaIdConfig.Builder<T> areaIdConfigBuilder = Flags.areaIdConfigAccess() 681 ? new AreaIdConfig.Builder<T>(mAccess, areaId) 682 : new AreaIdConfig.Builder<T>(areaId); 683 mAreaIdConfigs.add(areaIdConfigBuilder.build()); 684 return this; 685 } 686 687 /** 688 * Add {@code areaConfig} to {@link CarPropertyConfig} 689 * 690 * <p>This function uses the access set in the builder to define the area's access level. 691 * Make sure to call {@link CarPropertyConfig.Builder#setAccess(int)} before calling this 692 * function. 693 * 694 * @return Builder<T> 695 * @removed - use {@link #addAreaIdConfig(AreaIdConfig)} instead. 696 */ 697 @Deprecated 698 public Builder<T> addAreaConfig(int areaId, T min, T max) { 699 AreaIdConfig.Builder<T> areaIdConfigBuilder = Flags.areaIdConfigAccess() 700 ? new AreaIdConfig.Builder<T>(mAccess, areaId) 701 : new AreaIdConfig.Builder<T>(areaId); 702 mAreaIdConfigs.add(areaIdConfigBuilder.setMinValue(min).setMaxValue(max).build()); 703 return this; 704 } 705 706 /** 707 * Add {@link AreaIdConfig} to {@link CarPropertyConfig}. 708 * 709 * @return Builder<T> 710 */ 711 @NonNull 712 public Builder<T> addAreaIdConfig(@NonNull AreaIdConfig<T> areaIdConfig) { 713 mAreaIdConfigs.add(areaIdConfig); 714 return this; 715 } 716 717 718 /** 719 * Set {@code access} parameter to {@link CarPropertyConfig} 720 * 721 * @return Builder<T> 722 */ 723 public Builder<T> setAccess(int access) { 724 mAccess = access; 725 return this; 726 } 727 728 /** 729 * Set {@code changeMode} parameter to {@link CarPropertyConfig} 730 * 731 * @return Builder<T> 732 */ 733 public Builder<T> setChangeMode(int changeMode) { 734 mChangeMode = changeMode; 735 return this; 736 } 737 738 /** 739 * Set {@code configArray} parameter to {@link CarPropertyConfig} 740 * 741 * @return Builder<T> 742 */ 743 public Builder<T> setConfigArray(ArrayList<Integer> configArray) { 744 mConfigArray.clear(); 745 mConfigArray.addAll(configArray); 746 return this; 747 } 748 749 /** 750 * Set {@code configString} parameter to {@link CarPropertyConfig} 751 * 752 * @return Builder<T> 753 */ 754 public Builder<T> setConfigString(String configString) { 755 mConfigString = configString; 756 return this; 757 } 758 759 /** 760 * Set {@code maxSampleRate} parameter to {@link CarPropertyConfig} 761 * 762 * @return Builder<T> 763 */ 764 public Builder<T> setMaxSampleRate(float maxSampleRate) { 765 mMaxSampleRate = maxSampleRate; 766 return this; 767 } 768 769 /** 770 * Set {@code minSampleRate} parameter to {@link CarPropertyConfig} 771 * 772 * @return Builder<T> 773 */ 774 public Builder<T> setMinSampleRate(float minSampleRate) { 775 mMinSampleRate = minSampleRate; 776 return this; 777 } 778 779 /** 780 * Set whether property Id is Simulation. 781 * 782 * @return Builder 783 */ 784 public Builder<T> setPropertyIdIsSimulationPropId(boolean isSimulationPropId) { 785 mIsPropertyIdSimulationPropId = isSimulationPropId; 786 return this; 787 } 788 789 /** 790 * Builds a new {@link CarPropertyConfig}. 791 */ 792 public CarPropertyConfig<T> build() { 793 return new CarPropertyConfig<>(mAccess, mAreaType, mChangeMode, mConfigArray, 794 mConfigString, mMaxSampleRate, mMinSampleRate, 795 mPropertyId, mAreaIdConfigs, mType, 796 mIsPropertyIdSimulationPropId); 797 } 798 } 799 800 private static <U> SparseArray<AreaIdConfig<U>> generateAreaIdToAreaIdConfig( 801 List<AreaIdConfig<U>> areaIdConfigs) { 802 SparseArray<AreaIdConfig<U>> areaIdToAreaIdConfig = new SparseArray<>(areaIdConfigs.size()); 803 for (int i = 0; i < areaIdConfigs.size(); i++) { 804 AreaIdConfig<U> areaIdConfig = areaIdConfigs.get(i); 805 areaIdToAreaIdConfig.put(areaIdConfig.getAreaId(), areaIdConfig); 806 } 807 return areaIdToAreaIdConfig; 808 } 809 } 810