public void onClick(View view) {
int id = view.getId();
int mode = AudioState.ROUTE_WIRED_OR_EARPIECE;
Log.d(this, "onClick(View " + view + ", id " + id + ")...");
switch(id) {
case R.id.audioButton:
onAudioButtonClicked();
}
private void onAudioButtonClicked() {
if (isSupported(AudioState.ROUTE_BLUETOOTH)) {
showAudioModePopup();
} else {
getPresenter().toggleSpeakerphone();
}
}
CallButtonPresenter.java
public void toggleSpeakerphone() {
setAudioMode(newMode);
}
public void setAudioMode(int mode) {
TelecomAdapter.getInstance().setAudioRoute(mode);
}
Phone.java
public final void setAudioRoute(int route) {
mInCallAdapter.setAudioRoute(route);
}
InCallAdapter.java
public void setAudioRoute(int route) {
mHandler.obtainMessage(MSG_SET_AUDIO_ROUTE, route, 0).sendToTarget();
}
private final class InCallAdapterHandler extends Handler {
@Override
public void handleMessage(Message msg) {
case MSG_SET_AUDIO_ROUTE:
mCallsManager.setAudioRoute(msg.arg1);
break;
}
CallsManager.java
void setAudioRoute(int route) {
mCallAudioManager.setAudioRoute(route);
}
ok, 经过系列转换,终于见到曙光了。
CallAudioManager.java
void setAudioRoute(int route) {
setSystemAudioState(mAudioState.isMuted(), newRoute,
mAudioState.getSupportedRouteMask());
}
private void turnOnSpeaker(boolean on) {
// Wired headset and earpiece work the same way
if (mAudioManager.isSpeakerphoneOn() != on) {
Log.i(this, "turning speaker phone %s", on);
mAudioManager.setSpeakerphoneOn(on);
}
}
终于调用到AudioManager. 这才是系统提供的api。
audiomanager 通过binder 机制调用Audioservice。省去中间简单传递过程,直接从audioservice分析
private void setForceUse(int usage, int config) {
AudioSystem.setForceUse(usage, config);
}
通过audiosystem 以jni 机制调用native方法。 android_media_AudioSystem.cpp
static jint
android_media_AudioSystem_setForceUse(JNIEnv *env, jobject thiz, jint usage, jint config)
{
return (jint) check_AudioSystem_Command(AudioSystem::setForceUse(static_cast
static_cast
}
AudioSystem.cpp
status_t AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
const sp
if (aps == 0) return PERMISSION_DENIED;
return aps->setForceUse(usage, config);
}
IAudioPolicyService.cpp
virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast
data.writeInt32(static_cast
remote()->transact(SET_FORCE_USE, data, &reply);
return static_cast
}
AudioPolicyInterfaceImpl.cpp
status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config)
{
Mutex::Autolock _l(mLock);
mAudioPolicyManager->setForceUse(usage, config);
return NO_ERROR;
}
AudioPolicyManager.cpp
void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config)
{
applyStreamVolumes(output, newDevice, 0, true);
}
void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
audio_devices_t device,
int delayMs,
bool force)
{
checkAndSetVolume((audio_stream_type_t)stream,
mStreams[stream].getVolumeIndex(device),
output,
device,
delayMs,
force);
}
}
status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
int index,
audio_io_handle_t output,
audio_devices_t device,
int delayMs,
bool force)
{
}
后续基本流程
AudioPolicyClientImpl.cpp
AudioPolicyService.cpp
AudioFlinger.cpp