前边好几节介绍了Java层的SystemService类、ServiceManager类、SystemServiceManager类,以及SystemServer类中启动三大类服务的解析,我们知道启动系统服务时有的会调用SystemServiceManager.startService()或者ServiceManager.addService(),两者除了参数要求不一致外,都最终会调用IServiceManager.addService()中。
今天我们就来了解下ServiceManager这个进程的前世今生,包括它的Java层和native层。
目录
三、servicemanager和vndservicemanager
1. init.rc中启动servermanager、vndservicemanager进程
4.servicemanager和vndservicemanager的不同
1.Java层ServiceManager.addService()到servicemanager的过程。
一、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++的介绍请关注之后的更新。