1. 音频系统的启动
AudioFlinger和AudioPolicyService两大音频服务都是在android系统启动时就启动的。
当linux kenerl启动完成后,会启动android的init进程(system/core/init.c):
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon_recursive("/sys");
is_charger = !strcmp(bootmode, "charger");
INFO("property init\n");
property_load_boot_defaults();
INFO("reading config file\n");
init_parse_config_file("/init.rc");
init.rc文件(system/core/rootdir/init.rc)中保存了许多系统启动时需要启动的服务。其中就有多媒体服务mediaserver的启动:
service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
ioprio rt 4
关于init.rc的进一步了解,参考如下几篇文章:
https://blog.csdn.net/andrewblog/article/details/17122303
https://blog.csdn.net/zhonglunshun/article/details/78615980
mediaserver在frameworks/av/media/mediaserver/main_mediaserver.cpp中定义:
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
SoundTriggerHwService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
AudioFlinger和AudioPolicyService(frameworks/av/services/audioflinger/) 在此处被先后实例化,但是在AudioPolicyService.cpp和AudioFlinger.cpp中并未找到实例化函数instantiate,那么该函数必然位于两者的共同父类中:
class AudioFlinger :
public BinderService<AudioFlinger>,
public BnAudioFlinger
{
friend class BinderService<AudioFlinger>; // for AudioFlinger()
...
}
class AudioPolicyService :
public BinderService<AudioPolicyService>,
public BnAudioPolicyService,
public IBinder::DeathRecipient
{
friend class BinderService<AudioPolicyService>;
...
}
在frameworks/native/include/binder/BinderService.h中,我们找到了instantiate:
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
static void publishAndJoinThreadPool(bool allowIsolated = false) {
publish(allowIsolated);
joinThreadPool();
}
static void instantiate() { publish(); }
static status_t shutdown() { return NO_ERROR; }
private:
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
};
在publish函数中,SERVICE::getServiceName()调用了AudioFlinger类的静态成员函数getServiceName()获取AudioFlinger的服务名称,new SERVICE()则将AudioFlinger类实例化,addService向服务管理器注册AudioFlinger的实例。AudioFlinger服务启动后,其他进程可以通过ServiceManager来获取其代理对象IAudioFlinger通过IAudioFlinge可以向 AudioFlinger 发出各种服务请求,从而完成自己的音频业务。AudioPolicyService同理。
注意这里sm指向defaultServiceManager()返回的对象,defaultServiceManager()返回的是"IServiceManager对象",获取"IServiceManager对象"的目的是和"ServiceManager进程"进行通信,详细信息参考:https://blog.csdn.net/vichie2008/article/details/51889913
1.1 AudioFlinger的启动
接下来是AudioFlinger(frameworks/av/services/audioflinger/AudioFlinger.cpp)类的构造函数的初始化工作:
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mPrimaryHardwareDev(NULL),
mAudioHwDevs(NULL),
mHardwareStatus(AUDIO_HW_IDLE),
mMasterVolume(1.0f),
mMasterMute(false),
mNextUniqueId(1),
mMode(AUDIO_MODE_INVALID),
mBtNrecIsOff(false),
mIsLowRamDevice(true),
mIsDeviceTypeKnown(false),
mGlobalEffectEnableTime(0),
mPrimaryOutputSampleRate(0)
{
getpid_cached = getpid();
char value[PROPERTY_VALUE_MAX];
bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1);
if (doLog) {
mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters", MemoryHeapBase::READ_ONLY);
}
#ifdef TEE_SINK
(void) property_get("ro.debuggable", value, "0");
int debuggable = atoi(value);
int teeEnabled = 0;
if (debuggable) {
(void) property_get("af.tee", value, "0");
teeEnabled = atoi(value);
}
// FIXME symbolic constants here
if (teeEnabled & 1) {
mTeeSinkInputEnabled = true;
}
if (teeEnabled & 2) {
mTeeSinkOutputEnabled = true;
}
if (teeEnabled & 4) {
mTeeSinkTrackEnabled = true;
}
#endif
}
接下来是调用AudioFlinger::onFirstRef():
void AudioFlinger::onFirstRef()
{
int rc = 0;
Mutex::Autolock _l(mLock);
/* TODO: move all this work into an Init() function */
char val_str[PROPERTY_VALUE_MAX] = { 0 };
if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
uint32_t int_val;
if (1 == sscanf(val_str, "%u", &int_val)) {
mStandbyTimeInNsecs = milliseconds(int_val);
ALOGI("Using %u mSec as standby time.", int_val);
} else {
mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
ALOGI("Using default %u mSec as standby time.",
(uint32_t)(mStandbyTimeInNsecs / 1000000));
}
}
mPatchPanel = new PatchPanel(this);
mMode = AUDIO_MODE_NORMAL;
}
属性ro.audio.flinger_standbytime_ms为用户调整standby时间提供了一个接口,早期版本中这个时间值是固定的。接下来创建PatchPanel,一个Audio Patch用来表示一个或多个source端到一个或多个sink端,相关介绍在: https://blog.csdn.net/yzhang8703/article/details/47660803
关于会调用到函数onFirstRef的原因,BnAudioFlinger是由RefBase层层继承而来的,并且IServiceManager::addService的第二个参数实际上是一个强指针引用(constsp&),此时会调用incStrong函数,该函数在第一次调用时会调用onFirstRef()。详细信息参考: https://www.cnblogs.com/zhaoshuai1215/p/3432963.html
1.2 AudioPolicyService的启动
接下来看AudioPolicyService(frameworks/av/services/audiopolicy/AudioPolicyService.cpp)类的初始化:
AudioPolicyService::AudioPolicyService()
: BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
{
}
接着看AudioPolicyService::onFirstRef():
void AudioPolicyService::onFirstRef()
{
char value[PROPERTY_VALUE_MAX];
const struct hw_module_t *module;
int forced_val;
int rc;
{
Mutex::Autolock _l(mLock);
// start tone playback thread
mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
// start audio commands thread
mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
// start output activity command thread
mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
#ifdef USE_LEGACY_AUDIO_POLICY
ALOGI("AudioPolicyService CSTOR in legacy mode");
/* instantiate the audio policy manager */
rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
if (rc) {
return;
}
rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
if (rc) {
return;
}
rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
&mpAudioPolicy);
ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
if (rc) {
return;
}
rc = mpAudioPolicy->init_check(mpAudioPolicy);
ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
if (rc) {
return;
}
ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
#else
ALOGI("AudioPolicyService CSTOR in new mode");
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
#endif
}
// load audio processing modules
sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
{
Mutex::Autolock _l(mLock);
mAudioPolicyEffects = audioPolicyEffects;
}
}
1.2.1 创建AudioCommandThread线程
在AudioPolicyService对象构造过程中,分别创建了ApmTone、ApmAudio、ApmOutput三个AudioCommandThread线程:
1、 ApmTone用于播放tone音;
2、 ApmAudio用于执行audio命令;
3、ApmOutput用于执行输出命令;
在第一次强引用AudioCommandThread线程对象时,AudioCommandThread的onFirstRef函数被回调,于是启动线程:
void AudioPolicyService::AudioCommandThread::onFirstRef()
{
run(mName.string(), ANDROID_PRIORITY_AUDIO);
}
这里采用异步方式来执行audio command,当需要执行上表中的命令时,首先将命令投递到AudioCommandThread的mAudioCommands命令向量表中,然后通过mWaitWorkCV.signal()唤醒AudioCommandThread线程,被唤醒的AudioCommandThread线程执行完command后,又通过mWaitWorkCV.waitRelative(mLock, waitTime)睡眠等待命令到来。
另外,三个AudioCommandThread执行的命令包括以下几个:
enum {
START_TONE,
STOP_TONE,
SET_VOLUME,
SET_PARAMETERS,
SET_VOICE_VOLUME,
STOP_OUTPUT,
RELEASE_OUTPUT,
CREATE_AUDIO_PATCH,
RELEASE_AUDIO_PATCH,
UPDATE_AUDIOPORT_LIST,
UPDATE_AUDIOPATCH_LIST,
SET_AUDIOPORT_CONFIG,
};
1.2.2 加载audio_policy_module模块
搜索“hardware.h”得到其位置在hardware/libhardware/include/hardware/hardware.h,进一步搜索“hardware.c/hardware.cpp”找到了hardware/libhardware/hardware.c。在hardware.c发现了hw_get_module函数:
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
int i;
char prop[PATH_MAX];
char path[PATH_MAX];
char name[PATH_MAX];
char prop_name[PATH_MAX];
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* First try a property specific to the class and possibly instance */
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
if (property_get(prop_name, prop, NULL) > 0) {
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
/* Nothing found, try the default */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
return -ENOENT;
found:
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
return load(class_id, path, module);
}
接下来在/libhardware/include/hardware/audio_policy.h中找到了:
#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy"
因此,hw_get_module_by_class的第一个参数class_id = “audio_policy”
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);
此处inst == NULL; 所以name = “audio_policy”;
snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
if (property_get(prop_name, prop, NULL) > 0) {
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
判断“ro.hardware.audio_policy"是否存在,如果存在则加载,若不存在跳到下一步:
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}
在配置变量中查找,属性值(audio_policy.prop.so)是否存在,配置的变量如下:
static const char *variant_keys[] = {
"ro.hardware", /* This goes first so that it can pick up a different
file on the emulator. */
"ro.product.board",
"ro.board.platform",
"ro.arch"
};
如果不存在,则将prop=default。查看audio_policy.defaule.so库是否存在:
/* Nothing found, try the default */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
如果存在,则加载audio_policy.defaule.so。
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
return load(class_id, path, module);
更详细的介绍参考:https://blog.csdn.net/u014135607/article/details/79840130
hw_get_module函数加载audio_policy.default.so库得到audio_policy_module模块。
1.2.3 打开audio_policy_device设备
rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
if (rc) {
return;
}
audio_policy_dev_open函数可以在/libhardware/include/hardware/audio_policy.h中找到:
/** convenience API for opening and closing a supported device */
static inline int audio_policy_dev_open(const hw_module_t* module,
struct audio_policy_device** device)
{
return module->methods->open(module, AUDIO_POLICY_INTERFACE,
(hw_device_t**)device);
}
这里使用hw_module_t的方法打开设备,hw_module_t结构体的定义可以在(/hardware/libhardware/include/hardware/hardware.h)中找到:
typedef struct hw_module_t {
uint32_t tag;
uint16_t module_api_version;
/** Identifier of module */
const char *id;
/** Name of this module */
const char *name;
/** Author/owner/implementor of the module */
const char *author;
/** Modules methods */
struct hw_module_methods_t* methods;
/** module's dso */
void* dso;
} hw_module_t;
hw_module_methods_t的定义也在这里,我们找到了指向打开设备方法的指针:
typedef struct hw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
有两个文件实现了结构体hw_module_methods_t中open方法,分别是:/hardware/libhardware/modules/audio/audio_policy.c和/hardware/libhardware_legacy/audio/audio_policy_hal.cpp。
static struct hw_module_methods_t default_ap_module_methods = {
.open = default_ap_dev_open,
};
static struct hw_module_methods_t legacy_ap_module_methods = {
.open = legacy_ap_dev_open
};
考虑到宏定义#ifdef USE_LEGACY_AUDIO_POLICY
,hw_module_methods_t的实现应该在audio_policy_hal.cpp中。
static int legacy_ap_dev_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
struct legacy_ap_device *dev;
if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)
return -EINVAL;
dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));
if (!dev)
return -ENOMEM;
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = legacy_ap_dev_close;
dev->device.create_audio_policy = create_legacy_ap;
dev->device.destroy_audio_policy = destroy_legacy_ap;
*device = &dev->device.common;
return 0;
}
在函数legacy_ap_dev_open中我们也找到了结构体hw_device_t(/hardware/libhardware/include/hardware/hardware.h)中close方法和结构体audio_policy_device(/libhardware/include/hardware/audio_policy.h )中create_audio_policy和destroy_audio_policy方法的实现:
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
uint32_t tag;
uint32_t version;
/** reference to the module this device belongs to */
struct hw_module_t* module;
uint64_t reserved[12];
/** Close this device */
int (*close)(struct hw_device_t* device);
} hw_device_t;
struct audio_policy_device {
/**
* Common methods of the audio policy device. This *must* be the first member of
* audio_policy_device as users of this structure will cast a hw_device_t to
* audio_policy_device pointer in contexts where it's known the hw_device_t references an
* audio_policy_device.
*/
struct hw_device_t common;
int (*create_audio_policy)(const struct audio_policy_device *device,
struct audio_policy_service_ops *aps_ops,
void *service,
struct audio_policy **ap);
int (*destroy_audio_policy)(const struct audio_policy_device *device,
struct audio_policy *ap);
};
另外需要注意的是/libhardware/include/hardware/audio_policy.h文件的真实文件名应当是audio_policy_interface.h,需要和/system/core/include/system/audio_policy.h区分开来。该文件包含了一些从 /frameworks/base/include/media/AudioSystem.h转移过来的枚举值。
1.2.4创建audio_policy对象
首先来看/libhardware/include/hardware/audio_policy.h定义的三个结构体:
audio_policy, audio_policy_service_ops和audio_policy_device