首先给大家分享一个巨牛巨牛的人工智能教程,是我无意中发现的。教程不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵段子,像看小说一样,哈哈~我正在学习中,觉得太牛了,所以分享给大家!点这里可以跳转到教程
1.mediaserver位于main_mediaserver.cpp,其源码如下:
int main(int argc, char** argv){ sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> 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<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<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呢?
template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}
即:inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){ return IServiceManager::asInterface(obj);}
3.2 ServiceManager所提供的服务
//IServiceManager.hclass 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<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通信连接起来
//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(); \
替换后得到:
static const String16 descriptor; static sp<IServiceManager> asInterface(const sp<IBinder>& obj); virtual const String16& getInterfaceDescriptor() const; IServiceManager(); virtual ~IServiceManager();
asInterface是如何实现的?
// IServiceManager.cppIMPLEMENT_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() { } \
替换后为:
const String16 IServiceManager::descriptor("android.os.IServiceManager"); const String16& IServiceManagerE::getInterfaceDescriptor() const { return IServiceManager::descriptor; } sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder>& obj) { sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IServiceManager*>( 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<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);详细过程如下:
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) : 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<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
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<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派生,其家族关系如下:
class MediaPlayerService : public BnMediaPlayerService //业务逻辑和通信class BnMediaPlayerService: public BnInterface<IMediaPlayerService>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<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
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<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); //把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<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;}
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设备的操作啊!