您的位置:首页 > 其它

深入了解MediaServer-1

2014-10-22 10:55 369 查看
http://blog.csdn.net/myarrow/article/details/7048488

1.mediaserver位于main_mediaserver.cpp,其源码如下:

cpp] view
plaincopy

int main(int argc, char** argv)

{

sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();

LOGI("ServiceManager: %p", sm.get());

AudioFlinger::instantiate(); // 创建AudioFlinger对象, 服务名为"media.audio_flinger"

MediaPlayerService::instantiate(); // 创建MediaPlayerService对象,服务名为"media.player"

CameraService::instantiate(); // 创建CameraService对象, 服务名为"media.camera"

AudioPolicyService::instantiate(); // 创建AudioPolicyService对象,服务名为"media.audio_policy"

ProcessState::self()->startThreadPool(); // 创建线程,线程名为"Binder Thread #%d"格式,d为数字编码,例如"Binder Thread #1"

IPCThreadState::self()->joinThreadPool(); // 把上面的线程加入Binder管理,用于IPC进程间通信。

}

此程序的进程名为:/system/bin/mediaserver

[html] view
plaincopy

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空间。

[html] view
plaincopy

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。)

[html] view
plaincopy

sp<IServiceManager> defaultServiceManager()

{

if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

{

AutoMutex _l(gDefaultServiceManagerLock);

if (gDefaultServiceManager == NULL) {

gDefaultServiceManager = <span style="color:#ff0000;">interface_cast</span><IServiceManager>(

ProcessState::self()->getContextObject(NULL));

}

}

return gDefaultServiceManager;

}

ProcessState::self()->getContextObject(NULL)-> getStrongProxyForHandle(0)-> new BpBinder(handle) // handle值为0, 0在binder系统中代表ServiceManger所对应的BBinder.

即:gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0))

它创建了两个关键对象:

1)BpBinder对象,其handle为0

2)BpServiceManager对象,其mRemote值为1)中创建的BpBinder对象。

BpServiceManager实现了IServiceManager中定义的业务逻辑,又有一个成员BpBinder作为其通信代理。

3.1 如何把BpBinder转换为IServiceManager呢?

[html] view
plaincopy

template<typename INTERFACE>

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

{

return INTERFACE::asInterface(obj);

}

[html] view
plaincopy

即:

inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)

{

<span style="color:#3333ff;">return IServiceManager::asInterface(obj);

</span>}

3.2 ServiceManager所提供的服务

[html] view
plaincopy

//IServiceManager.h

class IServiceManager : public IInterface

{

public:

<span style="color:#3333ff;">DECLARE_META_INTERFACE(ServiceManager);

</span>

/**

* Retrieve an existing service, blocking for a few seconds

* if it doesn't yet exist.

*/

virtual sp<IBinder> getService( const String16& name) const = 0;

/**

* Retrieve an existing service, non-blocking.

*/

virtual sp<IBinder> checkService( const String16& name) const = 0;

/**

* Register a service.

*/

virtual status_t addService( const String16& name,

const sp<IBinder>& service) = 0;

/**

* Return list of all existing services.

*/

virtual Vector<String16> listServices() = 0;

enum {

GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,

CHECK_SERVICE_TRANSACTION,

ADD_SERVICE_TRANSACTION,

LIST_SERVICES_TRANSACTION,

};

}

3.3 如何把业务与Binder通信连接起来

[html] view
plaincopy

//IInterface.h

#define DECLARE_META_INTERFACE(INTERFACE) \

static const String16 descriptor; \

static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \

virtual const String16& getInterfaceDescriptor() const; \

I##INTERFACE(); \

virtual ~I##INTERFACE(); \

替换后得到:

[html] view
plaincopy

static const String16 descriptor;

static sp<IServiceManager> <span style="color:#3333ff;">asInterface</span>(const sp<IBinder>& obj);

virtual const String16& getInterfaceDescriptor() const;

IServiceManager();

virtual ~IServiceManager();

asInterface是如何实现的?

[html] view
plaincopy

// 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> I##INTERFACE::asInterface(const sp<IBinder>& obj) \

{ \

sp<I##INTERFACE> intr; \

if (obj != NULL) { \

intr = static_cast<I##INTERFACE*>( \

obj->queryLocalInterface( \

I##INTERFACE::descriptor).get()); \

if (intr == NULL) { \

intr = new Bp##INTERFACE(obj); \

} \

} \

return intr; \

} \

I##INTERFACE::I##INTERFACE() { } \

I##INTERFACE::~I##INTERFACE() { } \

替换后为:

[html] view
plaincopy

const String16 IServiceManager::descriptor("android.os.IServiceManager");

const String16& IServiceManagerE::getInterfaceDescriptor() const {

return IServiceManager::descriptor;

}

sp<IServiceManager> IServiceManager::<span style="color:#ff0000;">asInterface</span>(const sp<IBinder>& obj)

{

sp<IServiceManager> intr;

if (obj != NULL) {

intr = static_cast<IServiceManager*>(

obj->queryLocalInterface(

IServiceManager::descriptor).get());

if (intr == NULL) {

<span style="color:#3333ff;">intr = new BpServiceManager(obj);</span>

}

}

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<IServiceManager>

BnServiceManager同时从IServiceManager和BBinder派生,表示它可以直接参与Binder通信。

3)class BpServiceManager : public BpInterface<IServiceManager>

BpServiceManager同时从IServiceManager和BpRefBase派生。

BpRefBase中有一个成员变量:IBinder* const mRemote;

注:以上关系较复杂,但ServiceManger并没有使用以上派生关系,而是直接打开Binder设备并与之交互。

4)BpRefBase的成员变量mRemote的值就是传进去的BpBinder,使用它就可以与BBinder进行通信了。

5)intr = new BpServiceManager(obj);详细过程如下:

[html] view
plaincopy

BpServiceManager(const sp<IBinder>& impl)

: BpInterface<IServiceManager>(impl)

{

}

template<typename INTERFACE>

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)

: BpRefBase(remote)

{

}

BpRefBase::BpRefBase(const sp<IBinder>& o)

: <span style="color:#ff0000;">mRemote(o.get()), </span>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<xxxx>中xxx* 类型的指针。

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



[html] view
plaincopy

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为例分析注册过程。

[html] view
plaincopy

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<IBinder>& 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派生,其家族关系如下:

[html] view
plaincopy

class MediaPlayerService : public BnMediaPlayerService //业务逻辑和通信

class BnMediaPlayerService: public BnInterface<IMediaPlayerService>

class BnInterface : public IMediaPlayerService, public BBinder

//IMediaPlayerService:负责业务逻辑

//BBinder:负责通信

[html] view
plaincopy

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<IMediaRecorder> createMediaRecorder(pid_t pid);

void removeMediaRecorderClient(wp<MediaRecorderClient> client);

virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid);

// House keeping for media player clients

virtual sp<IMediaPlayer> create(

pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,

const KeyedVector<String8, String8> *headers);

virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);

virtual sp<IMediaConfig> createMediaConfig(pid_t pid);

virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);

virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);

virtual sp<IMemory> snoop();

virtual sp<IOMX> 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<MediaPlayerBase> createPlayer(player_type playerType);

status_t setDataSource(

const char *url,

const KeyedVector<String8, String8> *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<MediaPlayerBase> getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }

};

class MediaConfigClient: public BnMediaConfig

{

...

};

// ----------------------------------------------------------------------------

MediaPlayerService();

virtual ~MediaPlayerService();

mutable Mutex mLock;

SortedVector< wp<Client> > mClients;

SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;

int32_t mNextConnId;

sp<IOMX> mOMX;

int32_t mRatio;

int32_t mCrvs;

int32_t mLeft;

int32_t mTop;

int32_t mWidth;

int32_t mHeight;

}

4.1 addService

[html] view
plaincopy

void MediaPlayerService::instantiate() {

defaultServiceManager()->addService(

String16("media.player"), new MediaPlayerService());

}

创建一个新的Service—BnMediaPlayerService,想把它告诉ServiceManager。然后调用BpServiceManger的addService来向ServiceManager中增加一个Service.其它进程可通过字符串"media.player"来向ServiceManger查询到此服务。

addService是调用的BpServiceManager的函数。

[html] view
plaincopy

virtual status_t addService(const String16& name, const sp<IBinder>& 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); <span style="color:#ff0000;">//把MediaPlayerService写入flat_binder_object中

</span> //调用remote的transact函数

status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

return err == NO_ERROR ? reply.readInt32() : err;

}

remote()返回的是前面创建的BpBinder(0).

[html] view
plaincopy

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;

}

...

}

[html] view
plaincopy

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 = <span style="color:#ff0000;">writeTransactionData</span>(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 = <span style="color:#ff0000;">waitForResponse</span>(&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;

}

[html] view
plaincopy

status_t IPCThreadState::<span style="color:#ff0000;">writeTransactionData</span>(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.

[html] view
plaincopy

status_t IPCThreadState::<span style="color:#ff0000;">waitForResponse</span>(Parcel *reply, status_t *acquireResult)

{

int32_t cmd;

int32_t err;

while (1) {

if ((err=<span style="color:#ff0000;">talkWithDriver</span>()) < 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<const uint8_t*>(tr.data.ptr.buffer),

tr.data_size,

reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

tr.offsets_size/sizeof(size_t),

freeBuffer, this);

} else {

err = *static_cast<const status_t*>(tr.data.ptr.buffer);

freeBuffer(NULL,

reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

tr.data_size,

reinterpret_cast<const size_t*>(tr.data.ptr.offsets),

tr.offsets_size/sizeof(size_t), this);

}

} else {

freeBuffer(NULL,

reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

tr.data_size,

reinterpret_cast<const size_t*>(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;

}

[html] view
plaincopy

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");

<span style="color:#ff0000;">binder_write_read bwr;

</span>

// 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;

<span style="color:#3333ff;"> bwr.write_size = outAvail;

bwr.write_buffer = (long unsigned int)mOut.data();</span>

// This is what we'll read.

if (doReceive && needRead) {

<span style="color:#3333ff;"> bwr.read_size = mIn.dataCapacity();

bwr.read_buffer = (long unsigned int)mIn.data();

</span> } 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 { //<span style="color:red;">中间东西太复杂了,就是把<span lang="EN-US">mOut发送</span>数据和<span lang="EN-US">mIn</span>接收数据的处理后赋值给<span lang="EN-US">bwr</span></span>

IF_LOG_COMMANDS() {

alog << "About to read/write, write size = " << mOut.dataSize() << endl;

}

#if defined(HAVE_ANDROID_OS)

<span style="color:#ff0000;"> <span style="font-size:13px;"><strong>if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)</strong>

</span></span> 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);

<span style="color:red;">//</span><span style="color:red;">到这里,回复数据就在<span lang="EN-US">bwr</span>中了,<span lang="EN-US">bwr</span>接收回复数据的<span lang="EN-US">buffer</span>就是<span lang="EN-US">mIn</span>提供的<span lang="EN-US"><o:p></o:p></span></span>

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设备的操作啊!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: