深入了解MediaServer-1

来源:互联网 发布:php高级工程师是什么 编辑:程序博客网 时间:2024/06/05 11:10

http://blog.csdn.net/myarrow/article/details/7048488

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

[html] view plaincopyprint?
  1. int main(int argc, char** argv)  
  2. {  
  3.     sp<ProcessState> proc(ProcessState::self());  
  4.     sp<IServiceManager> sm = defaultServiceManager();  
  5.     LOGI("ServiceManager: %p", sm.get());  
  6.     AudioFlinger::instantiate();     //音频系统的mixer and resampler  
  7.     MediaPlayerService::instantiate();  //创建一个player,并进行AV播放  
  8.     CameraService::instantiate();     // 摄像和照相的服务  
  9.     AudioPolicyService::instantiate();  //音频策略的服务  
  10.     ProcessState::self()->startThreadPool();  
  11.     IPCThreadState::self()->joinThreadPool();  
  12. }  

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

[html] view plaincopyprint?
  1. void AudioFlinger::instantiate() {  
  2.     defaultServiceManager()->addService(  
  3.             String16("media.audio_flinger"), new AudioFlinger());  
  4. }  
  5.   
  6. void MediaPlayerService::instantiate() {  
  7.     defaultServiceManager()->addService(  
  8.             String16("media.player"), new MediaPlayerService());  
  9. }  
  10.   
  11. void CameraService::instantiate() {  
  12.     defaultServiceManager()->addService(  
  13.             String16("media.camera"), new CameraService());  
  14. }  
  15.   
  16. void AudioPolicyService::instantiate() {  
  17.     defaultServiceManager()->addService(  
  18.             String16("media.audio_policy"), new AudioPolicyService());  
  19. }  

查看系统已经注册的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 plaincopyprint?
  1. ProcessState::ProcessState()  
  2.     : mDriverFD(open_driver())  
  3.     , mVMStart(MAP_FAILED)  
  4.     , mManagesContexts(false)  
  5.     , mBinderContextCheckFunc(NULL)  
  6.     , mBinderContextUserData(NULL)  
  7.     , mThreadPoolStarted(false)  
  8.     , mThreadPoolSeq(1)  
  9. {  
  10.     if (mDriverFD >= 0) {  
  11.         // XXX Ideally, there should be a specific define for whether we  
  12.         // have mmap (or whether we could possibly have the kernel module  
  13.         // availabla).  
  14. #if !defined(HAVE_WIN32_IPC)  
  15.         // mmap the binder, providing a chunk of virtual address space to receive transactions.  
  16.         mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);  
  17.         if (mVMStart == MAP_FAILED) {  
  18.             // *sigh*  
  19.             LOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");  
  20.             close(mDriverFD);  
  21.             mDriverFD = -1;  
  22.         }  
  23. #else  
  24.         mDriverFD = -1;  
  25. #endif  
  26.     }  
  27.     if (mDriverFD < 0) {  
  28.         // Need to run without the driver, starting our own thread pool.  
  29.     }  
  30. }  

3. 神奇的 defaultServiceManager

defaultServiceManager在IServiceManager.cpp中实现,其功能是获得一个IServiceManager对象。通过这个对象,就可以与进程/system/bin/servicemanager进行通信。

(defaultServiceManager实际返回的是BpServiceManager,它的remote对象是BpBinder,传入的那个handle参数是0。)

[html] view plaincopyprint?
  1. sp<IServiceManager> defaultServiceManager()  
  2. {  
  3.     if (gDefaultServiceManager != NULL) return gDefaultServiceManager;  
  4.       
  5.     {  
  6.         AutoMutex _l(gDefaultServiceManagerLock);  
  7.         if (gDefaultServiceManager == NULL) {  
  8.             gDefaultServiceManager = <span style="color: rgb(255, 0, 0);">interface_cast</span><IServiceManager>(  
  9.                 ProcessState::self()->getContextObject(NULL));  
  10.         }  
  11.     }  
  12.       
  13.     return gDefaultServiceManager;  
  14. }  

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 plaincopyprint?
  1. template<typename INTERFACE>  
  2. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
  3. {  
  4.     return INTERFACE::asInterface(obj);  
  5. }  
[html] view plaincopyprint?
  1. 即:  
  2. inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)  
  3. {  
  4.     <span style="color: rgb(51, 51, 255);">return IServiceManager::asInterface(obj);  
  5. </span>}  


3.2 ServiceManager所提供的服务

[html] view plaincopyprint?
  1. //IServiceManager.h  
  2. class IServiceManager : public IInterface  
  3. {  
  4. public:  
  5.     <span style="color: rgb(51, 51, 255);">DECLARE_META_INTERFACE(ServiceManager);  
  6. </span>  
  7.     /**  
  8.      * Retrieve an existing service, blocking for a few seconds  
  9.      * if it doesn't yet exist.  
  10.      */  
  11.     virtual sp<IBinder>         getService( const String16& name) const = 0;  
  12.   
  13.     /**  
  14.      * Retrieve an existing service, non-blocking.  
  15.      */  
  16.     virtual sp<IBinder>         checkService( const String16& name) const = 0;  
  17.   
  18.     /**  
  19.      * Register a service.  
  20.      */  
  21.     virtual status_t            addService( const String16& name,  
  22.                                             const sp<IBinder>& service) = 0;  
  23.   
  24.     /**  
  25.      * Return list of all existing services.  
  26.      */  
  27.     virtual Vector<String16>    listServices() = 0;  
  28.   
  29.     enum {  
  30.         GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,  
  31.         CHECK_SERVICE_TRANSACTION,  
  32.         ADD_SERVICE_TRANSACTION,  
  33.         LIST_SERVICES_TRANSACTION,  
  34.     };  
  35. }  

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

[html] view plaincopyprint?
  1. //IInterface.h  
  2. #define DECLARE_META_INTERFACE(INTERFACE)                               \  
  3.     static const String16 descriptor;                                   \  
  4.     static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \  
  5.     virtual const String16& getInterfaceDescriptor() const;             \  
  6.     I##INTERFACE();                                                     \  
  7.     virtual ~I##INTERFACE();                                            \  

替换后得到:

[html] view plaincopyprint?
  1. static const String16 descriptor;                                    
  2. static sp<IServiceManager> <span style="color: rgb(51, 51, 255);">asInterface</span>(const sp<IBinder>& obj);     
  3. virtual const String16& getInterfaceDescriptor() const;               
  4. IServiceManager();                                                    
  5. virtual ~IServiceManager();     


asInterface是如何实现的?

[html] view plaincopyprint?
  1. // IServiceManager.cpp  
  2. IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");  
  3.   
  4. //IInterface.h  
  5. #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \  
  6.     const String16 I##INTERFACE::descriptor(NAME);                      \  
  7.     const String16& I##INTERFACE::getInterfaceDescriptor() const {      \  
  8.         return I##INTERFACE::descriptor;                                \  
  9.     }                                                                   \  
  10.     sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \  
  11.     {                                                                   \  
  12.         sp<I##INTERFACE> intr;                                          \  
  13.         if (obj != NULL) {                                              \  
  14.             intr = static_cast<I##INTERFACE*>(                          \  
  15.                 obj->queryLocalInterface(                               \  
  16.                         I##INTERFACE::descriptor).get());               \  
  17.             if (intr == NULL) {                                         \  
  18.                 intr = new Bp##INTERFACE(obj);                          \  
  19.             }                                                           \  
  20.         }                                                               \  
  21.         return intr;                                                    \  
  22.     }                                                                   \  
  23.     I##INTERFACE::I##INTERFACE() { }                                    \  
  24.     I##INTERFACE::~I##INTERFACE() { }                                   \  


替换后为:

[html] view plaincopyprint?
  1. const String16 IServiceManager::descriptor("android.os.IServiceManager");                        
  2. const String16& IServiceManagerE::getInterfaceDescriptor() const {        
  3.     return IServiceManager::descriptor;                                  
  4. }                                                                     
  5. sp<IServiceManager> IServiceManager::<span style="color: rgb(255, 0, 0);">asInterface</span>(const sp<IBinder>& obj)    
  6. {                                                                     
  7.     sp<IServiceManager> intr;                                            
  8.     if (obj != NULL) {                                                
  9.         intr = static_cast<IServiceManager*>(                            
  10.             obj->queryLocalInterface(                                 
  11.                     IServiceManager::descriptor).get());                 
  12.         if (intr == NULL) {                                           
  13.             <span style="color: rgb(51, 51, 255);">intr = new BpServiceManager(obj);</span>                            
  14.         }                                                             
  15.     }                                                                 
  16.     return intr;                                                      
  17. }                                                                     
  18. IServiceManager::IServiceManager() { }                                      
  19. 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 plaincopyprint?
  1. BpServiceManager(const sp<IBinder>& impl)  
  2.    : BpInterface<IServiceManager>(impl)  
  3. {  
  4. }  
  5. template<typename INTERFACE>  
  6. inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)  
  7.     : BpRefBase(remote)  
  8. {  
  9. }  
  10. BpRefBase::BpRefBase(const sp<IBinder>& o)  
  11.     : <span style="color: rgb(255, 0, 0);">mRemote(o.get()), </span>mRefs(NULL), mState(0)  
  12. {  
  13.     extendObjectLifetime(OBJECT_LIFETIME_WEAK);  
  14.   
  15.     if (mRemote) {  
  16.         mRemote->incStrong(this);           // Removed on first IncStrong().  
  17.         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.  
  18.     }  
  19. }  

 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 plaincopyprint?
  1. status_t BpBinder::transact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     // Once a binder has died, it will never come back to life.  
  5.     if (mAlive) {  
  6.         status_t status = IPCThreadState::self()->transact(  
  7.             mHandle, code, data, reply, flags);  
  8.         if (status == DEAD_OBJECT) mAlive = 0;  
  9.         return status;  
  10.     }  
  11.   
  12.     return DEAD_OBJECT;  
  13. }  


 4. 注册一个Service

以MediaPlayerService为例分析注册过程。 

[html] view plaincopyprint?
  1. void MediaPlayerService::instantiate() {  
  2.     defaultServiceManager()->addService(  
  3.             String16("media.player"), new MediaPlayerService());  
  4. }  
  5. MediaPlayerService::MediaPlayerService()  
  6. {  
  7.     LOGV("MediaPlayerService created");  
  8.     mNextConnId = 1;  
  9.     mRatio = -1;  
  10.     mCrvs = -1;  
  11.     mLeft = -1;  
  12.     mTop =-1;  
  13.     mWidth =-1;  
  14.     mHeight =-1;  
  15. }  
  16. virtual status_t addService(const String16& name, const sp<IBinder>& service)  
  17. {  
  18.     Parcel data, reply;  
  19.     data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());  
  20.     data.writeString16(name);  
  21.     data.writeStrongBinder(service);  
  22.     status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);  
  23.     return err == NO_ERROR ? reply.readInt32() : err;  
  24. }  

remote()返回的就是BpServiceManager中保存的BpBinder。

MediaPlayerService 从BnMediaPlayerService派生,其家族关系如下:

[html] view plaincopyprint?
  1. class MediaPlayerService : public BnMediaPlayerService //业务逻辑和通信  
  2. class BnMediaPlayerService: public BnInterface<IMediaPlayerService>  
  3. class BnInterface : public IMediaPlayerService, public BBinder  
  4. //IMediaPlayerService:负责业务逻辑  
  5. //BBinder:负责通信  
[html] view plaincopyprint?
  1. class MediaPlayerService : public BnMediaPlayerService  
  2. {  
  3.     class Client;  
  4.     class MediaConfigClient;  
  5.   
  6.     class AudioOutput : public MediaPlayerBase::AudioSink  
  7.     {  
  8.      ...  
  9.     };  
  10.   
  11.     class AudioCache : public MediaPlayerBase::AudioSink  
  12.     {  
  13.      ...  
  14.     };  
  15.   
  16. public:  
  17.     static  void                instantiate();  
  18.   
  19.     // IMediaPlayerService interface  
  20.     virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid);  
  21.     void    removeMediaRecorderClient(wp<MediaRecorderClient> client);  
  22.     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid);  
  23.   
  24.     // House keeping for media player clients  
  25.     virtual sp<IMediaPlayer>    create(  
  26.             pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,  
  27.             const KeyedVector<String8, String8> *headers);  
  28.   
  29.     virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);  
  30.     virtual sp<IMediaConfig>   createMediaConfig(pid_t pid);  
  31.     virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);  
  32.     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);  
  33.     virtual sp<IMemory>         snoop();  
  34.     virtual sp<IOMX>            getOMX();  
  35. private:  
  36.   
  37.     class Client : public BnMediaPlayer {  
  38.         virtual status_t        prepareAsync();  
  39.         virtual status_t        start();  
  40.         virtual status_t        stop();  
  41.         virtual status_t        pause();  
  42.         virtual status_t        isPlaying(bool* state);  
  43.         virtual status_t        seekTo(int msec);  
  44.         virtual status_t        getCurrentPosition(int* msec);  
  45.         virtual status_t        getDuration(int* msec);  
  46.         virtual status_t        reset();  
  47.         virtual status_t        setAudioStreamType(int type);  
  48.         virtual status_t        setLooping(int loop);  
  49.         virtual status_t        setVolume(float leftVolume, float rightVolume);  
  50.         virtual status_t        invoke(const Parcel& request, Parcel *reply);  
  51.         virtual status_t        setMetadataFilter(const Parcel& filter);  
  52.         virtual status_t        getMetadata(bool update_only,  
  53.                                             bool apply_filter,  
  54.                                             Parcel *reply);  
  55.   
  56.         sp<MediaPlayerBase>     createPlayer(player_type playerType);  
  57.   
  58.                 status_t        setDataSource(  
  59.                                 const char *url,  
  60.                                 const KeyedVector<String8, String8> *headers);  
  61.   
  62.                 status_t        setDataSource(int fd, int64_t offset, int64_t length);  
  63.         static  void            notify(void* cookie, int msg, int ext1, int ext2);  
  64.   
  65.     private:  
  66.         friend class MediaPlayerService;  
  67.         sp<MediaPlayerBase>     getPlayer() const { Mutex::Autolock lock(mLock); return mPlayer; }  
  68.     };  
  69.   
  70.   
  71.     class MediaConfigClient: public BnMediaConfig  
  72.     {  
  73.        ...  
  74.     };  
  75.   
  76. // ----------------------------------------------------------------------------  
  77.   
  78.                             MediaPlayerService();  
  79.     virtual                 ~MediaPlayerService();  
  80.   
  81.     mutable     Mutex                       mLock;  
  82.                 SortedVector< wp<Client> >  mClients;  
  83.                 SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;  
  84.                 int32_t                     mNextConnId;  
  85.                 sp<IOMX>                    mOMX;  
  86.     int32_t mRatio;  
  87.     int32_t mCrvs;  
  88.     int32_t mLeft;  
  89.     int32_t mTop;  
  90.     int32_t mWidth;  
  91.     int32_t mHeight;  
  92. }  

 

4.1 addService

[html] view plaincopyprint?
  1. void MediaPlayerService::instantiate() {  
  2.     defaultServiceManager()->addService(  
  3.             String16("media.player"), new MediaPlayerService());  
  4. }  

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

addService是调用的BpServiceManager的函数。

[html] view plaincopyprint?
  1. virtual status_t addService(const String16& name, const sp<IBinder>& service)  
  2.   
  3.     {  
  4.   
  5.         Parcel data, reply;  
  6.   
  7.         //data是发送到BnServiceManager的命令包  
  8.   
  9.         //看见没?先把Interface名字写进去,也就是什么android.os.IServiceManager  
  10.   
  11.         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());  
  12.   
  13.         //再把新service的名字写进去 叫media.player  
  14.   
  15.         data.writeString16(name);  
  16.   
  17.         //把新服务service—>就是MediaPlayerService写到命令中  
  18.   
  19.         data.writeStrongBinder(service); <span style="color: rgb(255, 0, 0);">//把MediaPlayerService写入flat_binder_object中  
  20.   
  21. </span>        //调用remote的transact函数  
  22.   
  23.         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);  
  24.   
  25.         return err == NO_ERROR ? reply.readInt32() : err;  
  26.   
  27. }  

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

[html] view plaincopyprint?
  1. status_t BpBinder::transact(  
  2.   
  3.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  4.   
  5. {  
  6.         //注意啊,这里的mHandle为0,code是ADD_SERVICE_TRANSACTION,data是命令包  
  7.          //reply是回复包,flags=0  
  8.         status_t status = IPCThreadState::self()->transact(  
  9.             mHandle, code, data, reply, flags);  
  10.         if (status == DEAD_OBJECT) mAlive = 0;  
  11.            return status;  
  12.     }  
  13. ...  
  14. }  
[html] view plaincopyprint?
  1. status_t IPCThreadState::transact(int32_t handle,  
  2.                                   uint32_t code, const Parcel& data,  
  3.                                   Parcel* reply, uint32_t flags)  
  4. {  
  5.     status_t err = data.errorCheck();  
  6.   
  7.     flags |= TF_ACCEPT_FDS;  
  8.   
  9.     IF_LOG_TRANSACTIONS() {  
  10.         TextOutput::Bundle _b(alog);  
  11.         alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "  
  12.             << handle << " / code " << TypeCode(code) << ": "  
  13.             << indent << data << dedent << endl;  
  14.     }  
  15.       
  16.     if (err == NO_ERROR) {  
  17.         LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),  
  18.             (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");  
  19.         err = <span style="color: rgb(255, 0, 0);">writeTransactionData</span>(BC_TRANSACTION, flags, handle, code, data, NULL);//把要发送的数据写入binder_transaction_data中  
  20.     }  
  21.       
  22.     if (err != NO_ERROR) {  
  23.         if (reply) reply->setError(err);  
  24.         return (mLastError = err);  
  25.     }  
  26.       
  27.     if ((flags & TF_ONE_WAY) == 0) {  
  28.         if (reply) {  
  29.             err = waitForResponse(reply);  
  30.         } else {  
  31.             Parcel fakeReply;  
  32.             err = <span style="color: rgb(255, 0, 0);">waitForResponse</span>(&fakeReply);  
  33.         }  
  34.           
  35.         IF_LOG_TRANSACTIONS() {  
  36.             TextOutput::Bundle _b(alog);  
  37.             alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "  
  38.                 << handle << ": ";  
  39.             if (reply) alog << indent << *reply << dedent << endl;  
  40.             else alog << "(none requested)" << endl;  
  41.         }  
  42.     } else {  
  43.         err = waitForResponse(NULL, NULL);  
  44.     }  
  45.       
  46.     return err;  
  47. }  

 

[html] view plaincopyprint?
  1. status_t IPCThreadState::<span style="color: rgb(255, 0, 0);">writeTransactionData</span>(int32_t cmd, uint32_t binderFlags,  
  2.     int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)  
  3. {  
  4.     binder_transaction_data tr;  
  5.   
  6.     tr.target.handle = handle;  
  7.     tr.code = code;  
  8.     tr.flags = binderFlags;  
  9.       
  10.     const status_t err = data.errorCheck();  
  11.     if (err == NO_ERROR) {  
  12.         tr.data_size = data.ipcDataSize();  
  13.         tr.data.ptr.buffer = data.ipcData();  
  14.         tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);  
  15.         tr.data.ptr.offsets = data.ipcObjects();  
  16.     } else if (statusBuffer) {  
  17.         tr.flags |= TF_STATUS_CODE;  
  18.         *statusBuffer = err;  
  19.         tr.data_size = sizeof(status_t);  
  20.         tr.data.ptr.buffer = statusBuffer;  
  21.         tr.offsets_size = 0;  
  22.         tr.data.ptr.offsets = NULL;  
  23.     } else {  
  24.         return (mLastError = err);  
  25.     }  
  26.       
  27.     mOut.writeInt32(cmd);  
  28.     mOut.write(&tr, sizeof(tr));  
  29.       
  30.     return NO_ERROR;  
  31. }  

上面的代码把数据封装成binder_transaction_data,然后写到mOut中。mOut是一个命令buffer,也是一个Parcel.

[html] view plaincopyprint?
  1. status_t IPCThreadState::<span style="color: rgb(255, 0, 0);">waitForResponse</span>(Parcel *reply, status_t *acquireResult)  
  2. {  
  3.     int32_t cmd;  
  4.     int32_t err;  
  5.   
  6.     while (1) {  
  7.         if ((err=<span style="color: rgb(255, 0, 0);">talkWithDriver</span>()) < NO_ERROR) break; //发送数据到ServiceManager  
  8.         err = mIn.errorCheck();  
  9.         if (err < NO_ERROR) break;  
  10.         if (mIn.dataAvail() == 0) continue;  
  11.           
  12.         cmd = mIn.readInt32();  
  13.           
  14.         IF_LOG_COMMANDS() {  
  15.             alog << "Processing waitForResponse Command: "  
  16.                 << getReturnString(cmd) << endl;  
  17.         }  
  18.   
  19.         switch (cmd) {  
  20.         case BR_TRANSACTION_COMPLETE:  
  21.             if (!reply && !acquireResult) goto finish;  
  22.             break;  
  23.           
  24.         case BR_DEAD_REPLY:  
  25.             err = DEAD_OBJECT;  
  26.             goto finish;  
  27.   
  28.         case BR_FAILED_REPLY:  
  29.             err = FAILED_TRANSACTION;  
  30.             goto finish;  
  31.           
  32.         case BR_ACQUIRE_RESULT:  
  33.             {  
  34.                 LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");  
  35.                 const int32_t result = mIn.readInt32();  
  36.                 if (!acquireResult) continue;  
  37.                 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;  
  38.             }  
  39.             goto finish;  
  40.           
  41.         case BR_REPLY:  
  42.             {  
  43.                 binder_transaction_data tr;  
  44.                 err = mIn.read(&tr, sizeof(tr));  
  45.                 LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");  
  46.                 if (err != NO_ERROR) goto finish;  
  47.   
  48.                 if (reply) {  
  49.                     if ((tr.flags & TF_STATUS_CODE) == 0) {  
  50.                         reply->ipcSetDataReference(  
  51.                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  52.                             tr.data_size,  
  53.                             reinterpret_cast<const size_t*>(tr.data.ptr.offsets),  
  54.                             tr.offsets_size/sizeof(size_t),  
  55.                             freeBuffer, this);  
  56.                     } else {  
  57.                         err = *static_cast<const status_t*>(tr.data.ptr.buffer);  
  58.                         freeBuffer(NULL,  
  59.                             reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  60.                             tr.data_size,  
  61.                             reinterpret_cast<const size_t*>(tr.data.ptr.offsets),  
  62.                             tr.offsets_size/sizeof(size_t), this);  
  63.                     }  
  64.                 } else {  
  65.                     freeBuffer(NULL,  
  66.                         reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  67.                         tr.data_size,  
  68.                         reinterpret_cast<const size_t*>(tr.data.ptr.offsets),  
  69.                         tr.offsets_size/sizeof(size_t), this);  
  70.                     continue;  
  71.                 }  
  72.             }  
  73.             goto finish;  
  74.   
  75.         default:  
  76.             err = executeCommand(cmd);  
  77.             if (err != NO_ERROR) goto finish;  
  78.             break;  
  79.         }  
  80.     }  
  81.   
  82. finish:  
  83.     if (err != NO_ERROR) {  
  84.         if (acquireResult) *acquireResult = err;  
  85.         if (reply) reply->setError(err);  
  86.         mLastError = err;  
  87.     }  
  88.       
  89.     return err;  
  90. }  

 

[html] view plaincopyprint?
  1. status_t IPCThreadState::talkWithDriver(bool doReceive)  
  2. {  
  3.     LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");  
  4.       
  5.     <span style="color: rgb(255, 0, 0);">binder_write_read bwr;  
  6. </span>      
  7.     // Is the read buffer empty?  
  8.     const bool needRead = mIn.dataPosition() >= mIn.dataSize();  
  9.       
  10.     // We don't want to write anything if we are still reading  
  11.     // from data left in the input buffer and the caller  
  12.     // has requested to read the next data.  
  13.     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;  
  14.       
  15. <span style="color: rgb(51, 51, 255);">    bwr.write_size = outAvail;  
  16.     bwr.write_buffer = (long unsigned int)mOut.data();</span>  
  17.   
  18.     // This is what we'll read.  
  19.     if (doReceive && needRead) {  
  20.  <span style="color: rgb(51, 51, 255);">       bwr.read_size = mIn.dataCapacity();  
  21.         bwr.read_buffer = (long unsigned int)mIn.data();  
  22. </span>    } else {  
  23.         bwr.read_size = 0;  
  24.     }  
  25.       
  26.     IF_LOG_COMMANDS() {  
  27.         TextOutput::Bundle _b(alog);  
  28.         if (outAvail != 0) {  
  29.             alog << "Sending commands to driver: " << indent;  
  30.             const void* cmds = (const void*)bwr.write_buffer;  
  31.             const void* end = ((const uint8_t*)cmds)+bwr.write_size;  
  32.             alog << HexDump(cmds, bwr.write_size) << endl;  
  33.             while (cmds < endcmds = printCommand(alog, cmds);  
  34.             alog << dedent;  
  35.         }  
  36.         alog << "Size of receive buffer: " << bwr.read_size  
  37.             << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;  
  38.     }  
  39.       
  40.     // Return immediately if there is nothing to do.  
  41.     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;  
  42.       
  43.     bwr.write_consumed = 0;  
  44.     bwr.read_consumed = 0;  
  45.     status_t err;  
  46.     do { //<span style="color: red;">中间东西太复杂了,就是把<span lang="EN-US">mOut发送</span>数据和<span lang="EN-US">mIn</span>接收数据的处理后赋值给<span lang="EN-US">bwr</span></span>  
  47.         IF_LOG_COMMANDS() {  
  48.             alog << "About to read/write, write size = " << mOut.dataSize() << endl;  
  49.         }  
  50. #if defined(HAVE_ANDROID_OS)  
  51.        <span style="color: rgb(255, 0, 0);"> <span style="font-size: 13px;"><strong>if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)</strong>  
  52. </span></span>            err = NO_ERROR;  
  53.         else  
  54.             err = -errno;  
  55. #else  
  56.         err = INVALID_OPERATION;  
  57. #endif  
  58.         IF_LOG_COMMANDS() {  
  59.             alog << "Finished read/write, write size = " << mOut.dataSize() << endl;  
  60.         }  
  61.     } while (err == -EINTR);  
  62.     <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>  
  63.     IF_LOG_COMMANDS() {  
  64.         alog << "Our err: " << (void*)err << ", write consumed: "  
  65.             << bwr.write_consumed << " (of " << mOut.dataSize()  
  66.             << "), read consumed: " << bwr.read_consumed << endl;  
  67.     }  
  68.   
  69.     if (err >= NO_ERROR) {  
  70.         if (bwr.write_consumed > 0) {  
  71.             if (bwr.write_consumed < (ssize_t)mOut.dataSize())  
  72.                 mOut.remove(0, bwr.write_consumed);  
  73.             else  
  74.                 mOut.setDataSize(0);  
  75.         }  
  76.         if (bwr.read_consumed > 0) {  
  77.             mIn.setDataSize(bwr.read_consumed);  
  78.             mIn.setDataPosition(0);  
  79.         }  
  80.         IF_LOG_COMMANDS() {  
  81.             TextOutput::Bundle _b(alog);  
  82.             alog << "Remaining data size: " << mOut.dataSize() << endl;  
  83.             alog << "Received commands from driver: " << indent;  
  84.             const void* cmds = mIn.data();  
  85.             const void* end = mIn.data() + mIn.dataSize();  
  86.             alog << HexDump(cmds, mIn.dataSize()) << endl;  
  87.             while (cmds < endcmds = printReturnCommand(alog, cmds);  
  88.             alog << dedent;  
  89.         }  
  90.         return NO_ERROR;  
  91.     }  
  92.       
  93.     return err;  
  94. }  

       至此发送addService到ServiceManager就已经结束了。BpServiceManager发送了一个addService命令到BnServiceManager,然后收到回复。

 

       问题:MediaPlayerService是一个BnMediaPlayerService,那么它是不是应该等着

BpMediaPlayerService来和他交互呢?但是我们没看见MediaPlayerService有打开binder设备的操作啊!

深入了解mediaserver-2

http://blog.csdn.net/myarrow/article/details/7050746

4.2 BnServiceManager<servicemanager进程>

      上面说了,defaultServiceManager返回的是一个BpServiceManager,通过它可以把命令请求发送到binder设备,而且handle的值为0。那么,系统的另外一端肯定有个接收命令的,那又是谁呢?

      很可惜啊,BnServiceManager不存在,但确实有一个程序完成了BnServiceManager的工作,那就是/system/bin/servicemanager进程.虽然service_manager没有从BnServiceManager中派生,但是它肯定完成了BnServiceManager的功能。

[html] view plaincopyprint?
  1. //service_manager.c  
  2. int main(int argc, char **argv)  
  3. {  
  4.     struct binder_state *bs;  
  5.     void *svcmgr = BINDER_SERVICE_MANAGER;  
  6.   
  7.     bs = binder_open(128*1024);  
  8.   
  9.     if (binder_become_context_manager(bs)) {  
  10.         LOGE("cannot become context manager (%s)\n", strerror(errno));  
  11.         return -1;  
  12.     }  
  13.   
  14.     svcmgr_handle = svcmgr;  
  15.    <span style="color: rgb(255, 0, 0);"> binder_loop(bs, svcmgr_handler);  
  16. </span>    return 0;  
  17. }  
[html] view plaincopyprint?
  1. void binder_loop(struct binder_state *bs, binder_handler func)  
  2. {  
  3.     int res;  
  4.     struct binder_write_read bwr;  
  5.     unsigned readbuf[32];  
  6.   
  7.     bwr.write_size = 0;  
  8.     bwr.write_consumed = 0;  
  9.     bwr.write_buffer = 0;  
  10.       
  11.     readbuf[0] = BC_ENTER_LOOPER;  
  12.     binder_write(bs, readbuf, sizeof(unsigned));  
  13.   
  14.     for (;;) {  
  15.         bwr.read_size = sizeof(readbuf);  
  16.         bwr.read_consumed = 0;  
  17.         bwr.read_buffer = (unsigned) readbuf;  
  18.   
  19.         <span style="color: rgb(255, 0, 0);">res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);  
  20. </span>  
  21.         if (res < 0) {  
  22.             LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));  
  23.             break;  
  24.         }  
  25.   
  26.         <span style="color: rgb(255, 0, 0);">res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);  
  27. </span>        if (res == 0) {  
  28.             LOGE("binder_loop: unexpected reply?!\n");  
  29.             break;  
  30.         }  
  31.         if (res < 0) {  
  32.             LOGE("binder_loop: io error %d %s\n", res, strerror(errno));  
  33.             break;  
  34.         }  
  35.     }  
  36. }  
[html] view plaincopyprint?
  1. int svcmgr_handler(struct binder_state *bs,  
  2.                    struct binder_txn *txn,  
  3.                    struct binder_io *msg,  
  4.                    struct binder_io *reply)  
  5. {  
  6.     struct svcinfo *si;  
  7.     uint16_t *s;  
  8.     unsigned len;  
  9.     void *ptr;  
  10.   
  11. //    LOGI("target=%p code=%d pid=%d uid=%d\n",  
  12. //         txn->target, txn->code, txn->sender_pid, txn->sender_euid);  
  13.   
  14.     if (txn->target != svcmgr_handle)  
  15.         return -1;  
  16.   
  17.     s = bio_get_string16(msg, &len);  
  18.   
  19.     if ((len != (sizeof(svcmgr_id) / 2)) ||  
  20.         memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {  
  21.         fprintf(stderr,"invalid id %s\n", str8(s));  
  22.         return -1;  
  23.     }  
  24.   
  25.     switch(txn->code) {  
  26.     case SVC_MGR_GET_SERVICE:  
  27.     case SVC_MGR_CHECK_SERVICE:  
  28.         s = bio_get_string16(msg, &len);  
  29.         ptr = do_find_service(bs, s, len);  
  30.         if (!ptr)  
  31.             break;  
  32.         bio_put_ref(reply, ptr);  
  33.         return 0;  
  34.   
  35.     case SVC_MGR_ADD_SERVICE:  
  36.         s = bio_get_string16(msg, &len);  
  37.         ptr = bio_get_ref(msg);  
  38.         if (do_add_service(bs, s, len, ptr, txn->sender_euid)) <span style="color: rgb(255, 0, 0);">//add a service to svclist  
  39. </span>            return -1;  
  40.         break;  
  41.   
  42.     case SVC_MGR_LIST_SERVICES: {  
  43.         unsigned n = bio_get_uint32(msg);  
  44.   
  45.         si = svclist;  
  46.         while ((n-- > 0) && si)  
  47.             si = si->next;  
  48.         if (si) {  
  49.             bio_put_string16(reply, si->name);  
  50.             return 0;  
  51.         }  
  52.         return -1;  
  53.     }  
  54.     default:  
  55.         LOGE("unknown code %d\n", txn->code);  
  56.         return -1;  
  57.     }  
  58.   
  59.     bio_put_uint32(reply, 0);  
  60.     return 0;  
  61. }  


5. MediaPlayerService等待请求
/system/bin/mediaserver在ProcessState::Self()中打开了binder,其looper又在哪儿呢?

[html] view plaincopyprint?
  1. //main_mediaserver.cpp  
  2. int main(int argc, char** argv)  
  3. {  
  4.     sp<ProcessState> proc(ProcessState::self());  
  5.     sp<IServiceManager> sm = defaultServiceManager();  
  6.     LOGI("ServiceManager: %p", sm.get());  
  7.     AudioFlinger::instantiate();  
  8.     MediaPlayerService::instantiate();  
  9.     CameraService::instantiate();  
  10.     AudioPolicyService::instantiate();  
  11.     ProcessState::self()->startThreadPool();  
  12.     IPCThreadState::self()->joinThreadPool();  
  13. }  

5.1 startThreadPool

[html] view plaincopyprint?
  1. void ProcessState::startThreadPool()  
  2. {  
  3.     AutoMutex _l(mLock);  
  4.     if (!mThreadPoolStarted) {  
  5.         mThreadPoolStarted = true;  
  6.         spawnPooledThread(true);  
  7.     }  
  8. }  
  9. void ProcessState::spawnPooledThread(bool isMain)  
  10. {  
  11.     if (mThreadPoolStarted) {  
  12.         int32_t s = android_atomic_add(1, &mThreadPoolSeq);  
  13.         char buf[32];  
  14.   
  15.         sprintf(buf, "Binder Thread #%d", s);  
  16.         LOGV("Spawning new pooled thread, name=%s\n", buf);  
  17.   
  18.         <span style="color: rgb(255, 0, 0);">//创建线程池,然后run起来,和java的Thread何其像也。  
  19. </span>        sp<Thread> t = new PoolThread(isMain);  
  20.         t->run(buf);  
  21.     }  
  22. }  
  23.   
  24. class PoolThread : public Thread  
  25. {  
  26. public:  
  27.     PoolThread(bool isMain)  
  28.         : mIsMain(isMain)  
  29.     {  
  30.     }  
  31.       
  32. protected:  
  33.     virtual bool threadLoop()  
  34.     {  
  35.         IPCThreadState::self()->joinThreadPool(mIsMain);  
  36.         return false;  
  37.     }  
  38.       
  39.     const bool mIsMain;  
  40. };  
  41.   
  42. <span style="font-size: 18px; color: rgb(255, 0, 0);">//还没有创建线程  
  43. </span>status_t Thread::run(const char* name, int32_t priority, size_t stack)  
  44. {  
  45.     Mutex::Autolock _l(mLock);  
  46.   
  47.     if (mRunning) {  
  48.         // thread already started  
  49.         return INVALID_OPERATION;  
  50.     }  
  51.   
  52.     // reset status and exitPending to their default value, so we can  
  53.     // try again after an error happened (either below, or in readyToRun())  
  54.     mStatus = NO_ERROR;  
  55.     mExitPending = false;  
  56.     mThread = thread_id_t(-1);  
  57.       
  58.     // hold a strong reference on ourself  
  59.     mHoldSelf = this;  
  60.   
  61.     mRunning = true;  
  62.   
  63.     bool res;  
  64.     if (mCanCallJava) {  
  65.         <span style="color: rgb(255, 0, 0);">//name为android:unnamed_thread  
  66. </span>        res = createThreadEtc<span style="color: rgb(255, 0, 0);">(_threadLoop</span>,  
  67.                 this, name, priority, stack, &mThread);  
  68.     } else {  
  69.         res = androidCreateRawThreadEtc(_<span style="color: rgb(255, 0, 0);">threadLoop</span>,  
  70.                 this, name, priority, stack, &mThread);  
  71.     }  
  72.       
  73.       
  74.     if (res == false) {  
  75.         mStatus = UNKNOWN_ERROR;   // something happened!  
  76.         mRunning = false;  
  77.         mThread = thread_id_t(-1);  
  78.         mHoldSelf.clear();  // "this" may have gone away after this.  
  79.   
  80.         return UNKNOWN_ERROR;  
  81.     }  
  82.       
  83.     // Do not refer to mStatus here: The thread is already running (may, in fact  
  84.     // already have exited with a valid mStatus result). The NO_ERROR indication  
  85.     // here merely indicates successfully starting the thread and does not  
  86.     // imply successful termination/execution.  
  87.     return NO_ERROR;  
  88. }  
  89.   
  90. int androidCreateRawThreadEtc(android_thread_func_t entryFunction,  
  91.                                void *userData,  
  92.                                const char* threadName,  
  93.                                int32_t threadPriority,  
  94.                                size_t threadStackSize,  
  95.                                android_thread_id_t *threadId)  
  96. {  
  97.     pthread_attr_t attr;   
  98.     pthread_attr_init(&attr);  
  99.     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  
  100.   
  101. #ifdef HAVE_ANDROID_OS  /* valgrind is rejecting RT-priority create reqs */  
  102.     if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {  
  103.         // We could avoid the trampoline if there was a way to get to the  
  104.         // android_thread_id_t (pid) from pthread_t  
  105.         thread_data_t* t = new thread_data_t;  
  106.         t->priority = threadPriority;  
  107.         t->threadName = threadName ? strdup(threadName) : NULL;  
  108.         t->entryFunction = entryFunction;  
  109.         t->userData = userData;  
  110.         entryFunction = (android_thread_func_t)&thread_data_t::trampoline;  
  111.         userData = t;              
  112.     }  
  113. #endif  
  114.   
  115.     if (threadStackSize) {  
  116.         pthread_attr_setstacksize(&attr, threadStackSize);  
  117.     }  
  118.       
  119.     errno = 0;  
  120.     pthread_t thread;  
  121.     <span style="color: rgb(255, 0, 0);">//终于看到了熟悉的线程创建,入口函数为:_threadLoop  
  122. </span>    int result = pthread_create(&thread, &attr,  
  123.                     (android_pthread_entry)entryFunction, userData);  
  124.     if (result != 0) {  
  125.         LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"  
  126.              "(android threadPriority=%d)",  
  127.             entryFunction, result, errno, threadPriority);  
  128.         return 0;  
  129.     }  
  130.   
  131.     if (threadId != NULL) {  
  132.         *threadId = (android_thread_id_t)thread; // XXX: this is not portable  
  133.     }  
  134.     return 1;  
  135. }  

 

新开的线程的入口函数为:_threadLoop
 

[html] view plaincopyprint?
  1. <span style="color: rgb(255, 0, 0);">int Thread::_threadLoop(void* user)  
  2. </span>{  
  3.     Thread* const self = static_cast<Thread*>(user);  
  4.     sp<Thread> strong(self->mHoldSelf);  
  5.     wp<Thread> weak(strong);  
  6.     self->mHoldSelf.clear();  
  7.   
  8. #if HAVE_ANDROID_OS  
  9.     // this is very useful for debugging with gdb  
  10.     self->mTid = gettid();  
  11. #endif  
  12.   
  13.     bool first = true;  
  14.   
  15.     do {  
  16.         bool result;  
  17.         if (first) {  
  18.             first = false;  
  19.             self->mStatus = self->readyToRun();  
  20.             result = (self->mStatus == NO_ERROR);  
  21.   
  22.             if (result && !self->mExitPending) {  
  23.                 // Binder threads (and maybe others) rely on threadLoop  
  24.                 // running at least once after a successful ::readyToRun()  
  25.                 // (unless, of course, the thread has already been asked to exit  
  26.                 // at that point).  
  27.                 // This is because threads are essentially used like this:  
  28.                 //   (new ThreadSubclass())->run();  
  29.                 // The caller therefore does not retain a strong reference to  
  30.                 // the thread and the thread would simply disappear after the  
  31.                 // successful ::readyToRun() call instead of entering the  
  32.                 // threadLoop at least once.  
  33.                 result = self->threadLoop();  <span style="color: rgb(255, 0, 0);">//调用自己的<span lang="EN-US">threadLoop</span>  
  34. </span>            }  
  35.         } else {  
  36.             result = self->threadLoop();  
  37.         }  
  38.   
  39.         if (result == false || self->mExitPending) {  
  40.             self->mExitPending = true;  
  41.             self->mLock.lock();  
  42.             self->mRunning = false;  
  43.             self->mThreadExitedCondition.broadcast();  
  44.             self->mLock.unlock();  
  45.             break;  
  46.         }  
  47.           
  48.         // Release our strong reference, to let a chance to the thread  
  49.         // to die a peaceful death.  
  50.         strong.clear();  
  51.         // And immediately, re-acquire a strong reference for the next loop  
  52.         strong = weak.promote();  
  53.     } while(strong != 0);  
  54.       
  55.     return 0;  
  56. }  

PoolThread::threadLoop

[html] view plaincopyprint?
  1. class PoolThread : public Thread  
  2. {  
  3. public:  
  4.     PoolThread(bool isMain)  
  5.         : mIsMain(isMain)  
  6.     {  
  7.     }  
  8.       
  9. protected:  
  10.     <span style="color: rgb(255, 0, 0);">virtual bool threadLoop()</span>  
  11.     {   ////mIsMain为true。 而且注意,这是一个新的线程,所以必然会创建一个新的IPCThreadState对象(记得线程本地存储吗?TLS)  
  12.         <span style="color: rgb(255, 0, 0);">IPCThreadState::self()->joinThreadPool(mIsMain);  
  13. </span>        return false;  
  14.     }  
  15.       
  16.     const bool mIsMain;  
  17. };  

主线程和工作线程都调用了joinThreadPool

[html] view plaincopyprint?
  1. void IPCThreadState::joinThreadPool(bool isMain)  
  2. {  
  3.     LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());  
  4.   
  5.     <span style="color: rgb(255, 0, 0);">mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);  
  6. </span>      
  7.     // This thread may have been spawned by a thread that was in the background  
  8.     // scheduling group, so first we will make sure it is in the default/foreground  
  9.     // one to avoid performing an initial transaction in the background.  
  10.     androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);  
  11.           
  12.     status_t result;  
  13.     do {  
  14.         int32_t cmd;  
  15.           
  16.         // When we've cleared the incoming command queue, process any pending derefs  
  17.         if (mIn.dataPosition() >= mIn.dataSize()) {  
  18.             size_t numPending = mPendingWeakDerefs.size();  
  19.             if (numPending > 0) {  
  20.                 for (size_t i = 0; i < numPending; i++) {  
  21.                     RefBase::weakref_type* refs = mPendingWeakDerefs[i];  
  22.                     refs->decWeak(mProcess.get());  
  23.                 }  
  24.                 mPendingWeakDerefs.clear();  
  25.             }  
  26.   
  27.             numPending = mPendingStrongDerefs.size();  
  28.             if (numPending > 0) {  
  29.                 for (size_t i = 0; i < numPending; i++) {  
  30.                     BBinder* obj = mPendingStrongDerefs[i];  
  31.                     obj->decStrong(mProcess.get());  
  32.                 }  
  33.                 mPendingStrongDerefs.clear();  
  34.             }  
  35.         }  
  36.   
  37.         // now get the next command to be processed, waiting if necessary  
  38.         <span style="color: rgb(255, 0, 0);">result = talkWithDriver();  
  39. </span>        if (result >= NO_ERROR) {  
  40.             size_t IN = mIn.dataAvail();  
  41.             if (IN < sizeof(int32_t)) continue;  
  42.             cmd = mIn.readInt32();  
  43.             IF_LOG_COMMANDS() {  
  44.                 alog << "Processing top-level Command: "  
  45.                     << getReturnString(cmd) << endl;  
  46.             }  
  47.   
  48.   
  49.             <span style="color: rgb(255, 0, 0);">result = executeCommand(cmd);  
  50. </span>        }  
  51.           
  52.         // After executing the command, ensure that the thread is returned to the  
  53.         // default cgroup before rejoining the pool.  The driver takes care of  
  54.         // restoring the priority, but doesn't do anything with cgroups so we  
  55.         // need to take care of that here in userspace.  Note that we do make  
  56.         // sure to go in the foreground after executing a transaction, but  
  57.         // there are other callbacks into user code that could have changed  
  58.         // our group so we want to make absolutely sure it is put back.  
  59.         androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);  
  60.   
  61.         // Let this thread exit the thread pool if it is no longer  
  62.         // needed and it is not the main process thread.  
  63.         if(result == TIMED_OUT && !isMain) {  
  64.             break;  
  65.         }  
  66.     } while (result != -ECONNREFUSED && result != -EBADF);  
  67.   
  68.     LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",  
  69.         (void*)pthread_self(), getpid(), (void*)result);  
  70.       
  71.     mOut.writeInt32(BC_EXIT_LOOPER);  
  72.     talkWithDriver(false);  
  73. }  

有loop了,但是有两个线程都执行了这个啊!这里有两个消息循环?
看看executeCommand

[html] view plaincopyprint?
  1. status_t IPCThreadState::executeCommand(int32_t cmd)  
  2. {  
  3.     BBinder* obj;  
  4.     RefBase::weakref_type* refs;  
  5.     status_t result = NO_ERROR;  
  6.       
  7.     switch (cmd) {  
  8.     case BR_ERROR:  
  9.         result = mIn.readInt32();  
  10.         break;  
  11.           
  12.     case BR_OK:  
  13.         break;  
  14.           
  15.     case BR_ACQUIRE:  
  16.         refs = (RefBase::weakref_type*)mIn.readInt32();  
  17.         obj = (BBinder*)mIn.readInt32();  
  18.         LOG_ASSERT(refs->refBase() == obj,  
  19.                    "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",  
  20.                    refs, obj, refs->refBase());  
  21.         obj->incStrong(mProcess.get());  
  22.         IF_LOG_REMOTEREFS() {  
  23.             LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);  
  24.             obj->printRefs();  
  25.         }  
  26.         mOut.writeInt32(BC_ACQUIRE_DONE);  
  27.         mOut.writeInt32((int32_t)refs);  
  28.         mOut.writeInt32((int32_t)obj);  
  29.         break;  
  30.           
  31.     case BR_RELEASE:  
  32.         refs = (RefBase::weakref_type*)mIn.readInt32();  
  33.         obj = (BBinder*)mIn.readInt32();  
  34.         LOG_ASSERT(refs->refBase() == obj,  
  35.                    "BR_RELEASE: object %p does not match cookie %p (expected %p)",  
  36.                    refs, obj, refs->refBase());  
  37.         IF_LOG_REMOTEREFS() {  
  38.             LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);  
  39.             obj->printRefs();  
  40.         }  
  41.         mPendingStrongDerefs.push(obj);  
  42.         break;  
  43.           
  44.     case BR_INCREFS:  
  45.         refs = (RefBase::weakref_type*)mIn.readInt32();  
  46.         obj = (BBinder*)mIn.readInt32();  
  47.         refs->incWeak(mProcess.get());  
  48.         mOut.writeInt32(BC_INCREFS_DONE);  
  49.         mOut.writeInt32((int32_t)refs);  
  50.         mOut.writeInt32((int32_t)obj);  
  51.         break;  
  52.           
  53.     case BR_DECREFS:  
  54.         refs = (RefBase::weakref_type*)mIn.readInt32();  
  55.         obj = (BBinder*)mIn.readInt32();  
  56.         // NOTE: This assertion is not valid, because the object may no  
  57.         // longer exist (thus the (BBinder*)cast above resulting in a different  
  58.         // memory address).  
  59.         //LOG_ASSERT(refs->refBase() == obj,  
  60.         //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",  
  61.         //           refs, obj, refs->refBase());  
  62.         mPendingWeakDerefs.push(refs);  
  63.         break;  
  64.           
  65.     case BR_ATTEMPT_ACQUIRE:  
  66.         refs = (RefBase::weakref_type*)mIn.readInt32();  
  67.         obj = (BBinder*)mIn.readInt32();  
  68.            
  69.         {  
  70.             const bool success = refs->attemptIncStrong(mProcess.get());  
  71.             LOG_ASSERT(success && refs->refBase() == obj,  
  72.                        "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",  
  73.                        refs, obj, refs->refBase());  
  74.               
  75.             mOut.writeInt32(BC_ACQUIRE_RESULT);  
  76.             mOut.writeInt32((int32_t)success);  
  77.         }  
  78.         break;  
  79.       
  80.     <span style="color: rgb(255, 0, 0);">case BR_TRANSACTION:  
  81. </span>        {  
  82.             binder_transaction_data tr;  
  83.             result = mIn.read(&tr, sizeof(tr));  
  84.             LOG_ASSERT(result == NO_ERROR,  
  85.                 "Not enough command data for brTRANSACTION");  
  86.             if (result != NO_ERROR) break;  
  87.               
  88.             Parcel buffer;  
  89.             buffer.ipcSetDataReference(  
  90.                 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),  
  91.                 tr.data_size,  
  92.                 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),  
  93.                 tr.offsets_size/sizeof(size_t), freeBuffer, this);  
  94.               
  95.             const pid_t origPid = mCallingPid;  
  96.             const uid_t origUid = mCallingUid;  
  97.               
  98.             mCallingPid = tr.sender_pid;  
  99.             mCallingUid = tr.sender_euid;  
  100.               
  101.             int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);  
  102.             if (gDisableBackgroundScheduling) {  
  103.                 if (curPrio > ANDROID_PRIORITY_NORMAL) {  
  104.                     // We have inherited a reduced priority from the caller, but do not  
  105.                     // want to run in that state in this process.  The driver set our  
  106.                     // priority already (though not our scheduling class), so bounce  
  107.                     // it back to the default before invoking the transaction.  
  108.                     setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);  
  109.                 }  
  110.             } else {  
  111.                 if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {  
  112.                     // We want to use the inherited priority from the caller.  
  113.                     // Ensure this thread is in the background scheduling class,  
  114.                     // since the driver won't modify scheduling classes for us.  
  115.                     // The scheduling group is reset to default by the caller  
  116.                     // once this method returns after the transaction is complete.  
  117.                     androidSetThreadSchedulingGroup(mMyThreadId,  
  118.                                                     ANDROID_TGROUP_BG_NONINTERACT);  
  119.                 }  
  120.             }  
  121.   
  122.             //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);  
  123.               
  124.             Parcel reply;  
  125.             IF_LOG_TRANSACTIONS() {  
  126.                 TextOutput::Bundle _b(alog);  
  127.                 alog << "BR_TRANSACTION thr " << (void*)pthread_self()  
  128.                     << " / obj " << tr.target.ptr << " / code "  
  129.                     << TypeCode(tr.code) << ": " << indent << buffer  
  130.                     << dedent << endl  
  131.                     << "Data addr = "  
  132.                     << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)  
  133.                     << ", offsets addr="  
  134.                     << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;  
  135.             }  
  136.        <span style="color: rgb(255, 0, 0);">     if (tr.target.ptr) {  
  137.                 sp<BBinder> b((BBinder*)tr.cookie); <span style="color: rgb(51, 51, 255);">//这里用的是<span lang="EN-US">BBinder</span>。  
  138. </span>                const status_t error = b->transact(tr.code, buffer, &reply, 0);  
  139.                 if (error < NO_ERROR) reply.setError(error);  
  140.                   
  141.             } else {  
  142.                 const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);  
  143.                 if (error < NO_ERROR) reply.setError(error);  
  144.             }  
  145. </span>              
  146.             //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",  
  147.             //     mCallingPid, origPid, origUid);  
  148.               
  149.             if ((tr.flags & TF_ONE_WAY) == 0) {  
  150.                 LOG_ONEWAY("Sending reply to %d!", mCallingPid);  
  151.                 sendReply(reply, 0);  
  152.             } else {  
  153.                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);  
  154.             }  
  155.               
  156.             mCallingPid = origPid;  
  157.             mCallingUid = origUid;  
  158.   
  159.             IF_LOG_TRANSACTIONS() {  
  160.                 TextOutput::Bundle _b(alog);  
  161.                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "  
  162.                     << tr.target.ptr << ": " << indent << reply << dedent << endl;  
  163.             }  
  164.               
  165.         }  
  166.         break;  
  167.       
  168.     case BR_DEAD_BINDER:  
  169.         {  
  170.             BpBinder *proxy = (BpBinder*)mIn.readInt32();  
  171.             proxy->sendObituary();  
  172.             mOut.writeInt32(BC_DEAD_BINDER_DONE);  
  173.             mOut.writeInt32((int32_t)proxy);  
  174.         } break;  
  175.           
  176.     case BR_CLEAR_DEATH_NOTIFICATION_DONE:  
  177.         {  
  178.             BpBinder *proxy = (BpBinder*)mIn.readInt32();  
  179.             proxy->getWeakRefs()->decWeak(proxy);  
  180.         } break;  
  181.           
  182.     case BR_FINISHED:  
  183.         result = TIMED_OUT;  
  184.         break;  
  185.           
  186.     case BR_NOOP:  
  187.         break;  
  188.           
  189.     case BR_SPAWN_LOOPER:  
  190.         mProcess->spawnPooledThread(false);  
  191.         break;  
  192.           
  193.     default:  
  194.         printf("*** BAD COMMAND %d received from Binder driver\n", cmd);  
  195.         result = UNKNOWN_ERROR;  
  196.         break;  
  197.     }  
  198.   
  199.     if (result != NO_ERROR) {  
  200.         mLastError = result;  
  201.     }  
  202.       
  203.     return result;  
  204. }  

BBinder的transact函数如下:

[html] view plaincopyprint?
  1. status_t BBinder::transact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     data.setDataPosition(0);  
  5.   
  6.     status_t err = NO_ERROR;  
  7.     switch (code) {  
  8.         case PING_TRANSACTION:  
  9.             reply->writeInt32(pingBinder());  
  10.             break;  
  11.         default:  
  12.             err = onTransact(code, data, reply, flags);  <span style="color: rgb(255, 0, 0);">//调用自己的onTransact,实际调用BnMediaPlayerService::onTransact  
  13. </span>            break;  
  14.     }  
  15.   
  16.     if (reply != NULL) {  
  17.         reply->setDataPosition(0);  
  18.     }  
  19.   
  20.     return err;  
  21. }  

BnMediaPlayerService从BBinder派生,所以会调用到它的onTransact函数,终于水落石出了,让我们看看BnMediaPlayerServcice的onTransact函数。

[html] view plaincopyprint?
  1. status_t BnMediaPlayerService::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4. <span style="color: rgb(255, 0, 0);">    // BnMediaPlayerService从BBinder和IMediaPlayerService派生  
  5.      // 所有IMediaPlayerService提供的函数都通过命令类型来区分  
  6. </span>  
  7.     switch(code) {  
  8.         case CREATE_URL: {  
  9.             CHECK_INTERFACE(IMediaPlayerService, data, reply);  
  10.             pid_t pid = data.readInt32();  
  11.             sp<IMediaPlayerClient> client =  
  12.                 interface_cast<IMediaPlayerClient>(data.readStrongBinder());  
  13.             const char* url = data.readCString();  
  14.   
  15.             KeyedVector<String8, String8> headers;  
  16.             int32_t numHeaders = data.readInt32();  
  17.             for (int i = 0; i < numHeaders; ++i) {  
  18.                 String8 key = data.readString8();  
  19.                 String8 value = data.readString8();  
  20.                 headers.add(key, value);  
  21.             }  
  22.           <span style="color: rgb(255, 0, 0);">//create是一个虚函数,由MediaPlayerService来实现,见MediaPlayerService::create  
  23. </span>          <span style="color: rgb(255, 0, 0);">//MediaPlayerService.cpp  
  24. </span>            sp<IMediaPlayer> player = create(  
  25.                     pid, client, url, numHeaders > 0 ? &headers : NULL);  
  26.   
  27.             reply->writeStrongBinder(player->asBinder());  
  28.             return NO_ERROR;  
  29.         } break;  
  30.         ...  
  31.    }  
  32. }  

其实,到这里,我们就明白了。BnXXX的onTransact函数收取命令,然后派发到派生类XXX的对应函数,由他们完成实际的工作。

说明:
    这里有点特殊,startThreadPool和joinThreadPool完后确实有两个线程,主线程和工作线程,而且都在做消息循环。为什么要这么做呢?他们参数isMain都是true。不知道google搞什么。难道是怕一个线程工作量太多,所以搞两个线程来工作?这种解释应该也是合理的。
    网上有人测试过把最后一句屏蔽掉,也能正常工作。但是难道主线程退出了,程序还能不退出吗?这个...管它的,反正知道有两个线程在那处理就行了。

深入了解mediaserver-3

http://blog.csdn.net/myarrow/article/details/7050974

6. MediaPlayer如何与MediaPlayerService交互

6.1    MeidaPlayerService根据MediaPlayer的请求,创建对应的MeidaPlayer

[html] view plaincopyprint?
  1. //MediaPlayerService.cpp  
  2. static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,  
  3.         notify_callback_f notifyFunc)  
  4. {  
  5.     sp<MediaPlayerBase> p;  
  6.     switch (playerType) {  
  7.         case XX_PLAYER:  
  8.             LOGV("Create XXPlayer");  
  9.             p = new XXPlayerService();  
  10.             break;  
  11. #ifndef NO_OPENCORE  
  12.         case PV_PLAYER:  
  13.             LOGV(" create PVPlayer");  
  14.             p = new PVPlayer();  
  15.             break;  
  16. #endif  
  17.         case SONIVOX_PLAYER:  
  18.             LOGV(" create MidiFile");  
  19.             p = new MidiFile();  
  20.             break;  
  21.         case VORBIS_PLAYER:  
  22.             LOGV(" create VorbisPlayer");  
  23.             p = new VorbisPlayer();  
  24.             break;  
  25. #if BUILD_WITH_FULL_STAGEFRIGHT  
  26.         case STAGEFRIGHT_PLAYER:  
  27.             LOGV(" create StagefrightPlayer");  
  28.             p = new StagefrightPlayer;  
  29.             break;  
  30. #endif  
  31.         case TEST_PLAYER:  
  32.             LOGV("Create Test Player stub");  
  33.             p = new TestPlayerStub();  
  34.             break;  
  35.     }  
  36.     if (p != NULL) {  
  37.         if (p->initCheck() == NO_ERROR) {  
  38.             p->setNotifyCallback(cookie, notifyFunc);  
  39.         } else {  
  40.             p.clear();  
  41.         }  
  42.     }  
  43.     if (p == NULL) {  
  44.         LOGE("Failed to create player object");  
  45.     }  
  46.     return p;  
  47. }  
[html] view plaincopyprint?
  1. class MediaPlayer : public BnMediaPlayerClient,  
  2.                     public virtual IMediaDeathNotifier  
  3.   
  4. =============================================================  
  5. class IMediaPlayerClient: public IInterface  
  6. {  
  7. public:  
  8.     DECLARE_META_INTERFACE(MediaPlayerClient);  
  9.   
  10.     virtual void notify(int msg, int ext1, int ext2) = 0;  
  11. };  
  12.   
  13. class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>  
  14. {  
  15. public:  
  16.     virtual status_t    onTransact( uint32_t code,  
  17.                                     const Parcel& data,  
  18.                                     Parcel* reply,  
  19.                                     uint32_t flags = 0);  
  20. };  
  21. =============================================================  
  22. class IMediaDeathNotifier: virtual public RefBase  
  23. {  
  24. public:  
  25.     IMediaDeathNotifier() { addObitRecipient(this); }  
  26.     virtual ~IMediaDeathNotifier() { removeObitRecipient(this); }  
  27.   
  28.     virtual void died() = 0;  
  29.     //establish binder interface to MediaPlayerService  
  30.     static const sp<IMediaPlayerService>& getMediaPlayerService();  
  31.   
  32. private:  
  33.     IMediaDeathNotifier &operator=(const IMediaDeathNotifier &);  
  34.     IMediaDeathNotifier(const IMediaDeathNotifier &);  
  35.   
  36.     static void addObitRecipient(const wp<IMediaDeathNotifier>& recipient);  
  37.     static void removeObitRecipient(const wp<IMediaDeathNotifier>& recipient);  
  38.   
  39.     class DeathNotifier: public IBinder::DeathRecipient  
  40.     {  
  41.     public:  
  42.                 DeathNotifier() {}  
  43.         virtual ~DeathNotifier();  
  44.   
  45.         virtual void binderDied(const wp<IBinder>& who);  
  46.     };  
  47.   
  48.     friend class DeathNotifier;  
  49.   
  50.     static  Mutex                                   sServiceLock;  
  51.     static  sp<IMediaPlayerService>                 sMediaPlayerService;  
  52.     static  sp<DeathNotifier>                       sDeathNotifier;  
  53.     static  SortedVector< wp<IMediaDeathNotifier> > sObitRecipients;  
  54. }  

6.2 通过ServiceManager获取BpMediaPlayerService

[cpp] view plaincopyprint?
  1. const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()  
  2. {  
  3.     LOGV("getMediaPlayerService");  
  4.     Mutex::Autolock _l(sServiceLock);  
  5.     if (sMediaPlayerService.get() == 0) {  
  6.         sp<IServiceManager> sm = defaultServiceManager();  
  7.         sp<IBinder> binder;  
  8.         do {  
  9.             binder = sm->getService(String16("media.player"));  
  10.             if (binder != 0) {  
  11.                 break;  
  12.              }  
  13.              LOGW("Media player service not published, waiting...");  
  14.              usleep(500000); // 0.5 s  
  15.         } while(true);  
  16.   
  17.         if (sDeathNotifier == NULL) {  
  18.         sDeathNotifier = new DeathNotifier();  
  19.     }  
  20.     binder->linkToDeath(sDeathNotifier);  
  21.   
  22.     // sMediaPlayerService中保存的为BpMediaPlayerService  
  23.   
  24.     sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);  
  25.     }  
  26.     LOGE_IF(sMediaPlayerService == 0, "no media player service!?");  
  27.     return sMediaPlayerService;  
  28. }  

6.3 获取mPlayer(IMediaPlayer,实质为BpMediaPlayer) 

[cpp] view plaincopyprint?
  1. status_t MediaPlayer::setDataSource(  
  2.         const char *url, const KeyedVector<String8, String8> *headers)  
  3. {  
  4.     LOGV("setDataSource(%s)", url);  
  5.     status_t err = BAD_VALUE;  
  6.     if (url != NULL) {  
  7.         //service实质上是BpMediaPlayerService  
  8.         const sp<IMediaPlayerService>& service(getMediaPlayerService());  
  9.   
  10.         if (service != 0) {  
  11.             // Player实质上是BpMediaPlayer  
  12.             sp<IMediaPlayer> player(service->create(getpid(), this, url, headers));  
  13.             //把BpMediaPlayer赋值给成员变量mPlayer,如果以前的mPlayer有效,则Disconnect以前的Player  
  14.             err = setDataSource(player);  
  15.         }  
  16.     }  
  17.     return err;  
  18. }  

BpMediaPlayerService::create (Client端)

[cpp] view plaincopyprint?
  1. class BpMediaPlayerService: public BpInterface<IMediaPlayerService>  
  2. {  
  3. public:  
  4.     BpMediaPlayerService(const sp<IBinder>& impl)  
  5.         : BpInterface<IMediaPlayerService>(impl)  
  6.     {  
  7.     }  
  8.   
  9.     virtual sp<IMediaPlayer> create(  
  10.             pid_t pid, const sp<IMediaPlayerClient>& client,  
  11.             const char* url, const KeyedVector<String8, String8> *headers) {  
  12.         Parcel data, reply;  
  13.         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());  
  14.         data.writeInt32(pid);  
  15.         data.writeStrongBinder(client->asBinder());  
  16.         data.writeCString(url);  
  17.   
  18.         if (headers == NULL) {  
  19.             data.writeInt32(0);  
  20.         } else {  
  21.             // serialize the headers  
  22.             data.writeInt32(headers->size());  
  23.             for (size_t i = 0; i < headers->size(); ++i) {  
  24.                 data.writeString8(headers->keyAt(i));  
  25.                 data.writeString8(headers->valueAt(i));  
  26.             }  
  27.         }  
  28.   
  29.         remote()->transact(CREATE_URL, data, &reply);  //传递到BnMediaPlayerSerivce执行  
  30.         return interface_cast<IMediaPlayer>(reply.readStrongBinder()); //返回BpMediaPlayer  
  31.     }  
  32. }  

在BnMediaPlayerService处理CREATE_URL(Server端)

[cpp] view plaincopyprint?
  1. status_t BnMediaPlayerService::onTransact(  
  2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
  3. {  
  4.     switch(code) {  
  5.         case CREATE_URL: { //收到上面的CREATE_URL并进行处理  
  6.             CHECK_INTERFACE(IMediaPlayerService, data, reply);  
  7.             pid_t pid = data.readInt32();  
  8.             sp<IMediaPlayerClient> client = //实质保存的为BpMediaPlayerClient,用于向MediaPlayer发通知消息,它为Client,MediaPlayer为Sever  
  9.                 interface_cast<IMediaPlayerClient>(data.readStrongBinder());  
  10.             const char* url = data.readCString();  
  11.   
  12.             KeyedVector<String8, String8> headers;  
  13.             int32_t numHeaders = data.readInt32();  
  14.             for (int i = 0; i < numHeaders; ++i) {  
  15.                 String8 key = data.readString8();  
  16.                 String8 value = data.readString8();  
  17.                 headers.add(key, value);  
  18.             }  
  19.             //在BnMediaPlayerService的派生类MediaPlayerService中实现,创建一个Client对象(Client:public BnMediaPlayer)  
  20.             sp<IMediaPlayer> player = create(  
  21.                     pid, client, url, numHeaders > 0 ? &headers : NULL);  
  22.   
  23.             reply->writeStrongBinder(player->asBinder());  
  24.             return NO_ERROR;  
  25.         } break;  
  26. }  

MediaPlayerService::create才是真正的实现创建IMediaPlayer

[cpp] view plaincopyprint?
  1. <p>sp<IMediaPlayer> MediaPlayerService::create(  
  2.         pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,  
  3.         const KeyedVector<String8, String8> *headers)  
  4. {  
  5.     int32_t connId = android_atomic_inc(&mNextConnId);</p><p>     //创建一个Clinet,class Client : public BnMediaPlayer,真正实现start, stop, pause, resume...  
  6.     sp<Client> c = new Client(this, pid, connId, client);  
  7.     LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);</p><p>    //分析url,并创建真正的player(demuxer,decoder)  
  8.     if (NO_ERROR != c->setDataSource(url, headers))  
  9.     {  
  10.         c.clear();  
  11.         return c;  
  12.     }  
  13.     wp<Client> w = c;  
  14.     Mutex::Autolock lock(mLock);  
  15.     mClients.add(w);  
  16.     return c;//返回此BnMediaPlayer派生类的对象  
  17. }</p>  

MediaPlayerService::Client::setDataSource分析URL类型,然后创建对应的Player

[cpp] view plaincopyprint?
  1. status_t MediaPlayerService::Client::setDataSource(  
  2.         const char *url, const KeyedVector<String8, String8> *headers)  
  3. {  
  4.     LOGV("setDataSource(%s)", url);  
  5.     if (url == NULL)  
  6.         return UNKNOWN_ERROR;  
  7.   
  8.     if (strncmp(url, "content://", 10) == 0) {  
  9.         // get a filedescriptor for the content Uri and  
  10.         // pass it to the setDataSource(fd) method  
  11.   
  12.         String16 url16(url);  
  13.         int fd = android::openContentProviderFile(url16);  
  14.         if (fd < 0)  
  15.         {  
  16.             LOGE("Couldn't open fd for %s", url);  
  17.             return UNKNOWN_ERROR;  
  18.         }  
  19.         setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus  
  20.         close(fd);  
  21.         return mStatus;  
  22.     } else {  
  23.         //根据url返回对应的player_type,如: PV_PLAYER,STAGEFRIGHT_PLAYER, XX_PLAYER  
  24.         player_type playerType = getPlayerType(url);  
  25.         LOGV("player type = %d", playerType);  
  26.   
  27.         // create the right type of player,建立真正的AVPlayer  
  28.         sp<MediaPlayerBase> p = createPlayer(playerType);  
  29.         if (p == NULL) return NO_INIT;  
  30.   
  31.         if (!p->hardwareOutput()) {  
  32.             mAudioOutput = new AudioOutput();  
  33.             static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);  
  34.         }  
  35.   
  36.         // now set data source,把URL传递给真正的AVPlayer  
  37.         LOGV(" setDataSource");  
  38.         mStatus = p->setDataSource(url, headers);  
  39.         p->setOutRange( mService->getLeft(), mService->getTop(), mService->getWidth(), mService->getHeight());   
  40.         if (mStatus == NO_ERROR) {  
  41.             mPlayer = p;  
  42.         } else {  
  43.             LOGE("  error: %d", mStatus);  
  44.         }  
  45.         return mStatus;  
  46.     }  
  47. }  

创建真正的AVPlayer

[cpp] view plaincopyprint?
  1. sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)  
  2. {  
  3.     // determine if we have the right player type  
  4.     sp<MediaPlayerBase> p = mPlayer;  
  5.     LOGV("Enter MediaPlayerService::Client::createPlayer: playerType is %d", playerType);  
  6.     if ((p != NULL) && (p->playerType() != playerType)) {  
  7.         LOGV("p->playerType() is: %d, , delete player", p->playerType());  
  8.         p.clear();  
  9.     }  
  10.     if (p == NULL) {  
  11.         LOGV("Create new player");  
  12.         p = android::createPlayer(playerType, this, notify);  
  13.     }  
  14.     return p;  
  15. }  
  16. static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,  
  17.         notify_callback_f notifyFunc)  
  18. {  
  19.     sp<MediaPlayerBase> p;  
  20.     switch (playerType) {  
  21.         case XX_PLAYER:  
  22.             LOGV("Create XXPlayer");  
  23.             p = new XXPlayerService();  
  24.             break;  
  25. #ifndef NO_OPENCORE  
  26.         case PV_PLAYER:  
  27.             LOGV(" create PVPlayer");  
  28.             p = new PVPlayer();  
  29.             break;  
  30. #endif  
  31.         case SONIVOX_PLAYER:  
  32.             LOGV(" create MidiFile");  
  33.             p = new MidiFile();  
  34.             break;  
  35.         case VORBIS_PLAYER:  
  36.             LOGV(" create VorbisPlayer");  
  37.             p = new VorbisPlayer();  
  38.             break;  
  39. #if BUILD_WITH_FULL_STAGEFRIGHT  
  40.         case STAGEFRIGHT_PLAYER:  
  41.             LOGV(" create StagefrightPlayer");  
  42.             p = new StagefrightPlayer;  
  43.             break;  
  44. #endif  
  45.         case TEST_PLAYER:  
  46.             LOGV("Create Test Player stub");  
  47.             p = new TestPlayerStub();  
  48.             break;  
  49.     }  
  50.     if (p != NULL) {  
  51.         if (p->initCheck() == NO_ERROR) {  
  52.             p->setNotifyCallback(cookie, notifyFunc);  
  53.         } else {  
  54.             p.clear();  
  55.         }  
  56.     }  
  57.     if (p == NULL) {  
  58.         LOGE("Failed to create player object");  
  59.     }  
  60.     return p;  
  61. }  

6.4 开始播放MediaPlayer::start

MediaPlayer::mPlayer实质为BpMediaPlayer

MediaPlayerService::Client::mPlayer实质为真正的AVPlayer,如:PVPlayer, XXPlayer

class PVPlayer: public MediaPlayerInterface

class MediaPlayerInterface : public MediaPlayerBase

 

MediaPlayer::start()  -->  mPlayer->start(BpMediaPlayer::start) --> remote()->transact(START, data, &reply)--> BpBinder::transact--> IPCThreadState::self()->transact--> ioctl(写) --> ioctl(读,在IPCThreadState::joinThreadPool中调用) --> BBinder::transact --> BnMediaPlayer::onTransact --> MediaPlayerService::Client::start -->MediaPlayerService::Client::mPlayer->start(PVPlayer->start)




0 0