/* * 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.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.graphics.Bitmap; import android.os.Handler; import java.util.List; import java.util.Map; /** * RadioTuner interface provides methods to control a radio tuner on the device: selecting and * configuring the active band, muting/unmuting, scanning and tuning, etc... * * Obtain a RadioTuner interface by calling {@link RadioManager#openTuner(int, * RadioManager.BandConfig, boolean, RadioTuner.Callback, Handler)}. * @hide */ @SystemApi public abstract class RadioTuner { /** Scanning direction UP for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ public static final int DIRECTION_UP = 0; /** Scanning directions DOWN for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ public static final int DIRECTION_DOWN = 1; /** * Close the tuner interface. The {@link Callback} callback will not be called * anymore and associated resources will be released. * Must be called when the tuner is not needed to make hardware resources available to others. * */ public abstract void close(); /** * Set the active band configuration for this module. * Must be a valid configuration obtained via buildConfig() from a valid BandDescriptor listed * in the ModuleProperties of the module with the specified ID. * @param config The desired band configuration (FmBandConfig or AmBandConfig). * @return * * @deprecated Only applicable for HAL 1.x. */ @Deprecated public abstract int setConfiguration(RadioManager.BandConfig config); /** * Get current configuration. * @param config a BandConfig array of lengh 1 where the configuration is returned. * @return * * * @deprecated Only applicable for HAL 1.x. */ @Deprecated public abstract int getConfiguration(RadioManager.BandConfig[] config); /** * Set mute state. When muted, the radio tuner audio source is not available for playback on * any audio device. when unmuted, the radio tuner audio source is output as a media source * and renderd over the audio device selected for media use case. * The radio tuner audio source is muted by default when the tuner is first attached. * Only effective if the tuner is attached with audio enabled. * * @param mute the requested mute state. * @return * */ public abstract int setMute(boolean mute); /** * Get mute state. * * @return {@code true} if the radio tuner audio source is muted or a problem occured * retrieving the mute state, {@code false} otherwise. */ public abstract boolean getMute(); /** * Step up or down by one channel spacing. * The operation is asynchronous and {@link Callback} * onProgramInfoChanged() will be called when step completes or * onError() when cancelled or timeout. * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. * @param skipSubChannel indicates to skip sub channels when the configuration currently * selected supports sub channel (e.g HD Radio). N/A otherwise. * @return * */ public abstract int step(int direction, boolean skipSubChannel); /** * Scan up or down to next valid station. * The operation is asynchronous and {@link Callback} * onProgramInfoChanged() will be called when scan completes or * onError() when cancelled or timeout. * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. * @param skipSubChannel indicates to skip sub channels when the configuration currently * selected supports sub channel (e.g HD Radio). N/A otherwise. * @return * */ public abstract int scan(int direction, boolean skipSubChannel); /** * Tune to a specific frequency. * The operation is asynchronous and {@link Callback} * onProgramInfoChanged() will be called when tune completes or * onError() when cancelled or timeout. * @param channel the specific channel or frequency to tune to. * @param subChannel the specific sub-channel to tune to. N/A if the selected configuration * does not support cub channels. * @return * * @deprecated Use {@link tune(ProgramSelector)} instead. */ @Deprecated public abstract int tune(int channel, int subChannel); /** * Tune to a program. * * The operation is asynchronous and {@link Callback} onProgramInfoChanged() will be called * when tune completes or onError() when cancelled or on timeout. * * @throws IllegalArgumentException if the provided selector is invalid */ public abstract void tune(@NonNull ProgramSelector selector); /** * Cancel a pending scan or tune operation. * If an operation is pending, {@link Callback} onError() will be called with * {@link #ERROR_CANCELLED}. * @return * */ public abstract int cancel(); /** * Cancels traffic or emergency announcement. * * If there was no announcement to cancel, no action is taken. * * There is a race condition between calling cancelAnnouncement and the actual announcement * being finished, so onTrafficAnnouncement / onEmergencyAnnouncement callback should be * tracked with proper locking. */ public abstract void cancelAnnouncement(); /** * Get current station information. * @param info a ProgramInfo array of lengh 1 where the information is returned. * @return * * @deprecated Use {@link onProgramInfoChanged} callback instead. */ @Deprecated public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); /** * Retrieves a {@link Bitmap} for the given image ID or null, * if the image was missing from the tuner. * * This involves doing a call to the tuner, so the bitmap should be cached * on the application side. * * If the method returns null for non-zero ID, it means the image was * updated on the tuner side. There is a race conditon between fetching * image for an old ID and tuner updating the image (and cleaning up the * old image). In such case, a new ProgramInfo with updated image id will * be sent with a {@link onProgramInfoChanged} callback. * * @param id The image identifier, retrieved with * {@link RadioMetadata#getBitmapId(String)}. * @return A {@link Bitmap} or null. * @throws IllegalArgumentException if id==0 * @hide This API is not thoroughly elaborated yet */ public abstract @Nullable Bitmap getMetadataImage(int id); /** * Initiates a background scan to update internally cached program list. * * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot. * * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will * be called if the return value of this call was {@code true}. As result of this call * programListChanged may be triggered (if the scanned list differs). * * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device * or permanently if the feature is not supported * (see ModuleProperties#isBackgroundScanningSupported()). */ public abstract boolean startBackgroundScan(); /** * Get the list of discovered radio stations. * * To get the full list, set filter to null or empty map. * Keys must be prefixed with unique vendor Java-style namespace, * eg. 'com.somecompany.parameter1'. * * @param vendorFilter vendor-specific selector for radio stations. * @return a list of radio stations. * @throws IllegalStateException if the scan is in progress or has not been started, * startBackgroundScan() call may fix it. * @throws IllegalArgumentException if the vendorFilter argument is not valid. * @deprecated Use {@link getDynamicProgramList} instead. */ @Deprecated public abstract @NonNull List getProgramList(@Nullable Map vendorFilter); /** * Get the dynamic list of discovered radio stations. * * The list object is updated asynchronously; to get the updates register * with {@link ProgramList#addListCallback}. * * When the returned object is no longer used, it must be closed. * * @param filter filter for the list, or null to get the full list. * @return the dynamic program list object, close it after use * or {@code null} if program list is not supported by the tuner */ public @Nullable ProgramList getDynamicProgramList(@Nullable ProgramList.Filter filter) { return null; } /** * Checks, if the analog playback is forced, see setAnalogForced. * * @throws IllegalStateException if the switch is not supported at current * configuration. * @return {@code true} if analog is forced, {@code false} otherwise. * @deprecated Use {@link isConfigFlagSet(int)} instead. */ @Deprecated public abstract boolean isAnalogForced(); /** * 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 managed from the HAL implementation side. * * Some radio technologies may not support this, ie. DAB. * * @param isForced {@code true} to force analog, {@code false} for a default behaviour. * @throws IllegalStateException if the switch is not supported at current * configuration. * @deprecated Use {@link setConfigFlag(int, boolean)} instead. */ @Deprecated public abstract void setAnalogForced(boolean isForced); /** * Checks, if a given config flag is supported * * @param flag Flag to check. * @return True, if the flag is supported. */ public boolean isConfigFlagSupported(@RadioManager.ConfigFlag int flag) { return false; } /** * Fetches the current setting of a given config flag. * * The success/failure result is consistent with isConfigFlagSupported. * * @param flag Flag to fetch. * @return The current value of the flag. * @throws IllegalStateException if the flag is not applicable right now. * @throws UnsupportedOperationException if the flag is not supported at all. */ public boolean isConfigFlagSet(@RadioManager.ConfigFlag int flag) { throw new UnsupportedOperationException(); } /** * Sets the config flag. * * The success/failure result is consistent with isConfigFlagSupported. * * @param flag Flag to set. * @param value The new value of a given flag. * @throws IllegalStateException if the flag is not applicable right now. * @throws UnsupportedOperationException if the flag is not supported at all. */ public void setConfigFlag(@RadioManager.ConfigFlag int flag, boolean value) { throw new UnsupportedOperationException(); } /** * Generic method for setting vendor-specific parameter values. * The framework does not interpret the parameters, they are passed * in an opaque manner between a vendor application and HAL. * * Framework does not make any assumptions on the keys or values, other than * ones stated in VendorKeyValue documentation (a requirement of key * prefixes). * See VendorKeyValue at hardware/interfaces/broadcastradio/2.0/types.hal. * * For each pair in the result map, the key will be one of the keys * contained in the input (possibly with wildcards expanded), and the value * will be a vendor-specific result status (such as "OK" or an error code). * The implementation may choose to return an empty map, or only return * a status for a subset of the provided inputs, at its discretion. * * Application and HAL must not use keys with unknown prefix. In particular, * it must not place a key-value pair in results vector for unknown key from * parameters vector - instead, an unknown key should simply be ignored. * In other words, results vector may contain a subset of parameter keys * (however, the framework doesn't enforce a strict subset - the only * formal requirement is vendor domain prefix for keys). * * @param parameters Vendor-specific key-value pairs. * @return Operation completion status for parameters being set. */ public @NonNull Map setParameters(@NonNull Map parameters) { throw new UnsupportedOperationException(); } /** * Generic method for retrieving vendor-specific parameter values. * The framework does not interpret the parameters, they are passed * in an opaque manner between a vendor application and HAL. * * Framework does not cache set/get requests, so it's possible for * getParameter to return a different value than previous setParameter call. * * The syntax and semantics of keys are up to the vendor (as long as prefix * rules are obeyed). For instance, vendors may include some form of * wildcard support. In such case, result vector may be of different size * than requested keys vector. However, wildcards are not recognized by * framework and they are passed as-is to the HAL implementation. * * Unknown keys must be ignored and not placed into results vector. * * @param keys Parameter keys to fetch. * @return Vendor-specific key-value pairs. */ public @NonNull Map getParameters(@NonNull List keys) { throw new UnsupportedOperationException(); } /** * 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(); /** * Indicates if this client actually controls the tuner. * Control is always granted after * {@link RadioManager#openTuner(int, * RadioManager.BandConfig, boolean, Callback, Handler)} * returns a non null tuner interface. * Control is lost when another client opens an interface on the same tuner. * When this happens, {@link Callback#onControlChanged(boolean)} is received. * The client can either wait for control to be returned (which is indicated by the same * callback) or close and reopen the tuner interface. * @return {@code true} if this interface controls the tuner, * {@code false} otherwise or if a problem occured retrieving the state. */ public abstract boolean hasControl(); /** Indicates a failure of radio IC or driver. * 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 * @deprecated See {@link onError} callback. */ @Deprecated public static final int ERROR_SERVER_DIED = 1; /** 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 * @deprecated See {@link onError} callback. */ @Deprecated public static final int ERROR_SCAN_TIMEOUT = 3; /** 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. * @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. * @deprecated See {@link onError} callback. */ @Deprecated public static final int ERROR_BACKGROUND_SCAN_FAILED = 6; /** * Callback provided by the client application when opening a {@link RadioTuner} * to receive asynchronous operation results, updates and error notifications. */ public static abstract class Callback { /** * onError() is called when an error occured while performing an asynchronous * operation of when the hardware or system service experiences a problem. * 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) {} /** * Called when program info (including metadata) for the current program has changed. * * It happens either upon successful completion of {@link RadioTuner#step(int, boolean)}, * {@link RadioTuner#scan(int, boolean)}, {@link RadioTuner#tune(int, int)}; when * a switching to alternate frequency occurs; or when metadata is updated. */ public void onProgramInfoChanged(RadioManager.ProgramInfo info) {} /** * Called when metadata is updated for the current program. * * @deprecated Use {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} instead. */ @Deprecated public void onMetadataChanged(RadioMetadata metadata) {} /** * onTrafficAnnouncement() is called when a traffic announcement starts and stops. */ public void onTrafficAnnouncement(boolean active) {} /** * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops. */ public void onEmergencyAnnouncement(boolean active) {} /** * onAntennaState() is called when the antenna is connected or disconnected. */ public void onAntennaState(boolean connected) {} /** * onControlChanged() is called when the client loses or gains control of the radio tuner. * The control is always granted after a successful call to * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}. * If another client opens the same tuner, onControlChanged() will be called with * control set to {@code false} to indicate loss of control. * At this point, RadioTuner APIs other than getters will return * {@link RadioManager#STATUS_INVALID_OPERATION}. * When the other client releases the tuner, onControlChanged() will be called * with control set to {@code true}. */ public void onControlChanged(boolean control) {} /** * onBackgroundScanAvailabilityChange() is called when background scan * feature becomes available or not. * * @param isAvailable true, if the tuner turned temporarily background- * capable, false in the other case. */ public void onBackgroundScanAvailabilityChange(boolean isAvailable) {} /** * Called when a background scan completes successfully. */ public void onBackgroundScanComplete() {} /** * Called when available program list changed. * * Use {@link RadioTuner#getProgramList(String)} to get an actual list. */ public void onProgramListChanged() {} /** * Generic callback for passing updates to vendor-specific parameter values. * The framework does not interpret the parameters, they are passed * in an opaque manner between a vendor application and HAL. * * It's up to the HAL implementation if and how to implement this callback, * as long as it obeys the prefix rule. In particular, only selected keys * may be notified this way. However, setParameters must not trigger * this callback, while an internal event can change parameters * asynchronously. * * @param parameters Vendor-specific key-value pairs. */ public void onParametersUpdated(@NonNull Map parameters) {} } }