2014年8月14日 星期四

(6)Application Frameworks層增加硬體訪問服務

在數字科技日新月異的今天,軟體和硬體的完美結合,造就了智能移動設備的流行。今天大家對iOS和Android系統的趨之若鶩,一定程度上是由於這兩個系統上有著豐富的應用軟體。因此,軟體和硬體的關係,在一定程度上可以說,硬體是為軟體服務的。硬體工程師研發出一款硬體設備,自然少了軟體工程師為其編寫驅動程式;而驅動程式的最終目的,是為了使得最上層的應用程式能夠使用這些硬體提供的服務來為用戶提供軟體功能。對Android系統上的應用軟體來說,就是要在系統的Application Frameworks層為其提供硬體服務。在前面的幾篇文章中,我們著重介紹了Linux核心層、硬體抽象層和執行時庫層提供的自定義硬體服務接口,這些接口都是通過C或者C++語言來實現的。在這一篇文章中,我們將介紹如何在Android系統的Application Frameworks層提供Java接口的硬體服務。


     一. 參照在Ubuntu為Android硬體抽象層(HAL)模組編寫JNI方法提供Java訪問硬體服務接口一文所示,為硬體抽象層模組準備好JNI方法調用層。


     二. 在Android系統中,硬體服務一般是執行在一個獨立的進程中為各種應用程式提供服務。因此,調用這些硬體服務的應用程式與這些硬體服務之間的通信需要通過代理來進行。為此,我們要先定義好通信接口。進入到frameworks/base/core/java/android/os目錄,新增IHelloService.aidl接口定義文件:


USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/core/java/android/os
USER-NAME@MACHINE-NAME:~/Android/frameworks/base/core/java/android/os$ vi IHelloService.aidl


     IHelloService.aidl定義了IHelloService接口:


package android.os;
interface IHelloService {
   void setVal(int val);
   int getVal();
}


IHelloService接口主要提供了設備和取得硬體暫存器val的值的功能,分別通過setVal和getVal兩個函數來實現。


三.返回到frameworks/base目錄,打開Android.mk文件,修改LOCAL_SRC_FILES變量的值,增加IHelloService.aidl源文件:


## READ ME: ########################################################
  ##
  ## When updating this list of aidl files, consider if that aidl is
  ## part of the SDK API. If it is, also add it to the list below that
  ## is preprocessed and distributed with the SDK. This list should
  ## not contain any aidl files for parcelables, but the one below should
  ## if you intend for 3rd parties to be able to send those objects
  ## across process boundaries.
  ##
  ## READ ME: ########################################################
  LOCAL_SRC_FILES += /
  ....................................................................
  core/java/android/os/IVibratorService.aidl \
  core/java/android/os/IHelloService.aidl \
  core/java/android/service/urlrenderer/IUrlRendererService.aidl \
  .....................................................................


   四. 編譯IHelloService.aidl接口:
   USER-NAME@MACHINE-NAME:~/Android$ mmm frameworks/base
  這樣,就會根據IHelloService.aidl生成相應的IHelloService.Stub接口。


成功訊息:
make: Entering directory `/home/cadtc/Android_BSP_Porting/android_4.0.4_tq210'
Aidl: framework <= frameworks/base/core/java/android/os/IHelloService.aidl
target Java: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Copying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/noproguard.classes.jar
target Dex: framework
Copying: out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/noproguard.classes.dex
target Jar: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/javalib.jar)
'out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.dex' as 'classes.dex'...
Install: out/target/product/tq210/system/framework/framework.jar
make: Leaving directory `/home/cadtc/Android_BSP_Porting/android_4.0.4_tq210'
cadtc@cadtc:~/Android_BSP_Porting/android_4.0.4_tq210$ mmm frameworks/base/services/java



  五.進入到frameworks/base/services/java/com/android/server目錄,新增HelloService.java文件:


package com.android.server;
import android.content.Context;
import android.os.IHelloService;
import android.util.Slog;
public class HelloService extends IHelloService.Stub {
private static final String TAG = "HelloService";
HelloService() {
init_native();
}
public void setVal(int val) {
setVal_native(val);
}
public int getVal() {
return getVal_native();
}
private static native boolean init_native();
    private static native void setVal_native(int val);
private static native int getVal_native();
};

HelloService主要是通過調用JNI方法init_native、setVal_native和getVal_native(見在Ubuntu為Android硬體抽象層(HAL)模組編寫JNI方法提供Java訪問硬體服務接口一文)來提供硬體服務。


六. 修改同目錄的SystemServer.java文件,在ServerThread::run函數中增加加載HelloService的程式:


   @Override
    public void run() {   
............................................................
           try {
                 Slog.i(TAG, "DiskStats Service");
         ServiceManager.addService("diskstats", new DiskStatsService(context));
           } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting DiskStats Service", e);
           }
           try {
                 Slog.i(TAG, "Hello Service");
                 ServiceManager.addService("hello", new HelloService());
           } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting Hello Service", e);
           }
............................................................
    }   
  
    七. 編譯HelloService和重新打包system.img:


    USER-NAME@MACHINE-NAME:~/Android$ mmm frameworks/base/services/java
    USER-NAME@MACHINE-NAME:~/Android$ make snod


成功訊息:
make: Entering directory `/home/cadtc/Android_BSP_Porting/android_4.0.4_tq210'
target Java: services (out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Copying: out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/services_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes.jar
Copying: out/target/common/obj/JAVA_LIBRARIES/services_intermediates/noproguard.classes.jar
target Dex: services
Copying: out/target/common/obj/JAVA_LIBRARIES/services_intermediates/noproguard.classes.dex
target Jar: services (out/target/common/obj/JAVA_LIBRARIES/services_intermediates/javalib.jar)
'out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes.dex' as 'classes.dex'...
Install: out/target/product/tq210/system/framework/services.jar
make: Leaving directory `/home/cadtc/Android_BSP_Porting/android_4.0.4_tq210'



    這樣,重新打包後的system.img系統鏡像文件就在Application Frameworks層中包含了我們自定義的硬體服務HelloService了,並且會在系統啟動的時候,自動加載HelloService。這時,應用程式就可以通過Java接口來訪問Hello硬體服務了。我們將在下一篇文章中描述如何編寫一個Java應用程式來調用這個HelloService接口來訪問硬體。



沒有留言:

張貼留言