前言
前面分析了CarAudioDynamicRouting,我们继续对CarAudioService的init函数进行分析
if (sUseCarAudioFocus) {
// Configure our AudioPolicy to handle focus events.
// This gives us the ability to decide which audio focus requests to accept and bypasses
// the framework ducking logic.
mFocusHandler = new CarZonesAudioFocus(mAudioManager,
mContext.getPackageManager(),
mCarAudioZones);
builder.setAudioPolicyFocusListener(mFocusHandler);
builder.setIsAudioFocusPolicy(true);
}
mAudioPolicy = builder.build();
if (sUseCarAudioFocus) {
// Connect the AudioPolicy and the focus listener
mFocusHandler.setOwningPolicy(this, mAudioPolicy);
}
sUseCarAudioFocus默认是true,如果我们不想在car上使用CarZoneAudioFocus这套逻辑,则可以改变这个值为false,如果为false,则AudioFocus的处理就会使用原生的逻辑。
1. CarZonesAudioFocus
首先看CarZonesAudioFocus的构造函数,这里的逻辑主要是围绕CarAudioZone 处理,为每个CarAudioZone 创建一个CarAudioFocus,下面我们会分析CarAudioFocus()
CarZonesAudioFocus(AudioManager audioManager,
PackageManager packageManager,
@NonNull CarAudioZone[] carAudioZones) {
//Create the zones here, the policy will be set setOwningPolicy,
// which is called right after this constructor.
Preconditions.checkNotNull(carAudioZones);
Preconditions.checkArgument(carAudioZones.length != 0,
"There must be a minimum of one audio zone");
//Create focus for all the zones
for (CarAudioZone audioZone : carAudioZones) {
Log.d(CarLog.TAG_AUDIO,
"CarZonesAudioFocus adding new zone " + audioZone.getId());
CarAudioFocus zoneFocusListener = new CarAudioFocus(audioManager, packageManager);
mFocusZones.put(audioZone.getId(), zoneFocusListener);
}
}
2. CarAudioFocus
CarAudioFocus的构造函数如下,只是传了audioManager和packageManager
CarAudioFocus(AudioManager audioManager, PackageManager packageManager) {
mAudioManager = audioManager;
mPackageManager = packageManager;
}
最后我们会调用setAudioPolicyFocusListener把CarZonesAudioFocus作为参数设置为AudioPolicy,那么说明CarZonesAudioFocus应该是继承了AudioPolicy.AudioPolicyFocusListener,我们回到CarZonesAudioFocus的源码中去看
class CarZonesAudioFocus extends AudioPolicy.AudioPolicyFocusListener
通过源码来看,果真是这样,那么我们来看一下AudioPolicyFocusListener里面都有什么
public static abstract class AudioPolicyFocusListener {
public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {}
public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {}
/**
* Called whenever an application requests audio focus.
* Only ever called if the {@link AudioPolicy} was built with
* {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}.
* @param afi information about the focus request and the requester
* @param requestResult deprecated after the addition of
* {@link AudioManager#setFocusRequestResult(AudioFocusInfo, int, AudioPolicy)}
* in Android P, always equal to {@link #AUDIOFOCUS_REQUEST_GRANTED}.
*/
public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {}
/**
* Called whenever an application abandons audio focus.
* Only ever called if the {@link AudioPolicy} was built with
* {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}.
* @param afi information about the focus request being abandoned and the original
* requester.
*/
public void onAudioFocusAbandon(AudioFocusInfo afi) {}
}
这里重点写了onAudioFocusRequest和onAudioFocusAbandon,这两个主要处理音源焦点用的。调用setIsAudioFocusPolicy(true)使自定义音源策略生效。最后mFocusHandler.setOwningPolicy(this, mAudioPolicy),把AudioPolicy传给CarZonesAudioFocus,这样init函数就结束了。
总结
到这里,我们就分析完了Android10.0 CarAudioService中的init函数。
写的有点笼统,这里面有点绕,需要不断的去思考。