Merge "Actually add DimmingStage to client target properties" into tm-dev
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 097257e..a78d989 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -211,10 +211,16 @@
         case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED):
             [[fallthrough]];
         case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
-            // CPMS is in WAIT_FOR_VHAL state, simply move to ON
-            // Send back to HAL
-            // ALWAYS update status for generated property value
+            // CPMS is in WAIT_FOR_VHAL state, simply move to ON and send back to HAL.
+            // Must erase existing state because in the case when Car Service crashes, the power
+            // state would already be ON when we receive WAIT_FOR_VHAL and thus new property change
+            // event would be generated. However, Car Service always expect a property change event
+            // even though there is not actual state change.
+            mServerSidePropStore->removeValuesForProperty(
+                    toInt(VehicleProperty::AP_POWER_STATE_REQ));
             prop = createApPowerStateReq(VehicleApPowerStateReq::ON);
+
+            // ALWAYS update status for generated property value
             if (auto writeResult =
                         mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
                 !writeResult.ok()) {
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 3dae9fc..6259f96 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -924,6 +924,32 @@
             return info.param.name;
         });
 
+TEST_F(FakeVehicleHardwareTest, testSetWaitForVhalAfterCarServiceCrash) {
+    int32_t propId = toInt(VehicleProperty::AP_POWER_STATE_REPORT);
+    VehiclePropValue request = VehiclePropValue{
+            .prop = propId,
+            .value.int32Values = {toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL)},
+    };
+    ASSERT_EQ(setValue(request), StatusCode::OK) << "failed to set property " << propId;
+
+    // Clear existing events.
+    clearChangedProperties();
+
+    // Simulate a Car Service crash, Car Service would restart and send the message again.
+    ASSERT_EQ(setValue(request), StatusCode::OK) << "failed to set property " << propId;
+
+    std::vector<VehiclePropValue> events = getChangedProperties();
+    // Even though the state is already ON, we should receive another ON event.
+    ASSERT_EQ(events.size(), 1u);
+    // Erase the timestamp for comparison.
+    events[0].timestamp = 0;
+    ASSERT_EQ(events[0], (VehiclePropValue{
+                                 .prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
+                                 .status = VehiclePropertyStatus::AVAILABLE,
+                                 .value.int32Values = {toInt(VehicleApPowerStateReq::ON), 0},
+                         }));
+}
+
 TEST_F(FakeVehicleHardwareTest, testGetObd2FreezeFrame) {
     int64_t timestamp = elapsedRealtimeNano();
 
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 0033fee..d364371 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 interface IBluetoothAudioPort {
   android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
-  void startStream();
+  void startStream(boolean isLowLatency);
   void stopStream();
   void suspendStream();
   void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 9f8007b..4ddf645 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -47,8 +47,11 @@
      * This indicates that the caller of this method has opened the data path
      * and wants to start an audio stream. The caller must wait for a
      * IBluetoothAudioProvider.streamStarted(Status) call.
+     *
+     * @param isLowLatency true if the stream being started with the latency
+     * control mechanism.
      */
-    void startStream();
+    void startStream(boolean isLowLatency);
 
     /**
      * This indicates that the caller of this method wants to stop the audio
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 0407751..18352a0 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -138,7 +138,7 @@
  public:
   BluetoothAudioPort() {}
 
-  ndk::ScopedAStatus startStream() { return ScopedAStatus::ok(); }
+  ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
 
   ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 7187828..e700e7e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -198,7 +198,7 @@
                << " has NO session";
     return false;
   }
-  auto hal_retval = stack_iface_->startStream();
+  auto hal_retval = stack_iface_->startStream(false);
   if (!hal_retval.isOk()) {
     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
                  << toString(session_type_) << " failed";
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 74a8a57..68ec7e8 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1655,7 +1655,7 @@
         } else {
             const auto errors = mReader.takeErrors();
             ASSERT_EQ(1, errors.size());
-            EXPECT_EQ(EX_UNSUPPORTED_OPERATION, errors[0].errorCode);
+            EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
 
             const auto changedTypes = mReader.takeChangedCompositionTypes(display.getDisplayId());
             ASSERT_EQ(1u, changedTypes.size());