一图摸清Android系统服务的获取和注册流程~
大纲:
- 独立进程的服务
- 非独立进程的服务
本文约1.9k字,阅读大约8分钟。
>
Android源码基于8.0。
先预览下整体流程~
开始分析!
获取系统服务
在日常开发中,可以通过Context.getSystemService()在自己的应用程序里获取到系统服务:
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
ServiceFetcher是一个抽象接口,抽象类CachedServiceFetcher实现了他,
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
Object service = cache[mCacheIndex];
if (service == null) {
service = createService(ctx);
cache[mCacheIndex] = service;
}
return (T)service;
}
}
public abstract T createService(ContextImpl ctx);
在SystemServiceRegistry里有个静态代码块static{}会“注册服务”,从中实现抽象方法createService()的逻辑,以电源服务PowerManager为例,
registerService(
Context.POWER_SERVICE, PowerManager.class,
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx){
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
IPowerManager service = IPowerManager.Stub.asInterface(b);
return new PowerManager(ctx.getOuterContext(),
service,
ctx.mMainThread.getHandler());
}});
AIDL可以辅助生成用于binder通信的类,IPowerManager就是定义在IPowerManager.aidl里的,binder内部细节本文不做讨论。
ServiceManager的getServiceOrThrow()函数会调用getService(),
public static IBinder getService(String name) {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().getService(name));
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
可见,我们的应用程序进程会通过binder跨进程通信,拿到ServiceManager进程的IServiceManager对象(本质是BpServiceManager),然后就可以通过IServiceManager对象的getService来获取系统服务了。
public interface IServiceManager extends IInterface{
public IBinder getService(String name);
}
看下IServiceManager的具体实现,在IServiceManager.cpp文件里,有个BpServiceManager类,
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
if (n > 0) {
sleep(1);
}
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
}
return NULL;
}
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
再梳理一下系统服务的获取过程:
应用程序进程调用getSystemService
通过binder跨进程通信,拿到ServiceManager进程的BpServiceManager对象
通过BpServiceManager获取到系统服务
注册系统服务
系统服务可以分成两大类:
一是有独立进程的ServiceManager、SurfaceFlinger等,他们在init进程启动时就会被fork创建;
二是非独立进程的AMS、PMS、WMS等,他们在init进程fork出Zygote进程,Zygote进程fork出的SystemServer进程创建。
独立进程的服务
独立进程的系统服务在init进程解析init.rc时启动,比如SurfaceFlinger,看下他的启动配置文件surfaceflinger.rc,
注:frameworks/native/services下列出了一系列服务,不过ServiceManager服务放在了[frameworks/native/cmds/servicemanager](https://www.androidos.net.cn/android/8.0.0_r4/xref/frameworks/native/cmds/servicemanager/servicemanager.rc)目录下。
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
service
以服务的形式来启动进程,surfaceflinger
是进程名字,/system/bin/surfaceflinger
是可执行程序的路径,该程序的入口函数main在main_surfaceflinger.cpp,
int main(int, char**) {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
flinger->init();
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
flinger->run();
return 0;
}
看下defaultServiceManager()的实现,在IServiceManager.cpp,
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
因为SurfaceFlinger进程和ServiceManager进程都是init进程启动的,有可能SurfaceFlinger在获取IServiceManager时,ServiceManager还没来得及注册,所以这里会边取边休眠,取到才结束循环。
得到IServiceManager后,执行sm->addService,在IServiceManager.cpp文件里有个BpServiceManager类,
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
梳理一下:
init进程解析init.rc配置fork出新的进程,*启动多项独立进程的系统服务*,如SurfaceFlinger
执行SurfaceFlinger的可执行程序,找到ServiceManager进程的BpServiceManager对象
通过BpServiceManager执行addService注册服务
非独立进程的服务
非独立进程的系统服务由SystemServer进程启动,从图解Android系统的启动一文可知,SystemServer借助SystemServiceManager类(SSM)来启动系统服务,比如AMS,
private void startBootstrapServices() {
mActivityManagerService = mSystemServiceManager
.startService(ActivityManagerService.Lifecycle.class)
//通过binder获取AMS服务
.getService();
//注册AMS
mActivityManagerService.setSystemProcess();
}
看到ActivityManagerService,
public void setSystemProcess() {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}
调用了ServiceManager.addService()进行注册,
public static void addService(String name, IBinder service, boolean allowIsolated) {
getIServiceManager().addService(name, service, allowIsolated);
}
可见,无论是SystemServer进程启动的服务,还是init进程启动的运行在独立进程里的服务,最终都是走ServiceManager进程的BpServiceManager.addService进行集中注册。
总结
综上,不管是由init进程启动的独立进程的系统服务如SurfaceFlinger,还是由SystemServer进程启动的非独立进程的系统服务如AMS,都是在ServiceManager进程中完成注册和获取的,在跨进程通信上使用了Android的binder机制。
不过哈迪在工作中没怎么用过binder,所以他的内部细节就暂时不深入了,后面抽时间再看。
再回顾一下~
系列文章:
参考资料
更多性感文章,关注原创技术公众号:哈利迪ei
评论