diff options
7 files changed, 89 insertions, 62 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index fd25e1bcd1e2..c0320aa26a08 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1986,6 +1986,7 @@ package android.hardware.radio { method public int describeContents(); method public android.hardware.radio.RadioManager.BandDescriptor[] getBands(); method public int getClassId(); + method public java.util.Map<java.lang.String, java.lang.Integer> getDabFrequencyTable(); method public int getId(); method public java.lang.String getImplementor(); method public int getNumAudioSources(); diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java index b00f6033976e..e1d7edfa7d9c 100644 --- a/core/java/android/hardware/radio/RadioManager.java +++ b/core/java/android/hardware/radio/RadioManager.java @@ -213,6 +213,7 @@ public class RadioManager { 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 */ @@ -221,6 +222,7 @@ public class RadioManager { 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; @@ -236,6 +238,13 @@ public class RadioManager { 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; } @@ -363,6 +372,19 @@ public class RadioManager { } /** + * 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. * @@ -403,6 +425,7 @@ public class RadioManager { mIsBgScanSupported = in.readInt() == 1; mSupportedProgramTypes = arrayToSet(in.createIntArray()); mSupportedIdentifierTypes = arrayToSet(in.createIntArray()); + mDabFrequencyTable = Utils.readStringIntMap(in); mVendorInfo = Utils.readStringMap(in); } @@ -433,6 +456,7 @@ public class RadioManager { dest.writeInt(mIsBgScanSupported ? 1 : 0); dest.writeIntArray(setToArray(mSupportedProgramTypes)); dest.writeIntArray(setToArray(mSupportedIdentifierTypes)); + Utils.writeStringIntMap(dest, mDabFrequencyTable); Utils.writeStringMap(dest, mVendorInfo); } @@ -456,67 +480,31 @@ public class RadioManager { @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + mId; - result = prime * result + mServiceName.hashCode(); - result = prime * result + mClassId; - result = prime * result + ((mImplementor == null) ? 0 : mImplementor.hashCode()); - result = prime * result + ((mProduct == null) ? 0 : mProduct.hashCode()); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - result = prime * result + ((mSerial == null) ? 0 : mSerial.hashCode()); - result = prime * result + mNumTuners; - result = prime * result + mNumAudioSources; - result = prime * result + (mIsCaptureSupported ? 1 : 0); - result = prime * result + Arrays.hashCode(mBands); - result = prime * result + (mIsBgScanSupported ? 1 : 0); - result = prime * result + mVendorInfo.hashCode(); - return result; + return Objects.hash(mId, mServiceName, mClassId, mImplementor, mProduct, mVersion, + mSerial, mNumTuners, mNumAudioSources, mIsCaptureSupported, mBands, + mIsBgScanSupported, mDabFrequencyTable, mVendorInfo); } @Override public boolean equals(Object obj) { - if (this == obj) - return true; - if (!(obj instanceof ModuleProperties)) - return false; + if (this == obj) return true; + if (!(obj instanceof ModuleProperties)) return false; ModuleProperties other = (ModuleProperties) obj; - if (mId != other.getId()) - return false; + + if (mId != other.getId()) return false; if (!TextUtils.equals(mServiceName, other.mServiceName)) return false; - if (mClassId != other.getClassId()) - return false; - if (mImplementor == null) { - if (other.getImplementor() != null) - return false; - } else if (!mImplementor.equals(other.getImplementor())) - return false; - if (mProduct == null) { - if (other.getProduct() != null) - return false; - } else if (!mProduct.equals(other.getProduct())) - return false; - if (mVersion == null) { - if (other.getVersion() != null) - return false; - } else if (!mVersion.equals(other.getVersion())) - return false; - if (mSerial == null) { - if (other.getSerial() != null) - return false; - } else if (!mSerial.equals(other.getSerial())) - return false; - if (mNumTuners != other.getNumTuners()) - return false; - if (mNumAudioSources != other.getNumAudioSources()) - return false; - if (mIsCaptureSupported != other.isCaptureSupported()) - return false; - if (!Arrays.equals(mBands, other.getBands())) - return false; - if (mIsBgScanSupported != other.isBackgroundScanningSupported()) - return false; - if (!mVendorInfo.equals(other.mVendorInfo)) 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 (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; } } diff --git a/core/java/android/hardware/radio/Utils.java b/core/java/android/hardware/radio/Utils.java index f1b589746a14..9887f7823269 100644 --- a/core/java/android/hardware/radio/Utils.java +++ b/core/java/android/hardware/radio/Utils.java @@ -56,6 +56,29 @@ final class Utils { return map; } + static void writeStringIntMap(@NonNull Parcel dest, @Nullable Map<String, Integer> map) { + if (map == null) { + dest.writeInt(0); + return; + } + dest.writeInt(map.size()); + for (Map.Entry<String, Integer> entry : map.entrySet()) { + dest.writeString(entry.getKey()); + dest.writeInt(entry.getValue()); + } + } + + static @NonNull Map<String, Integer> readStringIntMap(@NonNull Parcel in) { + int size = in.readInt(); + Map<String, Integer> map = new HashMap<>(); + while (size-- > 0) { + String key = in.readString(); + int value = in.readInt(); + map.put(key, value); + } + return map; + } + static <T extends Parcelable> void writeSet(@NonNull Parcel dest, @Nullable Set<T> set) { if (set == null) { dest.writeInt(0); diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java index f9b35f53d4d5..51e8ecfb0194 100644 --- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java +++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java @@ -48,7 +48,7 @@ class Tuner extends ITuner.Stub { private boolean mIsClosed = false; private boolean mIsMuted = false; - private int mRegion; // TODO(b/62710330): find better solution to handle regions + private int mRegion; private final boolean mWithAudio; Tuner(@NonNull ITunerCallback clientCallback, int halRev, diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java index 7a95971ca517..8e8169e2448a 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.hardware.broadcastradio.V2_0.AmFmBandRange; import android.hardware.broadcastradio.V2_0.AmFmRegionConfig; import android.hardware.broadcastradio.V2_0.Announcement; +import android.hardware.broadcastradio.V2_0.DabTableEntry; import android.hardware.broadcastradio.V2_0.IdentifierType; import android.hardware.broadcastradio.V2_0.ProgramFilter; import android.hardware.broadcastradio.V2_0.ProgramIdentifier; @@ -177,9 +178,15 @@ class Convert { return bands.toArray(new RadioManager.BandDescriptor[bands.size()]); } + private static @Nullable Map<String, Integer> dabConfigFromHal( + @Nullable List<DabTableEntry> config) { + if (config == null) return null; + return config.stream().collect(Collectors.toMap(e -> e.label, e -> e.frequency)); + } + static @NonNull RadioManager.ModuleProperties propertiesFromHal(int id, @NonNull String serviceName, @NonNull Properties prop, - @Nullable AmFmRegionConfig amfmConfig) { + @Nullable AmFmRegionConfig amfmConfig, @Nullable List<DabTableEntry> dabConfig) { Objects.requireNonNull(serviceName); Objects.requireNonNull(prop); @@ -209,6 +216,7 @@ class Convert { false, // isBgScanSupported is deprecated supportedProgramTypes, supportedIdentifierTypes, + dabConfigFromHal(dabConfig), vendorInfoFromHal(prop.vendorInfo) ); } diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index 4dff9e06000a..72f5bce8def2 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -22,6 +22,7 @@ import android.hardware.radio.ITuner; import android.hardware.radio.RadioManager; import android.hardware.broadcastradio.V2_0.AmFmRegionConfig; import android.hardware.broadcastradio.V2_0.Announcement; +import android.hardware.broadcastradio.V2_0.DabTableEntry; import android.hardware.broadcastradio.V2_0.IAnnouncementListener; import android.hardware.broadcastradio.V2_0.IBroadcastRadio; import android.hardware.broadcastradio.V2_0.ICloseHandle; @@ -56,12 +57,17 @@ class RadioModule { if (service == null) return null; Mutable<AmFmRegionConfig> amfmConfig = new Mutable<>(); - service.getAmFmRegionConfig(false, (int result, AmFmRegionConfig config) -> { + service.getAmFmRegionConfig(false, (result, config) -> { if (result == Result.OK) amfmConfig.value = config; }); - RadioManager.ModuleProperties prop = - Convert.propertiesFromHal(idx, fqName, service.getProperties(), amfmConfig.value); + Mutable<List<DabTableEntry>> dabConfig = new Mutable<>(); + service.getDabRegionConfig((result, config) -> { + if (result == Result.OK) dabConfig.value = config; + }); + + RadioManager.ModuleProperties prop = Convert.propertiesFromHal(idx, fqName, + service.getProperties(), amfmConfig.value, dabConfig.value); return new RadioModule(service, prop); } catch (RemoteException ex) { diff --git a/services/core/jni/BroadcastRadio/convert.cpp b/services/core/jni/BroadcastRadio/convert.cpp index 8c38e0a9e363..847222ae4ba1 100644 --- a/services/core/jni/BroadcastRadio/convert.cpp +++ b/services/core/jni/BroadcastRadio/convert.cpp @@ -395,7 +395,8 @@ static JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Propert gjni.ModuleProperties.cstor, moduleId, jServiceName.get(), prop10.classId, jImplementor.get(), jProduct.get(), jVersion.get(), jSerial.get(), prop10.numTuners, prop10.numAudioSources, prop10.supportsCapture, jBands.get(), isBgScanSupported, - jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(), jVendorInfo.get())); + jSupportedProgramTypes.get(), jSupportedIdentifierTypes.get(), nullptr, + jVendorInfo.get())); } JavaRef<jobject> ModulePropertiesFromHal(JNIEnv *env, const V1_0::Properties &properties, @@ -712,7 +713,7 @@ void register_android_server_broadcastradio_convert(JNIEnv *env) { gjni.ModuleProperties.cstor = GetMethodIDOrDie(env, modulePropertiesClass, "<init>", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;IIZ[Landroid/hardware/radio/RadioManager$BandDescriptor;Z" - "[I[ILjava/util/Map;)V"); + "[I[ILjava/util/Map;Ljava/util/Map;)V"); auto programInfoClass = FindClassOrDie(env, "android/hardware/radio/RadioManager$ProgramInfo"); gjni.ProgramInfo.clazz = MakeGlobalRefOrDie(env, programInfoClass); |