Binder机制结构图:
ServiceManagerProxy中的所有服务接口都是static的,用户不用额外创建任何类对象就可以直接使用ServiceManager的功能。
首先看ServiceManager(Java)中getService的实现:
/* \Android4.4\frameworks\base\core\java\android\os\ServiceManager.java*/
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();à sCache作为缓存,加快查询速度 public static IBinder getService(String name) { try { IBinder service = sCache.get(name);à查询缓存 if (service != null) { return service;à返回结果 } else { return getIServiceManager().getService(name); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } |
/* \Android4.4\frameworks\base\core\java\android\os\ServiceManager.java*/
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; }
// Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());à获取IServiceManager return sServiceManager; } |
/* \Android4.4\frameworks\base\core\java\android\os\ServiceManagerNative.java*/
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); } |
asInterface函数负责将一个Binder对象转换成IServiceManager并在必要是创建ServiceManagerProxy。
这里的IBinder对象(obj)是通过BinderInternal.getContextObject()得到的。
asInterface函数的处理逻辑分为以下两部分:
queryLocalInterface:查询本地是否已经有IServiceManager存在
如果没有查询到则创建IServiceManager
/* \Android4.4\frameworks\base\core\java\android\os\ServiceManagerNative.java*/
public ServiceManagerProxy(IBinder remote) { mRemote = remote; } |
构造函数简单的记录IBinder对象。
/* \Android4.4\frameworks\base\core\java\android\os\ServiceManagerNative.java*/
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; } |
该函数实现以下功能:
准备Parcel数据
IBinder .transact:利用IBinder的transact将请求发出,而不用理会Binder驱动中open,mmap以及Binder指令。所以IBinder中一定会在内部使用ProcessState和IPSThreadState来与Binder驱动通信
获取结果
IBinder是一个接口的定义如下:
/* \Android4.4\frameworks\base\core\java\android\os\IBinder.java*/
public interface IBinder { … public IInterface queryLocalInterface(String descriptor); … public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException; |
在创建ServiceManagerProxy时,传入了一个IBinder对象,然后借助它的transact方法就可以方便的与Binder驱动通信了,这个对象是通过BinderInternal类获取的:
/* \Android4.4\frameworks\base\core\java\com\android\internal\os\BinderInternal.java*/
public class BinderInternal { … public static final native IBinder getContextObject(); … |
这是一个native的方法,通过JNI调用本地代码实现,实现如下:
/* \Android4.4\frameworks\base\core\jni\android_util_Binder.cpp*/
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); } |
通过ProcessState创建对象然后转化为Java层的IBinder对象。
实现ProcessState的关键点在于:
保证同一进程中只有一个ProcessState实例存在,而且只有在ProcessState对象创建时才打开Binder设备以及做内存映射
向上次提供IPC服务
ProcessState的实现代码:
/* \Android4.4\frameworks\native\libs\binder\ProcessState.cpp*/
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess; } |
保证一个进程中只有一个ProcessState实例。
ProcessState的构造函数如下:
/* \Android4.4\frameworks\native\libs\binder\ProcessState.cpp*/
ProcessState::ProcessState() : mDriverFD(open_driver())àopen_driver() , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) {à成功打开/dev/binder // XXX Ideally, there should be a specific define for whether we // have mmap (or whether we could possibly have the kernel module // availabla). #if !defined(HAVE_WIN32_IPC) // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);à开始执行mmap,内存大小为:BINDER_VM_SIZE=(1*1024*1024 – (4096*2)) if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } #else mDriverFD = -1; #endif }
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); } |
/* \Android4.4\frameworks\native\libs\binder\ProcessState.cpp*/
static int open_driver() { int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers; status_t result = ioctl(fd, BINDER_VERSION, &vers); 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; } size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } } else { ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); } return fd; } |
接下来查看如何创建IBinder对象的:
/* \Android4.4\frameworks\native\libs\binder\ProcessState.cpp*/
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { return getStrongProxyForHandle(0); } |
实现函数:
/* \Android4.4\frameworks\native\libs\binder\ProcessState.cpp*/
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);à查找一个vector表mHandleToObject,这里保存了这个进程中已经创建的Binder相关信息
if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { // Special case for context manager... // The context manager is the only object for which we create // a BpBinder proxy without already holding a reference. // Perform a dummy transaction to ensure the context manager // is registered before we create the first local reference // to it (which will occur when creating the BpBinder). // If a local reference is created for the BpBinder when the // context manager is not present, the driver will fail to // provide a reference to the context manager, but the // driver API does not return status. // // Note that this is not race-free if the context manager // dies while this code runs. // // TODO: add a driver API to wait for context manager, or // stop special casing handle 0 for context manager and add // a driver API to get a handle to the context manager with // proper reference counting.
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; 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; } |
ProcessState中有一个全局列表来记录所有与Binder对象相关的信息,每个表都是一个handle_entry结构体,代码如下:
/* \Android4.4\frameworks\native\libs\binder\ProcessState.h*/
struct handle_entry { IBinder* binder; RefBase::weakref_type* refs; }; |
其中binder属性实际上是一个BpBinder,只有在两种情况下才会生成一个BpBinder:
在列表中没有找到对应的BpBinder
虽然从列表中查找到了对应的节点,但是没有办法顺利对这个BpBinder增减weakreference