Android 编写硬件访问服务

1、定义硬件访问服务接口

添加 frameworks\base\core\java\android\hardware\freg\IFregService.aidl

package android.hardware.freg;

interface IFregService {
    void setVal (int val);
    int getVal ();
}

修改 frameworks\base\Android.mk
core/java/android/hardware/freg/IFregService.aidl \

mmm frameworks/base/


2、实现硬件访问服务

添加 frameworks\base\services\core\java\com\android\server\freg\FregService.java

package com.android.server.freg;

import android.hardware.freg.IFregService;
import android.util.Slog;

/**
 * Created by liudongming on 1/14/17.
 */

public class FregService extends IFregService.Stub {
    private static final String TAG = "FregService";

    private long mPtr = 0;

    public FregService () {
        Slog.d(TAG, "FregService()");
        mPtr = init_native ();

        if(mPtr == 0){
            Slog.e(TAG, "Failed to initialize freg service.");
        }
    }

    public void setVal (int val){
        if (mPtr == 0){
            Slog.e(TAG, "setVal Freg service is not initialized.");
            return;
        }

        setVal_native(mPtr, val);
    }

    public int getVal(){
        if (mPtr == 0){
            Slog.e(TAG, "getVal Freg service is not initialized.");
            return 0;
        }

        return getVal_native(mPtr);
    }

    private static native long init_native();
    private static native void setVal_native(long ptr, int val);
    private static native int getVal_native(long ptr);
};

3、实现硬件访问服务的JNI方法

添加 frameworks\base\services\core\jni\com_android_server_freg_FregService.cpp

//
// Created by liudongming on 1/14/17.
//

#undef LOG_TAG
#define LOG_TAG "FregServiceJNI"
#define TAG "[Freg] "

#include "jni.h"
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>

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

#include <hardware/hardware.h>
#include <hardware/freg.h>

#include <stdio.h>

#define LOGD ALOGD
#define LOGI ALOGI
#define LOGW ALOGW
#define LOGE ALOGE

namespace android
{

    //设置虚拟硬件设备freg的寄存器的值,64位机器上指针占8字节,使用long来转换
    //static void freg_setVal (JNIEnv* env, jobject clazz, jint ptr, jint value){
    static void freg_setVal (JNIEnv* env, jobject clazz, jlong ptr, jint value){
        //将参数ptr转换为freg_device_t结构体变量
        freg_device_t* device = (freg_device_t*)ptr;
        if(!device){
            LOGE(TAG"Device freg is not open.");
            return;
        }

        int val = value;

        LOGI(TAG"Set value %d to device freg.", val);

        device->set_val(device, val);
    }

    //读取虚拟硬件设备freg的寄存器的值,64位机器上指针占8字节,使用long来转换
    //static jint freg_getVal (JNIEnv* env, jobject clazz, jint ptr) {
    static jint freg_getVal (JNIEnv* env, jobject clazz, jlong ptr) {
        //将参数ptr转换为freg_device_t结构体变量
        freg_device_t* device = (freg_device_t*)ptr;
        if(!device){
            LOGE(TAG"Device freg is not open.");
            return 0;
        }

        int val = 0;

        device->get_val (device, &val);

        LOGI(TAG"Get value %d from device freg.", val);

        return val;
    }

    //打开虚拟硬件设备freg
    static inline int freg_device_open(const hw_module_t* module, struct freg_device_t** device) {
        LOGD(TAG"freg_device_open");
        return module->methods->open(module, FREG_HARDWARE_DEVICE_ID, (struct hw_device_t**)device);
    }

    //初始化虚拟硬件设备freg
    static jlong freg_init (JNIEnv* env, jclass clazz) {
        freg_module_t* module;
        freg_device_t* device;

        LOGI(TAG"Initializing HAL stub freg......");

        //加载硬件抽象层模块freg
        if(hw_get_module(FREG_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0){
            LOGI(TAG"Device freg found.");

            //打开虚拟硬件设备freg
            if(freg_device_open(&(module->common), &device) == 0){
                LOGI(TAG"Device freg is open");

                //将freg_device_t接口转换为整形值返回
                //return (jlong)device;
                return reinterpret_cast<jlong>(device);
            }

            LOGE(TAG"Faied to open device freg.");
            return 0;
        }

        LOGE(TAG"Faied to get HAL stub freg.");
        return 0;
    }

    //Java本地接口方法表
    static const JNINativeMethod method_table[] = {
        {"init_native", "()J", (void*)freg_init},
        {"setVal_native", "(JI)V", (void*)freg_setVal},
        {"getVal_native", "(J)I", (void*)freg_getVal},
    };

    //注册Java本地接口方法
    int register_android_server_FregService(JNIEnv* env){
        return jniRegisterNativeMethods(env, "com/android/server/freg/FregService",
        method_table, NELEM(method_table));
    }
}



修改 frameworks\base\services\core\jni\Onload.cpp
添加
int register_android_server_FregService(JNIEnv* env);// add by liudongming

register_android_server_FregService(env); //add by liudongming

namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_AssetAtlasService(JNIEnv* env);
int register_android_server_BatteryStatsService(JNIEnv* env);
int register_android_server_ConsumerIrService(JNIEnv *env);
int register_android_server_InputApplicationHandle(JNIEnv* env);
int register_android_server_InputWindowHandle(JNIEnv* env);
int register_android_server_InputManager(JNIEnv* env);
int register_android_server_FregService(JNIEnv* env);// add by liudongming
int register_android_server_LightsService(JNIEnv* env);
int register_android_server_PowerManagerService(JNIEnv* env);
int register_android_server_SerialService(JNIEnv* env);
int register_android_server_SystemServer(JNIEnv* env);
int register_android_server_UsbDeviceManager(JNIEnv* env);
......


extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        ALOGE("GetEnv failed!");
        return result;
    }
    ALOG_ASSERT(env, "Could not retrieve the env!");

    register_android_server_PowerManagerService(env);
    register_android_server_SerialService(env);
    register_android_server_InputApplicationHandle(env);
    register_android_server_InputWindowHandle(env);
    register_android_server_InputManager(env);
    register_android_server_FregService(env); //add by liudongming
    register_android_server_LightsService(env);
    register_android_server_AlarmManagerService(env);
    register_android_server_UsbDeviceManager(env);
    register_android_server_UsbMidiDevice(env);
    register_android_server_UsbHostManager(env);
       ......

修改 frameworks\base\services\core\jni\Android.mk 添加

$(LOCAL_REL_DIR)/com_android_server_freg_FregService.cpp \

LOCAL_SRC_FILES += \
    ......
    $(LOCAL_REL_DIR)/com_android_server_freg_FregService.cpp \
    $(LOCAL_REL_DIR)/onload.cpp

编译一下 mmm /frameworks/base/


4、启动硬件访问服务

修改 frameworks\base\services\java\com\android\server\SystemServer.java


import com.android.server.freg.FregService; //add by liudongming

private void startOtherServices() {
               ......
        StatusBarManagerService statusBar = null;
        INotificationManager notification = null;
        InputMethodManagerService imm = null;
        FregService afregService = null; //add by liudongming
        WallpaperManagerService wallpaper = null;
        LocationManagerService location = null;
        CountryDetectorService countryDetector = null;

              ......
               // Bring up services needed for UI.
        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            traceBeginAndSlog("StartInputMethodManagerService");
            try {
                imm = new InputMethodManagerService(context, wm);
                ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
            } catch (Throwable e) {
                reportWtf("starting Input Manager Service", e);
            }
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

            //add by liudongming begin
            traceBeginAndSlog("StartFregService");
            try {
                afregService = new FregService();
                ServiceManager.addService("freg", afregService);
            } catch (Throwable e) {
                reportWtf("starting Freg Service", e);
            }
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            //add by liudongming end

            traceBeginAndSlog("StartAccessibilityManagerService");
            try {
                ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
                        new AccessibilityManagerService(context));
            } catch (Throwable e) {
                reportWtf("starting Accessibility Manager", e);
            }
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

注:要更新一下api

make update-api

生成新的两个txt文件记得提交服务器

/frameworks/base/api/current.txt

/frameworks/base/api/system-current.txt


mmm /frameworks/base/

make snod


5、开发Android应用程序来使用硬件访问服务

~/packages/experimental/FregServiceTest

----AndroidManifest.xml

----Android.mk

----src

     ----com/mycompany/fregtest

           -----MainActivity.java

----res

     ----layout

          -----activity_main.xml

---- values

     ---- strings.xml

---- minimap

     ----ic_launcher.png


AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mycompany.fregtest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Android.mk

# Copyright (C) 2010 Google Inc.
#
# 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.
#

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_PACKAGE_NAME := FregTest

include $(BUILD_PACKAGE)

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    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="com.mycompany.fregtest.MainActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text="@string/namd"
        android:ems="10"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:id="@+id/editText" />

    <Button
        android:text="@string/read"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_alignParentStart="true"
        android:id="@+id/btnRead" />

    <Button
        android:text="@string/write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btnWrite"
        android:layout_below="@+id/editText"
        android:layout_toEndOf="@+id/btnRead" />

    <Button
        android:text="@string/clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btnClear"
        android:layout_below="@+id/editText"
        android:layout_toEndOf="@+id/btnWrite" />
</RelativeLayout>

MainActivity.java

package com.mycompany.fregtest;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.hardware.freg.IFregService;
import android.util.Log;
import android.app.Activity;
import android.os.ServiceManager;
import android.os.RemoteException;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener {

    private EditText etFregVal;
    private Button   btnRead;
    private Button   btnWrite;
    private Button   btnClear;
    private IFregService fregService;
    private final String TAG = "FregTest";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etFregVal = (EditText) findViewById(R.id.editText);
        btnRead = (Button) findViewById(R.id.btnRead);
        btnWrite = (Button) findViewById(R.id.btnWrite);
        btnClear = (Button) findViewById(R.id.btnClear);

        btnRead.setOnClickListener(this);
        btnWrite.setOnClickListener(this);
        btnClear.setOnClickListener(this);

        fregService = IFregService.Stub.asInterface(ServiceManager.getService("freg"));
        if (fregService == null) {
            Toast.makeText(this, "fregService is null", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnRead:
                try{
                    int val = fregService.getVal();
                    Log.d(TAG, "fregService.getVal " + val);
                    String text = String.valueOf(val);
                    etFregVal.setText(text);
                } catch (RemoteException e) {
                    Log.e(TAG, "Remote Exception while reading value from freg service." + e);
                    Toast.makeText(this, "Remote Exception while reading value from freg service.",
                            Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btnWrite:
                try{
                    String text = etFregVal.getText().toString();
                    int val = Integer.parseInt(text);
                    Log.d(TAG, "fregService.setVal " + val);
                    fregService.setVal(val);
                } catch (RemoteException e){
                    Log.e(TAG, "Remote Exception while writing value to freg service." + e);
                    Toast.makeText(this, "Remote Exception while writing value to freg service.",
                            Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btnClear:
                etFregVal.setText("");
                break;
            default:
                break;
        }
    }
}


strings.xml

<resources>
    <string name="app_name">FregTest</string>
    <string name="namd"></string>
    <string name="read">读取</string>
    <string name="write">写入</string>
    <string name="clear">清除</string>
</resources>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值