过程"/>
android学习之ECService的实现过程
本文章以实际项目为基础,只供自己阅读(代码路径均来自A10项目4.4版本)。
首先 从上层应用开始:
import android.os.IECService;
import android.os.ServiceManager;
import android.os.RemoteException;
public void getECService(){
IECService ecService = IECService.Stub.asInterface(ServiceManager.getService("ECServiceinfo"));if(ecService==null){Log.e(TAG,"Unable to create the ECService instance!");return ;}try { oldEcVersion=ecService.getVersion(); newEcVersion=ecService.get_ECFW_Version();} catch (RemoteException e) { e.printStackTrace(); } vvold[0]= (byte)(oldEcVersion & 0x000000FF); vvold[1]= (byte)((oldEcVersion>>8) & 0x000000FF); oldEC=String.format("%02x %02x", vvold[1], vvold[0]); vvfw[0]= (byte)(newEcVersion & 0x000000FF); vvfw[1]= (byte)((newEcVersion>>8)& 0x000000FF); fwEC=String.format("%02x %02x", vvfw[1], vvfw[0]);}这里我们看到:要使用ECService首先要申请相对应的服务ecService=IECService.Stub.asInterface(ServiceManager.getService("ECServiceinfo"));
我们来研究下这个服务如何实现:
先看ServiceManager
/frameworks/base/services/java/com/android/server/SystemServer.java
try {Slog.i(TAG, "Input Method Service");imm = new InputMethodManagerService(context, wm);ServiceManager.addService("ECServiceinfo", new ECService());ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);} catch (Throwable e) {reportWtf("starting Input Manager Service", e);}
在ServiceManager中添加名为“ECServiceinfo”的ECServiceServiceManager
ServiceManager.addService("ECServiceinfo", new ECService());这句就将new ECService()服务加入到ServiceManager并命名为ECServiceinfo,
在应用层使用时就调用该名字。
至于ECService()服务怎么实现的,我们进一步看看
/frameworks/base/services/java/com/android/server$ vi ECService.java
public class ECService extends IECService.Stub{//private static final String TAG = "ECService-JAVA";public static final int EC_MODE_USER = 0;ECService() {Log.w(TAG, "init\n");mNativePointer = init_native();//ServiceManager.addService("ECServiceinfo", this);}
ECService 类 extends IECService.Stub这就涉及到android引入一个aidl通信接口机制
先看上层函数的实现public int getVersion() {Log.w(TAG, "framework:getVersion\n");return get_version(mNativePointer);}
再看aidl,其实它就是一个bind,负责java层和native层的通信:private static native int init_native();private static native void finalize_native(int ptr);private static native int get_version(int ptr);
注意:需要在android.mk中编译该接口文件:
/frameworks/base$ vim
Android.mk LOCAL_SRC_FILES += \
packages/services/PacProcessor/com/android/net/IProxyService.aidl \ packages/services/Proxy/com/android/net/IProxyCallback.aidl \ packages/services/Proxy/com/android/net/IProxyPortListener.aidl \
+core/java/android/os/IECService.aidl \
现在就要进入到native层看看native int get_version(int ptr);函数的实现:
/frameworks/base/services/jni/com_android_server_ECService.cpp
static JNINativeMethod method_table[] = { 261 { "init_native", "()I", (void*)init_native }, 262 { "get_version","(I)I", (void*)get_version }, 263 { "get_ecfw_version","(I)I", (void*)get_ecfw_version }, 264 { "ec_fw_upgrade","(I)I", (void*)ec_fw_upgrade }, 265 { "ctrl_request", "(II[B)I", (void*)ctrl_request}, 266 { "device_ctrl", "(III)I", (void*)device_ctrl}, 267 { "read_firmware", "(I[BI)I", (void*)read_firmware }, 268 { "write_firmware", "(I[BI)I", (void*)write_firmware }, 269 { "finalize_native", "(I)V", (void*)finalize_native }, 270 { "native_writeVendorFlags", "(II)I", (void*)native_writeVendorFlags }, 271 { "native_readVendorFlags", "(I)I", (void*)native_readVendorFlags }, 272 { "native_resetImageCheckFlags", "(I)I", (void*)native_resetImageCheckFlags }, 273 { "native_readImageCheckFlags", "(I[BI)I", (void*)native_readImageCheckFlags }, 274 { "native_readGSensorAngle", "(I)I", (void*)native_readGSensorAngle }, 275 }; 276 277 int register_android_server_ECService(JNIEnv *env) 278 { 279 return jniRegisterNativeMethods(env, "com/android/server/ECService", 280 method_table, NELEM(method_table)); 281 }
注册及配对函数
{ "get_version","(I)I", (void*)get_version },前面是Java层函数,后者是jni层函数
static ec_device_t* get_device(hw_module_t* module, char const* name)43 {44 int err;45 hw_device_t* device;46 err = module->methods->open(module, name, &device);47 if (err == 0) {48 return (ec_device_t*)device;49 } else {50 ALOGI("Jget_device failed\n");51 return NULL;52 }53 }
获取虚拟驱动设备,并获取hw层
static jint init_native(JNIEnv *env, jobject clazz)56 {57 int err;58 hw_module_t* module;59 Devices* devices;60 ALOGI("JInitializing HAL stub for ec......");61 devices = (Devices*)malloc(sizeof(Devices));62 ALOGI("ecservice jni init_native\n");63 err = hw_get_module(EC_HARDWARE_MODULE_ID, (hw_module_t const**)&module);64 if (err == 0) {65 } else {66 memset(devices, 0, sizeof(Devices));67 }68 ALOGI("ec init\n");69 devices->ec = get_device(module, "ec_module");70 71 return (jint)devices;72 }
我们关注的功能函数的在jni中的实现:
static jint get_version(JNIEnv *env, jobject clazz, int ptr) 164 { 165 Devices* devices = (Devices*)ptr; 166 if (devices == NULL) { 167 return -1; 168 } 169 ALOGI("jget_version\n"); 170 171 return devices->ec->ops->ec_get_version(devices->ec); 172 }
注意:同样要加入android.mk
/frameworks/base/services/jni/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES:= \
com_android_server_input_InputManagerService.cpp \ com_android_server_input_InputWindowHandle.cpp \ com_android_server_LightsService.cpp \
+com_android_server_ECService.cpp \
com_android_server_power_PowerManagerService.cpp \ com_android_server_SerialService.cpp \ com_android_server_SystemServer.cpp \ 还有
/frameworks/base/services/jni/onload.cpp
@@ -57,6 +58,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
register_android_server_InputManager(env); register_android_server_LightsService(env);
+register_android_server_ECService(env);
register_android_server_AlarmManagerService(env); register_android_server_UsbDeviceManager(env);
现在就要去hardware/hardware/libhardware/hardware.c
int hw_get_module(const char *id, const struct hw_module_t **module) { return hw_get_module_by_class(id, NULL, module); }jni层中函数的实现调用这个实现在devices->ec->ops->ec_get_version(devices->ec);
/hardware/libhardware/include/hardware$ vi ec.h
struct ec_device;typedef struct ec_device_ops{int (*ec_init)(struct ec_device *);int (*ec_get_version)(struct ec_device *);int (*ec_get_fw_version)(struct ec_device *);int (*ec_fw_upgrade)(struct ec_device *);int (*ec_ctrl_request)(struct ec_device *, int,unsigned char*);int (*ec_device_control)(struct ec_device *, int, int);}typedef struct ec_device { hw_device_t common; ec_device_ops_t *ops; void *priv; } ec_device_t;找到头文件后再寻找具体实现的cpplimi@git-server:~/android_4.4_A10/hardware/rk29/libec$ ls
Android_bak.mkAndroid.mk ECHal.cpp ECHal.h ECHal_Module.cpp ECHal_Module.h
以上文件需要添加
/hardware/rk29/libec$ vi ECHal_Module.cpp
int ec_get_version(struct ec_device * device){int ver; ite_ec_device_t* ite_dev = NULL; LOGV("%s", __FUNCTION__);if(!device) return -1;ite_dev = (ite_ec_device_t*) device; return gECHal->getECVersion();}
gECHal->getECVersion();继续追踪到 ECHal.cpp
hardware/rk29/libec$ vi ECHal.cpp
int ECHal::getECVersion(void){int ret;int flag =0;LOGI("H:getECVersion");if (ite_init() < 0) {LOGI("H:failed to open ec device\n");return -1;}if (ioctl(m_fd,CMD_GET_VERSION , &flag)) {LOGE("get ver=%0x\n",flag); return -1;}release();return flag;}if(ioctl(m_fd,CMD_GET_VERSION , &flag))这里将设备节点和cmd传给底层驱动
到此,基本流程就分析完了。但是还有几个需要注意的地方:
因为/hardware/rk29/libec是我们自己添加的,全工程make编译的时候无法将其编译得到的库文件加载到系统中,解决方法:
先进入到/hardware/rk29/libec/Android.mk 看看输入的结果:
LOCAL_CFLAGS := -fno-short-enums -DCOPY_IMAGE_BUFFER
ifeq ($(strip $(TARGET_BOARD_HARDWARE)),rk30board)
LOCAL_CFLAGS += -DTARGET_RK30 endif
..........
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
LOCAL_MODULE:=ec.$(TARGET_BOARD_HARDWARE)
LOCAL_MODULE_TAGS:= optional include $(BUILD_SHARED_LIBRARY)
在将其添加到系统中:
/device/rockchip/rksdk$ vi device.mk
@@ -201,6 +201,7 @@ PRODUCT_PACKAGES += \ power.$(TARGET_BOARD_PLATFORM) \ sensors.$(TARGET_BOARD_HARDWARE) \ gralloc.$(TARGET_BOARD_HARDWARE) \
+ec.$(TARGET_BOARD_HARDWARE) \
hwcomposer.$(TARGET_BOARD_HARDWARE) \
最后,赋予其权限相应的权限:/device/rockchip/rksdk$ vi ueventd.rk30board.rc
+#for ec
+/dev/ec0660 system system
+/dev/ite85610660 system system
其中/dev/ite8561
为EC的驱动设备节点,在/hardware/rk29/libec/ECHal.cpp中定义的: #define EC_DEVICE_PATH
"/dev/ite8561"
#define EC_CTRL_DEVICE_PATH "/dev/ec"
更多推荐
android学习之ECService的实现过程
发布评论