/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.hdmi;

import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.util.Log;

/**
 * Container for record source used for one touch record.
 * Use one of helper method by source type.
 * <ul>
 * <li>Own source: {@link #ofOwnSource()}
 * <li>Digital service(channel id): {@link #ofDigitalChannelId(int, DigitalChannelData)}
 * <li>Digital service(ARIB): {@link #ofArib(int, AribData)}
 * <li>Digital service(ATSC): {@link #ofAtsc(int, AtscData)}
 * <li>Digital service(DVB): {@link #ofDvb(int, DvbData)}
 * <li>Analogue: {@link #ofAnalogue(int, int, int)}
 * <li>External plug: {@link #ofExternalPlug(int)}
 * <li>External physical address: {@link #ofExternalPhysicalAddress(int)}.
 * <ul>
 *
 * @hide
 */
@SystemApi
public final class HdmiRecordSources {
    private static final String TAG = "HdmiRecordSources";

    /** Record source type for "Own Source". */
    private static final int RECORD_SOURCE_TYPE_OWN_SOURCE = 1;
    /** Record source type for "Digital Service". */
    private static final int RECORD_SOURCE_TYPE_DIGITAL_SERVICE = 2;
    /** Record source type for "Analogue Service". */
    private static final int RECORD_SOURCE_TYPE_ANALOGUE_SERVICE = 3;
    /** Record source type for "Exteranl Plug". */
    private static final int RECORD_SOURCE_TYPE_EXTERNAL_PLUG = 4;
    /** Record source type for "External Physical Address". */
    private static final int RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 5;

    private HdmiRecordSources() {}

    /**
     * Base class for each record source.
     * @hide
     */
    @SystemApi
    public static abstract class RecordSource {
        /* package */ final int mSourceType;
        /* package */ final int mExtraDataSize;

        /* package */ RecordSource(int sourceType, int extraDataSize) {
            mSourceType = sourceType;
            mExtraDataSize = extraDataSize;
        }

        /* package */ abstract int extraParamToByteArray(byte[] data, int index);

        /* package */ final int getDataSize(boolean includeType)  {
            return includeType ? mExtraDataSize + 1 : mExtraDataSize;
        }

        /* package */ final int toByteArray(boolean includeType, byte[] data, int index) {
            if (includeType) {
                // 1 to 8 bytes (depends on source).
                // {[Record Source Type]} |
                // {[Record Source Type] [Digital Service Identification]} |
                // {[Record Source Type] [Analogue Broadcast Type] [Analogue Frequency]
                // [Broadcast System]} |
                // {[Record Source Type] [External Plug]} |
                // {[Record Source Type] [External Physical Address]}
                // The first byte is used for record source type.
                data[index++] = (byte) mSourceType;
            }
            extraParamToByteArray(data, index);
            return getDataSize(includeType);
        }
    }

    // ---------------------------------------------------------------------------------------------
    // ---- Own source -----------------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    /**
     * Creates {@link OwnSource} of own source.
     */
    public static OwnSource ofOwnSource() {
        return new OwnSource();
    }

    /**
     * @hide
     */
    @SystemApi
    public static final class OwnSource extends RecordSource {
        private static final int EXTRA_DATA_SIZE = 0;

        private OwnSource() {
            super(RECORD_SOURCE_TYPE_OWN_SOURCE, EXTRA_DATA_SIZE);
        }

        @Override
        int extraParamToByteArray(byte[] data, int index) {
            return 0;
        }
    }


    // ---------------------------------------------------------------------------------------------
    // ---- Digital service data -------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    /**
     * Digital broadcast general types
     */
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ARIB = 0x0;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ATSC = 0x1;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_DVB = 0x2;

    /**
     * Digital broadcast specific types
     */
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ARIB_BS = 0x8;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ARIB_CS = 0x9;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ARIB_T = 0xA;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ATSC_CABLE = 0x10;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE = 0x11;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL = 0x12;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_DVB_C = 0x18;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_DVB_S = 0x19;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_DVB_S2 = 0x1A;
    /** @hide */
    public static final int DIGITAL_BROADCAST_TYPE_DVB_T = 0x1B;

    /** Channel number formats. */
    private static final int CHANNEL_NUMBER_FORMAT_1_PART = 0x01;
    private static final int CHANNEL_NUMBER_FORMAT_2_PART = 0x02;

    /**
     * Interface for digital source identification.
     */
    private interface DigitalServiceIdentification {
        int toByteArray(byte[] data, int index);
    }

    /**
     * Digital service identification for ARIB.
     * <p>
     * It consists of the following fields
     * <ul>
     * <li>transport stream id: 2bytes
     * <li>service id: 2bytes
     * <li>original network id: 2bytes
     * </ul>
     * @hide
     */
    public static final class AribData implements DigitalServiceIdentification {
        /** The transport_stream_ID of the transport stream carrying the required service */
        private final int mTransportStreamId;
        /** The service_ID of the required service */
        private final int mServiceId;
        /**
         * The original_network_ID of the network carrying the transport stream for the required
         * service
         */
        private final int mOriginalNetworkId;

        public AribData(int transportStreamId, int serviceId, int originalNetworkId) {
            mTransportStreamId = transportStreamId;
            mServiceId = serviceId;
            mOriginalNetworkId = originalNetworkId;
        }

        @Override
        public int toByteArray(byte[] data, int index) {
            return threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data,
                    index);
        }
    }

    /**
     * Digital service identification for ATSC.
     * <p>
     * It consists of the following fields
     * <ul>
     * <li>transport stream id: 2bytes
     * <li>program number: 2bytes
     * <li>reserved: 2bytes
     * </ul>
     * @hide
     */
    public static final class AtscData implements DigitalServiceIdentification {
        /** The transport_stream_ID of the transport stream carrying the required service */
        private final int mTransportStreamId;
        /** The Program_number of the required service */
        private final int mProgramNumber;

        public AtscData(int transportStreamId, int programNumber) {
            mTransportStreamId = transportStreamId;
            mProgramNumber = programNumber;
        }

        @Override
        public int toByteArray(byte[] data, int index) {
            return threeFieldsToSixBytes(mTransportStreamId, mProgramNumber, 0, data, index);
        }
    }

    /**
     * Digital service identification for DVB.
     * <p>
     * It consists of the following fields
     * <ul>
     * <li>transport stream id: 2bytes
     * <li>service id: 2bytes
     * <li>original network id: 2bytes
     * </ul>
     * @hide
     */
    public static final class DvbData implements DigitalServiceIdentification {
        /** The transport_stream_ID of the transport stream carrying the required service */
        private final int mTransportStreamId;
        /** The service_ID of the required service */
        private final int mServiceId;
        /**
         * The original_network_ID of the network carrying the transport stream for the required
         * service
         */
        private final int mOriginalNetworkId;

        public DvbData(int transportStreamId, int serviceId, int originalNetworkId) {
            mTransportStreamId = transportStreamId;
            mServiceId = serviceId;
            mOriginalNetworkId = originalNetworkId;
        }

        @Override
        public int toByteArray(byte[] data, int index) {
            return threeFieldsToSixBytes(mTransportStreamId, mServiceId, mOriginalNetworkId, data,
                    index);
        }
    }

    /**
     * Identifies a 1-part Logical or Virtual Channel Number or a 2-part Major and Minor channel
     * combination.
     */
    private static final class ChannelIdentifier {
        /** Identifies Channel Format */
        private final int mChannelNumberFormat;
        /**
         * Major Channel Number (if Channel Number Format is 2-part). If format is
         * CHANNEL_NUMBER_FORMAT_1_PART, this will be ignored(0).
         */
        private final int mMajorChannelNumber;
        /**
         * 1-part Channel Number, or a Minor Channel Number (if Channel Number Format is 2-part).
         */
        private final int mMinorChannelNumber;

        private ChannelIdentifier(int format, int majorNumber, int minorNumer) {
            mChannelNumberFormat = format;
            mMajorChannelNumber = majorNumber;
            mMinorChannelNumber = minorNumer;
        }

        private int toByteArray(byte[] data, int index) {
            // The first 6 bits for format, the 10 bits for major number.
            data[index] = (byte) (((mChannelNumberFormat << 2) | (mMajorChannelNumber >>> 8) & 0x3));
            data[index + 1] = (byte) (mMajorChannelNumber & 0xFF);
            // Minor number uses the next 16 bits.
            shortToByteArray((short) mMinorChannelNumber, data, index + 2);
            return 4;
        }
    }

    /**
     * Digital channel id.
     * <p>
     * It consists of the following fields
     * <ul>
     * <li>channel number format: 6bits
     * <li>major number: 10bits
     * <li>minor number: 16bits
     * <li>reserved: 2bytes
     * </ul>
     * @hide
     */
    public static final class DigitalChannelData implements DigitalServiceIdentification {
        /** Identifies the logical or virtual channel number of a service. */
        private final ChannelIdentifier mChannelIdentifier;

        public static DigitalChannelData ofTwoNumbers(int majorNumber, int minorNumber) {
            return new DigitalChannelData(
                    new ChannelIdentifier(CHANNEL_NUMBER_FORMAT_2_PART, majorNumber, minorNumber));
        }

        public static DigitalChannelData ofOneNumber(int number) {
            return new DigitalChannelData(
                    new ChannelIdentifier(CHANNEL_NUMBER_FORMAT_1_PART, 0, number));
        }

        private DigitalChannelData(ChannelIdentifier id) {
            mChannelIdentifier = id;
        }

        @Override
        public int toByteArray(byte[] data, int index) {
            mChannelIdentifier.toByteArray(data, index);
            // The last 2 bytes is reserved for future use.
            data[index + 4] = 0;
            data[index + 5] = 0;
            return 6;
        }
    }

    /**
     * Creates {@link DigitalServiceSource} with channel type.
     *
     * @param broadcastSystem digital broadcast system. It should be one of
     *            <ul>
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_BS}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_CS}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_T}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_CABLE}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_C}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S2}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_T}
     *            </ul>
     * @hide
     */
    public static DigitalServiceSource ofDigitalChannelId(int broadcastSystem,
            DigitalChannelData data) {
        if (data == null) {
            throw new IllegalArgumentException("data should not be null.");
        }
        switch (broadcastSystem) {
            case DIGITAL_BROADCAST_TYPE_ARIB:
            case DIGITAL_BROADCAST_TYPE_ATSC:
            case DIGITAL_BROADCAST_TYPE_DVB:
            case DIGITAL_BROADCAST_TYPE_ARIB_BS:
            case DIGITAL_BROADCAST_TYPE_ARIB_CS:
            case DIGITAL_BROADCAST_TYPE_ARIB_T:
            case DIGITAL_BROADCAST_TYPE_ATSC_CABLE:
            case DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE:
            case DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL:
            case DIGITAL_BROADCAST_TYPE_DVB_C:
            case DIGITAL_BROADCAST_TYPE_DVB_S:
            case DIGITAL_BROADCAST_TYPE_DVB_S2:
            case DIGITAL_BROADCAST_TYPE_DVB_T:
                return new DigitalServiceSource(
                        DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL,
                        broadcastSystem,
                        data);
            default:
                Log.w(TAG, "Invalid broadcast type:" + broadcastSystem);
                throw new IllegalArgumentException(
                        "Invalid broadcast system value:" + broadcastSystem);
        }
    }

    /**
     * Creates {@link DigitalServiceSource} of ARIB type.
     *
     * @param aribType ARIB type. It should be one of
     *            <ul>
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_BS}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_CS}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ARIB_T}
     *            </ul>
     * @hide
     */
    @Nullable
    public static DigitalServiceSource ofArib(int aribType, AribData data) {
        if (data == null) {
            throw new IllegalArgumentException("data should not be null.");
        }
        switch (aribType) {
            case DIGITAL_BROADCAST_TYPE_ARIB:
            case DIGITAL_BROADCAST_TYPE_ARIB_BS:
            case DIGITAL_BROADCAST_TYPE_ARIB_CS:
            case DIGITAL_BROADCAST_TYPE_ARIB_T:
                return new DigitalServiceSource(
                        DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID,
                        aribType, data);
            default:
                Log.w(TAG, "Invalid ARIB type:" + aribType);
                throw new IllegalArgumentException("type should not be null.");
        }
    }

    /**
     * Creates {@link DigitalServiceSource} of ATSC type.
     *
     * @param atscType ATSC type. It should be one of
     *            <ul>
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_CABLE}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL}
     *            </ul>
     * @hide
     */
    @Nullable
    public static DigitalServiceSource ofAtsc(int atscType, AtscData data) {
        if (data == null) {
            throw new IllegalArgumentException("data should not be null.");
        }
        switch (atscType) {
            case DIGITAL_BROADCAST_TYPE_ATSC:
            case DIGITAL_BROADCAST_TYPE_ATSC_CABLE:
            case DIGITAL_BROADCAST_TYPE_ATSC_SATELLITE:
            case DIGITAL_BROADCAST_TYPE_ATSC_TERRESTRIAL:
                return new DigitalServiceSource(
                        DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID,
                        atscType, data);
            default:
                Log.w(TAG, "Invalid ATSC type:" + atscType);
                throw new IllegalArgumentException("Invalid ATSC type:" + atscType);
        }
    }

    /**
     * Creates {@link DigitalServiceSource} of ATSC type.
     *
     * @param dvbType DVB type. It should be one of
     *            <ul>
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_C}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_S2}
     *            <li>{@link #DIGITAL_BROADCAST_TYPE_DVB_T}
     *            </ul>
     * @hide
     */
    @Nullable
    public static DigitalServiceSource ofDvb(int dvbType, DvbData data) {
        if (data == null) {
            throw new IllegalArgumentException("data should not be null.");
        }
        switch (dvbType) {
            case DIGITAL_BROADCAST_TYPE_DVB:
            case DIGITAL_BROADCAST_TYPE_DVB_C:
            case DIGITAL_BROADCAST_TYPE_DVB_S:
            case DIGITAL_BROADCAST_TYPE_DVB_S2:
            case DIGITAL_BROADCAST_TYPE_DVB_T:
                return new DigitalServiceSource(
                        DigitalServiceSource.DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID,
                        dvbType, data);
            default:
                Log.w(TAG, "Invalid DVB type:" + dvbType);
                throw new IllegalArgumentException("Invalid DVB type:" + dvbType);
        }
    }

    /**
     * Record source container for "Digital Service".
     * <ul>
     * <li>[Record Source Type] - 1 byte
     * <li>[Digital Identification] - 7 bytes
     * </ul>
     * @hide
     */
    @SystemApi
    public static final class DigitalServiceSource extends RecordSource {
        /** Indicates that a service is identified by digital service IDs. */
        private static final int DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID = 0;
        /** Indicates that a service is identified by a logical or virtual channel number. */
        private static final int DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL = 1;

        static final int EXTRA_DATA_SIZE = 7;

        /**
         * Type of identification. It should be one of DIGITAL_SERVICE_IDENTIFIED_BY_DIGITAL_ID and
         * DIGITAL_SERVICE_IDENTIFIED_BY_CHANNEL
         */
        private final int mIdentificationMethod;
        /**
         * Indicates the Digital Broadcast System of required service. This is present irrespective
         * of the state of [Service Identification Method].
         */
        private final int mBroadcastSystem;

        /**
         * Extra parameter for digital service identification.
         */
        private final DigitalServiceIdentification mIdentification;

        private DigitalServiceSource(int identificatinoMethod, int broadcastSystem,
                DigitalServiceIdentification identification) {
            super(RECORD_SOURCE_TYPE_DIGITAL_SERVICE, EXTRA_DATA_SIZE);
            mIdentificationMethod = identificatinoMethod;
            mBroadcastSystem = broadcastSystem;
            mIdentification = identification;
        }

        @Override
        int extraParamToByteArray(byte[] data, int index) {
            data[index] = (byte) ((mIdentificationMethod << 7) | (mBroadcastSystem & 0x7F));
            mIdentification.toByteArray(data, index + 1);
            return EXTRA_DATA_SIZE;

        }
    }


    // ---------------------------------------------------------------------------------------------
    // ---- Analogue service data ------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    /**
     * Analogue broadcast types.
     */
    /** @hide */
    public static final int ANALOGUE_BROADCAST_TYPE_CABLE = 0x0;
    /** @hide */
    public static final int ANALOGUE_BROADCAST_TYPE_SATELLITE = 0x1;
    /** @hide */
    public static final int ANALOGUE_BROADCAST_TYPE_TERRESTRIAL = 0x2;

    /**
     * Broadcast system values.
     */
    /** @hide */
    public static final int BROADCAST_SYSTEM_PAL_BG = 0;
    /** @hide */
    public static final int BROADCAST_SYSTEM_SECAM_LP = 1;
    /** @hide */
    public static final int BROADCAST_SYSTEM_PAL_M = 2;
    /** @hide */
    public static final int BROADCAST_SYSTEM_NTSC_M = 3;
    /** @hide */
    public static final int BROADCAST_SYSTEM_PAL_I = 4;
    /** @hide */
    public static final int BROADCAST_SYSTEM_SECAM_DK = 5;
    /** @hide */
    public static final int BROADCAST_SYSTEM_SECAM_BG = 6;
    /** @hide */
    public static final int BROADCAST_SYSTEM_SECAM_L = 7;
    /** @hide */
    public static final int BROADCAST_SYSTEM_PAL_DK = 8;
    /** @hide */
    public static final int BROADCAST_SYSTEM_PAL_OTHER_SYSTEM = 31;

    /**
     * Creates {@link AnalogueServiceSource} of analogue service.
     *
     * @param broadcastType
     * @param frequency
     * @param broadcastSystem
     * @hide
     */
    @Nullable
    public static AnalogueServiceSource ofAnalogue(int broadcastType, int frequency,
            int broadcastSystem){
        if (broadcastType < ANALOGUE_BROADCAST_TYPE_CABLE
                || broadcastType > ANALOGUE_BROADCAST_TYPE_TERRESTRIAL) {
            Log.w(TAG, "Invalid Broadcast type:" + broadcastType);
            throw new IllegalArgumentException("Invalid Broadcast type:" + broadcastType);
        }
        if (frequency < 0 || frequency > 0xFFFF) {
            Log.w(TAG, "Invalid frequency value[0x0000-0xFFFF]:" + frequency);
            throw new IllegalArgumentException(
                    "Invalid frequency value[0x0000-0xFFFF]:" + frequency);
        }
        if (broadcastSystem < BROADCAST_SYSTEM_PAL_BG
                || broadcastSystem > BROADCAST_SYSTEM_PAL_OTHER_SYSTEM) {

            Log.w(TAG, "Invalid Broadcast system:" + broadcastSystem);
            throw new IllegalArgumentException(
                    "Invalid Broadcast system:" + broadcastSystem);
        }

        return new AnalogueServiceSource(broadcastType, frequency, broadcastSystem);
    }

    /**
     * Record source for analogue service data. It consists of
     * <ul>
     * <li>[Record Source Type] - 1 byte
     * <li>[Analogue Broadcast Type] - 1 byte
     * <li>[Analogue Frequency] - 2 bytes
     * <li>[Broadcast System] - 1 byte
     * </ul>
     * @hide
     */
    @SystemApi
    public static final class AnalogueServiceSource extends RecordSource {
        /* package */ static final int EXTRA_DATA_SIZE = 4;

        /** Indicates the Analogue broadcast type. */
        private final int mBroadcastType;
        /** Used to specify the frequency used by an analogue tuner. 0x0000<N<0xFFFF. */
        private final int mFrequency;
        /**
         * This specifies information about the color system, the sound carrier and the
         * IF-frequency.
         */
        private final int mBroadcastSystem;

        private AnalogueServiceSource(int broadcastType, int frequency, int broadcastSystem) {
            super(RECORD_SOURCE_TYPE_ANALOGUE_SERVICE, EXTRA_DATA_SIZE);
            mBroadcastType = broadcastType;
            mFrequency = frequency;
            mBroadcastSystem = broadcastSystem;
        }

        @Override
        /* package */ int extraParamToByteArray(byte[] data, int index) {
            // [Analogue Broadcast Type] - 1 byte
            data[index] = (byte) mBroadcastType;
            // [Analogue Frequency] - 2 bytes
            shortToByteArray((short) mFrequency, data, index + 1);
            // [Broadcast System] - 1 byte
            data[index + 3] = (byte) mBroadcastSystem;
            return EXTRA_DATA_SIZE;
        }
    }


    // ---------------------------------------------------------------------------------------------
    // ---- External plug data ---------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    /**
     * Creates {@link ExternalPlugData} of external plug type.
     *
     * @param plugNumber plug number. It should be in range of [1, 255]
     * @hide
     */
    public static ExternalPlugData ofExternalPlug(int plugNumber) {
        if (plugNumber < 1 || plugNumber > 255) {
            Log.w(TAG, "Invalid plug number[1-255]" + plugNumber);
            throw new IllegalArgumentException("Invalid plug number[1-255]" + plugNumber);
        }
        return new ExternalPlugData(plugNumber);
    }

    /**
     * Record source for external plug (external non-HDMI device connect) type.
     * <ul>
     * <li>[Record Source Type] - 1 byte
     * <li>[External Plug] - 1 byte
     * </ul>
     * @hide
     */
    @SystemApi
    public static final class ExternalPlugData extends RecordSource {
        static final int EXTRA_DATA_SIZE = 1;

        /** External Plug number on the Recording Device. */
        private final int mPlugNumber;

        private ExternalPlugData(int plugNumber) {
            super(RECORD_SOURCE_TYPE_EXTERNAL_PLUG, EXTRA_DATA_SIZE);
            mPlugNumber = plugNumber;
        }

        @Override
        int extraParamToByteArray(byte[] data, int index) {
            data[index] = (byte) mPlugNumber;
            return EXTRA_DATA_SIZE;
        }
    }

    // ---------------------------------------------------------------------------------------------
    // ---- External physical address --------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    /**
     * Creates {@link ExternalPhysicalAddress} of external physical address.
     *
     * @param physicalAddress
     * @hide
     */
    public static ExternalPhysicalAddress ofExternalPhysicalAddress(int physicalAddress) {
        if ((physicalAddress & ~0xFFFF) != 0) {
            Log.w(TAG, "Invalid physical address:" + physicalAddress);
            throw new IllegalArgumentException("Invalid physical address:" + physicalAddress);
        }

        return new ExternalPhysicalAddress(physicalAddress);
    }

    /**
     * Record source for external physical address.
     * <ul>
     * <li>[Record Source Type] - 1 byte
     * <li>[Physical address] - 2 byte
     * </ul>
     * @hide
     */
    @SystemApi
    public static final class ExternalPhysicalAddress extends RecordSource {
        static final int EXTRA_DATA_SIZE = 2;

        private final int mPhysicalAddress;

        private ExternalPhysicalAddress(int physicalAddress) {
            super(RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS, EXTRA_DATA_SIZE);
            mPhysicalAddress = physicalAddress;
        }

        @Override
        int extraParamToByteArray(byte[] data, int index) {
            shortToByteArray((short) mPhysicalAddress, data, index);
            return EXTRA_DATA_SIZE;
        }
    }


    // ---------------------------------------------------------------------------------------------
    // ------- Helper methods ----------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------------
    private static int threeFieldsToSixBytes(int first, int second, int third, byte[] data,
            int index) {
        shortToByteArray((short) first, data, index);
        shortToByteArray((short) second, data, index + 2);
        shortToByteArray((short) third, data, index + 4);
        return 6;
    }

    private static int shortToByteArray(short value, byte[] byteArray, int index) {
        byteArray[index] = (byte) ((value >>> 8) & 0xFF);
        byteArray[index + 1] = (byte) (value & 0xFF);
        return 2;
    }

    /**
     * Checks the byte array of record source.
     * @hide
     */
    @SystemApi
    public static boolean checkRecordSource(byte[] recordSource) {
        if (recordSource == null || recordSource.length == 0) return false;

        int recordSourceType = recordSource[0];
        int extraDataSize = recordSource.length - 1;
        switch (recordSourceType) {
            case RECORD_SOURCE_TYPE_OWN_SOURCE:
                return extraDataSize == OwnSource.EXTRA_DATA_SIZE;
            case RECORD_SOURCE_TYPE_DIGITAL_SERVICE:
                return extraDataSize == DigitalServiceSource.EXTRA_DATA_SIZE;
            case RECORD_SOURCE_TYPE_ANALOGUE_SERVICE:
                return extraDataSize == AnalogueServiceSource.EXTRA_DATA_SIZE;
            case RECORD_SOURCE_TYPE_EXTERNAL_PLUG:
                return extraDataSize == ExternalPlugData.EXTRA_DATA_SIZE;
            case RECORD_SOURCE_TYPE_EXTERNAL_PHYSICAL_ADDRESS:
                return extraDataSize == ExternalPhysicalAddress.EXTRA_DATA_SIZE;
            default:
                return false;
        }
    }
}
