Android 6.0一个完整的native service

来源:互联网 发布:淘宝网买的学车模拟器 编辑:程序博客网 时间:2024/05/21 07:13

 

     上一篇博客《Android 6.0 如何添加完整的系统服务(app-framework-kernel)》http://www.cnblogs.com/hackfun/p/7418902.html
介绍了如何添加一个系统服务,客户端和服务端都是基于JAVA实现的OpersysService。经过进一步的学习,我将
演示如何使用C++实现一个相同功能的系统服务hfnativeservice。为了兼容OpersysService,将保留Opersys-
Service服务端中的HAL和driver,供hfnativeservice使用,即OpersysService和hfnativeservice这两个Service
都是用相同的HAL和driver。其中,hfnativeservice增加了一个服务端死亡通知机制,即hfnative-service的服
务端进程被杀掉时,客户端会收到这个通知,并做相应的清理工作。

    主要围绕以下几个步骤添加一个完整的C++系统服务:
(A) 添加HAL和Driver
(B) 添加服务接口,生成动态库
(C) 添加服务端
(D) 注册服务端
(E) 添加客户端
(F) 测试

 

(A) 添加HAL和Driver
   这部分参考上一篇博客《Android 6.0 如何添加完整的系统服务(app-framework-kernel)》的

    (A) 添加circular-char驱动
    (B) 添加opersyshw_qemu HAL

(B) 添加服务接口,生成动态库
   
为了对外只提供服务端或客户端的接口,这里把客户端和服务端之间的通信实现细节放在一起,生成动态库so
文件,服务端和客户端在使用的时候,加载这个so就可以了。IHfNativeService.cpp对客户端和服务端提供了相同
的接口,并实现了proxy和native之间的Binder通信细节。HfNativeManager.cpp根据IHfNativeService.cpp提供的
接口,进一步封装,隐藏了客户端的是操作细节,如服务的获取,注册死亡通知等。

相关头文件:

frameworks/native/include/hfnative/HfNativeManager.h

 1 #ifndef ANDROID_HACKFUN_HACKFUN_NATIVE_SERVICE_H 2 #define ANDROID_HACKFUN_HACKFUN_NATIVE_SERVICE_H 3  4 #include <stdint.h> 5 #include <sys/types.h> 6  7 #include <binder/IBinder.h> 8  9 #include <utils/RefBase.h>10 #include <utils/Singleton.h>11 #include <utils/threads.h>12 #include <hfnative/IHfNativeService.h> 13 14 namespace android {15 // ---------------------------------------------------------------------------16 17 class HfNativeManager : public Singleton<HfNativeManager>18 {19 public:20     HfNativeManager();21     ~HfNativeManager();22     23     int init_hfnative(void);24     void deinit_hfnative(void);25     int read_queue(char *buff, int len);26     int write_queue(char *buff, int len);27     int test_hfnative(int value);28 29     status_t assertState();30     bool checkService() const;31     void resetServiceStatus();32 33 private:34     bool isDied;35     // DeathRecipient interface36     void hfNativeServiceDied();37 38     mutable sp<IHfNativeService> mHfNativeServer;39     mutable sp<IBinder::DeathRecipient> mDeathObserver;40 };41 42 }; // namespace android43 44 #endif // ANDROID_HACKFUN_HACKFUN_NATIVE_SERVICE_H

 

 

frameworks/native/include/hfnative/IHfNativeService.h

 1 #ifndef ANDROID_HACKFUN_HACKFUN_COMPOSER_CLIENT_H 2 #define ANDROID_HACKFUN_HACKFUN_COMPOSER_CLIENT_H 3  4 #include <stdint.h> 5 #include <sys/types.h> 6  7 #include <utils/Errors.h> 8 #include <utils/RefBase.h> 9 10 #include <binder/IInterface.h>11 12 namespace android {13 // ----------------------------------------------------------------------------14 15 class IHfNativeService : public IInterface16 {17 public:18     DECLARE_META_INTERFACE(HfNativeService);19 20     virtual int init_native(void) = 0;21     virtual void finalize_native(void) = 0;22     virtual int read_native(char *Buff, int Len) = 0;23     virtual int write_native(char *Buff, int Len) = 0;24     virtual int test_native(int value) = 0;25 };26 27 // ----------------------------------------------------------------------------28 29 class BnHfNativeService: public BnInterface<IHfNativeService> {30 public:31     virtual status_t onTransact(uint32_t code, const Parcel& data,32             Parcel* reply, uint32_t flags = 0);33 };34 35 // ----------------------------------------------------------------------------36 37 }; // namespace android38 39 #endif // ANDROID_HACKFUN_HACKFUN_COMPOSER_CLIENT_H

 

 

源文件:

frameworks/native/libs/hfnative/IHfNativeService.cpp

  1 #define LOG_TAG "HfNativeService"  2   3 #include <stdio.h>  4 #include <stdint.h>  5 #include <malloc.h>  6 #include <sys/types.h>  7   8 #include <binder/Parcel.h>  9 #include <binder/IMemory.h> 10 #include <binder/IPCThreadState.h> 11 #include <binder/IServiceManager.h> 12 #include <hfnative/IHfNativeService.h> 13  14 namespace android { 15  16 enum { 17     INIT_NATIVE = IBinder::FIRST_CALL_TRANSACTION, 18     FINALIZE_NATIVE, 19     READ_NATIVE, 20     WRITE_NATIVE, 21     TEST_NATIVE 22 }; 23  24 class BpHfNativeService : public BpInterface<IHfNativeService> 25 { 26 public: 27     BpHfNativeService(const sp<IBinder>& impl) 28         : BpInterface<IHfNativeService>(impl) 29     { 30     } 31  32     int init_native(void) 33     { 34         Parcel data, reply; 35          36         data.writeInterfaceToken(IHfNativeService::getInterfaceDescriptor());  37         remote()->transact(INIT_NATIVE, data, &reply); 38  39         return (int)reply.readInt32(); 40     } 41  42     void finalize_native(void) 43     { 44         Parcel data, reply; 45  46         data.writeInterfaceToken(IHfNativeService::getInterfaceDescriptor()); 47         remote()->transact(FINALIZE_NATIVE, data, &reply); 48     } 49  50     int read_native(char *Buff, int Len) 51     { 52         Parcel data, reply; 53  54         data.writeInterfaceToken(IHfNativeService::getInterfaceDescriptor()); 55         data.writeInt32(Len); 56         remote()->transact(READ_NATIVE, data, &reply); 57         reply.read((void *)Buff, (size_t)Len); 58         return (int) reply.readInt32(); 59     } 60  61  62     int write_native(char *Buff, int Len) 63     { 64         Parcel data, reply; 65  66         data.writeInterfaceToken(IHfNativeService::getInterfaceDescriptor()); 67         data.writeInt32(Len); 68         data.write((const void *)Buff, (size_t)Len); 69         remote()->transact(WRITE_NATIVE, data, &reply); 70         return (int) reply.readInt32(); 71     } 72  73     int test_native(int value) 74     { 75         Parcel data, reply; 76  77         data.writeInterfaceToken(IHfNativeService::getInterfaceDescriptor()); 78         data.writeInt32(value); 79         remote()->transact(TEST_NATIVE, data, &reply); 80         return (int) reply.readInt32(); 81     } 82 }; 83  84 IMPLEMENT_META_INTERFACE(HfNativeService, "android.hfnative.HfNativeService"); 85  86 status_t BnHfNativeService::onTransact( 87     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 88 { 89     char *buff; 90     int len, retval; 91     status_t status; 92  93     switch(code) { 94         case INIT_NATIVE:  95             CHECK_INTERFACE(IHfNativeService, data, reply); 96             retval = init_native(); 97             reply->writeInt32(retval);  98             return NO_ERROR; 99 100         case FINALIZE_NATIVE:101             CHECK_INTERFACE(IHfNativeService, data, reply); 102             finalize_native();103             return NO_ERROR; 104 105         case READ_NATIVE: {106             CHECK_INTERFACE(IHfNativeService, data, reply);107             len = data.readInt32();108             buff = (char *)malloc(len);109             retval = read_native(buff, len);110             reply->write((const void *)buff, (size_t)len);111             free(buff);112             reply->writeInt32(retval);113             return NO_ERROR;114         } break;115 116         case WRITE_NATIVE: {117             CHECK_INTERFACE(IHfNativeService, data, reply);118             len = data.readInt32(); 119             buff = (char *)malloc(len);120             status = data.read((void *)buff, (size_t)len);      121             retval = write_native(buff, len);122             free(buff);123             reply->writeInt32(retval);124             return NO_ERROR;125         } break;126 127         case TEST_NATIVE:128             CHECK_INTERFACE(IHfNativeService, data, reply);129             retval = test_native(data.readInt32());130             reply->writeInt32(retval);131             return NO_ERROR;132 133         default:134           return BBinder::onTransact(code, data, reply, flags);135     }136 }137 138 }; // namespace android

 

 

frameworks/native/libs/hfnative/HfNativeManager.cpp

  1 #define LOG_TAG "HfNative"  2   3 #include <stdint.h>  4 #include <sys/types.h>  5   6 #include <utils/Errors.h>  7 #include <utils/RefBase.h>  8 #include <utils/Singleton.h>  9  10 #include <binder/IBinder.h> 11 #include <binder/IServiceManager.h> 12  13 #include <hfnative/IHfNativeService.h> 14 #include <hfnative/HfNativeManager.h> 15  16 // ---------------------------------------------------------------------------- 17 namespace android { 18 // ---------------------------------------------------------------------------- 19  20 HfNativeManager::HfNativeManager() : isDied(false) 21 { 22      23 } 24  25 HfNativeManager::~HfNativeManager() 26 { 27 } 28  29 void HfNativeManager::hfNativeServiceDied() 30 { 31     isDied = true; 32     mHfNativeServer.clear(); 33 } 34  35 status_t HfNativeManager::assertState() { 36     if (mHfNativeServer == NULL) { 37         // try for one second 38         const String16 name("hfnativeservice"); 39         for (int i=0 ; i<4 ; i++) { 40             status_t err = getService(name, &mHfNativeServer); 41             if (err == NAME_NOT_FOUND) { 42                 usleep(250000); 43                 continue; 44             } 45             if (err != NO_ERROR) { 46                 return err; 47             } 48             break; 49         } 50          51         init_hfnative(); 52         ALOGI("test hfnativeservice [%d]", test_hfnative(20)); 53  54  55         class DeathObserver : public IBinder::DeathRecipient { 56             HfNativeManager& mHfNativeManager; 57             virtual void binderDied(const wp<IBinder>& who) { 58                 ALOGW("hfnativeservice died [%p]", who.unsafe_get()); 59                 mHfNativeManager.hfNativeServiceDied(); 60             } 61         public: 62             DeathObserver(HfNativeManager& mgr) : mHfNativeManager(mgr) { } 63         }; 64  65         mDeathObserver = new DeathObserver(*const_cast<HfNativeManager *>(this)); 66         mHfNativeServer->asBinder(mHfNativeServer)->linkToDeath(mDeathObserver); 67     } 68  69     return NO_ERROR; 70 } 71  72 bool HfNativeManager::checkService() const  73 { 74     return isDied? true:false; 75 } 76  77 void HfNativeManager::resetServiceStatus()  78 { 79     isDied = false;  80 } 81  82  83 int HfNativeManager::init_hfnative(void) 84 { 85     return mHfNativeServer->init_native();  86 } 87  88 void HfNativeManager::deinit_hfnative(void) 89 { 90     mHfNativeServer->finalize_native(); 91 } 92  93 int HfNativeManager::read_queue(char *buff, int len) 94 { 95     return mHfNativeServer->read_native(buff,len); 96 } 97  98 int HfNativeManager::write_queue(char *buff, int len) 99 {100     return mHfNativeServer->write_native(buff,len);101 }102 103 int HfNativeManager::test_hfnative(int value)104 {105     return mHfNativeServer->test_native(value);106 }107 // ----------------------------------------------------------------------------108 }; // namespace android

 

 

frameworks/native/libs/hfnative/Android.mk

 1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3  4 LOCAL_SRC_FILES:= \ 5     IHfNativeService.cpp \ 6     HfNativeManager.cpp 7  8 LOCAL_SHARED_LIBRARIES := \ 9     libbinder \10     libcutils \11     libutils 12 13 LOCAL_MODULE:= libhfnativemgriface14 15 #ifneq ($(filter generic%,$(TARGET_DEVICE)),)16     # Emulator build17 #    LOCAL_CFLAGS += -DUSE_FENCE_SYNC18 #endif19 20 include $(BUILD_SHARED_LIBRARY)21 22 #ifeq (,$(ONE_SHOT_MAKEFILE))23 #include $(call first-makefiles-under,$(LOCAL_PATH))24 #endif

 

 

(C) 添加服务端

    服务端说白了就是客户端的远程调用,如,客户端调用write_native()的时候,服务端的write_native()
也会被调用。为什么客户端不能直接调用服务端的write_native(),就是因为客户端和服务端分别处于不同的
进程中,进程间的通讯必须通过Binder、socket等机制进行传递。

frameworks/native/services/hfnativeservice/HfNativeService.h

 1 #ifndef ANDROID_HACKFUN_NATIVE_SERVICE_H 2 #define ANDROID_HACKFUN_NATIVE_SERVICE_H 3  4 #include <stdint.h> 5 #include <sys/types.h> 6  7 #include <cutils/compiler.h> 8  9 #include <utils/Atomic.h>10 #include <utils/Errors.h>11 #include <utils/KeyedVector.h>12 #include <utils/RefBase.h>13 #include <utils/SortedVector.h>14 #include <utils/threads.h>15 16 #include <binder/BinderService.h>17 18 #include <hfnative/IHfNativeService.h>19 20 namespace android {21 22 // ---------------------------------------------------------------------------23 24 // ---------------------------------------------------------------------------25 class HfNativeService : public BinderService<HfNativeService>,26                        public BnHfNativeService27 {28 public:29     static char const* getServiceName() {30         return "hfnativeservice";31     }32 33     HfNativeService();34 35 private:36     virtual int init_native(void);37     virtual void finalize_native(void);38     virtual int read_native(char *Buff, int Len);39     virtual int write_native(char *Buff, int Len);40     virtual int test_native(int value);41 };42 43 // ---------------------------------------------------------------------------44 }; // namespace android45 46 #endif // ANDROID_HACKFUN_NATIVE_SERVICE_H

 

 

frameworks/native/services/hfnativeservice/HfNativeService.cpp

  1 #include <stdint.h>  2 #include <math.h>  3 #include <sys/types.h>  4   5 #include <utils/Errors.h>  6 #include <utils/RefBase.h>  7 #include <utils/Singleton.h>  8 #include <utils/String16.h>  9  10 #include <binder/BinderService.h> 11 #include <binder/IServiceManager.h> 12  13 #include <hfnative/IHfNativeService.h> 14  15 #include "HfNativeService.h" 16  17 #include <utils/misc.h> 18 #include <hardware/hardware.h> 19 #include <hardware/opersyshw.h>  20  21 #include <stdio.h> 22  23 namespace android { 24 // --------------------------------------------------------------------------- 25  26  27 opersyshw_device_t* opersyshw_dev;  28  29  30 HfNativeService::HfNativeService() 31 { 32 } 33  34 int HfNativeService::init_native(void) 35 { 36     int err; 37     hw_module_t* module; 38     opersyshw_device_t* dev = NULL; 39      40     ALOGI("init_native()");  41      42     err = hw_get_module(OPERSYSHW_HARDWARE_MODULE_ID, (hw_module_t const**)&module); 43     if (err == 0) { 44         if (module->methods->open(module, "", ((hw_device_t**) &dev)) != 0) { 45             ALOGE("Can't open opersys module!!!"); 46             return 0; 47         } 48     } else { 49         ALOGE("Can't get opersys module!!!");  50         return 0; 51     } 52      53     opersyshw_dev = dev; 54  55     return 0; 56 } 57  58 void HfNativeService::finalize_native(void) 59 { 60     opersyshw_device_t* dev = opersyshw_dev; 61      62     ALOGI("finalize_native()"); 63  64     if (dev == NULL) { 65         return; 66     } 67  68     dev->close(); 69  70     free(dev); 71 } 72  73  74 int HfNativeService::read_native(char *Buff, int Len) 75 { 76     opersyshw_device_t* dev = opersyshw_dev; 77     char* real_byte_array = Buff; 78     int length; 79      80     ALOGI("read_native()"); 81  82     if (dev == NULL) { 83         return 0; 84     } 85  86     length = dev->read((char*) real_byte_array, Len); 87      88     ALOGI("read data from hal: %s", (char *)real_byte_array); 89  90     return length; 91 } 92  93 int HfNativeService::write_native(char *Buff, int Len) 94 { 95     opersyshw_device_t* dev = opersyshw_dev; 96     char* real_byte_array = Buff; 97     int length; 98  99     ALOGI("write_native()");100 101     if (dev == NULL) {102         return 0;103     }104 105     length = dev->write((char*) real_byte_array, Len);106     107     ALOGI("write data to hal: %s", (char *)real_byte_array);108 109     return length;110 }111 112 int HfNativeService::test_native(int value)113 {114     opersyshw_device_t* dev = opersyshw_dev;115 116     if (dev == NULL) {117         return 0;118     }119     120     ALOGI("test_native()");121 122     return dev->test(value);123 }124 125 // ---------------------------------------------------------------------------126 }; // namespace android

 

 

frameworks/native/services/hfnativeservice/Android.mk

 1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3  4 LOCAL_SRC_FILES:= \ 5     HfNativeService.cpp \ 6  7 LOCAL_CFLAGS:= -DLOG_TAG=\"HfNativeService\" 8  9 LOCAL_C_INCLUDES += \10     $(call include-path-for, libhardware)/hardware11 12 LOCAL_SHARED_LIBRARIES := \13     libcutils \14     libutils \15     libbinder \16     libhardware \17     libhfnativemgriface18 19 LOCAL_MODULE:= libhfnativeservice20 21 include $(BUILD_SHARED_LIBRARY)

 

 

(D) 注册服务端
这里启动添加的的服务,使其运行于一个独立的进程中,等待客户端的请求。

frameworks/native/cmds/hfnative/main_hfnativeservice.cpp

 1 #include <binder/BinderService.h> 2 #include <HfNativeService.h> 3 #include <binder/IPCThreadState.h> 4 #include <binder/ProcessState.h> 5 #include <binder/IServiceManager.h> 6  7 #include <hfnative/IHfNativeService.h> 8  9 using namespace android;10 11 int main(int argc, char** argv) {12 #if 113     HfNativeService::publishAndJoinThreadPool(true);14     // Like the SurfaceFlinger, limit the number of binder threads to 4.15     ProcessState::self()->setThreadPoolMaxThreadCount(4);16 #else17     18     sp<ProcessState> proc(ProcessState::self());19 20     sp<IServiceManager> sm = defaultServiceManager();21 22     sm->addService(String16("hfnativeservice"), new HfNativeService());23 24     ProcessState::self()->startThreadPool();25     ProcessState::self()->giveThreadPoolName();26     IPCThreadState::self()->joinThreadPool();27     ProcessState::self()->setThreadPoolMaxThreadCount(4);28 #endif29     return 0;30 }

 

 

frameworks/native/cmds/hfnative/Android.mk

 1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3  4 LOCAL_SRC_FILES:= \ 5     main_hfnativeservice.cpp  6  7 LOCAL_SHARED_LIBRARIES := \ 8     libhfnativeservice \ 9     libbinder \10     libutils11 12 LOCAL_C_INCLUDES := \13     $(LOCAL_PATH)/../../services/hfnativeservice14 15 LOCAL_MODULE:= hfnativeservice16 17 include $(BUILD_EXECUTABLE)

 

 

(E) 添加客户端
    用户可以根据客户端提供的接口直接使用,无需关心复杂的客户端和服务端的通信细节。使用HfNativeManager
提供的接口,就能实现远程调用。这里创建了一个独立的线程用于等待接收服务端的死亡通知。

frameworks/base/tests/Hfnative/main_hfnativeclient.cpp

 1 #define LOG_TAG "HfNativeClient" 2  3 #include <fcntl.h> 4 #include <sys/prctl.h> 5 #include <sys/wait.h> 6 #include <cutils/properties.h> 7 #include <utils/Log.h> 8 #include <unistd.h> 9 #include <binder/IPCThreadState.h>10 #include <binder/ProcessState.h>11 12 #include <hfnative/HfNativeManager.h>13 14 using namespace android;15 16 17 class HfThread: public Thread {18 public:19     HfNativeManager *hfmgr;20 21     HfThread(void *ptr) {22         this->hfmgr = (HfNativeManager *)ptr;23     }24 25     bool threadLoop();26 };27 28 bool HfThread::threadLoop()29 {30     if (hfmgr->checkService()) {31         ALOGW("hfnativeservice Died, please do some clear!"); 32         hfmgr->resetServiceStatus();33     }34     35     usleep(250000);36 37     return true;38 }39 40 int main(int argc, char **argv) 41 {42     const char *str = {"Hello, Android !\0"};43     char buff[strlen(str)];44 45     HfNativeManager *hfmgr = new HfNativeManager();46 47     if (hfmgr->assertState() == NO_ERROR) {48         hfmgr->write_queue(const_cast<char *>(str), strlen(str));49         usleep(100000);50         hfmgr->read_queue(buff, sizeof(buff));51         ALOGI("Service returned: %s", buff);52     }53 54     sp<HfThread> th = new HfThread((void *)hfmgr);55     th->run();56 57     ProcessState::self()->startThreadPool();58     IPCThreadState::self()->joinThreadPool();59 60     return 0;61 }

 

 

frameworks/base/tests/Hfnative/Android.mk

 1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3  4 LOCAL_SRC_FILES:= \ 5     main_hfnativeclient.cpp  6  7 LOCAL_SHARED_LIBRARIES := \ 8     libhfnativemgriface \ 9     libbinder \10     libutils  \11     libcutils12 13 LOCAL_C_INCLUDES := \14     $(ANDROID_SOURCE)/frameworks/native/include/15 16 LOCAL_MODULE:= hfnativeclient17 18 include $(BUILD_EXECUTABLE)

 

 

(F) 测试

编译后生成对应文件:

out/target/product/<device>/.../system/lib/libhfnativemgriface.soout/target/product/<device>/.../system/lib/libhfnativeservice.soout/target/product/<device>/.../system/bin/hfnativeserviceout/target/product/<device>/.../system/bin/hfnativeclient

   

    然后push到机器的相应目录
    在机器根目录下,执行以下命令,并观察对应的输出打印(注意要先启动服务端进程):

# cd system/bin# hfnativeservice &# service check hfnativeserviceService hfnativeservice: found# hfnativeclient &# kill -9 pid

 

对应的输出打印:

......01-01 13:53:55.148  2424  2424 I HfNativeService: init_native()01-01 13:53:55.149  2424  2424 D opersyshw_qemu: OPERSYS HW has been initialized01-01 13:53:55.150  2424  2427 I HfNativeService: test_native()01-01 13:53:55.151  2434  2434 I HfNative: test hfnativeservice [20]01-01 13:53:55.151  2424  2424 I HfNativeService: write_native()01-01 13:53:55.151  2424  2424 D opersyshw_qemu: OPERSYS HW - write()for 16 bytes called01-01 13:53:55.151  2424  2424 D opersyshw_qemu: write data to driver: Hello, Android !01-01 13:53:55.151  2424  2424 I HfNativeService: write data to hal: Hello, Android !01-01 13:53:55.252  2424  2427 I HfNativeService: read_native()01-01 13:53:55.252  2424  2427 D opersyshw_qemu: OPERSYS HW - read()for 16 bytes called01-01 13:53:55.252  2424  2427 D opersyshw_qemu: read data from driver: Hello, Android !01-01 13:53:55.252  2424  2427 I HfNativeService: read data from hal: Hello, Android !01-01 13:53:55.252  2434  2434 I HfNativeClient: Service returned: Hello, Android !......01-01 13:54:08.210  2434  2434 W HfNative: hfnativeservice died [0xb6cc90c0]01-01 13:54:08.210   211   211 I ServiceManager: service 'hfnativeservice' died01-01 13:54:08.269  2434  2437 W HfNativeClient: hfnativeservice Died, please do some clear!......

 

阅读全文
0 0
原创粉丝点击