首页 > 其他分享 >Android Binder总结

Android Binder总结

时间:2023-07-14 16:57:26浏览次数:45  
标签:总结 return Parcel Binder reply Android data android const

Binder总结

首先感谢参考的博客 Android Binder原理,下面是我个人的总结,方便加深理解

1.0 系统服务启动

  1. 在servicemanager.rc中启动在servicemanager服务
  2. 调用binder_open函数用于打开binder设备文件,并申请128k字节大小的内存空间
  3. 调用binder_become_context_manager函数,将servicemanager注册成为Binder机制的上下文管理者
  4. 调用binder_loop函数,循环等待和处理client端发来的请求

2.0 系统服务的注册

以MediaPlayService为例:

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);
    //获取ProcessState实例
    sp<ProcessState> proc(ProcessState::self());//1
    sp<IServiceManager> sm(defaultServiceManager());//2 最终通过宏IMPLEMENT_META_INTERFACE,实际创建一个BpServiceManager
    ALOGI("ServiceManager: %p", sm.get());
    InitializeIcuOrDie();
    //注册MediaPlayerService
    MediaPlayerService::instantiate();//3
    ResourceManagerService::instantiate();
    registerExtensions();
    //启动Binder线程池
    ProcessState::self()->startThreadPool();
    //当前线程加入到线程池
    IPCThreadState::self()->joinThreadPool();
}

2.1 ProcessState::self()

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");
    return gProcess;
}

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(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);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

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

单例,mDriverFD驱动的文件描述符,mmap内存


2.2 defaultServiceManager()

返回全局gDefaultServiceManager

gDefaultServiceManager = interface_cast<IServiceManager>(
        ProcessState::self()->getContextObject(NULL));

2.2.1 ProcessState::getContextObject

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

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        // We need to crea namespace android    here isn't currently one, OR we
        // are unable to a                      e on this current one.  See comment
        // in getWeakProxy namespace android {} nfo about this.
        IBinder* b = e->binder;

        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle);  //创建BpBinder 
            e->binder = b;  //保存到handle_entry中一份
            if (b) e->refs = b->getWeakRefs();  // 保存一份引用
            result = b;
        } 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;
}            

创建了BpBinder(0); 并保存到handle_entry中,并返回给interface_cast函数做为什么参数

2.2.2 interface_cast

asInterface通过两个宏定义和实现DECLARE_META_INTERFACE(INTERFACE)IMPLEMENT_META_INTERFACE(INTERFACE, NAME)

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

// frameworks/native/libs/binder/include/binder/IInterface.h

#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() { }                                   \

//宏替换后

const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager");          
const ::android::String16&                                          
        IServiceManager::getInterfaceDescriptor() const {              
    return IServiceManager::descriptor;                                
} 
 //实现了asInterface函数
::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);//1                        
        }
    }
    return intr;
}                                                                   
IServiceManager::IServiceManager() { }                                    
IServiceManager::~IServiceManager() { }                                   

实际返回的是BpServiceManager对象,并内部持有一个BpBinder对象

2.3 MediaPlayerService::instantiate

void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService,());
}

virtual status_t addService(const String16& name, const sp<IBinder>& service,
                               bool allowIsolated, int dumpsysPriority) {
       Parcel data, reply;//数据包
       data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
       data.writeString16(name); //name值为"media.player"
       data.writeStrongBinder(service); //service值为MediaPlayerService
       data.writeInt32(allowIsolated ? 1 : 0);
       data.writeInt32(dumpsysPriority);
       status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);//1
       return err == NO_ERROR ? reply.readExceptionCode() : err;
   }

真正的添加服务是remote()->transact(),这里的remote就是前面的BpBinder对象


status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

也就是BpBinder的transact最后都走向了IPCThreadState::transact()

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

    flags |= TF_ACCEPT_FDS;
    ...
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//1

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    if ((flags & TF_ONE_WAY) == 0) {
       ...
        if (reply) {
            err = waitForResponse(reply);//2
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
       ...
    } else {
       //不需要等待reply的分支
        err = waitForResponse(NULL, NULL);
    }

    return err;
}
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data tr;//1

    tr.target.ptr = 0; 
    tr.target.handle = handle;//2 
    tr.code = code;  //code=ADD_SERVICE_TRANSACTION
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();//3
    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) {
        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.writeInt32(cmd);  //cmd=BC_TRANSACTION
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

NO_ERROR时候调用writeTransactionData写入数据, 构造结构体binder_transaction_data,最后通过mOut写入

没有TF_ONE_WAY这个flag时候会调用waitForResponse等待回复,这里主要是通过talkWithDriver方法从mIn循环读取数据

后面跟驱动交互不展开了

总结

getContextObject() 函数创建了 BpBinder对象,将BpBinder对象通过参数形式传递给函数interface_cast,interface_cast函数最后返回BpServiceManager对象,此时这个BpServiceManager对象内持有一个BpBinder对象

然后再调用addService方法添加系统服务,实际是调用之前BBpBinder对象的transact()方法,最后到IPCThreadState::transact()函数,主要是驱动协议交互完成注册


3.0 获取系统服务

defaultServiceManager()->getService(String16("media.player"))

循环调用checkService("media.player")直到不为null

    virtual sp<IBinder> checkService( const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);                                                                                                                            
        return reply.readStrongBinder();
    }

还是同样的套路remote是BpBinder对象,跟添加系统服务一样,只是transact的参数不同


4.0 Java系统服务注册

public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1
       ....
    } catch (PackageManager.NameNotFoundException e) {
        throw new RuntimeException(
                "Unable to find android system package", e);
    }
 ...
}

addService实际调用的是ServiceManagerProxy.addService()

// frameworks/base/core/java/android/os/ServiceManagerNative.java
class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
    
    public IBinder asBinder() {
        return mRemote;
    }
    
    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }
    ...
}

这个mRemote就是一个BpBinder对象,他的初始化在BinderInternal.getContextObject()

    private static IServiceManager getIServiceManager() {                                                                                                                                       
        if (sServiceManager != null) {
            return sServiceManager;
        }   
        
        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

BinderInternal.getContextObject()是个native函数

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)                                                                                                           
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

最后还是走到ProcessState::getContextObject(),在系统服务注册我们就已经认识过了

jni中静态注册android.os.Binder类中的方法

// frameworks/base/core/jni/android_util_Binder.cpp

const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{                               
    jclass clazz = FindClassOrDie(env, kBinderPathName);                               
                                       
    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);                               
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");                               
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");                               
                                       
    return RegisterMethodsOrDie(                               
        env, kBinderPathName,                               
        gBinderMethods, NELEM(gBinderMethods));                               
}


javaObjectForIBinder函数中完成BinderProxy类字段的初始化

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    ...
    // BinderProxy 实例化
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

        // The native object needs to hold a weak reference back to the
        // proxy, so we can retrieve the same proxy if it is still active.
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));

        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

    return object;
}

为什么是BinderProxy实例化,看完aidl你就知道了


        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an android.hardware.input.IInputManager
         * interface,
         * generating a proxy if needed.
         */
        public static android.hardware.input.IInputManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof android.hardware.input.IInputManager))) {
                return ((android.hardware.input.IInputManager) iin);
            }
            return new android.hardware.input.IInputManager.Stub.Proxy(obj);
        }

ServiceManager.getService()返回一个IBinder对象,如果queryLocalInterface成功直接将返回这个IBinder对象如,果失败创建IInputManager.Stub.Proxy对象


5.0 AIDL接口

IInputManager.Stub.asInterface(ServiceManager.getServiceOrThrow(ContextINPUT_SERVICE))
    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

我们已经知道ServiceManager.getService()实际是调用BpBinder.transact()函数,然后返回一个IBinder对象

        public static android.hardware.input.IInputManager asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof android.hardware.input.IInputManager))) {
                return ((android.hardware.input.IInputManager) iin);
            }
            // 创建Proxy
            return new android.hardware.input.IInputManager.Stub.Proxy(obj); 
        }



        private static class Proxy implements android.hardware.input.IInputManager {
            private android.os.IBinder mRemote;

            Proxy(android.os.IBinder remote) {
                mRemote = remote;
            }
        
            @Override
            public void enableInputDevice(int deviceId) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(deviceId);
                    mRemote.transact(Stub.TRANSACTION_enableInputDevice, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
        }

AIDL接口的实例需要一个IBinder对象的参数,这个参数通过ServiceManager.getService(Context.INPUT_SERVICE)来获取这个,所有接口函数调用都是通过这个IBinder对象

ServiceManager是怎么获取的IBinder对象的? ServiceManager内有一个BpBinder对象,是通过BpBinder::transact来获取的IBinder的

ServiceManager的BpBinder怎么来的? 实际是BinderInternal.getContextObject() 获取的,他是ProcessState::getContextObject(NULL)的封装

标签:总结,return,Parcel,Binder,reply,Android,data,android,const
From: https://www.cnblogs.com/tangshunhui/p/17553489.html

相关文章

  • 测试学习总结
    1.敏捷测试测试往往被期望承担项目质量控制的职责。这点很难做到,测试既不能控制代码如何编写,也不能控制开发人员测试他们编写的代码,但所有的质量把控都被期望能压缩在开发之后的测试阶段完成。 在敏捷项目中,测试人员不再被动等待工作降临,而是主动寻找在整个开发周期中都贡献价......
  • 20230714练习总结
    LOJ3686/JOISC2022DAY1京都观光考虑从\((x1,y1)\)只转一次弯到\((x2,y2)\)。先向南走当且仅当:\[\boxed{\frac{a_{x1}-a_{x2}}{x1-x2}<\frac{b_{y1}-b_{y2}}{y1-y2}}\]很容易想到斜率相关。但是如果只是对比两行,因为有列的条件参与,无法判断某一行是否一定不会被走过,于是......
  • 刷力扣高频SQL50题(基础)总结
    此随笔仅总结个人刷SQL题时,突然不会使用的某函数或某方法,大佬勿看勿喷regexp'正则表达式'一般用于邮箱校验例题:查找拥有有效邮箱的用户select*fromuserswheremailregexp'^[a-zA-Z]+[a-zA-Z0-9_\\./\\-]*@leetcode\\.com$'窗口函数窗口函数讲解函数+over(pa......
  • Web测试方法总结
           ......
  • 日常总结
    0.JavaSE(JavaStandardEdition)标准版以前称为J2SE,定位在个人计算机使用,用来开发C/S架构软件JavaEE(JavaPlatformEnterpriseEdition)企业版以前称为J2EE,定位在服务器端应用JavaWeb很多时候,javaweb与javaee是混用的,两者的概念并不能准确区分。对javaweb的理......
  • is greater than this module's compileSdkVersion (android-32). Dependency: an
    实现"isgreaterthanthismodule'scompileSdkVersion(android-32)"的步骤为了解决这个问题,我们需要按照以下步骤进行操作:步骤操作1确认项目的compileSdkVersion2更新项目的compileSdkVersion3更新相关依赖库的版本下面是每一步具体需要做的操作:步骤1......
  • P5979 [PA2014] Druzyny 总结--zhengjun
    思维妙妙题。首先发现\(d\)的限制满足单调性,所以可以转化为\(l\gep_r\)的限制。注意:\(p\)是单调不降的然后就是\(p_r\lel\ler,\max\limits_{i=l}^r\{c_i\}\ler-l+1\)。这个\(\max\)想到转化到笛卡尔树上操作。然而这题要需要一个dp,所以考虑类似cdq分治一样......
  • 火山引擎 DataLeap 构建Data Catalog系统的实践(三):关键技术与总结
     更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群关键技术构建一个好的DataCatalog系统,需要考虑的核心产品设计和技术设计有很多。篇幅所限,本文只概要介绍技术设计中最核心重要的部分,更多细节展开可参照后续的文章。数据模型统一......
  • 22年普陀区一模卷错题总结
    13.错误原因:听力没有听清26.错误原因:lovely的另一个意思不知道28.considerdoing固定搭配不会44.third不会拼49.surprise的各种词性及用法没搞清楚51.keepsettingyourselfnewchallenges意思不懂53.分不清howlong和howsoon的适用场合67.做题时没有联系上下文74.imagi......
  • flume知识点总结
    flume知识点总结1.flume作用:从各种各样的数据源采集数据(读数据,缓存数据,写数据)到各种各样的文件系统中,如kafka 2.flume的采集程序:agent(包括source组件,channel组件,sink组件) 3.flume基本配置:(dir)#定义三大组件的名称ag1.sources=source1ag1.sinks=sink1ag1.channels=c......