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

Commit 1cfcb103 authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Introduce backup logical addresses

Rename reserved logical addresses to backup and handle address
allocation for backup addresses if required.

Bug: 166227089
Test: atest com.android.server.hdmi
Change-Id: Iad269d97ccae125b73054975a7d35944867db850
parent 434b1ccb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -66,10 +66,10 @@ final class Constants {
    public static final int ADDR_PLAYBACK_3 = 11;

    /** Logical address reserved for future usage */
    public static final int ADDR_RESERVED_1 = 12;
    public static final int ADDR_BACKUP_1 = 12;

    /** Logical address reserved for future usage */
    public static final int ADDR_RESERVED_2 = 13;
    public static final int ADDR_BACKUP_2 = 13;

    /** Logical address for TV other than the one assigned with {@link #ADDR_TV} */
    public static final int ADDR_SPECIFIC_USE = 14;
+32 −26
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ final class HdmiCecController {

    private static final int NUM_LOGICAL_ADDRESS = 16;

    private static final int MAX_DEDICATED_ADDRESS = 11;

    private static final int MAX_HDMI_MESSAGE_HISTORY = 250;

    private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
@@ -104,7 +106,7 @@ final class HdmiCecController {
    private final Predicate<Integer> mSystemAudioAddressPredicate = new Predicate<Integer>() {
        @Override
        public boolean test(Integer address) {
            return HdmiUtils.getTypeFromAddress(address) == Constants.ADDR_AUDIO_SYSTEM;
            return HdmiUtils.isEligibleAddressForDevice(Constants.ADDR_AUDIO_SYSTEM, address);
        }
    };

@@ -195,31 +197,36 @@ final class HdmiCecController {
        });
    }

    /**
     * Address allocation will check the following addresses (in order):
     * <ul>
     *     <li>Given preferred logical address (if the address is valid for the given device
     *     type)</li>
     *     <li>All dedicated logical addresses for the given device type</li>
     *     <li>Backup addresses, if valid for the given device type</li>
     * </ul>
     */
    @IoThreadOnly
    private void handleAllocateLogicalAddress(final int deviceType, int preferredAddress,
            final AllocateAddressCallback callback) {
        assertRunOnIoThread();
        int startAddress = preferredAddress;
        // If preferred address is "unregistered", start address will be the smallest
        // address matched with the given device type.
        if (preferredAddress == Constants.ADDR_UNREGISTERED) {
            for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) {
                if (deviceType == HdmiUtils.getTypeFromAddress(i)) {
                    startAddress = i;
                    break;
        List<Integer> logicalAddressesToPoll = new ArrayList<>();
        if (HdmiUtils.isEligibleAddressForDevice(deviceType, preferredAddress)) {
            logicalAddressesToPoll.add(preferredAddress);
        }
        for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) {
            if (!logicalAddressesToPoll.contains(i) && HdmiUtils.isEligibleAddressForDevice(
                    deviceType, i) && HdmiUtils.isEligibleAddressForCecVersion(
                    mService.getCecVersion(), i)) {
                logicalAddressesToPoll.add(i);
            }
        }

        int logicalAddress = Constants.ADDR_UNREGISTERED;
        // Iterates all possible addresses which has the same device type.
        for (int i = 0; i < NUM_LOGICAL_ADDRESS; ++i) {
            int curAddress = (startAddress + i) % NUM_LOGICAL_ADDRESS;
            if (curAddress != Constants.ADDR_UNREGISTERED
                    && deviceType == HdmiUtils.getTypeFromAddress(curAddress)) {
        for (Integer logicalAddressToPoll : logicalAddressesToPoll) {
            boolean acked = false;
            for (int j = 0; j < HdmiConfig.ADDRESS_ALLOCATION_RETRY; ++j) {
                    if (sendPollMessage(curAddress, curAddress, 1)) {
                if (sendPollMessage(logicalAddressToPoll, logicalAddressToPoll, 1)) {
                    acked = true;
                    break;
                }
@@ -227,11 +234,10 @@ final class HdmiCecController {
            // If sending <Polling Message> failed, it becomes new logical address for the
            // device because no device uses it as logical address of the device.
            if (!acked) {
                    logicalAddress = curAddress;
                logicalAddress = logicalAddressToPoll;
                break;
            }
        }
        }

        final int assignedAddress = logicalAddress;
        HdmiLogger.debug("New logical address for device [%d]: [preferred:%d, assigned:%d]",
+2 −3
Original line number Diff line number Diff line
@@ -1368,9 +1368,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {

    private boolean checkRecorder(int recorderAddress) {
        HdmiDeviceInfo device = mService.getHdmiCecNetwork().getCecDeviceInfo(recorderAddress);
        return (device != null)
                && (HdmiUtils.getTypeFromAddress(recorderAddress)
                        == HdmiDeviceInfo.DEVICE_RECORDER);
        return (device != null) && (HdmiUtils.isEligibleAddressForDevice(
                HdmiDeviceInfo.DEVICE_RECORDER, recorderAddress));
    }

    private boolean checkRecordSource(byte[] recordSource) {
+1 −1
Original line number Diff line number Diff line
@@ -1561,7 +1561,7 @@ public class HdmiControlService extends SystemService {
                        new HdmiDeviceInfo(activeSource.logicalAddress,
                            activeSource.physicalAddress,
                            pathToPortId(activeSource.physicalAddress),
                            HdmiUtils.getTypeFromAddress(activeSource.logicalAddress), 0,
                            HdmiUtils.getTypeFromAddress(activeSource.logicalAddress).get(0), 0,
                            HdmiUtils.getDefaultDeviceName(activeSource.logicalAddress))
                        :
                            new HdmiDeviceInfo(activeSource.physicalAddress,
+65 −28
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.server.hdmi;

import static com.android.server.hdmi.Constants.ADDR_BACKUP_1;
import static com.android.server.hdmi.Constants.ADDR_BACKUP_2;
import static com.android.server.hdmi.Constants.ADDR_TV;

import android.annotation.Nullable;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.util.Slog;
@@ -29,6 +33,8 @@ import com.android.server.hdmi.Constants.AudioCodec;
import com.android.server.hdmi.Constants.FeatureOpcode;
import com.android.server.hdmi.Constants.PathRelationship;

import com.google.android.collect.Lists;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

@@ -37,6 +43,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -48,22 +55,37 @@ final class HdmiUtils {

    private static final String TAG = "HdmiUtils";

    private static final int[] ADDRESS_TO_TYPE = {
        HdmiDeviceInfo.DEVICE_TV,  // ADDR_TV
        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_1
        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_2
        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_1
        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_1
        HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM,  // ADDR_AUDIO_SYSTEM
        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_2
        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_3
        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_2
        HdmiDeviceInfo.DEVICE_RECORDER,  // ADDR_RECORDER_3
        HdmiDeviceInfo.DEVICE_TUNER,  // ADDR_TUNER_4
        HdmiDeviceInfo.DEVICE_PLAYBACK,  // ADDR_PLAYBACK_3
        HdmiDeviceInfo.DEVICE_RESERVED,
        HdmiDeviceInfo.DEVICE_RESERVED,
        HdmiDeviceInfo.DEVICE_TV,  // ADDR_SPECIFIC_USE
    private static final Map<Integer, List<Integer>> ADDRESS_TO_TYPE =
            new HashMap<Integer, List<Integer>>() {
                {
                    put(Constants.ADDR_TV, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TV));
                    put(Constants.ADDR_RECORDER_1,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER));
                    put(Constants.ADDR_RECORDER_2,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER));
                    put(Constants.ADDR_TUNER_1, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER));
                    put(Constants.ADDR_PLAYBACK_1,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK));
                    put(Constants.ADDR_AUDIO_SYSTEM,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM));
                    put(Constants.ADDR_TUNER_2, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER));
                    put(Constants.ADDR_TUNER_3, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER));
                    put(Constants.ADDR_PLAYBACK_2,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK));
                    put(Constants.ADDR_RECORDER_3,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_RECORDER));
                    put(Constants.ADDR_TUNER_4, Lists.newArrayList(HdmiDeviceInfo.DEVICE_TUNER));
                    put(Constants.ADDR_PLAYBACK_3,
                            Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK));
                    put(Constants.ADDR_BACKUP_1, Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK,
                            HdmiDeviceInfo.DEVICE_RECORDER, HdmiDeviceInfo.DEVICE_TUNER,
                            HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR));
                    put(Constants.ADDR_BACKUP_2, Lists.newArrayList(HdmiDeviceInfo.DEVICE_PLAYBACK,
                            HdmiDeviceInfo.DEVICE_RECORDER, HdmiDeviceInfo.DEVICE_TUNER,
                            HdmiDeviceInfo.DEVICE_VIDEO_PROCESSOR));
                    put(Constants.ADDR_SPECIFIC_USE, Lists.newArrayList(ADDR_TV));
                    put(Constants.ADDR_UNREGISTERED, Collections.emptyList());
                }
            };

    private static final String[] DEFAULT_NAMES = {
@@ -79,8 +101,8 @@ final class HdmiUtils {
        "Recorder_3",
        "Tuner_4",
        "Playback_3",
        "Reserved_1",
        "Reserved_2",
        "Backup_1",
        "Backup_2",
        "Secondary_TV",
    };

@@ -101,21 +123,36 @@ final class HdmiUtils {
     * @return true if the given address is valid
     */
    static boolean isValidAddress(int address) {
        return (Constants.ADDR_TV <= address && address <= Constants.ADDR_SPECIFIC_USE);
        return (ADDR_TV <= address && address <= Constants.ADDR_SPECIFIC_USE);
    }

    static boolean isEligibleAddressForDevice(int deviceType, int logicalAddress) {
        return isValidAddress(logicalAddress)
                && ADDRESS_TO_TYPE.get(logicalAddress).contains(deviceType);
    }

    static boolean isEligibleAddressForCecVersion(int cecVersion, int logicalAddress) {
        if (isValidAddress(logicalAddress)) {
            if (logicalAddress == ADDR_BACKUP_1 || logicalAddress == ADDR_BACKUP_2) {
                return cecVersion == Constants.VERSION_2_0;
            }
            return true;
        }
        return false;
    }

    /**
     * Return the device type for the given logical address.
     *
     * @param address logical address
     * @param logicalAddress logical address
     * @return device type for the given logical address; DEVICE_INACTIVE
     *         if the address is not valid.
     */
    static int getTypeFromAddress(int address) {
        if (isValidAddress(address)) {
            return ADDRESS_TO_TYPE[address];
    static List<Integer> getTypeFromAddress(int logicalAddress) {
        if (isValidAddress(logicalAddress)) {
            return ADDRESS_TO_TYPE.get(logicalAddress);
        }
        return HdmiDeviceInfo.DEVICE_INACTIVE;
        return Lists.newArrayList(HdmiDeviceInfo.DEVICE_INACTIVE);
    }

    /**
@@ -142,10 +179,10 @@ final class HdmiUtils {
     * @throws IllegalArgumentException
     */
    static void verifyAddressType(int logicalAddress, int deviceType) {
        int actualDeviceType = getTypeFromAddress(logicalAddress);
        if (actualDeviceType != deviceType) {
        List<Integer> actualDeviceTypes = getTypeFromAddress(logicalAddress);
        if (!actualDeviceTypes.contains(deviceType)) {
            throw new IllegalArgumentException("Device type missmatch:[Expected:" + deviceType
                    + ", Actual:" + actualDeviceType);
                    + ", Actual:" + actualDeviceTypes);
        }
    }

Loading