android—如何添加一个系统服务


前面分析过binder的实现流程,binder的实现包含了java和c++两部分,所以service的实现也包括java和c++两种,那么应该如何去自己实现并添加一个service?

c++中添加service

下面以SurfaceComposer这个service为例,
① 首先提供接口文件ISurfaceComposer.h

//frameworks\native\include\gui\ISurfaceComposer.h
//首先是接口,c++实现是虚函数
class ISurfaceComposer: public IInterface {
public:
    DECLARE_META_INTERFACE(SurfaceComposer);

    // flags for setTransactionState()
    enum {
        eSynchronous = 0x01,
        eAnimation   = 0x02,
    };

    enum {
        eDisplayIdMain = 0,
        eDisplayIdHdmi = 1
    };

    /* create connection with surface flinger, requires
     * ACCESS_SURFACE_FLINGER permission
     */
    virtual sp<ISurfaceComposerClient> createConnection() = 0;
}

② 建立BnSurfaceComposer
建立BnSurfaceComposer,需要重写BBinder的onTransact函数。

class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
public:
    enum {
        // Note: BOOT_FINISHED must remain this value, it is called from
        // Java by ActivityManagerService.
        BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
        CREATE_CONNECTION,
        CREATE_GRAPHIC_BUFFER_ALLOC,
        CREATE_DISPLAY_EVENT_CONNECTION,
        CREATE_DISPLAY,
        DESTROY_DISPLAY,
        GET_BUILT_IN_DISPLAY,
        SET_TRANSACTION_STATE,
        AUTHENTICATE_SURFACE,
        BLANK,
        UNBLANK,
        GET_DISPLAY_INFO,
        CONNECT_DISPLAY,
        CAPTURE_SCREEN,
    };

    virtual status_t onTransact(uint32_t code, const Parcel& data,
            Parcel* reply, uint32_t flags = 0);
};

③ Bpxxx的实现

frameworks\native\libs\gui\ISurfaceComposer.cpp中,



//Bp实现,代理端

class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
    BpSurfaceComposer(const sp<IBinder>& impl)
        : BpInterface<ISurfaceComposer>(impl)
    {
    }
    //代理接口
    virtual sp<ISurfaceComposerClient> createConnection()
    {
        uint32_t n;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
    }
}

④ Bnxxx的实现

//Bn端,即server端
status_t BnSurfaceComposer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case CREATE_CONNECTION: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            //createConnection就是server端的实现函数
            sp<IBinder> b = createConnection()->asBinder();
            reply->writeStrongBinder(b);
            return NO_ERROR;
        }
        default: {
            return BBinder::onTransact(code, data, reply, flags);
        }
    }
    // should be unreachable
    return NO_ERROR;
}   

⑤ 注册service
通过上面几步已经完成了service的建立,我们需要将service注册到service manager中。

class SurfaceFlinger : public BnSurfaceComposer,
    //在frameworks\native\services\surfaceflinger\main_surfaceflinger.cpp中,
    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);

⑥ 使用service

    //首先获取代理端BpSurfaceComposer
    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
    //直接调用代理BpSurfaceComposer的接口
    sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());

其中getComposerService()的实现为,

/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);
    if (instance.mComposerService == NULL) {
        ComposerService::getInstance().connectLocked();
        assert(instance.mComposerService != NULL);
        ALOGD("ComposerService reconnected");
    }
    return instance.mComposerService;
}   
void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    //获取service,返回的mComposerService是BpSurfaceComposer,有了Bp就能直接调用代理接口了
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerService& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService remote (surfaceflinger) died [%p]",
                  who.unsafe_get());
            mComposerService.composerServiceDied();
        }
     public:
        DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    mComposerService->asBinder()->linkToDeath(mDeathObserver);
}

java添加service

Android为了方便开发人员,提供了AIDL工具,简化了编写service的难度。下面以添加TestService这个服务为例,
① 编写AIDL文件

package android.app;

interface ITestService {
    boolean enableWifi(boolean enabled);
}

TestService的AIDL文件提供了一个接口,enableWifi()。

② 创建TestService服务
TestService 服务需要继承ITestService.Stub类,这个类就是通过AIDL工具对①中的AIDL文件处理后产生的,

class TestService extends ITestService.Stub {


    //实现接口
    public boolean enableWifi(boolean enabled)
    {
        ......
    } 
}

③ Context.java中添加service名字字符串

// Context.java中添加service名字字符串
    public static final String TEST_SERVICE = "my_test";

④ 向ServiceManager中注册service
java中大部分的系统service都是在SystemServer中去向service manager注册的,

//ServiceManager注册service
// 在SystemServer.java中,模仿其他向ServiceManager添加service的方法
            try {
                TestService myService = new TestService(context);
                ServiceManager.addService(Context.TEST_SERVICE, myService);
            } catch (Throwable e) {
                reportWtf("register my test service fail", e);
            }

⑤创建服务对应的Manager
对于每一个service而言,通常会有一个相关的Manager。 Managers提供API给app使用,成为SDK的一部分,是apps和remote service的中间桥梁。Manager中的接口和Service中的接口必须一一对应。

public class TestServiceManager{

    private final ITestService mService;
    private final Context mContext;

    //构造函数中传入的service,其实就是BpTestService
    TestServiceManager(Context context,ITestService service) {
        mContext = context;
        mService = service;
    }   
    public boolean enableWifi(boolean enabled) {
        try {
            return mService.enableWifi(enabled);
        } catch (RemoteException ex) {
        }
        return false;
    }
}

到目前为止,我们只是完成了Service的注册,但是还没有使用,该如何使用?

⑥ contextImpl中注册Manager
一旦我们实现了service和对应的Manager,需要有一种方法在app中调用他们。前面说过,Manager会成为SDK的一部分,供我们调用,那么Manager和Service是如何联系起来的?首先需要将我们的service和mangager注册到execution context,即contextImpl中,

        registerService(TEST_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(TEST_SERVICE);
                    //asInterface(BpBinder)后就是BpTestService
                    ITestService service = ITestService.Stub.asInterface(b);
                    //创建TestServiceManager,第二个参数为BpBpTestService
                    return new TestServiceManager(ctx.getOuterContext(), service);
                }});

registerService的第二个参数是一个ServiceFetcher对象,这里直接在调用时,新建了一个ServiceFetcher类,重写了createService方法。
ContextImpl.java中的registerService()方法,其核心就是把servicename和ServiceFetcher对象放到一个Hash的键值对中。

    private static void registerService(String serviceName, ServiceFetcher fetcher) {
        if (!(fetcher instanceof StaticServiceFetcher)) {
            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
        }
        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    }

⑦ app如何使用service

那么app是如何调用的呢?

import android.app.TestServiceManager;
import android.content.Context;


TestServiceManager mTestServiceManager;
mTestServiceManager=(TestServiceManager)context.getSystemService(Context.TEST_SERVICE);

然后直接调用TestServiceManager中的方法即可,其中的奥秘需要分析下getSystemService函数。
ContextImpl.java中,

    @Override
    public Object getSystemService(String name) {
        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
        //从ServiceFetcher 中获取service
        return fetcher == null ? null : fetcher.getService(this);
    }

getService()函数的核心就是上面重写的createService()函数,返回的就是TestServiceManager对象,所以通过context.getSystemService返回的是Manager对象。

    public Object getService(ContextImpl ctx) {
            ArrayList<Object> cache = ctx.mServiceCache;
            Object service;
            synchronized (cache) {
                if (cache.size() == 0) {
                    // Initialize the cache vector on first access.
                    // At this point sNextPerContextServiceCacheIndex
                    // is the number of potential services that are
                    // cached per-Context.
                    for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
                        cache.add(null);
                    }
                } else {
                    service = cache.get(mContextCacheIndex);
                    if (service != null) {
                        return service;
                    }
                }
                //调用重载的createService函数,返回的就是TestServiceManager对象
                service = createService(ctx);
                cache.set(mContextCacheIndex, service);
                return service;
            }
        }
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值