当App调用AudioManager的requestAudioFocus或abandonAudioFocus方法申请或释放音频焦点后,会通过AudioPolicy.AudioPolicyFocusListener的方式调用到CarZonesAudioFocus的onAudioFocusRequest或onAudioFocusAbandon方法,经过CarZonesAudioFocus对音频焦点进行仲裁后后,再通过CarAudioFocus的onAudioFocusRequest回调,来调用AudioManager的dispatchAudioFocusChange方法,其中
requestAudioFocus部分流程如下:
待更新
abandonAudioFocus部分流程如下:
待更新
onAudioFocusRequest回调处理流程如下:
待更新
onAudioFocusAbandon回调处理流程如下:
待更新
下面介绍AudioManager的dispatchAudioFocusChange流程:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
//Notifies an application with a focus listener of gain or loss of audio focus.
//通知具有焦点侦听器的应用程序音频焦点的增益或损失。
public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange,
@NonNull AudioPolicy ap) {
if (afi == null) {
throw new NullPointerException("Illegal null AudioFocusInfo");
}
if (ap == null) {
throw new NullPointerException("Illegal null AudioPolicy");
}
final IAudioService service = getService(); //获取IAudioService对象
try {
return service.dispatchFocusChange(afi, focusChange, ap.cb()); //调用IAudioService的dispatchFocusChange方法
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
调用IAudioService的dispatchFocusChange方法,IAudioService是一个接口,由AudioService的dispatchFocusChange方法实现:
//frameworks/base/service/java/com/android/server/audio/AudioService.java
public class AudioService extends IAudioService.Stub
private final MediaFocusControl mMediaFocusControl;
public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
if (afi == null) {
throw new IllegalArgumentException("Illegal null AudioFocusInfo");
}
if (pcb == null) {
throw new IllegalArgumentException("Illegal null AudioPolicy callback");
}
synchronized (mAudioPolicies) {
if (!mAudioPolicies.containsKey(pcb.asBinder())) {
throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
}
return mMediaFocusControl.dispatchFocusChange(afi, focusChange); //调用MediaFocusControl的dispatchFocusChange方法
}
}
}
调用MediaFocusControl的dispatchFocusChange方法:
//frameworks/base/service/java/com/android/server/audio/MediaFocusControl.java
public class MediaFocusControl implements PlayerFocusEnforcer {
int dispatchFocusChange(AudioFocusInfo afi, int focusChange) {
if (DEBUG) {
Log.v(TAG, "dispatchFocusChange " + focusChange + " to afi client="
+ afi.getClientId());
}
synchronized (mAudioFocusLock) {
if (mFocusPolicy == null) {
if (DEBUG) { Log.v(TAG, "> failed: no focus policy" ); }
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
final FocusRequester fr;
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
fr = mFocusOwnersForFocusPolicy.remove(afi.getClientId());
} else {
fr = mFocusOwnersForFocusPolicy.get(afi.getClientId());
}
if (fr == null) {
if (DEBUG) { Log.v(TAG, "> failed: no such focus requester known" ); }
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
return fr.dispatchFocusChange(focusChange); //调用FocusRequester的dispatchFocusChange方法
}
}
}
调用FocusRequester的dispatchFocusChange方法:
//frameworks/base/service/java/com/android/server/audio/FocusRequester.java
public class FocusRequester {
int dispatchFocusChange(int focusChange) {
final IAudioFocusDispatcher fd = mFocusDispatcher;
if (fd == null) {
if (MediaFocusControl.DEBUG) { Log.e(TAG, "dispatchFocusChange: no focus dispatcher"); }
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
if (focusChange == AudioManager.AUDIOFOCUS_NONE) {
if (MediaFocusControl.DEBUG) { Log.v(TAG, "dispatchFocusChange: AUDIOFOCUS_NONE"); }
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
} else if ((focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
|| focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
|| focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
|| focusChange == AudioManager.AUDIOFOCUS_GAIN)
&& (mFocusGainRequest != focusChange)){
Log.w(TAG, "focus gain was requested with " + mFocusGainRequest
+ ", dispatching " + focusChange);
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
|| focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT
|| focusChange == AudioManager.AUDIOFOCUS_LOSS) {
mFocusLossReceived = focusChange;
}
try {
fd.dispatchAudioFocusChange(focusChange, mClientId); //调用IAudioFocusDispatcher的dispatchAudioFocusChange方法
} catch (android.os.RemoteException e) {
Log.e(TAG, "dispatchFocusChange: error talking to focus listener " + mClientId, e);
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
}
}
调用IAudioFocusDispatcher的dispatchAudioFocusChange方法,IAudioFocusDispatcher是一个接口,由AudioManager实现:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
@Override
public void dispatchAudioFocusChange(int focusChange, String id) {
final FocusRequestInfo fri = findFocusRequestInfo(id);
if (fri != null) {
final OnAudioFocusChangeListener listener =
fri.mRequest.getOnAudioFocusChangeListener();
if (listener != null) {
final Handler h = (fri.mHandler == null) ?
mServiceEventHandlerDelegate.getHandler() : fri.mHandler;
final Message m = h.obtainMessage(
MSSG_FOCUS_CHANGE/*what*/, focusChange/*arg1*/, 0/*arg2 ignored*/, //获取要发送的消息
id/*obj*/);
h.sendMessage(m); //发送消息
}
}
}
};
}
发送MSSG_FOCUS_CHANGE消息,AudioManager的内部类ServiceEventHandlerDelegate的handleMessage方法会处理这个消息:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
private class ServiceEventHandlerDelegate {
private final Handler mHandler;
ServiceEventHandlerDelegate(Handler handler) {
Looper looper;
if (handler == null) {
if ((looper = Looper.myLooper()) == null) {
looper = Looper.getMainLooper();
}
} else {
looper = handler.getLooper();
}
if (looper != null) {
// implement the event handler delegate to receive events from audio service
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSSG_FOCUS_CHANGE: {
final FocusRequestInfo fri = findFocusRequestInfo((String)msg.obj);
if (fri != null) {
final OnAudioFocusChangeListener listener =
fri.mRequest.getOnAudioFocusChangeListener(); //获取OnAudioFocusChange监听器
if (listener != null) {
Log.d(TAG, "dispatching onAudioFocusChange("
+ msg.arg1 + ") to " + msg.obj);
listener.onAudioFocusChange(msg.arg1); //调用监听器的onAudioFocusChange方法,通知监听App
}
}
} break;
default:
Log.e(TAG, "Unknown event " + msg.what);
}
}
};
} else {
mHandler = null;
}
}
Handler getHandler() {
return mHandler;
}
}
}