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
31namespace android {
32
33class MemoryHeapBase;
34
35class RadioService :
36    public BinderService<RadioService>,
37    public BnRadioService
38{
39    friend class BinderService<RadioService>;
40
41public:
42    class ModuleClient;
43    class Module;
44
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
86       const struct radio_hw_device *hwDevice() const { return mHwDevice; }
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
166               sp<IRadioClient> client() const { return mClient; }
167               wp<Module> module() const { return mModule; }
168               radio_hal_band_config_t halConfig() const;
169               sp<CallbackThread> callbackThread() const { return mCallbackThread; }
170               void setTuner(const struct radio_tuner *tuner);
171               const struct radio_tuner *getTuner() const;
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
198private:
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