blob: ac3481ed97e9957466fc123b9d3ec766ef7523d2 [file] [log] [blame]
Eric Laurent4e090692015-03-05 15:12:40 -08001/*
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
Eric Laurent53810822015-03-12 09:12:01 -070069 Module(radio_hw_device* hwDevice,
Eric Laurent4e090692015-03-05 15:12:40 -080070 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
Eric Laurent4e090692015-03-05 15:12:40 -080090 private:
91
Eric Laurent53810822015-03-12 09:12:01 -070092 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.
Eric Laurent4e090692015-03-05 15:12:40 -0800101 }; // class Module
102
103 class CallbackThread : public Thread {
104 public:
105
Chih-Hung Hsieh62503ee2016-08-09 14:06:20 -0700106 explicit CallbackThread(const wp<ModuleClient>& moduleClient);
Eric Laurent4e090692015-03-05 15:12:40 -0800107
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:
Eric Laurent53810822015-03-12 09:12:01 -0700123 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
Eric Laurent4e090692015-03-05 15:12:40 -0800128 }; // 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
Eric Laurent53810822015-03-12 09:12:01 -0700184 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
Eric Laurent4e090692015-03-05 15:12:40 -0800189 const bool mAudio;
Eric Laurent53810822015-03-12 09:12:01 -0700190 const struct radio_tuner *mTuner; // HAL tuner interface. NULL indicates that
191 // this client does not have control on any
192 // tuner
Eric Laurent4e090692015-03-05 15:12:40 -0800193 }; // 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);
Eric Laurent53810822015-03-12 09:12:01 -0700204 Mutex mServiceLock; // protects mModules
205 volatile int32_t mNextUniqueId; // for module ID allocation
Eric Laurent4e090692015-03-05 15:12:40 -0800206 DefaultKeyedVector< radio_handle_t, sp<Module> > mModules;
207};
208
209} // namespace android
210
211#endif // ANDROID_HARDWARE_RADIO_SERVICE_H