Android-Native-Server 启动和注册详细分析
以mediaService为实例来讲解:
mediaService的启动入口 是一个 传统的 main()函数
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\av\media\mediaserver\main_mediaserver.cpp
步骤:、
1.获取ProcessState实例的强引用 proc
2.获取到一个BpServiceManager ServiceManager的代理类
3.初始化服务:AudioFlinger MediaPlayerService CameraService AudioPolicyService
4.开启线程池
int main(
int argc,
char
*
* argv)
{
//sp 是 strongpointer 是一个强引用指针
//获取ProcessState实例的强引用
sp
<ProcessState
> proc(ProcessState
:
:self());
//获取到一个BpServiceManager(BpBinder的子类)(servicerManager的代理对象)
sp
<IServiceManager
> sm
= defaultServiceManager();
ALOGI(
"ServiceManager: %p", sm.get());
//AudioFlinger服务初始化
AudioFlinger
:
:instantiate();
//MediaPlayerService服务初始化
MediaPlayerService
:
:instantiate();
//CameraService服务初始化
CameraService
:
:instantiate();
//AudioPolicyService服务初始化
AudioPolicyService
:
:instantiate();
//Server进程开启线程池 ?
ProcessState
:
:self()
-
>startThreadPool();
IPCThreadState
:
:self()
-
>joinThreadPool();
}
2.(callby 1) ProcessState::self()是一个单例模式,第一次调用时,gProcess == null 会出发ProcessState的构造函数
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
sp
<ProcessState
> ProcessState
:
:self()
{
Mutex
:
:Autolock _l(gProcessMutex);
if (gProcess
!= NULL) {
return gProcess;
}
gProcess
=
new ProcessState;
return gProcess;
}
3.(callby 2) ProcessState的实例化会打开Binder设备并进行内存映射。
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
ProcessState
:
:ProcessState()
: mDriverFD(open_driver())
//这里会打开Binder设备
, mVMStart(MAP_FAILED)
, mManagesContexts(
false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(
false)
, mThreadPoolSeq(
1)
{
if (mDriverFD
>
=
0) {
//表示打开open_drover()函数打开Binder设备并映射好虚拟内存空间成功
// XXX Ideally, there should be a specific define for whether we
// have mmap (or whether we could possibly have the kernel module
// availabla).
#
if
!
defined(HAVE_WIN32_IPC)
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart
= mmap(
0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE
| MAP_NORESERVE, mDriverFD,
0);
if (mVMStart
== MAP_FAILED) {
// *sigh*
ALOGE(
"Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD
=
-
1;
}
#
else
mDriverFD
=
-
1;
#
endif
}
LOG_ALWAYS_FATAL
4.(callby 3)Binder设备的打开函数。用来打开Binder设备。
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
static
int open_driver()
{
int fd
= open(
"/dev/binder", O_RDWR);
if (fd
>
=
0) {
//又是系统调用,具体功能就不知道了。
fcntl(fd, F_SETFD, FD_CLOEXEC);
int vers;
//获取Binder设备的版本号。
status_t result
= ioctl(fd, BINDER_VERSION,
&vers);
if (result
==
-
1) {
ALOGE(
"Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd
=
-
1;
}
//比较版本号是否匹配,不匹配就打开失败咯
if (result
!=
0
|| vers
!= BINDER_CURRENT_PROTOCOL_VERSION) {
ALOGE(
"Binder driver protocol does not match user space protocol!");
close(fd);
fd
=
-
1;
}
//通过Binder设备的系统调用,设置最大的线程数量
size_t maxThreads
=
15;
result
= ioctl(fd, BINDER_SET_MAX_THREADS,
&maxThreads);
if (result
==
-
1) {
ALOGE(
"Binder ioctl to set max threads failed: %s", strerror(errno));
}
}
else {
ALOGW(
"Opening '/dev/binder' failed: %s\n", strerror(errno));
}
return fd;
}
5.(callby 1) 返回一个BpServiceMamager.是ServiceManager的代理类。
源码位置:IServiceManager.cpp
interface
_cast是一个复杂的宏定
义把BpBidner封装成BpServiceManager,BpBidner存储在BpServiceManager父类的 BpRefBase 中的mRemote 中并提供remote()函数来返回BpBidner变量
sp
<IServiceManager
> defaultServiceManager()
{
if (gDefaultServiceManager
!= NULL)
return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager
== NULL) {
gDefaultServiceManager
= interface_cast
<IServiceManager
>(
ProcessState
:
:self()
-
>getContextObject(NULL));
}
//ProcessState::self()单例函数调用,getContextObject返回的是一个BpBidner
//interface_cast<IServiceManager> 函数把BpBidner封装成BpServiceManager,BpBidner被放在
//BpServiceManager父类的 BpRefBase 中的mRemote 中并提供remote()函数来返回BpBidner变量
}
return gDefaultServiceManager;
}
AudioFlinger::instantiate();这一句是对AudioFlinger的初始化(下面的MediaPlayerService等也是同个道理)
AudioFlinger继承了BinderService<AudioFlinger> 和BnAudioFlinger
Binder<AudioFlinger> 提供了两个静态函数在这里被用到
instantiate 和 publish,publish被instantiate简单调用而已。
源码:BinderService.h
template
<
typename SERVICE
>
class BinderService
{
public
:
//调用了IServiceManager的addService方法,实现服务的注册
static status_t publish(
bool allowIsolated
=
false) {
sp
<IServiceManager
> sm(defaultServiceManager());
return sm
-
>addService(String16(SERVICE
:
:getServiceName()),
new SERVICE(), allowIsolated);
}
static
void publishAndJoinThreadPool(
bool allowIsolated
=
false) {
sp
<IServiceManager
> sm(defaultServiceManager());
sm
-
>addService(String16(SERVICE
:
:getServiceName()),
new SERVICE(), allowIsolated);
ProcessState
:
:self()
-
>startThreadPool();
IPCThreadState
:
:self()
-
>joinThreadPool();
}
//简单调用了publish()方法。
static
void instantiate() { publish(); }
static status_t shutdown() {
return NO_ERROR;
}
};
publish中调用了人 defaultServiceManager。获取到serviceManager。
在Android的Binder框架中,可以说有三种C/S模式:
1.Client:serviceManager Server: Binder设备驱动
2.Client:AudioFlinger Server: serviceManager
3.Client:用户 Server: AudioFlinger
下面publish是第一种C/S模型,实现了serviceManage和Binder设备驱动的交互。通过 sm - > addService提交事务。
static status_t publish( bool allowIsolated = false ) {
sp < IServiceManager > sm(defaultServiceManager());
return sm - > addService(String16(SERVICE : : getServiceName()), new SERVICE(), allowIsolated);
}
下面是sm->addservice的具体实现:
Parcel是进程之间通信用的数据格式,data是client传给server的数据,reply是存储Server处理后返回的结果数据。
IServiceManager::getInterfaceDescriptor());是由宏实现的,返回的是"android.os.IserviceManager"
name是当前服务名称"media.audio_fligner"
service:是AudioFlinger实例
remote()返回的是BpBinder实例
virtual status_t addService(
const String16
& name,
const sp
<IBinder
>
& service,
bool allowIsolated)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager
:
:getInterfaceDescriptor());//"android.os.IserviceManager"
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated
?
1
:
0);
//调用remote()返回一个IBinder对象,在调用BpBinder的事物处理函数transact
//来处理这个事物
status_t err
= remote()
-
>transact(ADD_SERVICE_TRANSACTION, data,
&reply);
return err
== NO_ERROR
? reply.readExceptionCode()
: err;
}
transact中调用了 IPCThreadState::self()->transact,真正对事务进行处理是在IPCThreadState中进行的。
源码:BpBinder.cpp
status_t BpBinder
:
:transact(
uint32_t code,
const Parcel
& data, Parcel
* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status
= IPCThreadState
:
:self()
-
>transact(
mHandle, code, data, reply, flags);
if (status
== DEAD_OBJECT) mAlive
=
0;
return status;
}
return DEAD_OBJECT;
}
IPCThreadState::transact中有两个重要的函数:
writeTransactionData 和 waitForResponse
writeTransactionData :负责对与Binder设备通讯的数据进行封装。
waitForResponse:负责与Binder设备通讯,还有返回数据的封装。
status_t IPCThreadState
:
:transact(int32_t handle,
uint32_t code,
const Parcel
& data,
Parcel
* reply, uint32_t flags)
{
status_t err
= data.errorCheck();
flags
|= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput
:
:Bundle _b(alog);
alog
<<
"BC_TRANSACTION thr "
<< (
void
*)pthread_self()
<<
" / hand "
<< handle
<<
" / code "
<< TypeCode(code)
<<
": "
<< indent
<< data
<< dedent
<< endl;
}
if (err
== NO_ERROR) {
LOG_ONEWAY(
">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags
& TF_ONE_WAY)
==
0
?
"READ REPLY"
:
"ONE WAY");
err
= writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
..............
........省略部分代码.........
...............
if (reply) {
err
= waitForResponse(reply);
}
else {
Parcel fakeReply;
err
= waitForResponse(
&fakeReply);
}
..............
.........省略部分代码.........
...............
return err;
}
writeTransactionData 顾名思义就是写入事务所需要的数据。
与Binder设备进行数据的交互是另外一种数据结构binder_transaction_data,不同于进程之间进行通讯的数据结构Parcel
所以在这里就必须把Parcel转换成binder_transaction_data 。
最终是把binder_transaction_data 写进ServiceManager进程在Binder设备申请的内存映射区mOut里面。
上面就把要给Binder设备的数据封装好,放在一个Binder知道的地方。
接下来,就要让Binder去取数据,并做处理。
status_t IPCThreadState
:
:writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code,
const Parcel
& data, status_t
* statusBuffer)
{
binder_transaction_data tr;
tr.target.handle
= handle;
tr.code
= code;
tr.flags
= binderFlags;
tr.cookie
=
0;
tr.sender_pid
=
0;
tr.sender_euid
=
0;
const status_t err
= data.errorCheck();
if (err
== NO_ERROR) {
tr.data_size
= data.ipcDataSize();
tr.data.ptr.buffer
= data.ipcData();
tr.offsets_size
= data.ipcObjectsCount()
*
sizeof(size_t);
tr.data.ptr.offsets
= data.ipcObjects();
}
else
if (statusBuffer) {
tr.flags
|= TF_STATUS_CODE;
*statusBuffer
= err;
tr.data_size
=
sizeof(status_t);
tr.data.ptr.buffer
= statusBuffer;
tr.offsets_size
=
0;
tr.data.ptr.offsets
= NULL;
}
else {
return (mLastError
= err);
}
mOut.writeInt32(cmd);
mOut.write(
&tr,
sizeof(tr));
return NO_ERROR;
waitForResponse是另一个重要函数,里面有一个while循环,每次循环的开始都会执行talkWithDriver函数,然后去读取 cmd = mIn.readInt32(); 其返回的是一个command,意思是通过talkWithDriver不断地去访问Binder设备,“催促Binder设备快点处理我的事务”,然后通过mIn.readInt32()得到事务处理结果,再用swich语句来处理,Binder反馈回来的结果,其中case BR_REPLY:是我们最终想要得到的反馈结果,意思是Binder已经对我们的事务做了处理,并有结果了,在这个分支里面,我们
把结果写进
Parcel *
reply,并通过go finish结束函数。
status_t IPCThreadState
:
:waitForResponse(Parcel
*reply, status_t
*acquireResult)
{
int32_t cmd;
int32_t err;
while (
1) {
if ((err
=talkWithDriver())
< NO_ERROR)
break;
err
= mIn.errorCheck();
if (err
< NO_ERROR)
break;
if (mIn.dataAvail()
==
0)
continue;
cmd
= mIn.readInt32();
IF_LOG_COMMANDS() {
alog
<<
"Processing waitForResponse Command: "
<< getReturnString(cmd)
<< endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE
:
if (
!reply
&&
!acquireResult)
goto finish;
break;
case BR_DEAD_REPLY
:
err
= DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY
:
err
= FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT
:
{
ALOG_ASSERT(acquireResult
!= NULL,
"Unexpected brACQUIRE_RESULT");
const int32_t result
= mIn.readInt32();
if (
!acquireResult)
continue;
*acquireResult
= result
? NO_ERROR
: INVALID_OPERATION;
}
goto finish;
case BR_REPLY
:
{
binder_transaction_data tr;
err
= mIn.read(
&tr,
sizeof(tr));
ALOG_ASSERT(err
== NO_ERROR,
"Not enough command data for brREPLY");
if (err
!= NO_ERROR)
goto finish;
if (reply) {
if ((tr.flags
& TF_STATUS_CODE)
==
0) {
reply
-
>ipcSetDataReference(
reinterpret_cast
<
const uint8_t
*
>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast
<
const size_t
*
>(tr.data.ptr.offsets),
tr.offsets_size
/
sizeof(size_t),
freeBuffer,
this);
}
else {
err
=
*
static_cast
<
const status_t
*
>(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast
<
const uint8_t
*
>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast
<
const size_t
*
>(tr.data.ptr.offsets),
tr.offsets_size
/
sizeof(size_t),
this);
}
}
else {
freeBuffer(NULL,
reinterpret_cast
<
const uint8_t
*
>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast
<
const size_t
*
>(tr.data.ptr.offsets),
tr.offsets_size
/
sizeof(size_t),
this);
continue;
}
}
goto finish;
default
:
err
= executeCommand(cmd);
if (err
!= NO_ERROR)
goto finish;
break;
}
}
finish
:
if (err
!= NO_ERROR) {
if (acquireResult)
*acquireResult
= err;
if (reply) reply
-
>setError(err);
mLastError
= err;
}
return err;
}
talkWithDriver中进行内核的Binder通信。
关键函数是:ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) 进行系统调用。
最后把返回的数据写进 mIn 。
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
status_t IPCThreadState
:
:talkWithDriver(
bool doReceive)
{
ALOG_ASSERT(mProcess
-
>mDriverFD
>
=
0,
"Binder driver is not opened");
binder_write_read bwr;
// Is the read buffer empty?
const
bool needRead
= mIn.dataPosition()
>
= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail
= (
!doReceive
|| needRead)
? mOut.dataSize()
:
0;
bwr.write_size
= outAvail;
bwr.write_buffer
= (
long
unsigned
int)mOut.data();
// This is what we'll read.
if (doReceive
&& needRead) {
bwr.read_size
= mIn.dataCapacity();
bwr.read_buffer
= (
long
unsigned
int)mIn.data();
}
else {
bwr.read_size
=
0;
bwr.read_buffer
=
0;
}
//用来打印日志的
IF_LOG_COMMANDS() {
TextOutput
:
:Bundle _b(alog);
if (outAvail
!=
0) {
alog
<<
"Sending commands to driver: "
<< indent;
const
void
* cmds
= (
const
void
*)bwr.write_buffer;
const
void
* end
= ((
const uint8_t
*)cmds)
+bwr.write_size;
alog
<< HexDump(cmds, bwr.write_size)
<< endl;
while (cmds
< end) cmds
= printCommand(alog, cmds);
alog
<< dedent;
}
alog
<<
"Size of receive buffer: "
<< bwr.read_size
<<
", needRead: "
<< needRead
<<
", doReceive: "
<< doReceive
<< endl;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size
==
0)
&& (bwr.read_size
==
0))
return NO_ERROR;
bwr.write_consumed
=
0;
bwr.read_consumed
=
0;
status_t err;
do {
IF_LOG_COMMANDS() {
alog
<<
"About to read/write, write size = "
<< mOut.dataSize()
<< endl;
}
#
if
defined(HAVE_ANDROID_OS)
if (ioctl(mProcess
-
>mDriverFD, BINDER_WRITE_READ,
&bwr)
>
=
0)
err
= NO_ERROR;
else
err
=
-errno;
#
else
err
= INVALID_OPERATION;
#
endif
IF_LOG_COMMANDS() {
alog
<<
"Finished read/write, write size = "
<< mOut.dataSize()
<< endl;
}
}
while (err
==
-EINTR);
IF_LOG_COMMANDS() {
alog
<<
"Our err: "
<< (
void
*)err
<<
", write consumed: "
<< bwr.write_consumed
<<
" (of "
<< mOut.dataSize()
<<
"), read consumed: "
<< bwr.read_consumed
<< endl;
}
if (err
>
= NO_ERROR) {
if (bwr.write_consumed
>
0) {
if (bwr.write_consumed
< (ssize_t)mOut.dataSize())
mOut.remove(
0, bwr.write_consumed);
else
mOut.setDataSize(
0);
}
if (bwr.read_consumed
>
0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(
0);
}
IF_LOG_COMMANDS() {
TextOutput
:
:Bundle _b(alog);
alog
<<
"Remaining data size: "
<< mOut.dataSize()
<< endl;
alog
<<
"Received commands from driver: "
<< indent;
const
void
* cmds
= mIn.data();
const
void
* end
= mIn.data()
+ mIn.dataSize();
alog
<< HexDump(cmds, mIn.dataSize())
<< endl;
while (cmds
< end) cmds
= printReturnCommand(alog, cmds);
alog
<< dedent;
}
return NO_ERROR;
}
return err;
}
最后是开启线程池:
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
startThreadPool:
mThreadPoolStarted = true;设置当前线程池的启动标志。
spawnPooledThread中开启一个新线程sp<Thread> t = new PoolThread(isMain);//PoolThread是Thread的子类。
并执行线程函数来运行线程 t->run(buf);
最后IPCThreadState::self()->joinThreadPool();把主线程也加入了线程池。!!!
void ProcessState
:
:startThreadPool()
{
AutoMutex _l(mLock);
if (
!mThreadPoolStarted) {
mThreadPoolStarted
=
true;
spawnPooledThread(
true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[16];
snprintf(buf, sizeof(buf), "Binder_%X", s);
ALOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
}
}
上面提到的宏定义及其实现:
#
define DECLARE_META_INTERFACE(INTERFACE) \
static
const android
:
:String16 descriptor; \
static android
:
:sp
<I##INTERFACE
> asInterface( \
const android
:
:sp
<android
:
:IBinder
>
& obj); \
virtual
const android
:
:String16
& getInterfaceDescriptor()
const; \
I##INTERFACE(); \
virtual
~I##INTERFACE(); \
#
define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android
:
:String16 I##INTERFACE
:
:descriptor(NAME); \
const android
:
:String16
& \
I##INTERFACE
:
:getInterfaceDescriptor()
const { \
return I##INTERFACE
:
:descriptor; \
} \
android
:
:sp
<I##INTERFACE
> I##INTERFACE
:
:asInterface( \
const android
:
:sp
<android
:
:IBinder
>
& obj) \
{ \
android
:
:sp
<I##INTERFACE
> intr; \
if (obj
!= NULL) { \
intr
=
static_cast
<I##INTERFACE
*
>( \
obj
-
>queryLocalInterface( \
I##INTERFACE
:
:descriptor).get()); \
if (intr
== NULL) { \
intr
=
new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE
:
:I##INTERFACE() { } \
I##INTERFACE
:
:
~I##INTERFACE() { } \
#
define CHECK_INTERFACE(
interface, data, reply) \
if (
!data.checkInterface(
this)) {
return PERMISSION_DENIED; } \