Android13 AudioManager dispatchAudioFocusChange流程分析

当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;
        }
    }
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值