• ok6410 android driver(12)


      In this essay, I will talk about how to write the service libraries.

      TIPS :

    I won't discuss the name rules about HAL libraries, but it's quite important to our understanding.
    You can check the source file :
    android_source/hardware/libhardware/hardware.c
    Or google with key word :
    android hardware.c

      

      1、Android.mk

      In this file, it's important to write the LOCAL_SHARED_LIBRARIES and LOCAL_C_INCLUDE to assign the libraries for the service.

    # Android.mk
    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    
    # [optional, user, eng] 
    # eng = required
    # optinal = no install on target
    LOCAL_MODULE_TAGS := eng
    
    # This is the target being built.
    LOCAL_MODULE:= leds_hal_jni
    
    # Target install path.
    LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
    
    # All of the source files that we will compile.
    LOCAL_SRC_FILES:= 
        LedHalService.cpp
    
    # All of the shared libraries we link against.
    LOCAL_SHARED_LIBRARIES := 
          libandroid_runtime 
          libcutils 
          libhardware 
          libhardware_legacy 
          libnativehelper 
          libsystem_server 
          libutils 
          libui 
          libsurfaceflinger_client
           
    
    # Also need the JNI headers.
    LOCAL_C_INCLUDES += 
        $(JNI_H_INCLUDE) 
               hardware/leds_hal
    
    # Don't prelink this library.  For more efficient code, you may want
    # to add this library to the prelink map and set this to true.
    LOCAL_PRELINK_MODULE := false
    
    include $(BUILD_SHARED_LIBRARY)

      2、LedHalService.cpp

      Acturely, this file is the JNI file. Load the hal libraries (Use the hw_get_module function in hardware.c) and offer the API to android applications.

      There are another methods array we should know is JNINativeMethod.

      According the the native method, we could name the JNI functions ourselves without the long JNI default name.

    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <assert.h>
    #include <jni.h>
    
    #include <leds_hal.h>
    
    struct leds_device_t *leds_device = NULL;
    
    static jboolean leds_setOn(JNIEnv *env, jobject thiz, jint led)
    {
        LOGI("Leds HAL JNI : leds_setOn() is invoked.");
    
        if (leds_device == NULL) {
            LOGI("Leds HAL JNI : leds_device was not fetch correctly.");
            return -1;
        } else {
            return leds_device->set_on(leds_device, led);
        }
    }
    
    static jboolean leds_setOff(JNIEnv *env, jobject thiz, jint led)
    {
        LOGI("Leds HAL JNI : leds_setOff() is invoked.");
    
        if (leds_device == NULL) {
            LOGI("Leds HAL JNI : leds_device was not fetch correctly.");
            return -1;
        } else {
            return leds_device->set_off(leds_device, led);
        }
    }
    
    static inline int leds_device_open(const struct hw_module_t* module,
            struct leds_device_t** device)
    {
        return module->methods->open(module, LED_HARDWARE_MODULE_ID,
                (struct hw_device_t**) device);
    }
    
    static jboolean leds_init(JNIEnv *env, jclass clazz)
    {
        leds_module_t* module;
    
        LOGI(" >> finding HAL...");
        LOGI("HAL id :"LED_HARDWARE_MODULE_ID);
    
        if (hw_get_module(LED_HARDWARE_MODULE_ID, 
            (const hw_module_t**) &module) == 0) {
            LOGI("LedService JNI : Led Stub found.");
            if (leds_device_open(&module->hw_module, 
                    &leds_device) == 0) {
                LOGI("LedService JNI : Got Stub operation.");
                return 0;
            }
        }
        LOGE("LedService JNI : Get Stub operation failed.");
        return -1;
    }
    
    static const JNINativeMethod methods[] = {
        { "_init", "()Z", (void *) leds_init },
        { "_set_on", "(I)Z", (void *) leds_setOn },
        { "_set_off", "(I)Z", (void *) leds_setOff },
    };
    
    int register_leds_hal(JNIEnv *env)
    {
        static const char* const kClassName = "mobile/android/leds/hal/service/LedHalService";
        
        jclass clazz;
    
        clazz = env->FindClass(kClassName);
    
        if (clazz == NULL) {
            LOGE("Can't find class %s.
    ", kClassName);
            return -1;
        }
    
        if (env->RegisterNatives(clazz, methods, 
            sizeof(methods)/sizeof(methods[0]) != JNI_OK)) {
            LOGE("Failed registing methods for %s.
    ", kClassName);
            return -1;
        }
    
        return 0;
    }
    
    jint JNI_OnLoad(JavaVM *vm, void *reserved)
    {
        JNIEnv *env = NULL;
    
        if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
            LOGE(" GetEnv failed!");
            return -1;
        }
    
        register_leds_hal(env);
    
        return JNI_VERSION_1_4;
    }

      The prototype of JNINativeMethod :

    typedef struct { 
        const char* name; 
        const char* signature; 
        void*       fnPtr; 
    } JNINativeMethod;

      TIPS :

    In the LedHalService.cpp, we use #include <leds_hal.h> instead of #include "leds_hal.h", because of the Path was loaded in the Android.mk

      After compiling, we should push the file leds_jni.so to dir /system/lib/ in ok6410.

      Finaly, we write the Java program to call service library.

    package mobile.android.leds.hal.service;
    public class LedHalService {
        private static LedHalService ledHalService;
    
        public static LedHalService getInstance() {
            if (ledHalService == null)
                return new LedHalService();
            else 
                return ledHalService;
        }
    
        private LedHalService() {
            init();
        }
    
        public boolean init() {
            return _init();
        }
    
        public boolean setOn(int led) {
            return _set_on(led);
        }
    
        public boolean setOff(int led) {
            return _set_off(led);
        }
    
        private native boolean _init();
        private native boolean _set_on(int led);
        private native boolean _set_off(int led);
    
        static {
            System.load("/system/lib/leds_hal_jni.so");
        }
    }

      What's more, this is a Java file and we can't use it directly. We stiil need to create an apk to call its jar file.

    package com.example.leds_haljni;
    
    import mobile.android.leds.hal.service.LedHalService;
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.View;
    import android.widget.CheckBox;
    
    public class MainActivity extends Activity {
        private CheckBox[] cBox_leds = new CheckBox[4];
        LedHalService ledHalService = LedHalService.getInstance();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            cBox_leds[0] = (CheckBox) findViewById(R.id.checkBox_led1);
            cBox_leds[1] = (CheckBox) findViewById(R.id.checkBox_led2);
            cBox_leds[2] = (CheckBox) findViewById(R.id.checkBox_led3);
            cBox_leds[3] = (CheckBox) findViewById(R.id.checkBox_led4);
        }
        
        public void onClick_switch(View view) {
            
            for (int i = 0; i < 4; i ++) {
                if (cBox_leds[i].isChecked()) {
                    ledHalService.setOn(i);
                } else {
                    ledHalService.setOff(i);
                }    
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
    }

       Ok, here is the activity.xml and strings.xml :

      (1) activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hal_hello" />
    
        <CheckBox
            android:id="@+id/checkBox_led1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView1"
            android:layout_below="@+id/textView1"
            android:layout_marginTop="14dp"
            android:text="@string/led1" />
    
        <Button
            android:id="@+id/button_led"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/checkBox_led4"
            android:layout_alignBottom="@+id/checkBox_led4"
            android:layout_alignParentRight="true"
            android:onClick="onClick_switch"
            android:text="@string/button_led" />
    
        <CheckBox
            android:id="@+id/checkBox_led2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/checkBox_led1"
            android:layout_alignBottom="@+id/checkBox_led1"
            android:layout_alignRight="@+id/textView1"
            android:layout_marginRight="26dp"
            android:text="@string/led2" />
    
        <CheckBox
            android:id="@+id/checkBox_led3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/checkBox_led2"
            android:layout_alignBottom="@+id/checkBox_led2"
            android:layout_toRightOf="@+id/checkBox_led2"
            android:text="@string/led3" />
    
        <CheckBox
            android:id="@+id/checkBox_led4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/checkBox_led3"
            android:layout_alignBottom="@+id/checkBox_led3"
            android:layout_marginLeft="34dp"
            android:layout_toRightOf="@+id/checkBox_led3"
            android:text="@string/led4" />
    
    </RelativeLayout>

      (2) strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <string name="app_name">ledshal</string>
        <string name="action_settings">Settings</string>
        <string name="hal_hello">This is a leds HAL application :</string>
        <string name="led1">Led1</string>
        <string name="led2">Led2</string>
        <string name="led3">Led3</string>
        <string name="led4">Led4</string>
        <string name="button_led">Switch</string>
    
    </resources>

      That's all about the simple Led Hal.

     

  • 相关阅读:
    MyEclipse 2015 Stable 2.0破解方法
    GeoGlobe Server运维
    GeoGlobe Server运维
    Silverlight用户无法注册之MySql.Data.dll不一致
    Photoshop影像匀色技术
    GeoGlobe Server使用问题收集
    Windows Server 2008 R2中无法使用360免费Wifi的解决方案
    吉奥平台软件安装经验分享
    U盘中毒后变为快捷方式的解决方法
    主机访问虚拟机中新建的网站
  • 原文地址:https://www.cnblogs.com/plinx/p/3236859.html
Copyright © 2020-2023  润新知