1.内容简介:
Android Binder机制既提供IPC通信,又具有RPC功能,这样,对应上层应用程序提供了非常友好的API调用接口。实际上,为了支持支撑这一机制,从Android Framework到Native再到Binder Driver,是一个非常复杂的业务支撑系统。本节主要介绍在这个过程中,Binder在框架层的相关组件。
Binder源码分析系列文章:
Android系统源码分析-进程间通信机制binder(一):守护进程servicemanager
Android系统源码分析-进程间通信机制binder(二):binder内存映射
Android系统源码分析-进程间通信机制binder(三):从framework层到Native层
Android系统源码分析-进程间通信机制binder(四):从Native层到Driver层
2.Framework Binder架构:
从进程的角度,先看一下简化的Framework Binder结构:
说明:
Manager:属于Android Framework层,被用户App调用,它又调用Server的stub(通过代理proxy)。例如,ActivityManager,PackageManager...等。它运行在App所在的进程中。
Server:属于Android Framework层,向上提供服务,向下与servicemanager进行交互。
servicemanager:即服务管理,是一个守护进程。
Binder Driver:binder驱动。
Framework Binder相关组件:
为了支撑上述架构,Android提供了一系列的组件,如下图:
说明:
整个框架分为如下几层:
JAVA,JNI,C++,C层,这与Android系统框架是一致的;
1)JAVA层:
Service: 提供服务的组件,例如,ActivityManagerService,PackageMangerService。
Client:这里的client指的是Service的调用者,例如, ActivityManager,PackageManager。
SeiviceManager:提供service的管理,包括注册,获取service等;它的最大的特点是:它本身也是一个service,遵循C/S架构;同时,它又是其它service的管理类。用户要想访问到其它service,必须通过ServiceManager来实现。
parcel和Parcelable:用于Binder通信信息的数据结构;
IInterface:该接口是binder服务接口的父接口;
IBinder:Java层的IBinder类,提供了transact方法来调用远程服务;
Binder: 实现了IBinder接口,封装了JNI的实现。Java层Binder服务的基类;
IServiceManager:用于ServiceManager管理的基类;
2)JNI层:承上启下,进行各个组件的衔接(java层到Native层)。native即C/C++代码,jni使得程序员可以在C/C++端调用Java代码,也可以在Java端调用C/C++代码。下面这段代码展示了“如何进行java与native的衔接”:
以下代码截取自android_util_Binder.cpp:
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "getOrigCallingUidNative", "()I", (void*)android_os_Binder_getOrigCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy }
};
以下代码截取自android_os_Parcel.cpp注册的方法:
static const JNINativeMethod gParcelMethods[] = {
{"nativeDataSize", "(I)I", (void*)android_os_Parcel_dataSize},
{"nativeDataAvail", "(I)I", (void*)android_os_Parcel_dataAvail},
{"nativeDataPosition", "(I)I", (void*)android_os_Parcel_dataPosition},
{"nativeDataCapacity", "(I)I", (void*)android_os_Parcel_dataCapacity},
{"nativeSetDataSize", "(II)V", (void*)android_os_Parcel_setDataSize},
{"nativeSetDataPosition", "(II)V", (void*)android_os_Parcel_setDataPosition},
{"nativeSetDataCapacity", "(II)V", (void*)android_os_Parcel_setDataCapacity},
{"nativePushAllowFds", "(IZ)Z", (void*)android_os_Parcel_pushAllowFds},
{"nativeRestoreAllowFds", "(IZ)V", (void*)android_os_Parcel_restoreAllowFds},
{"nativeWriteByteArray", "(I[BII)V", (void*)android_os_Parcel_writeNative},
{"nativeWriteInt", "(II)V", (void*)android_os_Parcel_writeInt},
{"nativeWriteLong", "(IJ)V", (void*)android_os_Parcel_writeLong},
{"nativeWriteFloat", "(IF)V", (void*)android_os_Parcel_writeFloat},
{"nativeWriteDouble", "(ID)V", (void*)android_os_Parcel_writeDouble},
{"nativeWriteString", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString},
{"nativeWriteStrongBinder", "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
{"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor},
{"nativeCreateByteArray", "(I)[B", (void*)android_os_Parcel_createByteArray},
{"nativeReadInt", "(I)I", (void*)android_os_Parcel_readInt},
{"nativeReadLong", "(I)J", (void*)android_os_Parcel_readLong},
{"nativeReadFloat", "(I)F", (void*)android_os_Parcel_readFloat},
{"nativeReadDouble", "(I)D", (void*)android_os_Parcel_readDouble},
{"nativeReadString", "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString},
{"nativeReadStrongBinder", "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
{"nativeReadFileDescriptor", "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor},
{"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor},
{"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor},
{"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor},
{"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor},
{"nativeCreate", "()I", (void*)android_os_Parcel_create},
{"nativeFreeBuffer", "(I)V", (void*)android_os_Parcel_freeBuffer},
{"nativeDestroy", "(I)V", (void*)android_os_Parcel_destroy},
{"nativeMarshall", "(I)[B", (void*)android_os_Parcel_marshall},
{"nativeUnmarshall", "(I[BII)V", (void*)android_os_Parcel_unmarshall},
{"nativeAppendFrom", "(IIII)V", (void*)android_os_Parcel_appendFrom},
{"nativeHasFileDescriptors", "(I)Z", (void*)android_os_Parcel_hasFileDescriptors},
{"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
{"nativeEnforceInterface", "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
};
3)C++层(Native层):用于实现在java层定义的各个API,以及与下面的内核空间进行交互;
4)C层:这里主要指的是Android Binder Driver,相关内容,请参考前两节博文。
3. PackageManager Java层相关类图:
在App开始时,经常用到诸如ActivityManager,PackageManager...等组件(或者称为服务)。
本节以PackageManager来进行说明,各个组件的实现,相关类图如下:
相关代码:
frameworks/base/core/java/android/os/IBinder.java
frameworks/base/core/java/android/os/Binder.java
frameworks/base/core/java/android/os/IInterface.java
Client端:
frameworks/base/core/java/android/content/pm/PackageManager.java
frameworks/base/core/java/android/app/ApplicationPackageManager.java
Service端:
frameworks/base/core/java/android/content/pm/IPackageManager.aidl
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
这里,重点介绍一下AIDL。
AIDL:AIDL是Android中IPC(Inter-Process Communication)方式中的一种,AIDL是Android Interface definition language的缩写,AIDL的作用是,通过AIDL,可以在自己的APP里绑定一个其他APP的service,从而实现一个APP可以访问另外一个APP提供的服务。
从源码的角度来看,AIDL是以aidl为后缀的文件;在进行编译的时候,系统会将aidl编译为java文件。
可以看到:IPackageManager.接口就被定义在了IPackageManager.aidl文件中。
原始的IPackageManager.aidl文件如下:
interface IPackageManager {
PackageInfo getPackageInfo(String packageName, int flags, int userId);
int getPackageUid(String packageName, int userId);
int[] getPackageGids(String packageName);
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
PermissionInfo getPermissionInfo(String name, int flags);
List<PermissionInfo> queryPermissionsByGroup(String group, int flags);
PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
......
}
经过编译后的对应的java文件:
public interface IPackageManager extends android.os.IInterface{
//IPackageManager中定义的类Stub,Stub集成自Binder,并实现IPackageManager.aidl中定义的接口
public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager{
...
public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj){
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
//如果是当前进程,返回的是IPackageManager本身
if (((iin!=null)&&(iin instanceof android.content.pm.IPackageManager))) {
return ((android.content.pm.IPackageManager)iin);
}
//不是当前进程,返回的是代理类
return new android.content.pm.IPackageManager.Stub.Proxy(obj);
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
...
switch (code) {
case TRANSACTION_getPackageInfo:{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
int _arg1;
_arg1 = data.readInt();
int _arg2;
_arg2 = data.readInt();
android.content.pm.PackageInfo _result = this.getPackageInfo(_arg0, _arg1, _arg2);
reply.writeNoException();
if ((_result!=null)) {
reply.writeInt(1);
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
...//类似的case方法很多,这里只举例case TRANSACTION_getPackageInfo,其他代码省略
}
...
}
...
//类Stub中定义的代理类Proxy,Proxy中代理方法很多,这里同样只贴出了getPackageInfo方法
private static class Proxy implements android.content.pm.IPackageManager {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
...
@Override
public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.content.pm.PackageInfo _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(packageName);
_data.writeInt(flags);
_data.writeInt(userId);
mRemote.transact(Stub.TRANSACTION_getPackageInfo, _data, _reply, 0);
_reply.readException();
if ((0!=_reply.readInt())) {
_result = android.content.pm.PackageInfo.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
...
}
...
//这里的函数就是Stub实现的接口implements android.content.pm.IPackageManager,只列出来三个,别的都省略,继承接口方法必须全部实现,否则会报错
public void checkPackageStartable(java.lang.String packageName, int userId) throws android.os.RemoteException;
public boolean isPackageAvailable(java.lang.String packageName, int userId) throws android.os.RemoteException;
public android.content.pm.PackageInfo getPackageInfo(java.lang.String packageName, int flags, int userId) throws android.os.RemoteException;
...
}
分析:
1)IPackageManager 是继承自 android.os.IInterface的;
2)在IPackageManager中,提供了Stub抽象类。Stub类用于被外部的service来继承,这个类实现了IPackageManager.aidl中定义的接口;
3)在IPackageManager中,定义了私有静态类Proxy,Proxy类用于代理IPackageManager。外部的PackageManger调用的方法最终是由Proxy来实现的;
4)调用Proxy中的方法其实就是间接调用了Stub中的onTransact方法,在onTransact中最终调用了Stub实现的接口方法;
4. 服务注册:
我们所说的这些系统级服务,例如PackageMangerService,ActivityMangerService...等,是如何注册在servicemanager中的?本小节一起分析一下。
以PackageManagerService来看,
public static final IPackageManager main(Context context, boolean factoryTest,
boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
ServiceManager.addService("package", m);
return m;
}
可以看到,通过ServiceManager的addService来进行的注册。其中,第一个参数是要注册的服务的名称,这里是"package",第二个参数就是真正的服务的实例,即PackageManagerService。name和service是有对应关系的。这样,在后面使用service的时候,就可以通过name来找到具体的service了。
addService的代码:
/framework/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
分析:
1)getIServiceManager会获取到一个ServiceManager的实例,再通过这个实例去访问到ServiceManagerNative的对应的addService方法,最终调用到它的内部类ServiceManagerProxy的addService方法中。
ServiceManagerProxy的addService方法:
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.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);去调用
ServiceManagerNative的onTransact方法。与远端的服务进行通信。
在这个方法中:
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
try {
switch (code) {
case IServiceManager.GET_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = getService(name);
reply.writeStrongBinder(service);
return true;
}
case IServiceManager.CHECK_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = checkService(name);
reply.writeStrongBinder(service);
return true;
}
case IServiceManager.ADD_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
boolean allowIsolated = data.readInt() != 0;
addService(name, service, allowIsolated);
return true;
}
case IServiceManager.LIST_SERVICES_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String[] list = listServices();
reply.writeStringArray(list);
return true;
}
case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
IPermissionController controller
= IPermissionController.Stub.asInterface(
data.readStrongBinder());
setPermissionController(controller);
return true;
}
}
} catch (RemoteException e) {
}
return false;
}
public IBinder asBinder()
{
return this;
}
}
这里,只分析case IServiceManager.ADD_SERVICE_TRANSACTION的处理:
参数data的类型是Parcel,这个数据结构就是java与native进行数据交换的桥梁。
下面这些方法,最终都对应到native方法,这个对应关系是由android_os_Parcel.cpp完成的。如下表:
Parcel.java | android_os_Parcel.cpp |
data.enforceInterface(IServiceManager.descriptor); | {"nativeEnforceInterface", "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, |
data.readString(); | {"nativeReadString", "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString}, |
data.readStrongBinder(); | {"nativeReadStrongBinder", "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, |
data.readInt() | {"nativeReadInt", "(I)I", (void*)android_os_Parcel_readInt} |
最终,调用到native的Parcel.cpp中对应的函数中。
例如,Parcel::enforceInterface函数的实现:
bool Parcel::enforceInterface(const String16& interface,
IPCThreadState* threadState) const
{
int32_t strictPolicy = readInt32();
if (threadState == NULL) {
threadState = IPCThreadState::self();
}
if ((threadState->getLastTransactionBinderFlags() &
IBinder::FLAG_ONEWAY) != 0) {
// For one-way calls, the callee is running entirely
// disconnected from the caller, so disable StrictMode entirely.
// Not only does disk/network usage not impact the caller, but
// there's no way to commuicate back any violations anyway.
threadState->setStrictModePolicy(0);
} else {
threadState->setStrictModePolicy(strictPolicy);
}
const String16 str(readString16());
if (str == interface) {
return true;
} else {
ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
String8(interface).string(), String8(str).string());
return false;
}
}
可见,最终是通过IPCThreadState来实现,这就涉及到native层的具体binder的实现流程了。
下一节,分析native层相关代码。
5. PackageManagerService的初始化:
那么,PackageManagerService的main方法是什么时候被调用的呢?
答案就在system_server进程中。
system_server进程:在android系统初始化过程中,会有zygote孵化出system_server进程。可以用ps命令看到这个进程的父进程就是zygote。
在system_server中,初始化了Android Framework层的许多服务,其中,就包含PackageManagerService服务。
代码如下:
SystemServer.java的代码:
system_server初始化流程:
1)main -> call
System.loadLibrary("android_servers"); init1(args);
native public static void init1(String[] args);
2)init1 -> 通过native再调用到java层的init2
init2
3)init2:
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
4)ServerThread中,对各个组件进行初始化:
class ServerThread extends Thread {
@Override
public void run() {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
SystemClock.uptimeMillis());
Looper.prepare();
......
IPackageManager pm = null;
Context context = null;
WindowManagerService wm = null;
BluetoothService bluetooth = null;
......
try {
Slog.i(TAG, "Entropy Mixer");
ServiceManager.addService("entropy", new EntropyMixer());
Slog.i(TAG, "Power Manager");
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
......
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF,
onlyCore);
}
}
......
}
这样,PackageManagerService就初始化完成了。
6. 总结:
PackageManager的addService的代码调用流程:
SystemServer.init1/init2->PackageManagerService.main()
->ServiceManager.addService()->IServiceManager().addService
->ServiceManagerNative.addService()->ServiceManagerProxy.addService()
->Binder.onTransact()->ServiceManagerNative.onTransact() //
case IServiceManager.ADD_SERVICE_TRANSACTION: {
->Parcel.enforceInterface()
->android_os_Parcel.cpp //JNI
->Parcel::enforceInterface() //Parcel.cpp Native
以上,就是Binder在JAVA层相关的组件以及其在整个系统中的调用流程的基本介绍。