上一篇博客《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 interface 36 void hfNativeServiceDied(); 37 38 mutable sp<IHfNativeService> mHfNativeServer; 39 mutable sp<IBinder::DeathRecipient> mDeathObserver; 40 }; 41 42 }; // namespace android 43 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 IInterface 16 { 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 android 38 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:= libhfnativemgriface 14 15 #ifneq ($(filter generic%,$(TARGET_DEVICE)),) 16 # Emulator build 17 # LOCAL_CFLAGS += -DUSE_FENCE_SYNC 18 #endif 19 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 BnHfNativeService 27 { 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 android 45 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)/hardware 11 12 LOCAL_SHARED_LIBRARIES := 13 libcutils 14 libutils 15 libbinder 16 libhardware 17 libhfnativemgriface 18 19 LOCAL_MODULE:= libhfnativeservice 20 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 1 13 HfNativeService::publishAndJoinThreadPool(true); 14 // Like the SurfaceFlinger, limit the number of binder threads to 4. 15 ProcessState::self()->setThreadPoolMaxThreadCount(4); 16 #else 17 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 #endif 29 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 libutils 11 12 LOCAL_C_INCLUDES := 13 $(LOCAL_PATH)/../../services/hfnativeservice 14 15 LOCAL_MODULE:= hfnativeservice 16 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 libcutils 12 13 LOCAL_C_INCLUDES := 14 $(ANDROID_SOURCE)/frameworks/native/include/ 15 16 LOCAL_MODULE:= hfnativeclient 17 18 include $(BUILD_EXECUTABLE)
(F) 测试
编译后生成对应文件:
out/target/product/<device>/.../system/lib/libhfnativemgriface.so out/target/product/<device>/.../system/lib/libhfnativeservice.so out/target/product/<device>/.../system/bin/hfnativeservice out/target/product/<device>/.../system/bin/hfnativeclient
然后push到机器的相应目录
在机器根目录下,执行以下命令,并观察对应的输出打印(注意要先启动服务端进程):
# cd system/bin # hfnativeservice & # service check hfnativeservice Service 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 initialized 01-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 called 01-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 called 01-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‘ died 01-01 13:54:08.269 2434 2437 W HfNativeClient: hfnativeservice Died, please do some clear! ......