以audiosystem中的static status_t setStreamMute(int stream, bool mute);函数的调用为例。
AudioSystem.cpp中相应代码如下:
status_t AudioSystem::setStreamMute(int stream, bool mute)
{
if (uint32_t(stream) >= NUM_STREAM_TYPES) return BAD_VALUE;
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
af->setStreamMute(stream, mute);
return NO_ERROR;
}
get_audio_flinger返回的是gAudioFlinger指针,它对应"media.audio_flinger"这个服务。
binder = sm->getService(String16("media.audio_flinger"));
gAudioFlinger = interface_cast<IAudioFlinger>(binder);
af->setStreamMute(stream, mute);
就调用了IAudioFlinger.cpp中的
virtual status_t setStreamMute(int stream, bool muted)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32(stream);
data.writeInt32(muted);
remote()->transact(SET_STREAM_MUTE, data, &reply);
return reply.readInt32();
}
它利用Binder IPC机制,将SET_STREAM_MUTE这个任务交给了一个service。
status_t BnAudioFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
…
case SET_STREAM_MUTE: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
int stream = data.readInt32();
reply->writeInt32( setStreamMute(stream, data.readInt32()) );
return NO_ERROR;
} break;…
}
其中关键是调用了setStreamMute(stream, data.readInt32())这个函数。
那么,BnAudioFlinger作为一个service,其实际的setStreamMute(stream, data.readInt32())操作在哪里呢?
class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
可见,实际上是AudioFlinger作为一个service对IAudioFlinger提供服务。
status_t AudioFlinger::setStreamMute(int stream, bool muted)
{
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
return BAD_VALUE;
}
mStreamTypes[stream].mute = muted;
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
return NO_ERROR;
}
DefaultKeyedVector< int, sp<PlaybackThread> > mPlaybackThreads;是AudioFlinger的一个数据成员。结构就是个map。
由for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
可见,AudioFlinger可以为多个playback线程提供服务。AudioSystem中的setStreamMute函数是一个静态成员函数,针对的是system-wide的操作,所以讲所有playback现成的相应stream类型mute是合理的。
class PlaybackThread : public ThreadBase
class ThreadBase : public Thread
class Thread : virtual public RefBase
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
实际就调用了相应playback thread的setStreamMute函数,如下
status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted)
{
#ifdef LVMX
int audioOutputType = LifeVibes::getMixerType(mId, mType);
if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
LifeVibes::setStreamMute(audioOutputType, stream, muted);
}
#endif
mStreamTypes[stream].mute = muted;
return NO_ERROR;
}
AudioSystem为上层提供system-wide的audio操作。
AudioTrack为上层提供播放接口。
AudioRecord为上层提供录音接口。
他们最后使用的服务依然还是AudioFlinger.cpp
class TrackHandle : public android::BnAudioTrack
{
private:
sp<PlaybackThread::Track> mTrack;
};
以AudioTrack的start为例。
class BpAudioTrack : public BpInterface<IAudioTrack>
virtual status_t start()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
status_t status = remote()->transact(START, data, &reply);
if (status == NO_ERROR) {
status = reply.readInt32();
} else {
LOGW("start() error: %s", strerror(-status));
}
return status;
}
status_t BnAudioTrack::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
…
case START: {
CHECK_INTERFACE(IAudioTrack, data, reply);
reply->writeInt32(start());
return NO_ERROR;
} break;
….
}
在函数sp<IAudioTrack> AudioFlinger::createTrack中,有:
sp<TrackHandle> trackHandle;
trackHandle = new TrackHandle(track);
return trackHandle;
又有:class TrackHandle : public android::BnAudioTrack
可见实际为IAudioTrack提供服务的是TrackHandle。调用的是TrackHandle中的start。
status_t AudioFlinger::TrackHandle::start() {
return mTrack->start();
}
class TrackHandle : public android::BnAudioTrack {
private:
sp<PlaybackThread::Track> mTrack;
};
可见我们最后调用的是PlaybackThread::Track这个类中的start方法。
如下:
status_t AudioFlinger::PlaybackThread::Track::start()
(PS:以上分析不一定正确,有待改进)。