Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f89021a2 authored by Eiji's avatar Eiji Committed by Android Build Cherrypicker Worker
Browse files

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
parent 245dead4
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -927,13 +927,15 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
    protected int handleVendorCommandWithId(HdmiCecMessage message) {
        byte[] params = message.getParams();
        int vendorId = HdmiUtils.threeBytesToInt(params);
        if (!mService.invokeVendorCommandListenersOnReceived(
                mDeviceType, message.getSource(), message.getDestination(), params, true)) {
            if (message.getDestination() == Constants.ADDR_BROADCAST
                    || message.getSource() == Constants.ADDR_UNREGISTERED) {
            Slog.v(TAG, "Wrong broadcast vendor command. Ignoring");
        } else if (!mService.invokeVendorCommandListenersOnReceived(
                mDeviceType, message.getSource(), message.getDestination(), params, true)) {
                Slog.v(TAG, "Broadcast vendor command with no listeners. Ignoring");
            } else {
                return Constants.ABORT_REFUSED;
            }
        }
        return Constants.HANDLED;
    }

+18 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;

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 class HdmiCecLocalDeviceTest {
    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);
    }
}