--- 怎么添加一个系统服务? --- 1. 了解如何使用系统服务? 2. 了解系统服务调用的基本原理 3. 了解服务的注册原理 #### 如何使用系统服务以及基本原理 ```java // ContextImpl public Object getSystemServer(String name) { return SystemServiceRegistry.getSystemService(this, name); } // SystemServiceRegistry SYSTEM_SERVICE_FETCHERS = new ArrayMap>(); public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; } // 具体实现 public final T getService(ContextImpl ctx) { final Object[] cache = ctx.mServiceCache; T service = (T) cache[mCacheIndex]; if (service != null) { return service; } else { service = createService(ctx); cache[mCacheIndex] = service; } } ``` 然后看一下 createService 是如何实现的,这里以 Power Service 为例: ```java registerService(Context.POWER_SERVICE, PowerManager.class, new CachedServiceFetcher()) { @Override public PowerManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler()); } } ``` ```java // ServiceManager#getService public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return Binder.allowBlocking(rawGetService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } ``` #### 服务的注册原理 ```java public static void addService(String name, IBinder service) { getIServiceManager().addService(name, service, false); } ``` 什么时候注册的系统服务? 就是在 SystemServer 启动时注册。它的主要流程是:启用 binder 机制 -> 启动各类系统服务 -> 进去 Loop 循环。 需要注意的是,并不是所有的系统服务都是在 SystemServer 进程里的,有一些服务·是单开一个进程的,比如 ServiceManager、SurfaceFlinger、MediaService 等,但是同样需要注册到 ServiceManager 中。 独立进程的系统服务实现,以 SurfaceFlinger 为例: ```ini service surfaceflinger /system/bin/surfaceflinger class core user system group graphics drmrpc onrestart restart zygote writepid /dev/cpuset/system-background/tasks ``` ```c int main(int, char**) { sp ps(ProcessState::self()); // 启动 binder 线程池 ps->startThreadPool(); sp flinger = new SurfaceFlinger(); flinger->init(); // 注册 SurfaceFlinger 服务 sp sm(defaultServiceManager()); sm->addService(serviceName, flinger, false); flinger->run(); return 0; } ``` ProcessState 是一个进程内的单例,它的构造函数里面会启动 binder 机制,包括打开 binder 驱动,映射内存,分配缓冲区等等。 最后看一下defaultServiceManager 函数: ```c sp defaultServiceManager() { if(gDefaultServiceManager != null) { return gDefaultServiceManager; } while(gDefaultServiceManager == null) { gDefaultServiceManager = getContextObject(); if(gDefaultServiceManager==null) sleep(1); } } ``` 因为 ServiceManager 和 SurfaceFlinger 都是由 init 进程启动的,所以这里如果是独立线程启动,可能在注册服务时,ServiceManager 还未来得及向 binder 驱动注册,所以如果拿不到 ServiceManager 就睡眠不停循环获取。