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

Commit d4a94db1 authored by Jinsuk Kim's avatar Jinsuk Kim
Browse files

CEC: Bug fixes for vendor-specific command handling

- Add sendStandby()
- Respond with <Feature Abort>[INCORRECT_MODE] when the listener
  is not ready

Bug: 17379243
Bug: 17358887
Change-Id: I26a4157a70f11206978763fbbe69e4190e3e1d5c
parent 753fcc8a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ interface IHdmiControlService {
    void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
            boolean hasVendorId);
    void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
    void sendStandby(int deviceType, int deviceId);
    void setHdmiRecordListener(IHdmiRecordListener callback);
    void startOneTouchRecord(int recorderAddress, in byte[] recordSource);
    void stopOneTouchRecord(int recorderAddress);
+14 −3
Original line number Diff line number Diff line
@@ -517,8 +517,12 @@ abstract class HdmiCecLocalDevice {
    }

    protected boolean handleVendorCommand(HdmiCecMessage message) {
        mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
                message.getParams(), false);
        if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(),
                message.getParams(), false)) {
            // Vendor command listener may not have been registered yet. Respond with
            // <Feature Abort> [NOT_IN_CORRECT_MODE] so that the sender can try again later.
            mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
        }
        return true;
    }

@@ -526,7 +530,10 @@ abstract class HdmiCecLocalDevice {
        byte[] params = message.getParams();
        int vendorId = HdmiUtils.threeBytesToInt(params);
        if (vendorId == mService.getVendorId()) {
            mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params, true);
            if (!mService.invokeVendorCommandListeners(mDeviceType, message.getSource(), params,
                    true)) {
                mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
            }
        } else if (message.getDestination() != Constants.ADDR_BROADCAST &&
                message.getSource() != Constants.ADDR_UNREGISTERED) {
            Slog.v(TAG, "Wrong direct vendor command. Replying with <Feature Abort>");
@@ -537,6 +544,10 @@ abstract class HdmiCecLocalDevice {
        return true;
    }

    protected void sendStandby(int deviceId) {
        // Do nothing.
    }

    protected boolean handleSetOsdName(HdmiCecMessage message) {
        // The default behavior of <Set Osd Name> is doing nothing.
        return true;
+10 −0
Original line number Diff line number Diff line
@@ -1651,6 +1651,16 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        return true;
    }

    @Override
    protected void sendStandby(int deviceId) {
        HdmiDeviceInfo targetDevice = mDeviceInfos.get(deviceId);
        if (targetDevice == null) {
            return;
        }
        int targetAddress = targetDevice.getLogicalAddress();
        mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress));
    }

    @Override
    protected void dump(final IndentingPrintWriter pw) {
        super.dump(pw);
+21 −1
Original line number Diff line number Diff line
@@ -1344,6 +1344,22 @@ public final class HdmiControlService extends SystemService {
            });
        }

        @Override
        public void sendStandby(final int deviceType, final int deviceId) {
            enforceAccessPermission();
            runOnServiceThread(new Runnable() {
                @Override
                public void run() {
                    HdmiCecLocalDevice device = mCecController.getLocalDevice(deviceType);
                    if (device == null) {
                        Slog.w(TAG, "Local device not available");
                        return;
                    }
                    device.sendStandby(deviceId);
                }
            });
        }

        @Override
        public void setHdmiRecordListener(IHdmiRecordListener listener) {
            HdmiControlService.this.setHdmiRecordListener(listener);
@@ -1869,9 +1885,12 @@ public final class HdmiControlService extends SystemService {
        }
    }

    void invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
    boolean invokeVendorCommandListeners(int deviceType, int srcAddress, byte[] params,
            boolean hasVendorId) {
        synchronized (mLock) {
            if (mVendorCommandListenerRecords.isEmpty()) {
                return false;
            }
            for (VendorCommandListenerRecord record : mVendorCommandListenerRecords) {
                if (record.mDeviceType != deviceType) {
                    continue;
@@ -1882,6 +1901,7 @@ public final class HdmiControlService extends SystemService {
                    Slog.e(TAG, "Failed to notify vendor command reception", e);
                }
            }
            return true;
        }
    }