Android-Native-Server 启动和注册详细分析

摘要:
=NULL){returngProcess;}gProcess=newProcessState;returngProcess;}3.ProcessState的实例化会打开Binder设备并进行内存映射。源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworksativelibsinderProcessState.cppProcessState::ProcessState():mDriverFD//这里会打开Binder设备,mVMStart,mManagesContexts,mBinderContextCheckFunc,mBinderContextUserData,mThreadPoolStarted,mThreadPoolSeq{if{//表示打开open_drover()函数打开Binder设备并映射好虚拟内存空间成功//XXXIdeally,thereshouldbeaspecificdefineforwhetherwe//havemmap.#if!defined//mmapthebinder,providingachunkofvirtualaddressspacetoreceivetransactions.mVMStart=mmap;if{//*sigh*ALOGE;close;mDriverFD=-1;}#elsemDriverFD=-1;#endif}LOG_ALWAYS_FATAL4.Binder设备的打开函数。用来打开Binder设备。源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworksativelibsinderProcessState.cppstaticintopen_driver(){intfd=open;if{//又是系统调用,具体功能就不知道了。fcntl;intvers;//获取Binder设备的版本号。status_tresult=ioctl;if{ALOGE;close;fd=-1;}//比较版本号是否匹配,不匹配就打开失败咯if(result!
Android-Native-Server 启动和注册详细分析
以mediaService为实例来讲解:
mediaService的启动入口 是一个 传统的 main()函数
源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworksavmediamediaservermain_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_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.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_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.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. ");
close(mDriverFD);
mDriverFD =-1;
}
#else
mDriverFD =-1;
#endif
}
LOG_ALWAYS_FATAL
4.(callby 3)Binder设备的打开函数。用来打开Binder设备。
源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.cpp
staticint 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 ", 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);
}
staticvoid publishAndJoinThreadPool(bool allowIsolated =false) {
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
//简单调用了publish()方法。
staticvoid instantiate() { publish(); }
static status_t shutdown() {
return NO_ERROR;
}
};
publish中调用了人 defaultServiceManager。获取到serviceManager。
在Android的Binder框架中,可以说有三种C/S模式:
1.Client:serviceManagerServer: 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();
} elseif (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?
constbool 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 = (longunsignedint)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (longunsignedint)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;
constvoid* cmds = (constvoid*)bwr.write_buffer;
constvoid* 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;
}
#ifdefined(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;
constvoid* cmds = mIn.data();
constvoid* 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 ", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
}
}
上面提到的宏定义及其实现:
#define DECLARE_META_INTERFACE(INTERFACE)
staticconst android::String16 descriptor;
static android::sp<I##INTERFACE> asInterface(
const android::sp<android::IBinder>& obj);
virtualconst 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; }

免责声明:文章转载自《Android-Native-Server 启动和注册详细分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇android 内存泄漏,以及检测方法使用FDTemplateLayout框架打造个性App下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

GeeTest 极验验证

 前台Html页面 <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <script src="http://static.geetest.com/static/tools/gt.js"></script>...

C语言两个libxml2库使用的问题

最近使用libxml2想做点东西,翻看一些example后还是有些疑问,去segmentfault问了下,感谢@pingjiang的热心解答,问题解决,记录如下 (一)如下是一个XML文件,p为根结点 <p> <one>1</one> <two>2</two> <th...

vue后台管理系统项目

项目介绍1.项目根目录文件 2.源码子目录结构 3.api目录 4.assets目录 5.components目录 6.mixins目录 7.permission目录 8.router目录 9.store目录 10.styles目录 11.utils目录 项目文件介绍1.安装element-ui组件实现按需加载 // 1.1.npm...

C/C++文件输入输出操作——FILE*、fstream、windowsAPI

基于C的文件操作在ANSI C中,对文件的操作分为两种方式,即流式文件操作和I/O文件操作,下面就分别介绍之。 一、流式文件操作这种方式的文件操作有一个重要的结构FILE,FILE在头文件stdio.h中定义如下: typedef struct {int level;unsigned flags;char fd;unsigned char hold;int...

DataSnap基础

DataSnap基础 1. DATASNAP 历史 作为MIDAS起始于Delphi3,Delphi4是MIDAS II,Delphi5中是MIDASIII,而后基于COM远程数据模块方式使用TCP/IP,HTTP,(D)COM构建出强大的通讯能力.从Delphi6开始改名为DataSnap,直到D2007这个框架一直在使用.D2009重新架构了DataS...

Ogre2.0 全新功能打造新3D引擎

不知当初是在那看到,说是Ogre2.0浪费了一个版本号,当时也没多想,以为没多大更新,一直到现在想做一个编辑器时,忽然想到要看下最新版本的更新,不看不知道,一看吓一跳,所以说,网络上的话少信,你不认识别人,别人张嘴就来,对别人也没损失,还可以装B下,靠. 从现在Ogre2.1的代码来看,大约总结下,更新包含去掉过多的设计模式,SoA的数据结构(用于SIMD...