前面介绍过Binder通信的原理,所有的框架服务,实际上都是Binder服务。今天准备给一个例子,看下如何添加一个框架服务。
添加aidl文件
./frameworks/base/core/java/android/os/IBinderManager.aidl
package android.os;
interface IBinderManager {
void setVal(int value);
int getVal();
}
这里添加后,需要在编译文件中声明这个文件路径,然后才能编译。
./frameworks/base/.Android.bp
java_defaults {
name: "framework-defaults",
installable: true,
srcs: [
//……
"core/java/android/os/IBinderManager.aidl",
//……
],
}
编译完成后会生成一个IBinderManager.java文件
./out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/android/os/IBinderManager.java
在services.jar中添加service
./frameworks/base/services/core/java/com/android/server/BinderManagerService.java
package com.android.server;
import android.os.IBinderManager;
import android.util.Log;
public class BinderManagerService extends IBinderManager.Stub {
private int value;
@Override
public void setVal(int value) {
this.value = value;
Log.d("BinderManagerService", "setVal:" + value);
}
@Override
public int getVal() {
Log.d("BinderManagerService", "getVal:" + value);
return value;
}
}
在framework.jar中添加manager
./frameworks/base/core/java/android/os/BinderManager.java
package android.os;
import android.content.Context;
import android.util.Slog;
public class BinderManager {
private final IBinderManager mService;
private final Context mContext;
public BinderManager(Context context, IBinderManager service) {
mContext = context;
mService = service;
}
public void setValue(int value) {
try {
mService.setVal(value);
} catch (Exception e) {
Slog.d("BinderManager", "setValue:" + e);
}
}
public int getValue() {
try {
return mService.getVal();
} catch (Exception e) {
Slog.d("BinderManager", "getValue:" + e);
}
return -1;
}
}
在ServiceManager中注册Binder服务
./frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
private void startOtherServices() {
//……
ServiceManager.addService(Context.BINDER_MANAGER_SERVICE, new BinderManagerService());
//……
}
}
通过SystemServiceRegistry添加manager服务
./frameworks/base/core/java/android/app/SystemServiceRegistry.java
final class SystemServiceRegistry {
static {
//……
registerService(Context.BINDER_MANAGER_SERVICE, BinderManager.class,
new CachedServiceFetcher<BinderManager>() {
@Override
public BinderManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(Context.BINDER_MANAGER_SERVICE);
IBinderManager service =
IBinderManager.Stub.asInterface(b);
return new BinderManager(ctx, service);
}});
//……
}
}
添加SELinux权限
因为操作文件节点需要权限,所以在不修改的情况下,以上SystemServer的代码会报错。
SELinux : avc: denied { add } for service=binder_manager pid=2490 uid=1000 scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0
./system/sepolicy/private/service_contexts
binder_manager u:object_r:binder_manager_service:s0
最后,就可以通过context.getSystemService()方法获取到这个服务了。
网友评论