Binder机制 - ServiceManager(2)获取

ServiceManager的获取

1 Native层的获取:

通过调用 defaultServiceManager() 获取

defaultServiceManager

C++ 复制代码
// frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

gDefaultServiceManager 采用单例模式实现

第一次调用该函数会创建gDefaultServiceManager对象。如果创建失败则等待1秒然后循环反复直至成功(失败的场景:可能出现在开机过程中某些场景下过早调用defaultServiceManager()接口,而此时ServiceManager还没有准备好)

继续gDefaultServiceManager对象生成过程的分析:

C++ 复制代码
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));

1.1 ProcessState::self()

C++ 复制代码
// frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}

单例模式,第一次执行self()新建ProcessState:

1.1.1 ProcessState::ProcessState()

C++ 复制代码
ProcessState::ProcessState()
    : mDriverFD(open_driver())
    , mVMStart(MAP_FAILED)
    , 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)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        // 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);
        ...
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

在ProcessState的构造函数中比较重要的两步:

  1. 通过open_driver()打开"/open/binder",并将文件句柄赋值给mDriverFD。
  2. 通过调用mmap()映射内存。

1.1.2 open_driver()

C++ 复制代码
static int open_driver()
{	
    //1 打开文件/dev/binder
    int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        //2 检查/dev/binder的版本
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) {
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        }
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
            ALOGE("Binder driver protocol does not match user space protocol!");
            close(fd);
            fd = -1;
        }
        //#define DEFAULT_MAX_BINDER_THREADS 15
        //3 设置该进程最大线程数
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        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;
}
  1. open_driver()首先打开"/dev/binder"驱动。对应执行Binder驱动的binder_open()函数。
  2. 成功后调用 ioctl检查Binder版本
  3. 调用ioctl(,BINDER_SET_MAX_THREADS,) 设置该进程的最大线程数。对应调用Binder驱动的binder_ioctl()。

注意:区分"本文的open("/dev/binder",...)" 和 "ServiceManager中的open("/dev/binder",...)"。

  • 本文的open("/dev/binder",...):属于调用defaultServiceManager()的进程;

  • ServiceManager中的open("/dev/binder",...):属于ServiceManager进程的。

binder_ioctl()的BINDER_SET_MAX_THREADS

C 复制代码
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
	struct binder_proc *proc = filp->private_data;
	struct binder_thread *thread;
	unsigned int size = _IOC_SIZE(cmd);
	void __user *ubuf = (void __user *)arg;
	...
	ret = wait_event_interruptible(binder_user_error_wait,
                                   binder_stop_on_user_error < 2);
	...
	thread = binder_get_thread(proc);
	switch (cmd) {
		case BINDER_SET_MAX_THREADS:
		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
			ret = -EINVAL;
			goto err;
		}
		break;
		...
	}
	ret = 0;
	...
	return ret;
}

将最大线程数目从用户空间拷贝到内核空间,进而赋值给binder_proc->max_threads

1.1.3 mmap()

执行完open_driver()后调用mmap()映射内存,使内核虚拟地址空间和当前进程的虚拟地址空间指向同一内存。对于内存映射以及内核缓冲区管理后面会单独写一篇文章讲解。

至此,ProcessState::self()分析完毕,gDefaultServiceManager的赋值语句可以进一步的简化:

C++ 复制代码
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::getContextObject(NULL));

1.2 ProcessState::getContextObject()

C++ 复制代码
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

调用了getStrongProxyForHandle(0)。0代表的是请求ServiceManager(Binder机制规定ServiceManager描述符为0)。

1.2.1 ProcessState::getStrongProxyForHandle

C++ 复制代码
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    // 1
    // 在矢量数组mHandleToObject中查找"编号为handle的handle_entry对象";
    // 找到则直接返回;
    // 找不到则新建handle对应的handle_entry,并将其添加到mHandleToObject缓存起来。
    handle_entry* e = lookupHandleLocked(handle);
    // 2
    if (e != NULL) { // 进入
        IBinder* b = e->binder; // null,
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            // handle==0(即是Service Manager的句柄),
            if (handle == 0) {
                Parcel data;
                //尝试去ping Binder驱动判断对端是否存活
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            // 3 创建BpBinder代理
            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            ...
        }
    }

    return result;
}

说明:getStrongProxyForHandle()的目的是返回持有句柄handle的IBinder,这里入参为0表示指定是Service Manager的IBinder引用。

  1. lookupHandleLocked():

    在矢量数组mHandleToObject中查找是否有句柄为handle的handle_entry对象。

    • 有则返回该handle_entry对象;

    • 没有则新建handle对应的handle_entry,并将其添加到矢量数组mHandleToObject中,然后再返回。

    mHandleToObject是用于保存各个IBinder代理对象的矢量数组。

  2. e!=NULL为true,e->binder=NULL,handle=0;

    进入调用IPCThreadState::self()->transact(IBinder::PING_TRANSACTION)测试对端是否存活。Binder驱动已启动,ping是能够成功的。

  3. 新建BpBinder对象传入0,并赋值给e->binder。然后返回该BpBinder对象。

ProcessState::lookupHandleLocked()
C++ 复制代码
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}

说明:mHandleToObject是Vector矢量数组。

  • mHandleToObject的初始大小为0,因此if (N <= handle)为true。

  • 接下来就新建handle_entry,并将其添加到mHandleToObject中后续可以直接取,然后返回该handle_entry。

  • mHandleToObject和handle_entry的定义如下:

    C++ 复制代码
    class ProcessState : public virtual RefBase
    {
      ...
      private:
      ...
      struct handle_entry {
          IBinder* binder;
          RefBase::weakref_type* refs;
      };
      ...
      Vector<handle_entry>mHandleToObject;
      ...
    }

1.2.2 BpBinder::BpBinder

new BpBinder(0)新建BpBinder对象。BpBinder的构造函数:

c++ 复制代码
BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);

    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    IPCThreadState::self()->incWeakHandle(handle);
}
  1. 将ServiceManager的描述符保存到mHandle中。mHandle = 0;

  2. 增加IPCThreadState的引用计数。

    IPCThreadState::self()是获取IPCThreadState对象

IPCThreadState::self()
C++ 复制代码
static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gHaveTLS = false;
static pthread_key_t gTLS = 0;
static bool gShutdown = false;
static bool gDisableBackgroundScheduling = false;

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;
    }
    ...
    
    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        int key_create_value = pthread_key_create(&gTLS, threadDestructor);
        ...
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

获取IPCThreadState对象。若该对象已经存在,则直接返回;否则,创建IPCThreadState对象。

创建IPCThreadState
C++ 复制代码
IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),
      mMyThreadId(gettid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    pthread_setspecific(gTLS, this);
    clearCaller();
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

说明:

  1. 获取ProcessState对象并赋值给成员mProcess。

  2. 设置mIn和mOut的容量为256字节。

    mIn和mOut是用来和Binder驱动交互数据的

    • mOut是用来承载"IPCThreadState需要发送给Binder驱动的内容的",
    • mIn则是用来承载"Binder驱动反馈给IPCThreadState的内容的"。

ProcessState::getContextObject()就分析完了。gDefaultServiceManager的赋值语句可以进一步的简化:

C++ 复制代码
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

1.3 interface_cast() 模板

c++ 复制代码
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

模板函数。此时的INTERFACE是IServiceManager,所以带入模板返回的结果是IServiceManager::asInterface()。

1.3.1 模板解析出 IServiceManager::asInterface()

asInterface()是通过DECLARE_META_INTERFACE()来声明,并通过IMPLEMENT_META_INTERFACE()来实现的。

  1. IServiceManager中的DECLARE_META_INTERFACE()声明和IMPLEMENT_META_INTERFACE(),分别在: frameworks/native/include/binder/IServiceManager.h frameworks/native/libs/binder/IServiceManager.cpp

    C++ 复制代码
    // IServiceManager.h中的声明
    class IServiceManager : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(ServiceManager);
        ...
    }
    
    // IServiceManager.cpp中的实现
    IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
  2. DECLARE_META_INTERFACE()和IMPLEMENT_META_INTERFACE()的定义在frameworks/native/include/binder/IInterface.h中。

    C++ 复制代码
    #define DECLARE_META_INTERFACE(INTERFACE)                               \
        static const android::String16 descriptor;                          \
        static android::sp<I##INTERFACE> asInterface(                       \
                const android::sp<android::IBinder>& obj);                  \
        virtual const android::String16& getInterfaceDescriptor() const;    \
        I##INTERFACE();                                                     \
        virtual ~I##INTERFACE();                                            \
    
    
    #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
        const android::String16 I##INTERFACE::descriptor(NAME);             \
        const android::String16&                                            \
                I##INTERFACE::getInterfaceDescriptor() const {              \
            return I##INTERFACE::descriptor;                                \
        }                                                                   \
        android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
                const android::sp<android::IBinder>& obj)                   \
        {                                                                   \
            android::sp<I##INTERFACE> intr;                                 \
            if (obj != NULL) {                                              \
                intr = static_cast<I##INTERFACE*>(                          \
                    obj->queryLocalInterface(                               \
                            I##INTERFACE::descriptor).get());               \
                if (intr == NULL) {                                         \
                    intr = new Bp##INTERFACE(obj);                          \
                }                                                           \
            }                                                               \
            return intr;                                                    \
        }                                                                   \
        I##INTERFACE::I##INTERFACE() { }                                    \
        I##INTERFACE::~I##INTERFACE() { }                                   \

    用ServiceManager替换INTERFACE之后,得到结果如下:

    DECLARE_META_INTERFACE(ServiceManager)

    IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

    C++ 复制代码
    #define DECLARE_META_INTERFACE(ServiceManager)                             \
        static const android::String16 descriptor;                             \
        static android::sp<IServiceManager> asInterface(                       \
                const android::sp<android::IBinder>& obj);                     \
        virtual const android::String16& getInterfaceDescriptor() const;       \
        IServiceManager();                                                     \
        virtual ~IServiceManager();                                            \
    
    
    #define IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")                       \
        const android::String16 IServiceManager::descriptor("android.os.IServiceManager");             \
        const android::String16&                                               \
                IServiceManager::getInterfaceDescriptor() const {              \
            return IServiceManager::descriptor;                                \
        }                                                                      \
        android::sp<IServiceManager> IServiceManager::asInterface(             \
                const android::sp<android::IBinder>& obj)                      \
        {                                                                      \
            android::sp<IServiceManager> intr;                                 \
            if (obj != NULL) {                                                 \
                intr = static_cast<IServiceManager*>(                          \
                    obj->queryLocalInterface(                                  \
                            IServiceManager::descriptor).get());               \
                if (intr == NULL) {                                            \
                    intr = new BpServiceManager(obj);                          \
                }                                                              \
            }                                                                  \
            return intr;                                                       \
        }                                                                      \
        IServiceManager::IServiceManager() { }                                 \
        IServiceManager::~IServiceManager() { }                                \

得到IServiceManager::asInterface()的源码如下:

C++ 复制代码
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
{
    android::sp<IServiceManager> intr;
    if (obj != NULL) {
        intr = static_cast<IServiceManager*>(
            obj->queryLocalInterface(
                    IServiceManager::descriptor).get());
        if (intr == NULL) {
            intr = new BpServiceManager(obj);
        }
    }
    return intr;
}

说明:asInterface()的作用是获取IServiceManager接口。

  1. obj是传入的BpBinder对象,不为NULL。

    执行obj->queryLocalInterface("android.os.IServiceManager")来查找名称为"android.os.IServiceManager"的本地接口

    queryLocalInterface()的实现在BpBinder的父类IBinder中(frameworks/native/libs/binder/Binder.cpp)

    c++ 复制代码
    sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
    {   
        return NULL;
    }   

    intr=NULL,则需要新建 IServiceManager 对象。

  2. 新建BpServiceManager(obj)对象,并返回。(BpServiceManager的实现在frameworks/native/libs/binder/IServiceManager.cpp中)

至此,gDefaultServiceManager的创建流程就分析完了,它实际返回的是一个BpServiceManager对象,该对象包含IBinder的代理BpBinder。

获取gDefaultServiceManager的代码最终转化为:

C++ 复制代码
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));

2 Java层的获取

通过ServiceManager的getIServiceManager方法获取:

getIServiceManager

JAVA 复制代码
private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
    return sServiceManager;
}

2.1 BinderInternal.getContextObject()

JAVA 复制代码
public static final native IBinder getContextObject();

是一个native方法,jni调用到native层

android_os_BinderInternal_getContextObject

c++ 复制代码
// android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    // 返回 BpBinder(0)
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    // 返回 BinderProxy(BpBinder(0))
    return javaObjectForIBinder(env, b);
}

1> ProcessState::self()->getContextObject(NULL) 与前面native获取方式的讲解一致,同1.1 1.2章节,最终返回一个BpBinder(0)

2> javaObjectForIBinder

javaObjectForIBinder

JNI中的相关变量:

C++ 复制代码
const char* const kBinderProxyPathName = "android/os/BinderProxy";

static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    // "android/os/BinderProxy" 的class
    clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
    ...
    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    ...
}
c++ 复制代码
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    ...
    // 生成BinderProxy对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        // 给BinderProxy的成员mObject赋值入参BpBinder
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        ...
    }
    return object;
}

通过jni创建一个BinderProxy的java对象,持有BpBinder(0),并返回BinderProxy对象给java层。

至此,原来的代码可看做:

Java 复制代码
sServiceManager = ServiceManagerNative.asInterface(new BinderProxy(new BpBinder(0)));

2.2 ServiceManagerNative.asInterface

C++ 复制代码
static public IServiceManager asInterface(IBinder obj)
{
    if (obj == null) {
        return null;
    }
    IServiceManager in =
        (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    
    return new ServiceManagerProxy(obj);
}

入参:IBinder obj是2.1章节创建出来的BinderProxy。

asInterface创建ServiceManagerProxy对象持有BinderProxy并返回。

通过上面的过程,我们最终得到一个 ServiceManagerProxy 持有 BinderProxy,BinderProxy 又持有 BpBinder(0),原来的代码可看做:

Java 复制代码
sServiceManager = new ServiceManagerProxy(new BinderProxy(new BpBinder(0)));

总结

1 获取ServiceManager的过程都是在本进程内完成的(普通跨进程调用获取服务在本端的引用是需要调用getService发起一次binder通信的),没有通过驱动向对端请求。

  • 这是因为Binder机制里通常要获取对端引用是需要通过跨进程调用ServiceManager.getService的,而我们此时要获取的对端引用正是ServiceManager。所以Binder机制把ServiceManager的client端引用的获取设计成了不通过跨进程,而是直接在本地生成。

  • 这是如何实现的呢?就是把ServiceManager的引用描述符规定为固定的值0,调用者直接构建持有描述符0的BpBinder;而在驱动中把ServiceManager的binder实体对象设计为全局变量,这样就可以直接获取到了,而描述符为0的请求就直接看做对ServiceManager的请求。

2 获取过程简化成一句就是:

Jave层:

Java 复制代码
sServiceManager = new ServiceManagerProxy(new BinderProxy(new BpBinder(0)));

native层:

C++ 复制代码
gDefaultServiceManager = new BpServiceManager(new BpBinder(0));

3 通过本端的ServiceManager引用调用对端,实际最终就是通过BpBinder.transact发起请求。

相关推荐
Jouzzy5 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯5 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
Good_tea_h8 小时前
Android中的单例模式
android·单例模式
计算机源码社12 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽13 小时前
重修设计模式-结构型-门面模式
android
晨春计14 小时前
【git】
android·linux·git
标标大人15 小时前
c语言中的局部跳转以及全局跳转
android·c语言·开发语言
竹林海中敲代码15 小时前
Qt安卓开发连接手机调试(红米K60为例)
android·qt·智能手机
木鬼与槐16 小时前
MySQL高阶1783-大满贯数量
android·数据库·mysql
iofomo16 小时前
【Abyss】Android 平台应用级系统调用拦截框架
android·开发工具·移动端