上一篇文章中讲述了大管家servicemanager的启动流程,其中servicemanager多次与binder驱动交互,最终由于读取不到service们发送的命令而挂起进程。本篇文章将以一个service启动为例,分析service启动的流程,以便大家更好的理解binder机制中各个角色的交互关系。
首先上一篇文章中提到:XXXManagerService: 服务提供者。可以理解解为“淘宝卖家”。作为“淘宝卖家”的service们首先要向servicemanager(淘宝网站)注册它们的信息,那么问题来了,怎么向servicemanager注册它们的信息呢?通过上一篇文章我们了解到servicemanager将自己注册成了“大管家”,并且这个大管家是独一无二的,这样的话service们只要进入binder驱动中告诉它:“我需要这个独一无二的‘大管家’”,那么binder驱动就会找到servicemanager交给service们,service们再将自己注册到servicemanager中即可。流程到此还不算完因为虽然service虽然已经向servicemanager注册了,但是它最本职的工作是面向应用程序的,它需要向应用程序或者其他任何需要服务的程序提供服务,类比“淘宝卖家”最本职的工作是给“淘宝买家”提供商品。分析到此,有可能有些读者可能会发现,servicemanager为service们提供注册功能,那么servicemanager算不算是一个特殊的service呢?答案是肯定的,不同的是service们服务的目标是普通进程,而servicemanager是专门为service们提供服务的服务。那么根据上一篇文章的分析,可以知道既然service想要为其他普通进程提供服务,必然要接收它们提供的命令,类似淘宝买家要向淘宝卖家发送“我要买某某某商品”命令。那么根据推断service里面肯定有一个循环来接收普通进程发送的命令,就像servicemanager这个特殊的service一样,它有一个binder_looper中的for循环来接收service们发出的命令。
经过上一段的分析,应该还是不能对service的启动流程有清晰的认识,只要稍有印象即可。在接下来的篇幅中会一步一步分析service的启动过程,相信会对service的启动有更深刻的理解。
要说明的是service众多,有的是以标准C语言程序存在,有的是以java语言程序存在,本篇文章先分析java语言程序的service,而C语言的service将在下一篇文章中介绍。取ActivityManagerService(AMS)的启动作为代表进行分析,其他service启动大同小异。
关于AMS启动首先做一下说明:在Android系统启动时会创建SystemServer进程,源代码地址在frameworks/base/services/java/com/android/server/SystemServer.java,而该进程启动后会经过一系列操作调用两个方法,一个是init1方法,一个是init2方法,init1方法中讲主讲的C语言service启动,而init2方法则启动java语言实现的service,至于SystemServer进程如何启动,以及init1和init2方法如何调用会在文章后面讲解,此处暂时知道这两个方法会在SystemServer进程启动时依次调用即可。
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
位置:frameworks/base/services/java/com/android/server/SystemServer.java
程序较短,首先创建ServerThread线程,然后启动该线程。
接下里进入ServerThread线程中查看代码。
class ServerThread extends Thread {
@Override
public void run() {
...
context = ActivityManagerService.main(factoryTest);
...
ActivityManagerService.setSystemProcess();
...
}
}
位置:frameworks/base/services/java/com/android/server/SystemServer.java
ServerThread的主要功能是启动java层的各个service,只分析与AMS启动相关内容。run方法中调用ActivityManagerService静态方法main和setSystemProcess,首先分析ActivityManagerService的main方法。
public static final Context main(int factoryTest) {
AThread thr = new AThread();
thr.start();
synchronized (thr) {
while (thr.mService == null) {
try {
thr.wait();
} catch (InterruptedException e) {
}
}
}
ActivityManagerService m = thr.mService;
mSelf = m;
....
}
位置:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
忽略无关代码。main方法中首先启动了Athread线程,然后获取thr对象锁,进入临界区,若thr.mService的值为空,则阻塞当前线程,等待唤醒,可以猜测,在Athread线程中一定有关于thr.mService的赋值操作。下面进入到AThread中分析代码。
static class AThread extends Thread {
ActivityManagerService mService;
...
public AThread() {
super("ActivityManager");
}
public void run() {
...
ActivityManagerService m = new ActivityManagerService();
synchronized (this) {
mService = m;
notifyAll();
}
...
}
}
位置:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
忽略无关代码。AThread的run方法中首先创建了一个ActivityManagerService对象,然后进入临界区,将ActivityManagerService对象赋值为mService,再唤醒所有在AThread上等待的线程,这样执行main方法的线程将被唤醒继续执行。而main方法剩余操作将创建的ActivityManagerService对象赋值给了静态成员变量mSelf。这样main方法中关于AMS启动的部分就分析完了,接下来分析ServerThread中执行的ActivityManagerService.setSystemProcess()。
public static void setSystemProcess() {
...
ActivityManagerService m = mSelf;
ServiceManager.addService("activity", m);
....
}
位置:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
忽略无关代码。setSystemProcess只是将main方法中赋值的mSelf取出然后传入到ServiceManager.addService中去。接下来分析ServiceManager.addService方法。
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
位置:frameworks/base/core/java/android/os/ServiceManager.java
方法又将”activity”和mSelf转发给getIServiceManager().addService方法。注意这里的addService方法接收的是String类型和IBinder类型的参数,查看ActivityManagerService.java知道ActivityManagerService继承自ActivityManagerNative,而ActivityManagerNative又继承自Binder,Binder实现了IBinder接口。接下来先分析getIServiceManager()方法的执行。
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 获取sServiceManager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
位置:fameworks/base/core/java/android/os/ServiceManager.java
首先判断sServiceManager是否已经赋值,避免重复操作,sServiceManager声明为IServiceManager。下一句代码便是创建sServiceManager的地方,首先调用了静态方法BinderInternal.getContextObject(),先分析该方法。
public static final native IBinder getContextObject();
位置:frameworks/base/core/java/com/android/internal/os/BinderInternal.java
getContextObject方法是native方法,对应frameworks/base/core/jni/android_util_Binder.cpp中的android_os_BinderInternal_getContextObject函数,关于android系统如何映射native方法,后续文章会进行讲解,后面会多次遇到native方法,按照文章思路继续分析即可。接下来进入step2,分析getContextObject的执行结果。
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
首先解释一下sp,sp是smart pointer的缩写,意为智能指针,我们知道在C语言中内存的申请后必须手动释放,否则就会出现内存泄漏现象,在Android系统中,为了避免内存泄漏,定义了智能指针,实现内存的自动释放。其大概原理是,当智能指针的指向的对象引用被引用的次数为0时会自动释放内存。此处定义了一个指向IBinder类型的智能指针b,而ProcessState::self()->getContextObject(NULL)则返回一个IBinder类型的值。下面我们先进入静态函数ProcessState::self()中分析。
sp ProcessState::self()
{
if (gProcess != NULL) return gProcess;
AutoMutex _l(gProcessMutex);
if (gProcess == NULL) gProcess = new ProcessState;
return gProcess;
}
位置:frameworks/base/libs/binder/ProcessState.cpp
代码逻辑很简单,这是一个进程单例,整个进程中只有一个ProcessState对象,self方法返回该ProcessState对象。由于首次进入self函数,会调用构造函数创建该单例对象gProcess。下面进入ProcessState构造函数中分析。
ProcessState::ProcessState()
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// 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);
if (mVMStart == MAP_FAILED) {
// *sigh*
LOGE("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.");
}
位置:frameworks/base/libs/binder/ProcessState.cpp
首先调用了open_driver函数,并将返回值复制给mDriverFD变量,然后初始化了一堆其他的成员变量。可以猜测到open_driver函数应该就是打开binder驱动的函数,稍后我们再验证。然后该判断打开binder驱动打开是否成功,若成功打开,调用binder驱动提供的mmap函数映射内存。回顾上一篇文章servicemanager的启动,它在binder_open函数一样是进行了打开驱动和映射内存两项操作。下面分析open_driver函数。
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) {
LOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd = -1;
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
LOGE("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) {
LOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
} else {
LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
}
return fd;
}
位置:frameworks/base/libs/binder/ProcessState.cpp
同样是调用open函数打开binder驱动,然后进行错误判断,和servicemanager不同的是,该函数打开binder驱动后进行了两次ioctl函数的调用。这两次ioctl函数的调用发送的命令是BINDER_VERSION和BINDER_SET_MAX_THREADS,根据名字可以猜测到分别用来获取binder的版本,和设置最大线程数。下面先分析BINDER_VERSION的调用。
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
...
switch (cmd) {
...
case BINDER_VERSION:
if (size != sizeof(struct binder_version)) {
ret = -EINVAL;
goto err;
}
if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
ret = -EINVAL;
goto err;
}
...
}
...
}
位置:drivers/staging/android/binder.c
只分析case BINDER_VERSION内容。首先验证命令大小,然后将BINDER_CURRENT_PROTOCOL_VERSION的值写入&((struct binder_version *)ubuf)->protocol_version)中,而ubuf是在当前情况下传入的是int指针,此时将其强制转换为struct binder_version指针,并且binder_version中只有一个protocol_version属性,因此当相当于将BINDER_CURRENT_PROTOCOL_VERSION的值直接存入到传入参数&vers指向的地址中去。接下来分析另一个ioctl函数调用。
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
...
switch (cmd) {
...
case BINDER_SET_MAX_THREADS:
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret = -EINVAL;
goto err;
}
break;
...
}
...
}
位置:drivers/staging/android/binder.c
只分析case BINDER_SET_MAX_THREADS内容。此处将传入的maxThreads值复制到当前进程的binder_proc的max_threads变量中去。这样open_driver函数的调用就分析完成了。而ProcessState构造函数的剩余代码只是一些出错分析,这样ProcessState::self函数也执行完了,并返回到android_os_BinderInternal_getContextObject中执行getContextObject函数且传入参数为NULL。接下来进入ProcessState的getContextObject函数继续分析。
sp ProcessState::getContextObject(const sp& caller)
{
return getStrongProxyForHandle(0);
}
位置:frameworks/base/libs/binder/ProcessState.cpp
此处调用了getStrongProxyForHandle函数且传入值为0,继续分析getStrongProxyForHandle函数。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
//加锁
AutoMutex _l(mLock);
//通过参数handler查找handle_entry结构体
handle_entry* e = lookupHandleLocked(handle);
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)) {
b = new BpBinder(handle);
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;
}
位置:frameworks/base/libs/binder/ProcessState.cpp
首先定义返回值result,然后加锁,再从本地列表中handle_entry,若查不到则会创建一个返回给e,lookupHandleLocked的执行可自行查看。此时假设第一次执行getStrongProxyForHandle(0),显然if语句为真,b的值为NULL,则下一个if语句为真,创建BpBinder对象,并传入handler即0,再将b的值赋值给e->binder以便下次使用不再创建。接下里来将b的引用计数器赋值给e->refs,最后赋值b给result。总的来说该函数就是通过handler值创建了一个BpBinder的代理对象,并且将这个代理类存储到列表中,以便下次使用相同的handler调用该函数时不需要重新创建BpBinder。关于代理对象的意思可以查找关于设计模式中代理模式的用法,不再赘述。这样代码返回到android_os_BinderInternal_getContextObject函数继续执行,android_os_BinderInternal_getContextObject最后将javaObjectForIBinder的返回值return。javaObjectForIBinder函数的作用根据名字可以猜测,它应该是通过IBinder参数创建一个java的对象。javaObjectForIBinder函数在以后的分析中会经常使用,此处稍做解释,我们知道getStrongProxyForHandle只是创建了一个C语言层面的BpBinder,其中BpBinder继承了IBinder,那么这个BpBinder最终要拿来返回给java语言使用,但是它偏偏是一个C语言的对象,那么就需要一个java类来代表BpBinder,这个java类就是BinderProxy,位于frameworks/base/core/java/android/os/Binder.java中,巧妙的是BinderProxy中有一个int类型的属性mObject,它用来存储C语言层面的BpBinder的地址,这样下次需要使用BpBinder时就从BinderProxy的mObject中取出BpBinder的地址来操作BpBinder即可。概括的来说就是在BpBinder这个类上再加一层代理类BinderProxy,这种跨两种语言的代理模式经常在Android系统中出现。这样应该就明白了javaObjectForIBinder就是根据getStrongProxyForHandle返回的BpBinder创建了一个BinderProxy。关于javaObjectForIBinder的代码内容不再解释,有兴趣的可以自行研读。这样代码就一层层的返回到了getIServiceManager的执行中去,getIServiceManager方法最后将调用ServiceManagerNative.asInterface且参数为返回的BinderProxy,下面进入ServiceManagerNative.asInterface中分析。
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);
}
位置:frameworks/base/core/java/android/os/ServiceManagerNative.java
首先检查参数合法性,然后调用queryLocalInterface方法,queryLocalInterface的作用是查看要申请的service是否是本进程中的service,很明显要申请的servicemanager不在本进程中,最后创建了一个ServiceManagerProxy并传入了IBinder,这里ServiceManaagerProxy是对BinderProxy的进一步代理。这样getIServiceManager方法就执行完毕了,返回到再上一层的addService中执行,接着addService调用了getIServiceManager返回的ServiceManagerProxy实例的addService方法且传入参数name和ServiceManagerProxy,这里name是字符串“activity”,如果忘记的话可以反回前面相关的部分查看,可以注意到addService方法中有一个try-catch用来捕捉RemoteException, 这是一个远程连接异常,这样我们就可以猜测到接下来要执行的addService方法应该会涉及到远程连接,远程连接是什么呢?这里当然通过binder驱动和servicemanager程发生数据交互了!接下来进入step3分析addService方法的执行。
public void addService(String name, IBinder service)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
位置:frameworks/base/core/java/android/os/ServiceManagerNative.java
首先从step2中我们知道调用addService函数的IBinder其实是一个ServiceManagerProxy实例。addService函数中首先创建了data和reply两个Parcel的实例,这个Parcel是什么呢?可以把它理解成一种“包裹”,“包裹”里放着要进行IPC的数据,其中IPC包括数据读取和数据写入,data对应要写入的数据,而reply对应读取的数据。理解完Parcel的作用,我们再来看看它是如何实现的,这里要注意的是,Parcel这个概念在java和C语言层面都存在,几乎伴随着整个Binder机制,因此我们先分析Parcel的创建过程,其他操作待用到再进行分析。
...
private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
...
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
synchronized (pool) {
Parcel p;
for (int i=0; iif (p != null) {
pool[i] = null;
if (DEBUG_RECYCLE) {
p.mStack = new RuntimeException();
}
return p;
}
}
}
return new Parcel(0);
}
位置:frameworks/base/core/java/android/os/Parcel.java
一般来说,java的名为obtain的工厂方法都是实现了实例缓冲池的,这里也不例外,首先类赋值默认的缓冲池给pool数组,然后进入临界区,从缓冲池中取实例,若缓冲池中有实例,则取出并返回,且将池中该位置实例置空。若无实例则以0为参数调用构造函数创建实例。这里由于sOwnedPool只是一个空数组,并没有填入实例,因此取不到实例,所以调用new Parcel(0)。
private Parcel(int obj) {
if (DEBUG_RECYCLE) {
mStack = new RuntimeException();
}
//Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
init(obj);
}
位置:frameworks/base/core/java/android/os/Parcel.java
构造函数调用了init方法。
private native void init(int obj);
位置:frameworks/base/core/java/android/os/Parcel.java
init函数是本地方法,接下来进入本地层代码分析。
static void android_os_Parcel_init(JNIEnv* env, jobject clazz, jint parcelInt)
{
Parcel* parcel = (Parcel*)parcelInt;
int own = 0;
if (!parcel) {
//LOGI("Initializing obj %p: creating new Parcel\n", clazz);
own = 1;
parcel = new Parcel;
} else {
//LOGI("Initializing obj %p: given existing Parcel %p\n", clazz, parcel);
}
if (parcel == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
//LOGI("Initializing obj %p from C++ Parcel %p, own=%d\n", clazz, parcel, own);
env->SetIntField(clazz, gParcelOffsets.mOwnObject, own);
env->SetIntField(clazz, gParcelOffsets.mObject, (int)parcel);
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
因为传入参数obj为0因此,指针parcel被赋值为NULL。然后判断parcel是否为NULL,此处为NULL,则赋值own为1,新建本地层的Parcel对象。然后做错误检查,最后将own的值赋值给clazz的mOwnObject变量,也就是java层的Parcel的mOwnObject变量,同理赋值给mObject变量。这里可以理解为java层的Parcel类只是作为本地层Parcel类的代理类而已,真正存储数据的还是本地层的Parcel实例。这样就回到了addService方法中继续执行了。接下来执行data.writeInterfaceToken(IServiceManager.descriptor);因此继续分析writeInterfaceToken函数。
public final native void writeInterfaceToken(String interfaceName);
位置:frameworks/base/core/java/android/os/Parcel.java
首先IServiceManager.descriptor变量是字符串“android.os.IServiceManager”。writeInterfaceToken是本地方法。
static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jobject clazz, jstring name)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
// In the current implementation, the token is just the serialized interface name that
// the caller expects to be invoking
const jchar* str = env->GetStringCritical(name, 0);
if (str != NULL) {
parcel->writeInterfaceToken(String16(str, env->GetStringLength(name)));
env->ReleaseStringCritical(name, str);
}
}
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
首先从java层取出对应的本地层Parcel对象。若不为NULL,则取出字符串“android.os.IServiceManager”,再判断取出字符串不为空,则调用parcel对象的writeInterfaceToken函数,最后释放字符串。下面分析本地层writeInterfaceToken函数的执行。
// Write RPC headers. (previously just the interface token)
status_t Parcel::writeInterfaceToken(const String16& interface)
{
writeInt32(IPCThreadState::self()->getStrictModePolicy() |
STRICT_MODE_PENALTY_GATHER);
// currently the interface identification token is just its name as a string
return writeString16(interface);
}
位置:frameworks/base/libs/binder/Parcel.cpp
该函数注释写道“Write RPC headers. (previously just the interface token)”,意思是“写入RCP头部信息。(最前面只是接口的token)”,另一个注释:“currently the interface identification token is just its name as a string”,意思是“当前的的接口身份标识符就是它的一个字符串名称”。大概可以猜测出,writeInt32函数用于写入一个标识符没有实用信息,而writeString16用于写入鉴别身份的标识,也就是写入字符串“android.os.IServiceManager”,这两个函数就不再深入分析了,只是往Parcel中写入对应数据而已。这样就回到了addService方法中了,接下来将执行data.writeString(name);。
public final native void writeString(String val);
位置:frameworks/base/core/java/android/os/Parcel.java
writeString依然是本地方法。
static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring val)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
status_t err = NO_MEMORY;
if (val) {
const jchar* str = env->GetStringCritical(val, 0);
if (str) {
err = parcel->writeString16(str, env->GetStringLength(val));
env->ReleaseStringCritical(val, str);
}
} else {
err = parcel->writeString16(NULL, 0);
}
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
同样是先取出java层Parcel实例对应本地层的Parcel对象,然后使用writeString16函数将字符串“activity”写入。然后执行data.writeStrongBinder(service);。
public final native void writeStrongBinder(IBinder val);
位置:frameworks/base/core/java/android/os/Parcel.java
依然是本地方法。
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
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
同样先找到本地层Parcel,然后调用了writeStrongBinder函数。再将传入的ActivityManagerService,也就是jobject object,作为参数调用ibinderForJavaObject函数。接下来分析ibinderForJavaObject函数。
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetIntField(obj, gBinderProxyOffsets.mObject);
}
LOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
从名字可以看出来这是一个从java层的IBinder对象转换为本地层IBinder的函数,是不是有点类似Parcel,没错IBinder实体,也就是AMS,或者说服务实体在java层和本地层也是一一对应的,可是这里是转换为本地层的IBinder,AMS并没有创建对应的本地层IBinder啊?其实这里它已经创建了,与Parcel在构造函数中创建一样,AMS也是在它的构造函数中茶创建了本地层对应的IBinder,之前我们并没有分析这部分代码,现在回头分析AMS的创建。还记得frameworks/base/services/java/com/android/server/am/ActivityManagerService.java中的AThread线程吗?在它的run方法中调用了new ActivityManagerService(),这里创建的AMS实例也就是ibinderForJavaObject传入的jobject obj,我们知道ActivityManagerService继承自ActivityManagerNative,而ActivityManagerNative又继承自Binder,所以在ActivityManagerService构造函数调用时Binder的构造函数也调用,在它的构造函数里就完成了本地层的IBinder创建。
public Binder() {
init();
if (FIND_POTENTIAL_LEAKS) {
final Class extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
}
位置:frameworks/base/core/java/android/os/Binder.java
这里只有init起到了作用。
private native final void init();
位置:frameworks/base/core/java/android/os/Binder.java
本地方法。
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
LOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
}
位置:frameworks/base/core/jni/android_util_Binder.cpp
这里首先创建了JavaBBinderHolder对象,然后增加它的强引用,最后再把它的地址存入java层IBinder也就是Binder(AMS)实例的mObject属性中,以便进入本地层使用。从JavaBBinderHolder名字可以猜测它一个Holder,那么它应该持有一个本地层IBinder,那么我们继续分析JavaBBinderHolder类。
class JavaBBinderHolder : public RefBase
{
public:
sp get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp mBinder;
};
位置:frameworks/base/core/jni/android_util_Binder.cpp
可以看到它持有一个JavaBBinder对象,可是它暂时是NULL值。这样我们再回到ibinderForJavaObject函数中,根据函数内容,首先判断AMS是否是一个Binder对象,当然是,则首先取出AMS中存储的JavaBBinderHolder,再执行return jbh != NULL ? jbh->get(env, obj) : NULL;,所以执行了 jbh->get(env, obj),我们分析它的get函数,代码逻辑较简单,首先从取出JavaBBinder,若JavaBBinder为空则创建一个JavaBBinder并赋值给mBinder,最后返回创建的JavaBBinder。那么我们接着分析下JavaBBinder的构造函数。
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
LOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
...
private:
...
jobject const mObject;
};
位置:frameworks/base/core/jni/android_util_Binder.cpp
JavaBBinder调用构造函数时将AMS,也就是java层Binder实体存入了mObject变量,这样就清楚了,JavaBBinder其实是 一个代理类,他用来代理java层的AMS。这样get函数执行完了,接着ibinderForJavaObject函数也执行完了,返回到android_os_Parcel_writeStrongBinder函数执行writeStrongBinder。
status_t Parcel::writeStrongBinder(const sp& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
位置:frameworks/base/libs/binder/Parcel.cpp
本函数调用了flatten_binder函数。
status_t flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
LOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
obj.cookie = NULL;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = local->getWeakRefs();
obj.cookie = local;
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = NULL;
obj.cookie = NULL;
}
return finish_flatten_binder(binder, obj, out);
}
位置:frameworks/base/libs/binder/Parcel.cpp
这里首先创建了flat_binder_object结构体,然后赋值了它的flags属性,其中0x7f转换为二进制位1111111,而FLAT_BINDER_FLAG_ACCEPTS_FDS定义在内核工程中,位置是drivers/staging/android/binder.h,其值是0x100,二进制为100000000,做与运算结构是101111111。显然binder不为空,进入if语句后调用binder->localBinder(),我们知道传入进来的binder是ibinderForJavaObject函数返回的JavaBBinder,如果忘记的话可以查看前面的分析。而JavaBBinder继承自BBinder,那么我们接着分析BBinder的localBinder函数。
BBinder* BBinder::localBinder()
{
return this;
}
位置:frameworks/base/libs/binder/Binder.cpp
返回的就是当前BBinder。那么继续分析flatten_binder,进入else语句执行obj.type = BINDER_TYPE_BINDER; obj.binder = local->getWeakRefs(); obj.cookie = local;。最后调用finish_flatten_binder并返回。
inline static status_t finish_flatten_binder(
const sp& binder, const flat_binder_object& flat, Parcel* out)
{
return out->writeObject(flat, false);
}
位置:frameworks/base/libs/binder/Parcel.cpp
这里把flat_binder_object对象写入了Parcel,这样整个writeStrongBinder函数的执行也就完成了,我们总结一下writeStrongBinder的作用。它主要是将创建好的JavaBBinder,也就是AMS的代理类,封装成了flat_binder_object结构体,再把这个结构体写入到Parcel中去。这样我们再返回到addService函数,执行mRemote.transact函数,由于mRemote.transact这段语句执行完毕以后,跨进程告诉SM注册AMS也就执行完了,所以transact中有相当复杂的逻辑,我们留到下一篇文章中再分析。
总结: