/*
 * Copyright (C) 2016 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.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.audiofx.AudioEffect;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * The AudioRecordingConfiguration class collects the information describing an audio recording
 * session.
 * <p>Direct polling (see {@link AudioManager#getActiveRecordingConfigurations()}) or callback
 * (see {@link AudioManager#registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler)}
 * methods are ways to receive information about the current recording configuration of the device.
 * <p>An audio recording configuration contains information about the recording format as used by
 * the application ({@link #getClientFormat()}, as well as the recording format actually used by
 * the device ({@link #getFormat()}). The two recording formats may, for instance, be at different
 * sampling rates due to hardware limitations (e.g. application recording at 44.1kHz whereas the
 * device always records at 48kHz, and the Android framework resamples for the application).
 * <p>The configuration also contains the use case for which audio is recorded
 * ({@link #getClientAudioSource()}), enabling the ability to distinguish between different
 * activities such as ongoing voice recognition or camcorder recording.
 *
 */
public final class AudioRecordingConfiguration implements Parcelable {
    private final static String TAG = new String("AudioRecordingConfiguration");

    private final int mClientSessionId;

    private final int mClientSource;

    private final AudioFormat mDeviceFormat;
    private final AudioFormat mClientFormat;

    @NonNull private final String mClientPackageName;
    private final int mClientUid;

    private final int mPatchHandle;

    private final int mClientPortId;

    private boolean mClientSilenced;

    private final int mDeviceSource;

    private final AudioEffect.Descriptor[] mClientEffects;

    private final AudioEffect.Descriptor[] mDeviceEffects;

    /**
     * @hide
     */
    @TestApi
    public AudioRecordingConfiguration(int uid, int session, int source, AudioFormat clientFormat,
            AudioFormat devFormat, int patchHandle, String packageName, int clientPortId,
            boolean clientSilenced, int deviceSource,
            AudioEffect.Descriptor[] clientEffects, AudioEffect.Descriptor[] deviceEffects) {
        mClientUid = uid;
        mClientSessionId = session;
        mClientSource = source;
        mClientFormat = clientFormat;
        mDeviceFormat = devFormat;
        mPatchHandle = patchHandle;
        mClientPackageName = packageName;
        mClientPortId = clientPortId;
        mClientSilenced = clientSilenced;
        mDeviceSource = deviceSource;
        mClientEffects = clientEffects;
        mDeviceEffects = deviceEffects;
    }

    /**
     * @hide
     */
    @TestApi
    public AudioRecordingConfiguration(int uid, int session, int source,
                                       AudioFormat clientFormat, AudioFormat devFormat,
                                       int patchHandle, String packageName) {
        this(uid, session, source, clientFormat,
                   devFormat, patchHandle, packageName, 0 /*clientPortId*/,
                   false /*clientSilenced*/, MediaRecorder.AudioSource.DEFAULT /*deviceSource*/,
                   new AudioEffect.Descriptor[0] /*clientEffects*/,
                   new AudioEffect.Descriptor[0] /*deviceEffects*/);
    }

    /**
     * @hide
     * For AudioService dump
     * @param pw
     */
    public void dump(PrintWriter pw) {
        pw.println("  " + toLogFriendlyString(this));
    }

    /**
     * @hide
     */
    public static String toLogFriendlyString(AudioRecordingConfiguration arc) {
        String clientEffects = new String();
        for (AudioEffect.Descriptor desc : arc.mClientEffects) {
            clientEffects += "'" + desc.name + "' ";
        }
        String deviceEffects = new String();
        for (AudioEffect.Descriptor desc : arc.mDeviceEffects) {
            deviceEffects += "'" + desc.name + "' ";
        }

        return new String("session:" + arc.mClientSessionId
                + " -- source client=" + MediaRecorder.toLogFriendlyAudioSource(arc.mClientSource)
                + ", dev=" + arc.mDeviceFormat.toLogFriendlyString()
                + " -- uid:" + arc.mClientUid
                + " -- patch:" + arc.mPatchHandle
                + " -- pack:" + arc.mClientPackageName
                + " -- format client=" + arc.mClientFormat.toLogFriendlyString()
                + ", dev=" + arc.mDeviceFormat.toLogFriendlyString()
                + " -- silenced:" + arc.mClientSilenced
                + " -- effects client=" + clientEffects
                + ", dev=" + deviceEffects);
    }

    // Note that this method is called server side, so no "privileged" information is ever sent
    // to a client that is not supposed to have access to it.
    /**
     * @hide
     * Creates a copy of the recording configuration that is stripped of any data enabling
     * identification of which application it is associated with ("anonymized").
     * @param in
     */
    public static AudioRecordingConfiguration anonymizedCopy(AudioRecordingConfiguration in) {
        return new AudioRecordingConfiguration( /*anonymized uid*/ -1,
                in.mClientSessionId, in.mClientSource, in.mClientFormat,
                in.mDeviceFormat, in.mPatchHandle, "" /*empty package name*/,
                in.mClientPortId, in.mClientSilenced, in.mDeviceSource, in.mClientEffects,
                in.mDeviceEffects);
    }

    // matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
    /** @hide */
    @IntDef({
        MediaRecorder.AudioSource.DEFAULT,
        MediaRecorder.AudioSource.MIC,
        MediaRecorder.AudioSource.VOICE_UPLINK,
        MediaRecorder.AudioSource.VOICE_DOWNLINK,
        MediaRecorder.AudioSource.VOICE_CALL,
        MediaRecorder.AudioSource.CAMCORDER,
        MediaRecorder.AudioSource.VOICE_RECOGNITION,
        MediaRecorder.AudioSource.VOICE_COMMUNICATION,
        MediaRecorder.AudioSource.UNPROCESSED,
        MediaRecorder.AudioSource.VOICE_PERFORMANCE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface AudioSource {}

    // documented return values match the sources that return false
    //   in MediaRecorder.isSystemOnlyAudioSource(source)
    /**
     * Returns the audio source selected by the client.
     * @return the audio source selected by the client.
     */
    public @AudioSource int getClientAudioSource() { return mClientSource; }

    /**
     * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
     * @return the session number.
     */
    public int getClientAudioSessionId() {
        return mClientSessionId;
    }

    /**
     * Returns the audio format at which audio is recorded on this Android device.
     * Note that it may differ from the client application recording format
     * (see {@link #getClientFormat()}).
     * @return the device recording format
     */
    public AudioFormat getFormat() { return mDeviceFormat; }

    /**
     * Returns the audio format at which the client application is recording audio.
     * Note that it may differ from the actual recording format (see {@link #getFormat()}).
     * @return the recording format
     */
    public AudioFormat getClientFormat() { return mClientFormat; }

    /**
     * @pending for SystemApi
     * Returns the package name of the application performing the recording.
     * Where there are multiple packages sharing the same user id through the "sharedUserId"
     * mechanism, only the first one with that id will be returned
     * (see {@link PackageManager#getPackagesForUid(int)}).
     * <p>This information is only available if the caller has the
     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING} permission.
     * <br>When called without the permission, the result is an empty string.
     * @return the package name
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public String getClientPackageName() { return mClientPackageName; }

    /**
     * Returns the user id of the application performing the recording.
     * <p>This information is only available if the caller has the
     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING}
     * permission.
     * @return the user id
     * @throws SecurityException Thrown if the caller is missing the MODIFY_AUDIO_ROUTING permission
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
    public int getClientUid() {
        if (mClientUid == -1) {
            throw new SecurityException("MODIFY_AUDIO_ROUTING permission is missing");
        }
        return mClientUid;
    }

    /**
     * Returns information about the audio input device used for this recording.
     * @return the audio recording device or null if this information cannot be retrieved
     */
    public AudioDeviceInfo getAudioDevice() {
        // build the AudioDeviceInfo from the patch handle
        ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
        if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) {
            Log.e(TAG, "Error retrieving list of audio patches");
            return null;
        }
        for (int i = 0 ; i < patches.size() ; i++) {
            final AudioPatch patch = patches.get(i);
            if (patch.id() == mPatchHandle) {
                final AudioPortConfig[] sources = patch.sources();
                if ((sources != null) && (sources.length > 0)) {
                    // not supporting multiple sources, so just look at the first source
                    int devId = sources[0].port().id();
                    return AudioManager.getDeviceForPortId(devId, AudioManager.GET_DEVICES_INPUTS);
                }
                // patch handle is unique, there won't be another with the same handle
                break;
            }
        }
        Log.e(TAG, "Couldn't find device for recording, did recording end already?");
        return null;
    }

    /**
     * @hide
     * Returns the system unique ID assigned for the AudioRecord object corresponding to this
     * AudioRecordingConfiguration client.
     * @return the port ID.
     */
    public int getClientPortId() {
        return mClientPortId;
    }

    /**
     * Returns true if the audio returned to the client is currently being silenced by the
     * audio framework due to concurrent capture policy (e.g the capturing application does not have
     * an active foreground process or service anymore).
     * @return true if captured audio is silenced, false otherwise .
     */
    public boolean isClientSilenced() {
        return mClientSilenced;
    }

    /**
     * Returns the audio source currently used to configure the capture path. It can be different
     * from the source returned by {@link #getClientAudioSource()} if another capture is active.
     * @return the audio source active on the capture path.
     */
    public @AudioSource int getAudioSource() {
        return mDeviceSource;
    }

    /**
     * Returns the list of {@link AudioEffect.Descriptor} for all effects currently enabled on
     * the audio capture client (e.g. {@link AudioRecord} or {@link MediaRecorder}).
     * @return List of {@link AudioEffect.Descriptor} containing all effects enabled for the client.
     */
    public @NonNull List<AudioEffect.Descriptor> getClientEffects() {
        return new ArrayList<AudioEffect.Descriptor>(Arrays.asList(mClientEffects));
    }

    /**
     * Returns the list of {@link AudioEffect.Descriptor} for all effects currently enabled on
     * the capture stream.
     * @return List of {@link AudioEffect.Descriptor} containing all effects enabled on the
     * capture stream. This can be different from the list returned by {@link #getClientEffects()}
     * if another capture is active.
     */
    public @NonNull List<AudioEffect.Descriptor> getEffects() {
        return new ArrayList<AudioEffect.Descriptor>(Arrays.asList(mDeviceEffects));
    }

    public static final @android.annotation.NonNull Parcelable.Creator<AudioRecordingConfiguration> CREATOR
            = new Parcelable.Creator<AudioRecordingConfiguration>() {
        /**
         * Rebuilds an AudioRecordingConfiguration previously stored with writeToParcel().
         * @param p Parcel object to read the AudioRecordingConfiguration from
         * @return a new AudioRecordingConfiguration created from the data in the parcel
         */
        public AudioRecordingConfiguration createFromParcel(Parcel p) {
            return new AudioRecordingConfiguration(p);
        }
        public AudioRecordingConfiguration[] newArray(int size) {
            return new AudioRecordingConfiguration[size];
        }
    };

    @Override
    public int hashCode() {
        return Objects.hash(mClientSessionId, mClientSource);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mClientSessionId);
        dest.writeInt(mClientSource);
        mClientFormat.writeToParcel(dest, 0);
        mDeviceFormat.writeToParcel(dest, 0);
        dest.writeInt(mPatchHandle);
        dest.writeString(mClientPackageName);
        dest.writeInt(mClientUid);
        dest.writeInt(mClientPortId);
        dest.writeBoolean(mClientSilenced);
        dest.writeInt(mDeviceSource);
        dest.writeInt(mClientEffects.length);
        for (int i = 0; i < mClientEffects.length; i++) {
            mClientEffects[i].writeToParcel(dest);
        }
        dest.writeInt(mDeviceEffects.length);
        for (int i = 0; i < mDeviceEffects.length; i++) {
            mDeviceEffects[i].writeToParcel(dest);
        }
    }

    private AudioRecordingConfiguration(Parcel in) {
        mClientSessionId = in.readInt();
        mClientSource = in.readInt();
        mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
        mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
        mPatchHandle = in.readInt();
        mClientPackageName = in.readString();
        mClientUid = in.readInt();
        mClientPortId = in.readInt();
        mClientSilenced = in.readBoolean();
        mDeviceSource = in.readInt();
        mClientEffects = new AudioEffect.Descriptor[in.readInt()];
        for (int i = 0; i < mClientEffects.length; i++) {
            mClientEffects[i] = new AudioEffect.Descriptor(in);
        }
        mDeviceEffects = new AudioEffect.Descriptor[in.readInt()];
        for (int i = 0; i < mDeviceEffects.length; i++) {
            mDeviceEffects[i] = new AudioEffect.Descriptor(in);
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || !(o instanceof AudioRecordingConfiguration)) return false;

        AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;

        return ((mClientUid == that.mClientUid)
                && (mClientSessionId == that.mClientSessionId)
                && (mClientSource == that.mClientSource)
                && (mPatchHandle == that.mPatchHandle)
                && (mClientFormat.equals(that.mClientFormat))
                && (mDeviceFormat.equals(that.mDeviceFormat))
                && (mClientPackageName.equals(that.mClientPackageName))
                && (mClientPortId == that.mClientPortId)
                && (mClientSilenced == that.mClientSilenced)
                && (mDeviceSource == that.mDeviceSource)
                && (Arrays.equals(mClientEffects, that.mClientEffects))
                && (Arrays.equals(mDeviceEffects, that.mDeviceEffects)));
    }
}
