`
zzu_007
  • 浏览: 22354 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android源码之Binder(四)

阅读更多
case BINDER_SET_MAX_THREADS:
[// case BINDER_SET_MAX_THREADS
BINDER_SET_MAX_THREADS是设置Binder线程池的大小。
]// case BINDER_SET_MAX_THREADS
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
[// if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads)))
由此可见,BINDER_SET_MAX_THREADS的实现很简单,就是设置binder_proc的max_threads字段。
]// if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads)))
ret = -EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR:
[// case BINDER_SET_CONTEXT_MGR
BINDER_SET_CONTEXT_MGR是注册Service Manager服务的。
]// case BINDER_SET_CONTEXT_MGR
if (binder_context_mgr_node != NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
[// if (binder_context_mgr_node != NULL)
binder_context_mgr_node是一个全局的静态变量。指向全局的Service Manager的Binder实体对象。
当它不为NULL时,说明已经设置过Service Manager
static struct binder_node *binder_context_mgr_node;
]// if (binder_context_mgr_node != NULL)
if (binder_context_mgr_uid != -1) {
if (binder_context_mgr_uid != current->cred->euid) {
printk(KERN_ERR "binder: BINDER_SET_"
   "CONTEXT_MGR bad uid %d != %d\n",
   current->cred->euid,
   binder_context_mgr_uid);
ret = -EPERM;
goto err;
}
} else
binder_context_mgr_uid = current->cred->euid;
[// if (binder_context_mgr_uid != -1)
binder_context_mgr_uid也是一个静态的全局变量,保存Service Manager的进程ID。
binder_context_mgr_uid的定义如下:
static uid_t binder_context_mgr_uid = -1;
当binder_context_mgr_uid不为-1时,说明前面已经设置过Service Manager服务了。
这时候会判断当前进程是否是Service Manager注册的进程,也就是检查合法性
]// if (binder_context_mgr_uid != -1)
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
[// binder_context_mgr_node = binder_new_node(proc, NULL, NULL)
程序走到这里,则会调用binder_new_node来创建一个Binder实体对象。
binder_new_node函数的实现如下所示:
static struct binder_node *binder_new_node(struct binder_proc *proc,
   void __user *ptr,
   void __user *cookie)
[// static struct binder_node *binder_new_node(struct binder_proc *proc,
第一个参数proc用来描述Service Manager进程。
第二个参数ptr用来描述一个Binder本地对象,指向该Binder本地对象内部的一个弱引用计数对象的地址值
第三个参数cookie也用来描述一个Binder本地对象,指向该Binder本地对象的地址值
]// static struct binder_node *binder_new_node(struct binder_proc *proc,
{
struct rb_node **p = &proc->nodes.rb_node;
struct rb_node *parent = NULL;
struct binder_node *node;

while (*p) {
parent = *p;
node = rb_entry(parent, struct binder_node, rb_node);

if (ptr < node->ptr)
p = &(*p)->rb_left;
else if (ptr > node->ptr)
p = &(*p)->rb_right;
else
return NULL;
}
[// while (*p)
在这个while循环中以参数ptr为关键字,在红黑树中检查前面是否已经为参数ptr和cookie所描述的Binder本地对象创建过Binder实体对象。
]// while (*p)

node = kzalloc(sizeof(*node), GFP_KERNEL);
if (node == NULL)
return NULL;
binder_stats_created(BINDER_STAT_NODE);
rb_link_node(&node->rb_node, parent, p);
rb_insert_color(&node->rb_node, &proc->nodes);
node->debug_id = ++binder_last_id;
node->proc = proc;
node->ptr = ptr;
node->cookie = cookie;
node->work.type = BINDER_WORK_NODE;
INIT_LIST_HEAD(&node->work.entry);
INIT_LIST_HEAD(&node->async_todo);
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
"binder: %d:%d node %d u%p c%p created\n",
proc->pid, current->pid, node->debug_id,
node->ptr, node->cookie);
return node;
[// return node;
上面这段代码是创建一个Binder实体对象,并且对它进行初始化,最后将它加入到宿主进程的成员变量nodes所描述的一个红黑树中。
]// return node;
}
]// binder_context_mgr_node = binder_new_node(proc, NULL, NULL)
if (binder_context_mgr_node == NULL) {
ret = -ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
[// binder_context_mgr_node->has_weak_ref = 1
上面这四句代码是与引用计数相关的。
]// binder_context_mgr_node->has_weak_ref = 1
break;
case BINDER_THREAD_EXIT:
binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
proc->pid, thread->pid);
binder_free_thread(proc, thread);
thread = NULL;
break;
case BINDER_VERSION:
if (size != sizeof(struct binder_version)) {
ret = -EINVAL;
goto err;
}
if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
ret = -EINVAL;
goto err;
}
break;
default:
ret = -EINVAL;
goto err;
}
ret = 0;
err:
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
[// if (thread)
上面这句代码是将当前线程的状态位BINDER_LOOPER_STATE_NEED_RETURN清零,这样当前线程下次再次进入到Binder驱动程序时,Binder驱动程序就可以将进程间通信请求分发给它处理了。
]// if (thread)
mutex_unlock(&binder_lock);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
return ret;
}

上面的分析主要集中在Binder驱动程序中,Android系统在Frameworks层中将各个Binder驱动程序操作封装成一个Binder库,这样进程就可以方便地调用Binder库提供的接口来实现进程间通信。
接下来,我们分析一下Binder库的实现。
在Binder库中,Service组件和Client组件分别使用模版类BnInterface和BpInterface来描述,其中,前者称为Binder本地对象,后者称为Binder代理对象。
BnInterface和BpInterface的作用是为了代表驱动程序中的Binder实体对象和Binder引用对象。
模版类BnInterface和BpInterface定义在frameworks/base/include/binder/IInterface.h文件中,定义如下:
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
virtual const String16&     getInterfaceDescriptor() const;

protected:
virtual IBinder*            onAsBinder();
};


template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
[// BpInterface(const sp<IBinder>& remote)
BpInterface的构造函数实现如下:
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
]// BpInterface(const sp<IBinder>& remote)

protected:
virtual IBinder*            onAsBinder();
};
其中BnInterface和BpInterface都是模版类,其中模版参数INTERFACE要求必须继承自IInterface接口,这个接口也定义在frameworks/base/include/binder/IInterface.h文件中。
而且要求BnInterface和BpInterface都继承自INTERFACE!我靠,这设计够牛逼!
IInterface的定义如下:
class IInterface : public virtual RefBase
[// class IInterface : public virtual RefBase
可以看出IInterface继承了RefBase, 表示可以通过智能指针来管理对象
]// class IInterface : public virtual RefBase
{
public:
IInterface();
sp<IBinder>         asBinder();
sp<const IBinder>   asBinder() const;

protected:
virtual                     ~IInterface();
virtual IBinder*            onAsBinder() = 0;
};
我们首先分析Binder本地对象BnInterface的设计,从上面BnInterface类的声明上可以看出除了继承自IInterface之外,还继承了BBinder类,这个类为Binder本地对象提供了抽象的进程间通信接口。BBinder类的定义如下:
BBinder类的定义存在与frameworks\native\include\binder\Binder.h文件中,BBinder类的定义如下:
class BBinder : public IBinder
[// class BBinder : public IBinder
在BBinder类有两个重要的成员函数transact和onTransact.
当一个Binder代理对象通过Binder驱动程序向一个Binder本地对象发出一个进程间通信请求时,Binder驱动程序就会调用该Binder本地对象的成员transact来处理该请求。
成员函数onTransact是由BBinder的子类,即Binder本地对象类来实现的,它负责分发与业务相关的进程间通信请求。事实上,与业务相关的进程间通信请求是由Binder本地对象类的子类,即Service组件类来负责处理的。
]// class BBinder : public IBinder
{
public:
BBinder();

virtual const String16& getInterfaceDescriptor() const;
virtual bool        isBinderAlive() const;
virtual status_t    pingBinder();
virtual status_t    dump(int fd, const Vector<String16>& args);

virtual status_t    transact(   uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);

virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0);

virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);

virtual void        attachObject(   const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func);
virtual void*       findObject(const void* objectID) const;
virtual void        detachObject(const void* objectID);

virtual BBinder*    localBinder();

protected:
virtual             ~BBinder();

virtual status_t    onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);

private:
BBinder(const BBinder& o);
BBinder&    operator=(const BBinder& o);

class Extras;

Extras*     mExtras;
void*       mReserved0;
};
IBinder类的定义如下所示,定义在frameworks\native\include\binder\IBinder.h文件中
class IBinder : public virtual RefBase
{
public:
enum {
FIRST_CALL_TRANSACTION  = 0x00000001,
LAST_CALL_TRANSACTION   = 0x00ffffff,

PING_TRANSACTION        = B_PACK_CHARS('_','P','N','G'),
DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),
SYSPROPS_TRANSACTION    = B_PACK_CHARS('_', 'S', 'P', 'R'),

// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY             = 0x00000001
};

  IBinder();

/**
* Check if this IBinder implements the interface named by
* @a descriptor.  If it does, the base pointer to it is returned,
* which you can safely static_cast<> to the concrete C++ interface.
*/
virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);

/**
* Return the canonical name of the interface provided by this IBinder
* object.
*/
virtual const String16& getInterfaceDescriptor() const = 0;

virtual bool            isBinderAlive() const = 0;
virtual status_t        pingBinder() = 0;
virtual status_t        dump(int fd, const Vector<String16>& args) = 0;

virtual status_t        transact(   uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) = 0;

/**
* This method allows you to add data that is transported through
* IPC along with your IBinder pointer.  When implementing a Binder
* object, override it to write your desired data in to @a outData.
* You can then call getConstantData() on your IBinder to retrieve
* that data, from any process.  You MUST return the number of bytes
* written in to the parcel (including padding).
*/
class DeathRecipient : public virtual RefBase
{
public:
virtual void binderDied(const wp<IBinder>& who) = 0;
};

/**
* Register the @a recipient for a notification if this binder
* goes away.  If this binder object unexpectedly goes away
* (typically because its hosting process has been killed),
* then DeathRecipient::binderDied() will be called with a reference
* to this.
*
* The @a cookie is optional -- if non-NULL, it should be a
* memory address that you own (that is, you know it is unique).
*
* @note You will only receive death notifications for remote binders,
* as local binders by definition can't die without you dying as well.
* Trying to use this function on a local binder will result in an
* INVALID_OPERATION code being returned and nothing happening.
*
* @note This link always holds a weak reference to its recipient.
*
* @note You will only receive a weak reference to the dead
* binder.  You should not try to promote this to a strong reference.
* (Nor should you need to, as there is nothing useful you can
* directly do with it now that it has passed on.)
*/
virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0) = 0;

/**
* Remove a previously registered death notification.
* The @a recipient will no longer be called if this object
* dies.  The @a cookie is optional.  If non-NULL, you can
* supply a NULL @a recipient, and the recipient previously
* added with that cookie will be unlinked.
*/
virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
void* cookie = NULL,
uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL) = 0;

virtual bool            checkSubclass(const void* subclassID) const;

typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);

virtual void            attachObject(   const void* objectID,
void* object,
void* cleanupCookie,
object_cleanup_func func) = 0;
virtual void*           findObject(const void* objectID) const = 0;
virtual void            detachObject(const void* objectID) = 0;

virtual BBinder*        localBinder();
virtual BpBinder*       remoteBinder();

protected:
virtual          ~IBinder();

private:
};

接下来我们开始BpInterface的设计,BpInterface除了继承了IInterface之外,还继承了BpRefBase类,BpRefBase类为Binder代理对象提供了抽象的进程间通信接口。BpRefBase类的定义如下:
BpRefBase类的声明在frameworks\native\include\binder\Binder.h
class BpRefBase : public virtual RefBase
{
protected:
BpRefBase(const sp<IBinder>& o);
[// BpRefBase(const sp<IBinder>& o)
BpRefBase类的构造函数如下:
BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
[// mRemote(o.get())
这里初始化mRemote成员变量
]// mRemote(o.get())
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);

if (mRemote) {
mRemote->incStrong(this);           // Removed on first IncStrong().
mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
}
}
]// BpRefBase(const sp<IBinder>& o)
virtual                 ~BpRefBase();
virtual void            onFirstRef();
virtual void            onLastStrongRef(const void* id);
virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);

inline  IBinder*        remote()                { return mRemote; }
inline  IBinder*        remote() const          { return mRemote; }

private:
BpRefBase(const BpRefBase& o);
BpRefBase&              operator=(const BpRefBase& o);

IBinder* const          mRemote;
[// IBinder* const          mRemote
这里mRemote指向了一个Binder代理对象,其实是一个BpBinder类型的对象。
]// IBinder* const          mRemote
RefBase::weakref_type*  mRefs;
volatile int32_t        mState;
};
从BpRefBase类的声明中可以看出,BpRefBase继承了RefBase。


总结一下BnInterface和BpInterface类集成体系:
BnInterface->(INTERFACE->IInterface->RefBase, BBinder->IBinder->RefBase)
BpInterface->(INTERFACE->IInterface->RefBase, BpRefBase->RefBase)

我们接着
在Binder库中,Android系统还设计了两个很重要的类: IPCThreadState和ProcessState类。
这两个类的作用是为了和Binder驱动程序交互。

用户在设计自己的Service组件和client组件时,一般的流程是首先将Service组件加入到Service Manager中去,然后调用
ProcessState::self()->startThreadPool()
IPCThreadState::self()->joinThreadPool();
这两句代码。
这两句代码的作用就是注册Binder线程池,表示可以处理Binder进程间通信请求了。

我们就从上面两句代码开始分析FrameWorks的Binder库。
我们先看一下ProcessState类的声明:
class ProcessState : public virtual RefBase
{
public:
static  sp<ProcessState>    self();

void                setContextObject(const sp<IBinder>& object);
sp<IBinder>         getContextObject(const sp<IBinder>& caller);

void                setContextObject(const sp<IBinder>& object,
const String16& name);
sp<IBinder>         getContextObject(const String16& name,
const sp<IBinder>& caller);

void                startThreadPool();

typedef bool (*context_check_func)(const String16& name,
   const sp<IBinder>& caller,
   void* userData);

bool                isContextManager(void) const;
bool                becomeContextManager(
context_check_func checkFunc,
void* userData);

sp<IBinder>         getStrongProxyForHandle(int32_t handle);
wp<IBinder>         getWeakProxyForHandle(int32_t handle);
void                expungeHandle(int32_t handle, IBinder* binder);

void                setArgs(int argc, const char* const argv[]);
int                 getArgC() const;
const char* const*  getArgV() const;

void                setArgV0(const char* txt);

void                spawnPooledThread(bool isMain);

status_t            setThreadPoolMaxThreadCount(size_t maxThreads);

private:
friend class IPCThreadState;

ProcessState();
~ProcessState();

ProcessState(const ProcessState& o);
ProcessState&       operator=(const ProcessState& o);

struct handle_entry {
IBinder* binder;
RefBase::weakref_type* refs;
};

handle_entry*       lookupHandleLocked(int32_t handle);

int                 mDriverFD;
[// int                 mDriverFD
mDriverFD保存打开/dev/binder之后的文件描述符,就通过这个变量
]// int                 mDriverFD
void*               mVMStart;

mutable Mutex               mLock;  // protects everything below.

Vector<handle_entry>mHandleToObject;

bool                mManagesContexts;
context_check_func  mBinderContextCheckFunc;
void*               mBinderContextUserData;

KeyedVector<String16, sp<IBinder> >
mContexts;


String8             mRootDir;
bool                mThreadPoolStarted;
[// bool                mThreadPoolStarted
mThreadPoolStarted变量用于指示Binder库是否启动过
]// bool                mThreadPoolStarted
volatile int32_t            mThreadPoolSeq;
};
我们从ProcessState类的self()函数开始分析ProcessState的设计和实现:
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
[// gProcess = new ProcessState
这里调用ProcessState的构造函数来构造一个ProcessState对象并赋值给全局变量gProcess,我们来看一下ProcessState的构造函数的实现:
ProcessState::ProcessState()
: mDriverFD(open_driver())
[// mDriverFD(open_driver())
初始化mDriverFD是通过调用open_driver来初始化的。
open_driver函数的作用是打开/dev/binder文件,并做一些初始化的工作。
static int open_driver()
{
int fd = open("/dev/binder", O_RDWR);
[// int fd = open("/dev/binder", O_RDWR)
打开/dev/binder文件
]// int fd = open("/dev/binder", O_RDWR)
if (fd >= 0) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
int vers;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
[// status_t result = ioctl(fd, BINDER_VERSION, &vers)
首先通过ioctl函数获得Binder驱动程序的Binder内核的版本号。
这会陷入到Binder驱动程序的binder_ioctl函数中去。
]// 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;
}
[// if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION)
上面这段代码是为了验证Binder的版本。
]// if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION)
size_t maxThreads = 15;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
[// result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads)
这里是设置Binder线程池的大小,由此可以看出,默认的Binder线程池的大小为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;
}
]// mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// 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);
[// mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0)
这里调用mmap函数来使得Binder驱动分配空间。
]// 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_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}
]// gProcess = new ProcessState
return gProcess;
}
[// sp<ProcessState> ProcessState::self()
从self函数的实现可以看出ProcessState是一个单例模式。
]// sp<ProcessState> ProcessState::self()

分析完ProcessState的self函数之后,我们就看一下ProcessState的startThreadPool函数的实现:
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(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);
[// ALOGV("Spawning new pooled thread, name=%s\n", buf)
这里初始化线程的名字
]// ALOGV("Spawning new pooled thread, name=%s\n", buf)
sp<Thread> t = new PoolThread(isMain);
[// sp<Thread> t = new PoolThread(isMain)
这里构造了一个PoolThread对象,PoolThread类的定义如下:
class PoolThread : public Thread
{
public:
PoolThread(bool isMain)
: mIsMain(isMain)
[// PoolThread(bool isMain)
PoolThread的构造函数很简单,基本是个空函数。
PoolThread的父类Thread的构造函数详见Thread类
]// PoolThread(bool isMain)
{
}

protected:
virtual bool threadLoop()
[// virtual bool threadLoop()
threadLoop函数是一个很重要的函数.创建的线程实际调用的就是这个函数.
]// virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
[// IPCThreadState::self()->joinThreadPool(mIsMain)
这里会调用IPCThreadState的joinThreadPool函数,详见IPCThreadState类的设计和分析.
]// IPCThreadState::self()->joinThreadPool(mIsMain)
return false;
}

const bool mIsMain;
};
PoolThread类又继承自Thread类,Thread类的声明如下:
class Thread : virtual public RefBase
{
public:
// Create a Thread object, but doesn't create or start the associated
// thread. See the run() method.
Thread(bool canCallJava = true);
[// Thread(bool canCallJava = true)
Thread类的构造函数如下:
Thread::Thread(bool canCallJava)
:   mCanCallJava(canCallJava),
[// mCanCallJava(canCallJava)
可以看出, mCanCallJava默认是true
]// mCanCallJava(canCallJava)
mThread(thread_id_t(-1)),
mLock("Thread::mLock"),
mStatus(NO_ERROR),
mExitPending(false), mRunning(false)
#ifdef HAVE_ANDROID_OS
, mTid(-1)
#endif
{
}
]// Thread(bool canCallJava = true)
virtual             ~Thread();

// Start the thread in threadLoop() which needs to be implemented.
virtual status_t    run(    const char* name = 0,
int32_t priority = PRIORITY_DEFAULT,
size_t stack = 0);

// Ask this object's thread to exit. This function is asynchronous, when the
// function returns the thread might still be running. Of course, this
// function can be called from a different thread.
virtual void        requestExit();

// Good place to do one-time initializations
virtual status_t    readyToRun();

// Call requestExit() and wait until this object's thread exits.
// BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
// this function from this object's thread. Will return WOULD_BLOCK in
// that case.
status_t    requestExitAndWait();

// Wait until this object's thread exits. Returns immediately if not yet running.
// Do not call from this object's thread; will return WOULD_BLOCK in that case.
status_t    join();

#ifdef HAVE_ANDROID_OS
// Return the thread's kernel ID, same as the thread itself calling gettid() or
// androidGetTid(), or -1 if the thread is not running.
pid_t       getTid() const;
#endif

protected:
// exitPending() returns true if requestExit() has been called.
bool        exitPending() const;

private:
// Derived class must implement threadLoop(). The thread starts its life
// here. There are two ways of using the Thread object:
// 1) loop: if threadLoop() returns true, it will be called again if
//          requestExit() wasn't called.
// 2) once: if threadLoop() returns false, the thread will exit upon return.
virtual bool        threadLoop() = 0;

private:
Thread& operator=(const Thread&);
static  int             _threadLoop(void* user);
const   bool            mCanCallJava;
// always hold mLock when reading or writing
thread_id_t     mThread;
mutable Mutex           mLock;
Condition       mThreadExitedCondition;
status_t        mStatus;
// note that all accesses of mExitPending and mRunning need to hold mLock
volatile bool           mExitPending;
volatile bool           mRunning;
sp<Thread>      mHoldSelf;
#ifdef HAVE_ANDROID_OS
// legacy for debugging, not used by getTid() as it is set by the child thread
// and so is not initialized until the child reaches that point
pid_t           mTid;
#endif
};
PoolThread类继承自RefBase,说明可以用智能指针管理PoolThread。
]// sp<Thread> t = new PoolThread(isMain)
t->run(buf);
[// t->run(buf)
构造了PoolThread对象之外,就会调用run来启动线程,run函数其实是继承在Thread类的。
status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
Mutex::Autolock _l(mLock);

if (mRunning) {
// thread already started
return INVALID_OPERATION;
}

// reset status and exitPending to their default value, so we can
// try again after an error happened (either below, or in readyToRun())
mStatus = NO_ERROR;
mExitPending = false;
mThread = thread_id_t(-1);

// hold a strong reference on ourself
mHoldSelf = this;

mRunning = true;

bool res;
if (mCanCallJava) {
res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread);
[// res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread)
这里调用createThreadEtc函数,createThreadEtc函数是在哪定义的呢?我找不到啊!!!!!!
我猜想是创建一个线程,并且调用_threadLoop函数。
_threadLoop函数是定义在Thread类中:
int Thread::_threadLoop(void* user)
{
Thread* const self = static_cast<Thread*>(user);

sp<Thread> strong(self->mHoldSelf);
wp<Thread> weak(strong);
self->mHoldSelf.clear();

#ifdef HAVE_ANDROID_OS
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif

bool first = true;

do {
bool result;
if (first) {
first = false;
self->mStatus = self->readyToRun();
[// self->mStatus = self->readyToRun()
如果线程第一次启动, 则会调用readyToRun函数. readyToRun函数的实现如下:
status_t Thread::readyToRun()
                                                        {
                                                            return NO_ERROR;
                                                        }
                                                        readyToRun函数一般是由子类去重写的.
]// self->mStatus = self->readyToRun()
result = (self->mStatus == NO_ERROR);

if (result && !self->exitPending()) {
// Binder threads (and maybe others) rely on threadLoop
// running at least once after a successful ::readyToRun()
// (unless, of course, the thread has already been asked to exit
// at that point).
// This is because threads are essentially used like this:
//   (new ThreadSubclass())->run();
// The caller therefore does not retain a strong reference to
// the thread and the thread would simply disappear after the
// successful ::readyToRun() call instead of entering the
// threadLoop at least once.
result = self->threadLoop();
[// result = self->threadLoop()
调用完readyToRun之后,就会调用threadLoop函数.
threadLoop函数是个虚函数,其实这里调用的是PoolThread类的threadLoop函数.
]// result = self->threadLoop()
}
} else {
result = self->threadLoop();
}

// establish a scope for mLock
{
Mutex::Autolock _l(self->mLock);
if (result == false || self->mExitPending) {
self->mExitPending = true;
self->mRunning = false;
// clear thread ID so that requestExitAndWait() does not exit if
// called by a new thread using the same thread ID as this one.
self->mThread = thread_id_t(-1);
// note that interested observers blocked in requestExitAndWait are
// awoken by broadcast, but blocked on mLock until break exits scope
self->mThreadExitedCondition.broadcast();
break;
}
}

// Release our strong reference, to let a chance to the thread
// to die a peaceful death.
strong.clear();
// And immediately, re-acquire a strong reference for the next loop
strong = weak.promote();
} while(strong != 0);
[// while(strong != 0)
可以看出,在创建的线程里会陷入一个死循环中去。
WARNNING : ProcessState的_threadLoop有一个死循环
]// while(strong != 0)

return 0;
}
]// res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread)
} else {
res = androidCreateRawThreadEtc(_threadLoop, this, name, priority, stack, &mThread);
}

if (res == false) {
mStatus = UNKNOWN_ERROR;   // something happened!
mRunning = false;
mThread = thread_id_t(-1);
mHoldSelf.clear();  // "this" may have gone away after this.

return UNKNOWN_ERROR;
}

// Do not refer to mStatus here: The thread is already running (may, in fact
// already have exited with a valid mStatus result). The NO_ERROR indication
// here merely indicates successfully starting the thread and does not
// imply successful termination/execution.
return NO_ERROR;

// Exiting scope of mLock is a memory barrier and allows new thread to run
}
]// t->run(buf)
}
}
]// spawnPooledThread(true)
}
[// if (!mThreadPoolStarted)
如果还没有启动过,则会调用spawnPooledThread来启动Binder库的线程来负责与Binder驱动交互,并且将mThreadPoolStarted设置为true,表示已经启动过了。
]// if (!mThreadPoolStarted)
}

分析完ProcessState的设计, 我们开始分析IPCThreadState的设计和实现.
我们先看一下IPCThreadState类的声明:
class IPCThreadState
    {
    public:
        static  IPCThreadState*     self();
        static  IPCThreadState*     selfOrNull();  // self(), but won't instantiate

                sp<ProcessState>    process();

                status_t            clearLastError();

                pid_t               getCallingPid() const;
                uid_t               getCallingUid() const;

                void                setStrictModePolicy(int32_t policy);
                int32_t             getStrictModePolicy() const;

                void                setLastTransactionBinderFlags(int32_t flags);
                int32_t             getLastTransactionBinderFlags() const;

                int64_t             clearCallingIdentity();
                void                restoreCallingIdentity(int64_t token);

                int                 setupPolling(int* fd);
                status_t            handlePolledCommands();
                void                flushCommands();

                void                joinThreadPool(bool isMain = true);

                // Stop the local process.
                void                stopProcess(bool immediate = true);

                status_t            transact(int32_t handle,
                                             uint32_t code, const Parcel& data,
                                             Parcel* reply, uint32_t flags);

                void                incStrongHandle(int32_t handle);
                void                decStrongHandle(int32_t handle);
                void                incWeakHandle(int32_t handle);
                void                decWeakHandle(int32_t handle);
                status_t            attemptIncStrongHandle(int32_t handle);
        static  void                expungeHandle(int32_t handle, IBinder* binder);
                status_t            requestDeathNotification(   int32_t handle,
                                                                BpBinder* proxy);
                status_t            clearDeathNotification( int32_t handle,
                                                            BpBinder* proxy);

        static  void                shutdown();

        // Call this to disable switching threads to background scheduling when
        // receiving incoming IPC calls.  This is specifically here for the
        // Android system process, since it expects to have background apps calling
        // in to it but doesn't want to acquire locks in its services while in
        // the background.
        static  void                disableBackgroundScheduling(bool disable);

    private:
                                    IPCThreadState();
                                    ~IPCThreadState();

                status_t            sendReply(const Parcel& reply, uint32_t flags);
                status_t            waitForResponse(Parcel *reply,
                                                    status_t *acquireResult=NULL);
                status_t            talkWithDriver(bool doReceive=true);
                status_t            writeTransactionData(int32_t cmd,
                                                         uint32_t binderFlags,
                                                         int32_t handle,
                                                         uint32_t code,
                                                         const Parcel& data,
                                                         status_t* statusBuffer);
                status_t            getAndExecuteCommand();
                status_t            executeCommand(int32_t command);
                void                processPendingDerefs();

                void                clearCaller();

        static  void                threadDestructor(void *st);
        static  void                freeBuffer(Parcel* parcel,
                                               const uint8_t* data, size_t dataSize,
                                               const binder_size_t* objects, size_t objectsSize,
                                               void* cookie);

        const   sp<ProcessState>    mProcess;
        [// const   sp<ProcessState>    mProcess
        mProcess保存宿主进程
        ]// const   sp<ProcessState>    mProcess
        const   pid_t               mMyThreadId;
                Vector<BBinder*>    mPendingStrongDerefs;
                Vector<RefBase::weakref_type*> mPendingWeakDerefs;

                Parcel              mIn;
                Parcel              mOut;
                [// Parcel              mOut
                这里mIn和mOut是为了保存传输数据.
                mIn和mOut都是Parcel类型的, Parcel类的声明如下:
class Parcel
{
public:
class ReadableBlob;
class WritableBlob;

Parcel();
~Parcel();

const uint8_t*      data() const;
size_t              dataSize() const;
size_t              dataAvail() const;
size_t              dataPosition() const;
size_t              dataCapacity() const;

status_t            setDataSize(size_t size);
void                setDataPosition(size_t pos) const;
status_t            setDataCapacity(size_t size);

status_t            setData(const uint8_t* buffer, size_t len);

status_t            appendFrom(const Parcel *parcel,
   size_t start, size_t len);

bool                pushAllowFds(bool allowFds);
void                restoreAllowFds(bool lastValue);

bool                hasFileDescriptors() const;

// Writes the RPC header.
status_t            writeInterfaceToken(const String16& interface);

// Parses the RPC header, returning true if the interface name
// in the header matches the expected interface from the caller.
//
// Additionally, enforceInterface does part of the work of
// propagating the StrictMode policy mask, populating the current
// IPCThreadState, which as an optimization may optionally be
// passed in.
bool                enforceInterface(const String16& interface,
IPCThreadState* threadState = NULL) const;
bool                checkInterface(IBinder*) const;

void                freeData();

const size_t*       objects() const;
size_t              objectsCount() const;

status_t            errorCheck() const;
void                setError(status_t err);

status_t            write(const void* data, size_t len);
void*               writeInplace(size_t len);
status_t            writeUnpadded(const void* data, size_t len);
status_t            writeInt32(int32_t val);
status_t            writeInt64(int64_t val);
status_t            writeFloat(float val);
status_t            writeDouble(double val);
status_t            writeIntPtr(intptr_t val);
status_t            writeCString(const char* str);
status_t            writeString8(const String8& str);
status_t            writeString16(const String16& str);
status_t            writeString16(const char16_t* str, size_t len);
status_t            writeStrongBinder(const sp<IBinder>& val);
status_t            writeWeakBinder(const wp<IBinder>& val);
status_t            write(const Flattenable& val);

template<typename T>
status_t            write(const LightFlattenable<T>& val);


// Place a native_handle into the parcel (the native_handle's file-
// descriptors are dup'ed, so it is safe to delete the native_handle
// when this function returns).
// Doesn't take ownership of the native_handle.
status_t            writeNativeHandle(const native_handle* handle);

// Place a file descriptor into the parcel.  The given fd must remain
// valid for the lifetime of the parcel.
// The Parcel does not take ownership of the given fd unless you ask it to.
status_t            writeFileDescriptor(int fd, bool takeOwnership = false);

// Place a file descriptor into the parcel.  A dup of the fd is made, which
// will be closed once the parcel is destroyed.
status_t            writeDupFileDescriptor(int fd);

// Writes a blob to the parcel.
// If the blob is small, then it is stored in-place, otherwise it is
// transferred by way of an anonymous shared memory region.
// The caller should call release() on the blob after writing its contents.
status_t            writeBlob(size_t len, WritableBlob* outBlob);

status_t            writeObject(const flat_binder_object& val, bool nullMetaData);

// Like Parcel.java's writeNoException().  Just writes a zero int32.
// Currently the native implementation doesn't do any of the StrictMode
// stack gathering and serialization that the Java implementation does.
status_t            writeNoException();

void                remove(size_t start, size_t amt);

status_t            read(void* outData, size_t len) const;
const void*         readInplace(size_t len) const;
int32_t             readInt32() const;
status_t            readInt32(int32_t *pArg) const;
int64_t             readInt64() const;
status_t            readInt64(int64_t *pArg) const;
float               readFloat() const;
status_t            readFloat(float *pArg) const;
double              readDouble() const;
status_t            readDouble(double *pArg) const;
intptr_t            readIntPtr() const;
status_t            readIntPtr(intptr_t *pArg) const;

const char*         readCString() const;
String8             readString8() const;
String16            readString16() const;
const char16_t*     readString16Inplace(size_t* outLen) const;
sp<IBinder>         readStrongBinder() const;
wp<IBinder>         readWeakBinder() const;
status_t            read(Flattenable& val) const;

template<typename T>
status_t            read(LightFlattenable<T>& val) const;

// Like Parcel.java's readExceptionCode().  Reads the first int32
// off of a Parcel's header, returning 0 or the negative error
// code on exceptions, but also deals with skipping over rich
// response headers.  Callers should use this to read & parse the
// response headers rather than doing it by hand.
int32_t             readExceptionCode() const;

// Retrieve native_handle from the parcel. This returns a copy of the
// parcel's native_handle (the caller takes ownership). The caller
// must free the native_handle with native_handle_close() and
// native_handle_delete().
native_handle*     readNativeHandle() const;


// Retrieve a file descriptor from the parcel.  This returns the raw fd
// in the parcel, which you do not own -- use dup() to get your own copy.
int                 readFileDescriptor() const;

// Reads a blob from the parcel.
// The caller should call release() on the blob after reading its contents.
status_t            readBlob(size_t len, ReadableBlob* outBlob) const;

const flat_binder_object* readObject(bool nullMetaData) const;

// Explicitly close all file descriptors in the parcel.
void                closeFileDescriptors();

typedef void        (*release_func)(Parcel* parcel,
const uint8_t* data, size_t dataSize,
const size_t* objects, size_t objectsSize,
void* cookie);

const uint8_t*      ipcData() const;
size_t              ipcDataSize() const;
const size_t*       ipcObjects() const;
size_t              ipcObjectsCount() const;
void                ipcSetDataReference(const uint8_t* data, size_t dataSize,
const size_t* objects, size_t objectsCount,
release_func relFunc, void* relCookie);

void                print(TextOutput& to, uint32_t flags = 0) const;

private:
Parcel(const Parcel& o);
Parcel&             operator=(const Parcel& o);

status_t            finishWrite(size_t len);
void                releaseObjects();
void                acquireObjects();
status_t            growData(size_t len);
status_t            restartWrite(size_t desired);
status_t            continueWrite(size_t desired);
void                freeDataNoInit();
void                initState();
void                scanForFds() const;

template<class T>
status_t            readAligned(T *pArg) const;

template<class T>   T readAligned() const;

template<class T>
status_t            writeAligned(T val);

status_t            mError;
uint8_t*            mData;
[// uint8_t*            mData
mData指向保存数据的数组
]// uint8_t*            mData
size_t              mDataSize;
[// size_t              mDataSize
mDataSize表示现有保存数据的大小
]// size_t              mDataSize
size_t              mDataCapacity;
[// size_t              mDataCapacity
mDataCapacity表示可以保存数据的容量
]// size_t              mDataCapacity
mutable size_t      mDataPos;
[// mutable size_t      mDataPos
mDataPos现在保存数据的末尾
]// mutable size_t      mDataPos
size_t*             mObjects;
size_t              mObjectsSize;
size_t              mObjectsCapacity;
mutable size_t      mNextObjectHint;

mutable bool        mFdsKnown;
mutable bool        mHasFds;
bool                mAllowFds;

release_func        mOwner;
void*               mOwnerCookie;

class Blob {
public:
Blob();
~Blob();

void release();
inline size_t size() const { return mSize; }

protected:
void init(bool mapped, void* data, size_t size);
void clear();

bool mMapped;
void* mData;
size_t mSize;
};

public:
class ReadableBlob : public Blob {
friend class Parcel;
public:
inline const void* data() const { return mData; }
};

class WritableBlob : public Blob {
friend class Parcel;
public:
inline void* data() { return mData; }
};
};


在这里我们就看一下Parcel的构造函数的实现:
                Parcel::Parcel()
                    {
                        LOG_ALLOC("Parcel %p: constructing", this);
                        initState();
                        [
                        这里会调用initState函数来初始化状态.
                        void Parcel::initState()
                            {
                                LOG_ALLOC("Parcel %p: initState", this);
                                mError = NO_ERROR;
                                mData = 0;
                                mDataSize = 0;
                                mDataCapacity = 0;
                                mDataPos = 0;
                                ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
                                ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
                                mObjects = NULL;
                                mObjectsSize = 0;
                                mObjectsCapacity = 0;
                                mNextObjectHint = 0;
                                mHasFds = false;
                                mFdsKnown = true;
                                mAllowFds = true;
                                mOwner = NULL;
                            }
                        ]
                    }
                ]// Parcel              mOut
                status_t            mLastError;
                pid_t               mCallingPid;
                uid_t               mCallingUid;
                int32_t             mStrictModePolicy;
                int32_t             mLastTransactionBinderFlags;
    };
和ProcessState类一样,我们也从IPCThreadState的self函数开始分析:
IPCThreadState* IPCThreadState::self()
    {
        if (gHaveTLS) {
    restart:
            const pthread_key_t k = gTLS;
            IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
            if (st) return st;
            return new IPCThreadState;
            [// return new IPCThreadState
            这里会调用IPCThreadState的构造函数来创建一个IPCThreadState对象.
            IPCThreadState的构造函数如下:
            IPCThreadState::IPCThreadState()
                    : mProcess(ProcessState::self()),
                    [// mProcess(ProcessState::self())
                    这里保存宿主进程
                    ]// mProcess(ProcessState::self())
                      mMyThreadId(gettid()),
                      mStrictModePolicy(0),
                      mLastTransactionBinderFlags(0)
                {
                    pthread_setspecific(gTLS, this);
                    [// pthread_setspecific(gTLS, this)
                    这里会将创建的IPCThreadState对象设置到ThreadLocal中去.
                    ]// pthread_setspecific(gTLS, this)
                    clearCaller();
                    mIn.setDataCapacity(256);
                    [// mIn.setDataCapacity(256)
在构造函数中,首先调用setDataCapacity函数, setDataCapacity函数的定义如下:
status_t Parcel::setDataCapacity(size_t size)
                        {
                            if (size > mDataCapacity) return continueWrite(size);
                            [// if (size > mDataCapacity) return continueWrite(size)
mDataCapacity保存了当前数据缓冲区的容量, 初始值为0.
所有这里调用continueWrite函数来设置缓冲区的大小
status_t Parcel::continueWrite(size_t desired)
                                {
                                    // If shrinking, first adjust for any objects that appear
                                    // after the new data size.
                                    size_t objectsSize = mObjectsSize;
                                    [// size_t objectsSize = mObjectsSize
                                    成员变量mObjectsSize表示数据缓冲区中Binder对象数组的大小, mObjectsSize的定义如下:
                                    size_t              mObjectsSize;
                                    ]// size_t objectsSize = mObjectsSize
                                    if (desired < mDataSize) {
                                        if (desired == 0) {
                                            objectsSize = 0;
                                        } else {
                                            while (objectsSize > 0) {
                                                if (mObjects[objectsSize-1] < desired)
                                                    break;
                                                objectsSize--;
                                            }
                                        }
                                    }
                                    [// if (desired < mDataSize)
这里desired表示目标大小, mDataSize表示当前数据的大小.
如果desired < mDataSize,则表示要缩减数据缓冲区的大小.
这时候,如果desired值为0, 则简单的将objectsSize值设置为0, 否则则从后向前删除Binder对象数组的个数.
                                    ]// if (desired < mDataSize)

                                    if (mOwner) {
                                    [// if (mOwner)
                                    成员变量mOwner是个函数指针, 定义如下:
                                    release_func        mOwner;
                                    release_func声明如下:
                                    typedef void        (*release_func)(Parcel* parcel,
                                                                                const uint8_t* data, size_t dataSize,
                                                                                const binder_size_t* objects, size_t objectsSize,
                                                                                void* cookie);
                                    ]// if (mOwner)
                                        // If the size is going to zero, just release the owner's data.
                                        if (desired == 0) {
                                            freeData();
                                            return NO_ERROR;
                                        }

                                        // If there is a different owner, we need to take
                                        // posession.
                                        uint8_t* data = (uint8_t*)malloc(desired);
                                        if (!data) {
                                            mError = NO_MEMORY;
                                            return NO_MEMORY;
                                        }
                                        binder_size_t* objects = NULL;

                                        if (objectsSize) {
                                            objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
                                            if (!objects) {
                                                free(data);

                                                mError = NO_MEMORY;
                                                return NO_MEMORY;
                                            }

                                            // Little hack to only acquire references on objects
                                            // we will be keeping.
                                            size_t oldObjectsSize = mObjectsSize;
                                            mObjectsSize = objectsSize;
                                            acquireObjects();
                                            mObjectsSize = oldObjectsSize;
                                        }

                                        if (mData) {
                                            memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
                                        }
                                        if (objects && mObjects) {
                                            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
                                        }
                                        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
                                        mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
                                        mOwner = NULL;

                                        LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
                                        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                                        gParcelGlobalAllocSize += desired;
                                        gParcelGlobalAllocCount++;
                                        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);

                                        mData = data;
                                        mObjects = objects;
                                        mDataSize = (mDataSize < desired) ? mDataSize : desired;
                                        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
                                        mDataCapacity = desired;
                                        mObjectsSize = mObjectsCapacity = objectsSize;
                                        mNextObjectHint = 0;

                                    } else if (mData) {
                                        if (objectsSize < mObjectsSize) {
                                            // Need to release refs on any objects we are dropping.
                                            const sp<ProcessState> proc(ProcessState::self());
                                            for (size_t i=objectsSize; i<mObjectsSize; i++) {
                                                const flat_binder_object* flat
                                                    = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
                                                if (flat->type == BINDER_TYPE_FD) {
                                                    // will need to rescan because we may have lopped off the only FDs
                                                    mFdsKnown = false;
                                                }
                                                release_object(proc, *flat, this);
                                            }
                                            binder_size_t* objects =
                                                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
                                            if (objects) {
                                                mObjects = objects;
                                            }
                                            mObjectsSize = objectsSize;
                                            mNextObjectHint = 0;
                                        }

                                        // We own the data, so we can just do a realloc().
                                        if (desired > mDataCapacity) {
                                            uint8_t* data = (uint8_t*)realloc(mData, desired);
                                            if (data) {
                                                LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
                                                        desired);
                                                pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                                                gParcelGlobalAllocSize += desired;
                                                gParcelGlobalAllocSize -= mDataCapacity;
                                                pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
                                                mData = data;
                                                mDataCapacity = desired;
                                            } else if (desired > mDataCapacity) {
                                                mError = NO_MEMORY;
                                                return NO_MEMORY;
                                            }
                                        } else {
                                            if (mDataSize > desired) {
                                                mDataSize = desired;
                                                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
                                            }
                                            if (mDataPos > desired) {
                                                mDataPos = desired;
                                                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
                                            }
                                        }

                                    } else {
                                        // This is the first data.  Easy!
                                        uint8_t* data = (uint8_t*)malloc(desired);
[// uint8_t* data = (uint8_t*)malloc(desired)
这里会申请一段内存,大小为desired字节
]// uint8_t* data = (uint8_t*)malloc(desired)
                                        if (!data) {
                                            mError = NO_MEMORY;
                                            return NO_MEMORY;
                                        }

                                        if(!(mDataCapacity == 0 && mObjects == NULL
                                             && mObjectsCapacity == 0)) {
                                            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
                                        }

                                        LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
                                        pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
                                        gParcelGlobalAllocSize += desired;
                                        gParcelGlobalAllocCount++;
                                        pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);

                                        mData = data;
                                        mDataSize = mDataPos = 0;
                                        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
                                        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
                                        mDataCapacity = desired;
                                    }

                                    return NO_ERROR;
                                }

                            ]// if (size > mDataCapacity) return continueWrite(size)
                            return NO_ERROR;
                        }
                    ]// mIn.setDataCapacity(256)
                    mOut.setDataCapacity(256);
                }
            ]// return new IPCThreadState
        }

        if (gShutdown) return NULL;

        pthread_mutex_lock(&gTLSMutex);
        if (!gHaveTLS) {
            if (pthread_key_create(&gTLS, threadDestructor) != 0) {
                pthread_mutex_unlock(&gTLSMutex);
                return NULL;
            }
            gHaveTLS = true;
        }
        pthread_mutex_unlock(&gTLSMutex);
        goto restart;
    }
    [// IPCThreadState* IPCThreadState::self()
    从IPCThreadState的self函数中可以看出, IPCThreadState也是单例的, 是用ThreadLocal做的.
    ]// IPCThreadState* IPCThreadState::self()

    调用完IPCThreadState的self函数得到一个全局的IPCThreadState对象之后,就可以调用joinThreadPool函数.
    joinThreadPool函数的定义如下:
    void IPCThreadState::joinThreadPool(bool isMain)
    [// void IPCThreadState::joinThreadPool(bool isMain)
    joinThreadPool函数有一个参数isMain, 其实默认参数为true;
    ]// void IPCThreadState::joinThreadPool(bool isMain)
    {
        LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

        mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
        [// mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER)
        这里首先发一个BC_ENTER_LOOPER来使得Binder线程池可用.
我们看一下Parcel的writeInt32函数的实现:
status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
[// return writeAligned(val)
writeInt32调用writeAligned函数,writeAligned函数的定义如下:
template<class T> status_t Parcel::writeAligned(T val) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));

if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
*reinterpret_cast<T*>(mData+mDataPos) = val;
[// *reinterpret_cast<T*>(mData+mDataPos) = val
这里将数据写入到数据的末尾
]// *reinterpret_cast<T*>(mData+mDataPos) = val
return finishWrite(sizeof(val));
[// return finishWrite(sizeof(val))
写入完数据后,会调用finishWrite函数来更新长度信息,传入的参数就是刚刚写入的数据的长度
status_t Parcel::finishWrite(size_t len)
{
//printf("Finish write of %d\n", len);
mDataPos += len;
[// mDataPos += len
更新数据的位置信息
]// mDataPos += len
ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
if (mDataPos > mDataSize) {
mDataSize = mDataPos;
[// mDataSize = mDataPos
如果需要,更新现有数据的大小
]// mDataSize = mDataPos
ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
}
//printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
return NO_ERROR;
}
]// return finishWrite(sizeof(val))
}
[// if ((mDataPos+sizeof(val)) <= mDataCapacity)
这里(mDataPos+sizeof(val)) <= mDataCapacity表示剩余容量可以写入数据。
]// if ((mDataPos+sizeof(val)) <= mDataCapacity)

status_t err = growData(sizeof(val));
[// status_t err = growData(sizeof(val))
如果mDataPos+sizeof(val)) > mDataCapacity,则说明现在的容量已经不够写入数据了,则调用growData函数来增加容量。
growData函数的定义如下:
status_t Parcel::growData(size_t len)
{
size_t newSize = ((mDataSize+len)*3)/2;
[// size_t newSize = ((mDataSize+len)*3)/2
这里保存新容量
]// size_t newSize = ((mDataSize+len)*3)/2
return (newSize <= mDataSize)
? (status_t) NO_MEMORY
: continueWrite(newSize);
[// return (newSize <= mDataSize)
这里会调用continueWrite来重新申请容量了。
]// return (newSize <= mDataSize)
}
]// status_t err = growData(sizeof(val))
if (err == NO_ERROR) goto restart_write;
return err;
}
]// return writeAligned(val)
}
        ]// mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER)

        // This thread may have been spawned by a thread that was in the background
        // scheduling group, so first we will make sure it is in the foreground
        // one to avoid performing an initial transaction in the background.
        set_sched_policy(mMyThreadId, SP_FOREGROUND);

        status_t result;
        do {
            processPendingDerefs();
            [// processPendingDerefs()
进入循环之后, 首先调用processPendingDerefs函数, processPendingDerefs函数其实是为了延缓执行减少强弱智能指针.
void IPCThreadState::processPendingDerefs()
                {
                    if (mIn.dataPosition() >= mIn.dataSize()) {
                        size_t numPending = mPendingWeakDerefs.size();
                        if (numPending > 0) {
                            for (size_t i = 0; i < numPending; i++) {
                                RefBase::weakref_type* refs = mPendingWeakDerefs[i];
                                refs->decWeak(mProcess.get());
                            }
                            mPendingWeakDerefs.clear();
                        }

                        numPending = mPendingStrongDerefs.size();
                        if (numPending > 0) {
                            for (size_t i = 0; i < numPending; i++) {
                                BBinder* obj = mPendingStrongDerefs[i];
                                obj->decStrong(mProcess.get());
                            }
                            mPendingStrongDerefs.clear();
                        }
                    }
                }
            ]// processPendingDerefs()
            // now get the next command to be processed, waiting if necessary
            result = getAndExecuteCommand();
            [// result = getAndExecuteCommand()
这里调用getAndExecuteCommand函数来和Binder驱动进行交互.
status_t IPCThreadState::getAndExecuteCommand()
                {
                    status_t result;
                    int32_t cmd;

                    result = talkWithDriver();
                    [// result = talkWithDriver()
                    talkWithDriver函数的作用是发送命令给Binder驱动程序.
                    status_t IPCThreadState::talkWithDriver(bool doReceive)
                    [// status_t IPCThreadState::talkWithDriver(bool doReceive)
talkWithDriver的参数doReceive有一个默认参数true
                    ]// status_t IPCThreadState::talkWithDriver(bool doReceive)
                        {
                            if (mProcess->mDriverFD <= 0) {
                                return -EBADF;
                            }
                            [// if (mProcess->mDriverFD <= 0)
这里的mDriverFD保存的就是打开的/dev/binder的文件描述符, 和Binder驱动程序交互就是通过它
                            ]// if (mProcess->mDriverFD <= 0)

                            binder_write_read bwr;

                            // Is the read buffer empty?
                            const bool needRead = mIn.dataPosition() >= mIn.dataSize();
[// const bool needRead = mIn.dataPosition() >= mIn.dataSize()
Parcel类的dataPosition函数定义如下:
size_t Parcel::dataPosition() const
{
return mDataPos;
}
Parcel类的dataSize函数定义如下:
size_t Parcel::dataSize() const
{
return (mDataSize > mDataPos ? mDataSize : mDataPos);
}
可以看出dataSize返回的是真正的数据的大小。
这里needRead其实是表示是否还要从Binder驱动读取数据。
如果mIn.dataPosition() < mIn.dataSize(),则说明mIn还有数据没读完。
]// 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;
[// const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0
这里是判读是否输出数据给Binder驱动处理,条件就是doReceive为false或者needRead为true。
为什么doReceive要为false呢?doReceive默认参数为true啊。
如果needRead为false,则说明还有数据没读完了,因此就不要再给Binder发数据了。
]// const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0

                            bwr.write_size = outAvail;
                            bwr.write_buffer = (uintptr_t)mOut.data();
[// bwr.write_buffer = (uintptr_t)mOut.data()
这里将输出数据的大小和数据准备好
]// bwr.write_buffer = (uintptr_t)mOut.data()

                            // This is what we'll read.
                            if (doReceive && needRead) {
                                bwr.read_size = mIn.dataCapacity();
                                bwr.read_buffer = (uintptr_t)mIn.data();
                            } else {
                                bwr.read_size = 0;
                                bwr.read_buffer = 0;
                            }
[// if (doReceive && needRead)
这里是准备读取的。如果needRead为true,则将读取的数据位置设置为mIn的数据缓冲区,大小为mIn的容量。
]// if (doReceive && needRead)

                            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;
[// if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR
这里如果读和写都为0,则不需要读和写,那直接返回吧。
]// if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR

                            bwr.write_consumed = 0;
                            bwr.read_consumed = 0;
[// bwr.read_consumed = 0
上面这两句代码,是为了在与Binder驱动程序交互前,将读和写的消耗设置为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)
                                [// if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
                                这里通过ioctl函数, 将命令发送给Binder驱动, 并取回Binder驱动发送过来的命令
                                ]// if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
                                    err = NO_ERROR;
                                else
                                    err = -errno;
                        #else
                                err = INVALID_OPERATION;
                        #endif
                                if (mProcess->mDriverFD <= 0) {
                                    err = -EBADF;
                                }
                                IF_LOG_COMMANDS() {
                                    alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
                                }
                            } while (err == -EINTR);

                            IF_LOG_COMMANDS() {
                                alog << "Our err: " << (void*)(intptr_t)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 > 0)
如果bwr.write_consumed > 0,则说明Binder驱动已经消耗了Binder库发送给Binder驱动的命令。
]// if (bwr.write_consumed > 0)
                                    if (bwr.write_consumed < mOut.dataSize())
[// if (bwr.write_consumed < mOut.dataSize())
如果bwr.write_consumed < mOut.dataSize(),则说明没有完全消耗完发送给Binder驱动的命令
]// if (bwr.write_consumed < mOut.dataSize())
                                        mOut.remove(0, bwr.write_consumed);
[// mOut.remove(0, bwr.write_consumed)
调用remove函数来删除部门数据,我们看一下remove函数的实现
void Parcel::remove(size_t start, size_t amt)
{
LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
}
我插!remove函数居然啥也没实现。
]// mOut.remove(0, bwr.write_consumed)
                                    else
                                        mOut.setDataSize(0);
[// mOut.setDataSize(0)
调用setDataSize(0)就相当于将数据都删除。
setDataSize的函数实现如下:
status_t Parcel::setDataSize(size_t size)
{
status_t err;
err = continueWrite(size);
if (err == NO_ERROR) {
mDataSize = size;
ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
}
return err;
}
]// mOut.setDataSize(0)
                                }

                                if (bwr.read_consumed > 0) {
[// if (bwr.read_consumed > 0)
如果bwr.read_consumed > 0, 则说明Binder驱动有返回。这时候就需要读取从Binder驱动返回的命令。
]// if (bwr.read_consumed > 0)
                                    mIn.setDataSize(bwr.read_consumed);
[// mIn.setDataSize(bwr.read_consumed)
这里将mIn的数据大小设置为read_consumed,
]// mIn.setDataSize(bwr.read_consumed)
                                    mIn.setDataPosition(0);
[// mIn.setDataPosition(0)
调用setDataPosition(0)函数,将数据的位置设置为0,指向数据的开头。
]// 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;
                        }
                    ]// result = talkWithDriver()
                    if (result >= NO_ERROR) {
                        size_t IN = mIn.dataAvail();
                        if (IN < sizeof(int32_t)) return result;
                        cmd = mIn.readInt32();
                        [// cmd = mIn.readInt32()
                        这里取回从Binder驱动程序返回的命令.
                        但是,这里为什么只取一个????????
readInt32函数的定义如下:

int32_t Parcel::readInt32() const
{
return readAligned<int32_t>();
[// return readAligned<int32_t>()
template<class T> T Parcel::readAligned() const {
T result;
if (readAligned(&result) != NO_ERROR) {
[// if (readAligned(&result) != NO_ERROR)
readAligned函数的定义如下:
template<class T> status_t Parcel::readAligned(T *pArg) const {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(T)) <= mDataSize) {
const void* data = mData+mDataPos;
mDataPos += sizeof(T);
*pArg =  *reinterpret_cast<const T*>(data);
return NO_ERROR;
} else {
return NOT_ENOUGH_DATA;
}
}
由readAligned函数的定义可以看出,readAligned函数的实现还是很简单的,就是将数据取出,并更新mDataPos,使其指向下一个数据的位置。
]// if (readAligned(&result) != NO_ERROR)
result = 0;
}

return result;
}
]// return readAligned<int32_t>()
}
                        ]// cmd = mIn.readInt32()
                        IF_LOG_COMMANDS() {
                            alog << "Processing top-level Command: "
                                 << getReturnString(cmd) << endl;
                        }

                        result = executeCommand(cmd);
                        [// result = executeCommand(cmd)
这里调用executeCommand来执行从Binder驱动程序返回的命令.
executeCommand函数的实现如下:
status_t IPCThreadState::executeCommand(int32_t cmd)
                            {
                                BBinder* obj;
                                RefBase::weakref_type* refs;
                                status_t result = NO_ERROR;

                                switch ((uint32_t)cmd) {
                                case BR_ERROR:
                                    result = mIn.readInt32();
                                    break;

                                case BR_OK:
                                    break;

                                case BR_ACQUIRE:
                                    refs = (RefBase::weakref_type*)mIn.readPointer();
                                    obj = (BBinder*)mIn.readPointer();
                                    ALOG_ASSERT(refs->refBase() == obj,
                                               "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
                                               refs, obj, refs->refBase());
                                    obj->incStrong(mProcess.get());
                                    IF_LOG_REMOTEREFS() {
                                        LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
                                        obj->printRefs();
                                    }
                                    mOut.writeInt32(BC_ACQUIRE_DONE);
                                    mOut.writePointer((uintptr_t)refs);
                                    mOut.writePointer((uintptr_t)obj);
                                    break;

                                case BR_RELEASE:
                                    refs = (RefBase::weakref_type*)mIn.readPointer();
                                    obj = (BBinder*)mIn.readPointer();
                                    ALOG_ASSERT(refs->refBase() == obj,
                                               "BR_RELEASE: object %p does not match cookie %p (expected %p)",
                                               refs, obj, refs->refBase());
                                    IF_LOG_REMOTEREFS() {
                                        LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
                                        obj->printRefs();
                                    }
                                    mPendingStrongDerefs.push(obj);
                                    break;

                                case BR_INCREFS:
                                    refs = (RefBase::weakref_type*)mIn.readPointer();
                                    obj = (BBinder*)mIn.readPointer();
                                    refs->incWeak(mProcess.get());
                                    mOut.writeInt32(BC_INCREFS_DONE);
                                    mOut.writePointer((uintptr_t)refs);
                                    mOut.writePointer((uintptr_t)obj);
                                    break;

                                case BR_DECREFS:
                                    refs = (RefBase::weakref_type*)mIn.readPointer();
                                    obj = (BBinder*)mIn.readPointer();
                                    // NOTE: This assertion is not valid, because the object may no
                                    // longer exist (thus the (BBinder*)cast above resulting in a different
                                    // memory address).
                                    //ALOG_ASSERT(refs->refBase() == obj,
                                    //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
                                    //           refs, obj, refs->refBase());
                                    mPendingWeakDerefs.push(refs);
                                    break;

                                case BR_ATTEMPT_ACQUIRE:
                                    refs = (RefBase::weakref_type*)mIn.readPointer();
                                    obj = (BBinder*)mIn.readPointer();

                                    {
                                        const bool success = refs->attemptIncStrong(mProcess.get());
                                        ALOG_ASSERT(success && refs->refBase() == obj,
                                                   "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
                                                   refs, obj, refs->refBase());

                                        mOut.writeInt32(BC_ACQUIRE_RESULT);
                                        mOut.writeInt32((int32_t)success);
                                    }
                                    break;

                                case BR_TRANSACTION:
                                    {
                                        binder_transaction_data tr;
                                        result = mIn.read(&tr, sizeof(tr));
                                        ALOG_ASSERT(result == NO_ERROR,
                                            "Not enough command data for brTRANSACTION");
                                        if (result != NO_ERROR) break;

                                        Parcel buffer;
                                        buffer.ipcSetDataReference(
                                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                                            tr.data_size,
                                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                                            tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);

                                        const pid_t origPid = mCallingPid;
                                        const uid_t origUid = mCallingUid;
                                        const int32_t origStrictModePolicy = mStrictModePolicy;
                                        const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;

                                        mCallingPid = tr.sender_pid;
                                        mCallingUid = tr.sender_euid;
                                        mLastTransactionBinderFlags = tr.flags;

                                        int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
                                        if (gDisableBackgroundScheduling) {
                                            if (curPrio > ANDROID_PRIORITY_NORMAL) {
                                                // We have inherited a reduced priority from the caller, but do not
                                                // want to run in that state in this process.  The driver set our
                                                // priority already (though not our scheduling class), so bounce
                                                // it back to the default before invoking the transaction.
                                                setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
                                            }
                                        } else {
                                            if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
                                                // We want to use the inherited priority from the caller.
                                                // Ensure this thread is in the background scheduling class,
                                                // since the driver won't modify scheduling classes for us.
                                                // The scheduling group is reset to default by the caller
                                                // once this method returns after the transaction is complete.
                                                set_sched_policy(mMyThreadId, SP_BACKGROUND);
                                            }
                                        }

                                        //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);

                                        Parcel reply;
                                        status_t error;
                                        IF_LOG_TRANSACTIONS() {
                                            TextOutput::Bundle _b(alog);
                                            alog << "BR_TRANSACTION thr " << (void*)pthread_self()
                                                << " / obj " << tr.target.ptr << " / code "
                                                << TypeCode(tr.code) << ": " << indent << buffer
                                                << dedent << endl
                                                << "Data addr = "
                                                << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
                                                << ", offsets addr="
                                                << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
                                        }
                                        if (tr.target.ptr) {
                                            sp<BBinder> b((BBinder*)tr.cookie);
                                            error = b->transact(tr.code, buffer, &reply, tr.flags);
[// error = b->transact(tr.code, buffer, &reply, tr.flags)
这里会调用BBinder的transact函数来传递命令,BBinder的transact函数定义如下
status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);

status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
[// err = onTransact(code, data, reply, flags)
调用onTransact来调用用户自定义的onTransact实现
]// err = onTransact(code, data, reply, flags)
break;
}

if (reply != NULL) {
reply->setDataPosition(0);
}

return err;
}
]// error = b->transact(tr.code, buffer, &reply, tr.flags)
                                        } else {
                                            error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                                        }

                                        //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
                                        //     mCallingPid, origPid, origUid);

                                        if ((tr.flags & TF_ONE_WAY) == 0) {
                                            LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                                            if (error < NO_ERROR) reply.setError(error);
                                            sendReply(reply, 0);
                                        } else {
                                            LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
                                        }

                                        mCallingPid = origPid;
                                        mCallingUid = origUid;
                                        mStrictModePolicy = origStrictModePolicy;
                                        mLastTransactionBinderFlags = origTransactionBinderFlags;

                                        IF_LOG_TRANSACTIONS() {
                                            TextOutput::Bundle _b(alog);
                                            alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                                                << tr.target.ptr << ": " << indent << reply << dedent << endl;
                                        }

                                    }
                                    break;

                                case BR_DEAD_BINDER:
                                    {
                                        BpBinder *proxy = (BpBinder*)mIn.readPointer();
                                        proxy->sendObituary();
                                        mOut.writeInt32(BC_DEAD_BINDER_DONE);
                                        mOut.writePointer((uintptr_t)proxy);
                                    } break;

                                case BR_CLEAR_DEATH_NOTIFICATION_DONE:
                                    {
                                        BpBinder *proxy = (BpBinder*)mIn.readPointer();
                                        proxy->getWeakRefs()->decWeak(proxy);
                                    } break;

                                case BR_FINISHED:
                                    result = TIMED_OUT;
                                    break;

                                case BR_NOOP:
                                    break;

                                case BR_SPAWN_LOOPER:
                                    mProcess->spawnPooledThread(false);
                                    break;

                                default:
                                    printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
                                    result = UNKNOWN_ERROR;
                                    break;
                                }

                                if (result != NO_ERROR) {
                                    mLastError = result;
                                }

                                return result;
                            }
                        ]// result = executeCommand(cmd)

                        // After executing the command, ensure that the thread is returned to the
                        // foreground cgroup before rejoining the pool.  The driver takes care of
                        // restoring the priority, but doesn't do anything with cgroups so we
                        // need to take care of that here in userspace.  Note that we do make
                        // sure to go in the foreground after executing a transaction, but
                        // there are other callbacks into user code that could have changed
                        // our group so we want to make absolutely sure it is put back.
                        set_sched_policy(mMyThreadId, SP_FOREGROUND);
                    }

                    return result;
                }
            ]// result = getAndExecuteCommand()

            if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
                ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting", mProcess->mDriverFD, result);
                abort();
            }

            // Let this thread exit the thread pool if it is no longer
            // needed and it is not the main process thread.
            if(result == TIMED_OUT && !isMain) {
                break;
            }
        } while (result != -ECONNREFUSED && result != -EBADF);
        [// while (result != -ECONNREFUSED && result != -EBADF)
        这里会进入一个死循环来处理与Binder驱动程序的交互.
        WARNNING : IPCThreadState的joinThreadPool有一个死循环.
        ]// while (result != -ECONNREFUSED && result != -EBADF)

        LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
            (void*)pthread_self(), getpid(), (void*)result);

        mOut.writeInt32(BC_EXIT_LOOPER);
        talkWithDriver(false);
        [// talkWithDriver(false)
如果程序运行到这里,则说明Binder库因为各种原因要退出了, 因此这里会发送一个BC_EXIT_LOOPER命令给Binder驱动程序.
        ]// talkWithDriver(false)
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics