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.content.Context;
23import android.content.Intent;
24import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import java.lang.ref.WeakReference;
28import java.util.List;
29import 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
40public 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     * */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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         */
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         */
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         */
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         */
295        public void onMetadataChanged(RadioMetadata metadata) {}
296        /**
297         * onTrafficAnnouncement() is called when a traffic announcement starts and stops.
298         */
299        public void onTrafficAnnouncement(boolean active) {}
300        /**
301         * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops.
302         */
303        public void onEmergencyAnnouncement(boolean active) {}
304        /**
305         * onAntennaState() is called when the antenna is connected or disconnected.
306         */
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         */
319        public void onControlChanged(boolean control) {}
320    }
321
322}
323
324