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

Commit 89e93af6 authored by Amy's avatar Amy Committed by shubang
Browse files

Add HDMI device info into TIF once receive report Physical Address or

Set Osd Name from a new device.

ag/5268266

Test: local tested.
Bug: 117291910
Change-Id: Ibc9b7071309213bc87ec697dd6902d7c358ba735
parent a00e1184
Loading
Loading
Loading
Loading
+90 −3
Original line number Diff line number Diff line
@@ -30,12 +30,15 @@ import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.tv.TvContract;
import android.os.SystemProperties;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.hdmi.Constants.AudioCodec;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;

/**
@@ -101,8 +104,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
    final void addCecDevice(HdmiDeviceInfo info) {
        assertRunOnServiceThread();
        HdmiDeviceInfo old = addDeviceInfo(info);
        if (info.getLogicalAddress() == mAddress) {
        if (info.getPhysicalAddress() == mService.getPhysicalAddress()) {
            // The addition of the device itself should not be notified.
            // Note that different logical address could still be the same local device.
            return;
        }
        if (old == null) {
@@ -127,6 +131,23 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
        invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
    }

    /**
     * Called when a device is updated.
     *
     * @param info device info of the updating device.
     */
    @ServiceThreadOnly
    final void updateCecDevice(HdmiDeviceInfo info) {
        assertRunOnServiceThread();
        HdmiDeviceInfo old = addDeviceInfo(info);

        if (old == null) {
            invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE);
        } else if (!old.equals(info)) {
            invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE);
        }
    }

    /**
    * Add a new {@link HdmiDeviceInfo}. It returns old device info which has the same
     * logical address as new device info's.
@@ -136,7 +157,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
     *         that has the same logical address as new one has.
     */
    @ServiceThreadOnly
    private HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) {
    @VisibleForTesting
    protected HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) {
        assertRunOnServiceThread();
        HdmiDeviceInfo oldDeviceInfo = getCecDeviceInfo(deviceInfo.getLogicalAddress());
        if (oldDeviceInfo != null) {
@@ -262,6 +284,71 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
                Constants.PROPERTY_PREFERRED_ADDRESS_AUDIO_SYSTEM, String.valueOf(addr));
    }

    @Override
    @ServiceThreadOnly
    protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
        assertRunOnServiceThread();
        int path = HdmiUtils.twoBytesToInt(message.getParams());
        int address = message.getSource();
        int type = message.getParams()[2];

        // Ignore if [Device Discovery Action] is going on.
        if (hasAction(DeviceDiscoveryAction.class)) {
            Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message);
            return true;
        }

        // Update the device info with TIF, note that the same device info could have added in
        // device discovery and we do not want to override it with default OSD name. Therefore we
        // need the following check to skip redundant device info updating.
        HdmiDeviceInfo oldDevice = getCecDeviceInfo(address);
        if (oldDevice == null || oldDevice.getPhysicalAddress() != path) {
            addCecDevice(new HdmiDeviceInfo(
                    address, path, mService.pathToPortId(path), type,
                    Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(address)));
            // if we are adding a new device info, send out a give osd name command
            // to update the name of the device in TIF
            mService.sendCecCommand(
                    HdmiCecMessageBuilder.buildGiveOsdNameCommand(mAddress, address));
            return true;
        }

        Slog.w(TAG, "Device info exists. Not updating on Physical Address.");
        return true;
    }

    @Override
    @ServiceThreadOnly
    protected boolean handleSetOsdName(HdmiCecMessage message) {
        int source = message.getSource();
        String osdName;
        HdmiDeviceInfo deviceInfo = getCecDeviceInfo(source);
        // If the device is not in device list, ignore it.
        if (deviceInfo == null) {
            Slog.i(TAG, "No source device info for <Set Osd Name>." + message);
            return true;
        }
        try {
            osdName = new String(message.getParams(), "US-ASCII");
        } catch (UnsupportedEncodingException e) {
            Slog.e(TAG, "Invalid <Set Osd Name> request:" + message, e);
            return true;
        }

        if (deviceInfo.getDisplayName().equals(osdName)) {
            Slog.d(TAG, "Ignore incoming <Set Osd Name> having same osd name:" + message);
            return true;
        }

        Slog.d(TAG, "Updating device OSD name from "
                + deviceInfo.getDisplayName()
                + " to " + osdName);
        updateCecDevice(new HdmiDeviceInfo(deviceInfo.getLogicalAddress(),
                deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(),
                deviceInfo.getDeviceType(), deviceInfo.getVendorId(), osdName));
        return true;
    }

    @Override
    @ServiceThreadOnly
    protected boolean handleReportAudioStatus(HdmiCecMessage message) {
+89 −0
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.server.hdmi;

import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE;

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;
@@ -25,6 +28,7 @@ import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;

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

import android.hardware.hdmi.HdmiDeviceInfo;
import android.media.AudioManager;
import android.os.Looper;
import android.os.SystemProperties;
@@ -64,6 +68,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
    private int mMusicMaxVolume;
    private boolean mMusicMute;
    private int mAvrPhysicalAddress;
    private int mInvokeDeviceEventState;
    private HdmiDeviceInfo mDeviceInfo;

    @Before
    public void setUp() {
@@ -127,6 +133,18 @@ public class HdmiCecLocalDeviceAudioSystemTest {

                @Override
                void wakeUp() {}

                @Override
                void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) {
                    mDeviceInfo = device;
                    mInvokeDeviceEventState = status;
                }

                @Override
                int pathToPortId(int path) {
                    // port id is not useful for the test right now
                    return 1;
                }
            };

        mMyLooper = mTestLooper.getLooper();
@@ -157,6 +175,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
        mNativeWrapper.setPhysicalAddress(mAvrPhysicalAddress);
        SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true");
        SystemProperties.set(Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, "true");
        mInvokeDeviceEventState = 0;
        mDeviceInfo = null;
    }

    @Test
@@ -611,4 +631,73 @@ public class HdmiCecLocalDeviceAudioSystemTest {
        mTestLooper.dispatchAll();
        assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
    }

    @Test
    public void updateCecDevice_deviceNotExists_addDevice() {
        assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE);
        HdmiDeviceInfo newDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));

        mHdmiCecLocalDeviceAudioSystem.updateCecDevice(newDevice);
        assertThat(mDeviceInfo).isEqualTo(newDevice);
        assertThat(mHdmiCecLocalDeviceAudioSystem
            .getCecDeviceInfo(newDevice.getLogicalAddress())).isEqualTo(newDevice);
        assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE);
    }

    @Test
    public void updateCecDevice_deviceExists_doNothing() {
        mInvokeDeviceEventState = 0;
        HdmiDeviceInfo oldDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));
        mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice);

        mHdmiCecLocalDeviceAudioSystem.updateCecDevice(oldDevice);
        assertThat(mInvokeDeviceEventState).isEqualTo(0);
    }

    @Test
    public void updateCecDevice_deviceInfoDifferent_updateDevice() {
        assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_UPDATE_DEVICE);
        HdmiDeviceInfo oldDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));
        mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice);

        HdmiDeviceInfo differentDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2100, 4, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));

        mHdmiCecLocalDeviceAudioSystem.updateCecDevice(differentDevice);
        assertThat(mDeviceInfo).isEqualTo(differentDevice);
        assertThat(mHdmiCecLocalDeviceAudioSystem
            .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice);
        assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_UPDATE_DEVICE);
    }

    @Test
    public void handleReportPhysicalAddress_differentPath_addDevice() {
        assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE);
        HdmiDeviceInfo oldDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2100, 2, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));
        mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice);

        HdmiDeviceInfo differentDevice = new HdmiDeviceInfo(
                ADDR_PLAYBACK_1, 0x2200, 1, HdmiDeviceInfo.DEVICE_PLAYBACK,
                Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(ADDR_PLAYBACK_1));
        HdmiCecMessage reportPhysicalAddress = HdmiCecMessageBuilder
                .buildReportPhysicalAddressCommand(
                        ADDR_PLAYBACK_1, 0x2200, HdmiDeviceInfo.DEVICE_PLAYBACK);
        mHdmiCecLocalDeviceAudioSystem.handleReportPhysicalAddress(reportPhysicalAddress);

        mHdmiCecLocalDeviceAudioSystem.addDeviceInfo(oldDevice);
        mTestLooper.dispatchAll();
        assertThat(mDeviceInfo).isEqualTo(differentDevice);
        assertThat(mHdmiCecLocalDeviceAudioSystem
            .getCecDeviceInfo(differentDevice.getLogicalAddress())).isEqualTo(differentDevice);
        assertThat(mInvokeDeviceEventState).isEqualTo(DEVICE_EVENT_ADD_DEVICE);
    }
}