您的位置:首页 > 移动开发 > Android开发

android binder简单理解三

2015-02-06 17:43 441 查看
前面两章已经把meidaserver和servicemanager的通信建立了,并且mediaserver向servicemanager注册了service media.player。现在来简单看看media的client是怎么和mediaserver通信的。

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

593 public MediaPlayer() {
。。。。。。 //这些都不是我要关注的东西
609 /* Native setup requires a weak reference to our object.
610 * It's easier to create it here than in C++.
611 */
612 native_setup(new WeakReference<MediaPlayer>(this));//这个看起来和mediaserver有关
613 }


native_setup, jni的东西,去看看jni
framework/base/media/jni/android_media_MediaPlayer.cpp

640 static void
641 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
642 {
643     ALOGV("native_setup");
644     sp<MediaPlayer> mp = new MediaPlayer();//这个从frameworks/av/include/media/mediaplayer.h这里来,下面具体看看
645     if (mp == NULL) {
646         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
647         return;
648     }

650     // create new listener and give it to MediaPlayer
651     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);//相当于注册callback,
652     mp->setListener(listener);
653
654     // Stow our new C++ MediaPlayer in an opaque field in the Java object.
655     setMediaPlayer(env, thiz, mp);//这个也简单,就是把mp保存起来
656 }


frameworks/av/include/media/mediaplayer.h

193 class MediaPlayer : public BnMediaPlayerClient,
194                     public virtual IMediaDeathNotifier

可见MediaPlayer继承了IMediaDeathNotifier

new MediaPlayer(),看看它的构造函数:

frameworks/av/media/libmedia/mediaplayer.cpp

45 MediaPlayer::MediaPlayer()
46 {
47 ALOGV("constructor");
48 mListener = NULL;
49 mCookie = NULL;
50 mStreamType = AUDIO_STREAM_MUSIC;
51 mCurrentPosition = -1;
52 mSeekPosition = -1;
53 mCurrentState = MEDIA_PLAYER_IDLE;
54 mPrepareSync = false;
55 mPrepareStatus = NO_ERROR;
56 mLoop = false;
57 mLeftVolume = mRightVolume = 1.0;
58 mVideoWidth = mVideoHeight = 0;
59 mLockThreadId = 0;
60 mAudioSessionId = AudioSystem::newAudioSessionId();
61 AudioSystem::acquireAudioSessionId(mAudioSessionId);
62 mSendLevel = 0;
63 mRetransmitEndpointValid = false;
64 }


没做什么实际的东西,还没要和service通信。一般而言new了一个player之后会调用setDataSource(String)的,这个应该要和service通信了吧?

java层就不看了,它一定会同过jni调用下去的,直接看jni中的东西

228 static void
229 android_media_MediaPlayer_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
230 {
231 sp<MediaPlayer> mp = getMediaPlayer(env, thiz);//上面new的 Mediaplayer
232 if (mp == NULL ) {
233 jniThrowException(env, "java/lang/IllegalStateException", NULL);
234 return;
235 }
236
237 if (fileDescriptor == NULL) {
。。。。。。
241 int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
242 ALOGV("setDataSourceFD: fd %d", fd);
243 process_media_player_call( env, thiz, mp->setDataSource(fd, offset, length), "java/io/IOException", "setDataSourceFD failed." );
//这个调用很特别,关于jni的原理现在还不懂,但可以知道它进入了frameworks/av/media/libmedia/mediaplayer.cpp中的 setDataSource
 244 }
frameworks/av/media/libmedia/mediaplayer.cpp
157 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
158 {
159 ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
160 status_t err = UNKNOWN_ERROR;
161 const sp<IMediaPlayerService>& service(getMediaPlayerService());//嗯,这里去获取service
162 if (service != 0) {
163 sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
164 if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
165 (NO_ERROR != player->setDataSource(fd, offset, length))) {
166 player.clear();
166 player.clear();
167 }
168 err = attachNewPlayer(player);
169 }
170 return err;
171 }


因为MediaPlayer继承了IMediaDeathNotifier,其实getMediaPlayerService()是在IMediaDeathNotifier实现的。
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"));/*这个和上一篇的流程基本一样只是ADD_SERVICE_TRANSACTION变成了

CHECK_SERVICE_TRANSACTION。这会导致最终servicemanager进入service_manager.c

233     switch(txn->code) {
234     case SVC_MGR_GET_SERVICE:
235     case SVC_MGR_CHECK_SERVICE:
236         s = bio_get_string16(msg, &len);
237         ptr = do_find_service(bs, s, len, txn->sender_euid);
238         if (!ptr)
返回的binder就是经过转换后的<span><span class="keyword">new</span><span> MediaPlayerService()</span></span>

*/
 44 if (binder != 0) {
45 break;
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);
/*
经过interface_cast之后,binder就变成了BpMediaPlayerService,经过如下
interface_cast<IMediaPlayerService>(MediaPlayerService)
-->IMediaPlayerService::asInterface(MediaPlayerService)
-->(/frameworks/native/include/binder/IInterface.h)
89     android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
90             const android::sp<android::IBinder>& obj)                   \

-->android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(&MediaPlayerService){//经过代入的代码
 92         android::sp<I##MediaPlayerService> intr;                                 \
 93         if (obj != NULL) {                                              \
 94             intr = static_cast<IMediaPlayerServcie*>( 
/*
进这里obj(IBinder)和IMediaPlayerService的descriptor当然不一样,intr==null
*/                        \
 95                 obj->queryLocalInterface(                               \
 96                         IMediaPlayerService::descriptor).get());               \
 97             if (intr == NULL) {                                         \
 98                 intr = new BpMediaPlayerService(IBinder);                         
<pre name="code" class="cpp">\ 99             }
 100         }

 101        return intr;//就在这里返回了BpMediaPlayerService

}

*/

 56 } 57 ALOGE_IF(sMediaPlayerService == 0, "no media player service!?"); 58 return sMediaPlayerService; 59 }


所以sMediaPlayerService其实就是BpMediaPlayerService

BpMediaPlayerService继承BpInterface
54 class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
55 {
56 public:
57 BpMediaPlayerService(const sp<IBinder>& impl)
58 : BpInterface<IMediaPlayerService>(impl)
59 {
60 }
62 template<typename INTERFACE>
63 class BpInterface : public INTERFACE, public B
4000
pRefBase
64 {
65 public:
66                                 BpInterface(const sp<IBinder>& remote);
67


到这里remote被赋值为IBinder

终于从const sp<IMediaPlayerService>& service(getMediaPlayerService())出来了,返回了一个 BpMediaPlayerService对象

回到了setDataSource函数,那接着看,

163         sp<IMediaPlayer> player(service->create(this, mAudioSessionId));

这句就变成了sp<IMediaPlayer> player(BpMediaPlayerService->create(this, mAudioSessionId)) 70 virtual sp<IMediaPlayer> create(
71 const sp<IMediaPlayerClient>& client, int audioSessionId) {
72 Parcel data, reply;
73 data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
74 data.writeStrongBinder(client->asBinder());
75 data.writeInt32(audioSessionId);
76
77 remote()->transact(CREATE, data, &reply);
78 return interface_cast<IMediaPlayer>(reply.readStrongBinder());
79 }


因为remote是IBinder,所以: IBinder->transact,当然IBinder的transact函数只在它的继承函数BpBinder实现,所以又变成了,BpBinder->transcat,
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);//mHandle又是什么?这个当然是刚刚获取MediaPlayerService时返回的handle了
这样在驱动中就可以找到MediaPlayerService了
 166 if (status == DEAD_OBJECT) mAlive = 0;
167 return status;
168 }
169
170 return DEAD_OBJECT;
171 }

这样就到了MediaServicePlayer端的create,

260 sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
261 int audioSessionId)
262 {
263 pid_t pid = IPCThreadState::self()->getCallingPid();
264 int32_t connId = android_atomic_inc(&mNextConnId);
265
266 sp<Client> c = new Client(
267 this, pid, connId, client, audioSessionId,
268 IPCThreadState::self()->getCallingUid());
269
270 ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
271 IPCThreadState::self()->getCallingUid());
272
273 wp<Client> w = c;
274 {
275 Mutex::Autolock lock(mLock);
276 mClients.add(w);
277 }
278 return c;
279 }

就这样MediaPlayerService的client就和service 通信上了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: