Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eab3e550 authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk
Browse files

Update ProgramInfo to match HAL 2.0 changes.

Bug: 70939328
Bug: 69958777
Test: instrumentation (none added)
Change-Id: Ia3065eb5f9fdd881d0eac603dd0c79b23b712be5
parent f151a7b3
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -1804,6 +1804,7 @@ package android.hardware.radio {
    method public deprecated int getProgramType();
    method public deprecated int getProgramType();
    method public android.hardware.radio.ProgramSelector.Identifier[] getSecondaryIds();
    method public android.hardware.radio.ProgramSelector.Identifier[] getSecondaryIds();
    method public deprecated long[] getVendorIds();
    method public deprecated long[] getVendorIds();
    method public android.hardware.radio.ProgramSelector withSecondaryPreferred(android.hardware.radio.ProgramSelector.Identifier);
    method public void writeToParcel(android.os.Parcel, int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.hardware.radio.ProgramSelector> CREATOR;
    field public static final android.os.Parcelable.Creator<android.hardware.radio.ProgramSelector> CREATOR;
    field public static final int IDENTIFIER_TYPE_AMFM_FREQUENCY = 1; // 0x1
    field public static final int IDENTIFIER_TYPE_AMFM_FREQUENCY = 1; // 0x1
@@ -1988,12 +1989,15 @@ package android.hardware.radio {
  public static class RadioManager.ProgramInfo implements android.os.Parcelable {
  public static class RadioManager.ProgramInfo implements android.os.Parcelable {
    method public int describeContents();
    method public int describeContents();
    method public deprecated int getChannel();
    method public deprecated int getChannel();
    method public android.hardware.radio.ProgramSelector.Identifier getLogicallyTunedTo();
    method public android.hardware.radio.RadioMetadata getMetadata();
    method public android.hardware.radio.RadioMetadata getMetadata();
    method public android.hardware.radio.ProgramSelector.Identifier getPhysicallyTunedTo();
    method public java.util.Collection<android.hardware.radio.ProgramSelector.Identifier> getRelatedContent();
    method public android.hardware.radio.ProgramSelector getSelector();
    method public android.hardware.radio.ProgramSelector getSelector();
    method public int getSignalStrength();
    method public int getSignalStrength();
    method public deprecated int getSubChannel();
    method public deprecated int getSubChannel();
    method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo();
    method public java.util.Map<java.lang.String, java.lang.String> getVendorInfo();
    method public boolean isDigital();
    method public deprecated boolean isDigital();
    method public boolean isLive();
    method public boolean isLive();
    method public boolean isMuted();
    method public boolean isMuted();
    method public boolean isStereo();
    method public boolean isStereo();
+33 −0
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.stream.Stream;
import java.util.stream.Stream;
@@ -362,6 +363,38 @@ public final class ProgramSelector implements Parcelable {
        return mVendorIds;
        return mVendorIds;
    }
    }


    /**
     * Creates an equivalent ProgramSelector with a given secondary identifier preferred.
     *
     * Used to point to a specific physical identifier for technologies that may broadcast the same
     * program on different channels. For example, with a DAB program broadcasted over multiple
     * ensembles, the radio hardware may select the one with the strongest signal. The UI may select
     * preferred ensemble though, so the radio hardware may try to use it in the first place.
     *
     * This is a best-effort hint for the tuner, not a guaranteed behavior.
     *
     * Setting the given secondary identifier as preferred means filtering out other secondary
     * identifiers of its type and adding it to the list.
     *
     * @param preferred preferred secondary identifier
     * @return a new ProgramSelector with a given secondary identifier preferred
     */
    public @NonNull ProgramSelector withSecondaryPreferred(@NonNull Identifier preferred) {
        int preferredType = preferred.getType();
        Identifier[] secondaryIds = Stream.concat(
            // remove other identifiers of that type
            Arrays.stream(mSecondaryIds).filter(id -> id.getType() != preferredType),
            // add preferred identifier instead
            Stream.of(preferred)).toArray(Identifier[]::new);

        return new ProgramSelector(
            mProgramType,
            mPrimaryId,
            secondaryIds,
            mVendorIds
        );
    }

    /**
    /**
     * Builds new ProgramSelector for AM/FM frequency.
     * Builds new ProgramSelector for AM/FM frequency.
     *
     *
+135 −87
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.SystemService;
@@ -33,9 +34,13 @@ import android.os.ServiceManager.ServiceNotFoundException;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;


import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
@@ -1382,35 +1387,44 @@ public class RadioManager {
        };
        };
    }
    }


    /** Radio program information returned by
    /** Radio program information. */
     * {@link RadioTuner#getProgramInformation(RadioManager.ProgramInfo[])} */
    public static class ProgramInfo implements Parcelable {
    public static class ProgramInfo implements Parcelable {


        // sourced from hardware/interfaces/broadcastradio/1.1/types.hal
        // sourced from hardware/interfaces/broadcastradio/2.0/types.hal
        private static final int FLAG_LIVE = 1 << 0;
        private static final int FLAG_LIVE = 1 << 0;
        private static final int FLAG_MUTED = 1 << 1;
        private static final int FLAG_MUTED = 1 << 1;
        private static final int FLAG_TRAFFIC_PROGRAM = 1 << 2;
        private static final int FLAG_TRAFFIC_PROGRAM = 1 << 2;
        private static final int FLAG_TRAFFIC_ANNOUNCEMENT = 1 << 3;
        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;
        @NonNull private final ProgramSelector mSelector;
        private final boolean mTuned;  // TODO(b/69958777): replace with mFlags
        @Nullable private final ProgramSelector.Identifier mLogicallyTunedTo;
        private final boolean mStereo;
        @Nullable private final ProgramSelector.Identifier mPhysicallyTunedTo;
        private final boolean mDigital;
        @NonNull private final Collection<ProgramSelector.Identifier> mRelatedContent;
        private final int mFlags;
        private final int mInfoFlags;
        private final int mSignalStrength;
        private final int mSignalQuality;
        private final RadioMetadata mMetadata;
        @Nullable private final RadioMetadata mMetadata;
        @NonNull private final Map<String, String> mVendorInfo;
        @NonNull private final Map<String, String> mVendorInfo;


        /** @hide */
        /** @hide */
        public ProgramInfo(@NonNull ProgramSelector selector, boolean tuned, boolean stereo,
        public ProgramInfo(@NonNull ProgramSelector selector,
                boolean digital, int signalStrength, RadioMetadata metadata, int flags,
                @Nullable ProgramSelector.Identifier logicallyTunedTo,
                Map<String, String> vendorInfo) {
                @Nullable ProgramSelector.Identifier physicallyTunedTo,
            mSelector = selector;
                @Nullable Collection<ProgramSelector.Identifier> relatedContent,
            mTuned = tuned;
                int infoFlags, int signalQuality, @Nullable RadioMetadata metadata,
            mStereo = stereo;
                @Nullable Map<String, String> vendorInfo) {
            mDigital = digital;
            mSelector = Objects.requireNonNull(selector);
            mFlags = flags;
            mLogicallyTunedTo = logicallyTunedTo;
            mSignalStrength = signalStrength;
            mPhysicallyTunedTo = physicallyTunedTo;
            if (relatedContent == null) {
                mRelatedContent = Collections.emptyList();
            } else {
                Preconditions.checkCollectionElementsNotNull(relatedContent, "relatedContent");
                mRelatedContent = relatedContent;
            }
            mInfoFlags = infoFlags;
            mSignalQuality = signalQuality;
            mMetadata = metadata;
            mMetadata = metadata;
            mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
            mVendorInfo = (vendorInfo == null) ? new HashMap<>() : vendorInfo;
        }
        }
@@ -1424,6 +1438,51 @@ public class RadioManager {
            return mSelector;
            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.
        /** Main channel expressed in units according to band type.
         * Currently all defined band types express channels as frequency in kHz
         * Currently all defined band types express channels as frequency in kHz
         * @return the program channel
         * @return the program channel
@@ -1458,19 +1517,28 @@ public class RadioManager {
         * @return {@code true} if currently tuned, {@code false} otherwise.
         * @return {@code true} if currently tuned, {@code false} otherwise.
         */
         */
        public boolean isTuned() {
        public boolean isTuned() {
            return mTuned;
            return (mInfoFlags & FLAG_TUNED) != 0;
        }
        }

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

        /** {@code true} if the received program is digital (e.g HD radio)
        /** {@code true} if the received program is digital (e.g HD radio)
         * @return {@code true} if digital, {@code false} otherwise.
         * @return {@code true} if digital, {@code false} otherwise.
         * @deprecated Use {@link getLogicallyTunedTo()} instead.
         */
         */
        @Deprecated
        public boolean isDigital() {
        public boolean isDigital() {
            return mDigital;
            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);
        }
        }


        /**
        /**
@@ -1479,7 +1547,7 @@ public class RadioManager {
         * usually targetted at reduced latency.
         * usually targetted at reduced latency.
         */
         */
        public boolean isLive() {
        public boolean isLive() {
            return (mFlags & FLAG_LIVE) != 0;
            return (mInfoFlags & FLAG_LIVE) != 0;
        }
        }


        /**
        /**
@@ -1489,7 +1557,7 @@ public class RadioManager {
         * It does NOT mean the user has muted audio.
         * It does NOT mean the user has muted audio.
         */
         */
        public boolean isMuted() {
        public boolean isMuted() {
            return (mFlags & FLAG_MUTED) != 0;
            return (mInfoFlags & FLAG_MUTED) != 0;
        }
        }


        /**
        /**
@@ -1497,7 +1565,7 @@ public class RadioManager {
         * regularily.
         * regularily.
         */
         */
        public boolean isTrafficProgram() {
        public boolean isTrafficProgram() {
            return (mFlags & FLAG_TRAFFIC_PROGRAM) != 0;
            return (mInfoFlags & FLAG_TRAFFIC_PROGRAM) != 0;
        }
        }


        /**
        /**
@@ -1505,15 +1573,18 @@ public class RadioManager {
         * at the very moment.
         * at the very moment.
         */
         */
        public boolean isTrafficAnnouncementActive() {
        public boolean isTrafficAnnouncementActive() {
            return (mFlags & FLAG_TRAFFIC_ANNOUNCEMENT) != 0;
            return (mInfoFlags & FLAG_TRAFFIC_ANNOUNCEMENT) != 0;
        }
        }


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

        /** Metadata currently received from this station.
        /** Metadata currently received from this station.
         * null if no metadata have been received
         * null if no metadata have been received
         * @return current meta data received from this program.
         * @return current meta data received from this program.
@@ -1537,17 +1608,13 @@ public class RadioManager {
        }
        }


        private ProgramInfo(Parcel in) {
        private ProgramInfo(Parcel in) {
            mSelector = in.readParcelable(null);
            mSelector = Objects.requireNonNull(in.readTypedObject(ProgramSelector.CREATOR));
            mTuned = in.readByte() == 1;
            mLogicallyTunedTo = in.readTypedObject(ProgramSelector.Identifier.CREATOR);
            mStereo = in.readByte() == 1;
            mPhysicallyTunedTo = in.readTypedObject(ProgramSelector.Identifier.CREATOR);
            mDigital = in.readByte() == 1;
            mRelatedContent = in.createTypedArrayList(ProgramSelector.Identifier.CREATOR);
            mSignalStrength = in.readInt();
            mInfoFlags = in.readInt();
            if (in.readByte() == 1) {
            mSignalQuality = in.readInt();
                mMetadata = RadioMetadata.CREATOR.createFromParcel(in);
            mMetadata = in.readTypedObject(RadioMetadata.CREATOR);
            } else {
                mMetadata = null;
            }
            mFlags = in.readInt();
            mVendorInfo = Utils.readStringMap(in);
            mVendorInfo = Utils.readStringMap(in);
        }
        }


@@ -1564,18 +1631,13 @@ public class RadioManager {


        @Override
        @Override
        public void writeToParcel(Parcel dest, int flags) {
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeParcelable(mSelector, 0);
            dest.writeTypedObject(mSelector, flags);
            dest.writeByte((byte)(mTuned ? 1 : 0));
            dest.writeTypedObject(mLogicallyTunedTo, flags);
            dest.writeByte((byte)(mStereo ? 1 : 0));
            dest.writeTypedObject(mPhysicallyTunedTo, flags);
            dest.writeByte((byte)(mDigital ? 1 : 0));
            Utils.writeTypedCollection(dest, mRelatedContent);
            dest.writeInt(mSignalStrength);
            dest.writeInt(mInfoFlags);
            if (mMetadata == null) {
            dest.writeInt(mSignalQuality);
                dest.writeByte((byte)0);
            dest.writeTypedObject(mMetadata, flags);
            } else {
                dest.writeByte((byte)1);
                mMetadata.writeToParcel(dest, flags);
            }
            dest.writeInt(mFlags);
            Utils.writeStringMap(dest, mVendorInfo);
            Utils.writeStringMap(dest, mVendorInfo);
        }
        }


@@ -1586,52 +1648,38 @@ public class RadioManager {


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


        @Override
        @Override
        public int hashCode() {
        public int hashCode() {
            final int prime = 31;
            return Objects.hash(mSelector, mLogicallyTunedTo, mPhysicallyTunedTo,
            int result = 1;
                mRelatedContent, mInfoFlags, mSignalQuality, mMetadata, mVendorInfo);
            result = prime * result + mSelector.hashCode();
            result = prime * result + (mTuned ? 1 : 0);
            result = prime * result + (mStereo ? 1 : 0);
            result = prime * result + (mDigital ? 1 : 0);
            result = prime * result + mFlags;
            result = prime * result + mSignalStrength;
            result = prime * result + ((mMetadata == null) ? 0 : mMetadata.hashCode());
            result = prime * result + mVendorInfo.hashCode();
            return result;
        }
        }


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

            if (mTuned != other.isTuned())
            if (!Objects.equals(mSelector, other.mSelector)) return false;
                return false;
            if (!Objects.equals(mLogicallyTunedTo, other.mLogicallyTunedTo)) return false;
            if (mStereo != other.isStereo())
            if (!Objects.equals(mPhysicallyTunedTo, other.mPhysicallyTunedTo)) return false;
                return false;
            if (!Objects.equals(mRelatedContent, other.mRelatedContent)) return false;
            if (mDigital != other.isDigital())
            if (mInfoFlags != other.mInfoFlags) return false;
                return false;
            if (mSignalQuality != other.mSignalQuality) return false;
            if (mFlags != other.mFlags)
            if (!Objects.equals(mMetadata, other.mMetadata)) return false;
                return false;
            if (!Objects.equals(mVendorInfo, other.mVendorInfo)) return false;
            if (mSignalStrength != other.getSignalStrength())

                return false;
            if (mMetadata == null) {
                if (other.getMetadata() != null)
                    return false;
            } else if (!mMetadata.equals(other.getMetadata()))
                return false;
            if (!mVendorInfo.equals(other.mVendorInfo)) return false;
            return true;
            return true;
        }
        }
    }
    }
+15 −0
Original line number Original line Diff line number Diff line
@@ -22,6 +22,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.RemoteException;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
import java.util.Map;
import java.util.Map;
@@ -93,6 +95,19 @@ final class Utils {
        });
        });
    }
    }


    static <T extends Parcelable> void writeTypedCollection(@NonNull Parcel dest,
            @Nullable Collection<T> coll) {
        ArrayList<T> list = null;
        if (coll != null) {
            if (coll instanceof ArrayList) {
                list = (ArrayList) coll;
            } else {
                list = new ArrayList<>(coll);
            }
        }
        dest.writeTypedList(list);
    }

    static void close(ICloseHandle handle) {
    static void close(ICloseHandle handle) {
        try {
        try {
            handle.close();
            handle.close();
+28 −18
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.hardware.broadcastradio.V2_0.AmFmBandRange;
import android.hardware.broadcastradio.V2_0.AmFmBandRange;
import android.hardware.broadcastradio.V2_0.AmFmRegionConfig;
import android.hardware.broadcastradio.V2_0.AmFmRegionConfig;
import android.hardware.broadcastradio.V2_0.Announcement;
import android.hardware.broadcastradio.V2_0.Announcement;
import android.hardware.broadcastradio.V2_0.IdentifierType;
import android.hardware.broadcastradio.V2_0.ProgramFilter;
import android.hardware.broadcastradio.V2_0.ProgramFilter;
import android.hardware.broadcastradio.V2_0.ProgramIdentifier;
import android.hardware.broadcastradio.V2_0.ProgramIdentifier;
import android.hardware.broadcastradio.V2_0.ProgramInfo;
import android.hardware.broadcastradio.V2_0.ProgramInfo;
@@ -37,6 +38,7 @@ import android.util.Slog;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.HashSet;
@@ -219,30 +221,37 @@ class Convert {
        return hwId;
        return hwId;
    }
    }


    static @NonNull ProgramSelector.Identifier programIdentifierFromHal(@NonNull ProgramIdentifier id) {
    static @Nullable ProgramSelector.Identifier programIdentifierFromHal(
            @NonNull ProgramIdentifier id) {
        if (id.type == IdentifierType.INVALID) return null;
        return new ProgramSelector.Identifier(id.type, id.value);
        return new ProgramSelector.Identifier(id.type, id.value);
    }
    }


    static @NonNull ProgramSelector programSelectorFromHal(
    static @NonNull ProgramSelector programSelectorFromHal(
            @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
            @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
        ProgramSelector.Identifier[] secondaryIds = sel.secondaryIds.stream().map(
        ProgramSelector.Identifier[] secondaryIds = sel.secondaryIds.stream().
            id -> programIdentifierFromHal(id)).toArray(ProgramSelector.Identifier[]::new);
                map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
                toArray(ProgramSelector.Identifier[]::new);


        return new ProgramSelector(
        return new ProgramSelector(
                identifierTypeToProgramType(sel.primaryId.type),
                identifierTypeToProgramType(sel.primaryId.type),
            programIdentifierFromHal(sel.primaryId),
                Objects.requireNonNull(programIdentifierFromHal(sel.primaryId)),
                secondaryIds, null);
                secondaryIds, null);
    }
    }


    static @NonNull RadioManager.ProgramInfo programInfoFromHal(@NonNull ProgramInfo info) {
    static @NonNull RadioManager.ProgramInfo programInfoFromHal(@NonNull ProgramInfo info) {
        Collection<ProgramSelector.Identifier> relatedContent = info.relatedContent.stream().
                map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
                collect(Collectors.toList());

        return new RadioManager.ProgramInfo(
        return new RadioManager.ProgramInfo(
                programSelectorFromHal(info.selector),
                programSelectorFromHal(info.selector),
            (info.infoFlags & ProgramInfoFlags.TUNED) != 0,
                programIdentifierFromHal(info.logicallyTunedTo),
            (info.infoFlags & ProgramInfoFlags.STEREO) != 0,
                programIdentifierFromHal(info.physicallyTunedTo),
            false,  // TODO(b/69860743): digital
                relatedContent,
                info.infoFlags,
                info.signalQuality,
                info.signalQuality,
                null,  // TODO(b/69860743): metadata
                null,  // TODO(b/69860743): metadata
            info.infoFlags,
                vendorInfoFromHal(info.vendorInfo)
                vendorInfoFromHal(info.vendorInfo)
        );
        );
    }
    }
@@ -260,10 +269,11 @@ class Convert {
    }
    }


    static @NonNull ProgramList.Chunk programListChunkFromHal(@NonNull ProgramListChunk chunk) {
    static @NonNull ProgramList.Chunk programListChunkFromHal(@NonNull ProgramListChunk chunk) {
        Set<RadioManager.ProgramInfo> modified = chunk.modified.stream().map(
        Set<RadioManager.ProgramInfo> modified = chunk.modified.stream().
            info -> programInfoFromHal(info)).collect(Collectors.toSet());
                map(info -> programInfoFromHal(info)).collect(Collectors.toSet());
        Set<ProgramSelector.Identifier> removed = chunk.removed.stream().map(
        Set<ProgramSelector.Identifier> removed = chunk.removed.stream().
            id -> programIdentifierFromHal(id)).collect(Collectors.toSet());
                map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
                collect(Collectors.toSet());


        return new ProgramList.Chunk(chunk.purge, chunk.complete, modified, removed);
        return new ProgramList.Chunk(chunk.purge, chunk.complete, modified, removed);
    }
    }
Loading