JAVA类的路径:
frameworks/base/media/java/android/media/MediaPlayer.java
JAVA本地调用部分(JNI):
frameworks/base/media/jni/android_media_MediaPlayer.cpp 这部分内容编译成为目标是libmedia_jni.so。
主要的头文件在以下的目录中:frameworks/base/include/media/
多媒体底层库在以下的目录中:frameworks/av/media/libmedia/
这部分的内容被编译成库libmedia.so。
多媒体服务部分:
frameworks/av/media/libmediaplayerservice/
文件为mediaplayerservice.h和mediaplayerservice.cpp
这部分内容被编译成库libmediaplayerservice.so。
int main(int argc __unused, char** argv)
{
...
InitializeIcuOrDie();
//获得ProcessState实例对象
sp<ProcessState> proc(ProcessState::self());
//获取ServiceManager实例对象
sp<IServiceManager> sm = defaultServiceManager();
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
SoundTriggerHwService::instantiate();
RadioService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
defaultServiceManager
获取Service Manager远程接口的函数是defaultServiceManager.
gDefaultServiceManager是单例模式,调用defaultServiceManager函数时,如果gDefaultServiceManager已经创建,
则直接返回,否则通过interface_cast(ProcessState::self()->getContextObject(NULL))来创建一个,
并保存在gDefaultServiceManager全局变量中.
getService接口来获得.Service Manager远程接口是一个特殊的Binder引用,它的引用句柄一定是0。
ProcessState::ProcessState()
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
//采用内存映射函数mmap,给binder分配一块虚拟地址空间,用来接收事务
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
close(mDriverFD); //没有足够空间分配给/dev/binder,则关闭驱动
mDriverFD = -1;
}
}
}
ProcessState的单例模式的惟一性,因此一个进程只打开binder设备一次,其中ProcessState的成员变量mDriverFD记录binder驱动的fd,用于访问binder设备。
BINDER_VM_SIZE = (1*1024*1024) - (4096 *2), binder分配的默认内存大小为1M-8k。
DEFAULT_MAX_BINDER_THREADS = 15,binder默认的最大可并发访问的线程数为16。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
//获取handle=0的IBinder
return getStrongProxyForHandle(0);
}
interface_cast
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
对于asInterface()函数,也是通过模板函数来定义的,通过下面两个代码完成的:
//位于IServiceManager.h文件
DECLARE_META_INTERFACE(IServiceManager)
//位于IServiceManager.cpp文件
IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager")
IServiceManager::asInterface() 等价于 new BpServiceManager()
交互
如果我们要使用MediaPlayerService服务,那么MediaPlayerService客户端就需要与MediaPlayerService
(即BnMediaPlayerService)交互。交互的过程需要建立一个循环,然后读写Binder设备。注意,
在BnMediaPlayerService中并没有打开Binder设备和建立一个循环监听,这里实际上是借用ProcessState来完成了MediaPlayerService的一些功能.
IPCThreadState::self()->joinThreadPool,也就是说,主线程和工作线程都会执行joinThreadPool;
在该函数中通过talkWithDriver函数操作Binder驱动程序,executeCommand函数来执行命令。
查看executeCommand的代码可以得知,实际上会根据不同的命令进行不同的解析,
但是最终的解析还是调用BBinder::transact函数,而transact又调用了自己的BBinder::onTransact函数。
这里的BnMediaPlayerService继承自BBinder,所以会调用到它自己的BnMediaPlayerService::onTransact函数。
客户端
libs/media/mediaplayer.cpp
class MediaPlayer : public BnMediaPlayerClient,
public virtual IMediaDeathNotifier
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(getpid(), this, url));
err = setDataSource(player);