Added LOW_SPEED_COLLISION_WARNING_STATE to API

Bug: 310955303
Test: atest CtsCarTestCases:LowSpeedCollisionWarningStateTest
AndroidCarApiTest: LowSpeedCollisionWarningStateTest
CtsCarTestCases: CarPropertyManagerTest
CtsCarTestCases: VehiclePropertyIdsTest
Change-Id: I6e9cf0ed3ca95e929b1471a816f4b99e98513c5c
diff --git a/car-lib-module/api/system-current.txt b/car-lib-module/api/system-current.txt
index 2d3f8cc..26b6b77 100644
--- a/car-lib-module/api/system-current.txt
+++ b/car-lib-module/api/system-current.txt
@@ -316,6 +316,7 @@
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LANE_KEEP_ASSIST_ENABLED = 287313928; // 0x11201008
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LANE_KEEP_ASSIST_STATE = 289411081; // 0x11401009
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LOW_SPEED_COLLISION_WARNING_ENABLED = 287313953; // 0x11201021
+    field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LOW_SPEED_COLLISION_WARNING_STATE = 289411106; // 0x11401022
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_FOLD_ENABLED = 337644358; // 0x14200b46
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_TILT_ENABLED = 337644359; // 0x14200b47
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_CAR_AIRBAGS)) public static final int SEAT_AIRBAGS_DEPLOYED = 356518821; // 0x15400ba5
@@ -1370,6 +1371,13 @@
     field public static final int USER_OVERRIDE = 4; // 0x4
   }
 
+  @FlaggedApi("android.car.feature.android_vic_vehicle_properties") public final class LowSpeedCollisionWarningState {
+    method @NonNull public static String toString(int);
+    field public static final int NO_WARNING = 1; // 0x1
+    field public static final int OTHER = 0; // 0x0
+    field public static final int WARNING = 2; // 0x2
+  }
+
   public class PropertyNotAvailableException extends java.lang.IllegalStateException {
     method public int getVendorErrorCode();
   }
diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt
index 2d3f8cc..26b6b77 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -316,6 +316,7 @@
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LANE_KEEP_ASSIST_ENABLED = 287313928; // 0x11201008
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LANE_KEEP_ASSIST_STATE = 289411081; // 0x11401009
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LOW_SPEED_COLLISION_WARNING_ENABLED = 287313953; // 0x11201021
+    field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LOW_SPEED_COLLISION_WARNING_STATE = 289411106; // 0x11401022
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_FOLD_ENABLED = 337644358; // 0x14200b46
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_TILT_ENABLED = 337644359; // 0x14200b47
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_CAR_AIRBAGS)) public static final int SEAT_AIRBAGS_DEPLOYED = 356518821; // 0x15400ba5
@@ -1370,6 +1371,13 @@
     field public static final int USER_OVERRIDE = 4; // 0x4
   }
 
+  @FlaggedApi("android.car.feature.android_vic_vehicle_properties") public final class LowSpeedCollisionWarningState {
+    method @NonNull public static String toString(int);
+    field public static final int NO_WARNING = 1; // 0x1
+    field public static final int OTHER = 0; // 0x0
+    field public static final int WARNING = 2; // 0x2
+  }
+
   public class PropertyNotAvailableException extends java.lang.IllegalStateException {
     method public int getVendorErrorCode();
   }
diff --git a/car-lib/api/test-current.txt b/car-lib/api/test-current.txt
index 56cf71e..fc0e40f 100644
--- a/car-lib/api/test-current.txt
+++ b/car-lib/api/test-current.txt
@@ -322,6 +322,7 @@
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LANE_KEEP_ASSIST_ENABLED = 287313928; // 0x11201008
     field @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LANE_KEEP_ASSIST_STATE = 289411081; // 0x11401009
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(anyOf={android.car.Car.PERMISSION_READ_ADAS_SETTINGS, android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS})) @RequiresPermission.Write(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_CONTROL_ADAS_SETTINGS)) public static final int LOW_SPEED_COLLISION_WARNING_ENABLED = 287313953; // 0x11201021
+    field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_ADAS_STATES)) public static final int LOW_SPEED_COLLISION_WARNING_STATE = 289411106; // 0x11401022
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_FOLD_ENABLED = 337644358; // 0x14200b46
     field @RequiresPermission(android.car.Car.PERMISSION_CONTROL_CAR_MIRRORS) public static final int MIRROR_AUTO_TILT_ENABLED = 337644359; // 0x14200b47
     field @FlaggedApi("android.car.feature.android_vic_vehicle_properties") @RequiresPermission.Read(@androidx.annotation.RequiresPermission(android.car.Car.PERMISSION_READ_CAR_AIRBAGS)) public static final int SEAT_AIRBAGS_DEPLOYED = 356518821; // 0x15400ba5
@@ -1447,6 +1448,13 @@
     field public static final int USER_OVERRIDE = 4; // 0x4
   }
 
+  @FlaggedApi("android.car.feature.android_vic_vehicle_properties") public final class LowSpeedCollisionWarningState {
+    method @NonNull public static String toString(int);
+    field public static final int NO_WARNING = 1; // 0x1
+    field public static final int OTHER = 0; // 0x0
+    field public static final int WARNING = 2; // 0x2
+  }
+
   public class PropertyNotAvailableException extends java.lang.IllegalStateException {
     method public int getVendorErrorCode();
   }
diff --git a/car-lib/generated-prop-config/CarSvcProps.json b/car-lib/generated-prop-config/CarSvcProps.json
index 491a39b..59c87e5c 100644
--- a/car-lib/generated-prop-config/CarSvcProps.json
+++ b/car-lib/generated-prop-config/CarSvcProps.json
@@ -3530,6 +3530,27 @@
         "value": "android.car.permission.CONTROL_ADAS_SETTINGS"
       },
       "systemApi": true
+    },
+    "LOW_SPEED_COLLISION_WARNING_STATE": {
+      "propertyName": "LOW_SPEED_COLLISION_WARNING_STATE",
+      "propertyId": 289411106,
+      "description": "Low Speed Collision Warning State state.",
+      "readPermission": {
+        "type": "single",
+        "value": "android.car.permission.READ_ADAS_STATES"
+      },
+      "systemApi": true,
+      "dataEnums": [
+        0,
+        1,
+        2,
+        -1,
+        -2,
+        -3,
+        -4,
+        -5,
+        -6
+      ]
     }
   }
 }
\ No newline at end of file
diff --git a/car-lib/src/android/car/VehiclePropertyIds.java b/car-lib/src/android/car/VehiclePropertyIds.java
index 68c8756..b73278f 100644
--- a/car-lib/src/android/car/VehiclePropertyIds.java
+++ b/car-lib/src/android/car/VehiclePropertyIds.java
@@ -6812,6 +6812,47 @@
     public static final int LOW_SPEED_COLLISION_WARNING_ENABLED = 287313953;
 
     /**
+     * Low Speed Collision Warning State state.
+     *
+     * <p>Returns the current state of Low Speed Collision Warning. This property will always return
+     * a valid state defined in {@link android.car.hardware.property.LowSpeedCollisionWarningState}
+     * or {@link android.car.hardware.property.ErrorState}. This property is different from the
+     * pre-existing {@link VehiclePropertyIds#FORWARD_COLLISION_WARNING_ENABLED}, which applies to
+     * higher speed applications only. If the vehicle doesn't have a separate collision detection
+     * system for low speed environments, this property will not be implemented.
+     *
+     * <p>For the global area ID (0), the {@link
+     * android.car.hardware.property.AreaIdConfig#getSupportedEnumValues()} array obtained from
+     * {@link android.car.hardware.CarPropertyConfig#getAreaIdConfig(int)} specifies which states
+     * from {@link android.car.hardware.property.LowSpeedCollisionWarningState} and {@link
+     * android.car.hardware.property.ErrorState} are supported.
+     *
+     * <p>Property Config:
+     * <ul>
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_ACCESS_READ}
+     *  <li>{@link VehicleAreaType#VEHICLE_AREA_TYPE_GLOBAL}
+     *  <li>{@link android.car.hardware.CarPropertyConfig#VEHICLE_PROPERTY_CHANGE_MODE_ONCHANGE}
+     *  <li>{@code Integer} property type
+     * </ul>
+     *
+     * <p>Required Permission:
+     * <ul>
+     *  <li>Signature|Privileged permission {@link Car#PERMISSION_READ_ADAS_STATES} to read
+     *  property.
+     *  <li>Property is not writable.
+     * </ul>
+     *
+     * @data_enum {@link android.car.hardware.property.LowSpeedCollisionWarningState}
+     * @data_enum {@link ErrorState}
+     *
+     * @hide
+     */
+    @FlaggedApi(FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
+    @SystemApi
+    @RequiresPermission.Read(@RequiresPermission(Car.PERMISSION_READ_ADAS_STATES))
+    public static final int LOW_SPEED_COLLISION_WARNING_STATE = 289411106;
+
+    /**
      * @deprecated to prevent others from instantiating this class
      */
     @Deprecated
diff --git a/car-lib/src/android/car/hardware/property/LowSpeedCollisionWarningState.java b/car-lib/src/android/car/hardware/property/LowSpeedCollisionWarningState.java
new file mode 100644
index 0000000..c12e8e9
--- /dev/null
+++ b/car-lib/src/android/car/hardware/property/LowSpeedCollisionWarningState.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.car.hardware.property;
+
+import static android.car.feature.Flags.FLAG_ANDROID_VIC_VEHICLE_PROPERTIES;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+import com.android.car.internal.util.ConstantDebugUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to enumerate the state of {@link
+ * android.car.VehiclePropertyIds#LOW_SPEED_COLLISION_WARNING_STATE}.
+ *
+ * @hide
+ */
+@FlaggedApi(FLAG_ANDROID_VIC_VEHICLE_PROPERTIES)
+@SystemApi
+public final class LowSpeedCollisionWarningState {
+
+    /**
+     * This state is used as an alternative for any {@code LowSpeedCollisionWarningState} value that
+     * is not defined in the platform. Ideally, implementations of {@link
+     * android.car.VehiclePropertyIds#LOW_SPEED_COLLISION_WARNING_STATE} should not use this state.
+     * The framework can use this field to remain backwards compatible if {@code
+     * LowSpeedCollisionWarningState} is extended to include additional states.
+     */
+    public static final int OTHER = 0;
+    /**
+     * Low Speed Collision Warning is enabled and monitoring for potential collision, but no
+     * potential collision is detected.
+     */
+    public static final int NO_WARNING = 1;
+    /**
+     * Low Speed Collision Warning is enabled, detects a potential collision, and is actively
+     * warning the user.
+     */
+    public static final int WARNING = 2;
+
+    private LowSpeedCollisionWarningState() {}
+
+    /**
+     * Returns a user-friendly representation of {@code LowSpeedCollisionWarningState}.
+     */
+    @NonNull
+    public static String toString(
+            @LowSpeedCollisionWarningStateInt int lowSpeedCollisionWarningState) {
+        String lowSpeedCollisionWarningStateString = ConstantDebugUtils.toName(
+                LowSpeedCollisionWarningState.class, lowSpeedCollisionWarningState);
+        return (lowSpeedCollisionWarningStateString != null)
+                ? lowSpeedCollisionWarningStateString
+                : "0x" + Integer.toHexString(lowSpeedCollisionWarningState);
+    }
+
+    /** @hide */
+    @IntDef({OTHER, NO_WARNING, WARNING})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface LowSpeedCollisionWarningStateInt {}
+}
diff --git a/tests/android_car_api_test/src/android/car/apitest/LowSpeedCollisionWarningStateTest.java b/tests/android_car_api_test/src/android/car/apitest/LowSpeedCollisionWarningStateTest.java
new file mode 100644
index 0000000..1109eab
--- /dev/null
+++ b/tests/android_car_api_test/src/android/car/apitest/LowSpeedCollisionWarningStateTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.car.apitest;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@SmallTest
+@RunWith(Parameterized.class)
+public class LowSpeedCollisionWarningStateTest {
+    private final int mJavaConstantValue;
+    private final int mHalConstantValue;
+
+    public LowSpeedCollisionWarningStateTest(int javaConstantValue, int halConstantValue) {
+        mJavaConstantValue = javaConstantValue;
+        mHalConstantValue = halConstantValue;
+    }
+
+    @Parameterized.Parameters
+    public static Collection constantValues() {
+        return Arrays.asList(
+                new Object[][] {
+                        {
+                                android.car.hardware.property.LowSpeedCollisionWarningState.OTHER,
+                                android.hardware.automotive.vehicle.LowSpeedCollisionWarningState
+                                        .OTHER
+                        },
+                        {
+                                android.car.hardware.property.LowSpeedCollisionWarningState
+                                        .NO_WARNING,
+                                android.hardware.automotive.vehicle.LowSpeedCollisionWarningState
+                                        .NO_WARNING
+                        },
+                        {
+                                android.car.hardware.property.LowSpeedCollisionWarningState.WARNING,
+                                android.hardware.automotive.vehicle.LowSpeedCollisionWarningState
+                                        .WARNING
+                        },
+                });
+    }
+
+    @Test
+    public void testMatchWithVehicleHal() {
+        assertWithMessage("Java constant")
+                .that(mJavaConstantValue)
+                .isEqualTo(mHalConstantValue);
+    }
+}