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
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);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
5 years ago
|
因为 ServiceManager 和 SurfaceFlinger 都是由 init 进程启动的,所以这里如果是独立线程启动,可能在注册服务时,ServiceManager 还未来得及向 binder 驱动注册,所以如果拿不到 ServiceManager 就睡眠不停循环获取。
|
||
|
|