通过MediaPlayer简单理解Binder的使用

目录

一、说明

二、MediaPlayer中的Binder

1、MediaPlayer的UML图

2、MediaPlayerService的初始化

3、MediaPlayer的初始化

4、MediaPlayer与MediaPlayerService的通信


一、说明

Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的。所以搞明白Binder的话,在很大程度上就能理解程序运行的流程。

想要具体学习Binder可以参考:Android Binder 进程间通讯机制

了解binder的基本模型后,这篇就看下binder在MediaPlayer中的应用

二、MediaPlayer中的Binder

1、MediaPlayer的UML图

 

2、MediaPlayerService的初始化

frameworks/av/media/mediaserver/main_mediaserver.cpp

44  int main(int argc __unused, char** argv)
45  {
...
128          InitializeIcuOrDie();
129          sp<ProcessState> proc(ProcessState::self());
130          sp<IServiceManager> sm = defaultServiceManager();
131          ALOGI("ServiceManager: %p", sm.get());
132          AudioFlinger::instantiate();
133          MediaPlayerService::instantiate(); // MediaPlayerService的初始化
134          ResourceManagerService::instantiate();
135          CameraService::instantiate();
136          AudioPolicyService::instantiate();
137          SoundTriggerHwService::instantiate();
138          RadioService::instantiate();
139          registerExtensions();
140          ProcessState::self()->startThreadPool();
141          IPCThreadState::self()->joinThreadPool();
142      }
143  }

初始化很简单,下面大概看下MediaPlayerService是什么

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp 

271  void MediaPlayerService::instantiate() {
            // 初始化了一个MediaPlayerService并通过serviceManager add起来
272      defaultServiceManager()->addService(
273              String16("media.player"), new MediaPlayerService()); 
274  }

defaultServiceManager的addService是怎么处理这些服务的呢?

详情请查看:serviceManager服务管理者

到这里MediaPlayerService初始化完成,然后顺便看下MediaPlayerService的类关系

frameworks/av/media/libmediaplayerservice/MediaPlayerService.h

69  class MediaPlayerService : public BnMediaPlayerService // 继承自BnMediaPlayerService 
70  {
71      class Client;
72  
73      class AudioOutput : public MediaPlayerBase::AudioSink
74      {
75          class CallbackData;

可以看到MediaPlayerService 继承自BnMediaPlayerService ,看下BnMediaPlayerService

frameworks/av/include/media/IMediaPlayerService.h

98  class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
99  {
100  public:
101      virtual status_t    onTransact( uint32_t code,
102                                      const Parcel& data,
103                                      Parcel* reply,
104                                      uint32_t flags = 0);
105  };

BnMediaPlayerService试下了模板(具体语法不太懂,单纯理解是接口的意思吧,帮忙斧正),分别看下BnInterface

frameworks/native/include/binder/IInterface.h

50  class BnInterface : public INTERFACE, public BBinder
51  {
52  public:
53      virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
54      virtual const String16&     getInterfaceDescriptor() const;
55  
56  protected:
57      virtual IBinder*            onAsBinder();
58  };

frameworks/native/include/binder/Binder.h 

27  class BBinder : public IBinder
28  {

看来BnInterface是一个实现了IBinder的接口

再看下IMediaPlayerService

frameworks/av/include/media/IMediaPlayerService.h 

45  class IMediaPlayerService: public IInterface
46  {
47  public:
48      DECLARE_META_INTERFACE(MediaPlayerService);
49  
50      virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
51      virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
52      virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, int audioSessionId = 0) // 这里会创建client端
53              = 0;
54 

简单总结下:

MediaPlayerService就是继承了binder的服务端,并且启动后被增加到serviceManager中

3、MediaPlayer的初始化

frameworks/base/media/java/android/media/MediaPlayer.java

630      public MediaPlayer() {
631  
632          Looper looper;
633         ...
649          native_setup(new WeakReference<MediaPlayer>(this));
650      }
 
1922      private native final void native_setup(Object mediaplayer_this);

然后看下jni层的调用

frameworks/base/media/jni/android_media_MediaPlayer.cpp

869  android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
870  {
871      ALOGV("native_setup");
             // 初始化MediaPlayer
872      sp<MediaPlayer> mp = new MediaPlayer();
878      // create new listener and give it to MediaPlayer
879      sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
880      mp->setListener(listener);
882      // Stow our new C++ MediaPlayer in an opaque field in the Java object.
883      setMediaPlayer(env, thiz, mp);
884  }

看下MediaPlayer的构造方法

frameworks/av/media/libmedia/mediaplayer.cpp

50  MediaPlayer::MediaPlayer()
51  {
52      ALOGV("constructor");
53      mListener = NULL;
54      mCookie = NULL;
55      mStreamType = AUDIO_STREAM_MUSIC;
56      mAudioAttributesParcel = NULL;
57      mCurrentPosition = -1;
58      mSeekPosition = -1;
59      mCurrentState = MEDIA_PLAYER_IDLE;
60      mPrepareSync = false;
61      mPrepareStatus = NO_ERROR;
62      mLoop = false;
63      mLeftVolume = mRightVolume = 1.0;
64      mVideoWidth = mVideoHeight = 0;
65      mLockThreadId = 0;
66      mAudioSessionId = AudioSystem::newAudioUniqueId();
67      AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
68      mSendLevel = 0;
69      mRetransmitEndpointValid = false;
70  }

看样子只是定义了一些初始状态值

下面看下mediaplayer是什么

frameworks/av/include/media/mediaplayer.h

204  class MediaPlayer : public BnMediaPlayerClient, 
205                      public virtual IMediaDeathNotifier // 看样子应该是死了要通知的接口,暂时不看
206  {

发现MediaPlayer集成自BnMediaPlayerClient,看下BnMediaPlayerClient

frameworks/av/include/media/IMediaPlayerClient.h 

36  class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient>
37  {
38  public:
39      virtual status_t    onTransact( uint32_t code,  // 竟然只有一个方法,肯定比较关键了,看样子是向服务端通信的接口
40                                      const Parcel& data,
41                                      Parcel* reply,
42                                      uint32_t flags = 0);
43  };

BnInterface与刚才的一样是个模板,看下IMediaPlayerClient

frameworks/av/include/media/IMediaPlayerClient.h 

26  class IMediaPlayerClient: public IInterface
27  {
28  public:
29      DECLARE_META_INTERFACE(MediaPlayerClient); // 暂时不知道干嘛用的
30  
31      virtual void notify(int msg, int ext1, int ext2, const Parcel *obj) = 0;
32  };

简单总结下:

mediaplayer就是继承了binder的并重写了具体的onTransact方法。

4、MediaPlayer与MediaPlayerService的通信

MediaPlayer是客户端,也就是我们说的C/S中的C端

MediaPlayerService和MediaPlayerService::Client是服务器端。也就是我们说的C/S中的S端。​​​​​​​

MediaPlayerService实现IMediaPlayerService定义的业务逻辑,其主要功能是根据MediaPlayer::setDataSource输入的URL调用create函数创建对应的Player.​​​​​​​

MediaPlayerService::Client实现IMediaPlayer定义的业务逻辑,其主要功能包括start, stop, pause, resume…,其实现方法是调用MediaPlayerService create的Player中的对应方法来实现具体功能。​​​​​​​

此前在第四篇那个图中已经画了个整体,今天再把MediaPlayerService,MediaPlayerService::Client,MediaPlayer放大看下他们在实际业务中交互关系。

看下MediaPlayer的怎么把资源传递给MediaPlayerService的

frameworks/av/media/libmedia/mediaplayer.cpp

200  status_t MediaPlayer::setDataSource(const sp<IDataSource> &source)
201  {
202      ALOGV("setDataSource(IDataSource)");
203      status_t err = UNKNOWN_ERROR;
204      const sp<IMediaPlayerService>& service(getMediaPlayerService()); // 看来这就是获取服务端的关键方法了
205      if (service != 0) {
206          sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); //初始化MediaPlayerService时的create方法,
207          if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
208              (NO_ERROR != player->setDataSource(source))) {
209              player.clear();
210          }
211          err = attachNewPlayer(player);
212      }
213      return err;
214  }

看来关键是通过getMediaPlayerService()获取服务端的,看看这个方法怎么获取的

frameworks/wilhelm/src/android/android_GenericMediaPlayer.h

125      static const sp<IMediaPlayerService> getMediaPlayerService() {
126          return IMediaDeathNotifier::getMediaPlayerService();
127      }

又调用IMediaDeathNotifier中的getMediaPlayerService()

frameworks/av/media/libmedia/IMediaDeathNotifier.cpp 

35  IMediaDeathNotifier::getMediaPlayerService()
36  {
37      ALOGV("getMediaPlayerService");
38      Mutex::Autolock _l(sServiceLock);
39      if (sMediaPlayerService == 0) {
40          sp<IServiceManager> sm = defaultServiceManager(); // 这个不是就是那个服务管理者嘛
41          sp<IBinder> binder;
42          do {
43              binder = sm->getService(String16("media.player")); // 之前addservice里的key,然后通过这个key把服务取出来,这里怎么是个binder 对象呢?再往下看
44              if (binder != 0) {
45                  break;
46              }
47              ALOGW("Media player service not published, waiting...");
48              usleep(500000); // 0.5 s
49          } while (true);
50  
51          if (sDeathNotifier == NULL) {
52              sDeathNotifier = new DeathNotifier();
53          }
54          binder->linkToDeath(sDeathNotifier); // 绑到死
55          sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); // 这里应该就是把binder转成sMediaPlayerService 了
56      }
57      ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
58      return sMediaPlayerService;
59  }

先看下这个interface_cast是怎么把binder转成sMediaPlayerService的

frameworks/native/include/binder/IInterface.h 

41  template<typename INTERFACE>
42  inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
43  {
44      return INTERFACE::asInterface(obj); // 模板函数,这里的INTERFACE应该是IMediaPlayerService
45  }

通过模板函数调用IMediaPlayerService的asInterface方法

frameworks/av/include/media/IMediaPlayerService.h

但是IMediaPlayerService中没有定义这个方法啊,但是有一个宏定义:

45  class IMediaPlayerService: public IInterface
46  {
47  public:
48      DECLARE_META_INTERFACE(MediaPlayerService);

frameworks/native/include/binder/IInterface.h

74  #define DECLARE_META_INTERFACE(INTERFACE)                               \
75      static const android::String16 descriptor;                          \
          // 原来在这啊,又是模板方法
76      static android::sp<I##INTERFACE> asInterface(                       \
77              const android::sp<android::IBinder>& obj);                  \
78      virtual const android::String16& getInterfaceDescriptor() const;    \
79      I##INTERFACE();                                                     \
80      virtual ~I##INTERFACE();
 
83  #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
84      const android::String16 I##INTERFACE::descriptor(NAME);             \
85      const android::String16&                                            \
86              I##INTERFACE::getInterfaceDescriptor() const {              \
87          return I##INTERFACE::descriptor;                                \
88      }                                                                   \
89      android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
90              const android::sp<android::IBinder>& obj)                   \
91      {                                                                   \
92          android::sp<I##INTERFACE> intr;                                 \
93          if (obj != NULL) {                                              \
94              intr = static_cast<I##INTERFACE*>(                          \
95                  obj->queryLocalInterface(                               \
96                          I##INTERFACE::descriptor).get());               \
97              if (intr == NULL) {                                         \
                      // 把刚才的参数带模板就是 new BpMediaPlayerService(binder)
98                  intr = new Bp##INTERFACE(obj);                          \
99              }                                                           \
100          }                                                               \
101          return intr;                                                    \
102      }                                                                   \
103      I##INTERFACE::I##INTERFACE() { }                                    \
104      I##INTERFACE::~I##INTERFACE() { }                                   \
105   

可以看到把刚才的参数MediaPlayerService代入模板函数最后就是  new BpMediaPlayerService(binder)

frameworks/av/media/libmedia/IMediaPlayerService.cpp

56  public:
57      BpMediaPlayerService(const sp<IBinder>& impl)
58          : BpInterface<IMediaPlayerService>(impl)
59      {
60      }

因此 前面的const sp<IMediaPlayerService>& service(getMediaPlayerService()); 就是获取BpMediaPlayerService对象

接下来回过头再开刚才的binder = sm->getService(String16("media.player"));看他是怎么找到对应的binder呢

先看看这个sm是什么,根据之前sp<IServiceManager> sm = defaultServiceManager();

看下这个defaultServiceManager

frameworks/native/libs/binder/IServiceManager.cpp

33  sp<IServiceManager> defaultServiceManager()
34  {
35      if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
36  
37      {
38          AutoMutex _l(gDefaultServiceManagerLock);
39          while (gDefaultServiceManager == NULL) {
                 // 又是interface_cast模板函数,根据前面分析这个应该是 new BpServiceManager
40              gDefaultServiceManager = interface_cast<IServiceManager>(
41                  ProcessState::self()->getContextObject(NULL));
42              if (gDefaultServiceManager == NULL)
43                  sleep(1);
44          }
45      }
46  
47      return gDefaultServiceManager;
48  }

从模板函数interface_cast得知defaultServiceManager 返回 BpServiceManager

然后看下BpServiceManager的getService(String16("media.player"))方法

frameworks/native/libs/binder/IServiceManager.cpp 

134      virtual sp<IBinder> getService(const String16& name) const
135      {
136          unsigned n;
137          for (n = 0; n < 5; n++){
138              sp<IBinder> svc = checkService(name);
139              if (svc != NULL) return svc;
140              ALOGI("Waiting for service %s...\n", String8(name).string());
141              sleep(1);
142          }
143          return NULL;
144      }

看下关键的checkService

146      virtual sp<IBinder> checkService( const String16& name) const
147      {
148          Parcel data, reply;
149          data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
150          data.writeString16(name);
                // 关键代码,remote的transact方法 发送消息CHECK_SERVICE_TRANSACTION
151          remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
152          return reply.readStrongBinder();
153      }

 

这里可以看出调用的是remote()的transact方法发送消息“media.player”

然后找到并返回对应的BpMediaPlayerService

接下来ServiceManager怎么通信还请看问题:serviceManager服务管理者

这里只是知道ServiceManager最终返回了对应的服务

至此,const sp<IMediaPlayerService>& service(getMediaPlayerService()); 分析完毕

简单总结下就是:

MediaPlayer::setDataSource 方法中

通过const sp<IMediaPlayerService>& service(getMediaPlayerService());获取到BpMediaPlayerService

接下来看下 sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); 创建播放器的过程

也就是BpMediaPlayerService的create方法

frameworks/av/media/libmedia/IMediaPlayerService.cpp

70      virtual sp<IMediaPlayer> create(
71              const sp<IMediaPlayerClient>& client, int audioSessionId) {
72          Parcel data, reply;
73          data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());


74          data.writeStrongBinder(IInterface::asBinder(client));
75          data.writeInt32(audioSessionId);
76  
              // 发消息创建播放器
77          remote()->transact(CREATE, data, &reply);
78          return interface_cast<IMediaPlayer>(reply.readStrongBinder());
79      }

这个remote()又是什么呢?

frameworks/native/include/binder/IInterface.h 

140  template<typename INTERFACE>
141  inline IBinder* BpInterface<INTERFACE>::onAsBinder()
142  {
143      return remote();
144  }

这个remote()看资料应该是BpBinder 但是我没找到具体代码关联

接下来看下BpBinder的transact方法

frameworks/native/libs/binder/BpBinder.cpp

159  status_t BpBinder::transact(
160      uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
161  {
162      // Once a binder has died, it will never come back to life.
163      if (mAlive) {
164          status_t status = IPCThreadState::self()->transact(
165              mHandle, code, data, reply, flags);
166          if (status == DEAD_OBJECT) mAlive = 0;
167          return status;
168      }
169  
170      return DEAD_OBJECT;
171  }

又通过IPCThreadState::self()的transact方法

frameworks/native/libs/binder/IPCThreadState.cpp

548  status_t IPCThreadState::transact(int32_t handle,
549                                    uint32_t code, const Parcel& data,
550                                    Parcel* reply, uint32_t flags)
551  {
552      status_t err = data.errorCheck(); // 检测数据错误
 
563      if (err == NO_ERROR) {
564          LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
565              (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
566          err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
567      }
568        // 获取返回
582          if (reply) {
583              err = waitForResponse(reply);
584          } else {
585              Parcel fakeReply;
586              err = waitForResponse(&fakeReply);
587          }
607      return err;
608  }

再看下writeTransactionData

904  status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
905      int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
906  {
907      binder_transaction_data tr;
908  
917      const status_t err = data.errorCheck(); //检测没有错误后转化成binder_transaction_data 然后通过mOut写入
918      if (err == NO_ERROR) {
919          tr.data_size = data.ipcDataSize();
920          tr.data.ptr.buffer = data.ipcData();
921          tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
922          tr.data.ptr.offsets = data.ipcObjects();
923    }
934      mOut.writeInt32(cmd);
935      mOut.write(&tr, sizeof(tr));
936  
937      return NO_ERROR;
938  }

可以看到会将数据格式转化为binder_transaction_data 的方式写入到mOut

frameworks/native/include/binder/IPCThreadState.h

123              Parcel              mOut;

原来这个mOut就是Parcel

Parcel是一个容器,它主要用于存储序列化数据,然后可以通过Binder在进程间传递这些数据

Parcel可以包含原始数据类型(用各种对应的方法写入,比如writeInt(),writeFloat()等),可以包含Parcelable对象,它还包含了一个活动的IBinder对象的引用,这个引用导致另一端接收到一个指向这个IBinder的代理IBinder。

注:Parcel不是一般目的的序列化机制。这个类被设计用于高性能的IPC传输。因此不适合把Parcel写入永久化存储中,因为Parcel中的数据类型的实现的改变会导致旧版的数据不可读。

至此消息写入,然后看下收到消息后的流程

既然是不断接收消息肯定会有一个接收消息的循环体,还记得再main_mediaserver.cpp中初始化MediaPlayerService的同时也创建了关键的消息接收循环体

frameworks/av/media/mediaserver/main_mediaserver.cpp

44  int main(int argc __unused, char** argv)
45  {
...
128          InitializeIcuOrDie();
129          sp<ProcessState> proc(ProcessState::self());
130          sp<IServiceManager> sm = defaultServiceManager();
131          ALOGI("ServiceManager: %p", sm.get());
132          AudioFlinger::instantiate();
133          MediaPlayerService::instantiate(); // MediaPlayerService的初始化
134          ResourceManagerService::instantiate();
135          CameraService::instantiate();
136          AudioPolicyService::instantiate();
137          SoundTriggerHwService::instantiate();
138          RadioService::instantiate();
139          registerExtensions();
140          ProcessState::self()->startThreadPool(); // 启动线程池   
141          IPCThreadState::self()->joinThreadPool(); // 执行消息循环
142      }
143  }

先看下这个ProcessState::self()→startThreadPool();线程池是怎么操作的

frameworks/native/libs/binder/ProcessState.cpp

132  void ProcessState::startThreadPool()
133  {
134      AutoMutex _l(mLock);
135      if (!mThreadPoolStarted) {
136          mThreadPoolStarted = true;
137          spawnPooledThread(true);
138      }
139  }

再看下spawnPooledThread方法

286  void ProcessState::spawnPooledThread(bool isMain)
287  {
288      if (mThreadPoolStarted) {
289          String8 name = makeBinderThreadName();
290          ALOGV("Spawning new pooled thread, name=%s\n", name.string());
291          sp<Thread> t = new PoolThread(isMain); // 创建线程池
292          t->run(name.string());
293      }
294  }

看下new PoolThread(isMain)的过程

frameworks/native/libs/binder/ProcessState.cpp

52  class PoolThread : public Thread
53  {
54  public:
55      PoolThread(bool isMain) // 这个是主线程
56          : mIsMain(isMain)
57      {
58      }
59  
60  protected:
61      virtual bool threadLoop() // 这个就是顺便创建的工作线程了
62      {
              // 在工作线程中调用的joinThreadPool方法
63          IPCThreadState::self()->joinThreadPool(mIsMain);
64          return false;
65      }
66  
67      const bool mIsMain;
68  };

然后就看下IPCThreadState::self()→joinThreadPool(mIsMain);都干了什么

frameworks/native/libs/binder/IPCThreadState.cpp 

477  void IPCThreadState::joinThreadPool(bool isMain)
478  {
481      mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
488      status_t result;
489      do {
490          processPendingDerefs();
491          // now get the next command to be processed, waiting if necessary
492          result = getAndExecuteCommand(); // 通过一个do while循环调用getAndExecuteCommand
505      } while (result != -ECONNREFUSED && result != -EBADF);
510      mOut.writeInt32(BC_EXIT_LOOPER);
511      talkWithDriver(false);
512  }

看下关键的getAndExecuteCommand

414  status_t IPCThreadState::getAndExecuteCommand()
415  {
416      status_t result;
417      int32_t cmd;
418  
419      result = talkWithDriver(); // 获取result
420      if (result >= NO_ERROR) {
421          size_t IN = mIn.dataAvail();
422          if (IN < sizeof(int32_t)) return result;
423          cmd = mIn.readInt32(); // 通过mIn获取cmd ,前面已知这个mIn就是Parcel的对象,专门用来binder通信的载体
427          }
428  
429          pthread_mutex_lock(&mProcess->mThreadCountLock);
430          mProcess->mExecutingThreadsCount++;
431          pthread_mutex_unlock(&mProcess->mThreadCountLock);
432  
433          result = executeCommand(cmd);  // 执行cmd
434  
435          pthread_mutex_lock(&mProcess->mThreadCountLock);
436          mProcess->mExecutingThreadsCount--;
437          pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
438          pthread_mutex_unlock(&mProcess->mThreadCountLock);
447          set_sched_policy(mMyThreadId, SP_FOREGROUND);
448      }
449  
450      return result;
451  }

看来关键分三步:

1、result = talkWithDriver(); // 获取result

2、cmd = mIn.readInt32(); // 通过mIn获取cmd ,前面已知这个mIn就是Parcel的对象,专门用来binder通信的载体

3、result = executeCommand(cmd);  // 执行cmd

先看下result = talkWithDriver();

803  status_t IPCThreadState::talkWithDriver(bool doReceive)
804  {
809      binder_write_read bwr;
811      // Is the read buffer empty?
812      const bool needRead = mIn.dataPosition() >= mIn.dataSize(); // 判断是否需要读取
817      const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0; // 获取数据长度
818  
819      bwr.write_size = outAvail; // 复制给binder_write_read 对象
820      bwr.write_buffer = (uintptr_t)mOut.data();
821  
822      // This is what we'll read.
823      if (doReceive && needRead) {
824          bwr.read_size = mIn.dataCapacity();
825          bwr.read_buffer = (uintptr_t)mIn.data();
826      } else {
827          bwr.read_size = 0;
828          bwr.read_buffer = 0;
829      }
845      // Return immediately if there is nothing to do.
846      if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
847  
848      bwr.write_consumed = 0;
849      bwr.read_consumed = 0;
850      status_t err;
851      do {
855  #if defined(HAVE_ANDROID_OS)
856          if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) // 通过ioctl进行读取
857              err = NO_ERROR;
858          else
859              err = -errno;
860  #else
861          err = INVALID_OPERATION;
862  #endif
863          if (mProcess->mDriverFD <= 0) {
864              err = -EBADF;
865          }
869      } while (err == -EINTR);
877      if (err >= NO_ERROR) {
878          if (bwr.write_consumed > 0) {
879              if (bwr.write_consumed < mOut.dataSize())
880                  mOut.remove(0, bwr.write_consumed);
881              else
882                  mOut.setDataSize(0);
883          }
884          if (bwr.read_consumed > 0) {
885              mIn.setDataSize(bwr.read_consumed);
886              mIn.setDataPosition(0); // 如果读到数据mIn复位
887          }
898          return NO_ERROR; // 如果没啥问题的话 返回NO_ERROR
899      }
900  
901      return err;
902  }

返回没有错的时候就会执行: 

cmd = mIn.readInt32(); // 通过mIn获取cmd ,前面已知这个mIn就是Parcel的对象,专门用来binder通信的载体

result = executeCommand(cmd);  // 执行cmd

947  status_t IPCThreadState::executeCommand(int32_t cmd)
948  {
949      BBinder* obj;
950      RefBase::weakref_type* refs;
951      status_t result = NO_ERROR;
952  
953      switch ((uint32_t)cmd) {
 
1026      case BR_TRANSACTION: // 主要看下这个case
1027          {
1028              binder_transaction_data tr; 
1029              result = mIn.read(&tr, sizeof(tr));
1032              if (result != NO_ERROR) break;
1033  
1034              Parcel buffer;
1035              buffer.ipcSetDataReference( // Parcel 类型的buffer,用来承载收到的数据
1036                  reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
1037                  tr.data_size,
1038                  reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
1039                  tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
1040  
1041              const pid_t origPid = mCallingPid;
1042              const uid_t origUid = mCallingUid;
1043              const int32_t origStrictModePolicy = mStrictModePolicy;
1044              const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
1045  
1046              mCallingPid = tr.sender_pid;
1047              mCallingUid = tr.sender_euid;
1048              mLastTransactionBinderFlags = tr.flags;
1049  
1050              int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
1072              Parcel reply;
1073              status_t error;
1085              if (tr.target.ptr) {
1086                  sp<BBinder> b((BBinder*)tr.cookie); // 关键部分,将binder_transaction_data 的cookie 转化为BBinder
1087                  error = b->transact(tr.code, buffer, &reply, tr.flags); // 调用BBinder的transact,这块有个问题,是怎么对应MediaPlayerService的?
1089              } else {
1090                  error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
1091              }
1096              if ((tr.flags & TF_ONE_WAY) == 0) {
1098                  if (error < NO_ERROR) reply.setError(error);
1099                  sendReply(reply, 0);
1100              } else {
1101                  LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
1102              }
1103  
1104              mCallingPid = origPid;
1105              mCallingUid = origUid;
1106              mStrictModePolicy = origStrictModePolicy;
1107              mLastTransactionBinderFlags = origTransactionBinderFlags;
1115          }
1116          break;
1153      return result;
1154  }

可以看到,在executeCommand中调用BBinder的transact方法处理收到的数据

前面分析已知MediaPlayerService最终会实现BBinder中的onTransact方法

只是目前没有看明白BBinder是怎么指向到MediaPlayerService

现在就看下MediaPlayerService中的onTransact

frameworks/av/media/libmedia/IMediaPlayerService.cpp

156  status_t BnMediaPlayerService::onTransact(
157      uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
158  {
159      switch (code) {
160          case CREATE: { //前面发过来的是CREATE,这里就单独看下它
161              CHECK_INTERFACE(IMediaPlayerService, data, reply); // 检查一下数据
162              sp<IMediaPlayerClient> client =
163                  interface_cast<IMediaPlayerClient>(data.readStrongBinder()); // 通过传过来的data获取IMediaPlayerClient
 164              int audioSessionId = data.readInt32(); // 通过传进来的data获取audioSessionId 
165              sp<IMediaPlayer> player = create(client, audioSessionId); // 调用create方法 ,具体实现在MediaPlayerService.cpp中
166              reply->writeStrongBinder(IInterface::asBinder(player)); // 将创建的player返回,在发送端的waitForResponse中接收并处理
167              return NO_ERROR;
168          } break;

然后看下create的具体实现过程

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

331  sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
332          int audioSessionId)
333  {
334      pid_t pid = IPCThreadState::self()->getCallingPid(); // 获取调用者的PID
335      int32_t connId = android_atomic_inc(&mNextConnId); // 记录数量
336  
337      sp<Client> c = new Client(
338              this, pid, connId, client, audioSessionId,
339              IPCThreadState::self()->getCallingUid()); // 创建Client
340  
341      ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
342           IPCThreadState::self()->getCallingUid());
343  
344      wp<Client> w = c;
345      {
346          Mutex::Autolock lock(mLock);
347          mClients.add(w); // 将Client添加到队列
348      }
349      return c;
350  }

创建好Client后,通过reply→writeStrongBinder(IInterface::asBinder(player));返回

然后再发送端的transact方法中调用waitForResponse获取返回值,并返回给调用者,

frameworks/av/media/libmedia/IMediaPlayerService.cpp

70      virtual sp<IMediaPlayer> create(
71              const sp<IMediaPlayerClient>& client, int audioSessionId) {
72          Parcel data, reply;
73          data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());




74          data.writeStrongBinder(IInterface::asBinder(client));
75          data.writeInt32(audioSessionId);
76  
              // 发消息创建播放器
77          remote()->transact(CREATE, data, &reply);
78          return interface_cast<IMediaPlayer>(reply.readStrongBinder()); // 模板方法interface_cast将reply.readStrongBinder()转化为IMediaPlayer

79      }

至此sp<IMediaPlayer> player(service->create(this, mAudioSessionId)); //初始化MediaPlayerService时的create方法

分析完成

然后就是player→setDataSource(source)方法

类似于create ,setDataSource 最终会在MediaPlayerService中实现

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp 

693  status_t MediaPlayerService::Client::setDataSource(
694          const sp<IMediaHTTPService> &httpService,
695          const char *url,
696          const KeyedVector<String8, String8> *headers)
697  {


到这里Binder的通信大概分析完成,后面就知道从客户端MediaPlayer 调用服务端MediaPlayerService的方法直接来找就好了。
具体MediaPlayer 的播放框架还请查看:

参考:

https://www.jianshu.com/p/4ee3fd07da14

https://blog.csdn.net/chuiziky/article/details/82713126

https://blog.csdn.net/jacklam200/article/details/37518527

侵删!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值