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 #ifndef ANDROID_HARDWARE_RADIO_SERVICE_H
18 #define ANDROID_HARDWARE_RADIO_SERVICE_H
19 
20 #include <utils/Vector.h>
21 //#include <binder/AppOpsManager.h>
22 #include <binder/MemoryDealer.h>
23 #include <binder/BinderService.h>
24 #include <binder/IAppOpsCallback.h>
25 #include <radio/IRadioService.h>
26 #include <radio/IRadio.h>
27 #include <radio/IRadioClient.h>
28 #include <system/radio.h>
29 #include <hardware/radio.h>
30 
31 namespace android {
32 
33 class MemoryHeapBase;
34 
35 class RadioService :
36     public BinderService<RadioService>,
37     public BnRadioService
38 {
39     friend class BinderService<RadioService>;
40 
41 public:
42     class ModuleClient;
43     class Module;
44 
getServiceName()45     static char const* getServiceName() { return "media.radio"; }
46 
47                         RadioService();
48     virtual             ~RadioService();
49 
50     // IRadioService
51     virtual status_t listModules(struct radio_properties *properties,
52                                  uint32_t *numModules);
53 
54     virtual status_t attach(radio_handle_t handle,
55                             const sp<IRadioClient>& client,
56                             const struct radio_band_config *config,
57                             bool withAudio,
58                             sp<IRadio>& radio);
59 
60     virtual status_t    onTransact(uint32_t code, const Parcel& data,
61                                    Parcel* reply, uint32_t flags);
62 
63     virtual status_t    dump(int fd, const Vector<String16>& args);
64 
65 
66     class Module : public virtual RefBase {
67     public:
68 
69        Module(radio_hw_device* hwDevice,
70               struct radio_properties properties);
71 
72        virtual ~Module();
73 
74                sp<ModuleClient> addClient(const sp<IRadioClient>& client,
75                                   const struct radio_band_config *config,
76                                   bool audio);
77 
78                void removeClient(const sp<ModuleClient>& moduleClient);
79 
80                status_t setMute(bool mute);
81 
82                status_t getMute(bool *mute);
83 
84        virtual status_t dump(int fd, const Vector<String16>& args);
85 
hwDevice()86        const struct radio_hw_device *hwDevice() const { return mHwDevice; }
properties()87        const struct radio_properties properties() const { return mProperties; }
88        const struct radio_band_config *getDefaultConfig() const ;
89 
90     private:
91 
92        void notifyDeviceConnection(bool connected, const char *address);
93 
94         Mutex                         mLock;          // protects  mModuleClients
95         const struct radio_hw_device  *mHwDevice;     // HAL hardware device
96         const struct radio_properties mProperties;    // cached hardware module properties
97         Vector< sp<ModuleClient> >    mModuleClients; // list of attached clients
98         bool                          mMute;          // radio audio source state
99                                                       // when unmuted, audio is routed to the
100                                                       // output device selected for media use case.
101     }; // class Module
102 
103     class CallbackThread : public Thread {
104     public:
105 
106         CallbackThread(const wp<ModuleClient>& moduleClient);
107 
108         virtual ~CallbackThread();
109 
110 
111         // Thread virtuals
112         virtual bool threadLoop();
113 
114         // RefBase
115         virtual void onFirstRef();
116 
117                 void exit();
118 
119                 void sendEvent(radio_hal_event_t *halEvent);
120                 sp<IMemory> prepareEvent(radio_hal_event_t *halEvent);
121 
122     private:
123         wp<ModuleClient>      mModuleClient;    // client module the thread belongs to
124         Condition             mCallbackCond;    // condition signaled when a new event is posted
125         Mutex                 mCallbackLock;    // protects mEventQueue
126         Vector< sp<IMemory> > mEventQueue;      // pending callback events
127         sp<MemoryDealer>      mMemoryDealer;    // shared memory for callback event
128     }; // class CallbackThread
129 
130     class ModuleClient : public BnRadio,
131                    public IBinder::DeathRecipient {
132     public:
133 
134        ModuleClient(const sp<Module>& module,
135               const sp<IRadioClient>& client,
136               const struct radio_band_config *config,
137               bool audio);
138 
139        virtual ~ModuleClient();
140 
141        // IRadio
142        virtual void detach();
143 
144        virtual status_t setConfiguration(const struct radio_band_config *config);
145 
146        virtual status_t getConfiguration(struct radio_band_config *config);
147 
148        virtual status_t setMute(bool mute);
149 
150        virtual status_t getMute(bool *mute);
151 
152        virtual status_t scan(radio_direction_t direction, bool skipSubChannel);
153 
154        virtual status_t step(radio_direction_t direction, bool skipSubChannel);
155 
156        virtual status_t tune(unsigned int channel, unsigned int subChannel);
157 
158        virtual status_t cancel();
159 
160        virtual status_t getProgramInformation(struct radio_program_info *info);
161 
162        virtual status_t hasControl(bool *hasControl);
163 
164        virtual status_t dump(int fd, const Vector<String16>& args);
165 
client()166                sp<IRadioClient> client() const { return mClient; }
module()167                wp<Module> module() const { return mModule; }
168                radio_hal_band_config_t halConfig() const;
callbackThread()169                sp<CallbackThread> callbackThread() const { return mCallbackThread; }
170                void setTuner(const struct radio_tuner *tuner);
171                const struct radio_tuner *getTuner() const;
audio()172                bool audio() const { return mAudio; }
173 
174                void onCallbackEvent(const sp<IMemory>& event);
175 
176        virtual void onFirstRef();
177 
178 
179        // IBinder::DeathRecipient implementation
180        virtual void        binderDied(const wp<IBinder> &who);
181 
182     private:
183 
184         mutable Mutex               mLock;           // protects mClient, mConfig and mTuner
185         wp<Module>                  mModule;         // The module this client is attached to
186         sp<IRadioClient>            mClient;         // event callback binder interface
187         radio_band_config_t         mConfig;         // current band configuration
188         sp<CallbackThread>          mCallbackThread; // event callback thread
189         const bool                  mAudio;
190         const struct radio_tuner    *mTuner;        // HAL tuner interface. NULL indicates that
191                                                     // this client does not have control on any
192                                                     // tuner
193     }; // class ModuleClient
194 
195 
196     static void callback(radio_hal_event_t *halEvent, void *cookie);
197 
198 private:
199 
200     virtual void onFirstRef();
201 
202     static void convertProperties(radio_properties_t *properties,
203                                   const radio_hal_properties_t *halProperties);
204     Mutex               mServiceLock;   // protects mModules
205     volatile int32_t    mNextUniqueId;  // for module ID allocation
206     DefaultKeyedVector< radio_handle_t, sp<Module> > mModules;
207 };
208 
209 } // namespace android
210 
211 #endif // ANDROID_HARDWARE_RADIO_SERVICE_H
212