android IPC binder 的(service 和 client)简单应用

时间:2021-04-24 05:29:02

Binder 架构

名词解析:Bn: Bindernative,本地;Bp:Binderproxy,代理。I:IInterface;Binder 应用架构逻辑如下:

 android IPC binder 的(service 和 client)简单应用

备注:实心箭头为调用关系;空心箭头为继承关系;

iclient的实现

/***************************************************************************/

    itestclient.h

#ifndef ANDROID_ITESTCLIENT_H
#define ANDROID_ITESTCLIENT_H

#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>

namespace android {

class ITestClient: public IInterface
{
public:
    DECLARE_META_INTERFACE(TestClient);

    virtual void notify(int msg, int ext1, int ext2,const Parcel*p_obj) = 0;
};

// ----------------------------------------------------------------------------

class BnTestClient: public BnInterface<ITestClient>
{
public:
    virtual status_t    onTransact( uint32_tcode,
                                   const Parcel& data,
                                   Parcel* reply,
                                   uint32_t flags = 0);
};

}; // namespace android

#endif // ANDROID_ITESTCLIENT_H

/***************************************************************************/ 

itestclient.cpp

#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>

#include <utils/Errors.h> // for status_t
#include <utils/RefBase.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Log.h>


#include "itestclient.h"

namespace android {

enum {
    NOTIFY = IBinder::FIRST_CALL_TRANSACTION,
};

class BpTestClient: public BpInterface<ITestClient>
{
public:
    BpTestClient(const sp<IBinder>& impl)
        : BpInterface<ITestClient>(impl)
    {
    }

    virtual void notify(int msg, int ext1, int ext2, constParcel *p_obj)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ITestClient::getInterfaceDescriptor());
        data.writeInt32(msg);
        data.writeInt32(ext1);
        data.writeInt32(ext2);
        if (p_obj &&p_obj->dataSize() > 0) {
                 data.appendFrom(const_cast<Parcel *>(p_obj), 0, p_obj->dataSize());
             }
        //remote()->transact(NOTIFY,data, &reply, IBinder::FLAG_ONEWAY);/****async,异步调用*****/
        remote()->transact(NOTIFY, data,&reply);/***sync,同步调用**/
        reply.readInt32();
        return;
    }
};

IMPLEMENT_META_INTERFACE(TestClient, "android.os.ITestClient");

// ----------------------------------------------------------------------

status_t BnTestClient::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply,uint32_t flags)
{

    switch (code) {
        case NOTIFY: {
           CHECK_INTERFACE(ITestClient, data, reply);
            int msg =data.readInt32();
            int ext1 =data.readInt32();
            int ext2 =data.readInt32();
            Parcel obj;
            if(data.dataAvail() > 0) {
               obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(),data.dataAvail());
            }
           //__android_log_print(ANDROID_LOG_VERBOSE, "itestclient","notify:0x%x-0x%x-0x%x\n",msg,ext1,ext2);
            notify(msg,ext1, ext2, &obj);
           reply->writeInt32(NO_ERROR);

            returnNO_ERROR;
        } break;
        default:
            returnBBinder::onTransact(code, data, reply, flags);
    }
}

}; // namespace android

client的实现

/***************************************************************************/

testclient.h

#ifndef _TESTCLIENT_H_
#define _TESTCLIENT_H_

#include "listener.h"

namespace android {

class Testclient : public BnTestClient
{
public:
     Testclient();
    ~Testclient();
    int destory();
    int testSiRequest(test_request_t *p_test);
    int testSiFree(test_request_t *p_test);
    status_t setListener(const sp<Listener>&listener);
    sp<Listener> getListener(void);
    
    virtual void notify(int msg, int ext1, int ext2, constParcel *p_obj);
private:
     sp<Testclient> mclient_class;
     sp<ITESTService>  test_service_proxy;
     sp<IServiceManager>  sm;
     sp<IBinder>  binder;
    Mutex mLock;
    sp<Listener> mListener;
};
};
#endif

 /***************************************************************************/

testclient.cpp

#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h> // for status_t
#include <utils/RefBase.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Log.h>
#include "itestclient.h"
#include "itestservice.h"
#include "listener.h"
#include <utils/Log.h>
extern "C" {
#include "sys_types.h"
#include "dvb_test_attr.h"
};
#include "testclient.h"

#define TEST_CLIENT_LOG_TAG "testclient"
#ifdef TEST_CLIENT_LOG_TAG
#define Testclientprintfv(...) __android_log_print(ANDROID_LOG_VERBOSE, TEST_CLIENT_LOG_TAG,__VA_ARGS__)
#define Testclientprintfd(...) __android_log_print(ANDROID_LOG_DEBUG, TEST_CLIENT_LOG_TAG,__VA_ARGS__)
#define Testclientprintfi(...) __android_log_print(ANDROID_LOG_INFO, TEST_CLIENT_LOG_TAG,__VA_ARGS__)
#define Testclientprintfw(...) __android_log_print(ANDROID_LOG_WARN, TEST_CLIENT_LOG_TAG,__VA_ARGS__)
#define Testclientprintfe(...) __android_log_print(ANDROID_LOG_ERROR, TEST_CLIENT_LOG_TAG,__VA_ARGS__)
#else
#define Testclientprintfv(...)
#define Testclientprintfd(...)
#define Testclientprintfi(...)
#define Testclientprintfw(...)
#define Testclientprintfe(...)
#endif

namespace android
{

Testclient::Testclient()
{
    mclient_class = this;
    Testclientprintfv("#### testclientinit\n");

    sm = defaultServiceManager();
    binder = sm->getService(String16("service.test"));
    if (binder == NULL) {
    //aout << "service.test cannot found!"<< endl;
    Testclientprintfe("#### service.si cannotfound\n");
    return;
    }

    test_service_proxy = interface_cast<ITESTService>(binder);
    test_service_proxy->createClient(this,(int)mclient_class.get());
    Testclientprintfv("#### testclient[0x%x] init isok\n", (int)mclient_class.get());
    return;
}

Testclient::~Testclient()
{
    Testclientprintfv("#### testclient ~Testclient\n");
}

int Testclient::destory(void)
{
    if (test_service_proxy == NULL) {
    Testclientprintfe("#### test_service_proxy cannotfound\n");
    return (UNKNOWN_ERROR);
    }
    Testclientprintfv("#### destory testclient[0x%x]\n",(int)mclient_class.get());
    Mutex::Autolock _l(mLock);
    test_service_proxy->destoryClient(this, (int)mclient_class.get());
    mclient_class = NULL;
    return (NO_ERROR);
}

int Testclient::testSiRequest(test_request_t *p_test)
{
    if (test_service_proxy == NULL) {
    Testclientprintfe("#### test_service_proxy cannotfound\n");
    return (UNKNOWN_ERROR);
    }
    Mutex::Autolock _l(mLock);
    Parcel mobj;
    mobj.setDataPosition(0);
    mobj.write((u8 *)p_test, sizeof(test_request_t));
    mobj.setDataPosition(0);
    test_service_proxy->testSiRequest(&mobj);
    mobj.freeData();
    return (NO_ERROR);
}

int Testclient::testSiFree(test_request_t *p_test)
{
    if (test_service_proxy == NULL) {
    Testclientprintfe("#### test_service_proxy cannotfound\n");
    return (UNKNOWN_ERROR);
    }
    Mutex::Autolock _l(mLock);
    Parcel mobj;
    mobj.setDataPosition(0);
    mobj.write((u8 *)p_test, sizeof(test_request_t));
    mobj.setDataPosition(0);
    test_service_proxy->testSiFree(&mobj);
    mobj.freeData();
    return (NO_ERROR);
}

status_t Testclient::setListener(const sp<Listener> &listener)
{
    Testclientprintfv("setListener");
    Mutex::Autolock _l(mLock);
    mListener = listener;
    return NO_ERROR;
}

sp<Listener> Testclient::getListener(void)
{
    return mListener;
}
void Testclient::notify(int msg, int ext1, int ext2, const Parcel *p_obj)
{
    //Testclientprintfv("notify msg=%d, ext1=%d,ext2=%d", msg, ext1, ext2);
    sp<Listener> listener = mListener;
    if (listener != NULL) {
    int size = p_obj->dataSize();
    unsigned char *p_buffer_parcel = NULL;
    if (size > 0) {
        p_buffer_parcel = (unsigned char*)malloc(size);
        if (NULL != p_buffer_parcel) {
        p_obj->setDataPosition(0);
        p_obj->read(p_buffer_parcel, size);
        p_obj->setDataPosition(0);
        } else {
        size = 0;
        ;
        }
    }

    listener->notify(msg, ext1, ext2, p_buffer_parcel, size);

    if ((size > 0) && (NULL != p_buffer_parcel)) {
        free(p_buffer_parcel);
    }
    }
}
}

iservice的实现

/***************************************************************************/

itestservice.h

#ifndef _ITESTSERVICE_H_
#define _ITESTSERVICE_H_

#include <utils/Errors.h> // for status_t
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>

namespace android {

class ITESTService: public IInterface
{
public:
    DECLARE_META_INTERFACE(TESTService);
    
    // declare what this service can do

    virtual status_t createClient(const sp<ITestClient>&client,int clientId) =0;
    virtual status_t destoryClient(const sp<ITestClient>&client,int clientId) =0;
    virtual status_t testSiRequest(const Parcel *p_obj) = 0;
    virtual status_t testSiFree(const Parcel *p_obj) = 0;
    
    enum {
        TEST_SERVICE_CREAT =IBinder::FIRST_CALL_TRANSACTION,
        TEST_SERVICE_DESTORY,
        TEST_SERVICE_SI_REQUEST,
        TEST_SERVICE_SI_FREE,
    };
};

// ----------------------------------------------------------------------------
class BnTESTService: public BnInterface<ITESTService>
{
public:
    virtual status_t onTransact( uint32_t code,
                                const Parcel& data,
                                Parcel *reply,
                                uint32_t flags = 0);
};

};// namespace android

#endif//end of _ITESTSERVICE_H_

 /***************************************************************************/

itestservice.cpp

#include <stdint.h>
#include <sys/types.h>
#include <utils/RefBase.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Log.h>
#include "itestclient.h"
#include "itestservice.h"

namespace android {

// ----------------------------------------------------------------------
class BpTESTService : public BpInterface<ITESTService>
{
public:
    BpTESTService(const sp<IBinder> &impl)
    : BpInterface<ITESTService>(impl)
    {
    }

    virtual status_t createClient(const sp<ITestClient>&client,int clientId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ITESTService::getInterfaceDescriptor());
        data.writeStrongBinder(client->asBinder());
        data.writeInt32(clientId);
        remote()->transact(TEST_SERVICE_CREAT,data, &reply);
        return reply.readInt32();
    }

      virtual status_t destoryClient(const sp<ITestClient>&client,int clientId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ITESTService::getInterfaceDescriptor());
       data.writeStrongBinder(client->asBinder());
        data.writeInt32(clientId);
        remote()->transact(TEST_SERVICE_DESTORY,data, &reply);
        return reply.readInt32();
    }
virtual status_t testSiRequest(const Parcel *p_obj)
{
      Parcel data, reply;
      //__android_log_print(ANDROID_LOG_VERBOSE,"itestservice","TestServiceControl:%d,%d,%d\n",cmd,data1,data2);
      data.writeInterfaceToken(ITESTService::getInterfaceDescriptor());
      if (p_obj && p_obj->dataSize() >0) {
         data.appendFrom(const_cast<Parcel *>(p_obj), 0, p_obj->dataSize());
      }
      remote()->transact(TEST_SERVICE_SI_REQUEST,data, &reply);
      return reply.readInt32();
 }

virtual status_t testSiFree(const Parcel *p_obj)
{
      Parcel data, reply;
      //__android_log_print(ANDROID_LOG_VERBOSE,"itestservice","TestServiceControl:%d,%d,%d\n",cmd,data1,data2);
      data.writeInterfaceToken(ITESTService::getInterfaceDescriptor());
      if (p_obj && p_obj->dataSize() >0) {
         data.appendFrom(const_cast<Parcel *>(p_obj), 0, p_obj->dataSize());
      }
      remote()->transact(TEST_SERVICE_SI_FREE,data, &reply);
      return reply.readInt32();
 }
    
};

IMPLEMENT_META_INTERFACE(TESTService, "android.os.ITESTService");

// ----------------------------------------------------------------------
String16 TESTServiceID("android.os.ITESTService");

status_t BnTESTService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply,uint32_t flags)
{
    CHECK_INTERFACE(ITESTService, data, reply);
    
    switch (code) {
        
       case TEST_SERVICE_CREAT:
        {    
            sp<ITestClient>client =
            interface_cast<ITestClient>(data.readStrongBinder());
          int clientId =data.readInt32();
           createClient(client,clientId);
           return(reply->writeInt32(NO_ERROR));
        }
           break;

      case TEST_SERVICE_DESTORY:
        {
        sp<ITestClient> client =
            interface_cast<ITestClient>(data.readStrongBinder());
          int clientId =data.readInt32();
           destoryClient(client,clientId);
           return(reply->writeInt32(NO_ERROR));
        }
        break;

        case TEST_SERVICE_SI_REQUEST:
         {
               Parcelobj;
               if(data.dataAvail() > 0) {
                  obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(),data.dataAvail());
               }
              //__android_log_print(ANDROID_LOG_VERBOSE, "itestservice","TestServiceControl(ontransact):%d,%d,%d\n",cmd,data1,data2);
               testSiRequest(&obj);
              return(reply->writeInt32(NO_ERROR));
            }
        break;
      case TEST_SERVICE_SI_FREE:
       {
               Parcel obj;
               if (data.dataAvail() > 0) {
                   obj.appendFrom(const_cast<Parcel *>(&data), data.dataPosition(),data.dataAvail());
               }
            //__android_log_print(ANDROID_LOG_VERBOSE, "itestservice","TestServiceControl(ontransact):%d,%d,%d\n",cmd,data1,data2);
             testSiFree(&obj);
            return(reply->writeInt32(NO_ERROR));
         }
        break;
        default:
           return(BBinder::onTransact(code, data, reply, flags));
    }

    return (0);
}


};// namespace android

 

service的实现

testservice.h

#define TEST_CLIENT_MAX_NUMBER 16

namespace android
{

typedef struct tg_ITestClient
{
    int gfixed;
    int client_id;
    sp<ITestClient> mclient;
} ITestClient_t;

class TESTService : public BnTESTService
{
  public:
    TESTService();
    ~TESTService();
    void clientNotify(BOOL msgSync, int clientId, int msg, intext1, int ext2, const Parcel *p_obj);
    virtual status_t createClient(const sp<ITestClient>&client, int clientId);
    virtual status_t destoryClient(const sp<ITestClient>&client, int clientId);
    virtual status_t testSiRequest(const Parcel *p_obj);
    virtual status_t testSiFree(const Parcel *p_obj);

  private:
    ITestClient_t *getFreeTestClient(int clientId);
    ITestClient_t *getBusyTestClient(int clientId);
    ITestClient_t clientTab[TEST_CLIENT_MAX_NUMBER];
    Mutex mLock;
    BOOL gFail;
};

}; // namespace android

 

/***************************************************************************/

testservice.cpp

#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h> // for status_t
#include <utils/RefBase.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/Log.h>
#include "itestclient.h"
#include "testservice.h"
#include <utils/Log.h>

#define TEST_SERVICE_LOG_TAG "testservie"
#ifdef TEST_SERVICE_LOG_TAG
#define Testserviceprintfv(...) __android_log_print(ANDROID_LOG_VERBOSE, TEST_SERVICE_LOG_TAG,__VA_ARGS__)
#define Testserviceprintfd(...) __android_log_print(ANDROID_LOG_DEBUG, TEST_SERVICE_LOG_TAG,__VA_ARGS__)
#define Testserviceprintfi(...) __android_log_print(ANDROID_LOG_INFO, TEST_SERVICE_LOG_TAG,__VA_ARGS__)
#define Testserviceprintfw(...) __android_log_print(ANDROID_LOG_WARN, TEST_SERVICE_LOG_TAG,__VA_ARGS__)
#define Testserviceprintfe(...) __android_log_print(ANDROID_LOG_ERROR, TEST_SERVICE_LOG_TAG,__VA_ARGS__)
#else
#define Testserviceprintfv(...)
#define Testserviceprintfd(...)
#define Testserviceprintfi(...)
#define Testserviceprintfw(...)
#define Testserviceprintfe(...)
#endif

#define ALIGN4_SIZE(s) (((s) + 3) & ~3)


//using namespace android;

namespace android
{

static sp<TESTService> mServiceheadle = NULL;

extern "C" {
void testSiNotify(notify_msg_t *p_msg)
{
    //  int i = 0;
    int msg_id = p_msg->msg_type;
    int data1 = p_msg->tableId;
    int data2 = p_msg->dataType;
    int data_size = p_msg->data_size;
    int clientId = p_msg->clientId;
    unsigned char *p_parce_buff = (unsigned char*)p_msg->p_data;

    if (mServiceheadle == NULL) {
    Testserviceprintfe("serviece is NULL\n");
    return;
    }
    if (p_parce_buff != NULL) {
    Parcel mobj;
    int parcel_size = 0;
    parcel_size = ALIGN4_SIZE(data_size);
    /****user java parcel  readByteArray*******/
    mobj.writeInt32(parcel_size);
    mobj.write(p_parce_buff, parcel_size);
    mobj.setDataPosition(0);
    //Testserviceprintfv("send message(parcel) msg id =0x%x,data1 =x%x,data1 =x%x, data size =%d\n",msg_id,data1,data2,mobj.dataSize());
    //Testserviceprintfv("send message(parcel) msg info:%s\n",(char *)p_parce_buff);

    mServiceheadle->clientNotify(p_msg->msgSync, clientId,msg_id, data1, data2, &mobj);
    mobj.freeData();
    } else {
    //Testserviceprintfv("send message msg id = 0x%x,data1=x%x,data1 =x%x,\n",msg_id,data1,data2);
    mServiceheadle->clientNotify(p_msg->msgSync, clientId,msg_id, data1, data2, NULL);
    }
}
};

TESTService::TESTService()
{
    void *p_handle = NULL;
    Testserviceprintfv("test service init\n");
    gFail = FALSE;
    memset(clientTab, 0, sizeof(ITestClient_t) * TEST_CLIENT_MAX_NUMBER);
    p_handle = test_svc_init();
    if (p_handle == NULL) {
    gFail = TRUE;
    Testserviceprintfv("test service init fail!\n");
    }
    mServiceheadle = this;
}
TESTService::~TESTService()
{
    Testserviceprintfv("test service destory\n");
    if (gFail == FALSE) {
    test_svc_deinit();
    }
    memset(clientTab, 0, sizeof(ITestClient_t) * TEST_CLIENT_MAX_NUMBER);
    mServiceheadle = NULL;
}

ITestClient_t *TESTService::getFreeTestClient(int clientId)
{
    int i = 0;
    for (i = 0; i < TEST_CLIENT_MAX_NUMBER; i++) {
    if ((clientTab[i].client_id == clientId) &&
        (clientTab[i].gfixed == true)) {
        return NULL;
    }
    }

    for (i = 0; i < TEST_CLIENT_MAX_NUMBER; i++) {
    if (clientTab[i].gfixed == false) {
        return &clientTab[i];
    }
    }

    return NULL;
}

ITestClient_t *TESTService::getBusyTestClient(int clientId)
{
    int i = 0;
    for (i = 0; i < TEST_CLIENT_MAX_NUMBER; i++) {
    if ((clientTab[i].client_id == clientId) &&
        (clientTab[i].gfixed == true)) {
        return &clientTab[i];
    }
    }
    return NULL;
}

void TESTService::clientNotify(BOOL msgSync, int clientId, int msg, int ext1,int ext2, const Parcel *p_obj)
{
    unsigned char i = 0;
    if (msgSync != TRUE) {
    Mutex::Autolock l(mLock);
    }
    for (i = 0; i < TEST_CLIENT_MAX_NUMBER; i++) {
    if ((clientTab[i].gfixed == true) &&(clientTab[i].client_id == clientId)) {
        sp<ITestClient> testclient =clientTab[i].mclient;
        testclient->notify(msg, ext1, ext2,p_obj);
    }
    }
}

status_t TESTService::createClient(const sp<ITestClient> &client, intclientId)
{
    ITestClient_t *p_iclient = NULL;
    Testserviceprintfv("create client[0x%x] start\n",clientId);
    Mutex::Autolock l(mLock);
    Testserviceprintfv("create client[0x%x]endlock\n", clientId);
    p_iclient = getFreeTestClient(clientId);
    if (p_iclient == NULL) {
    Testserviceprintfe("create client[0x%x] fail\n",clientId);
    return (UNKNOWN_ERROR);
    }
    p_iclient->mclient = client;
    p_iclient->client_id = clientId;
    p_iclient->gfixed = true;
    Testserviceprintfv("create client[0x%x]\n",clientId);
    return (NO_ERROR);
}

status_t TESTService::destoryClient(const sp<ITestClient> &client,int clientId)
{
    ITestClient_t *p_iclient = NULL;
    Mutex::Autolock l(mLock);
    p_iclient = getBusyTestClient(clientId);
    if (p_iclient == NULL) {
    Testserviceprintfe("destory client[0x%x]\n",clientId);
    return (UNKNOWN_ERROR);
    }

    p_iclient->mclient = NULL;
    p_iclient->client_id = 0;
    p_iclient->gfixed = false;
    Testserviceprintfv("create client[0x%x]\n",clientId);
    return (NO_ERROR);
}

status_t TESTService::testSiRequest(const Parcel *p_obj)
{
    unsigned char *p_data_buff = NULL;
    int data_size = 0;
    req_test_t requestParam;
    memset(&requestParam, 0, sizeof(req_test_t));
    Mutex::Autolock l(mLock);
    if (p_obj && p_obj->dataSize() > 0) {
    data_size = p_obj->dataSize();
    p_data_buff = (unsigned char *)malloc(data_size);
    if (p_data_buff != NULL) {

        p_obj->setDataPosition(0);
        p_obj->read(p_data_buff, data_size);
    } else {
        Testserviceprintfe("TestServiceControl:malloc:%d fail\n", data_size);
        return (UNKNOWN_ERROR);
    }

    if (data_size == sizeof(test_request_t)) {
        memcpy(&requestParam.request,p_data_buff, data_size);
        requestParam.notify = (test_notify_t)testSiNotify;
        test_svc_request(&requestParam);
        free(p_data_buff);
        return (NO_ERROR);
    } else {
        free(p_data_buff);
    }
    }
    return (UNKNOWN_ERROR);
}

status_t TESTService::testSiFree(const Parcel *p_obj)
{
    unsigned char *p_data_buff = NULL;
    int data_size = 0;
    req_test_t requestParam;
    memset(&requestParam, 0, sizeof(req_test_t));
    Mutex::Autolock l(mLock);
    if (p_obj && p_obj->dataSize() > 0) {
    data_size = p_obj->dataSize();
    p_data_buff = (unsigned char *)malloc(data_size);
    if (p_data_buff != NULL) {

        p_obj->setDataPosition(0);
        p_obj->read(p_data_buff, data_size);
    } else {
        Testserviceprintfe("TestServiceControl:malloc:%d fail\n", data_size);
        return (UNKNOWN_ERROR);
    }

    if (data_size == sizeof(test_request_t)) {
        memcpy(&requestParam.request,p_data_buff, data_size);
        requestParam.notify = (test_notify_t)testSiNotify;
        test_svc_free(&requestParam);
        free(p_data_buff);
        return (NO_ERROR);
    } else {
        free(p_data_buff);
    }
    }
    return (UNKNOWN_ERROR);
}

}; // namespace android

 

Lister

/***************************************************************************/

listener.h

#ifndef _LISTENER_H_

#define _LISTENER_H_

#include "jni.h"

#include "JNIHelp.h"

#include "android_runtime/AndroidRuntime.h"

#include <utils/Errors.h> // for status_t

#include "utils/KeyedVector.h"

#include <utils/RefBase.h>

#include <binder/IMemory.h>

#include <binder/IServiceManager.h>

#include <binder/IPCThreadState.h>

#include <binder/Parcel.h>

namespace android {

class Listener : virtual public RefBase

{

public:

    virtual void notify(int msg, int ext1, int ext2, unsigned char *p_data,unsigned int dataSize) =0;

};

class JNIListener: public Listener

{

public:

    JNIListener(JNIEnv* env, jobject thiz,jmethodID callMethodId);

    ~JNIListener();

    virtual void notify(int msg, int ext1, int ext2,unsigned char *p_data,unsigned int dataSize) ;

private:

    JNIListener();

    jmethodID   mpost_event;

    jclass      mClass;     // Reference to MediaPlayer class

};

};

#endif

/***************************************************************************/

listener.cpp

#include <utils/Log.h>

#include <stdint.h>

#include <sys/types.h>

#include <stdio.h>

#include <assert.h>

#include <limits.h>

#include <unistd.h>

#include <fcntl.h>

#include <utils/threads.h>

#include "jni.h"

#include "JNIHelp.h"

#include "android_runtime/AndroidRuntime.h"

#include <utils/Errors.h> // for status_t

#include "utils/KeyedVector.h"

#include <utils/RefBase.h>

#include <binder/IMemory.h>

#include <binder/IServiceManager.h>

#include <binder/IPCThreadState.h>

#include <binder/Parcel.h>

#include <utils/String8.h>

#include <utils/Log.h>

#include <android/log.h>

#include <cutils/log.h>

#include <log/log.h>

#include "android_os_Parcel.h"

#include "android_util_Binder.h"

#include "listener.h"

namespace android

{

JNIListener::JNIListener(JNIEnv *env, jobject thiz, jmethodID callMethodId)

{

    // Hold onto the MediaPlayer class for use in calling the static method

    // that posts events to the application thread.

    jclass clazz = env->GetObjectClass(thiz);

    if (clazz == NULL) {

    ALOGE("Can't find android/os/dvb");

    jniThrowException(env, "java/lang/Exception", NULL);

    return;

    }

    mClass = (jclass)env->NewGlobalRef(clazz);

    mpost_event = callMethodId;

    __android_log_print(ANDROID_LOG_VERBOSE, "dvbclientlistener", "#### JNIListener ok\n");

}

JNIListener::~JNIListener()

{

    // remove global references

    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->DeleteGlobalRef(mClass);

    __android_log_print(ANDROID_LOG_VERBOSE, "dvbclientlistener", "#### ~JNIListener ok\n");

}

void JNIListener::notify(int msg, int ext1, int ext2, unsigned char *p_data, unsigned int dataSize)

{

    JNIEnv *env = AndroidRuntime::getJNIEnv();

    //__android_log_print(ANDROID_LOG_VERBOSE,"dvbclientjni","notify");

    if ((p_data != NULL) && (dataSize > 0)) {

#if 1

    jobject jParcel = createJavaParcelObject(env);

    if (jParcel != NULL) {

        Parcel *nativeParcel = parcelForJavaObject(env, jParcel);

        if (NULL != nativeParcel) {

        nativeParcel->setData(p_data, dataSize);

        nativeParcel->setDataPosition(0);

        env->CallStaticVoidMethod(mClass, mpost_event,

                                  msg, ext1, ext2, jParcel);

        }

        env->DeleteLocalRef(jParcel);

    }

#else

    int size = p_obj->dataSize();

    __android_log_print(ANDROID_LOG_VERBOSE, "dvbclientjni", "notify call  message(parcel) msg id = 0x%x,data1 =x%x,data1 =x%x, data size = %d\n",

                        msg, ext1, ext2, size);

    char *p_buffer_parcel = (char *)malloc(size);

    if (NULL != p_buffer_parcel) {

        p_obj->setDataPosition(0);

        p_obj->read(p_buffer_parcel, size);

        p_obj->setDataPosition(0);

        // __android_log_print(ANDROID_LOG_VERBOSE, "dvbclientjni","notify call  message(parcel) msg info:%s\n",(char *)p_buffer_parcel);

        jbyteArray jbarr = env->NewByteArray(size);

        if (jbarr != NULL) {

        jbyte *bytekey = env->GetByteArrayElements(jbarr, 0);

        if (bytekey != NULL) {

            int bytekeylen = env->GetArrayLength(jbarr);

            memcpy(bytekey, p_buffer_parcel, bytekeylen);

            env->CallStaticVoidMethod(mClass, mpost_event, msg, ext1, ext2, jbarr);

            env->ReleaseByteArrayElements(jbarr, bytekey, 0);

            env->DeleteLocalRef(jbarr);

        }

        }

        free(p_buffer_parcel);

    }

#endif

    } else {

    //   __android_log_print(ANDROID_LOG_VERBOSE, "dvbclientjni","notify call  message msg id = 0x%x,data1 =x%x,data1 =x%x\n",

    //          msg,ext1,ext2);

    env->CallStaticVoidMethod(mClass, mpost_event, msg, ext1, ext2, NULL);

    }

    if (env->ExceptionCheck()) {

    ALOGW("An exception occurred while notifying an event.");

    //LOGW_EX(env);

    env->ExceptionClear();

    }

}

}



service  process

#include<binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>

#include "testservice.h"

using namespace android;

int main(int argc, char **argv)
{
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    sm->addService(String16("service.test"), new TESTService());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return(0);
}


android.mk

LOCAL_C_INCLUDES := \
    external/jhead \
    external/tremor/Tremor \
    $(TOP)/frameworks/base/core/jni


LOCAL_SRC_FILES := \
    $(call all-cpp-files-under,binder) \
    $(call all-cpp-files-under,jniListener) \

LOCAL_SHARED_LIBRARIES += libutils libbinder libandroid_runtime

加入启动服务

service testserver /system/bin/testserver
    class main