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