native服务器端MediadrmServer服务

主要参考《深入理解 Android 卷I》邓必山,虽然基于的android版本有点旧,但是一本经得起细读的好书

实际上这里是一个完整的客户端(service)访问服务器端(servicemanager),再是服务器端(service)响应客户端(client)

原理大致如下图所示:实际上client和server属于是两个进程,binder_driver就类似于网络。他将两者沟通在了一起。

Mediadrmserver实际上android的DRM服务,以前以为是android启动的时候就一定会加载的,但是里面填加的log在启动时候并没有输出(不排除log丢失)实际上极有可能是错误的

参考前一篇博文,这些服务是在android启动之后才加载的。所有直接在system/bin下面去手动执行就OK,system/bin下面的都属于是可执行文件 ./文件名就可以启动该服务。

frameworks/av/services/mediadrm$ vi main_mediadrmserver.cpp

int main()
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    MediaDrmService::instantiate();
    ProcessState::self()->startThreadPool();//启动服务,执行完该函数之后,到下一步的时候直接没有输出相应的信息,在关机的时候或者是强制退出的时候也没有出来
    IPCThreadState::self()->joinThreadPool();
}
  • ProcessState是每个进程只有一个对象,所以直接是单例模式。在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个
    进程只有一个对象,这个对象负责打开Binder驱动,建立线程池,让其进程里面的所有线程都能通过Binder通信。
  • IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量。mProcess中,通过mProcess可以获得Binder的句柄。
  • IServiceManager类属于是抽象的接口,所有的Service都需要被servicemanager,IServiceManager的派生类中实现将service添加到servicemanager里面去,目测这个派生类是

 1、创建ProcessState实例

// 针对ProcessState定义的全局变量
Mutex gProcessMutex;
sp<ProcessState> gProcess;

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    //gProcess是在Static.cpp中定义的一个全局变量
    //程序刚开始执行,gProcess一定为空,在程序启动之后,因为进程一直运行,所以进程的ProcessState对象是一直都存在,所以最好不要在这里输出信息,不然卡死。
    if (gProcess != NULL) {
        return gProcess;
    }
    //创建一个ProcessState对象,并赋值给gProcess
    gProcess = new ProcessState;//为什么类后面不加上()呢?实际上C++new对象的时候是可以不加()的
    return gProcess;
}

 sp<ProcessState> proc(ProcessState::self());实际的执行结果为

sp<ProcessState> proc(gProcess) 等价于

ProcessState *gProcess = new ProcessState ;

ProcessState * proc = gProcess;

实际上这里引入了两个指针对象 proc和gProcess,他们都是指向的同一块内存。

ProcessState::self()返回了一个全局的指针gProcess,深入他的构造函数。

ProcessState::ProcessState()
    //Android中有很多代码都是这么写的,稍不留神就容易忽略这里调用了一个很重要的函数
    : mDriverFD(open_driver()) //int  mDriverFD;初始化为文件设备指针 
    , mVMStart(MAP_FAILED)//映射内存的起始地址void*               mVMStart;
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
   , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)//初始化为false,在启动线程池的时候有用到该变量
    , mThreadPoolSeq(1)
{   
    if (mDriverFD >= 0) {//打开文件成功
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        // mmap binder 提供一块虚拟地址空间来接收事务
        /*
        BIDNER_VM_SIZE定义为(1*1024*1024)-(4096*2)=1M-8K
        mmap的用法希望读者man一下,不过这个函数真正的实现和驱动有关系,而Binder驱动会分配一块内存来接收数据。实际上接收数据的binder驱动(所以感觉mVMStart没啥子用呢!),
也就是说这块空间实际上是在内核驱动中进行分配的,只是将他的虚拟地址映射过来了而已 */ mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);// mDriverFD实际上是打开的设备的文件描述符,那这块空间是如何使用的呢? if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } } LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); }

主要是两个事1、open /dev/binder   2、分配虚拟地址空间,其中mmap函数之前在file_operations这个结构体中有所接触,功能为将设备内存映射到进程相应的虚拟地址空间去。

实际上内核空间已经划分了很多分的缓冲区出来。因为不止一个进程!!!

open_driver,/dev/binder这个设备。

static int open_driver()
{
    // 它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备
    int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);// 打开文件失败返回-1
    if (fd >= 0) {
        int vers = 0;
        
        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) {//ioctl中返回0是指的什么呢?应该是查询失败了,成功了才不为0
            ALOGE("Binder driver protocol does not match user space protocol!");
            close(fd);
            fd = -1;
        }
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        //通过ioctl方式告诉binder驱动,这个fd支持的最大线程数,一般是15个
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
            // 这里不close(fd);和fd=-1;???
        }
    } else {
        ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
    }
    return fd;
}

 2、创建IServiceManager对象

IserviceManager对象是通过defaultServiceManager函数生成的,defaultServiceManager这个函数是定义在命名空间android内的函数,所以可以直接使用,具体的实现在IServiceManager.cpp中。

和上面的gProcess一样,属于在static.cpp文件中定义的全局变量

// ------------ IServiceManager.cpp

Mutex gDefaultServiceManagerLock;
sp<IServiceManager> gDefaultServiceManager;
sp<IPermissionController> gPermissionController;

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) 
        return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock); //全局的锁
        while (gDefaultServiceManager == NULL) {
            //真正的gDefaultServiceManager是在这里创建的
            gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

sp<IServiceManager> sm = defaultServiceManager();

等价于:sp<IServiceManager> sm = gDefaultServiceManager;

IServiceManager *sm =  gDefaultServiceManager 这属于是最直接的等价了。

interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));如何产生IServiceManager类型的指针的呢?

该函数模板定义在IIterface.h文件中:

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

实际上转换为:

inline sp<IServiceManager> interface_cast(const sp<IBinder>&obj)

{

  return IServiceManager::asinterface(obj);

}

传入的参数为:ProcessState::self()->getContextObject(NULL),实际上是IBinder类型的对象。实际上这里可以看出来sp<IBinder>和sp IBinder *这两个是不同的,因为sp<IBinder>后面是可以接上一用类型的。(没有充分理解引用在参数传递中的使用,实际上传入的是一个sp<IBinder>类型,传递进去的形式为以引用类型的形式传递进去的)

ProcessState::self()->getContextObject(NULL)如何产生sp<IBinder>类型的对象的呢?

PorcessState::self()返回的是gProcess指针,等价于gProcess->getContextObject(NULL);

interface_cast<IServiceManager>(gProcess->getContextObject(NULL));

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

在ProcessState.cpp文件里面明显看到getContextObject是一个被重载了的operation,我们幸运的重载了第一个方法,这里注意是里面传入的是0,也就是handle为0,好像很重要!!!

等价于interface_cast<IServiceManager>( getStrongProxyForHandle(0));何必如此大费周章呢?我就是想得到一个对象而已。

            struct handle_entry {//里面有如下两个成员
                IBinder* binder;
                RefBase::weakref_type* refs;
            };

            handle_entry*       lookupHandleLocked(int32_t handle);//感觉这是之前一个被我忽视的重点函数
       // 定义有下面这个Vector,里面的成员是handle_entry
            Vector<handle_entry>mHandleToObject;

lookupHandleLocked函数:

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {//如果handle是0,N应该是大于等于0吧
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);//插入的这三个数据分别表示的什么???
        if (err < NO_ERROR) // 插入失败的时候返回的是NULL
            return NULL;
    }
    return &mHandleToObject.editItemAt(handle);// 就取的是刚刚插入的那个对象
}

已经迫不及待想进入IPCThreadState这个类了!!!

但是深入getStrongProxyForHandle函数发现,你竟然已经开始ping了。啥时候给你建立的连接啊!你竟然就开始ping了,一定是分析漏了什么。答案就在gProcess内!也就是我们最开始的时候提到的new ProcessState对象这里

原来在创建对象的时候就已经获取了设备描述符以及虚拟内存空间,接下来就是如何使用的问题了。

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);
/*
根据索引查找对应的资源。如果lookupHandleLocked发现没有对应的资源项,则会
创建一个新的项并返回。这个新项的内容需要填充。
*/
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {// e一定不为空,因为在lookupHandleLocked中若为空这个是指N==0的情况,也会insert一个进去,为NULL只能是插入失败的情况了。
        IBinder* b = e->binder;// 不好意思,刚好是NULL
        if (b == NULL || !e->refs->attemptIncWeak(this)) {//对于新创建的资源项,它的binder为空,所以走这个分支。注意,handle的值为0。
            if (handle == 0) {// 刚好是0

                Parcel data;// binder驱动通信相关的数据结构
                status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, NULL, 0);//ping一下service_manager,确保他现在是联通,实际上在这里是不是就已经开始和service_manager进行通信了呢?
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            //创建一个BpBinder,BpBinder实际上是IBinder的子类
            b = new BpBinder(handle); //子类转父类是可以直接转的,父类转子类需要强制
            //填充entry的内容
            e->binder = b;// 实际上赋值给了他的子类对象
            if (b) 
                e->refs = b->getWeakRefs();
            result = b;// 赋值给全局的父类的对象IBinder,方便返回
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;//返回IBinder(handle)实际上是BpBinder(handle),注意,handle的值为0
}

 IPCThreadState::self()->transact这个函数先放在这里(对于service来说,这里是ping一下service_manager是否连通?那对于client呢?)。回到主题,创建IServiceManager对象。

interface_cast<IServiceManager>(gProcess->getContextObject(NULL));

等价于interface_cast<IServiceManager>(new BpBinder(handle));

等价于:

inline sp<IServiceManager> interface_cast(const sp<IBinder>&obj)

{

  return IServiceManager::asinterface(obj);

}

return IServiceManager::asinterface(new BpBinder(handle));

回到IServiceManager的asinterface函数。因为这里IServiceManager::asinterface为静态函数,所以可以直接通过类名来引用。来看看IServiceManager类的定义,里面涉及到两个相当重要的宏。

class IServiceManager : public IInterface
{
public:
    //关键无比的宏!
    DECLARE_META_INTERFACE(ServiceManager);
     //下面是IServiceManager所提供的业务函数
    virtual sp<IBinder>         getService( const String16& name) const = 0;
    virtual sp<IBinder>         checkService( const String16& name) const = 0;
    virtual status_t            addService( const String16& name,
                                            const sp<IBinder>& service,
                                            bool allowIsolated = false) = 0;
    virtual Vector<String16>    listServices() = 0;
    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};

宏DECLEAR_META_INTERFACE定义了一些模板服务(数据类型前面都加上了命名空间)的实现,在service中十分常用。

// 下面两个宏是至关重要的两个宏
#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor; /*定义一个描述字符串*/                         \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);  /*定义一个asInterface函数*/                \
    virtual const android::String16& getInterfaceDescriptor() const; /*定义一个getInterfaceDescriptor函数,估计就是返回descriptor字符串*/   \
    I##INTERFACE(); /*定义IServiceManager的构造函数和析构函数 ##表示将该宏转换成字符串*/                                                    \
    virtual ~I##INTERFACE();   /*前面的I呢?我晕原来是IserviceManager前面的那个I*/                                         \

static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder> &obj)

到他的实现的宏IMPLEMENT_META_INTERFACE里面。

申明是在IServiceManager.cpp文件中IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

/* DECLARE宏声明了一些函数和一个变量,那么,IMPLEMENT
   宏的作用肯定就是定义它们了。IMPLEMENT的定义在IInterface.h
   中*/
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);  /* 成员初始化的一种方式*/           \
    const android::String16&      /*实现getInterfaceDescriptor函数*/                                      \
           I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;   /*返回字符串descriptor,值是"android.os.IServiceManager" */                            \
    }                                                                   \
    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) {   /*obj是我们刚才创建的那个BpBinder(0)*/                                      \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

翻译一下:

static sp<IServiceManager> IServiceManager::asInterface(const sp<IBinder> &obj){
  sp<IServiceManager> intr;
  if(obj  !=NULL){
    intr = static_cast<IServiceManager>(obj->queryLocalInterface(IServiceManager::descriptor).get());
    if(intr==NULL){
      intr = new BpServiceManager(obj);
    }
  }
  return intr;
}

里面涉及到IBinder::queryLocalInterface(),在Binder技术篇(一)中提到,他实际上返回的是执行IIterface类型的对象,但是在IBinder中返回的是NULL,BpBinder、BBinder均没有实现。

继续在BBinder的子类BnInterface重载返回了this(本身)BpBinder的子类BpInterface没有实现,所以等价于。

intr = static_cast<IServiceManager>(NULL.get());还是NULL,所以直接new一个BpServiceManager对象。

intr = new BpServiceManager(obj); IServiceManager是BpServiceManager爸爸的爸爸(个人认为,android卷1中直接讲解的是他的爸爸),即我最后获取的服务实际上BpServiceManager的对象

return IServiceManager::asinterface(new BpBinder(handle));

return (new BpServiceManager(obj));

继续深入BpServiceManager(obj)的构造函数:这个在注册服务的时候将使用到。

BpServiceManager之所以感觉有点怪怪的,是因为他的父类定义的一个模板继承

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase // 有趣,传入的参数成了继承的类,实现了动态的继承,很多都是这样实现的
{
public:
                                BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
};

INTERFACE决定了他的祖类。

class BpServiceManager : public BpInterface<IServiceManager>//决定了模板继承类的实现 
{
public:
    BpServiceManager(const sp<IBinder>& impl)//构造函数
        : BpInterface<IServiceManager>(impl)// 调用父类的构造函数,他的分类有两个,到底是调用哪个呢?实际上说他的父类有两个这种说法是错误的
    {
    }
。。。。。。
};
BpInterface<IServiceManager>作为一个类来看待呢!实际上是调用了BpInterface<IServiceManager>这个类的构造函数

族谱关系应该是这样的,在另一篇博文中有错误,因为BpInterface类的不确定性,我们可以将BpInterface视为BpInterface<IServiceManager>,就有了将其视为一个整体的想法(个人意测)

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

调用BpInterface<IServiceManager>的构造函数BpInterface,然后里面又调用了祖类构造函数BpRefBase(remote)

[-->Binder.cpp::BpRefBase类]

// IBinder* const          mRemote;
// RefBase::weakref_type*  mRefs;
// std::atomic<int32_t>    mState;
BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)// .体现出他引用的特质,get在IBinder和BpBinder都关于这个的定义或者重载,所以初步推测是在他的父类上,只是被IBinder继承了。
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

    if (mRemote) {
        mRemote->incStrong(this);           // Removed on first IncStrong().
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    }
}

mRemote实际上是我们new BpBinder(handle)对象,他实际上是远程服务在本地的代理,有了他就可以远程服务进行通信了。

  3、初始化instantiate

3.1业务层工作

void MediaDrmService::instantiate() {
    defaultServiceManager()->addService(String16("media.drm"), new MediaDrmService());
}
defaultServiceManager()返回的是刚刚我们生成的那个BpSeriveManager,为什么要提到BpServiceManager而不是提到IServiceManager呢?因为addService实际上是IService类的一个纯虚函数,他需要在子类中得以实现。
注意函数定义的是三个参数,但是默认只是传了两个进去,根据之前window编程的经验,他实际上是默认为0。
    virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());//应该也属于是static函数
        data.writeString16(name);//“media.drm”
        data.writeStrongBinder(service);// new MediaDrmService() MediaDrmService的对象
        data.writeInt32(allowIsolated ? 1 : 0);//默认是0
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);//remote()返回的是IBinder的对象吗?我感觉好像是BpBinder对象
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

来瞅瞅remote()返回的是啥?预知详情还需回头看BpServiceManager的构造函数。

remote( )返回的就是mRemote对象。

3.2通信层工作

IBinder::transact------>BpBinder::transact不然你还真可能找到BBinder里面去了。

我有点理解了为什么说BpBinder实际是道具了。

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) {//初始化为1
        //BpBinder果然是道具,它把transact工作交给了IPCThreadState
        status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);//mHandle也是参数,最后一个参数默认是0
        if (status == DEAD_OBJECT) 
            mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

好吧!又回到了IPCThreadState这个类。先暂时放这里,后面一起分析。

  •   调用BpServiceManager的addService是一个业务层的函数
  • ·  addService函数中把请求数据打包成data后,传给了BpBinder的transact函数,这是把通信的工作交给了BpBinder

3.2.1伙计IPCProcessState::self

  • IPCThreadState,每个线程都有一个IPCThreadState实例登记在Linux线程的上下文附属数据中,主要负责Binder的读取,写入和请求处理框架。IPCThreadState在构造的时候获取进程的ProcessState并记录在自己的成员变量。mProcess中,通过mProcess可以获得Binder的句柄。

还记得在开始的时候,记录的比较清楚的,每个线程都有一个IPCProcessState,还应该关注的是mProcess后面会时常用到。

class IPCThreadState
{
public:
    static  IPCThreadState*     self();//单例模式,静态函数可以直接通过类名::函数名 进行引用
            Parcel              mIn;//发送命令缓冲区
            Parcel              mOut;//接收命令缓冲器
const sp<ProcessState> mProcess; // 进程的ProcessState对象
const pid_t mMyThreadId;//每个线程均有一个线程id

pid_t mCallingPid; // 进程ID
uid_t mCallingUid; // 用户id

};

这里主要涉及到线程的本地存储,也就是TLS,new对象的时候,真的是相当的羞涩啊!!

static bool gShutdown = false;
static bool gHaveTLS = false;
IPCThreadState* IPCThreadState::self()//调用self不是创建一个线程,而是得到当前线程的IPCThreadState对象
{
    if (gHaveTLS) {//第一次进来为false,所以第一次进来不会进来这里
restart:
        const pthread_key_t k = gTLS;
/*
TLS是Thread Local Storage(线程本地存储空间)的简称。
这里只需知晓:这种空间每个线程都有,而且线程间不共享这些空间。
通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。
从线程本地存储空间中获得保存在其中的IPCThreadState对象。
有调用pthread_getspecific的地方,肯定也有调用pthread_setspecific的地方。
*/
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) 
            return st;
        return new IPCThreadState;//new一个对象,构造函数中会调用pthread_setspecific。
    }

    if (gShutdown) {//初始化也是false啊
#ifdef _MTK_ENG_BUILD_
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
        ALOGD("IPCThreadState 0x%p, gTLS:%d gHaveTLS:%d\n", &st, gTLS, gHaveTLS);
#endif
        ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
        return NULL;
    }

    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        // 函数 pthread_key_create() 用来创建线程私有数据。该函数从 TSD 池中分配一项,将其地址值赋给 key 供以后访问使用  
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);//创建了IPCThreadState对象,实际上写法是十分晦涩的
        if (key_create_value != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                    strerror(key_create_value));
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;//其实goto没有我们说的那么不好,汇编代码也有很多跳转语句,关键是要用好。
}

这里根据这个描述,就不深入threadDestructor函数了。

主要用到TLS,首次进入gHaveTLS为false,锁保护说明此函数很多其他函数在调用。
通过if (pthread_key_create(&gTLS, threadDestructor) != 0),中threadDestructor(void *st)
调用IPCThreadState::IPCThreadState()创建IPCThreadState对象,并将对象的索引设置为gTLS。再次进入后通过gTLS获取到IPCThreadState对象。
IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mMyThreadId(gettid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    //在构造函数中,把自己设置到线程本地存储中去
    pthread_setspecific(gTLS, this);//线程说,我已经藏在TLS中,下次就通过get/set来和我联系吧!
    clearCaller();// 初始化进程id和uid为0
    //mIn和mOut是两个Parcel。把它看成是发送和接收命令的缓冲区即可。
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

 

3.2.2传输带:transact

 这里先以添加服务为例:发送数据------>等待回应。

//注意,handle的值为0,代表了通信的目的端。
status_t IPCThreadState::transact(int32_t handle,// 传入的是0
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err = data.errorCheck();//我们传入的Parcle

    flags |= TF_ACCEPT_FDS;//flags初始化是0,取|后就是TF_ACCEPT_FDS
    //这个应该就是一个判断的log输出
    IF_LOG_TRANSACTIONS() {
            TextOutput::Bundle _b(alog);
            alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
            << handle << " / code " << TypeCode(code) << ": "
            << indent << data << dedent << endl;
    }
    /*
注意这里的第一个参数BC_TRANSACTION,它是应用程序向binder设备发送消息的消息码,
而binder设备向应用程序回复消息的消息码以BR_开头。消息码的定义在
binder_module.h中,请求消息码和回应消息码的对应关系,需要查看Binder驱动的实现才能将其理清楚,我们这里暂时用不上。
*/
   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);//应用程序向binder发送消息
    }
    
    if (err != NO_ERROR) {
        if (reply) 
            reply->setError(err);
#ifdef _MTK_ENG_BUILD_
        ALOGD("transact return err=%d before ioctl\n", (int32_t)err);
#endif
        return (mLastError = err);//一个赋值语句的返回值,肯定是0啊!
    }
    
    if ((flags & TF_ONE_WAY) == 0) {//flag参数默认是0,这里只有前面设置为TF_ACCEPT_FDS,所以这里为true
        if (reply) {//reply不为空
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
       
        IF_LOG_TRANSACTIONS() {
            TextOutput::Bundle _b(alog);
            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "<< handle << ": ";
            if (reply) 
                alog << indent << *reply << dedent << endl;
            else 
                alog << "(none requested)" << endl;
        }
    } else {
        err = waitForResponse(NULL, NULL);
    }
    
#ifdef _MTK_ENG_BUILD_
    if (err != NO_ERROR) {
        ALOGD("transact return err=%d\n", (int32_t)err);
    }
#endif
    return err;
}

 第一个函数发送命令请求,实际上有点名不副实:WriteTransactData()语气说是发送数据,不如说是将数据打包成binder_transact_data类型

 

struct binder_transaction_data { 
    /* The first two are only used for bcTRANSACTION and brTRANSACTION, 
     * identifying the target and contents of the transaction. 
     */ 
    union { 
        size_t  handle; /* target descriptor of command transaction */ //指挥交易目标描述符
        void    *ptr;   /* target descriptor of return transaction */ // 返回交易目标描述符
    } target; 
    void        *cookie;    /* target object cookie */ 
    unsigned int    code;       /* transaction command */ 
 
    /* General information about the transaction. */ 
    unsigned int    flags; 
    pid_t       sender_pid; 
    uid_t       sender_euid; 
    size_t      data_size;  /* number of bytes of data */ 
    size_t      offsets_size;   /* number of bytes of offsets */ 
 
    /* If this transaction is inline, the data immediately 
     * follows here; otherwise, it ends with a pointer to 
     * the data buffer. 
     */ 
    union { 
        struct { 
            /* transaction data */ 
            const void  *buffer; //传输内容的数据量
            /* offsets from buffer to flat_binder_object structs */ 
            const void  *offsets; // Binder实体的偏移量(会遇到多个Binder实体)
        } ptr; 
        uint8_t buf[8]; 
    } data; 

}; 

 

具体来看看,是如何填充:

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)//最后一个传入的值是NULL
{//binder_transaction_data是和binder设备通信的数据结构
    binder_transaction_data tr;

    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    //果然,handle的值传递给了target,用来标识目的端,其中0是sServiceManager的标志
    tr.target.handle = handle;
    tr.code = code;//code是消息码,是用来switch/case的!
    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(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {//第一次传入NULL的话,应该是不会进来的
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t);
        tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }
    //把命令写到mOut中,而不是直接发出去,可见这个函数有点名不副实。我之前好像有点搞错了,mOut实际是发送数据,mIn才是接收数据
    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));
    
    return NO_ERROR;
}

然后是等待相应:

//执行waitForResponse()方法,循环执行,直到收到应答消息. 调用talkWithDriver()跟驱动交互,收到应答消息,便会写入mIn, 则根据收到的不同响应吗,执行相应的操作。
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)//添加服务的函数中,后一个参数是NULL
{
    uint32_t cmd;
    int32_t err;
#ifdef _MTK_ENG_BUILD_
    cmd = 0;// initialze it for build error [-Werror=maybe-uninitialized]
#endif
    while (1) {//好家伙,talkWithDriver!
        if ((err=talkWithDriver()) < NO_ERROR) //我假设是在第二次轮询的时候没有收到应答信息然后退出
            break;
        err = mIn.errorCheck();//和binder通信完了,mIn里面已经有数据了
        if (err < NO_ERROR) 
            break;
        if (mIn.dataAvail() == 0) 
            continue;
        
        cmd = (uint32_t)mIn.readInt32();
        
        IF_LOG_COMMANDS() {
            alog << "Processing waitForResponse Command: "<< getReturnString(cmd) << endl;
        }
        
        // BR是binder设备向应用程序发送消息的消息码,和BC相互对应
        // BC_XXX/BC_XXX命令对
        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) {//reply不为NULL
                    if ((tr.flags & TF_STATUS_CODE) == 0) {
                        reply->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);
                    } else {
                        err = *reinterpret_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 binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t), this);
                    }
                } else {
                    freeBuffer(NULL,
                        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), this);
                    continue;
                }
            }
            goto finish;

        default:
            // 默认返回的就是BR_TRANSACT
            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;
#ifdef _MTK_ENG_BUILD_
        ALOGD("WFR got cmd %d err=%d\n", cmd, err);
#endif
    }
    
    return err;
}

BC_TRANSACT的回应者是BR_TRANSACT,所以这里直接就到了default,所以就直接到了这里面来了。

executeCommand(cmd);// 执行命令

3.2.3真正的通信者talkWithDriver

数据打包成了binder_transact_data并写入mOut之后,需要做的就是真正和binder设备通信(talkWithDriver),然后将得到返回值。

status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    if (mProcess->mDriverFD <= 0) {//打开binder设备失败
        return -EBADF;
    }
    
    binder_write_read bwr;//binder_write_read是用来与binder设备交换数据的结构。
    
    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
    
    // We don't want to write anything if we are still reading
    // from data left in the input buffer and the caller
    // has requested to read the next data.
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
    //请求命令的填充。
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();// (uintptr_t)类型存放的是指针地址

    // This is what we'll read.
    //接收数据缓冲区信息的填充。如果以后收到数据,就直接填在mIn中了。
    if (doReceive && needRead) {
       bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();//(uintptr_t)类型存放的是指针地址
    } else {//mOut有数据,mIn还没有数据。doReceive默认值为true
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }

    // 都属于是log输出
    IF_LOG_COMMANDS() {
        TextOutput::Bundle _b(alog);
        if (outAvail != 0) {
            alog << "Sending commands to driver: " << indent;
            const void* cmds = (const void*)bwr.write_buffer;
            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
            alog << HexDump(cmds, bwr.write_size) << endl;
            while (cmds < end) cmds = printCommand(alog, cmds);
            alog << dedent;
        }
        alog << "Size of receive buffer: " << bwr.read_size
            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
    }
    
    // Return immediately if there is nothing to do.
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) 
        return NO_ERROR;

    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    //中间东西太复杂了,不就是把mOut数据和mIn接收数据的处理后赋值给bwr吗?
    do {
        IF_LOG_COMMANDS() {
            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
        }
#if defined(__ANDROID__)
//看来不是read/write调用,而是ioctl方式。
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else {
#ifdef _MTK_ENG_BUILD_
            ALOGD("TWD: ioctl return errno %d\n", errno);
#endif
            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 < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
       if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        IF_LOG_COMMANDS() {
            TextOutput::Bundle _b(alog);
            alog << "Remaining data size: " << mOut.dataSize() << endl;
            alog << "Received commands from driver: " << indent;
            const void* cmds = mIn.data();
            const void* end = mIn.data() + mIn.dataSize();
            alog << HexDump(cmds, mIn.dataSize()) << endl;
            while (cmds < end) cmds = printReturnCommand(alog, cmds);
            alog << dedent;
        }
        return NO_ERROR;
    }
    
    return err;
}

4、开启线程池startThreadpool

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);//注意,传进去的参数是true。
    }
} 

里面解决一个之前在inputreader和dispatcher里面的疑惑,为什么run执行完之后会循环执行threadloop

void ProcessState::spawnPooledThread(bool isMain)
{ //PoolThread是在IPCThreadState中定义的一个Thread子类
    if (mThreadPoolStarted) {// 放俺进去,刚刚朕已经给了一个true了
        String8 name = makeBinderThreadName();//大胆猜测是“media.drm”
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());//会循环执行threadloop吗?实际上是不会的,因为在threadloop里面返回了false
    }
}

Thread被创建, 
Thread中的run被调用, 
__threadLoop()被调用, 
readyToRun()被调用, 
然后循环调用threadLoop()。 
并且在threadLoop()返回false时,可以退出循环。这个和inputdispatcher或者说InputReader不一样的是,这里是返回false,而输入子系统那块是返回true。具体的有空可以去分析。

 

class PoolThread : public Thread
{
public:
    PoolThread(bool isMain)
        : mIsMain(isMain)//为true了
    {
    }

protected:
    virtual bool threadLoop()//只会执行一次
    {//线程函数如此简单,不过是在这个新线程中又创建了一个IPCThreadState。
     //你还记得它是每个伙计都有一个的吗?
        IPCThreadState* ipc = IPCThreadState::self();
        if(ipc)
            ipc->joinThreadPool(mIsMain);//新建立的线程添加到线程池里面去,怎么区分一个是新建线程,一个是主线程呢?妈呀!这个变量不是说了吗?mIsMain
        //IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }

    const bool mIsMain;// 初始化为true
};

 实际上是创建了一个主线程。并将主线程加入线程池。

void IPCThreadState::joinThreadPool(bool isMain)//主线程是没有往里面扔数据的,因为主线程里面模式是没有传入参数的
{
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
// 注意,如果isMain为true,我们则需要循环处理。把请求信息写到mOut中,待会儿一起发出去。mOut实际上是全局的
/*
对于isMain=true的情况下, command为BC_ENTER_LOOPER,代表的是Binder主线程,不会退出的线程;
对于isMain=false的情况下,command为BC_REGISTER_LOOPER,表示是由binder驱动创建的线程。
*/
    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);// 设置哪个线程为前台线程呢?mMyThreadId是在构建IPCThreadState的时候更新的
    // 主线程调用该函数的时候就是主线程,新建的线程调用的时候就是新建的线程调用的
        
    status_t result;
    do {//这个是很重要的,意味着,他实际上是在循环监听着客户端通过binder_driver来发送的请求,之前一直忽视,导致一直费解
       processPendingDerefs();// 处理上次循环尚未完成的内容
        // now get the next command to be processed, waiting if necessary
        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);

    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);//和底层驱动交互
}

 来看看getAndExecuteCommand

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;
    //发送命令,读取请求
    result = talkWithDriver();//循环和binder_driver进行交流,获取客户端的请求,然后再对请求进行处理excutecommand
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();//mIn应该也是全局的
        if (IN < sizeof(int32_t)) // 应该一般都不会执行到这里
            return result;
        cmd = mIn.readInt32();
        IF_LOG_COMMANDS() {alog << "Processing top-level Command: "<< getReturnString(cmd) << endl;}

        pthread_mutex_lock(&mProcess->mThreadCountLock);//先不管mProcess,这里只要知道那是一个上锁的地方就OK了
        
        mProcess->mExecutingThreadsCount++;//自增
        if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&mProcess->mStarvationStartTimeMs == 0) {
            mProcess->mStarvationStartTimeMs = uptimeMillis();
        }
        pthread_mutex_unlock(&mProcess->mThreadCountLock);

        result = executeCommand(cmd);//处理消息

        pthread_mutex_lock(&mProcess->mThreadCountLock);
        mProcess->mExecutingThreadsCount--;//自减,这样的话就保持不变
        if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&mProcess->mStarvationStartTimeMs != 0) {
            int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
            if (starvationTimeMs > 100) {
                ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms", mProcess->mMaxThreads, starvationTimeMs);
            }
            mProcess->mStarvationStartTimeMs = 0;
        }
        //  会重启动等待该条件变量的所有线程
        pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
        pthread_mutex_unlock(&mProcess->mThreadCountLock);

        set_sched_policy(mMyThreadId, SP_FOREGROUND);// 防止其他调用,将其设置成了后台线程
    }

    return result;
}

然后是excutemand函数,这个在客户端这个有介绍:

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();
        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;
            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) {

                    setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
                }
            } else {
                if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
                    set_sched_policy(mMyThreadId, SP_BACKGROUND);
                }
            }

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

            Parcel reply;
            status_t error;
            IF_LOG_TRANSACTIONS() {
                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) {
                if (reinterpret_cast<RefBase::weakref_type*>(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags);
                    reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
                } else {
                    error = UNKNOWN_TRANSACTION;
                }

            } else {
                // the_context_object实际上是一个全局变量,实际上他是一个BBinder的对象
                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;
        break;
    /*收到Binder驱动发来的service死掉的消息,看来只有Bp端能收到了,后面我们将会对此进行分析。*/
    //Binder驱动会通知死亡消息
    case BR_DEAD_BINDER:
        {
            BpBinder *proxy = (BpBinder*)mIn.readPointer();//下面的proxy对应着已经死亡的远端BBinder。
#ifdef _MTK_ENG_BUILD_
        ALOGD("[DN #5] BR_DEAD_BINDER cookie %p", proxy);
#endif
            proxy->sendObituary();//发送讣告,Obituary是讣告的意思。最终会传递到你的DeathNotifier中。
            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;
        //特别注意,这里将收到来自驱动的指示以创建一个新线程,用于和Binder通信
    case BR_SPAWN_LOOPER:
        mProcess->spawnPooledThread(false);
        break;
        
    default:
#ifdef _MTK_ENG_BUILD_
        ALOGD("*** BAD COMMAND %d received from Binder driver\n", cmd);
#else
        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
#endif
        result = UNKNOWN_ERROR;
        break;
    }
    if (result != NO_ERROR) {
#ifdef _MTK_ENG_BUILD_
        ALOGD("EXECMD cmd %d return %d\n", cmd, (int32_t)result);
#endif
        mLastError = result;
    }
    
    return result;
}

BBinder的transact函数里面会调用它的子类的ontrasact函数。

5、将当前线程添加到线程池jionThreadPool

IPCThreadState::self()->joinThreadPool();

有好几次调用IPCThreadState::self()难道每次调用都产生了一条线程,那是得产生多少条线程啊!实际上不是的,具体的详见上面的self函数的分析

总结:

int main()
{ // 这个我肯定是在surfaceflinger里面见到过的,且里面的套路是一样的,ProcessState,实际上每个进程只有一个对象,就像是每个进程有唯一的javaVM一样
    signal(SIGPIPE, SIG_IGN);
    // 1、获取ProcessState实例,实际上这里的self表示的是单例模式
    sp<ProcessState> proc(ProcessState::self());
    // 2、sm作为ServiceManager的客户端,需要向ServiceManager注册服务,调用defaultServiceManager,得到一个IServiceManager
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    // 3、初始化多媒体系统的MediaPlayer服务,我们将以它作为主切入点
    MediaDrmService::instantiate();
    // 4、根据名称来推断,难道是要创建一个线程池吗?
    ProcessState::self()->startThreadPool();//startThreadPool中新启动的线程通过joinThreadPool读取binder设备,查看是否有请求(这个才是主线程吗?// 5、将自己加入到刚才的线程池中
    IPCThreadState::self()->joinThreadPool();//主线程也调用joinThreadPool读取binder设备,查看是否有请求(当前线程?
}

 

 

 

 

 

 

 

 
 

posted on 2017-08-04 17:08  feifeiyuan  阅读(1602)  评论(0编辑  收藏  举报