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