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

Commit c6bc7a25 authored by Paul Colta's avatar Paul Colta Committed by Gerrit Code Review
Browse files

Merge "HDMI: Process buffered <Active Source> faster on TVs" into main

parents 28501b72 87fb3596
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.server.hdmi;

import android.hardware.hdmi.HdmiDeviceInfo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Buffer storage to keep incoming messages for later processing. Used to
@@ -83,6 +85,16 @@ final class DelayedMessageBuffer {
        return false;
    }

    List<HdmiCecMessage> getBufferedMessagesWithOpcode(int opcode) {
        List<HdmiCecMessage> messages = new ArrayList<>();
        for (HdmiCecMessage message : mBuffer) {
            if (message.getOpcode() == opcode) {
                messages.add(message);
            }
        }
        return messages;
    }

    void processAllMessages() {
        // Use the copied buffer.
        ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<>(mBuffer);
+27 −1
Original line number Diff line number Diff line
@@ -205,7 +205,9 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
        resetSelectRequestBuffer();
        launchDeviceDiscovery();
        startQueuedActions();
        if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) {
        List<HdmiCecMessage> bufferedActiveSource = mDelayedMessageBuffer
                .getBufferedMessagesWithOpcode(Constants.MESSAGE_ACTIVE_SOURCE);
        if (bufferedActiveSource.isEmpty()) {
            addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() {
                @Override
                public void onComplete(int result) {
@@ -220,7 +222,31 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
                    }
                }
            }));
        } else {
            addCecDeviceForBufferedActiveSource(bufferedActiveSource.get(0));
        }
    }

    // Add a new CEC device with known information from the buffered <Active Source> message. This
    // helps TvInputCallback#onInputAdded to be called such that the message can be processed and
    // the TV to switch to the new active input.
    @ServiceThreadOnly
    private void addCecDeviceForBufferedActiveSource(HdmiCecMessage bufferedActiveSource) {
        assertRunOnServiceThread();
        if (bufferedActiveSource == null) {
            return;
        }
        int source = bufferedActiveSource.getSource();
        int physicalAddress = HdmiUtils.twoBytesToInt(bufferedActiveSource.getParams());
        List<Integer> deviceTypes = HdmiUtils.getTypeFromAddress(source);
        HdmiDeviceInfo newDevice = HdmiDeviceInfo.cecDeviceBuilder()
                .setLogicalAddress(source)
                .setPhysicalAddress(physicalAddress)
                .setDisplayName(HdmiUtils.getDefaultDeviceName(source))
                .setDeviceType(deviceTypes.get(0))
                .setVendorId(Constants.VENDOR_ID_UNKNOWN)
                .build();
        mService.getHdmiCecNetwork().addCecDevice(newDevice);
    }

    @ServiceThreadOnly
+29 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE;
import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;

import static com.google.common.truth.Truth.assertThat;

@@ -1907,4 +1908,32 @@ public class HdmiCecLocalDeviceTvTest {
        // NewDeviceAction did not start and <Give OSD Name> was not sent.
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveOsdName);
    }

    @Test
    public void onOneTouchPlay_wakeUp_addCecDevice() {
        assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
                .isEmpty();
        mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
                HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
                HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED);
        mPowerManager.setInteractive(false);
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
                mTvLogicalAddress);
        HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
                0x1000);
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(activeSource)).isEqualTo(
                Constants.HANDLED);
        mTestLooper.dispatchAll();
        assertThat(mPowerManager.isInteractive()).isTrue();

        // FakePowerManagerWrapper#wakeUp() doesn't broadcast Intent.ACTION_SCREEN_ON so we have to
        // manually call this method.
        mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
        mTestLooper.dispatchAll();
        assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
                .hasSize(1);
    }
}