转自:https://blog.csdn.net/shi_xin/article/details/38903749
volume设置,跳过binder部分(binder请独立理解)
没有采用深度优先的方法,容易绕来绕去,就不知道再看什么了。
采用不断透调的方法讲解,一步一步从上层直逼底层,从整体上了解音量设置过程。
透调中有点难度的调用最后讲解。
一、JNI部分
android_media_AudioSystem.cpp-----framework/base/core/jni/
- android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env,
- jobject thiz,
- jint stream,
- jint index,
- jint device)
- {
- return check_AudioSystem_Command(
- AudioSystem::setStreamVolumeIndex(static_cast <audio_stream_type_t>(stream),
- index,
- (audio_devices_t)device));
- }
关键的参数:
index:音量值;
device:如下列举了一笑部分
- enum{
- AUDIO_DEVICE_NONE = 0x0,
- /* reserved bits */
- AUDIO_DEVICE_BIT_IN = 0x80000000,
- AUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
- /* output devices */
- AUDIO_DEVICE_OUT_EARPIECE = 0x1,
- AUDIO_DEVICE_OUT_SPEAKER = 0x2,
- AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
- AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
- 。。。
- }
stream:
- /* The audio stream for phone calls */
- public static final int STREAM_VOICE_CALL = 0;
- /* The audio stream for system sounds */
- public static final int STREAM_SYSTEM = 1;
- /* The audio stream for the phone ring and message alerts */
- public static final int STREAM_RING = 2;
- /* The audio stream for music playback */
- public static final int STREAM_MUSIC = 3;
- /* The audio stream for alarms */
- public static final int STREAM_ALARM = 4;
- /* The audio stream for notifications */
- public static final int STREAM_NOTIFICATION = 5;
- /* @hide The audio stream for phone calls when connected on bluetooth */
- public static final int STREAM_BLUETOOTH_SCO = 6;
- /* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
- public static final int STREAM_SYSTEM_ENFORCED = 7;
- /* @hide The audio stream for DTMF tones */
- public static final int STREAM_DTMF = 8;
看到函数内部,调用的仕audiosystem的setStreamVolumeIndex函数,进到audiosystem
二、audiosystem
AudioSystem.cpp-----framework/av/media/libmedia/
- status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,
- int index,
- audio_devices_t device)
- {
- const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return PERMISSION_DENIED;
- return aps->setStreamVolumeIndex(stream, index, device);
- }
这里采用了binder机制,直接无视它!知道是一种调用方式就可以。
看到函数调用了audiopolicyservice里的函数setStreamVolumeIndex;
三、audiopolicyservice
AudioPolicyService.cpp-----framework/av/media/services/audioflinger
- status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
- int index,
- audio_devices_t device)
- {
- if (mpAudioPolicy == NULL) {
- return NO_INIT;
- }
- if (!settingsAllowed()) {
- return PERMISSION_DENIED;
- }
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
- return BAD_VALUE;
- }
- Mutex::Autolock _l(mLock);
- if (mpAudioPolicy->set_stream_volume_index_for_device) {
- return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
- stream,
- index,
- device);
- } else {
- return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
- }
- }
函数内部,调用了
- mpAudioPolicy->set_stream_volume_index_for_device
四、
audio_policy_hal.cpp----system/core/libcutils/
- static int ap_set_stream_volume_index(struct audio_policy *pol,
- audio_stream_type_t stream,
- int index)
- {
- struct legacy_audio_policy *lap = to_lap(pol);
- return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,
- index,
- AUDIO_DEVICE_OUT_DEFAULT);
- }
五、audiopolicymanager
audiopolicymanagerbase.c----hardware/libhardware_legacy/audio
看到四中的apm就猜到调用的仕audiopolicymanagerbase中的函数,(疑点2),进入audiopolicymanagerbase.c中的函数
- status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream,
- int index,
- audio_devices_t device)
- {
- if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
- return BAD_VALUE;
- }
- if (!audio_is_output_device(device)) {
- return BAD_VALUE;
- }
- // Force max volume if stream cannot be muted
- if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
- ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
- stream, device, index);
- // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
- // clear all device specific values
- if (device == AUDIO_DEVICE_OUT_DEFAULT) {
- mStreams[stream].mIndexCur.clear();
- }
- mStreams[stream].mIndexCur.add(device, index);
- // compute and apply stream volume on all outputs according to connected device
- status_t status = NO_ERROR;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- audio_devices_t curDevice =
- getDeviceForVolume(mOutputs.valueAt(i)->device());
- if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)||
- status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
- if (volStatus != NO_ERROR) {
- status = volStatus;
- }
- }
- }
- return status;
- }
- status_t AudioPolicyManagerBase::checkAndSetVolume(int stream,
- int index,
- audio_io_handle_t output,
- audio_devices_t device,
- int delayMs,
- bool force)
- {
- 。。。。
- if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
- mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
- mLastVoiceVolume = voiceVolume;
- }
- }
- return NO_ERROR;
- }
即调用的是audioPolicyService->setStreamVolume
六、audiopolicyservice
audiopolicyservice.cpp---frameworks/av/services/audioflinger
- int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
- float volume,
- audio_io_handle_t output,
- int delayMs)
- {
- return (int)mAudioCommandThread->volumeCommand(stream, volume,
- output, delayMs);
- }
volumeCommand函数也在这个文件内
- status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
- float volume,
- audio_io_handle_t output,
- int delayMs)
- {
- status_t status = NO_ERROR;
- AudioCommand *command = new AudioCommand();
- command->mCommand = SET_VOLUME;
- VolumeData *data = new VolumeData();
- data->mStream = stream;
- data->mVolume = volume;
- data->mIO = output;
- command->mParam = data;
- Mutex::Autolock _l(mLock);
- insertCommand_l(command, delayMs);
- mWaitWorkCV.signal();
- if (command->mWaitStatus) {
- command->mCond.wait(mLock);
- status = command->mStatus;
- command->mCond.signal();
- delete command;
- }
- return status;
- }
- insertCommand_l(command, delayMs);
- bool AudioPolicyService::AudioCommandThread::threadLoop()
- {
- nsecs_t waitTime = INT64_MAX;
- mLock.lock();
- while (!exitPending())
- {
- while (!mAudioCommands.isEmpty()) {
- nsecs_t curTime = systemTime();
- if (mAudioCommands[0]->mTime <= curTime) {
- AudioCommand *command = mAudioCommands[0];
- mAudioCommands.removeAt(0);
- mLastCommand = *command;
- // SPRD: Delete command after waiting was end
- bool deleteAudioCommand = true;
- switch (command->mCommand) {
- 。。。。
- case SET_VOLUME: {
- VolumeData *data = (VolumeData *)command->mParam;
- ALOGV("AudioCommandThread() processing set volume stream %d, \
- volume %f, output %d", data->mStream, data->mVolume, data->mIO);
- command->mStatus = AudioSystem::setStreamVolume(data->mStream,
- data->mVolume,
- data->mIO);
- if (command->mWaitStatus) {
- // SPRD: Delete command after waiting was end
- deleteAudioCommand = false;
- command->mCond.signal();
- command->mCond.waitRelative(mLock, kAudioCommandTimeout);
- }
- delete data;
- }break;
- 。。。。。
- mLock.unlock();
- return false;
- }
调到啊udiosystem的函数
七、audiosystem
audiosystem.c---frameworks/av/media/libmedia
- status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value,
- audio_io_handle_t output)
- {
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- af->setStreamVolume(stream, value, output);
- return NO_ERROR;
- }
八、audioflinger
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
调用过程详细分析:
疑点1、mpAudioPolicy调用的是audio_policy_hal.cpp中的方法分析:
函数内部,使用mpAudioPolicy的方法,这就需要看下audiopolicyservice的构造函数;
- AudioPolicyService::AudioPolicyService()
- : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
- {
- 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);
- /* instantiate the audio policy manager */
- rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);//1.1分析
- if (rc)
- return;
- rc = audio_policy_dev_open(module, &mpAudioPolicyDev);//1.2分析
- 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);//1.3分析
- 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;
- /* SPRD: maybe set this property better, but here just change the default value @{ */
- property_get("ro.camera.sound.forced", value, "1");
- forced_val = strtol(value, NULL, 0);
- ALOGV("setForceUse() !forced_val=%d ",!forced_val);
- mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
- /* @} */
- ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
- // load audio pre processing modules
- if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
- loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
- } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
- loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
- }
- }
1.1分析hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
其中,#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy"
- <p>int hw_get_module(const char *id, const struct hw_module_t **module)</p><p>上面函数调用Hardware.c--------audio/hardware/libhardware/</p><p>
- </p>
- <pre name="code" class="cpp">int hw_get_module_by_class(const char *class_id, const char *inst,
- const struct hw_module_t **module)//class_id保存"audio_policy",inst为NULL
- {
- int status;
- int i;
- const struct hw_module_t *hmi = NULL;
- char prop[PATH_MAX];
- char path[PATH_MAX];
- char name[PATH_MAX];
- if (inst)//inst=NULL,走else
- snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
- else
- strlcpy(name, class_id, PATH_MAX);//将"audio_policy"拷贝到name中;
- /*
- * 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.
- */
- /* Loop through the configuration variants looking for a module */
- for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
- if (i < HAL_VARIANT_KEYS_COUNT) {
- if (property_get(variant_keys[i], prop, NULL) == 0) {
- continue;
- }
- snprintf(path, sizeof(path), "%s/%s.%s.so",
- HAL_LIBRARY_PATH2, name, prop);
- if (access(path, R_OK) == 0) break;
- snprintf(path, sizeof(path), "%s/%s.%s.so",
- HAL_LIBRARY_PATH1, name, prop);
- if (access(path, R_OK) == 0) break;
- } else {
- snprintf(path, sizeof(path), "%s/%s.default.so",
- HAL_LIBRARY_PATH2, name);
- if (access(path, R_OK) == 0) break;
- snprintf(path, sizeof(path), "%s/%s.default.so",
- HAL_LIBRARY_PATH1, name);//#define HAL_LIBRARY_PATH1 "/system/lib/hw"
- //将"/system/lib/hw/audio_policy.default.so"拷贝到path中
- if (access(path, R_OK) == 0) break;//判断是否是可读文件,至此,已经确定加载audio_policy.default.so文件,下面的load将完成加载</u>
- }
- }
- status = -ENOENT;
- if (i < HAL_VARIANT_KEYS_COUNT+1) {
- /* load the module, if this fails, we're doomed, and we should not try
- * to load a different variant. */
- status = load(class_id, path, module);//定义的load函数,下面分析
- }
- return status;
- }
- /**
- * Load the file defined by the variant and if successful
- * return the dlopen handle and the hmi.
- * @return 0 = success, !0 = failure.
- */
- static int load(const char *id,
- const char *path,
- const struct hw_module_t **pHmi)
- {
- int status;
- void *handle;
- struct hw_module_t *hmi;
- /*
- * load the symbols resolving undefined symbols before
- * dlopen returns. Since RTLD_GLOBAL is not or'd in with
- * RTLD_NOW the external symbols will not be global
- */
- handle = dlopen(path, RTLD_NOW);//打开指定的 文件,即audio_policy.default.so
- if (handle == NULL) {
- char const *err_str = dlerror();
- ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
- status = -EINVAL;
- goto done;
- }
- /* Get the address of the struct hal_module_info. */
- const char *sym = HAL_MODULE_INFO_SYM_AS_STR;//#define HAL_MODULE_INFO_SYM_AS_STR "HMI"
- hmi = (struct hw_module_t *)dlsym(handle, sym);//根据动态链接库操作句柄与符号,返回符号对应的地址保存给hmi
- if (hmi == NULL) {
- ALOGE("load: couldn't find symbol %s", sym);
- status = -EINVAL;
- goto done;
- }
- /* Check that the id matches */
- if (strcmp(id, hmi->id) != 0) {
- ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);
- status = -EINVAL;
- goto done;
- }
- hmi->dso = handle;
- /* success */
- status = 0;
- done:
- if (status != 0) {
- hmi = NULL;
- if (handle != NULL) {
- dlclose(handle);
- handle = NULL;
- }
- } else {
- ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
- id, path, *pHmi, handle);
- }
- *pHmi = hmi;//将地址赋值给形参。至此,整个动态库so的加载完成,并将地址返回
- return status;
- }