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