2020-04-07-Android添加框架服务

2020-04-08  本文已影响0人  耿望

前面介绍过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()方法获取到这个服务了。

上一篇 下一篇

猜你喜欢

热点阅读