当App调用AudioManager的requestAudioFocus方法申请音频焦点时,会通过AudioPolicy.AudioPolicyFocusListener的方式调用到CarZonesAudioFocus的onAudioFocusRequest方法,经过CarZonesAudioFocus对音频焦点进行仲裁后后,再通过CarAudioFocus的setFocusRequestResult通知AudioManager,这时AudioManager的requestAudioFocus方法才会返回处理结果,接下来我们分析AudioManager的setFocusRequestResult方法:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
public void setFocusRequestResult(@NonNull AudioFocusInfo afi,
@FocusRequestResult int requestResult, @NonNull AudioPolicy ap) {
if (afi == null) {
throw new IllegalArgumentException("Illegal null AudioFocusInfo");
}
if (ap == null) {
throw new IllegalArgumentException("Illegal null AudioPolicy");
}
final IAudioService service = getService(); //取得IAudioService对象
try {
service.setFocusRequestResultFromExtPolicy(afi, requestResult, ap.cb()); //调用IAudioService的setFocusRequestResultFromExtPolicy方法
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
调用IAudioService的setFocusRequestResultFromExtPolicy方法,IAudioService是一个接口,由AudioService实现,因此会调用AudioService的setFocusRequestResultFromExtPolicy方法:
//frameworks/base/service/java/com/android/server/audio/AudioService.java
public class AudioService extends IAudioService.Stub
private final MediaFocusControl mMediaFocusControl;
public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
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 external focus");
}
mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult); //调用MediaFocusControl的setFocusRequestResultFromExtPolicy方法
}
}
}
调用MediaFocusControl的setFocusRequestResultFromExtPolicy方法:
//frameworks/base/service/java/com/android/server/audio/MediaFocusControl.java
public class MediaFocusControl implements PlayerFocusEnforcer {
void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult) {
synchronized (mExtFocusChangeLock) {
if (afi.getGen() > mExtFocusChangeCounter) {
return;
}
}
final FocusRequester fr;
if (requestResult == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
fr = mFocusOwnersForFocusPolicy.remove(afi.getClientId()); //获取FocusRequester对象
} else {
fr = mFocusOwnersForFocusPolicy.get(afi.getClientId()); //获取FocusRequester对象
}
if (fr != null) {
fr.dispatchFocusResultFromExtPolicy(requestResult); //调用FocusRequester的dispatchFocusResultFromExtPolicy方法
}
}
}
调用FocusRequester的dispatchFocusResultFromExtPolicy方法:
//frameworks/base/service/java/com/android/server/audio/FocusRequester.java
public class FocusRequester {
void dispatchFocusResultFromExtPolicy(int requestResult) {
final IAudioFocusDispatcher fd = mFocusDispatcher;
if (fd == null) {
if (MediaFocusControl.DEBUG) {
Log.e(TAG, "dispatchFocusResultFromExtPolicy: no focus dispatcher");
}
return;
}
if (DEBUG) {
Log.v(TAG, "dispatching result" + requestResult + " to " + mClientId);
}
try {
fd.dispatchFocusResultFromExtPolicy(requestResult, mClientId); //调用IAudioFocusDispatcher的dispatchFocusResultFromExtPolicy方法
} catch (android.os.RemoteException e) {
Log.e(TAG, "dispatchFocusResultFromExtPolicy: error talking to focus listener"
+ mClientId, e);
}
}
}
调用IAudioFocusDispatcher的dispatchFocusResultFromExtPolicy方法,IAudioFocusDispatcher是一个接口,由AudioManager实现:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
@Override
public void dispatchFocusResultFromExtPolicy(int requestResult, String clientId) {
synchronized (mFocusRequestsLock) {
// TODO use generation counter as the key instead
final BlockingFocusResultReceiver focusReceiver =
mFocusRequestsAwaitingResult.remove(clientId);
if (focusReceiver != null) {
focusReceiver.notifyResult(requestResult); //调用BlockingFocusResultReceiver的notifyResult方法
} else {
Log.e(TAG, "dispatchFocusResultFromExtPolicy found no result receiver");
}
}
}
};
}
调用BlockingFocusResultReceiver的notifyResult方法,BlockingFocusResultReceiver是AudioManager的内部类:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
private static final class BlockingFocusResultReceiver {
private final SafeWaitObject mLock = new SafeWaitObject();
@GuardedBy("mLock")
private boolean mResultReceived = false;
// request denied by default (e.g. timeout)
private int mFocusRequestResult = AudioManager.AUDIOFOCUS_REQUEST_FAILED;
private final String mFocusClientId;
void notifyResult(int requestResult) {
synchronized (mLock) {
mResultReceived = true;
mFocusRequestResult = requestResult;
mLock.safeNotify(); //调用SafeWaitObject 的safeNotify方法,通知锁
}
}
}
}
在AudioManager的requestAudioFocus方法中调用focusReceiver的waitForResult方法等待上面的Notify:
//frameworks/base/media/java/android/media/AudioManager.java
public class AudioManager {
public int requestAudioFocus(@NonNull AudioFocusRequest afr, @Nullable AudioPolicy ap) {
if (afr == null) {
throw new NullPointerException("Illegal null AudioFocusRequest");
}
// this can only be checked now, not during the creation of the AudioFocusRequest instance
if (afr.locksFocus() && ap == null) {
throw new IllegalArgumentException(
"Illegal null audio policy when locking audio focus");
}
registerAudioFocusRequest(afr);
final IAudioService service = getService();
final int status;
int sdk;
try {
sdk = getContext().getApplicationInfo().targetSdkVersion;
} catch (NullPointerException e) {
// some tests don't have a Context
sdk = Build.VERSION.SDK_INT;
}
final String clientId = getIdForAudioFocusListener(afr.getOnAudioFocusChangeListener());
final BlockingFocusResultReceiver focusReceiver;
synchronized (mFocusRequestsLock) {
try {
// TODO status contains result and generation counter for ext policy
status = service.requestAudioFocus(afr.getAudioAttributes(),
afr.getFocusGain(), mICallBack,
mAudioFocusDispatcher,
clientId,
getContext().getOpPackageName() /* package name */,
getContext().getAttributionTag(),
afr.getFlags(),
ap != null ? ap.cb() : null,
sdk);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
if (status != AudioManager.AUDIOFOCUS_REQUEST_WAITING_FOR_EXT_POLICY) {
// default path with no external focus policy
return status;
}
if (mFocusRequestsAwaitingResult == null) {
mFocusRequestsAwaitingResult =
new HashMap<String, BlockingFocusResultReceiver>(1);
}
focusReceiver = new BlockingFocusResultReceiver(clientId);
mFocusRequestsAwaitingResult.put(clientId, focusReceiver);
}
focusReceiver.waitForResult(EXT_FOCUS_POLICY_TIMEOUT_MS);
if (DEBUG && !focusReceiver.receivedResult()) {
Log.e(TAG, "requestAudio response from ext policy timed out, denying request");
}
synchronized (mFocusRequestsLock) {
mFocusRequestsAwaitingResult.remove(clientId);
}
return focusReceiver.requestResult(); //返回焦点申请结果
}
}
BlockingFocusResultReceiver的waitForResult方法如下:
public class AudioManager {
private static final class BlockingFocusResultReceiver {
private final SafeWaitObject mLock = new SafeWaitObject();
@GuardedBy("mLock")
private boolean mResultReceived = false;
// request denied by default (e.g. timeout)
private int mFocusRequestResult = AudioManager.AUDIOFOCUS_REQUEST_FAILED;
private final String mFocusClientId;
public void waitForResult(long timeOutMs) {
synchronized (mLock) {
if (mResultReceived) {
// the result was received before waiting
return;
}
try {
mLock.safeWait(timeOutMs); //调用SafeWaitObject的safeWait,等待锁
} catch (InterruptedException e) { }
}
}
}
}