Binder 从java到c++到kernel,涉及的内容不少,很难在一篇文章中说清楚。这篇主要是自我记录,方便后续查询并拆分总结的。
由于涉及的的确很是多,不能面面俱到,因此可能一些地方感受比较模糊、没说明白的。这须要本身去阅读了解。文章很长,须要耐心。
关于基础部分,并非都要了解了才行,而是要彻底弄清楚Binder各个层次须要,列出的一些须要多关注的知识点。
另外,该篇文章着重在注册服务和获取服务的过程,有详细的代码流程(这个有点复杂、占篇幅很大部分)辅助理解 注册和获取服务过程的总体思想把握。html
不作详细介绍,只是列出。
如前言所说,基础部分并不是都要所有了解才可理解Binder。只是列出的须要多关注的地方。java
这里的进程空间就是进程在内存中的空间。在linux中,有node
Binder跨进程通讯,就是借用了这个。
示意图:
进程了解 能够参考下:浅谈进程&线程
linux
须要清楚:进程是独立的,一个进程不能直接访问另外一个进程。android
进程间若是须要交换数据、进行通讯,这个就是IPC(进程间通讯/跨进程通讯)。能够参考相关文章大体了解下:
随笔分类 - Android_系统_进程线程
c++
这里简单将,就是将用户空间一段内存地址映射到内核空间,映射关系创建后,任一修改都能反应到另外一方。
git
一个容器对象,包含数据和对象引用,支持序列化和跨进程后的反序列化。这里主要用于binder的跨进程通讯。
api
Android Interface definition language,接口定义语言,能够了解下。
安全
IPC在Android中不少:如显然四大组件都须要进行IPC。
Andriod没有使用Linux中的各类IPC机制(进程间通讯概述),经过基于OpenBinder的定制修改,实现了本身的一套轻量级的IPC机制---Binder。
在Android中,Binder几乎用于全部核心的跨进程事件中。cookie
相对于Linux中其余IPC机制,那么Binder有什么优势呢?
Binder是基于C/S模式。主要有这几个部分:
角色 | 做用 |
---|---|
Server进程 | 服务端,提供服务的进程。 |
Client进程 | 客户端,使用服务的进程。上层应用。 |
ServerManager进程 | 管理服务。Server须要向它注册本身提供的服务。Client向它查询、获取须要的服务。 |
Binder驱动 | 核心部分,Client经过它发送请求到Server,Server经过它返回结果到Client。内核中的驱动设备/dev/binder。 |
下面详述中会具体说到。
首先,整体上就如上述进程空间描述。Binder经过内核进行跨进程。
具体点,以下图:
服务经过binder驱动注册到ServiceManager,ServiceManager保存了服务的名称、handle等信息 并加入svclist列表中。客户端经过binder驱动向ServiceManager进程查询获取到对应的服务的handle,而后binder将信息返回给客户端,客户端获取获得相应的服务Binder。
详述Binder的流程 主要是服务注册、获取、ServiceManager相关的代码流程,这段很长,若是不须要看 能够直接跳到最后一块:简单总结。
下面AMS的注册和获取为例说明。Binder过程比较复杂,其中最需注意的是各个层次(java层/c++/kernel) IBinder对象具体是什么。
Binder源码,java层和c++层在 framework/下。驱动层在 kernel/下。
Android AOSP没有kernel源码,得单独下载。这里阅读的源码是AndroidQ的,AOSP部分是android-10.0.0_r40;kernel部分是MTK的,主要两个文件路径在kernel-4.9/drivers/android/binder.c和kernel-4.9/include/uapi/linux/android/binder.h。
另外,下面的过程不少地方 不少方法都须要详细研究的。下面尽可能简化了,即便这样(也是水平有限),内容也很长。
主要是一个进程如何与另外一个进程通讯。围绕这 下面主要介绍了几点:
服务是Context.ACTIVITY_SERVICE。
下面是画的一个注册过程的相对完整的流程(不是类图。文章是MD的,能够直接查看文本看到图片地址,该图片地址。使用wps画的 因为非会员,图形个数有限制带了水印。),再结合代码详细说明下。
这是一个理想的状态流程,好比实际中不少对象从保存好的地方直接获取不需从新建立。
简述:
注册传入了两个主要参数(服务名:activity,Binder:this)。经过一系列调用,最终将服务的名称和Binder等写入到了数据包Parcel(data)中,最终进入了Binder驱动。Binder驱动为AMS建立了binder结点binder_node。最后Binder驱动将相关信息给到ServerManager进程,ServiceManager将其封装加入svclist列表完成注册。
系统启动后,这个服务即开始注册。这个很简单,注意传入的服务名是Context.ACTIVITY_SERVICE(即activity),以及this(AMS自己,也是继承了IBinder的Binder实体)。
SystemServer.java: private void startBootstrapServices() { ...... mActivityManagerService.setSystemProcess(); ...... } ActivityManagerService.java: public void setSystemProcess() { ...... ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); ...... } ServiceManager.java: @UnsupportedAppUsage public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { ...... getIServiceManager().addService(name, service, allowIsolated, dumpPriority); ...... }
getIServiceManager().addService(),这里须要弄清楚的就是getIServiceManager()和addService()两个方法,下面正式开始注册流程。
ServiceManager.java: @UnsupportedAppUsage private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; }
关键的一句,这里有几个须要依次弄清楚的。
详细来看下这4点:
先看第一点(1/4)
BinderInternal.java: @UnsupportedAppUsage public static final native IBinder getContextObject(); frameworks/base/core/jni/android_util_Binder.cpp: { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
getContextObject()是native修饰的方法,经过jni,进入了C++。
下面主要来看下ProcessState::self()->getContextObject(NULL)和javaObjectForIBinder(env, b)。
-----回顾点2: getContextObject()具体获取的是什么
ProcessState.java: #ifdef __ANDROID_VNDK__ const char* kDefaultDriver = "/dev/vndbinder"; #else const char* kDefaultDriver = "/dev/binder"; #endif #define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) #define DEFAULT_MAX_BINDER_THREADS 15 sp<ProcessState> ProcessState::self() { ...... gProcess = new ProcessState(kDefaultDriver); return gProcess; } ProcessState::ProcessState(const char *driver) : mDriverName(String8(driver)) , mDriverFD(open_driver(driver)) ...... { ...... mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); ...... } static int open_driver(const char *driver) { int fd = open(driver, O_RDWR | O_CLOEXEC); if (fd >= 0) { int vers = 0; status_t result = ioctl(fd, BINDER_VERSION, &vers); ...... size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); ...... }
从代码可以看到最终经过open_driver()方法打开了/dev/binder或者/dev/vndbinder驱动。经过ioctl进入binder内核并创建联系,在binder内核中建立了binder_proc并设置进程的最大线程数。
注意两个个设置:
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) { return getStrongProxyForHandle(0); } sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; ...... handle_entry* e = lookupHandleLocked(handle); if (e != nullptr) { IBinder* b = e->binder; if (b == nullptr || !e->refs->attemptIncWeak(this)) { ....... b = BpBinder::create(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result; }
回到回顾点2,getContextObject()获取了句柄为0的BpBinder。先lookupHandleLocked()尝试获取,没有则建立了一个BpBinder对象。
BpBinder的handle,若是是0 则该BpBinder是servicemanager的binder引用,若是非0 其handle值就是不一样Service的hanlde 关联了各个Service。也就是说任何的系统service均可以经过BpBinder(0)就能知道servicemanager的地址。
-----注意点1: 这个handle为0的BpBinder很重要,binder驱动等地方都有关联。
frameworks/base/core/jni/android_util_Binder.cpp: jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { ...... if (val->checkSubclass(&gBinderOffsets)) { // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object. jobject object = static_cast<JavaBBinder*>(val.get())->object(); LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object); return object; } BinderProxyNativeData* nativeData = new BinderProxyNativeData(); nativeData->mOrgue = new DeathRecipientList; nativeData->mObject = val; jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get()); ...... return object; }
在注册过程,返回的是BinderProxy。前面知道传入的是BpBinder对象,这是native层的对象在Java层没法使用,转换成BinderProxy。
接着看第二点(2/4)
Binder.java: public static IBinder allowBlocking(IBinder binder) { try { if (binder instanceof BinderProxy) { ((BinderProxy) binder).mWarnOnBlocking = false; } else if (binder != null && binder.getInterfaceDescriptor() != null && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) { Log.w(TAG, "Unable to allow blocking on interface " + binder); } } catch (RemoteException ignored) { } return binder; }
这个没什么好说的。
再看第三点(3/4)
ServiceManagerNative.java: @UnsupportedAppUsage static public IServiceManager asInterface(IBinder obj) { ...... IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } ....... return new ServiceManagerProxy(obj); }
前面传递的参数obj是一个保存着BpBinder的BinderProxy对象,这个BpBinder的handle是0(即关联servicemanager,后续经过transact传入binder驱动 找到目标进程)。
queryLocalInterface获取本地binder,此时in返回是null,因此这里返回了一个ServiceManagerProxy对象,并传入了BinderProxy对象。后续就经过这个BinderProxy代理对象进行通讯。
回到回顾点1,从上面一系列能够看出getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
这句话:
getIServiceManager()获取的是ServiceManagerProxy对象,参数obj是BinderProxy。
接着看最后一点(4/4),addService()
最后来看下ServiceManagerProxy中的相关方法(ServiceManagerProxy是ServiceManagerNative内部类),即getIServiceManager().addService():
ServiceManagerNative.java: class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; } public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) 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); data.writeInt(dumpPriority); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); } }
注意data.writeStrongBinder(service);
这里写入的IBinder对象是AMS最初传入的this,是Binder的实例,而不是BinderProxy。
这里的mRemote即建立ServiceManagerProxy对象时传入的BinderProxy。
下面就是开始进入binder驱动了,得耐心接着看了。
这个写入过程稍微注意下。
Parcel: public final void writeStrongBinder(IBinder val) { nativeWriteStrongBinder(mNativePtr, val); } private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); frameworks/base/core/jni/android_os_Parcel.cpp: {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } } frameworks/base/core/jni/android_util_Binder.cpp: sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; // Instance of Binder? if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); return jbh->get(env, obj); } // Instance of BinderProxy? if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return getBPNativeData(env, obj)->mObject; } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; } class JavaBBinderHolder { public: sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { b = new JavaBBinder(env, obj); ...... }; class JavaBBinder : public BBinder { ..... }
上面已经说过,这里的service就是AMS对象,即Binder实例。因此writeStrongBinder()写入的service经过ibinderForJavaObject(env, object)封装成JavaBBinder(也即BBinder)。即服务Service对象转换成BBinder,传入到binder驱动了。
parcel->writeStrongBinder(ibinderForJavaObject(env, object)); --> Parcel.cpp: status_t Parcel::writeStrongBinder(const sp<IBinder>& val) { return flatten_binder(ProcessState::self(), val, this); } status_t flatten_binder(const sp<ProcessState>& /*proc*/, const sp<IBinder>& binder, Parcel* out) { ...... if (binder != nullptr) { BBinder *local = binder->localBinder(); if (!local) { ....... } else { obj.hdr.type = BINDER_TYPE_BINDER; .....
上面看到这里binder是BBinder对象,注意这里的hdr.type = BINDER_TYPE_BINDER ,在binder驱动中有使用。
接着Java层今后开始向binder驱动传递
BinderProxy: public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...... try { return transactNative(code, data, reply, flags); ...... } public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; frameworks/base/core/jni/android_util_Binder.cpp: {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException {...... Parcel* data = parcelForJavaObject(env, dataObj); Parcel* reply = parcelForJavaObject(env, replyObj); ...... IBinder* target = getBPNativeData(env, obj)->mObject.get(); ...... status_t err = target->transact(code, *data, reply, flags); ...... }
parcelForJavaObject将data、reply两个Parcel由Java对象转换成C++。
getBPNativeData()获取的是BpBinder对象。
frameworks/native/libs/binder/BpBinder.cpp: status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // Once a binder has died, it will never come back to life. if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); ...... } frameworks/native/libs/binder/IPCThreadState.cpp: status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { ...... err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr); err = waitForResponse(??); ...... } status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { tr.target.handle = handle; tr.code = code; ...... mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR; } status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { ...... while (1) { if ((err=talkWithDriver()) < NO_ERROR) break; ...... cmd = (uint32_t)mIn.readInt32(); ....... } status_t IPCThreadState::talkWithDriver(bool doReceive) { ...... do { ...... if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0) err = NO_ERROR; else err = -errno; ...... } while (err == -EINTR); ...... if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } ...... }
transact()中关键两步,writeTransactionData()和waitForResponse()。
writeTransactionData()将要传递的数据及命令写入到mOut。这里要发送的命令是BC_TRANSACTION。 在注意的是,handle标识的是目标端,这里是0。即注册中目标是Servicemanager(handle 0 对应 binder_context_mgr_node对象)。
waitForResponse()中while(1)死循环,经过talkWithDriver()中ioctl进入binder,这里传入到binder_ioctl的参数cmd是BINDER_WRITE_READ。
waitForResponse()很重要,在死循环中会对binder返回的应答进行处理,cmd = (uint32_t)mIn.readInt32();
获取应答的命令类型。
另外,注意下传入transact()中的flag为0(即非TF_ONE_WAY)。
经过ioctl(),进入了binder内核
{kernel}/drivers/android/binder.c static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { ..... switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read(filp, cmd, arg, thread); if (ret) goto err; break; ...... } static int binder_ioctl_write_read(struct file *filp, unsigned int cmd, unsigned long arg, struct binder_thread *thread) { ...... if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; goto out; } ...... if (bwr.write_size > 0) { ret = binder_thread_write(proc, thread, bwr.write_buffer, bwr.write_size, &bwr.write_consumed); ...... if (copy_to_user(ubuf, &bwr, sizeof(bwr))) ret = -EFAULT; goto out; ...... if (bwr.read_size > 0) { ret = binder_thread_read(proc, thread, bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); ...... } static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size, binder_size_t *consumed) { ...... void __user *buffer = (void __user *)(uintptr_t)binder_buffer; void __user *ptr = buffer + *consumed; ...... if (get_user(cmd, (uint32_t __user *)ptr)) ...... switch (cmd) { ...... case BC_TRANSACTION: case BC_REPLY: { struct binder_transaction_data tr; if (copy_from_user(&tr, ptr, sizeof(tr))) return -EFAULT; ptr += sizeof(tr); binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0); break; } ...... } }
经过系统调用,进入binder驱动的binder_ioctl()方法,这里传入的cmd是BINDER_WRITE_READ(),上面 BpBinder中的transact()有说。
上面 BpBinder中的transact()也说过发送命令在mOut中是BC_TRANSACTION,这时经过copy_from_user()从用户空间拷贝数据到了内核空间。最终进入到binder_transaction()事务处理。
注意第四个参数cmd==BC_REPLY为false 。
static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply, binder_size_t extra_buffers_size) { ..... if(reply){ ...... }else { if (tr->target.handle) { ...... } else { ...... target_node = context->binder_context_mgr_node; ...... } } ...... switch (hdr->type) { case BINDER_TYPE_BINDER: case BINDER_TYPE_WEAK_BINDER: { struct flat_binder_object *fp; fp = to_flat_binder_object(hdr); #ifdef BINDER_WATCHDOG ret = binder_translate_binder(tr, fp, t, thread); #else ret = binder_translate_binder(fp, t, thread); #endif ...... tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; t->work.type = BINDER_WORK_TRANSACTION; ...... if (!binder_proc_transaction(t, target_proc, } #ifdef BINDER_WATCHDOG static int binder_translate_binder(struct binder_transaction_data *tr, ...... { struct binder_node *node; node = binder_get_node(proc, fp->binder); if (!node) { node = binder_new_node(proc, fp); if (!node) return -ENOMEM; #ifdef BINDER_WATCHDOG parse_service_name(tr, proc, node->name); #endif ...... ret = binder_inc_ref_for_node(target_proc, node, fp->hdr.type == BINDER_TYPE_BINDER, &thread->todo, &rdata); ...... if (fp->hdr.type == BINDER_TYPE_BINDER) fp->hdr.type = BINDER_TYPE_HANDLE; fp->binder = 0; fp->handle = rdata.desc; } /* this is an addService() transaction identified by: * fp->type == BINDER_TYPE_BINDER && tr->target.handle == 0 */ void parse_service_name(struct binder_transaction_data *tr,
binder_transaction()这个事务处理方法很长,这里主要说下几个注意点。
reply:前面流程传入的为false,cmd是BC_TRANSACTION。说明这是一个Client发给Server的请求事务,在Client端线程上。若为true,便是BC_REPLY说明这是一个Server发给Client的事务处理回复。在server端的线程上。
tr->target.handle:若是是BC_TRANSACTION(这里注册中是这个),接着判断tr->target.handle。若是>0,即目标为普通Service,若是为0,则目标service是ServiceManager。从而获取目标结点target_node,进一步获取目标进程、目标线程及相关信息。
前面有讲到传递的BBinder对象中hdr.type = BINDER_TYPE_BINDER。最终有走到binder_translate_binder,为注册服务建立了binder_node结点,保存了服务的进程及相关信息。
向servicemanager添加BINDER_WORK_TRANSACTION事务,接下来进入ServiceManager进程。
handle值(也待详细了解//TODO):
binder_get_node()->binder_new_node()->binder_inc_ref_for_node()->binder_get_ref_for_node_olocked(),不详述。
new_ref->data.desc,data.desc即handle。
handle值计算方法规律:
每一个进程binder_proc所记录的binder_ref的handle值是从1开始递增的;
全部进程binder_proc所记录的handle=0的binder_ref都指向service manager;
同一个服务的binder_node在不一样进程的binder_ref的handle值能够不一样;
接下来的注册过程进入ServiceManager,从下面ServiceManager的建立过程了解。
ServiceManager自己也是Binder服务,但它经过自身的binder.c与Binder驱动直接通讯。经过循环binder_loop进行读取和处理事务。
主要关注两个文件:frameworks/native/cmds/servicemanager/service_manager.c
和frameworks/native/cmds/servicemanager/binder.c
。
系统启动经过init.rc建立并启动servicemanager。直接看其中main()方法。
frameworks/native/cmds/servicemanager/service_manager.c: int main(int argc, char** argv) { ...... //打开binder驱动,申请128k字节大小的内存空间 bs = binder_open(driver, 128*1024); ...... if (binder_become_context_manager(bs)) { ...... binder_loop(bs, svcmgr_handler); ...... }
重点须要关注的是上述3个方法,依次来看:
struct binder_state *binder_open(const char* driver, size_t mapsize) { ...... bs->fd = open(driver, O_RDWR | O_CLOEXEC); ...... if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) || (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { ...... bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); ...... } frameworks/native/cmds/servicemanager/binder.c: int binder_become_context_manager(struct binder_state *bs) { int result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR_EXT, &obj); // fallback to original method if (result != 0) { android_errorWriteLog(0x534e4554, "121035042"); result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); } } void binder_loop(struct binder_state *bs, binder_handler func) { ...... readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(uint32_t)); for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (uintptr_t) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); ...... res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); ...... } int binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func) { while (ptr < end) { uint32_t cmd = *(uint32_t *) ptr; case BR_TRANSACTION_SEC_CTX: case BR_TRANSACTION: { ...... res = func(bs, &txn, &msg, &reply); if (txn.transaction_data.flags & TF_ONE_WAY) { binder_free_buffer(bs, txn.transaction_data.data.ptr.buffer); } else { binder_send_reply(bs, &reply, txn.transaction_data.data.ptr.buffer, res); } ...... } void binder_send_reply(struct binder_state *bs, ...... { ...... data.cmd_reply = BC_REPLY; ...... binder_write(bs, &data, sizeof(data)); }
binder_open():这个比较简单,经过系统调用在binder驱动中建立binder_proc对象,调用mmap()内存映射分配了128K的内存空间。
binder_become_context_manager():使servicemanager成为上下文的管理者,建立了全局的binder_node对象binder_context_mgr_node。
binder_loop();这个是最重要的方法,进入死循环,等待Client端的请求。解析binder信息,此处参数ptr指向BC_ENTER_LOOPER,func指向svcmgr_handler。故有请求到来(如BR_TRANSACTION),则调用svcmgr_handler处理,处理完成后会发送BC_REPLY。
看看svcmgr_handler
frameworks/native/cmds/servicemanager/service_manager.c: int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data_secctx *txn_secctx, struct binder_io *msg, struct binder_io *reply) { ...... switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid, (const char*) txn_secctx->secctx); bio_put_ref(reply, handle); case SVC_MGR_ADD_SERVICE: if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority, txn->sender_pid, (const char*) txn_secctx->secctx)) ...... bio_put_uint32(reply, 0); ...... }
SVC_MGR_ADD_SERVICE就是从addService那拆解来的。SVC_MGR_GET_SERVICE相似。
ServiceManager最核心的两个功能为查询和注册服务:
注册服务:do_add_service(),记录服务名和handle信息,保存到svclist列表;
查询服务:do_find_service(),根据服务名查询相应的的handle信息。
这样,服务就注册到ServiceManager。可以被客户端获取。
同服务注册同样,先看下大体的流程图。
简述:
客户端经过binder驱动从servicemanager进程查询到服务的handle,servicemanager进程一样应答binder驱动,binder驱动经过处理,向客户端返回正确的数据命令,客户端从而获取到服务的Binder对象。完成获取服务的的操做。
直接来看
ActivityManager: @UnsupportedAppUsage public static IActivityManager getService() { return IActivityManagerSingleton.get(); } @UnsupportedAppUsage private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
ServiceManager: @UnsupportedAppUsage private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>(); @UnsupportedAppUsage public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return Binder.allowBlocking(rawGetService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } private static IBinder rawGetService(String name) throws RemoteException { ...... final IBinder binder = getIServiceManager().getService(name); ...... }
getIServiceManager()与注册时的流程差很少,返回的是ServiceManagerProxy对象,不在依次赘述了。
ServiceManagerNative.java-> class ServiceManagerProxy: @UnsupportedAppUsage 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; }
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
进入binder驱动的也与注册相似。很少赘述。
这里过程大体是,经过transact进入binder驱动,一样找到的目标端是servicemanager,向servicemanager发送请求(BR_TRANSACTION)查询服务(上述ServiceManager建立中),servicemanager查询服务得到服务的handle,经过BC_REPLY返回到binder驱动。binder驱动得到服务的handle,最终一样走到binder_transaction()。binder_thread_read()。
下面是一些信息(do_find_service()查询到服务handle后经过bio_put_ref回应的一些信息,binder中进行处理的重要信息):
void bio_put_ref(struct binder_io *bio, uint32_t handle) { ...... obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj->hdr.type = BINDER_TYPE_HANDLE; obj->handle = handle; obj->cookie = 0; }
static void binder_transaction(struct binder_proc *proc, ...... case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { struct flat_binder_object *fp; fp = to_flat_binder_object(hdr); ret = binder_translate_handle(fp, t, thread); ..... binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, object_offset, fp, sizeof(*fp)); } static int binder_translate_handle(struct flat_binder_object *fp, ...... if (node->proc == target_proc) { ...... if (fp->hdr.type == BINDER_TYPE_HANDLE) fp->hdr.type = BINDER_TYPE_BINDER; else fp->hdr.type = BINDER_TYPE_WEAK_BINDER; fp->binder = node->ptr; fp->cookie = node->cookie; ...... } else { ...... ret = binder_inc_ref_for_node(target_proc, node, fp->hdr.type == BINDER_TYPE_HANDLE, NULL, &dest_rdata); } }
经过上述方法依次走下去。在binder_translate_handle()
中,node->proc == target_proc
,当前是在servicemanager进程的,而目标进程是请求服务所在进程,因此等于判断不成立。
这个过程很是重要,分两种状况来讲:
当请求服务的进程与服务属于不一样进程,则为请求服务所在进程建立binder_ref对象,指向服务进程中的binder_node;
当请求服务的进程与服务属于同一进程,则再也不建立新对象,只是引用计数加1,而且修改type为BINDER_TYPE_BINDER或BINDER_TYPE_WEAK_BINDER。
经过binder_thread_read进行一些处理。binder向客户端发送BR_REPLY。
sp<IBinder> Parcel::readStrongBinder() const { ALOGW("BINDER_DEBUG Parcel->readStrongBinder()"); sp<IBinder> val; ...... readNullableStrongBinder(&val); return val; } status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const { ALOGW("BINDER_DEBUG Parcel->readNullableStrongBinder() val=%p", val); return unflatten_binder(ProcessState::self(), *this, val); } status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { ALOGW("BINDER_DEBUG Parcel->unflatten_binder() sp<IBinder> begin"); const flat_binder_object* flat = in.readObject(false); if (flat) { switch (flat->hdr.type) { case BINDER_TYPE_BINDER: *out = reinterpret_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(nullptr, *flat, in); case BINDER_TYPE_HANDLE: *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder( static_cast<BpBinder*>(out->get()), *flat, in); } } return BAD_TYPE; }
由上面分析知道,servicemanager传入的是BINDER_TYPE_HANDLE。请求服务与服务不在同一进程,这个值未变,还是BINDER_TYPE_HANDLE。getStrongProxyForHandle()注册时有讲过,这里再也不单独列出。这里就获取到了对应服务的BpBinder(handle)。handle是从servicemanager查到对应服务的handle。这样服务获取就完成了。
简单回顾总结下几个点
开始在 Binder---IPC 中所说的,服务注册与获取的大体过程:
服务经过binder驱动注册到ServiceManager,ServiceManager保存了服务的名称、handle等信息 并加入svclist列表中。客户端经过binder驱动向ServiceManager进程查询获取到对应的服务的handle,而后binder将信息返回给客户端,客户端获取获得相应的服务Binder。
总结下 一个完整的服务注册过程与binder交互命令大体以下图:
服务的注册和获取基本相似,两个过程,服务端都是ServiceManager。
Client端(BC_TRANSACTION)--->binder驱动(BR_TRANSACTION_COMPLETE)--->Client端; binder驱动(BR_TRANSACTION)--->Service端(BC_REPLY)--->binder驱动(BR_TRANSACTION_COMPLETE)--->Service端;binder驱动(BR_REPLY)--->Client端。
总结下readStrongBinder():
请求服务进程与服务进程不在同一进程(如这个服务获取),返回的是BpBinder对象。若是在同一进程,则不在建立新对象 只是引用加1,返回的是BBinder对象。
咱们经过handle去获取远程端的Binder对象,如handle为0 就能获取到servicemanager的BpBinder对象,经过查询到的某个服务的handle获取到对应服务的BpBinder对象(本地则是BBinder对象)。
在注册时data.writeStrongBinder(service);
,经过ibinderForJavaObject()将service实体binder对象转换成BBinder,而后传入binder驱动,完成服务注册到servicemanager。
这里的BBinder和BpBinder都是native层的Binder对象。 BBinder是本地Binder(Native Binder),BpBinder即远程端Binder。
BpBinder提供transact()方法来发送请求;BBinder提供了onTransact()接口来接收请求。
BpBinder时客户端建立用于消息发送的代理;BBinder是服务端用于接收消息的。当通讯时,Client端经过BinderProxy 经由Bpbinder的transact()方法最终发送请求到binder驱动。binder驱动接收到通过处理,发送给目标进程JavaBBinder,最终经由服务实体的onTransact()接受处理。
在注册过程,servicemanager中svcmgr_handler()至关于服务端Java层的onTransact()。下面是普通服务接收到请求的过程:
frameworks/native/libs/binder/IPCThreadState.cpp sp<BBinder> the_context_object; status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) { ...... default: err = executeCommand(cmd); ...... } status_t IPCThreadState::executeCommand(int32_t cmd) { ...... case BR_TRANSACTION_SEC_CTX: case BR_TRANSACTION: { ...... if (tr.target.ptr) { ...... error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer, &reply, tr.flags); ...... } else { error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } ...... } frameworks/native/libs/binder/Binder.cpp status_t BBinder::transact( ...... err = onTransact(code, data, reply, flags); } frameworks/base/core/jni/android_util_Binder.cpp status_t onTransact( ...... jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags); ...... } gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); frameworks/base/core/java/android/os/Binder.java // Entry point from android_util_Binder.cpp's onTransact @UnsupportedAppUsage private boolean execTransact(int code, long dataObj, long replyObj, ...... return execTransactInternal(code, dataObj, replyObj, flags, callingUid); } private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags, ...... res = onTransact(code, data, reply, flags); }
这里onTransact()最终调用到子类实现的onTransact(),即具体服务实现的onTransact()方法。
从上又有通常这样的一个结构层次图(网络中不少,上述理解供参考):
struct binder_node { ...... struct binder_proc *proc; struct hlist_head refs; }
binder_node--->binder结点,即binder的实体。服务注册就会建立一个binder_node。
proc: binder_proc,这里是binder实体对应的进程,至关于某个服务在哪进程。
refs: binder实体的引用对象列表,至关于全部使用某个服务的客户端链表。
struct binder_ref { struct binder_ref_data data; struct binder_proc *proc; struct binder_node *node; } struct binder_ref_data { int debug_id; uint32_t desc; int strong; int weak; };
binder_ref--->跟踪结点的引用,binder_node的引用的信息
proc:引用对象进程,使用服务的进程
node:引用的binder_node,即引用的目标结点
desc:该引用对象的句柄(handle)
struct binder_proc { struct hlist_node proc_node; struct list_head todo; }
binder_proc--->binder进程的上下文信息,每一个使用binder的进程都会建立一个binder_proc对象。在打开/dev/binder时就建立了。
proc_node:将该对象连接到全局binder_procs对象中。
todo:该进程的待处理事务队列。
binder驱动结构体不少,须要多注意,不过都有注释,理解不难。