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

Commit 701ee593 authored by Jinsuk Kim's avatar Jinsuk Kim Committed by android-build-merger
Browse files

am 62a1e753: Merge "CEC: Handle <Active Source> arriving before...

am 62a1e753: Merge "CEC: Handle <Active Source> arriving before TvInputCallback.onAddInput" into lmp-mr1-dev automerge: 09d4e037
automerge: 764a1ba8

* commit '764a1ba8':
  CEC: Handle <Active Source> arriving before TvInputCallback.onAddInput
parents e1d1abc3 764a1ba8
Loading
Loading
Loading
Loading
+9 −11
Original line number Original line Diff line number Diff line
@@ -88,26 +88,24 @@ final class DelayedMessageBuffer {
     * Process messages from a given logical device. Called by
     * Process messages from a given logical device. Called by
     * {@link NewDeviceAction} actions when they finish adding the device
     * {@link NewDeviceAction} actions when they finish adding the device
     * information.
     * information.
     * <p>&lt;Active Source&gt; is not processed in this method but processed
     * <p>&lt;Active Source&gt; is processed only when the TV input is ready.
     * separately via {@link #processActiveSource()}.
     * If not, {@link #processActiveSource()} will be invoked later to handle it.
     *
     *
     * @param address logical address of CEC device which the messages to process
     * @param address logical address of CEC device which the messages to process
     *        are associated with
     *        are associated with
     */
     */
    void processMessagesForDevice(int address) {
    void processMessagesForDevice(int address) {
        HdmiLogger.debug("Processing message for address:" + address);
        HdmiLogger.debug("Checking message for address:" + address);
        for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
        for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
            HdmiCecMessage message = iter.next();
            HdmiCecMessage message = iter.next();
            if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE) {
            if (message.getSource() != address) continue;
                continue;
            if (message.getOpcode() == Constants.MESSAGE_ACTIVE_SOURCE
            }
                    && !mDevice.isInputReady(HdmiDeviceInfo.idForCecDevice(address))) continue;
            if (message.getSource() == address) {
            mDevice.onMessage(message);
            mDevice.onMessage(message);
            HdmiLogger.debug("Processing message:" + message);
            HdmiLogger.debug("Processing message:" + message);
            iter.remove();
            iter.remove();
        }
        }
    }
    }
    }


    /**
    /**
     * Process &lt;Active Source&gt;.
     * Process &lt;Active Source&gt;.
+11 −0
Original line number Original line Diff line number Diff line
@@ -190,6 +190,17 @@ abstract class HdmiCecLocalDevice {
     */
     */
    protected abstract void setPreferredAddress(int addr);
    protected abstract void setPreferredAddress(int addr);


    /**
     * Returns true if the TV input associated with the CEC device is ready
     * to accept further processing such as input switching. This is used
     * to buffer certain CEC commands and process it later if the input is not
     * ready yet. For other types of local devices(non-TV), this method returns
     * true by default to let the commands be processed right away.
     */
    protected boolean isInputReady(int deviceId) {
        return true;
    }

    /**
    /**
     * Dispatch incoming message.
     * Dispatch incoming message.
     *
     *
+46 −2
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Collections;
import java.util.Iterator;
import java.util.Iterator;
import java.util.List;
import java.util.List;
import java.util.HashMap;


/**
/**
 * Represent a logical device of type TV residing in Android system.
 * Represent a logical device of type TV residing in Android system.
@@ -143,12 +144,44 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        public void onInputAdded(String inputId) {
        public void onInputAdded(String inputId) {
            TvInputInfo tvInfo = mService.getTvInputManager().getTvInputInfo(inputId);
            TvInputInfo tvInfo = mService.getTvInputManager().getTvInputInfo(inputId);
            HdmiDeviceInfo info = tvInfo.getHdmiDeviceInfo();
            HdmiDeviceInfo info = tvInfo.getHdmiDeviceInfo();
            if (info != null && info.isCecDevice()) {
            if (info == null) return;
                mDelayedMessageBuffer.processActiveSource(info.getLogicalAddress());
            addTvInput(inputId, info.getId());
            if (info.isCecDevice()) {
                processDelayedActiveSource(info.getLogicalAddress());
            }
            }
        }
        }

        @Override
        public void onInputRemoved(String inputId) {
            removeTvInput(inputId);
        }
    };
    };


    // Keeps the mapping (TV input ID, HDMI device ID) to keep track of the TV inputs ready to
    // accept input switching request from HDMI devices. Requests for which the corresponding
    // input ID is not yet registered by TV input framework need to be buffered for delayed
    // processing.
    private final HashMap<String, Integer> mTvInputs = new HashMap<>();

    @ServiceThreadOnly
    private void addTvInput(String inputId, int deviceId) {
        assertRunOnServiceThread();
        mTvInputs.put(inputId, deviceId);
    }

    @ServiceThreadOnly
    private void removeTvInput(String inputId) {
        assertRunOnServiceThread();
        mTvInputs.remove(inputId);
    }

    @Override
    @ServiceThreadOnly
    protected boolean isInputReady(int deviceId) {
        assertRunOnServiceThread();
        return mTvInputs.containsValue(deviceId);
    }

    HdmiCecLocalDeviceTv(HdmiControlService service) {
    HdmiCecLocalDeviceTv(HdmiControlService service) {
        super(service, HdmiDeviceInfo.DEVICE_TV);
        super(service, HdmiDeviceInfo.DEVICE_TV);
        mPrevPortId = Constants.INVALID_PORT_ID;
        mPrevPortId = Constants.INVALID_PORT_ID;
@@ -168,6 +201,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
        mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
                mAddress, mService.getVendorId()));
                mAddress, mService.getVendorId()));
        mCecSwitches.add(mService.getPhysicalAddress());  // TV is a CEC switch too.
        mCecSwitches.add(mService.getPhysicalAddress());  // TV is a CEC switch too.
        mTvInputs.clear();
        mSkipRoutingControl = (reason == HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
        mSkipRoutingControl = (reason == HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
        launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
        launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
                reason != HdmiControlService.INITIATED_BY_BOOT_UP);
                reason != HdmiControlService.INITIATED_BY_BOOT_UP);
@@ -447,8 +481,12 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress);
        HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress);
        if (info == null) {
        if (info == null) {
            if (!handleNewDeviceAtTheTailOfActivePath(physicalAddress)) {
            if (!handleNewDeviceAtTheTailOfActivePath(physicalAddress)) {
                HdmiLogger.debug("Device info not found: %X; buffering the command", logicalAddress);
                mDelayedMessageBuffer.add(message);
                mDelayedMessageBuffer.add(message);
            }
            }
        } else if (!isInputReady(info.getId())) {
            HdmiLogger.debug("Input not ready for device: %X; buffering the command", info.getId());
            mDelayedMessageBuffer.add(message);
        } else {
        } else {
            ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
            ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
            ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
            ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
@@ -1776,6 +1814,12 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        mDelayedMessageBuffer.processMessagesForDevice(address);
        mDelayedMessageBuffer.processMessagesForDevice(address);
    }
    }


    @ServiceThreadOnly
    void processDelayedActiveSource(int address) {
        assertRunOnServiceThread();
        mDelayedMessageBuffer.processActiveSource(address);
    }

    @Override
    @Override
    protected void dump(final IndentingPrintWriter pw) {
    protected void dump(final IndentingPrintWriter pw) {
        super.dump(pw);
        super.dump(pw);