/*
 * 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.media;

import android.compat.annotation.UnsupportedAppUsage;

/**
 * An audio port is a node of the audio framework or hardware that can be connected to or
 * disconnect from another audio node to create a specific audio routing configuration.
 * Examples of audio ports are an output device (speaker) or an output mix (see AudioMixPort).
 * All attributes that are relevant for applications to make routing selection are described
 * in an AudioPort,  in particular:
 * - possible channel mask configurations.
 * - audio format (PCM 16bit, PCM 24bit...)
 * - gain: a port can be associated with one or more gain controllers (see AudioGain).
 *
 * This object is always created by the framework and read only by applications.
 * A list of all audio port descriptors currently available for applications to control
 * is obtained by AudioManager.listAudioPorts().
 * An application can obtain an AudioPortConfig for a valid configuration of this port
 * by calling AudioPort.buildConfig() and use this configuration
 * to create a connection between audio sinks and sources with AudioManager.connectAudioPatch()
 *
 * @hide
 */
public class AudioPort {
    private static final String TAG = "AudioPort";

    /**
     * For use by the audio framework.
     */
    public static final int ROLE_NONE = 0;
    /**
     * The audio port is a source (produces audio)
     */
    public static final int ROLE_SOURCE = 1;
    /**
     * The audio port is a sink (consumes audio)
     */
    public static final int ROLE_SINK = 2;

    /**
     * audio port type for use by audio framework implementation
     */
    public static final int TYPE_NONE = 0;
    /**
     */
    public static final int TYPE_DEVICE = 1;
    /**
     */
    public static final int TYPE_SUBMIX = 2;
    /**
     */
    public static final int TYPE_SESSION = 3;


    @UnsupportedAppUsage
    AudioHandle mHandle;
    @UnsupportedAppUsage
    protected final int mRole;
    private final String mName;
    private final int[] mSamplingRates;
    private final int[] mChannelMasks;
    private final int[] mChannelIndexMasks;
    private final int[] mFormats;
    @UnsupportedAppUsage
    private final AudioGain[] mGains;
    @UnsupportedAppUsage
    private AudioPortConfig mActiveConfig;

    @UnsupportedAppUsage
    AudioPort(AudioHandle handle, int role, String name,
            int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
            int[] formats, AudioGain[] gains) {

        mHandle = handle;
        mRole = role;
        mName = name;
        mSamplingRates = samplingRates;
        mChannelMasks = channelMasks;
        mChannelIndexMasks = channelIndexMasks;
        mFormats = formats;
        mGains = gains;
    }

    AudioHandle handle() {
        return mHandle;
    }

    /**
     * Get the system unique device ID.
     */
    @UnsupportedAppUsage
    public int id() {
        return mHandle.id();
    }


    /**
     * Get the audio port role
     */
    @UnsupportedAppUsage
    public int role() {
        return mRole;
    }

    /**
     * Get the human-readable name of this port. Perhaps an internal
     * designation or an physical device.
     */
    public String name() {
        return mName;
    }

    /**
     * Get the list of supported sampling rates
     * Empty array if sampling rate is not relevant for this audio port
     */
    public int[] samplingRates() {
        return mSamplingRates;
    }

    /**
     * Get the list of supported channel mask configurations
     * (e.g AudioFormat.CHANNEL_OUT_STEREO)
     * Empty array if channel mask is not relevant for this audio port
     */
    public int[] channelMasks() {
        return mChannelMasks;
    }

    /**
     * Get the list of supported channel index mask configurations
     * (e.g 0x0003 means 2 channel, 0x000F means 4 channel....)
     * Empty array if channel index mask is not relevant for this audio port
     */
    public int[] channelIndexMasks() {
        return mChannelIndexMasks;
    }

    /**
     * Get the list of supported audio format configurations
     * (e.g AudioFormat.ENCODING_PCM_16BIT)
     * Empty array if format is not relevant for this audio port
     */
    public int[] formats() {
        return mFormats;
    }

    /**
     * Get the list of gain descriptors
     * Empty array if this port does not have gain control
     */
    public AudioGain[] gains() {
        return mGains;
    }

    /**
     * Get the gain descriptor at a given index
     */
    AudioGain gain(int index) {
        if (index < 0 || index >= mGains.length) {
            return null;
        }
        return mGains[index];
    }

    /**
     * Build a specific configuration of this audio port for use by methods
     * like AudioManager.connectAudioPatch().
     * @param samplingRate
     * @param channelMask The desired channel mask. AudioFormat.CHANNEL_OUT_DEFAULT if no change
     * from active configuration requested.
     * @param format The desired audio format. AudioFormat.ENCODING_DEFAULT if no change
     * from active configuration requested.
     * @param gain The desired gain. null if no gain changed requested.
     */
    public AudioPortConfig buildConfig(int samplingRate, int channelMask, int format,
                                        AudioGainConfig gain) {
        return new AudioPortConfig(this, samplingRate, channelMask, format, gain);
    }

    /**
     * Get currently active configuration of this audio port.
     */
    public AudioPortConfig activeConfig() {
        return mActiveConfig;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || !(o instanceof AudioPort)) {
            return false;
        }
        AudioPort ap = (AudioPort)o;
        return mHandle.equals(ap.handle());
    }

    @Override
    public int hashCode() {
        return mHandle.hashCode();
    }

    @Override
    public String toString() {
        String role = Integer.toString(mRole);
        switch (mRole) {
            case ROLE_NONE:
                role = "NONE";
                break;
            case ROLE_SOURCE:
                role = "SOURCE";
                break;
            case ROLE_SINK:
                role = "SINK";
                break;
        }
        return "{mHandle: " + mHandle
                + ", mRole: " + role
                + "}";
    }
}
