RadioTuner.java revision 8cfb0e81fdd91b7fe1c02287394ac068287281d5
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
17package android.hardware.radio;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SystemApi;
22import android.os.Handler;
23
24import java.util.List;
25
26/**
27 * RadioTuner interface provides methods to control a radio tuner on the device: selecting and
28 * configuring the active band, muting/unmuting, scanning and tuning, etc...
29 *
30 * Obtain a RadioTuner interface by calling {@link RadioManager#openTuner(int,
31 * RadioManager.BandConfig, boolean, RadioTuner.Callback, Handler)}.
32 * @hide
33 */
34@SystemApi
35public abstract class RadioTuner {
36
37    /** Scanning direction UP for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */
38    public static final int DIRECTION_UP      = 0;
39
40    /** Scanning directions DOWN for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */
41    public static final int DIRECTION_DOWN    = 1;
42
43    /**
44     * Close the tuner interface. The {@link Callback} callback will not be called
45     * anymore and associated resources will be released.
46     * Must be called when the tuner is not needed to make hardware resources available to others.
47     * */
48    public abstract void close();
49
50    /**
51     * Set the active band configuration for this module.
52     * Must be a valid configuration obtained via buildConfig() from a valid BandDescriptor listed
53     * in the ModuleProperties of the module with the specified ID.
54     * @param config The desired band configuration (FmBandConfig or AmBandConfig).
55     * @return
56     * <ul>
57     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
58     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
59     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
60     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
61     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
62     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
63     *  service fails, </li>
64     * </ul>
65     */
66    public abstract int setConfiguration(RadioManager.BandConfig config);
67
68    /**
69     * Get current configuration.
70     * @param config a BandConfig array of lengh 1 where the configuration is returned.
71     * @return
72     * <ul>
73     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
74     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
75     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
76     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
77     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
78     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
79     *  service fails, </li>
80     * </ul>
81     */
82    public abstract int getConfiguration(RadioManager.BandConfig[] config);
83
84
85    /**
86     * Set mute state. When muted, the radio tuner audio source is not available for playback on
87     * any audio device. when unmuted, the radio tuner audio source is output as a media source
88     * and renderd over the audio device selected for media use case.
89     * The radio tuner audio source is muted by default when the tuner is first attached.
90     * Only effective if the tuner is attached with audio enabled.
91     *
92     * @param mute the requested mute state.
93     * @return
94     * <ul>
95     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
96     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
97     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
98     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
99     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
100     *  service fails, </li>
101     * </ul>
102     */
103    public abstract int setMute(boolean mute);
104
105    /**
106     * Get mute state.
107     *
108     * @return {@code true} if the radio tuner audio source is muted or a problem occured
109     * retrieving the mute state, {@code false} otherwise.
110     */
111    public abstract boolean getMute();
112
113    /**
114     * Step up or down by one channel spacing.
115     * The operation is asynchronous and {@link Callback}
116     * onProgramInfoChanged() will be called when step completes or
117     * onError() when cancelled or timeout.
118     * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}.
119     * @param skipSubChannel indicates to skip sub channels when the configuration currently
120     * selected supports sub channel (e.g HD Radio). N/A otherwise.
121     * @return
122     * <ul>
123     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
124     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
125     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
126     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
127     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
128     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
129     *  service fails, </li>
130     * </ul>
131     */
132    public abstract int step(int direction, boolean skipSubChannel);
133
134    /**
135     * Scan up or down to next valid station.
136     * The operation is asynchronous and {@link Callback}
137     * onProgramInfoChanged() will be called when scan completes or
138     * onError() when cancelled or timeout.
139     * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}.
140     * @param skipSubChannel indicates to skip sub channels when the configuration currently
141     * selected supports sub channel (e.g HD Radio). N/A otherwise.
142     * @return
143     * <ul>
144     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
145     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
146     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
147     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
148     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
149     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
150     *  service fails, </li>
151     * </ul>
152     */
153    public abstract int scan(int direction, boolean skipSubChannel);
154
155    /**
156     * Tune to a specific frequency.
157     * The operation is asynchronous and {@link Callback}
158     * onProgramInfoChanged() will be called when tune completes or
159     * onError() when cancelled or timeout.
160     * @param channel the specific channel or frequency to tune to.
161     * @param subChannel the specific sub-channel to tune to. N/A if the selected configuration
162     * does not support cub channels.
163     * @return
164     * <ul>
165     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
166     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
167     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
168     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
169     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
170     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
171     *  service fails, </li>
172     * </ul>
173     * @deprecated Use {@link tune(ProgramSelector)} instead.
174     */
175    @Deprecated
176    public abstract int tune(int channel, int subChannel);
177
178    /**
179     * Tune to a program.
180     *
181     * The operation is asynchronous and {@link Callback} onProgramInfoChanged() will be called
182     * when tune completes or onError() when cancelled or on timeout.
183     *
184     * @thows IllegalArgumentException if the provided selector is invalid
185     */
186    public abstract void tune(@NonNull ProgramSelector selector);
187
188    /**
189     * Cancel a pending scan or tune operation.
190     * If an operation is pending, {@link Callback} onError() will be called with
191     * {@link #ERROR_CANCELLED}.
192     * @return
193     * <ul>
194     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
195     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
196     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
197     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
198     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
199     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
200     *  service fails, </li>
201     * </ul>
202     */
203    public abstract int cancel();
204
205    /**
206     * Get current station information.
207     * @param info a ProgramInfo array of lengh 1 where the information is returned.
208     * @return
209     * <ul>
210     *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
211     *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
212     *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
213     *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
214     *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
215     *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
216     *  service fails, </li>
217     * </ul>
218     */
219    public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
220
221    /**
222     * Initiates a background scan to update internally cached program list.
223     *
224     * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot.
225     *
226     * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will
227     * be called if the return value of this call was {@code true}. As result of this call
228     * programListChanged may be triggered (if the scanned list differs).
229     *
230     * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature
231     * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device
232     * or permanently if the feature is not supported
233     * (see ModuleProperties#isBackgroundScanningSupported()).
234     */
235    public abstract boolean startBackgroundScan();
236
237    /**
238     * Get the list of discovered radio stations.
239     *
240     * To get the full list, set filter to null or empty string. Otherwise, client application
241     * must verify vendor product/name before setting this parameter to anything else.
242     *
243     * @param filter vendor-specific selector for radio stations.
244     * @return a list of radio stations.
245     * @throws IllegalStateException if the scan is in progress or has not been started,
246     *         startBackgroundScan() call may fix it.
247     * @throws IllegalArgumentException if the filter argument is not valid.
248     */
249    public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter);
250
251    /**
252     * Checks, if the analog playback is forced, see setAnalogForced.
253     *
254     * @throws IllegalStateException if the switch is not supported at current
255     *         configuration.
256     * @return {@code true} if analog is forced, {@code false} otherwise.
257     */
258    public abstract boolean isAnalogForced();
259
260    /**
261     * Forces the analog playback for the supporting radio technology.
262     *
263     * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
264     * this option. This is purely user choice, ie. does not reflect digital-
265     * analog handover managed from the HAL implementation side.
266     *
267     * Some radio technologies may not support this, ie. DAB.
268     *
269     * @param isForced {@code true} to force analog, {@code false} for a default behaviour.
270     * @throws IllegalStateException if the switch is not supported at current
271     *         configuration.
272     */
273    public abstract void setAnalogForced(boolean isForced);
274
275    /**
276     * Get current antenna connection state for current configuration.
277     * Only valid if a configuration has been applied.
278     * @return {@code true} if the antenna is connected, {@code false} otherwise.
279     */
280    public abstract boolean isAntennaConnected();
281
282    /**
283     * Indicates if this client actually controls the tuner.
284     * Control is always granted after
285     * {@link RadioManager#openTuner(int,
286     * RadioManager.BandConfig, boolean, Callback, Handler)}
287     * returns a non null tuner interface.
288     * Control is lost when another client opens an interface on the same tuner.
289     * When this happens, {@link Callback#onControlChanged(boolean)} is received.
290     * The client can either wait for control to be returned (which is indicated by the same
291     * callback) or close and reopen the tuner interface.
292     * @return {@code true} if this interface controls the tuner,
293     * {@code false} otherwise or if a problem occured retrieving the state.
294     */
295    public abstract boolean hasControl();
296
297    /** Indicates a failure of radio IC or driver.
298     * The application must close and re open the tuner */
299    public static final int ERROR_HARDWARE_FAILURE = 0;
300    /** Indicates a failure of the radio service.
301     * The application must close and re open the tuner */
302    public static final  int ERROR_SERVER_DIED = 1;
303    /** A pending seek or tune operation was cancelled */
304    public static final  int ERROR_CANCELLED = 2;
305    /** A pending seek or tune operation timed out */
306    public static final  int ERROR_SCAN_TIMEOUT = 3;
307    /** The requested configuration could not be applied */
308    public static final  int ERROR_CONFIG = 4;
309    /** Background scan was interrupted due to hardware becoming temporarily unavailable. */
310    public static final int ERROR_BACKGROUND_SCAN_UNAVAILABLE = 5;
311    /** Background scan failed due to other error, ie. HW failure. */
312    public static final int ERROR_BACKGROUND_SCAN_FAILED = 6;
313
314    /**
315     * Callback provided by the client application when opening a {@link RadioTuner}
316     * to receive asynchronous operation results, updates and error notifications.
317     */
318    public static abstract class Callback {
319        /**
320         * onError() is called when an error occured while performing an asynchronous
321         * operation of when the hardware or system service experiences a problem.
322         * status is one of {@link #ERROR_HARDWARE_FAILURE}, {@link #ERROR_SERVER_DIED},
323         * {@link #ERROR_CANCELLED}, {@link #ERROR_SCAN_TIMEOUT},
324         * {@link #ERROR_CONFIG}
325         */
326        public void onError(int status) {}
327        /**
328         * onConfigurationChanged() is called upon successful completion of
329         * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}
330         * or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)}
331         */
332        public void onConfigurationChanged(RadioManager.BandConfig config) {}
333        /**
334         * onProgramInfoChanged() is called upon successful completion of
335         * {@link RadioTuner#step(int, boolean)}, {@link RadioTuner#scan(int, boolean)},
336         * {@link RadioTuner#tune(int, int)} or when a switching to alternate frequency occurs.
337         * Note that if metadata only are updated,  {@link #onMetadataChanged(RadioMetadata)} will
338         * be called.
339         */
340        public void onProgramInfoChanged(RadioManager.ProgramInfo info) {}
341        /**
342         * onMetadataChanged() is called when new meta data are received on current program.
343         * Meta data are also received in {@link RadioManager.ProgramInfo} when
344         *  {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} is called.
345         */
346        public void onMetadataChanged(RadioMetadata metadata) {}
347        /**
348         * onTrafficAnnouncement() is called when a traffic announcement starts and stops.
349         */
350        public void onTrafficAnnouncement(boolean active) {}
351        /**
352         * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops.
353         */
354        public void onEmergencyAnnouncement(boolean active) {}
355        /**
356         * onAntennaState() is called when the antenna is connected or disconnected.
357         */
358        public void onAntennaState(boolean connected) {}
359        /**
360         * onControlChanged() is called when the client loses or gains control of the radio tuner.
361         * The control is always granted after a successful call to
362         * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}.
363         * If another client opens the same tuner, onControlChanged() will be called with
364         * control set to {@code false} to indicate loss of control.
365         * At this point, RadioTuner APIs other than getters will return
366         * {@link RadioManager#STATUS_INVALID_OPERATION}.
367         * When the other client releases the tuner, onControlChanged() will be called
368         * with control set to {@code true}.
369         */
370        public void onControlChanged(boolean control) {}
371
372        /**
373         * onBackgroundScanAvailabilityChange() is called when background scan
374         * feature becomes available or not.
375         *
376         * @param isAvailable true, if the tuner turned temporarily background-
377         *                    capable, false in the other case.
378         */
379        public void onBackgroundScanAvailabilityChange(boolean isAvailable) {}
380
381        /**
382         * Called when a background scan completes successfully.
383         */
384        public void onBackgroundScanComplete() {}
385
386        /**
387         * Called when available program list changed.
388         *
389         * Use getProgramList() to get the actual list.
390         */
391        public void onProgramListChanged() {}
392    }
393
394}
395
396