上一篇博客《Android 6.0 如何添加完整的系統服務(app-framework-kernel)》http://www.cnblogs.com/hackfun/p/7418902.html介紹瞭如何添加一個系統服務,客戶端和服務端都是基於JAVA實現的OpersysService。經過進一步的 ...
上一篇博客《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();