/**
 * 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 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 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 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 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 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 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 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 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 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));
    }
}
