You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.8 KiB

5 years ago
---
怎么添加一个系统服务?
---
1. 了解如何使用系统服务?
2. 了解系统服务调用的基本原理
3. 了解服务的注册原理
#### 如何使用系统服务以及基本原理
```java
// ContextImpl
public Object getSystemServer(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
// SystemServiceRegistry
SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();
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<PowerManager>()) {
@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<ProcessState> ps(ProcessState::self());
// 启动 binder 线程池
ps->startThreadPool();
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
flinger->init();
// 注册 SurfaceFlinger 服务
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(serviceName, flinger, false);
flinger->run();
return 0;
}
```
ProcessState 是一个进程内的单例,它的构造函数里面会启动 binder 机制,包括打开 binder 驱动,映射内存,分配缓冲区等等。
最后看一下defaultServiceManager 函数:
```c
sp<IServiceManager> defaultServiceManager() {
if(gDefaultServiceManager != null) {
return gDefaultServiceManager;
}
while(gDefaultServiceManager == null) {
gDefaultServiceManager = getContextObject();
if(gDefaultServiceManager==null) sleep(1);
}
}
```
因为 ServiceManager 和 SurfaceFlinger 都是由 init 进程启动的,所以这里如果是独立线程启动,可能在注册服务时,ServiceManager 还未来得及向 binder 驱动注册,所以如果拿不到 ServiceManager 就睡眠不停循环获取。