目录
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
侵删!