• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.SystemApi;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Handler;
23 import android.os.Looper;
24 import android.os.Message;
25 import java.lang.ref.WeakReference;
26 import java.util.UUID;
27 
28 /**
29  * A RadioModule implements the RadioTuner interface for a broadcast radio tuner physically
30  * present on the device and exposed by the radio HAL.
31  *
32  * @hide
33  */
34 public class RadioModule extends RadioTuner {
35     private long mNativeContext = 0;
36     private int mId;
37     private NativeEventHandlerDelegate mEventHandlerDelegate;
38 
RadioModule(int moduleId, RadioManager.BandConfig config, boolean withAudio, RadioTuner.Callback callback, Handler handler)39     RadioModule(int moduleId, RadioManager.BandConfig config, boolean withAudio,
40             RadioTuner.Callback callback, Handler handler) {
41         mId = moduleId;
42         mEventHandlerDelegate = new NativeEventHandlerDelegate(callback, handler);
43         native_setup(new WeakReference<RadioModule>(this), config, withAudio);
44     }
native_setup(Object module_this, RadioManager.BandConfig config, boolean withAudio)45     private native void native_setup(Object module_this,
46             RadioManager.BandConfig config, boolean withAudio);
47 
48     @Override
finalize()49     protected void finalize() {
50         native_finalize();
51     }
native_finalize()52     private native void native_finalize();
53 
initCheck()54     boolean initCheck() {
55         return mNativeContext != 0;
56     }
57 
58     // RadioTuner implementation
close()59     public native void close();
60 
setConfiguration(RadioManager.BandConfig config)61     public native int setConfiguration(RadioManager.BandConfig config);
62 
getConfiguration(RadioManager.BandConfig[] config)63     public native int getConfiguration(RadioManager.BandConfig[] config);
64 
setMute(boolean mute)65     public native int setMute(boolean mute);
66 
getMute()67     public native boolean getMute();
68 
step(int direction, boolean skipSubChannel)69     public native int step(int direction, boolean skipSubChannel);
70 
scan(int direction, boolean skipSubChannel)71     public native int scan(int direction, boolean skipSubChannel);
72 
tune(int channel, int subChannel)73     public native int tune(int channel, int subChannel);
74 
cancel()75     public native int cancel();
76 
getProgramInformation(RadioManager.ProgramInfo[] info)77     public native int getProgramInformation(RadioManager.ProgramInfo[] info);
78 
isAntennaConnected()79     public native boolean isAntennaConnected();
80 
hasControl()81     public native boolean hasControl();
82 
83 
84     /* keep in sync with radio_event_type_t in system/core/include/system/radio.h */
85     static final int EVENT_HW_FAILURE = 0;
86     static final int EVENT_CONFIG = 1;
87     static final int EVENT_ANTENNA = 2;
88     static final int EVENT_TUNED = 3;
89     static final int EVENT_METADATA = 4;
90     static final int EVENT_TA = 5;
91     static final int EVENT_AF_SWITCH = 6;
92     static final int EVENT_EA = 7;
93     static final int EVENT_CONTROL = 100;
94     static final int EVENT_SERVER_DIED = 101;
95 
96     private class NativeEventHandlerDelegate {
97         private final Handler mHandler;
98 
NativeEventHandlerDelegate(final RadioTuner.Callback callback, Handler handler)99         NativeEventHandlerDelegate(final RadioTuner.Callback callback,
100                                    Handler handler) {
101             // find the looper for our new event handler
102             Looper looper;
103             if (handler != null) {
104                 looper = handler.getLooper();
105             } else {
106                 looper = Looper.getMainLooper();
107             }
108 
109             // construct the event handler with this looper
110             if (looper != null) {
111                 // implement the event handler delegate
112                 mHandler = new Handler(looper) {
113                     @Override
114                     public void handleMessage(Message msg) {
115                         switch (msg.what) {
116                         case EVENT_HW_FAILURE:
117                             if (callback != null) {
118                                 callback.onError(RadioTuner.ERROR_HARDWARE_FAILURE);
119                             }
120                             break;
121                         case EVENT_CONFIG: {
122                             RadioManager.BandConfig config = (RadioManager.BandConfig)msg.obj;
123                             switch(msg.arg1) {
124                             case RadioManager.STATUS_OK:
125                                 if (callback != null) {
126                                     callback.onConfigurationChanged(config);
127                                 }
128                                 break;
129                             default:
130                                 if (callback != null) {
131                                     callback.onError(RadioTuner.ERROR_CONFIG);
132                                 }
133                                 break;
134                             }
135                         } break;
136                         case EVENT_ANTENNA:
137                             if (callback != null) {
138                                 callback.onAntennaState(msg.arg2 == 1);
139                             }
140                             break;
141                         case EVENT_AF_SWITCH:
142                         case EVENT_TUNED: {
143                             RadioManager.ProgramInfo info = (RadioManager.ProgramInfo)msg.obj;
144                             switch (msg.arg1) {
145                             case RadioManager.STATUS_OK:
146                                 if (callback != null) {
147                                     callback.onProgramInfoChanged(info);
148                                 }
149                                 break;
150                             case RadioManager.STATUS_TIMED_OUT:
151                                 if (callback != null) {
152                                     callback.onError(RadioTuner.ERROR_SCAN_TIMEOUT);
153                                 }
154                                 break;
155                             case RadioManager.STATUS_INVALID_OPERATION:
156                             default:
157                                 if (callback != null) {
158                                     callback.onError(RadioTuner.ERROR_CANCELLED);
159                                 }
160                                 break;
161                             }
162                         } break;
163                         case EVENT_METADATA: {
164                             RadioMetadata metadata = (RadioMetadata)msg.obj;
165                             if (callback != null) {
166                                 callback.onMetadataChanged(metadata);
167                             }
168                         } break;
169                         case EVENT_TA:
170                             if (callback != null) {
171                                 callback.onTrafficAnnouncement(msg.arg2 == 1);
172                             }
173                             break;
174                         case EVENT_EA:
175                             if (callback != null) {
176                                 callback.onEmergencyAnnouncement(msg.arg2 == 1);
177                             }
178                         case EVENT_CONTROL:
179                             if (callback != null) {
180                                 callback.onControlChanged(msg.arg2 == 1);
181                             }
182                             break;
183                         case EVENT_SERVER_DIED:
184                             if (callback != null) {
185                                 callback.onError(RadioTuner.ERROR_SERVER_DIED);
186                             }
187                             break;
188                         default:
189                             // Should not happen
190                             break;
191                         }
192                     }
193                 };
194             } else {
195                 mHandler = null;
196             }
197         }
198 
handler()199         Handler handler() {
200             return mHandler;
201         }
202     }
203 
204 
205     @SuppressWarnings("unused")
postEventFromNative(Object module_ref, int what, int arg1, int arg2, Object obj)206     private static void postEventFromNative(Object module_ref,
207                                             int what, int arg1, int arg2, Object obj) {
208         RadioModule module = (RadioModule)((WeakReference)module_ref).get();
209         if (module == null) {
210             return;
211         }
212 
213         NativeEventHandlerDelegate delegate = module.mEventHandlerDelegate;
214         if (delegate != null) {
215             Handler handler = delegate.handler();
216             if (handler != null) {
217                 Message m = handler.obtainMessage(what, arg1, arg2, obj);
218                 handler.sendMessage(m);
219             }
220         }
221     }
222 }
223 
224