/**
 * Copyright (C) 2015 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.radio;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * The RadioManager class allows to control a broadcast radio tuner present on the device.
 * It provides data structures and methods to query for available radio modules, list their
 * properties and open an interface to control tuning operations and receive callbacks when
 * asynchronous operations complete or events occur.
 * @hide
 */
@SystemApi
@SystemService(Context.RADIO_SERVICE)
@RequiresFeature(PackageManager.FEATURE_BROADCAST_RADIO)
public class RadioManager {
    private static final String TAG = "BroadcastRadio.manager";

    /** Method return status: successful operation */
    public static final int STATUS_OK = 0;
    /** Method return status: unspecified error */
    public static final int STATUS_ERROR = Integer.MIN_VALUE;
    /** Method return status: permission denied */
    public static final int STATUS_PERMISSION_DENIED = -1;
    /** Method return status: initialization failure */
    public static final int STATUS_NO_INIT = -19;
    /** Method return status: invalid argument provided */
    public static final int STATUS_BAD_VALUE = -22;
    /** Method return status: cannot reach service */
    public static final int STATUS_DEAD_OBJECT = -32;
    /** Method return status: invalid or out of sequence operation */
    public static final int STATUS_INVALID_OPERATION = -38;
    /** Method return status: time out before operation completion */
    public static final int STATUS_TIMED_OUT = -110;


    // keep in sync with radio_class_t in /system/core/incluse/system/radio.h
    /** Radio module class supporting FM (including HD radio) and AM */
    public static final int CLASS_AM_FM = 0;
    /** Radio module class supporting satellite radio */
    public static final int CLASS_SAT = 1;
    /** Radio module class supporting Digital terrestrial radio */
    public static final int CLASS_DT = 2;

    public static final int BAND_INVALID = -1;
    /** AM radio band (LW/MW/SW).
     * @see BandDescriptor */
    public static final int BAND_AM = 0;
    /** FM radio band.
     * @see BandDescriptor */
    public static final int BAND_FM = 1;
    /** FM HD radio or DRM  band.
     * @see BandDescriptor */
    public static final int BAND_FM_HD = 2;
    /** AM HD radio or DRM band.
     * @see BandDescriptor */
    public static final int BAND_AM_HD = 3;
    @IntDef(prefix = { "BAND_" }, value = {
        BAND_INVALID,
        BAND_AM,
        BAND_FM,
        BAND_AM_HD,
        BAND_FM_HD,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Band {}

    // keep in sync with radio_region_t in /system/core/incluse/system/radio.h
    /** Africa, Europe.
     * @see BandDescriptor */
    public static final int REGION_ITU_1  = 0;
    /** Americas.
     * @see BandDescriptor */
    public static final int REGION_ITU_2  = 1;
    /** Russia.
     * @see BandDescriptor */
    public static final int REGION_OIRT   = 2;
    /** Japan.
     * @see BandDescriptor */
    public static final int REGION_JAPAN  = 3;
    /** Korea.
     * @see BandDescriptor */
    public static final int REGION_KOREA  = 4;

    /**
     * Forces mono audio stream reception.
     *
     * Analog broadcasts can recover poor reception conditions by jointing
     * stereo channels into one. Mainly for, but not limited to AM/FM.
     */
    public static final int CONFIG_FORCE_MONO = 1;
    /**
     * Forces the analog playback for the supporting radio technology.
     *
     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
     * this option. This is purely user choice, ie. does not reflect digital-
     * analog handover state managed from the HAL implementation side.
     *
     * Some radio technologies may not support this, ie. DAB.
     */
    public static final int CONFIG_FORCE_ANALOG = 2;
    /**
     * Forces the digital playback for the supporting radio technology.
     *
     * User may disable digital-analog handover that happens with poor
     * reception conditions. With digital forced, the radio will remain silent
     * instead of switching to analog channel if it's available. This is purely
     * user choice, it does not reflect the actual state of handover.
     */
    public static final int CONFIG_FORCE_DIGITAL = 3;
    /**
     * RDS Alternative Frequencies.
     *
     * If set and the currently tuned RDS station broadcasts on multiple
     * channels, radio tuner automatically switches to the best available
     * alternative.
     */
    public static final int CONFIG_RDS_AF = 4;
    /**
     * RDS region-specific program lock-down.
     *
     * Allows user to lock to the current region as they move into the
     * other region.
     */
    public static final int CONFIG_RDS_REG = 5;
    /** Enables DAB-DAB hard- and implicit-linking (the same content). */
    public static final int CONFIG_DAB_DAB_LINKING = 6;
    /** Enables DAB-FM hard- and implicit-linking (the same content). */
    public static final int CONFIG_DAB_FM_LINKING = 7;
    /** Enables DAB-DAB soft-linking (related content). */
    public static final int CONFIG_DAB_DAB_SOFT_LINKING = 8;
    /** Enables DAB-FM soft-linking (related content). */
    public static final int CONFIG_DAB_FM_SOFT_LINKING = 9;

    /** @hide */
    @IntDef(prefix = { "CONFIG_" }, value = {
        CONFIG_FORCE_MONO,
        CONFIG_FORCE_ANALOG,
        CONFIG_FORCE_DIGITAL,
        CONFIG_RDS_AF,
        CONFIG_RDS_REG,
        CONFIG_DAB_DAB_LINKING,
        CONFIG_DAB_FM_LINKING,
        CONFIG_DAB_DAB_SOFT_LINKING,
        CONFIG_DAB_FM_SOFT_LINKING,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConfigFlag {}

    /*****************************************************************************
     * Lists properties, options and radio bands supported by a given broadcast radio module.
     * Each module has a unique ID used to address it when calling RadioManager APIs.
     * Module properties are returned by {@link #listModules(List <ModuleProperties>)} method.
     ****************************************************************************/
    public static class ModuleProperties implements Parcelable {

        private final int mId;
        @NonNull private final String mServiceName;
        private final int mClassId;
        private final String mImplementor;
        private final String mProduct;
        private final String mVersion;
        private final String mSerial;
        private final int mNumTuners;
        private final int mNumAudioSources;
        private final boolean mIsInitializationRequired;
        private final boolean mIsCaptureSupported;
        private final BandDescriptor[] mBands;
        private final boolean mIsBgScanSupported;
        private final Set<Integer> mSupportedProgramTypes;
        private final Set<Integer> mSupportedIdentifierTypes;
        @Nullable private final Map<String, Integer> mDabFrequencyTable;
        @NonNull private final Map<String, String> mVendorInfo;

        /** @hide */
        public ModuleProperties(int id, String serviceName, int classId, String implementor,
                String product, String version, String serial, int numTuners, int numAudioSources,
                boolean isInitializationRequired, boolean isCaptureSupported,
                BandDescriptor[] bands, boolean isBgScanSupported,
                @ProgramSelector.ProgramType int[] supportedProgramTypes,
                @ProgramSelector.IdentifierType int[] supportedIdentifierTypes,
                @Nullable Map<String, Integer> dabFrequencyTable,
                Map<String, String> vendorInfo) {
            mId = id;
            mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName;
            mClassId = classId;
            mImplementor = implementor;
            mProduct = product;
            mVersion = version;
            mSerial = serial;
            mNumTuners = numTuners;
            mNumAudioSources = numAudioSources;
            mIsInitializationRequired = isInitializationRequired;
            mIsCaptureSupported = isCaptureSupported;
            mBands = bands;
            mIsBgScanSupported = isBgScanSupported;
            mSupportedProgramTypes = arrayToSet(supportedProgramTypes);
            mSupportedIdentifierTypes = arrayToSet(supportedIdentifierTypes);
            if (dabFrequencyTable != null) {
                for (Map.Entry<String, Integer> entry : dabFrequencyTable.entrySet()) {
                    Objects.requireNonNull(entry.getKey());
                    Objects.requireNonNull(entry.getValue());
                }
            }
            mDabFrequencyTable = dabFrequencyTable;
            mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
        }

        private static Set<Integer> arrayToSet(int[] arr) {
            return Arrays.stream(arr).boxed().collect(Collectors.toSet());
        }

        private static int[] setToArray(Set<Integer> set) {
            return set.stream().mapToInt(Integer::intValue).toArray();
        }

        /** Unique module identifier provided by the native service.
         * For use with {@link #openTuner(int, BandConfig, boolean, Callback, Handler)}.
         * @return the radio module unique identifier.
         */
        public int getId() {
            return mId;
        }

        /**
         * Module service (driver) name as registered with HIDL.
         * @return the module service name.
         */
        public @NonNull String getServiceName() {
            return mServiceName;
        }

        /** Module class identifier: {@link #CLASS_AM_FM}, {@link #CLASS_SAT}, {@link #CLASS_DT}
         * @return the radio module class identifier.
         */
        public int getClassId() {
            return mClassId;
        }

        /** Human readable broadcast radio module implementor
         * @return the name of the radio module implementator.
         */
        public String getImplementor() {
            return mImplementor;
        }

        /** Human readable broadcast radio module product name
         * @return the radio module product name.
         */
        public String getProduct() {
            return mProduct;
        }

        /** Human readable broadcast radio module version number
         * @return the radio module version.
         */
        public String getVersion() {
            return mVersion;
        }

        /** Radio module serial number.
         * Can be used for subscription services.
         * @return the radio module serial number.
         */
        public String getSerial() {
            return mSerial;
        }

        /** Number of tuners available.
         * This is the number of tuners that can be open simultaneously.
         * @return the number of tuners supported.
         */
        public int getNumTuners() {
            return mNumTuners;
        }

        /** Number tuner audio sources available. Must be less or equal to getNumTuners().
         * When more than one tuner is supported, one is usually for playback and has one
         * associated audio source and the other is for pre scanning and building a
         * program list.
         * @return the number of audio sources available.
         */
        public int getNumAudioSources() {
            return mNumAudioSources;
        }

        /**
         * Checks, if BandConfig initialization (after {@link RadioManager#openTuner})
         * is required to be done before other operations or not.
         *
         * If it is, the client has to wait for {@link RadioTuner.Callback#onConfigurationChanged}
         * callback before executing any other operations. Otherwise, such operation will fail
         * returning {@link RadioManager#STATUS_INVALID_OPERATION} error code.
         */
        public boolean isInitializationRequired() {
            return mIsInitializationRequired;
        }

        /** {@code true} if audio capture is possible from radio tuner output.
         * This indicates if routing to audio devices not connected to the same HAL as the FM radio
         * is possible (e.g. to USB) or DAR (Digital Audio Recorder) feature can be implemented.
         * @return {@code true} if audio capture is possible, {@code false} otherwise.
         */
        public boolean isCaptureSupported() {
            return mIsCaptureSupported;
        }

        /**
         * {@code true} if the module supports background scanning. At the given time it may not
         * be available though, see {@link RadioTuner#startBackgroundScan()}.
         *
         * @return {@code true} if background scanning is supported (not necessary available
         * at a given time), {@code false} otherwise.
         */
        public boolean isBackgroundScanningSupported() {
            return mIsBgScanSupported;
        }

        /**
         * Checks, if a given program type is supported by this tuner.
         *
         * If a program type is supported by radio module, it means it can tune
         * to ProgramSelector of a given type.
         *
         * @return {@code true} if a given program type is supported.
         */
        public boolean isProgramTypeSupported(@ProgramSelector.ProgramType int type) {
            return mSupportedProgramTypes.contains(type);
        }

        /**
         * Checks, if a given program identifier is supported by this tuner.
         *
         * If an identifier is supported by radio module, it means it can use it for
         * tuning to ProgramSelector with either primary or secondary Identifier of
         * a given type.
         *
         * @return {@code true} if a given program type is supported.
         */
        public boolean isProgramIdentifierSupported(@ProgramSelector.IdentifierType int type) {
            return mSupportedIdentifierTypes.contains(type);
        }

        /**
         * A frequency table for Digital Audio Broadcasting (DAB).
         *
         * The key is a channel name, i.e. 5A, 7B.
         *
         * The value is a frequency, in kHz.
         *
         * @return a frequency table, or {@code null} if the module doesn't support DAB
         */
        public @Nullable Map<String, Integer> getDabFrequencyTable() {
            return mDabFrequencyTable;
        }

        /**
         * A map of vendor-specific opaque strings, passed from HAL without changes.
         * Format of these strings can vary across vendors.
         *
         * It may be used for extra features, that's not supported by a platform,
         * for example: preset-slots=6; ultra-hd-capable=false.
         *
         * Keys must be prefixed with unique vendor Java-style namespace,
         * eg. 'com.somecompany.parameter1'.
         */
        public @NonNull Map<String, String> getVendorInfo() {
            return mVendorInfo;
        }

        /** List of descriptors for all bands supported by this module.
         * @return an array of {@link BandDescriptor}.
         */
        public BandDescriptor[] getBands() {
            return mBands;
        }

        private ModuleProperties(Parcel in) {
            mId = in.readInt();
            String serviceName = in.readString();
            mServiceName = TextUtils.isEmpty(serviceName) ? "default" : serviceName;
            mClassId = in.readInt();
            mImplementor = in.readString();
            mProduct = in.readString();
            mVersion = in.readString();
            mSerial = in.readString();
            mNumTuners = in.readInt();
            mNumAudioSources = in.readInt();
            mIsInitializationRequired = in.readInt() == 1;
            mIsCaptureSupported = in.readInt() == 1;
            Parcelable[] tmp = in.readParcelableArray(BandDescriptor.class.getClassLoader());
            mBands = new BandDescriptor[tmp.length];
            for (int i = 0; i < tmp.length; i++) {
                mBands[i] = (BandDescriptor) tmp[i];
            }
            mIsBgScanSupported = in.readInt() == 1;
            mSupportedProgramTypes = arrayToSet(in.createIntArray());
            mSupportedIdentifierTypes = arrayToSet(in.createIntArray());
            mDabFrequencyTable = Utils.readStringIntMap(in);
            mVendorInfo = Utils.readStringMap(in);
        }

        public static final @android.annotation.NonNull Parcelable.Creator<ModuleProperties> CREATOR
                = new Parcelable.Creator<ModuleProperties>() {
            public ModuleProperties createFromParcel(Parcel in) {
                return new ModuleProperties(in);
            }

            public ModuleProperties[] newArray(int size) {
                return new ModuleProperties[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mId);
            dest.writeString(mServiceName);
            dest.writeInt(mClassId);
            dest.writeString(mImplementor);
            dest.writeString(mProduct);
            dest.writeString(mVersion);
            dest.writeString(mSerial);
            dest.writeInt(mNumTuners);
            dest.writeInt(mNumAudioSources);
            dest.writeInt(mIsInitializationRequired ? 1 : 0);
            dest.writeInt(mIsCaptureSupported ? 1 : 0);
            dest.writeParcelableArray(mBands, flags);
            dest.writeInt(mIsBgScanSupported ? 1 : 0);
            dest.writeIntArray(setToArray(mSupportedProgramTypes));
            dest.writeIntArray(setToArray(mSupportedIdentifierTypes));
            Utils.writeStringIntMap(dest, mDabFrequencyTable);
            Utils.writeStringMap(dest, mVendorInfo);
        }

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

        @Override
        public String toString() {
            return "ModuleProperties [mId=" + mId
                    + ", mServiceName=" + mServiceName + ", mClassId=" + mClassId
                    + ", mImplementor=" + mImplementor + ", mProduct=" + mProduct
                    + ", mVersion=" + mVersion + ", mSerial=" + mSerial
                    + ", mNumTuners=" + mNumTuners
                    + ", mNumAudioSources=" + mNumAudioSources
                    + ", mIsInitializationRequired=" + mIsInitializationRequired
                    + ", mIsCaptureSupported=" + mIsCaptureSupported
                    + ", mIsBgScanSupported=" + mIsBgScanSupported
                    + ", mBands=" + Arrays.toString(mBands) + "]";
        }

        @Override
        public int hashCode() {
            return Objects.hash(mId, mServiceName, mClassId, mImplementor, mProduct, mVersion,
                mSerial, mNumTuners, mNumAudioSources, mIsInitializationRequired,
                mIsCaptureSupported, mBands, mIsBgScanSupported, mDabFrequencyTable, mVendorInfo);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof ModuleProperties)) return false;
            ModuleProperties other = (ModuleProperties) obj;

            if (mId != other.getId()) return false;
            if (!TextUtils.equals(mServiceName, other.mServiceName)) return false;
            if (mClassId != other.mClassId) return false;
            if (!Objects.equals(mImplementor, other.mImplementor)) return false;
            if (!Objects.equals(mProduct, other.mProduct)) return false;
            if (!Objects.equals(mVersion, other.mVersion)) return false;
            if (!Objects.equals(mSerial, other.mSerial)) return false;
            if (mNumTuners != other.mNumTuners) return false;
            if (mNumAudioSources != other.mNumAudioSources) return false;
            if (mIsInitializationRequired != other.mIsInitializationRequired) return false;
            if (mIsCaptureSupported != other.mIsCaptureSupported) return false;
            if (!Objects.equals(mBands, other.mBands)) return false;
            if (mIsBgScanSupported != other.mIsBgScanSupported) return false;
            if (!Objects.equals(mDabFrequencyTable, other.mDabFrequencyTable)) return false;
            if (!Objects.equals(mVendorInfo, other.mVendorInfo)) return false;
            return true;
        }
    }

    /** Radio band descriptor: an element in ModuleProperties bands array.
     * It is either an instance of {@link FmBandDescriptor} or {@link AmBandDescriptor} */
    public static class BandDescriptor implements Parcelable {

        private final int mRegion;
        private final int mType;
        private final int mLowerLimit;
        private final int mUpperLimit;
        private final int mSpacing;

        BandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing) {
            if (type != BAND_AM && type != BAND_FM && type != BAND_FM_HD && type != BAND_AM_HD) {
                throw new IllegalArgumentException("Unsupported band: " + type);
            }
            mRegion = region;
            mType = type;
            mLowerLimit = lowerLimit;
            mUpperLimit = upperLimit;
            mSpacing = spacing;
        }

        /** Region this band applies to. E.g. {@link #REGION_ITU_1}
         * @return the region this band is associated to.
         */
        public int getRegion() {
            return mRegion;
        }
        /** Band type, e.g {@link #BAND_FM}. Defines the subclass this descriptor can be cast to:
         * <ul>
         *  <li>{@link #BAND_FM} or {@link #BAND_FM_HD} cast to {@link FmBandDescriptor}, </li>
         *  <li>{@link #BAND_AM} cast to {@link AmBandDescriptor}, </li>
         * </ul>
         * @return the band type.
         */
        public int getType() {
            return mType;
        }

        /**
         * Checks if the band is either AM or AM_HD.
         *
         * @return {@code true}, if band is AM or AM_HD.
         */
        public boolean isAmBand() {
            return mType == BAND_AM || mType == BAND_AM_HD;
        }

        /**
         * Checks if the band is either FM or FM_HD.
         *
         * @return {@code true}, if band is FM or FM_HD.
         */
        public boolean isFmBand() {
            return mType == BAND_FM || mType == BAND_FM_HD;
        }

        /** Lower band limit expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         * @return the lower band limit.
         */
        public int getLowerLimit() {
            return mLowerLimit;
        }
        /** Upper band limit expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         * @return the upper band limit.
         */
        public int getUpperLimit() {
            return mUpperLimit;
        }
        /** Channel spacing in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         * @return the channel spacing.
         */
        public int getSpacing() {
            return mSpacing;
        }

        private BandDescriptor(Parcel in) {
            mRegion = in.readInt();
            mType = in.readInt();
            mLowerLimit = in.readInt();
            mUpperLimit = in.readInt();
            mSpacing = in.readInt();
        }

        private static int lookupTypeFromParcel(Parcel in) {
            int pos = in.dataPosition();
            in.readInt();  // skip region
            int type = in.readInt();
            in.setDataPosition(pos);
            return type;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<BandDescriptor> CREATOR
                = new Parcelable.Creator<BandDescriptor>() {
            public BandDescriptor createFromParcel(Parcel in) {
                int type = lookupTypeFromParcel(in);
                switch (type) {
                    case BAND_FM:
                    case BAND_FM_HD:
                        return new FmBandDescriptor(in);
                    case BAND_AM:
                    case BAND_AM_HD:
                        return new AmBandDescriptor(in);
                    default:
                        throw new IllegalArgumentException("Unsupported band: " + type);
                }
            }

            public BandDescriptor[] newArray(int size) {
                return new BandDescriptor[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mRegion);
            dest.writeInt(mType);
            dest.writeInt(mLowerLimit);
            dest.writeInt(mUpperLimit);
            dest.writeInt(mSpacing);
        }

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

        @Override
        public String toString() {
            return "BandDescriptor [mRegion=" + mRegion + ", mType=" + mType + ", mLowerLimit="
                    + mLowerLimit + ", mUpperLimit=" + mUpperLimit + ", mSpacing=" + mSpacing + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + mRegion;
            result = prime * result + mType;
            result = prime * result + mLowerLimit;
            result = prime * result + mUpperLimit;
            result = prime * result + mSpacing;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!(obj instanceof BandDescriptor))
                return false;
            BandDescriptor other = (BandDescriptor) obj;
            if (mRegion != other.getRegion())
                return false;
            if (mType != other.getType())
                return false;
            if (mLowerLimit != other.getLowerLimit())
                return false;
            if (mUpperLimit != other.getUpperLimit())
                return false;
            if (mSpacing != other.getSpacing())
                return false;
            return true;
        }
    }

    /** FM band descriptor
     * @see #BAND_FM
     * @see #BAND_FM_HD */
    public static class FmBandDescriptor extends BandDescriptor {
        private final boolean mStereo;
        private final boolean mRds;
        private final boolean mTa;
        private final boolean mAf;
        private final boolean mEa;

        /** @hide */
        public FmBandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing,
                boolean stereo, boolean rds, boolean ta, boolean af, boolean ea) {
            super(region, type, lowerLimit, upperLimit, spacing);
            mStereo = stereo;
            mRds = rds;
            mTa = ta;
            mAf = af;
            mEa = ea;
        }

        /** Stereo is supported
         * @return {@code true} if stereo is supported, {@code false} otherwise.
         */
        public boolean isStereoSupported() {
            return mStereo;
        }
        /** RDS or RBDS(if region is ITU2) is supported
         * @return {@code true} if RDS or RBDS is supported, {@code false} otherwise.
         */
        public boolean isRdsSupported() {
            return mRds;
        }
        /** Traffic announcement is supported
         * @return {@code true} if TA is supported, {@code false} otherwise.
         */
        public boolean isTaSupported() {
            return mTa;
        }
        /** Alternate Frequency Switching is supported
         * @return {@code true} if AF switching is supported, {@code false} otherwise.
         */
        public boolean isAfSupported() {
            return mAf;
        }

        /** Emergency Announcement is supported
         * @return {@code true} if Emergency annoucement is supported, {@code false} otherwise.
         */
        public boolean isEaSupported() {
            return mEa;
        }

        /* Parcelable implementation */
        private FmBandDescriptor(Parcel in) {
            super(in);
            mStereo = in.readByte() == 1;
            mRds = in.readByte() == 1;
            mTa = in.readByte() == 1;
            mAf = in.readByte() == 1;
            mEa = in.readByte() == 1;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<FmBandDescriptor> CREATOR
                = new Parcelable.Creator<FmBandDescriptor>() {
            public FmBandDescriptor createFromParcel(Parcel in) {
                return new FmBandDescriptor(in);
            }

            public FmBandDescriptor[] newArray(int size) {
                return new FmBandDescriptor[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeByte((byte) (mStereo ? 1 : 0));
            dest.writeByte((byte) (mRds ? 1 : 0));
            dest.writeByte((byte) (mTa ? 1 : 0));
            dest.writeByte((byte) (mAf ? 1 : 0));
            dest.writeByte((byte) (mEa ? 1 : 0));
        }

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

        @Override
        public String toString() {
            return "FmBandDescriptor [ "+ super.toString() + " mStereo=" + mStereo
                    + ", mRds=" + mRds + ", mTa=" + mTa + ", mAf=" + mAf +
                    ", mEa =" + mEa + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = super.hashCode();
            result = prime * result + (mStereo ? 1 : 0);
            result = prime * result + (mRds ? 1 : 0);
            result = prime * result + (mTa ? 1 : 0);
            result = prime * result + (mAf ? 1 : 0);
            result = prime * result + (mEa ? 1 : 0);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!super.equals(obj))
                return false;
            if (!(obj instanceof FmBandDescriptor))
                return false;
            FmBandDescriptor other = (FmBandDescriptor) obj;
            if (mStereo != other.isStereoSupported())
                return false;
            if (mRds != other.isRdsSupported())
                return false;
            if (mTa != other.isTaSupported())
                return false;
            if (mAf != other.isAfSupported())
                return false;
            if (mEa != other.isEaSupported())
                return false;
            return true;
        }
    }

    /** AM band descriptor.
     * @see #BAND_AM */
    public static class AmBandDescriptor extends BandDescriptor {

        private final boolean mStereo;

        /** @hide */
        public AmBandDescriptor(int region, int type, int lowerLimit, int upperLimit, int spacing,
                boolean stereo) {
            super(region, type, lowerLimit, upperLimit, spacing);
            mStereo = stereo;
        }

        /** Stereo is supported
         *  @return {@code true} if stereo is supported, {@code false} otherwise.
         */
        public boolean isStereoSupported() {
            return mStereo;
        }

        private AmBandDescriptor(Parcel in) {
            super(in);
            mStereo = in.readByte() == 1;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<AmBandDescriptor> CREATOR
                = new Parcelable.Creator<AmBandDescriptor>() {
            public AmBandDescriptor createFromParcel(Parcel in) {
                return new AmBandDescriptor(in);
            }

            public AmBandDescriptor[] newArray(int size) {
                return new AmBandDescriptor[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeByte((byte) (mStereo ? 1 : 0));
        }

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

        @Override
        public String toString() {
            return "AmBandDescriptor [ "+ super.toString() + " mStereo=" + mStereo + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = super.hashCode();
            result = prime * result + (mStereo ? 1 : 0);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!super.equals(obj))
                return false;
            if (!(obj instanceof AmBandDescriptor))
                return false;
            AmBandDescriptor other = (AmBandDescriptor) obj;
            if (mStereo != other.isStereoSupported())
                return false;
            return true;
        }
    }


    /** Radio band configuration. */
    public static class BandConfig implements Parcelable {

        @NonNull final BandDescriptor mDescriptor;

        BandConfig(BandDescriptor descriptor) {
            mDescriptor = Objects.requireNonNull(descriptor);
        }

        BandConfig(int region, int type, int lowerLimit, int upperLimit, int spacing) {
            mDescriptor = new BandDescriptor(region, type, lowerLimit, upperLimit, spacing);
        }

        private BandConfig(Parcel in) {
            mDescriptor = new BandDescriptor(in);
        }

        BandDescriptor getDescriptor() {
            return mDescriptor;
        }

        /** Region this band applies to. E.g. {@link #REGION_ITU_1}
         *  @return the region associated with this band.
         */
        public int getRegion() {
            return mDescriptor.getRegion();
        }
        /** Band type, e.g {@link #BAND_FM}. Defines the subclass this descriptor can be cast to:
         * <ul>
         *  <li>{@link #BAND_FM} or {@link #BAND_FM_HD} cast to {@link FmBandDescriptor}, </li>
         *  <li>{@link #BAND_AM} cast to {@link AmBandDescriptor}, </li>
         * </ul>
         *  @return the band type.
         */
        public int getType() {
            return mDescriptor.getType();
        }
        /** Lower band limit expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         *  @return the lower band limit.
         */
        public int getLowerLimit() {
            return mDescriptor.getLowerLimit();
        }
        /** Upper band limit expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         *  @return the upper band limit.
         */
        public int getUpperLimit() {
            return mDescriptor.getUpperLimit();
        }
        /** Channel spacing in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         *  @return the channel spacing.
         */
        public int getSpacing() {
            return mDescriptor.getSpacing();
        }


        public static final @android.annotation.NonNull Parcelable.Creator<BandConfig> CREATOR
                = new Parcelable.Creator<BandConfig>() {
            public BandConfig createFromParcel(Parcel in) {
                int type = BandDescriptor.lookupTypeFromParcel(in);
                switch (type) {
                    case BAND_FM:
                    case BAND_FM_HD:
                        return new FmBandConfig(in);
                    case BAND_AM:
                    case BAND_AM_HD:
                        return new AmBandConfig(in);
                    default:
                        throw new IllegalArgumentException("Unsupported band: " + type);
                }
            }

            public BandConfig[] newArray(int size) {
                return new BandConfig[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            mDescriptor.writeToParcel(dest, flags);
        }

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

        @Override
        public String toString() {
            return "BandConfig [ " + mDescriptor.toString() + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + mDescriptor.hashCode();
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!(obj instanceof BandConfig))
                return false;
            BandConfig other = (BandConfig) obj;
            BandDescriptor otherDesc = other.getDescriptor();
            if ((mDescriptor == null) != (otherDesc == null)) return false;
            if (mDescriptor != null && !mDescriptor.equals(otherDesc)) return false;
            return true;
        }
    }

    /** FM band configuration.
     * @see #BAND_FM
     * @see #BAND_FM_HD */
    public static class FmBandConfig extends BandConfig {
        private final boolean mStereo;
        private final boolean mRds;
        private final boolean mTa;
        private final boolean mAf;
        private final boolean mEa;

        /** @hide */
        public FmBandConfig(FmBandDescriptor descriptor) {
            super((BandDescriptor)descriptor);
            mStereo = descriptor.isStereoSupported();
            mRds = descriptor.isRdsSupported();
            mTa = descriptor.isTaSupported();
            mAf = descriptor.isAfSupported();
            mEa = descriptor.isEaSupported();
        }

        FmBandConfig(int region, int type, int lowerLimit, int upperLimit, int spacing,
                boolean stereo, boolean rds, boolean ta, boolean af, boolean ea) {
            super(region, type, lowerLimit, upperLimit, spacing);
            mStereo = stereo;
            mRds = rds;
            mTa = ta;
            mAf = af;
            mEa = ea;
        }

        /** Get stereo enable state
         * @return the enable state.
         */
        public boolean getStereo() {
            return mStereo;
        }

        /** Get RDS or RBDS(if region is ITU2) enable state
         * @return the enable state.
         */
        public boolean getRds() {
            return mRds;
        }

        /** Get Traffic announcement enable state
         * @return the enable state.
         */
        public boolean getTa() {
            return mTa;
        }

        /** Get Alternate Frequency Switching enable state
         * @return the enable state.
         */
        public boolean getAf() {
            return mAf;
        }

        /**
         * Get Emergency announcement enable state
         * @return the enable state.
         */
        public boolean getEa() {
            return mEa;
        }

        private FmBandConfig(Parcel in) {
            super(in);
            mStereo = in.readByte() == 1;
            mRds = in.readByte() == 1;
            mTa = in.readByte() == 1;
            mAf = in.readByte() == 1;
            mEa = in.readByte() == 1;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<FmBandConfig> CREATOR
                = new Parcelable.Creator<FmBandConfig>() {
            public FmBandConfig createFromParcel(Parcel in) {
                return new FmBandConfig(in);
            }

            public FmBandConfig[] newArray(int size) {
                return new FmBandConfig[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeByte((byte) (mStereo ? 1 : 0));
            dest.writeByte((byte) (mRds ? 1 : 0));
            dest.writeByte((byte) (mTa ? 1 : 0));
            dest.writeByte((byte) (mAf ? 1 : 0));
            dest.writeByte((byte) (mEa ? 1 : 0));
        }

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

        @Override
        public String toString() {
            return "FmBandConfig [" + super.toString()
                    + ", mStereo=" + mStereo + ", mRds=" + mRds + ", mTa=" + mTa
                    + ", mAf=" + mAf + ", mEa =" + mEa + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = super.hashCode();
            result = prime * result + (mStereo ? 1 : 0);
            result = prime * result + (mRds ? 1 : 0);
            result = prime * result + (mTa ? 1 : 0);
            result = prime * result + (mAf ? 1 : 0);
            result = prime * result + (mEa ? 1 : 0);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!super.equals(obj))
                return false;
            if (!(obj instanceof FmBandConfig))
                return false;
            FmBandConfig other = (FmBandConfig) obj;
            if (mStereo != other.mStereo)
                return false;
            if (mRds != other.mRds)
                return false;
            if (mTa != other.mTa)
                return false;
            if (mAf != other.mAf)
                return false;
            if (mEa != other.mEa)
                return false;
            return true;
        }

        /**
         * Builder class for {@link FmBandConfig} objects.
         */
        public static class Builder {
            private final BandDescriptor mDescriptor;
            private boolean mStereo;
            private boolean mRds;
            private boolean mTa;
            private boolean mAf;
            private boolean mEa;

            /**
             * Constructs a new Builder with the defaults from an {@link FmBandDescriptor} .
             * @param descriptor the FmBandDescriptor defaults are read from .
             */
            public Builder(FmBandDescriptor descriptor) {
                mDescriptor = new BandDescriptor(descriptor.getRegion(), descriptor.getType(),
                        descriptor.getLowerLimit(), descriptor.getUpperLimit(),
                        descriptor.getSpacing());
                mStereo = descriptor.isStereoSupported();
                mRds = descriptor.isRdsSupported();
                mTa = descriptor.isTaSupported();
                mAf = descriptor.isAfSupported();
                mEa = descriptor.isEaSupported();
            }

            /**
             * Constructs a new Builder from a given {@link FmBandConfig}
             * @param config the FmBandConfig object whose data will be reused in the new Builder.
             */
            public Builder(FmBandConfig config) {
                mDescriptor = new BandDescriptor(config.getRegion(), config.getType(),
                        config.getLowerLimit(), config.getUpperLimit(), config.getSpacing());
                mStereo = config.getStereo();
                mRds = config.getRds();
                mTa = config.getTa();
                mAf = config.getAf();
                mEa = config.getEa();
            }

            /**
             * Combines all of the parameters that have been set and return a new
             * {@link FmBandConfig} object.
             * @return a new {@link FmBandConfig} object
             */
            public FmBandConfig build() {
                FmBandConfig config = new FmBandConfig(mDescriptor.getRegion(),
                        mDescriptor.getType(), mDescriptor.getLowerLimit(),
                        mDescriptor.getUpperLimit(), mDescriptor.getSpacing(),
                        mStereo, mRds, mTa, mAf, mEa);
                return config;
            }

            /** Set stereo enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setStereo(boolean state) {
                mStereo = state;
                return this;
            }

            /** Set RDS or RBDS(if region is ITU2) enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setRds(boolean state) {
                mRds = state;
                return this;
            }

            /** Set Traffic announcement enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setTa(boolean state) {
                mTa = state;
                return this;
            }

            /** Set Alternate Frequency Switching enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setAf(boolean state) {
                mAf = state;
                return this;
            }

            /** Set Emergency Announcement enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setEa(boolean state) {
                mEa = state;
                return this;
            }
        };
    }

    /** AM band configuration.
     * @see #BAND_AM */
    public static class AmBandConfig extends BandConfig {
        private final boolean mStereo;

        /** @hide */
        public AmBandConfig(AmBandDescriptor descriptor) {
            super((BandDescriptor)descriptor);
            mStereo = descriptor.isStereoSupported();
        }

        AmBandConfig(int region, int type, int lowerLimit, int upperLimit, int spacing,
                boolean stereo) {
            super(region, type, lowerLimit, upperLimit, spacing);
            mStereo = stereo;
        }

        /** Get stereo enable state
         * @return the enable state.
         */
        public boolean getStereo() {
            return mStereo;
        }

        private AmBandConfig(Parcel in) {
            super(in);
            mStereo = in.readByte() == 1;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<AmBandConfig> CREATOR
                = new Parcelable.Creator<AmBandConfig>() {
            public AmBandConfig createFromParcel(Parcel in) {
                return new AmBandConfig(in);
            }

            public AmBandConfig[] newArray(int size) {
                return new AmBandConfig[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeByte((byte) (mStereo ? 1 : 0));
        }

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

        @Override
        public String toString() {
            return "AmBandConfig [" + super.toString()
                    + ", mStereo=" + mStereo + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = super.hashCode();
            result = prime * result + (mStereo ? 1 : 0);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (!super.equals(obj))
                return false;
            if (!(obj instanceof AmBandConfig))
                return false;
            AmBandConfig other = (AmBandConfig) obj;
            if (mStereo != other.getStereo())
                return false;
            return true;
        }

        /**
         * Builder class for {@link AmBandConfig} objects.
         */
        public static class Builder {
            private final BandDescriptor mDescriptor;
            private boolean mStereo;

            /**
             * Constructs a new Builder with the defaults from an {@link AmBandDescriptor} .
             * @param descriptor the FmBandDescriptor defaults are read from .
             */
            public Builder(AmBandDescriptor descriptor) {
                mDescriptor = new BandDescriptor(descriptor.getRegion(), descriptor.getType(),
                        descriptor.getLowerLimit(), descriptor.getUpperLimit(),
                        descriptor.getSpacing());
                mStereo = descriptor.isStereoSupported();
            }

            /**
             * Constructs a new Builder from a given {@link AmBandConfig}
             * @param config the FmBandConfig object whose data will be reused in the new Builder.
             */
            public Builder(AmBandConfig config) {
                mDescriptor = new BandDescriptor(config.getRegion(), config.getType(),
                        config.getLowerLimit(), config.getUpperLimit(), config.getSpacing());
                mStereo = config.getStereo();
            }

            /**
             * Combines all of the parameters that have been set and return a new
             * {@link AmBandConfig} object.
             * @return a new {@link AmBandConfig} object
             */
            public AmBandConfig build() {
                AmBandConfig config = new AmBandConfig(mDescriptor.getRegion(),
                        mDescriptor.getType(), mDescriptor.getLowerLimit(),
                        mDescriptor.getUpperLimit(), mDescriptor.getSpacing(),
                        mStereo);
                return config;
            }

            /** Set stereo enable state
             * @param state The new enable state.
             * @return the same Builder instance.
             */
            public Builder setStereo(boolean state) {
                mStereo = state;
                return this;
            }
        };
    }

    /** Radio program information. */
    public static class ProgramInfo implements Parcelable {

        // sourced from hardware/interfaces/broadcastradio/2.0/types.hal
        private static final int FLAG_LIVE = 1 << 0;
        private static final int FLAG_MUTED = 1 << 1;
        private static final int FLAG_TRAFFIC_PROGRAM = 1 << 2;
        private static final int FLAG_TRAFFIC_ANNOUNCEMENT = 1 << 3;
        private static final int FLAG_TUNED = 1 << 4;
        private static final int FLAG_STEREO = 1 << 5;

        @NonNull private final ProgramSelector mSelector;
        @Nullable private final ProgramSelector.Identifier mLogicallyTunedTo;
        @Nullable private final ProgramSelector.Identifier mPhysicallyTunedTo;
        @NonNull private final Collection<ProgramSelector.Identifier> mRelatedContent;
        private final int mInfoFlags;
        private final int mSignalQuality;
        @Nullable private final RadioMetadata mMetadata;
        @NonNull private final Map<String, String> mVendorInfo;

        /** @hide */
        public ProgramInfo(@NonNull ProgramSelector selector,
                @Nullable ProgramSelector.Identifier logicallyTunedTo,
                @Nullable ProgramSelector.Identifier physicallyTunedTo,
                @Nullable Collection<ProgramSelector.Identifier> relatedContent,
                int infoFlags, int signalQuality, @Nullable RadioMetadata metadata,
                @Nullable Map<String, String> vendorInfo) {
            mSelector = Objects.requireNonNull(selector);
            mLogicallyTunedTo = logicallyTunedTo;
            mPhysicallyTunedTo = physicallyTunedTo;
            if (relatedContent == null) {
                mRelatedContent = Collections.emptyList();
            } else {
                Preconditions.checkCollectionElementsNotNull(relatedContent, "relatedContent");
                mRelatedContent = relatedContent;
            }
            mInfoFlags = infoFlags;
            mSignalQuality = signalQuality;
            mMetadata = metadata;
            mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
        }

        /**
         * Program selector, necessary for tuning to a program.
         *
         * @return the program selector.
         */
        public @NonNull ProgramSelector getSelector() {
            return mSelector;
        }

        /**
         * Identifier currently used for program selection.
         *
         * This identifier can be used to determine which technology is
         * currently being used for reception.
         *
         * Some program selectors contain tuning information for different radio
         * technologies (i.e. FM RDS and DAB). For example, user may tune using
         * a ProgramSelector with RDS_PI primary identifier, but the tuner hardware
         * may choose to use DAB technology to make actual tuning. This identifier
         * must reflect that.
         */
        public @Nullable ProgramSelector.Identifier getLogicallyTunedTo() {
            return mLogicallyTunedTo;
        }

        /**
         * Identifier currently used by hardware to physically tune to a channel.
         *
         * Some radio technologies broadcast the same program on multiple channels,
         * i.e. with RDS AF the same program may be broadcasted on multiple
         * alternative frequencies; the same DAB program may be broadcast on
         * multiple ensembles. This identifier points to the channel to which the
         * radio hardware is physically tuned to.
         */
        public @Nullable ProgramSelector.Identifier getPhysicallyTunedTo() {
            return mPhysicallyTunedTo;
        }

        /**
         * Primary identifiers of related contents.
         *
         * Some radio technologies provide pointers to other programs that carry
         * related content (i.e. DAB soft-links). This field is a list of pointers
         * to other programs on the program list.
         *
         * Please note, that these identifiers does not have to exist on the program
         * list - i.e. DAB tuner may provide information on FM RDS alternatives
         * despite not supporting FM RDS. If the system has multiple tuners, another
         * one may have it on its list.
         */
        public @Nullable Collection<ProgramSelector.Identifier> getRelatedContent() {
            return mRelatedContent;
        }

        /** Main channel expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         * @return the program channel
         * @deprecated Use {@link getSelector()} instead.
         */
        @Deprecated
        public int getChannel() {
            try {
                return (int) mSelector.getFirstId(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY);
            } catch (IllegalArgumentException ex) {
                Log.w(TAG, "Not an AM/FM program");
                return 0;
            }
        }

        /** Sub channel ID. E.g 1 for HD radio HD1
         * @return the program sub channel
         * @deprecated Use {@link getSelector()} instead.
         */
        @Deprecated
        public int getSubChannel() {
            try {
                return (int) mSelector.getFirstId(
                        ProgramSelector.IDENTIFIER_TYPE_HD_SUBCHANNEL) + 1;
            } catch (IllegalArgumentException ex) {
                // this is a normal behavior for analog AM/FM selector
                return 0;
            }
        }

        /** {@code true} if the tuner is currently tuned on a valid station
         * @return {@code true} if currently tuned, {@code false} otherwise.
         */
        public boolean isTuned() {
            return (mInfoFlags & FLAG_TUNED) != 0;
        }

        /** {@code true} if the received program is stereo
         * @return {@code true} if stereo, {@code false} otherwise.
         */
        public boolean isStereo() {
            return (mInfoFlags & FLAG_STEREO) != 0;
        }

        /** {@code true} if the received program is digital (e.g HD radio)
         * @return {@code true} if digital, {@code false} otherwise.
         * @deprecated Use {@link getLogicallyTunedTo()} instead.
         */
        @Deprecated
        public boolean isDigital() {
            ProgramSelector.Identifier id = mLogicallyTunedTo;
            if (id == null) id = mSelector.getPrimaryId();

            int type = id.getType();
            return (type != ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY
                && type != ProgramSelector.IDENTIFIER_TYPE_RDS_PI);
        }

        /**
         * {@code true} if the program is currently playing live stream.
         * This may result in a slightly altered reception parameters,
         * usually targetted at reduced latency.
         */
        public boolean isLive() {
            return (mInfoFlags & FLAG_LIVE) != 0;
        }

        /**
         * {@code true} if radio stream is not playing, ie. due to bad reception
         * conditions or buffering. In this state volume knob MAY be disabled to
         * prevent user increasing volume too much.
         * It does NOT mean the user has muted audio.
         */
        public boolean isMuted() {
            return (mInfoFlags & FLAG_MUTED) != 0;
        }

        /**
         * {@code true} if radio station transmits traffic information
         * regularily.
         */
        public boolean isTrafficProgram() {
            return (mInfoFlags & FLAG_TRAFFIC_PROGRAM) != 0;
        }

        /**
         * {@code true} if radio station transmits traffic information
         * at the very moment.
         */
        public boolean isTrafficAnnouncementActive() {
            return (mInfoFlags & FLAG_TRAFFIC_ANNOUNCEMENT) != 0;
        }

        /**
         * Signal quality (as opposed to the name) indication from 0 (no signal)
         * to 100 (excellent)
         * @return the signal quality indication.
         */
        public int getSignalStrength() {
            return mSignalQuality;
        }

        /** Metadata currently received from this station.
         * null if no metadata have been received
         * @return current meta data received from this program.
         */
        public RadioMetadata getMetadata() {
            return mMetadata;
        }

        /**
         * A map of vendor-specific opaque strings, passed from HAL without changes.
         * Format of these strings can vary across vendors.
         *
         * It may be used for extra features, that's not supported by a platform,
         * for example: paid-service=true; bitrate=320kbps.
         *
         * Keys must be prefixed with unique vendor Java-style namespace,
         * eg. 'com.somecompany.parameter1'.
         */
        public @NonNull Map<String, String> getVendorInfo() {
            return mVendorInfo;
        }

        private ProgramInfo(Parcel in) {
            mSelector = Objects.requireNonNull(in.readTypedObject(ProgramSelector.CREATOR));
            mLogicallyTunedTo = in.readTypedObject(ProgramSelector.Identifier.CREATOR);
            mPhysicallyTunedTo = in.readTypedObject(ProgramSelector.Identifier.CREATOR);
            mRelatedContent = in.createTypedArrayList(ProgramSelector.Identifier.CREATOR);
            mInfoFlags = in.readInt();
            mSignalQuality = in.readInt();
            mMetadata = in.readTypedObject(RadioMetadata.CREATOR);
            mVendorInfo = Utils.readStringMap(in);
        }

        public static final @android.annotation.NonNull Parcelable.Creator<ProgramInfo> CREATOR
                = new Parcelable.Creator<ProgramInfo>() {
            public ProgramInfo createFromParcel(Parcel in) {
                return new ProgramInfo(in);
            }

            public ProgramInfo[] newArray(int size) {
                return new ProgramInfo[size];
            }
        };

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeTypedObject(mSelector, flags);
            dest.writeTypedObject(mLogicallyTunedTo, flags);
            dest.writeTypedObject(mPhysicallyTunedTo, flags);
            Utils.writeTypedCollection(dest, mRelatedContent);
            dest.writeInt(mInfoFlags);
            dest.writeInt(mSignalQuality);
            dest.writeTypedObject(mMetadata, flags);
            Utils.writeStringMap(dest, mVendorInfo);
        }

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

        @Override
        public String toString() {
            return "ProgramInfo"
                    + " [selector=" + mSelector
                    + ", logicallyTunedTo=" + Objects.toString(mLogicallyTunedTo)
                    + ", physicallyTunedTo=" + Objects.toString(mPhysicallyTunedTo)
                    + ", relatedContent=" + mRelatedContent.size()
                    + ", infoFlags=" + mInfoFlags
                    + ", mSignalQuality=" + mSignalQuality
                    + ", mMetadata=" + Objects.toString(mMetadata)
                    + "]";
        }

        @Override
        public int hashCode() {
            return Objects.hash(mSelector, mLogicallyTunedTo, mPhysicallyTunedTo,
                mRelatedContent, mInfoFlags, mSignalQuality, mMetadata, mVendorInfo);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof ProgramInfo)) return false;
            ProgramInfo other = (ProgramInfo) obj;

            if (!Objects.equals(mSelector, other.mSelector)) return false;
            if (!Objects.equals(mLogicallyTunedTo, other.mLogicallyTunedTo)) return false;
            if (!Objects.equals(mPhysicallyTunedTo, other.mPhysicallyTunedTo)) return false;
            if (!Objects.equals(mRelatedContent, other.mRelatedContent)) return false;
            if (mInfoFlags != other.mInfoFlags) return false;
            if (mSignalQuality != other.mSignalQuality) return false;
            if (!Objects.equals(mMetadata, other.mMetadata)) return false;
            if (!Objects.equals(mVendorInfo, other.mVendorInfo)) return false;

            return true;
        }
    }


    /**
     * Returns a list of descriptors for all broadcast radio modules present on the device.
     * @param modules An List of {@link ModuleProperties} where the list will be returned.
     * @return
     * <ul>
     *  <li>{@link #STATUS_OK} in case of success, </li>
     *  <li>{@link #STATUS_ERROR} in case of unspecified error, </li>
     *  <li>{@link #STATUS_NO_INIT} if the native service cannot be reached, </li>
     *  <li>{@link #STATUS_BAD_VALUE} if modules is null, </li>
     *  <li>{@link #STATUS_DEAD_OBJECT} if the binder transaction to the native service fails, </li>
     * </ul>
     */
    @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
    public int listModules(List<ModuleProperties> modules) {
        if (modules == null) {
            Log.e(TAG, "the output list must not be empty");
            return STATUS_BAD_VALUE;
        }

        Log.d(TAG, "Listing available tuners...");
        List<ModuleProperties> returnedList;
        try {
            returnedList = mService.listModules();
        } catch (RemoteException e) {
            Log.e(TAG, "Failed listing available tuners", e);
            return STATUS_DEAD_OBJECT;
        }

        if (returnedList == null) {
            Log.e(TAG, "Returned list was a null");
            return STATUS_ERROR;
        }

        modules.addAll(returnedList);
        return STATUS_OK;
    }

    private native int nativeListModules(List<ModuleProperties> modules);

    /**
     * Open an interface to control a tuner on a given broadcast radio module.
     * Optionally selects and applies the configuration passed as "config" argument.
     * @param moduleId radio module identifier {@link ModuleProperties#getId()}. Mandatory.
     * @param config desired band and configuration to apply when enabling the hardware module.
     * optional, can be null.
     * @param withAudio {@code true} to request a tuner with an audio source.
     * This tuner is intended for live listening or recording or a radio program.
     * If {@code false}, the tuner can only be used to retrieve program informations.
     * @param callback {@link RadioTuner.Callback} interface. Mandatory.
     * @param handler the Handler on which the callbacks will be received.
     * Can be null if default handler is OK.
     * @return a valid {@link RadioTuner} interface in case of success or null in case of error.
     */
    @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
    public RadioTuner openTuner(int moduleId, BandConfig config, boolean withAudio,
            RadioTuner.Callback callback, Handler handler) {
        if (callback == null) {
            throw new IllegalArgumentException("callback must not be empty");
        }

        Log.d(TAG, "Opening tuner " + moduleId + "...");

        ITuner tuner;
        TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
        try {
            tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
        } catch (RemoteException | IllegalArgumentException | IllegalStateException ex) {
            Log.e(TAG, "Failed to open tuner", ex);
            return null;
        }
        if (tuner == null) {
            Log.e(TAG, "Failed to open tuner");
            return null;
        }
        return new TunerAdapter(tuner, halCallback,
                config != null ? config.getType() : BAND_INVALID);
    }

    private final Map<Announcement.OnListUpdatedListener, ICloseHandle> mAnnouncementListeners =
            new HashMap<>();

    /**
     * Adds new announcement listener.
     *
     * @param enabledAnnouncementTypes a set of announcement types to listen to
     * @param listener announcement listener
     */
    @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
    public void addAnnouncementListener(@NonNull Set<Integer> enabledAnnouncementTypes,
            @NonNull Announcement.OnListUpdatedListener listener) {
        addAnnouncementListener(cmd -> cmd.run(), enabledAnnouncementTypes, listener);
    }

    /**
     * Adds new announcement listener with executor.
     *
     * @param executor the executor
     * @param enabledAnnouncementTypes a set of announcement types to listen to
     * @param listener announcement listener
     */
    @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
    public void addAnnouncementListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull Set<Integer> enabledAnnouncementTypes,
            @NonNull Announcement.OnListUpdatedListener listener) {
        Objects.requireNonNull(executor);
        Objects.requireNonNull(listener);
        int[] types = enabledAnnouncementTypes.stream().mapToInt(Integer::intValue).toArray();
        IAnnouncementListener listenerIface = new IAnnouncementListener.Stub() {
            public void onListUpdated(List<Announcement> activeAnnouncements) {
                executor.execute(() -> listener.onListUpdated(activeAnnouncements));
            }
        };
        synchronized (mAnnouncementListeners) {
            ICloseHandle closeHandle = null;
            try {
                closeHandle = mService.addAnnouncementListener(types, listenerIface);
            } catch (RemoteException ex) {
                ex.rethrowFromSystemServer();
            }
            Objects.requireNonNull(closeHandle);
            ICloseHandle oldCloseHandle = mAnnouncementListeners.put(listener, closeHandle);
            if (oldCloseHandle != null) Utils.close(oldCloseHandle);
        }
    }

    /**
     * Removes previously registered announcement listener.
     *
     * @param listener announcement listener, previously registered with
     *        {@link addAnnouncementListener}
     */
    @RequiresPermission(Manifest.permission.ACCESS_BROADCAST_RADIO)
    public void removeAnnouncementListener(@NonNull Announcement.OnListUpdatedListener listener) {
        Objects.requireNonNull(listener);
        synchronized (mAnnouncementListeners) {
            ICloseHandle closeHandle = mAnnouncementListeners.remove(listener);
            if (closeHandle != null) Utils.close(closeHandle);
        }
    }

    @NonNull private final Context mContext;
    @NonNull private final IRadioService mService;

    /**
     * @hide
     */
    public RadioManager(@NonNull Context context) throws ServiceNotFoundException {
        mContext = context;
        mService = IRadioService.Stub.asInterface(
                ServiceManager.getServiceOrThrow(Context.RADIO_SERVICE));
    }
}
