Merge changes from topic "vhal_static_lib"

* changes:
  Define a makefile for vhal static libs.
  Make HVAC dep properties unavailable to get when power is off.
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
new file mode 100644
index 0000000..f4a7cd1
--- /dev/null
+++ b/automotive/vehicle/Android.bp
@@ -0,0 +1,26 @@
+/*
+ * 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "VehicleHalInterfaceDefaults",
+    static_libs: [
+        "android.hardware.automotive.vehicle-V2-ndk",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/Android.bp
index 73f7df0..d2c5145 100644
--- a/automotive/vehicle/aidl/impl/Android.bp
+++ b/automotive/vehicle/aidl/impl/Android.bp
@@ -19,13 +19,6 @@
 }
 
 cc_defaults {
-    name: "VehicleHalInterfaceDefaults",
-    static_libs: [
-        "android.hardware.automotive.vehicle-V2-ndk",
-    ],
-}
-
-cc_defaults {
     name: "VehicleHalDefaults",
     static_libs: [
         "android-automotive-large-parcelable-lib",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 5e35b0f..956c7c0 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -194,7 +194,7 @@
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
     ValueResultType getEchoReverseBytes(
             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
-    bool isHvacPropAndHvacNotAvailable(int32_t propId);
+    bool isHvacPropAndHvacNotAvailable(int32_t propId) const;
 
     std::unordered_map<int32_t, ConfigDeclaration> loadConfigDeclarations();
 
@@ -236,6 +236,7 @@
             const aidl::android::hardware::automotive::vehicle::SetValueRequest& request);
 
     std::string genFakeDataCommand(const std::vector<std::string>& options);
+    void sendHvacPropertiesCurrentValues();
 
     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
             aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 6e085db..a9dced9 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -295,7 +295,7 @@
     return {};
 }
 
-bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) {
+bool FakeVehicleHardware::isHvacPropAndHvacNotAvailable(int32_t propId) const {
     std::unordered_set<int32_t> powerProps(std::begin(HVAC_POWER_PROPERTIES),
                                            std::end(HVAC_POWER_PROPERTIES));
     if (powerProps.count(propId)) {
@@ -366,6 +366,11 @@
         return getUserHalProp(value);
     }
 
+    if (isHvacPropAndHvacNotAvailable(propId)) {
+        *isSpecialValue = true;
+        return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
+    }
+
     switch (propId) {
         case OBD2_FREEZE_FRAME:
             *isSpecialValue = true;
@@ -408,6 +413,27 @@
     return std::move(gotValue);
 }
 
+void FakeVehicleHardware::sendHvacPropertiesCurrentValues() {
+    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+        int powerPropId = HVAC_POWER_PROPERTIES[i];
+        auto powerPropResults = mServerSidePropStore->readValuesForProperty(powerPropId);
+        if (!powerPropResults.ok()) {
+            ALOGW("failed to get power prop 0x%x, error: %s", powerPropId,
+                  getErrorMsg(powerPropResults).c_str());
+            continue;
+        }
+        auto& powerPropValues = powerPropResults.value();
+        for (size_t j = 0; j < powerPropValues.size(); j++) {
+            auto powerPropValue = std::move(powerPropValues[j]);
+            powerPropValue->status = VehiclePropertyStatus::AVAILABLE;
+            powerPropValue->timestamp = elapsedRealtimeNano();
+            // This will trigger a property change event for the current hvac property value.
+            mServerSidePropStore->writeValue(std::move(powerPropValue), /*updateStatus=*/true,
+                                             VehiclePropertyStore::EventMode::ALWAYS);
+        }
+    }
+}
+
 VhalResult<void> FakeVehicleHardware::maybeSetSpecialValue(const VehiclePropValue& value,
                                                            bool* isSpecialValue) {
     *isSpecialValue = false;
@@ -419,6 +445,13 @@
         return setUserHalProp(value);
     }
 
+    if (propId == toInt(VehicleProperty::HVAC_POWER_ON) && value.value.int32Values.size() == 1 &&
+        value.value.int32Values[0] == 1) {
+        // If we are turning HVAC power on, send current hvac property values through on change
+        // event.
+        sendHvacPropertiesCurrentValues();
+    }
+
     if (isHvacPropAndHvacNotAvailable(propId)) {
         *isSpecialValue = true;
         return StatusError(StatusCode::NOT_AVAILABLE) << "hvac not available";
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 79990ad..67b1aa4 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -61,6 +61,7 @@
 using ::android::base::ScopedLockAssertion;
 using ::android::base::StringPrintf;
 using ::android::base::unexpected;
+using ::testing::AnyOfArray;
 using ::testing::ContainerEq;
 using ::testing::ContainsRegex;
 using ::testing::Eq;
@@ -1140,6 +1141,71 @@
     EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
 }
 
+TEST_F(FakeVehicleHardwareTest, testGetHvacPropNotAvailable) {
+    StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                  .areaId = HVAC_ALL,
+                                                  .value.int32Values = {0}});
+
+    ASSERT_EQ(status, StatusCode::OK);
+
+    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+        int powerPropId = HVAC_POWER_PROPERTIES[i];
+        auto getValueResult = getValue(VehiclePropValue{
+                .prop = powerPropId,
+                .areaId = HVAC_ALL,
+        });
+
+        EXPECT_FALSE(getValueResult.ok());
+        EXPECT_EQ(getValueResult.error(), StatusCode::NOT_AVAILABLE);
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testSetHvacPropNotAvailable) {
+    StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                  .areaId = HVAC_ALL,
+                                                  .value.int32Values = {0}});
+
+    ASSERT_EQ(status, StatusCode::OK);
+
+    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+        int powerPropId = HVAC_POWER_PROPERTIES[i];
+        status = setValue(VehiclePropValue{
+                .prop = powerPropId,
+                .areaId = HVAC_ALL,
+        });
+
+        EXPECT_EQ(status, StatusCode::NOT_AVAILABLE);
+    }
+}
+
+TEST_F(FakeVehicleHardwareTest, testHvacPowerOnSendCurrentHvacPropValues) {
+    StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                                  .areaId = HVAC_ALL,
+                                                  .value.int32Values = {0}});
+
+    ASSERT_EQ(status, StatusCode::OK);
+
+    clearChangedProperties();
+
+    status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
+                                       .areaId = HVAC_ALL,
+                                       .value.int32Values = {1}});
+
+    auto events = getChangedProperties();
+    // If we turn HVAC power on, we expect to receive one property event for every HVAC prop areas
+    // plus one event for HVAC_POWER_ON.
+    std::vector<int32_t> changedPropIds;
+    for (size_t i = 0; i < sizeof(HVAC_POWER_PROPERTIES) / sizeof(int32_t); i++) {
+        changedPropIds.push_back(HVAC_POWER_PROPERTIES[i]);
+    }
+    changedPropIds.push_back(toInt(VehicleProperty::HVAC_POWER_ON));
+    ASSERT_EQ(events.size(), changedPropIds.size());
+    for (const auto& event : events) {
+        EXPECT_EQ(event.areaId, HVAC_ALL);
+        EXPECT_THAT(event.prop, AnyOfArray(changedPropIds));
+    }
+}
+
 TEST_F(FakeVehicleHardwareTest, testGetUserPropertySetOnly) {
     for (VehicleProperty prop : std::vector<VehicleProperty>({
                  VehicleProperty::INITIAL_USER_INFO,
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
new file mode 100644
index 0000000..b15b26c
--- /dev/null
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -0,0 +1,18 @@
+# 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.
+
+# This make file contains the latest version of static cpp libraries for VHAL
+# interface and VHAL properties.
+
+LOCAL_STATIC_LIBRARIES += android.hardware.automotive.vehicle-V2-ndk