diff options
author | Justin Klaassen <justinklaassen@google.com> | 2018-04-03 23:21:57 -0400 |
---|---|---|
committer | Justin Klaassen <justinklaassen@google.com> | 2018-04-03 23:21:57 -0400 |
commit | 4d01eeaffaa720e4458a118baa137a11614f00f7 (patch) | |
tree | 66751893566986236788e3c796a7cc5e90d05f52 /android/hardware/radio | |
parent | a192cc2a132cb0ee8588e2df755563ec7008c179 (diff) | |
download | android-28-4d01eeaffaa720e4458a118baa137a11614f00f7.tar.gz |
Import Android SDK Platform P [4697573]
/google/data/ro/projects/android/fetch_artifact \
--bid 4697573 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4697573.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: If80578c3c657366cc9cf75f8db13d46e2dd4e077
Diffstat (limited to 'android/hardware/radio')
-rw-r--r-- | android/hardware/radio/ProgramList.java | 11 | ||||
-rw-r--r-- | android/hardware/radio/ProgramSelector.java | 9 | ||||
-rw-r--r-- | android/hardware/radio/RadioManager.java | 122 | ||||
-rw-r--r-- | android/hardware/radio/RadioMetadata.java | 49 | ||||
-rw-r--r-- | android/hardware/radio/RadioTuner.java | 61 | ||||
-rw-r--r-- | android/hardware/radio/TunerAdapter.java | 36 | ||||
-rw-r--r-- | android/hardware/radio/TunerCallbackAdapter.java | 51 | ||||
-rw-r--r-- | android/hardware/radio/Utils.java | 23 |
8 files changed, 284 insertions, 78 deletions
diff --git a/android/hardware/radio/ProgramList.java b/android/hardware/radio/ProgramList.java index b2aa9ba5..e6f523c0 100644 --- a/android/hardware/radio/ProgramList.java +++ b/android/hardware/radio/ProgramList.java @@ -263,6 +263,17 @@ public final class ProgramList implements AutoCloseable { /** * @hide for framework use only */ + public Filter() { + mIdentifierTypes = Collections.emptySet(); + mIdentifiers = Collections.emptySet(); + mIncludeCategories = false; + mExcludeModifications = false; + mVendorFilter = null; + } + + /** + * @hide for framework use only + */ public Filter(@Nullable Map<String, String> vendorFilter) { mIdentifierTypes = Collections.emptySet(); mIdentifiers = Collections.emptySet(); diff --git a/android/hardware/radio/ProgramSelector.java b/android/hardware/radio/ProgramSelector.java index 0294a29b..2a878ebb 100644 --- a/android/hardware/radio/ProgramSelector.java +++ b/android/hardware/radio/ProgramSelector.java @@ -441,6 +441,15 @@ public final class ProgramSelector implements Parcelable { */ public static @NonNull ProgramSelector createAmFmSelector( @RadioManager.Band int band, int frequencyKhz, int subChannel) { + if (band == RadioManager.BAND_INVALID) { + // 50MHz is a rough boundary between AM (<30MHz) and FM (>60MHz). + if (frequencyKhz < 50000) { + band = (subChannel <= 0) ? RadioManager.BAND_AM : RadioManager.BAND_AM_HD; + } else { + band = (subChannel <= 0) ? RadioManager.BAND_FM : RadioManager.BAND_FM_HD; + } + } + boolean isAm = (band == RadioManager.BAND_AM || band == RadioManager.BAND_AM_HD); boolean isDigital = (band == RadioManager.BAND_AM_HD || band == RadioManager.BAND_FM_HD); if (!isAm && !isDigital && band != RadioManager.BAND_FM) { diff --git a/android/hardware/radio/RadioManager.java b/android/hardware/radio/RadioManager.java index b00f6033..8263bb8d 100644 --- a/android/hardware/radio/RadioManager.java +++ b/android/hardware/radio/RadioManager.java @@ -21,10 +21,12 @@ 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; @@ -58,6 +60,7 @@ import java.util.stream.Collectors; */ @SystemApi @SystemService(Context.RADIO_SERVICE) +@RequiresFeature(PackageManager.FEATURE_BROADCAST_RADIO) public class RadioManager { private static final String TAG = "BroadcastRadio.manager"; @@ -208,19 +211,23 @@ public class RadioManager { 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 isCaptureSupported, BandDescriptor[] bands, boolean isBgScanSupported, + 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; @@ -231,11 +238,19 @@ public class RadioManager { 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; } @@ -317,6 +332,18 @@ public class RadioManager { 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. @@ -363,6 +390,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. * @@ -394,6 +434,7 @@ public class RadioManager { 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]; @@ -403,6 +444,7 @@ public class RadioManager { mIsBgScanSupported = in.readInt() == 1; mSupportedProgramTypes = arrayToSet(in.createIntArray()); mSupportedIdentifierTypes = arrayToSet(in.createIntArray()); + mDabFrequencyTable = Utils.readStringIntMap(in); mVendorInfo = Utils.readStringMap(in); } @@ -428,11 +470,13 @@ public class RadioManager { 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); } @@ -449,6 +493,7 @@ public class RadioManager { + ", mVersion=" + mVersion + ", mSerial=" + mSerial + ", mNumTuners=" + mNumTuners + ", mNumAudioSources=" + mNumAudioSources + + ", mIsInitializationRequired=" + mIsInitializationRequired + ", mIsCaptureSupported=" + mIsCaptureSupported + ", mIsBgScanSupported=" + mIsBgScanSupported + ", mBands=" + Arrays.toString(mBands) + "]"; @@ -456,67 +501,32 @@ 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, mIsInitializationRequired, + 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 (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; } } diff --git a/android/hardware/radio/RadioMetadata.java b/android/hardware/radio/RadioMetadata.java index 3cc4b566..6e510607 100644 --- a/android/hardware/radio/RadioMetadata.java +++ b/android/hardware/radio/RadioMetadata.java @@ -96,6 +96,48 @@ public final class RadioMetadata implements Parcelable { */ public static final String METADATA_KEY_CLOCK = "android.hardware.radio.metadata.CLOCK"; + /** + * Technology-independent program name (station name). + */ + public static final String METADATA_KEY_PROGRAM_NAME = + "android.hardware.radio.metadata.PROGRAM_NAME"; + + /** + * DAB ensemble name. + */ + public static final String METADATA_KEY_DAB_ENSEMBLE_NAME = + "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME"; + + /** + * DAB ensemble name - short version (up to 8 characters). + */ + public static final String METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT = + "android.hardware.radio.metadata.DAB_ENSEMBLE_NAME_SHORT"; + + /** + * DAB service name. + */ + public static final String METADATA_KEY_DAB_SERVICE_NAME = + "android.hardware.radio.metadata.DAB_SERVICE_NAME"; + + /** + * DAB service name - short version (up to 8 characters). + */ + public static final String METADATA_KEY_DAB_SERVICE_NAME_SHORT = + "android.hardware.radio.metadata.DAB_SERVICE_NAME_SHORT"; + + /** + * DAB component name. + */ + public static final String METADATA_KEY_DAB_COMPONENT_NAME = + "android.hardware.radio.metadata.DAB_COMPONENT_NAME"; + + /** + * DAB component name. + */ + public static final String METADATA_KEY_DAB_COMPONENT_NAME_SHORT = + "android.hardware.radio.metadata.DAB_COMPONENT_NAME_SHORT"; + private static final int METADATA_TYPE_INVALID = -1; private static final int METADATA_TYPE_INT = 0; @@ -119,6 +161,13 @@ public final class RadioMetadata implements Parcelable { METADATA_KEYS_TYPE.put(METADATA_KEY_ICON, METADATA_TYPE_BITMAP); METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP); METADATA_KEYS_TYPE.put(METADATA_KEY_CLOCK, METADATA_TYPE_CLOCK); + METADATA_KEYS_TYPE.put(METADATA_KEY_PROGRAM_NAME, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_SERVICE_NAME_SHORT, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME, METADATA_TYPE_TEXT); + METADATA_KEYS_TYPE.put(METADATA_KEY_DAB_COMPONENT_NAME_SHORT, METADATA_TYPE_TEXT); } // keep in sync with: system/media/radio/include/system/radio_metadata.h diff --git a/android/hardware/radio/RadioTuner.java b/android/hardware/radio/RadioTuner.java index ed20c4aa..0edd0553 100644 --- a/android/hardware/radio/RadioTuner.java +++ b/android/hardware/radio/RadioTuner.java @@ -64,7 +64,9 @@ public abstract class RadioTuner { * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native * service fails, </li> * </ul> + * @deprecated Only applicable for HAL 1.x. */ + @Deprecated public abstract int setConfiguration(RadioManager.BandConfig config); /** @@ -80,7 +82,10 @@ public abstract class RadioTuner { * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native * service fails, </li> * </ul> + * + * @deprecated Only applicable for HAL 1.x. */ + @Deprecated public abstract int getConfiguration(RadioManager.BandConfig[] config); @@ -228,7 +233,9 @@ public abstract class RadioTuner { * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native * service fails, </li> * </ul> + * @deprecated Use {@link onProgramInfoChanged} callback instead. */ + @Deprecated public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); /** @@ -427,7 +434,10 @@ public abstract class RadioTuner { * Get current antenna connection state for current configuration. * Only valid if a configuration has been applied. * @return {@code true} if the antenna is connected, {@code false} otherwise. + * + * @deprecated Use {@link onAntennaState} callback instead */ + @Deprecated public abstract boolean isAntennaConnected(); /** @@ -446,20 +456,41 @@ public abstract class RadioTuner { public abstract boolean hasControl(); /** Indicates a failure of radio IC or driver. - * The application must close and re open the tuner */ + * The application must close and re open the tuner + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_HARDWARE_FAILURE = 0; /** Indicates a failure of the radio service. - * The application must close and re open the tuner */ + * The application must close and re open the tuner + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_SERVER_DIED = 1; - /** A pending seek or tune operation was cancelled */ + /** A pending seek or tune operation was cancelled + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_CANCELLED = 2; - /** A pending seek or tune operation timed out */ + /** A pending seek or tune operation timed out + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_SCAN_TIMEOUT = 3; - /** The requested configuration could not be applied */ + /** The requested configuration could not be applied + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_CONFIG = 4; - /** Background scan was interrupted due to hardware becoming temporarily unavailable. */ + /** Background scan was interrupted due to hardware becoming temporarily unavailable. + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_BACKGROUND_SCAN_UNAVAILABLE = 5; - /** Background scan failed due to other error, ie. HW failure. */ + /** Background scan failed due to other error, ie. HW failure. + * @deprecated See {@link onError} callback. + */ + @Deprecated public static final int ERROR_BACKGROUND_SCAN_FAILED = 6; /** @@ -473,13 +504,29 @@ public abstract class RadioTuner { * status is one of {@link #ERROR_HARDWARE_FAILURE}, {@link #ERROR_SERVER_DIED}, * {@link #ERROR_CANCELLED}, {@link #ERROR_SCAN_TIMEOUT}, * {@link #ERROR_CONFIG} + * + * @deprecated Use {@link onTuneFailed} for tune, scan and step; + * other use cases (configuration, background scan) are already deprecated. */ public void onError(int status) {} + + /** + * Called when tune, scan or step operation fails. + * + * @param result cause of the failure + * @param selector ProgramSelector argument of tune that failed; + * null for scan and step. + */ + public void onTuneFailed(int result, @Nullable ProgramSelector selector) {} + /** * onConfigurationChanged() is called upon successful completion of * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)} * or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)} + * + * @deprecated Only applicable for HAL 1.x. */ + @Deprecated public void onConfigurationChanged(RadioManager.BandConfig config) {} /** diff --git a/android/hardware/radio/TunerAdapter.java b/android/hardware/radio/TunerAdapter.java index 91944bfd..be2846f8 100644 --- a/android/hardware/radio/TunerAdapter.java +++ b/android/hardware/radio/TunerAdapter.java @@ -60,6 +60,7 @@ class TunerAdapter extends RadioTuner { mLegacyListProxy.close(); mLegacyListProxy = null; } + mCallback.close(); } try { mTuner.close(); @@ -202,15 +203,17 @@ class TunerAdapter extends RadioTuner { @Override public int getProgramInformation(RadioManager.ProgramInfo[] info) { if (info == null || info.length != 1) { - throw new IllegalArgumentException("The argument must be an array of length 1"); + Log.e(TAG, "The argument must be an array of length 1"); + return RadioManager.STATUS_BAD_VALUE; } - try { - info[0] = mTuner.getProgramInformation(); - return RadioManager.STATUS_OK; - } catch (RemoteException e) { - Log.e(TAG, "service died", e); - return RadioManager.STATUS_DEAD_OBJECT; + + RadioManager.ProgramInfo current = mCallback.getCurrentProgramInformation(); + if (current == null) { + Log.w(TAG, "Didn't get program info yet"); + return RadioManager.STATUS_INVALID_OPERATION; } + info[0] = current; + return RadioManager.STATUS_OK; } @Override @@ -276,6 +279,7 @@ class TunerAdapter extends RadioTuner { try { mTuner.startProgramListUpdates(filter); } catch (UnsupportedOperationException ex) { + Log.i(TAG, "Program list is not supported with this hardware"); return null; } catch (RemoteException ex) { mCallback.setProgramListObserver(null, () -> { }); @@ -288,12 +292,20 @@ class TunerAdapter extends RadioTuner { @Override public boolean isAnalogForced() { - return isConfigFlagSet(RadioManager.CONFIG_FORCE_ANALOG); + try { + return isConfigFlagSet(RadioManager.CONFIG_FORCE_ANALOG); + } catch (UnsupportedOperationException ex) { + throw new IllegalStateException(ex); + } } @Override public void setAnalogForced(boolean isForced) { - setConfigFlag(RadioManager.CONFIG_FORCE_ANALOG, isForced); + try { + setConfigFlag(RadioManager.CONFIG_FORCE_ANALOG, isForced); + } catch (UnsupportedOperationException ex) { + throw new IllegalStateException(ex); + } } @Override @@ -343,11 +355,7 @@ class TunerAdapter extends RadioTuner { @Override public boolean isAntennaConnected() { - try { - return mTuner.isAntennaConnected(); - } catch (RemoteException e) { - throw new RuntimeException("service died", e); - } + return mCallback.isAntennaConnected(); } @Override diff --git a/android/hardware/radio/TunerCallbackAdapter.java b/android/hardware/radio/TunerCallbackAdapter.java index b299ffe0..0fb93e53 100644 --- a/android/hardware/radio/TunerCallbackAdapter.java +++ b/android/hardware/radio/TunerCallbackAdapter.java @@ -37,8 +37,12 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { @NonNull private final Handler mHandler; @Nullable ProgramList mProgramList; - @Nullable List<RadioManager.ProgramInfo> mLastCompleteList; // for legacy getProgramList call + + // cache for deprecated methods + boolean mIsAntennaConnected = true; + @Nullable List<RadioManager.ProgramInfo> mLastCompleteList; private boolean mDelayedCompleteCallback = false; + @Nullable RadioManager.ProgramInfo mCurrentProgramInfo; TunerCallbackAdapter(@NonNull RadioTuner.Callback callback, @Nullable Handler handler) { mCallback = callback; @@ -49,6 +53,12 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { } } + void close() { + synchronized (mLock) { + if (mProgramList != null) mProgramList.close(); + } + } + void setProgramListObserver(@Nullable ProgramList programList, @NonNull ProgramList.OnCloseListener closeListener) { Objects.requireNonNull(closeListener); @@ -92,12 +102,46 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { } } + @Nullable RadioManager.ProgramInfo getCurrentProgramInformation() { + synchronized (mLock) { + return mCurrentProgramInfo; + } + } + + boolean isAntennaConnected() { + return mIsAntennaConnected; + } + @Override public void onError(int status) { mHandler.post(() -> mCallback.onError(status)); } @Override + public void onTuneFailed(int status, @Nullable ProgramSelector selector) { + mHandler.post(() -> mCallback.onTuneFailed(status, selector)); + + int errorCode; + switch (status) { + case RadioManager.STATUS_PERMISSION_DENIED: + case RadioManager.STATUS_DEAD_OBJECT: + errorCode = RadioTuner.ERROR_SERVER_DIED; + break; + case RadioManager.STATUS_ERROR: + case RadioManager.STATUS_NO_INIT: + case RadioManager.STATUS_BAD_VALUE: + case RadioManager.STATUS_INVALID_OPERATION: + Log.i(TAG, "Got an error with no mapping to the legacy API (" + status + + "), doing a best-effort conversion to ERROR_SCAN_TIMEOUT"); + // fall through + case RadioManager.STATUS_TIMED_OUT: + default: + errorCode = RadioTuner.ERROR_SCAN_TIMEOUT; + } + mHandler.post(() -> mCallback.onError(errorCode)); + } + + @Override public void onConfigurationChanged(RadioManager.BandConfig config) { mHandler.post(() -> mCallback.onConfigurationChanged(config)); } @@ -109,6 +153,10 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { return; } + synchronized (mLock) { + mCurrentProgramInfo = info; + } + mHandler.post(() -> { mCallback.onProgramInfoChanged(info); @@ -129,6 +177,7 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { @Override public void onAntennaState(boolean connected) { + mIsAntennaConnected = connected; mHandler.post(() -> mCallback.onAntennaState(connected)); } diff --git a/android/hardware/radio/Utils.java b/android/hardware/radio/Utils.java index f1b58974..9887f782 100644 --- a/android/hardware/radio/Utils.java +++ b/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); |