HDMI: Fix broadcast vendor command handling error

HDMI CEC spec allows broadcasted <Vendor Command With ID> but it is always ignored regardless of listener registration.
Fix to allow broadcasted <Vendor Command With ID> and ignore it only when there is no listener registration.

Bug: 364774754
Test: atest com.android.server.hdmi
Merged-In: Ica6a40bf99a30179344ab51e1f1db5e2456abc82
Change-Id: Ica6a40bf99a30179344ab51e1f1db5e2456abc82
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 81204ef..a8d5696 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -927,12 +927,14 @@
     protected int handleVendorCommandWithId(HdmiCecMessage message) {
         byte[] params = message.getParams();
         int vendorId = HdmiUtils.threeBytesToInt(params);
-        if (message.getDestination() == Constants.ADDR_BROADCAST
-                || message.getSource() == Constants.ADDR_UNREGISTERED) {
-            Slog.v(TAG, "Wrong broadcast vendor command. Ignoring");
-        } else if (!mService.invokeVendorCommandListenersOnReceived(
+        if (!mService.invokeVendorCommandListenersOnReceived(
                 mDeviceType, message.getSource(), message.getDestination(), params, true)) {
-            return Constants.ABORT_REFUSED;
+            if (message.getDestination() == Constants.ADDR_BROADCAST
+                    || message.getSource() == Constants.ADDR_UNREGISTERED) {
+                Slog.v(TAG, "Broadcast vendor command with no listeners. Ignoring");
+            } else {
+                return Constants.ABORT_REFUSED;
+            }
         }
         return Constants.HANDLED;
     }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index 3dd8312..44fc387 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -19,6 +19,7 @@
 
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
+import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
 import static com.android.server.hdmi.Constants.ADDR_TV;
 import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID;
@@ -520,21 +521,32 @@
     public void handleVendorCommand_notHandled() {
         HdmiCecMessage vendorCommand = HdmiCecMessageBuilder.buildVendorCommand(ADDR_TV,
                 ADDR_PLAYBACK_1, new byte[]{0});
-        mNativeWrapper.onCecMessage(vendorCommand);
+        @Constants.HandleMessageResult int result =
+                mHdmiLocalDevice.handleVendorCommand(vendorCommand);
         mTestLooper.dispatchAll();
 
-        HdmiCecMessageBuilder.buildFeatureAbortCommand(ADDR_PLAYBACK_1, ADDR_TV,
-                vendorCommand.getOpcode(), Constants.ABORT_REFUSED);
+        assertEquals(Constants.ABORT_REFUSED, result);
     }
 
     @Test
     public void handleVendorCommandWithId_notHandled_Cec14() {
         HdmiCecMessage vendorCommand = HdmiCecMessageBuilder.buildVendorCommandWithId(ADDR_TV,
                 ADDR_PLAYBACK_1, 0x1234, new byte[]{0});
-        mNativeWrapper.onCecMessage(vendorCommand);
+        @Constants.HandleMessageResult int result =
+                mHdmiLocalDevice.handleVendorCommandWithId(vendorCommand);
         mTestLooper.dispatchAll();
 
-        HdmiCecMessageBuilder.buildFeatureAbortCommand(ADDR_PLAYBACK_1, ADDR_TV,
-                vendorCommand.getOpcode(), Constants.ABORT_REFUSED);
+        assertEquals(Constants.ABORT_REFUSED, result);
+    }
+
+    @Test
+    public void handleVendorCommandWithId_broadcasted_handled() {
+        HdmiCecMessage vendorCommand = HdmiCecMessageBuilder.buildVendorCommandWithId(ADDR_TV,
+                ADDR_BROADCAST, 0x1234, new byte[]{0});
+        @Constants.HandleMessageResult int result =
+                mHdmiLocalDevice.handleVendorCommandWithId(vendorCommand);
+        mTestLooper.dispatchAll();
+
+        assertEquals(Constants.HANDLED, result);
     }
 }