servicemanger的前世今生--Android 12

前边好几节介绍了Java层的SystemService类、ServiceManager类、SystemServiceManager类,以及SystemServer类中启动三大类服务的解析,我们知道启动系统服务时有的会调用SystemServiceManager.startService()或者ServiceManager.addService(),两者除了参数要求不一致外,都最终会调用IServiceManager.addService()中。

今天我们就来了解下ServiceManager这个进程的前世今生,包括它的Java层和native层。


目录

一、ServiceManager的作用

二、ServiceManager相关代码路径

三、servicemanager和vndservicemanager

1. init.rc中启动servermanager、vndservicemanager进程

2. servicemanager.rc

3. vndservicemanager.rc

4.servicemanager和vndservicemanager的不同

四、ServiceManager的启动过程

五、ServiceManager.cpp的类图

六、IServiceManager.cpp

1. IServiceManager相关类解析

2. native层添加service的代码

七、IServiceManager.aidl

1.Java层ServiceManager.addService()到servicemanager的过程。

2. AIDL编译成C++ Binder接口


一、ServiceManager的作用

ServiceManager是Binder IPC通信的管家,本身也是一个Binder服务,他相当于 “DNS服务器”,内部存储了serviceName与其Binder Service的对应关系,管理Java层和native层的service,支持addService()、getService()、checkService、listServices()等功能。


二、ServiceManager相关代码路径

C++: frameworks/native/cmds/servicemanager/ServiceManager.cpp,源码参考网址为:ServiceManager.cpp - OpenGrok cross reference for /frameworks/native/cmds/servicemanager/ServiceManager.cpp

C++: frameworks/native/libs/binder/IServiceManager.cpp,源码参考地址为:IServiceManager.cpp - OpenGrok cross reference for /frameworks/native/libs/binder/IServiceManager.cpp

Java: frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl

Java: frameworks/base/core/java/android/os/ServiceManager.java,源码参考地址为:

http://aospxref.com/android-12.0.0_r3/xref/frameworks/base/core/java/android/os/ServiceManager.java

Java: frameworks/base/core/java/android/os/ServiceManagerNative.java


三、servicemanager和vndservicemanager

由于systemserver进程启动三类服务时会向servicemanager中addService(),所以servicemanager进程应该比systemserver进程启动的更早。

1. init.rc中启动servermanager、vndservicemanager进程

#init.rc路径: /system/core/rootdir/init.rc

# Start essential services.
start servicemanager
start hwservicemanager
start vndservicemanager

2. servicemanager.rc

# /frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    # 重启时,重启apexd、audioservice、gatekkeeperd服务
    onrestart restart apexd
    onrestart restart audioserver 
    onrestart restart gatekeeperd
    # 重启时,重启class为main、hal、early_hal的所有服务
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

3. vndservicemanager.rc

在init.rc中启动关键服务的时候有vndservicemanager。

# /frameworks/native/cmds/servicemanager/vndservicemanager.rc
service vndservicemanager /vendor/bin/vndservicemanager /dev/vndbinder
    class core
    user system
    group system readproc
    writepid /dev/cpuset/system-background/tasks
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    shutdown critical

它与servicemanager共用一套代码,代码路径都在:frameworks/native/cmds/servicemanager/,编译这两个service在同一个Android.bp,具体如下: 

cc_binary {
    name: "servicemanager",
    defaults: ["servicemanager_defaults"],
    init_rc: ["servicemanager.rc"],
    srcs: ["main.cpp"],
}

cc_binary {
    name: "vndservicemanager",
    defaults: ["servicemanager_defaults"],
    init_rc: ["vndservicemanager.rc"],
    vendor: true,
    cflags: [
        "-DVENDORSERVICEMANAGER=1",
    ],
    required: [
        "vndservice",
    ],
    srcs: ["main.cpp"],
}

4.servicemanager和vndservicemanager的不同

(1) 两者的驱动节点不同:servicemanager的driver节点为/dev/binder,vndservicemanager的driver节点为/dev/vndbinder,后者service的option指定了"/dev/vndbinder"。

(2) 两者的路径不同:servicemanager的可执行文件路径为/system/bin/servicemanager,vndservicemanager的service可执行文件路径为/vendor/bin/vndservicemanager。

(3) 启动时参数个数不同:根据servicemanager.rc中只执行了/system/bin/servicemanager,没有额外参数,因此参数个数是1。而vndservicemmanager.rc中执行了/vendor/bin/vndservicemanager /dev/vndbinder,因此参数是2。这对于/frameworks/native/cmds/servicemanager/main.cpp中main()的参数很重要,用于判断设备节点路径。

// /frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }
    //两个参数的话就取第二个值"/dev/vndbinder",否则赋值为“/dev/binder”
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";
    ...
}

四、ServiceManager的启动过程

该servicemanager进程的启动入口为/frameworks/native/cmds/servicemanager/main.cpp中main()。

讲解非常详细的Blog请参考:ServiceManager原理 - Android 12 S 代码梳理,本文不再叙述相同内容,转载其完整时序图如下:


五、ServiceManager.cpp的类图

路径:/frameworks/native/cmds/servicemanager/ServiceManager.h和 /frameworks/native/cmds/servicemanager/ServiceManager.cpp

 ServiceManager继承BnServiceManager,但是BnServiceManager是由IServiceManager.aidl生成的c++文件,目录在: android/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/ android_arm_armv7-a-neon_cortex-a9_shared/gen/aidl/android/os/。

 以上标注的四个文件是由IServiceManager.aidl生成的。AIDL文件除了会生成Java文件外,还可以生成c++文件,详细请参考七、IServiceManager.aidl


六、IServiceManager.cpp

目录:frameworks/native/libs/binder/IServiceManager.cpp

1. IServiceManager相关类解析

本人理解:/frameworks/native/libs/binder/IServiceManager.cpp相当于servicemanager进程对外暴露的接口集,主要是为native层的service服务,例如native层添加service都是调用它的addService()接口。

它各个方法的具体实现是在ServiceManagerShim类中,ServiceManagerShim类各个方法的实现实际上通过IServiceManager.aidl与servicemanager进程通信的。以addService为例:

//源码文件:/frameworks/native/libs/binder/IServiceManager.cpp
sp<AidlServiceManager> mTheRealServiceManager;
//AILD生成的c++的文件,即Android/os/IServiceManager.cpp,而非当前源码文件
using AidlServiceManager = android::os::IServiceManager; 

status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)
{
    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

---------------------------------------------------------------------------------
[[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager;

sp<IServiceManager> defaultServiceManager()
{
    std::call_once(gSmOnce, []() {
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            //该sm就是IServiceManager.aidl的客户端BpIServiceManager
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            if (sm == nullptr) {
                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
                sleep(1);
            }
        }
        //调用ServiceManagerShim的构造方法
        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
    });

    return gDefaultServiceManager;
}
---------------------------------------------------------------------------------
//ServiceManagerShim构造函数,把上述sm赋值给mTheRealServiceManager
ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
 : mTheRealServiceManager(impl)
{}

mTheRealServiceManager实际上就是defaultServiceManager()中的sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr)),所以该类的addService()实际上调用AIDL生成的c++客户端BpServiceManager.addService(),然后利用Binder机制调用servicemanager服务器端BnServiceManager.onTransact()中的addService()逻辑,前边介绍ServiceManager.cpp时类图中表明ServiceManager类是继承BnServiceManager,所以由IServiceManager.cpp通过IServiceManager.aidl与servicemanager进程的ServiceManager.cpp完成通信,把新增的native service添加到service manager中进行管理。

2. native层添加service的代码

int main(int argc, char **argv) {
    sp<ProcessState> proc(ProcessState::self()); 
    //获取ServiceManager的  
    sp<IServiceManager> sm = defaultServiceManager();    
    
    sp<VrEyeTrackingService> mService = new VrEyeTrackingService();    
    sm->addService(String16(NATIVESERVICE_NAME), mService, false);

    ProcessState::self()->startThreadPool();    
    IPCThreadState::self()->joinThreadPool();    
    return 0;    
}

七、IServiceManager.aidl

目录:frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl

该AIDL接口即是JAVA层/frameworks/base/core/java/android/os/ServiceManager.java与servicemanager进行IPC通信的桥梁,也是C++层/frameworks/native/libs/binder/ IServiceManager.cpp与servicemanager进程进行IPC通信的桥梁。

1.Java层ServiceManager.addService()到servicemanager的过程。

// /frameworks/base/core/java/android/os/ServieManager.java
public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) {
    try {
        getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}
-------------------------------------------------------------------------------------------
private static IServiceManager sServiceManager;

private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }
    // Find the service manager
    sServiceManager = ServiceManagerNative.
        asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}
// /frameworks/base/core/java/android/os/ServiceManagerNative.java
public final class ServiceManagerNative {
    private ServiceManagerNative() {}

     //Cast a Binder object into a service manager interface, generating a proxy if needed.
    public static IServiceManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }
}

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
        //获取servicemanager客户端服务
        mServiceManager = IServiceManager.Stub.asInterface(remote);
    }
    ...
    public IBinder getService(String name) throws RemoteException {
        // Same as checkService (old versions of servicemanager had both methods).
        return mServiceManager.checkService(name);
    }

    public IBinder checkService(String name) throws RemoteException {
        return mServiceManager.checkService(name);
    }

    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
    ...
}

由上述可知getIServiceManager()实际上是IServiceManager.Stub,Java的ServiceManager.addService()实际上调用的Stub.addService(),该实现参考AIDL的实现原理。

2. AIDL编译成C++ Binder接口

对于IServiceManager.aidl,它的编译在/frameworks/native/libs/binder/Android.bp中,

// /frameworks/native/libs/binder/Android.bp

// AIDL interface between libbinder and framework.jar
filegroup {
    name: "libbinder_aidl",
    srcs: [
        "aidl/android/os/IClientCallback.aidl",
        "aidl/android/os/IServiceCallback.aidl",
        "aidl/android/os/IServiceManager.aidl",
        "aidl/android/os/ServiceDebugInfo.aidl",
    ],
    path: "aidl",
}

aidl_interface {
    name: "libbinder_aidl_test_stub",
    unstable: true,
    local_include_dir: "aidl",
    srcs: [":libbinder_aidl"],
    vendor_available: true,
    backend: { //AIDL编译器为后端生成相应的代码,目前支持Java、cpp、ndk。
        java: {
            enabled: false, //关闭生成Java后端代码
        },
    },
}

cc_library {
    name: "libbinder",
    // for vndbinder
    vendor_available: true,
    vndk: {
        enabled: true,
    },
    double_loadable: true,
    host_supported: true,
    ...
    srcs: [
        "Binder.cpp",
        "BpBinder.cpp",
        "IServiceManager.cpp",
        ...
        ":libbinder_aidl",  //libbinder库引入了IServiceManager.aidl
    ],

    target: {
        android: {
            srcs: libbinder_device_interface_sources,
            // NOT static to keep the wire protocol unfrozen
            static: {
                enabled: false,
            },
        },
        ...
        vendor: {
            exclude_srcs: libbinder_device_interface_sources,
        },
        darwin: {
            enabled: false,
        },
    },

    aidl: {
        export_aidl_headers: true, //可以被外部引用
    },
    ...
}

 因此对于IServiceManager.aidl文件会生成四个文件:BnServiceManager.h--server端,BpServiceManager--clien端,以及IServiceManager.h和IServiceManager.cpp,生成目录为:android/out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm_armv7-a-neon_cortex-a9_shared/gen/aidl/android/os/。

注意:其他cpp文件可以引入#include <android/os/IServiceManager.h>来访问using AidlServiceManager = android::os::IServiceManager。

更多关于AIDL编译成c++的介绍请关注之后的更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值