211 lines
7.3 KiB
C++
211 lines
7.3 KiB
C++
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_HARDWARE_RADIO_SERVICE_H
|
|
#define ANDROID_HARDWARE_RADIO_SERVICE_H
|
|
|
|
#include <utils/Vector.h>
|
|
//#include <binder/AppOpsManager.h>
|
|
#include <binder/MemoryDealer.h>
|
|
#include <binder/BinderService.h>
|
|
#include <binder/IAppOpsCallback.h>
|
|
#include <radio/IRadioService.h>
|
|
#include <radio/IRadio.h>
|
|
#include <radio/IRadioClient.h>
|
|
#include <system/radio.h>
|
|
#include <hardware/radio.h>
|
|
|
|
namespace android {
|
|
|
|
class MemoryHeapBase;
|
|
|
|
class RadioService :
|
|
public BinderService<RadioService>,
|
|
public BnRadioService
|
|
{
|
|
friend class BinderService<RadioService>;
|
|
|
|
public:
|
|
class ModuleClient;
|
|
class Module;
|
|
|
|
static char const* getServiceName() { return "media.radio"; }
|
|
|
|
RadioService();
|
|
virtual ~RadioService();
|
|
|
|
// IRadioService
|
|
virtual status_t listModules(struct radio_properties *properties,
|
|
uint32_t *numModules);
|
|
|
|
virtual status_t attach(radio_handle_t handle,
|
|
const sp<IRadioClient>& client,
|
|
const struct radio_band_config *config,
|
|
bool withAudio,
|
|
sp<IRadio>& radio);
|
|
|
|
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
|
Parcel* reply, uint32_t flags);
|
|
|
|
virtual status_t dump(int fd, const Vector<String16>& args);
|
|
|
|
|
|
class Module : public virtual RefBase {
|
|
public:
|
|
|
|
Module(radio_hw_device* hwDevice,
|
|
struct radio_properties properties);
|
|
|
|
virtual ~Module();
|
|
|
|
sp<ModuleClient> addClient(const sp<IRadioClient>& client,
|
|
const struct radio_band_config *config,
|
|
bool audio);
|
|
|
|
void removeClient(const sp<ModuleClient>& moduleClient);
|
|
|
|
status_t setMute(bool mute);
|
|
|
|
status_t getMute(bool *mute);
|
|
|
|
virtual status_t dump(int fd, const Vector<String16>& args);
|
|
|
|
const struct radio_hw_device *hwDevice() const { return mHwDevice; }
|
|
const struct radio_properties properties() const { return mProperties; }
|
|
const struct radio_band_config *getDefaultConfig() const ;
|
|
|
|
private:
|
|
|
|
void notifyDeviceConnection(bool connected, const char *address);
|
|
|
|
Mutex mLock; // protects mModuleClients
|
|
const struct radio_hw_device *mHwDevice; // HAL hardware device
|
|
const struct radio_properties mProperties; // cached hardware module properties
|
|
Vector< sp<ModuleClient> > mModuleClients; // list of attached clients
|
|
bool mMute; // radio audio source state
|
|
// when unmuted, audio is routed to the
|
|
// output device selected for media use case.
|
|
}; // class Module
|
|
|
|
class CallbackThread : public Thread {
|
|
public:
|
|
|
|
CallbackThread(const wp<ModuleClient>& moduleClient);
|
|
|
|
virtual ~CallbackThread();
|
|
|
|
|
|
// Thread virtuals
|
|
virtual bool threadLoop();
|
|
|
|
// RefBase
|
|
virtual void onFirstRef();
|
|
|
|
void exit();
|
|
|
|
void sendEvent(radio_hal_event_t *halEvent);
|
|
sp<IMemory> prepareEvent(radio_hal_event_t *halEvent);
|
|
|
|
private:
|
|
wp<ModuleClient> mModuleClient; // client module the thread belongs to
|
|
Condition mCallbackCond; // condition signaled when a new event is posted
|
|
Mutex mCallbackLock; // protects mEventQueue
|
|
Vector< sp<IMemory> > mEventQueue; // pending callback events
|
|
sp<MemoryDealer> mMemoryDealer; // shared memory for callback event
|
|
}; // class CallbackThread
|
|
|
|
class ModuleClient : public BnRadio,
|
|
public IBinder::DeathRecipient {
|
|
public:
|
|
|
|
ModuleClient(const sp<Module>& module,
|
|
const sp<IRadioClient>& client,
|
|
const struct radio_band_config *config,
|
|
bool audio);
|
|
|
|
virtual ~ModuleClient();
|
|
|
|
// IRadio
|
|
virtual void detach();
|
|
|
|
virtual status_t setConfiguration(const struct radio_band_config *config);
|
|
|
|
virtual status_t getConfiguration(struct radio_band_config *config);
|
|
|
|
virtual status_t setMute(bool mute);
|
|
|
|
virtual status_t getMute(bool *mute);
|
|
|
|
virtual status_t scan(radio_direction_t direction, bool skipSubChannel);
|
|
|
|
virtual status_t step(radio_direction_t direction, bool skipSubChannel);
|
|
|
|
virtual status_t tune(unsigned int channel, unsigned int subChannel);
|
|
|
|
virtual status_t cancel();
|
|
|
|
virtual status_t getProgramInformation(struct radio_program_info *info);
|
|
|
|
virtual status_t hasControl(bool *hasControl);
|
|
|
|
virtual status_t dump(int fd, const Vector<String16>& args);
|
|
|
|
sp<IRadioClient> client() const { return mClient; }
|
|
wp<Module> module() const { return mModule; }
|
|
radio_hal_band_config_t halConfig() const;
|
|
sp<CallbackThread> callbackThread() const { return mCallbackThread; }
|
|
void setTuner(const struct radio_tuner *tuner);
|
|
const struct radio_tuner *getTuner() const;
|
|
bool audio() const { return mAudio; }
|
|
|
|
void onCallbackEvent(const sp<IMemory>& event);
|
|
|
|
virtual void onFirstRef();
|
|
|
|
|
|
// IBinder::DeathRecipient implementation
|
|
virtual void binderDied(const wp<IBinder> &who);
|
|
|
|
private:
|
|
|
|
mutable Mutex mLock; // protects mClient, mConfig and mTuner
|
|
wp<Module> mModule; // The module this client is attached to
|
|
sp<IRadioClient> mClient; // event callback binder interface
|
|
radio_band_config_t mConfig; // current band configuration
|
|
sp<CallbackThread> mCallbackThread; // event callback thread
|
|
const bool mAudio;
|
|
const struct radio_tuner *mTuner; // HAL tuner interface. NULL indicates that
|
|
// this client does not have control on any
|
|
// tuner
|
|
}; // class ModuleClient
|
|
|
|
|
|
static void callback(radio_hal_event_t *halEvent, void *cookie);
|
|
|
|
private:
|
|
|
|
virtual void onFirstRef();
|
|
|
|
static void convertProperties(radio_properties_t *properties,
|
|
const radio_hal_properties_t *halProperties);
|
|
Mutex mServiceLock; // protects mModules
|
|
volatile int32_t mNextUniqueId; // for module ID allocation
|
|
DefaultKeyedVector< radio_handle_t, sp<Module> > mModules;
|
|
};
|
|
|
|
} // namespace android
|
|
|
|
#endif // ANDROID_HARDWARE_RADIO_SERVICE_H
|