1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.radio; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.os.Message; 27 import java.lang.ref.WeakReference; 28 import java.util.List; 29 import java.util.UUID; 30 31 /** 32 * RadioTuner interface provides methods to control a radio tuner on the device: selecting and 33 * configuring the active band, muting/unmuting, scanning and tuning, etc... 34 * 35 * Obtain a RadioTuner interface by calling {@link RadioManager#openTuner(int, 36 * RadioManager.BandConfig, boolean, RadioTuner.Callback, Handler)}. 37 * @hide 38 */ 39 @SystemApi 40 public abstract class RadioTuner { 41 42 /** Scanning direction UP for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ 43 public static final int DIRECTION_UP = 0; 44 45 /** Scanning directions DOWN for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ 46 public static final int DIRECTION_DOWN = 1; 47 48 /** 49 * Close the tuner interface. The {@link Callback} callback will not be called 50 * anymore and associated resources will be released. 51 * Must be called when the tuner is not needed to make hardware resources available to others. 52 * */ close()53 public abstract void close(); 54 55 /** 56 * Set the active band configuration for this module. 57 * Must be a valid configuration obtained via buildConfig() from a valid BandDescriptor listed 58 * in the ModuleProperties of the module with the specified ID. 59 * @param config The desired band configuration (FmBandConfig or AmBandConfig). 60 * @return 61 * <ul> 62 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 63 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 64 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 65 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 66 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 67 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 68 * service fails, </li> 69 * </ul> 70 */ setConfiguration(RadioManager.BandConfig config)71 public abstract int setConfiguration(RadioManager.BandConfig config); 72 73 /** 74 * Get current configuration. 75 * @param config a BandConfig array of lengh 1 where the configuration is returned. 76 * @return 77 * <ul> 78 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 79 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 80 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 81 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 82 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 83 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 84 * service fails, </li> 85 * </ul> 86 */ getConfiguration(RadioManager.BandConfig[] config)87 public abstract int getConfiguration(RadioManager.BandConfig[] config); 88 89 90 /** 91 * Set mute state. When muted, the radio tuner audio source is not available for playback on 92 * any audio device. when unmuted, the radio tuner audio source is output as a media source 93 * and renderd over the audio device selected for media use case. 94 * The radio tuner audio source is muted by default when the tuner is first attached. 95 * Only effective if the tuner is attached with audio enabled. 96 * 97 * @param mute the requested mute state. 98 * @return 99 * <ul> 100 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 101 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 102 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 103 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 104 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 105 * service fails, </li> 106 * </ul> 107 */ setMute(boolean mute)108 public abstract int setMute(boolean mute); 109 110 /** 111 * Get mute state. 112 * 113 * @return {@code true} if the radio tuner audio source is muted or a problem occured 114 * retrieving the mute state, {@code false} otherwise. 115 */ getMute()116 public abstract boolean getMute(); 117 118 /** 119 * Step up or down by one channel spacing. 120 * The operation is asynchronous and {@link Callback} 121 * onProgramInfoChanged() will be called when step completes or 122 * onError() when cancelled or timeout. 123 * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. 124 * @param skipSubChannel indicates to skip sub channels when the configuration currently 125 * selected supports sub channel (e.g HD Radio). N/A otherwise. 126 * @return 127 * <ul> 128 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 129 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 130 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 131 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 132 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 133 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 134 * service fails, </li> 135 * </ul> 136 */ step(int direction, boolean skipSubChannel)137 public abstract int step(int direction, boolean skipSubChannel); 138 139 /** 140 * Scan up or down to next valid station. 141 * The operation is asynchronous and {@link Callback} 142 * onProgramInfoChanged() will be called when scan completes or 143 * onError() when cancelled or timeout. 144 * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. 145 * @param skipSubChannel indicates to skip sub channels when the configuration currently 146 * selected supports sub channel (e.g HD Radio). N/A otherwise. 147 * @return 148 * <ul> 149 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 150 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 151 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 152 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 153 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 154 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 155 * service fails, </li> 156 * </ul> 157 */ scan(int direction, boolean skipSubChannel)158 public abstract int scan(int direction, boolean skipSubChannel); 159 160 /** 161 * Tune to a specific frequency. 162 * The operation is asynchronous and {@link Callback} 163 * onProgramInfoChanged() will be called when tune completes or 164 * onError() when cancelled or timeout. 165 * @param channel the specific channel or frequency to tune to. 166 * @param subChannel the specific sub-channel to tune to. N/A if the selected configuration 167 * does not support cub channels. 168 * @return 169 * <ul> 170 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 171 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 172 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 173 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 174 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 175 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 176 * service fails, </li> 177 * </ul> 178 */ tune(int channel, int subChannel)179 public abstract int tune(int channel, int subChannel); 180 181 /** 182 * Cancel a pending scan or tune operation. 183 * If an operation is pending, {@link Callback} onError() will be called with 184 * {@link #ERROR_CANCELLED}. 185 * @return 186 * <ul> 187 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 188 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 189 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 190 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 191 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 192 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 193 * service fails, </li> 194 * </ul> 195 */ cancel()196 public abstract int cancel(); 197 198 /** 199 * Get current station information. 200 * @param info a ProgramInfo array of lengh 1 where the information is returned. 201 * @return 202 * <ul> 203 * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 204 * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 205 * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 206 * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 207 * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 208 * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 209 * service fails, </li> 210 * </ul> 211 */ getProgramInformation(RadioManager.ProgramInfo[] info)212 public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); 213 214 /** 215 * Get the list of discovered radio stations. 216 * 217 * To get the full list, set filter to null or empty string. Otherwise, client application 218 * must verify vendor product/name before setting this parameter to anything else. 219 * 220 * @param filter vendor-specific selector for radio stations. 221 * @return a list of radio stations. 222 * @throws IllegalStateException if the scan is in progress or has not been started. 223 * @throws IllegalArgumentException if the filter argument is not valid. 224 * @hide FutureFeature 225 */ getProgramList(@ullable String filter)226 public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter); 227 228 /** 229 * Get current antenna connection state for current configuration. 230 * Only valid if a configuration has been applied. 231 * @return {@code true} if the antenna is connected, {@code false} otherwise. 232 */ isAntennaConnected()233 public abstract boolean isAntennaConnected(); 234 235 /** 236 * Indicates if this client actually controls the tuner. 237 * Control is always granted after 238 * {@link RadioManager#openTuner(int, 239 * RadioManager.BandConfig, boolean, Callback, Handler)} 240 * returns a non null tuner interface. 241 * Control is lost when another client opens an interface on the same tuner. 242 * When this happens, {@link Callback#onControlChanged(boolean)} is received. 243 * The client can either wait for control to be returned (which is indicated by the same 244 * callback) or close and reopen the tuner interface. 245 * @return {@code true} if this interface controls the tuner, 246 * {@code false} otherwise or if a problem occured retrieving the state. 247 */ hasControl()248 public abstract boolean hasControl(); 249 250 /** Indicates a failure of radio IC or driver. 251 * The application must close and re open the tuner */ 252 public static final int ERROR_HARDWARE_FAILURE = 0; 253 /** Indicates a failure of the radio service. 254 * The application must close and re open the tuner */ 255 public static final int ERROR_SERVER_DIED = 1; 256 /** A pending seek or tune operation was cancelled */ 257 public static final int ERROR_CANCELLED = 2; 258 /** A pending seek or tune operation timed out */ 259 public static final int ERROR_SCAN_TIMEOUT = 3; 260 /** The requested configuration could not be applied */ 261 public static final int ERROR_CONFIG = 4; 262 263 /** 264 * Callback provided by the client application when opening a {@link RadioTuner} 265 * to receive asynchronous operation results, updates and error notifications. 266 */ 267 public static abstract class Callback { 268 /** 269 * onError() is called when an error occured while performing an asynchronous 270 * operation of when the hardware or system service experiences a problem. 271 * status is one of {@link #ERROR_HARDWARE_FAILURE}, {@link #ERROR_SERVER_DIED}, 272 * {@link #ERROR_CANCELLED}, {@link #ERROR_SCAN_TIMEOUT}, 273 * {@link #ERROR_CONFIG} 274 */ onError(int status)275 public void onError(int status) {} 276 /** 277 * onConfigurationChanged() is called upon successful completion of 278 * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)} 279 * or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)} 280 */ onConfigurationChanged(RadioManager.BandConfig config)281 public void onConfigurationChanged(RadioManager.BandConfig config) {} 282 /** 283 * onProgramInfoChanged() is called upon successful completion of 284 * {@link RadioTuner#step(int, boolean)}, {@link RadioTuner#scan(int, boolean)}, 285 * {@link RadioTuner#tune(int, int)} or when a switching to alternate frequency occurs. 286 * Note that if metadata only are updated, {@link #onMetadataChanged(RadioMetadata)} will 287 * be called. 288 */ onProgramInfoChanged(RadioManager.ProgramInfo info)289 public void onProgramInfoChanged(RadioManager.ProgramInfo info) {} 290 /** 291 * onMetadataChanged() is called when new meta data are received on current program. 292 * Meta data are also received in {@link RadioManager.ProgramInfo} when 293 * {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} is called. 294 */ onMetadataChanged(RadioMetadata metadata)295 public void onMetadataChanged(RadioMetadata metadata) {} 296 /** 297 * onTrafficAnnouncement() is called when a traffic announcement starts and stops. 298 */ onTrafficAnnouncement(boolean active)299 public void onTrafficAnnouncement(boolean active) {} 300 /** 301 * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops. 302 */ onEmergencyAnnouncement(boolean active)303 public void onEmergencyAnnouncement(boolean active) {} 304 /** 305 * onAntennaState() is called when the antenna is connected or disconnected. 306 */ onAntennaState(boolean connected)307 public void onAntennaState(boolean connected) {} 308 /** 309 * onControlChanged() is called when the client loses or gains control of the radio tuner. 310 * The control is always granted after a successful call to 311 * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}. 312 * If another client opens the same tuner, onControlChanged() will be called with 313 * control set to {@code false} to indicate loss of control. 314 * At this point, RadioTuner APIs other than getters will return 315 * {@link RadioManager#STATUS_INVALID_OPERATION}. 316 * When the other client releases the tuner, onControlChanged() will be called 317 * with control set to {@code true}. 318 */ onControlChanged(boolean control)319 public void onControlChanged(boolean control) {} 320 } 321 322 } 323 324