android 經過jni實現framework(app)層調用android驅動

準備工做

在正式開始以前,須要知道下面兩點以及知足下面條件:java

前提條件

Android原生代碼,能夠經過make全編經過,編譯完成以後,能夠經過emulator命令啓動out目錄下生成的image文件,須要注意在執行emulator命令以前,須要執行source build/envsetup.sh構建環境,以及lunch選擇產品android

1.定義ISelfManager.aidl文件

系統裏面不少的aidl文件定義在/frameworks/base/core/Java/android/os下,因此咱們須要作的就是參考其餘的aidl,照樣子寫一個簡單的ISelfManager.aidlexpress

/frameworks/basecore/java/android/os/ISelfManager.aidlapache

package android.os;

interface ISelfManager {

    int selfAddNumber(int numberFirst, int numberSecond);
    String selfAddString(String originalStr);
}

2.更新Android.mk文件

在frameworks/base/Android.mk文件的LOCAL_SRC_FILES中系統添加了不少aidl文件,咱們須要添加本身定義的ISelfManager.aidl文件api

LOCAL_SRC_FILES += \
    core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
    core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
        .....
        core/java/android/os/ISelfManager.aidl \

而後使用mmm frameworks/base,此時會自動根據aidl文件生成對應的stub接口,其實這裏沒有生成也沒有關係,咱們能夠本身將該文件添加到Android studio中,讓ADT自動生成也能夠,這裏主要是方便後面編寫實現類,沒有太多的實際意義。 app

 

3.添加遠端實現SelfManagerService.java

這裏,咱們沒有特殊的需求就放在frameworks/base/services/core/java/com/android/server裏less

SelfManagerService.javasocket

package com.android.server;
import android.util.Log;
import android.os.ISelfManager;
/**
     * @hide
     */
public class SelfManagerService extends ISelfManager.Stub {
    /**
     * @hide
     */
    public int read() {
        int result = tngpio_read();
        Slog.e("zhy", "read=" + result);
        return result;
    }
    /**
     * @hide
     */
    public void write(char c) {
        Log.e("zhy", "write:" + c);
        tngpio_write(c);
    }

    private static native int tngpio_read();
    private static native void tngpio_write(char c);

}

 

4.建立對應的SelfManager

/frameworks/base/core/java/android/app/SelfManager.javaide

package android.app;
import android.util.Log;
import android.os.ISelfManager;
import android.content.Context;
import android.os.RemoteException;

public class SelfManager {
    private static String TAG = "SelfManager";

    ISelfManager mSelfManager;

    public SelfManager(Context ctx,ISelfManager selfManager) {
        mSelfManager = selfManager;
    }

    public int read() throws RemoteException {

        return mSelfManager.read();
    }

    public void write(char c) throws RemoteException {

        mSelfManager.write(c);
    }
}

 

5.管理和註冊SelfManagerService

在開始以前,已經分析系統Service的註冊流程,須要分別在SystemServer.java和SystemServiceRegistry.java中修改函數

  • 在SystemServer.java中將SelfManagerService添加到ServiceManager中管理,這裏我添加到了startOtherServices方法中
private void startOtherServices() {
    ....

    ServiceManager.addService("selfservice", new SelfManagerService());
    ....
}
  •  
  • 在SystemServiceRegistry.java中註冊咱們的SelfManagerService服務
import android.os.ISelfManager;
static {
    ....
    registerService("selfservice", SelfManager.class,
                new CachedServiceFetcher<SelfManager>() {
                    @Override
                    public SelfManager createService(ContextImpl ctx) {
                        IBinder b = ServiceManager.getService("selfservice");
                        ISelfManager service = ISelfManager.Stub.asInterface(b);
                        return new SelfManager(ctx,service);
                }});
    ....
}

這裏的」selfservice」,通常來講須要在Context.java中聲明,而後在這裏引用。

 

6.更新service.te文件

service.te主要用來定義咱們本身服務的類型,在/system/sepolicy/service.te目錄下,不一樣廠商的定製可能致使該路徑不一樣在該文件中已經定義了不少service類型,只須要照着畫就好了。

type wifi_service, app_api_service, system_server_service, service_manager_type;
// 參照 wifi_service的定義添加本身的定義就好了
type selfservice, system_api_service, system_server_service, service_manager_type;

更新/system/sepolicy/service_contexts文件

selfservice                               u:object_r:system_server_service:s0
  • 如今萬事已經具有了.全編就能夠了,須要注意, 在全編以前,須要更新當前系統的API 
    執行make update-api -j4,完成以後會生成本身添加的服務的API

    /frameworks/base/api/current.txt

    public class SelfManager {
        ctor public SelfManager(android.content.Context, android.os.ISelfManager);
        method public int selfAddNumber(int, int) throws android.os.RemoteException;
        method public java.lang.String
    完成以後,執行make命令全編就能夠了,

7.建立而且實現com_android_server_SelfManagerService.cpp

爲何須要它?由於咱們的hal代碼並無提供jni的接口(這裏提供了一種新的方法來提供native方法,以前是自動產生頭文件而後來實現的)。

frameworks/base/services/core/jni/com_android_server_SelfManagerService.cpp

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "SelfManagerService"

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"

#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/vibrator.h>

#include <stdio.h>

#include "JNIHelp.h"
#include "jni.h"
#include <utils/Log.h>
#include <utils/misc.h>

#include <fcntl.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

//方法在驅動中生成的節點
#define DEV_NAME "/dev/memdev"


namespace android
{
    static jint com_android_server_SelfManagerService_tngpio_read (JNIEnv* env, jobject clazz)
    {
        jint fd;
        fd = open(DEV_NAME, O_RDWR); //open 是jni提供的函數
        char buffer[1] = {1};
        jint result = read(fd, buffer, 1);
        return result;
    }

    static void com_android_server_SelfManagerService_tngpio_write (JNIEnv* env, jobject clazz, char c)
    {
        jint fd;
        char buffer[1] = {c};
       fd = open(DEV_NAME, O_RDWR);
       write(fd, buffer, 1);
       close(fd);
    }

   /*Java本地接口方法表*/  
    static JNINativeMethod method_table[] = {
        { "tngpio_read", "()I", (void*)com_android_server_SelfManagerService_tngpio_read },
        { "tngpio_write", "(C)V", (void*)com_android_server_SelfManagerService_tngpio_write }

    };

/*註冊Java本地接口方法*/ 
    int register_android_server_SelfManagerService(JNIEnv *env)
    {
            return jniRegisterNativeMethods(env, "com/android/server/SelfManagerService",
            method_table, NELEM(method_table));
    }

};

 

8.註冊native接口

在frameworks/base/services/core/jni/onload.cpp中添加(兩個地方)

int register_android_server_SelfManagerService(JNIEnv* env);  

register_android_server_SelfManagerService(env);  

9.修改Android.mk

在frameworks/base/services/core/jni/Android.mk中加入本身寫的

com_android_server_SelfManagerService.cpp:

$(LOCAL_REL_DIR)/com_android_server_SelfManagerService.cpp \  

10.mmm frameworks/base/services/編譯.

進行到這裏,全部的步驟就完成了,咱們能夠經過

SelfManager selfManager = (SelfManager) getContext().getSystemService("selfservice");
selfManager.read();
selfManager.write('c');

來調用驅動的讀和寫的方法。

幾個須要注意的地方

1:新建接口ISelfManager.aidl文件後,必定要將這個文件添加到framework/base/ 目錄下的Android.mk文件中

2:修改SelfManagerService.java這個文件後,最後執行下make update-api -j4,生成新的jar包

 

參考博客:http://blog.csdn.net/mockingbirds/article/details/54382072

http://blog.csdn.net/hedaogelaoshu/article/details/45247337

http://blog.csdn.net/richu123/article/details/51025477

相關文章
相關標籤/搜索