Android系统源码分析-进程间通信机制binder(三):从framework层到Native层

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.javaandroid_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层相关的组件以及其在整个系统中的调用流程的基本介绍。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值