1.mediaserver位于main_mediaserver.cpp,其源码如下:
int main(int argc, char** argv)
{
sp proc(ProcessState::self());
sp sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate(); //音频系统的mixer and resampler
MediaPlayerService::instantiate(); //创建一个player,并进行AV播放
CameraService::instantiate(); // 摄像和照相的服务
AudioPolicyService::instantiate(); //音频策略的服务
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
此程序的进程名为:/system/bin/mediaserver
void AudioFlinger::instantiate() {
defaultServiceManager()->addService(
String16("media.audio_flinger"), new AudioFlinger());
}
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
void CameraService::instantiate() {
defaultServiceManager()->addService(
String16("media.camera"), new CameraService());
}
void AudioPolicyService::instantiate() {
defaultServiceManager()->addService(
String16("media.audio_policy"), new AudioPolicyService());
}
查看系统已经注册的media类Service,其结果如下:
# service list | busybox grep media
5 audio: [android.media.IAudioService]
63 media.audio_policy: [android.media.IAudioPolicyService]
64 media.camera: [android.hardware.ICameraService]
65 media.player: [android.media.IMediaPlayerService]
66 media.audio_flinger: [android.media.IAudioFlinger]
2. 独一无二的ProcessState
ProcessState是一个单实例,每个进程只有一个实例。ProcessState::self()功能为打开/dev/binder设备,设置线程池中最大线程数,通过mmap把Binder Driver为其分配的内在映射到用户空间,以便把发送方的数据从发送方的用户空间直接copy到接收方的mmap空间。
ProcessState::ProcessState()
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// XXX Ideally, there should be a specific define for whether we
// have mmap (or whether we could possibly have the kernel module
// availabla).
#if !defined(HAVE_WIN32_IPC)
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
}
#else
mDriverFD = -1;
#endif
}
if (mDriverFD < 0) {
// Need to run without the driver, starting our own thread pool.
}
}
3. 神奇的 defaultServiceManager
defaultServiceManager在IServiceManager.cpp中实现,其功能是获得一个IServiceManager对象。通过这个对象,就可以与进程/system/bin/servicemanager进行通信。
(defaultServiceManager实际返回的是BpServiceManager,它的remote对象是BpBinder,传入的那个handle参数是0。)
sp defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject(NULL)-> getStrongProxyForHandle(0)-> new BpBinder(handle) // handle值为0, 0在binder系统中代表ServiceManger所对应的BBinder.
即:gDefaultServiceManager = interface_cast
它创建了两个关键对象:
1)BpBinder对象,其handle为0
2)BpServiceManager对象,其mRemote值为1)中创建的BpBinder对象。
BpServiceManager实现了IServiceManager中定义的业务逻辑,又有一个成员BpBinder作为其通信代理。
3.1 如何把BpBinder转换为IServiceManager呢?
template
inline sp interface_cast(const sp& obj)
{
return INTERFACE::asInterface(obj);
}
即:
inline sp interface_cast(const sp& obj)
{
return IServiceManager::asInterface(obj);
}
3.2 ServiceManager所提供的服务
//IServiceManager.h
class IServiceManager : public IInterface
{
public:
DECLARE_META_INTERFACE(ServiceManager);
/**
* Retrieve an existing service, blocking for a few seconds
* if it doesn't yet exist.
*/
virtual sp getService( const String16& name) const = 0;
/**
* Retrieve an existing service, non-blocking.
*/
virtual sp checkService( const String16& name) const = 0;
/**
* Register a service.
*/
virtual status_t addService( const String16& name,
const sp& service) = 0;
/**
* Return list of all existing services.
*/
virtual Vector listServices() = 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
}
3.3 如何把业务与Binder通信连接起来
//IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE) \
static const String16 descriptor; \
static sp asInterface(const sp& obj); \
virtual const String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
替换后得到:
static const String16 descriptor;
static sp asInterface(const sp& obj);
virtual const String16& getInterfaceDescriptor() const;
IServiceManager();
virtual ~IServiceManager();
asInterface是如何实现的?
// IServiceManager.cpp
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
//IInterface.h
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const String16 I##INTERFACE::descriptor(NAME); \
const String16& I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
sp I##INTERFACE::asInterface(const sp& obj) \
{ \
sp intr; \
if (obj != NULL) { \
intr = static_cast( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
替换后为:
const String16 IServiceManager::descriptor("android.os.IServiceManager");
const String16& IServiceManagerE::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
sp IServiceManager::asInterface(const sp& obj)
{
sp intr;
if (obj != NULL) {
intr = static_cast(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
如何把BpBinder转换为IServiceManager的答案为:intr = new BpServiceManager(obj);
其原理为:interface_cast并不是一个指针转换,而是把BpBinder做为一个参数,创建了一个新的BpServiceManager.
3.3.1 IServiceManager家族图谱
转自:http://book.51cto.com/art/201109/293428.htm
1)IServiceManager,BpServiceManager和BnServiceManager都与业务逻辑相关。
2)class BnServiceManager : public BnInterface
BnServiceManager同时从IServiceManager和BBinder派生,表示它可以直接参与Binder通信。
3)class BpServiceManager : public BpInterface
BpRefBase中有一个成员变量:IBinder* const mRemote;
注:以上关系较复杂,但ServiceManger并没有使用以上派生关系,而是直接打开Binder设备并与之交互。
4)BpRefBase的成员变量mRemote的值就是传进去的BpBinder,使用它就可以与BBinder进行通信了。
5)intr = new BpServiceManager(obj);详细过程如下:
BpServiceManager(const sp& impl)
: BpInterface(impl)
{
}
template
inline BpInterface::BpInterface(const sp& remote)
: BpRefBase(remote)
{
}
BpRefBase::BpRefBase(const sp& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}
o.get(),这个是sp类的获取实际数据指针的一个方法,它返回的是sp
3.4 ProcessState & IPCThreadState
ProcessState负责打开BinderDriver,准备好与Binder Driver通信;而IPCThreadState负责通过Binder Driver而进行跨进程的实际数据的读写。例如,client进程的程序调用BpBinder的IBinder中的transact()函数,此transact()函数则调用IPCThreadState中的transact()函数调用Binder Driver的ioctl()函数进行数据的传输。
IPCThreadState::transact->IPCThreadState::waitForResponse-> IPCThreadState::talkWithDriver->ioctl
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
4. 注册一个Service
以MediaPlayerService为例分析注册过程。
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
MediaPlayerService::MediaPlayerService()
{
LOGV("MediaPlayerService created");
mNextConnId = 1;
mRatio = -1;
mCrvs = -1;
mLeft = -1;
mTop =-1;
mWidth =-1;
mHeight =-1;
}
virtual status_t addService(const String16& name, const sp& service)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
remote()返回的就是BpServiceManager中保存的BpBinder。
MediaPlayerService 从BnMediaPlayerService派生,其家族关系如下:
class MediaPlayerService : public BnMediaPlayerService //业务逻辑和通信
class BnMediaPlayerService: public BnInterface
class BnInterface : public IMediaPlayerService, public BBinder
//IMediaPlayerService:负责业务逻辑
//BBinder:负责通信
class MediaPlayerService : public BnMediaPlayerService
{
class Client;
class MediaConfigClient;
class AudioOutput : public MediaPlayerBase::AudioSink
{
...
};
class AudioCache : public MediaPlayerBase::AudioSink
{
...
};
public:
static void instantiate();
// IMediaPlayerService interface
virtual sp createMediaRecorder(pid_t pid);
void removeMediaRecorderClient(wp client);
virtual sp createMetadataRetriever(pid_t pid);
// House keeping for media player clients
virtual sp create(
pid_t pid, const sp& client, const char* url,
const KeyedVector *headers);
virtual sp create(pid_t pid, const sp& client, int fd, int64_t offset, int64_t length);
virtual sp createMediaConfig(pid_t pid);
virtual sp decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp snoop();
virtual sp getOMX();
private:
class Client : public BnMediaPlayer {
virtual status_t prepareAsync();
virtual status_t start();
virtual status_t stop();
virtual status_t pause();
virtual status_t isPlaying(bool* state);
virtual status_t seekTo(int msec);
virtual status_t getCurrentPosition(int* msec);
virtual status_t getDuration(int* msec);
virtual status_t reset();
virtual status_t setAudioStreamType(int type);
virtual status_t setLooping(int loop);
virtual status_t setVolume(float leftVolume, float rightVolume);
virtual status_t invoke(const Parcel& request, Parcel *reply);
virtual status_t setMetadataFilter(const Parcel& filter);
virtual status_t getMetadata(bool update_only,
bool apply_filter,
Parcel *reply);
sp createPlayer(player_type playerType);
status_t setDataSource(
const char *url,
const KeyedVector *headers);
status_t setDataSource(int fd, int64_t offset, int64_t length);
static void notify(void* cookie, int msg, int ext1, int ext2);
private:
friend class MediaPlayerService;
sp getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }
};
class MediaConfigClient: public BnMediaConfig
{
...
};
// ----------------------------------------------------------------------------
MediaPlayerService();
virtual ~MediaPlayerService();
mutable Mutex mLock;
SortedVector< wp > mClients;
SortedVector< wp > mMediaRecorderClients;
int32_t mNextConnId;
sp mOMX;
int32_t mRatio;
int32_t mCrvs;
int32_t mLeft;
int32_t mTop;
int32_t mWidth;
int32_t mHeight;
}
4.1 addService
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
创建一个新的Service—BnMediaPlayerService,想把它告诉ServiceManager。然后调用BpServiceManger的addService来向ServiceManager中增加一个Service.其它进程可通过字符串"media.player"来向ServiceManger查询到此服务。
addService是调用的BpServiceManager的函数。
virtual status_t addService(const String16& name, const sp& service)
{
Parcel data, reply;
//data是发送到BnServiceManager的命令包
//看见没?先把Interface名字写进去,也就是什么android.os.IServiceManager
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
//再把新service的名字写进去 叫media.player
data.writeString16(name);
//把新服务service—>就是MediaPlayerService写到命令中
data.writeStrongBinder(service); //把MediaPlayerService写入flat_binder_object中
//调用remote的transact函数
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readInt32() : err;
}
remote()返回的是前面创建的BpBinder(0).
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
//注意啊,这里的mHandle为0,code是ADD_SERVICE_TRANSACTION,data是命令包
//reply是回复包,flags=0
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
...
}
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
<< handle << " / code " << TypeCode(code) << ": "
<< indent << data << dedent << endl;
}
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//把要发送的数据写入binder_transaction_data中
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
<< handle << ": ";
if (reply) alog << indent << *reply << dedent << endl;
else alog << "(none requested)" << endl;
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
tr.data.ptr.offsets = data.ipcObjects();
} else if (statusBuffer) {
tr.flags |= TF_STATUS_CODE;
*statusBuffer = err;
tr.data_size = sizeof(status_t);
tr.data.ptr.buffer = statusBuffer;
tr.offsets_size = 0;
tr.data.ptr.offsets = NULL;
} else {
return (mLastError = err);
}
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
上面的代码把数据封装成binder_transaction_data,然后写到mOut中。mOut是一个命令buffer,也是一个Parcel.
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break; //发送数据到ServiceManager
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
case BR_REPLY:
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
reply->ipcSetDataReference(
reinterpret_cast(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t),
freeBuffer, this);
} else {
err = *static_cast(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t), this);
}
} else {
freeBuffer(NULL,
reinterpret_cast(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t), this);
continue;
}
}
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
binder_write_read bwr;
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (long unsigned int)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (long unsigned int)mIn.data();
} else {
bwr.read_size = 0;
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
if (outAvail != 0) {
alog << "Sending commands to driver: " << indent;
const void* cmds = (const void*)bwr.write_buffer;
const void* end = ((const uint8_t*)cmds)+bwr.write_size;
alog << HexDump(cmds, bwr.write_size) << endl;
while (cmds < end) cmds = printCommand(alog, cmds);
alog << dedent;
}
alog << "Size of receive buffer: " << bwr.read_size
<< ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do { //中间东西太复杂了,就是把mOut发送数据和mIn接收数据的处理后赋值给bwr
IF_LOG_COMMANDS() {
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(HAVE_ANDROID_OS)
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
IF_LOG_COMMANDS() {
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
}
} while (err == -EINTR);
//到这里,回复数据就在bwr中了,bwr接收回复数据的buffer就是mIn提供的
IF_LOG_COMMANDS() {
alog << "Our err: " << (void*)err << ", write consumed: "
<< bwr.write_consumed << " (of " << mOut.dataSize()
<< "), read consumed: " << bwr.read_consumed << endl;
}
if (err >= NO_ERROR) {
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < (ssize_t)mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
alog << "Remaining data size: " << mOut.dataSize() << endl;
alog << "Received commands from driver: " << indent;
const void* cmds = mIn.data();
const void* end = mIn.data() + mIn.dataSize();
alog << HexDump(cmds, mIn.dataSize()) << endl;
while (cmds < end) cmds = printReturnCommand(alog, cmds);
alog << dedent;
}
return NO_ERROR;
}
return err;
}
至此发送addService到ServiceManager就已经结束了。BpServiceManager发送了一个addService命令到BnServiceManager,然后收到回复。
问题:MediaPlayerService是一个BnMediaPlayerService,那么它是不是应该等着
BpMediaPlayerService来和他交互呢?但是我们没看见MediaPlayerService有打开binder设备的操作啊!