找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 12704|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

學(xué)習(xí)筆記-貫通 Android 底層驅(qū)動(dòng)至應(yīng)用層APP接口流程 代碼分析

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:91350 發(fā)表于 2015-9-30 01:04 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
以下例子均為未經(jīng)測(cè)試的代碼,也重點(diǎn)在整個(gè)的流程概況。目前仍有些不是太明白的地方。

分以下幾點(diǎn)(忽略HAL層):


驅(qū)動(dòng):lichee/linux-3.4/drivers/
        主要是初始化相關(guān)芯片以及具體的交互功能,然后創(chuàng)建設(shè)備節(jié)點(diǎn)來(lái)與上層交互。(盡量不做邏輯控制)
        調(diào)用 class_register() 接口時(shí),會(huì)在 /sys/class/ 目錄下創(chuàng)建設(shè)備節(jié)點(diǎn)。
        調(diào)用 misc_register()  接口時(shí),會(huì)在 /dev/ 目錄下創(chuàng)建設(shè)備節(jié)點(diǎn)。
        
JNI:android/frameworks/base/services/jni/
        該層一般是提供JAVA與 C\C++ 之間通信,這一層我主要用來(lái)做一些基本的邏輯控制處理,記得之前有
        次參加面試,該公司主要是做類似安防的手機(jī),他們就是主要在這層做邏輯控制。該層主要是通過(guò)
        映射表來(lái)描述 JAVA 方法與 C\C++ 函數(shù)之間的對(duì)應(yīng)關(guān)系。
        static JNINativeMethod method_table[] ={
                //  JAVA 方法                返回值與參數(shù)描述        C\C++ 函數(shù)
                {"Xxx_Init_native",             "()I",                    (void *)HardwareConfig_XxxInit},
                {"Xxx_Cmd_native",                 "(II)I",                   (void *)HardwareConfig_XxxCmd},
        };


Server:android/frameworks/base/services/java/com/android/server/SystemServer.java
        這個(gè)主要是供其他 APP 通過(guò) aidl 接口調(diào)用到 Server 方法,Server 方法通過(guò)JNI映射表,
        調(diào)用JNI的函數(shù)。進(jìn)一步封裝接口,實(shí)現(xiàn)必要的邏輯處理。


aidl:frameworks/base/core/java/android/os
        該文件用來(lái)生成 Stub 接口文件,用來(lái)聲明在 Server 提供的接口。
        
SystemServer:創(chuàng)建 Server 實(shí)例,加入服務(wù)表中,供 APP 獲取使用。


接口:
        聲明一些數(shù)據(jù)結(jié)構(gòu)、獲取 Server 根據(jù)需要決定是否再進(jìn)一步封裝接口。
        其主要的目的是為了APP能夠更加方便的使用接口。
        
APP:
        通過(guò)接口文件,來(lái)調(diào)用相關(guān)的接口從而間接調(diào)用底層驅(qū)動(dòng)功能。


調(diào)用流程:APP 通過(guò)獲取AIDL通信,獲取服務(wù),通過(guò)服務(wù)調(diào)用服務(wù)的提供的類,調(diào)用JNI接口、JNI再去調(diào)用驅(qū)動(dòng)。
        
具體例子:


/////////////////////////////////////////////////////////////////////////////////////////////
驅(qū)動(dòng):lichee/linux-3.4/drivers/my_drivers/pt22xx.c
        會(huì)創(chuàng)建一個(gè)設(shè)備節(jié)點(diǎn):/dev/MicAdjust 用于給上層交互
/////////////////////////////////////////////////////////////////////////////////////////////
        long Pt22xx_ioctl(struct file *file, unsigned int cmd, unsigned long args)
        {
                unsigned char ret = 0;
               
                if (_IOC_TYPE(cmd) != MAGIC)
                        return -EINVAL;


                switch(cmd)
                {
                        case CMD_SETMICVOL:                                        dprintk("CMD_SETMICVOL....");
                                g_CurrentMicVolume = args;
                                // 與底層硬件進(jìn)行交互
                                break;
                                
                        case CMD_SETMICECHO:                                dprintk("CMD_SETMICECHO....");
                                g_CurrentMicEcho = args;
                                // 與底層硬件進(jìn)行交互
                                break;


                        case CMD_GETMICVOL:                                dprintk("CMD_GETMICECHO....");
                                ret = g_CurrentMicVolume;
                                break;
                                
                        case CMD_GETMICECHO:                                dprintk("CMD_GETMICECHO....");
                                ret = g_CurrentMicEcho;
                                break;
                                
                        default:                                                        dprintk("no cmd....");
                                return -EINVAL;
                }
               
                return ret;
        }




        static struct file_operations Pt22xx_fops = {
                .owner                            =    THIS_MODULE,
                .unlocked_ioctl            =    Pt22xx_ioctl,
        };


        static struct miscdevice Pt22xx_misc =
        {
                .minor = MISC_DYNAMIC_MINOR,
                .name = "MicAdjust",
                .fops = &Pt22xx_fops,
        };


        /*************************** 驅(qū)動(dòng)入口 驅(qū)動(dòng)出口 ***************************/
         static int __init Pt22xx_init(void)
        {
                misc_register(&Pt22xx_misc);
                return 0;
        }


        static void __exit Pt22xx_exit(void)
        {


        }
        /*************************** 驅(qū)動(dòng)入口 驅(qū)動(dòng)出口 ***************************/


        module_init(Pt22xx_init);
        module_exit(Pt22xx_exit);
        MODULE_LICENSE("GPL");
/////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////
Jni:android/frameworks/base/services/jni/my_jni/Mic.cpp
        會(huì)創(chuàng)建一個(gè)設(shè)備節(jié)點(diǎn):/dev/MicAdjust 用于給上層交互
/////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
        對(duì)應(yīng)驅(qū)動(dòng)的JNI文件
//-------------------------------------------------------------------------------------


// 功放命令實(shí)現(xiàn)
jint Mic_Cmd(JNIEnv *env, jobject thiz,  jint cmd, jint arg1)
{
        int ret = 0;
        // 這里則通過(guò)識(shí)別命令和參數(shù) 通過(guò) ioctl 函數(shù)設(shè)置驅(qū)動(dòng)
        // 這里應(yīng)用層 ioctl() 實(shí)際上回調(diào)的是驅(qū)動(dòng)層 -> Pt22xx_ioctl() 函數(shù)
        return ret;
}


// 初始化函數(shù),需要識(shí)別并初始化硬件設(shè)備
jint Mic_Init(JNIEnv *env, jobject thiz)
{
        // 初始化硬件
        // 這里會(huì) open /dev/MicAdjust  設(shè)備節(jié)點(diǎn)
        return 0;
}


//-------------------------------------------------------------------------------------
        管理和協(xié)調(diào)各個(gè)JNI程序,實(shí)現(xiàn)一些基本的邏輯功能,例如參數(shù)保存之類的。。
        android/frameworks/base/services/jni/com_android_server_HardwareConfig.cpp
//-------------------------------------------------------------------------------------
namespace android {
        /* 一些數(shù)據(jù)結(jié)構(gòu) */
        
        ///////////////////////////// AMP 邏輯實(shí)現(xiàn) ////////////////////////////////////////
        /* 處理獲取命令 */
        jint HardwareConfig_GetAmp(enum enAmp_CMDTYPE cmd)
        {
                int ret;        
                switch(cmd)
                {


                        default:
                                return eAMP_CMD_ERROR;
                }
               
                return ret;
        }
        
        // 功放命令實(shí)現(xiàn)
        jint HardwareConfig_AmpCmd(JNIEnv *env, jobject thiz,  jint cmd, jint arg1)
        {
                int ret = 0;


                // 非法參數(shù)檢查
               
                // 判斷是否為獲取命令
                if( IsAmpGetCmdType(cmd) )
                {
                        return HardwareConfig_GetAmp((enum enAmp_CMDTYPE)cmd);
                }
               
                // 參數(shù)檢查并糾正


                // 調(diào)用相應(yīng)的功能函數(shù)
                ret = Amp_Cmd((enAmp_CMDTYPE)cmd, (enAmp_ARGSTYPE)arg1);
               
                /* 保存相關(guān)參數(shù) */
                return ret;
        }
        
        ///////////////////////////// MIC 邏輯實(shí)現(xiàn) ////////////////////////////////////////
        jint HardwareConfig_GetMic(enum enMic_CMDTYPE cmd)
        {
                int ret;


                switch((int)cmd)
                {
                        default:
                                return eMIC_CMD_ERROR;
                }
               
                return ret;        
        }
        
        
        jint HardwareConfig_MicCmd(JNIEnv *env, jobject thiz,  jint cmd, jint arg1)
        {
                int ret = 0;
               
                // 非法參數(shù)檢查
               
                // 判斷是否為獲取命令
                if( IsAmpGetCmdType(cmd) )
                {
                        return HardwareConfig_GetAmp((enum enAmp_CMDTYPE)cmd);
                }
               
                // 參數(shù)檢查并糾正


                // 調(diào)用相應(yīng)的功能函數(shù)
                ret = Amp_Cmd((enAmp_CMDTYPE)cmd, (enAmp_ARGSTYPE)arg1);
               
                /* 保存相關(guān)參數(shù) */
                return ret;
        }
        
        ///////////////////////////// 以上為邏輯功能實(shí)現(xiàn) ////////////////////////////////////////
        
        
        // 初始化函數(shù),需要識(shí)別并初始化硬件設(shè)備 這里對(duì)硬件初始化主要是調(diào)用各自的JNI接口初始化的
        jint HardwareConfig_Init(JNIEnv *env, jobject thiz)
        {
                // 讀取配置文件
               
                /* 功放初始化 */
                Amp_Init();
                Amp_Cmd(...);        
                Amp_Cmd(...);        
                Amp_Cmd(...);
               
                /* 初始化麥克風(fēng) */               
                Mic_Init();
                Mic_Cmd(...);
                Mic_Cmd(...);
               
                /* 初始化其他硬件 */
                return 0;
        }


        ///////////////////////////// JNI ////////////////////////////////////////
        // 構(gòu)建映射表
        static JNINativeMethod method_table[] ={
                {"HardwareConfig_Init_native",             "()I",      (void *)HardwareConfig_Init},
                {"Amp_Cmd_native",                 "(II)I",   (void *)HardwareConfig_AmpCmd},
                {"Mic_Cmd_native",                 "(II)I",   (void *)HardwareConfig_MicCmd},
                //.... 其他硬件
        };
        
        int register_android_server_HardwareConfigService(JNIEnv* env)
        {
                return jniRegisterNativeMethods(env,"com/android/server/HardwareConfigService", method_table, NELEM(method_table));
        }
}
//-------------------------------------------------------------------------------------
        修改 onload.cpp 文件,該文件是用來(lái)集中加載所有Jni。
        android\frameworks\base\services\jni\onload.cpp
//-------------------------------------------------------------------------------------
#include "JNIHelp.h"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"


namespace android {
//... 省略
int register_android_server_HardwareConfigService(JNIEnv* env);
};


using namespace android;


extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
        //... 省略
        register_android_server_HardwareConfigService(env);
        
    return JNI_VERSION_1_4;
}


//-------------------------------------------------------------------------------------
        修改 對(duì)應(yīng)目錄下的 Android.mk 文件,該文件是用來(lái)編譯這些Jni文件的
        android\frameworks\base\services\jni\Android.mk
//-------------------------------------------------------------------------------------
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)


LOCAL_SRC_FILES:= \
    // ... 省略
        zhc_jni/Mic.cpp \
        com_android_server_HardwareConfig.cpp \
    onload.cpp


LOCAL_C_INCLUDES += \
        // ... 省略
        my_jni


ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
    LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
endif


LOCAL_MODULE:= libandroid_servers


include $(BUILD_SHARED_LIBRARY)


/*************** 完成以上步驟就可以在當(dāng)前目錄下通過(guò) mm 命令編譯出 JNI SO庫(kù)文件了 ***********/
/////////////////////////////////////////////////////////////////////////////////////////////
Server:
        在 android\frameworks\base\services\java\com\android\server 建立一個(gè)文件 HardwareConfigService.java
/////////////////////////////////////////////////////////////////////////////////////////////
package com.android.server;


import android.content.Context;
import android.util.Slog;
import android.content.Context;


public class HardwareConfigService extends IHardwareConfigService.Stub {


    private static final String TAG = "HardwareConfigService";
        private static native int HardwareConfig_Init_native();
        private static native int Amp_Cmd_native(int cmd, int arg1);
        private static native int Mic_Cmd_native(int cmd, int arg1);
        private static Context mContext;


        /////////////////////////////////////  初始化處理部分 ////////////////////////////////
        // 當(dāng)這個(gè)類被創(chuàng)建時(shí),以下代碼將會(huì)被執(zhí)行
    public HardwareConfigService(Context context)
    {
                mContext = context;
        HardwareConfig_Init_native();        // <---- 這里調(diào)用 JNI 部分接口 進(jìn)行初始化
    }
        
        ///////////////////////////////////// 接口定義部分 ////////////////////////////////
        public int Amp_Cmd(int Cmd, int arg1)                // <<---- 對(duì)外提供的調(diào)用的接口
        {
                int ret = 0;
                // 在這里可以對(duì)接口做進(jìn)一步封裝
                ret = Amp_Cmd_native(Cmd, arg1);                // <---- 這里調(diào)用 JNI 部分接口
                return ret;
        }


        public int Mic_Cmd(int Cmd, int arg1)                // <<---- 對(duì)外提供的調(diào)用的接口
        {
                int ret = 0;
                // 在這里可以對(duì)接口做進(jìn)一步封裝
                ret = Mic_Cmd_native(Cmd, arg1);                // <---- 這里調(diào)用 JNI 部分接口
                return ret;
        }
        
};


//-------------------------------------------------------------------------------------
        修改同目錄下的SystemServer.java文件,在ServerThread::run方法里加入
//-------------------------------------------------------------------------------------
class ServerThread extends Thread {
    private static final String TAG = "SystemServer";
    private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
        // ... 省略代碼
    @Override
    public void run() {

                try{        // 在這里 new 了一個(gè)對(duì)象并添加到 ServiceManager 中。
                        Slog.i(TAG, "add HardwareConfigService");
                        ServiceManager.addService("HardwareConfigService", new HardwareConfigService(context));
                } catch (RuntimeException e) {
                        Slog.e("System", "******************************************");
                        Slog.e("System", "************ Failure starting HardwareConfigService", e);
                }
        // ... 省略代碼
    }
}


public class SystemServer {
    private static final String TAG = "SystemServer";
        
        // ... 省略代碼
    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }
}


/*************** 完成以上步驟就可以在 android\frameworks\base\services\java 下通過(guò) mm 命令編譯了 ***********/


/////////////////////////////////////////////////////////////////////////////////////////////
AIAL:在 frameworks/base/core/java/android/os/ 新建立一個(gè)文件 IHardwareConfigService.aidl
/////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------
        加入以下內(nèi)容,以下內(nèi)容為 服務(wù)里面的public接口,即提供給APP使用的接口
//-------------------------------------------------------------------------------------
package android.os;
interface IHardwareConfigService
{
        int Amp_Cmd(int Cmd, int arg1);
        int Mic_Cmd(int Cmd, int arg1);
}
//-------------------------------------------------------------------------------------
        返回到 frameworks/base 修改 Android.mk 文件
//-------------------------------------------------------------------------------------
LOCAL_SRC_FILES += \
        core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
        ## 省略
        core/java/android/os/IHardwareConfigService.aidl \ ## 增加這一行代碼
# Include subdirectory makefiles




/////////////////////////////////////////////////////////////////////////////////////////////
接口文件:這個(gè)接口文件主要是進(jìn)一步封裝接口,把一些命令標(biāo)識(shí)什么的都放到問(wèn)個(gè)文件里面
        在 android\frameworks\base\policy\src\com\android\internal\policy\impl
        新建立一個(gè)文件 HardwareConfigServiceInterface.java
/////////////////////////////////////////////////////////////////////////////////////////////
package com.android.internal.policy.impl;


import android.os.IHardwareConfigService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;


public class HardwareConfigServiceInterface {
        
        private IHardwareConfigService HardwareConfigService = null;
        static final String TAG = "HardwareConfigServiceInterface";
        
        ///////////////////////// 功放命令與參數(shù)定義 ////////////////////////////        
        public enum enAmp_CMDTYPE                  
        {   
                // 設(shè)置命令
                eAMP_CMD_OPEN,                                                // 打開(kāi)
                eAMP_CMD_CLOSE,                                                // 關(guān)閉
                eAMP_CMD_SETMUTE,                                        // 靜音
                eAMP_CMD_SETVOLUME,                                        // 設(shè)置音量
                eAMP_CMD_SETEQ,                                                // 設(shè)置音效
                eAMP_CMD_SETSIGLEEND,                                // 設(shè)置立體聲
                eAMP_CMD_SETSURROUND,                                // 設(shè)置環(huán)繞
                eAMP_CMD_SETTREBLEBASS_CTRL,                // 高低音控制        
                eAMP_CMD_SETTREBLE,                                        // 設(shè)置高音
                eAMP_CMD_SETBASS,                                        // 設(shè)置低音
                // .........
                eAMP_CMD_ERROR,                                                // 命令執(zhí)行錯(cuò)誤或失敗,同時(shí)也是命令的個(gè)數(shù)
        };
        ///////////////////////// 功放接口 ////////////////////////////        
        
        /* 獲取某些命令是已經(jīng)使能了還是關(guān)閉了 設(shè)計(jì)此接口是為了應(yīng)用層更加方便的判斷 出錯(cuò)返回 eAMP_ARGS_NOT_USER*/
        public enAmp_ARGSTYPE Amp_GetCmd(enAmp_CMDTYPE Cmd)
        {
                int index = 0;
                // 省略轉(zhuǎn)換代碼
                index = Amp_Cmd(Cmd, enAmp_ARGSTYPE.eAMP_ARGS_NOT_USER.ordinal());
                // 省略轉(zhuǎn)換代碼
                return enAmp_ARGSTYPE.eAMP_ARGS_NOT_USER;        
        }


        /* 獲取具體的值 例如 高低音的值 出錯(cuò)返回 -1 */
        public int Amp_GetData(enAmp_CMDTYPE Cmd)
        {
                int ret = Amp_Cmd(Cmd, enAmp_ARGSTYPE.eAMP_ARGS_NOT_USER.ordinal());
                // 省略轉(zhuǎn)換代碼
                return ret;
        }
        
        public enAmp_CMDTYPE Amp_SetCmd(enAmp_CMDTYPE Cmd, enAmp_ARGSTYPE Args)
        {        
                int index = 0;
                // 省略轉(zhuǎn)換代碼
                index = Amp_Cmd(Cmd, Args.ordinal());
                // 省略轉(zhuǎn)換代碼
                return enAmp_CMDTYPE.eAMP_CMD_ERROR;
        }
        
        public int Amp_SetData(enAmp_CMDTYPE Cmd, int Args)
        {        
                Log.d(TAG, "Amp_SetData() Cmd = " + Cmd + "Args = " + Args );
                return  Amp_Cmd(Cmd, Args);
        }
        
        /* 最終的實(shí)現(xiàn)是由此命令完成的 設(shè)置命令時(shí)出錯(cuò)返回 eAMP_CMD_ERROR 的索引*/
        private int Amp_Cmd(enAmp_CMDTYPE Cmd, int Args)
        {
                Log.d(TAG, "Amp_SetCmd() Cmd = " + Cmd + " ordinal = " + Cmd.ordinal());
                Log.d(TAG, "Amp_SetCmd() Args = " + Args);
                try
                {
                        if(null == HardwareConfigService)
                        {
                                HardwareConfigService = IHardwareConfigService.Stub.asInterface(ServiceManager.getService("HardwareConfigService"));
                        }
                        
                        return HardwareConfigService.Amp_Cmd(Cmd.ordinal(), Args);
                        
                } catch (RemoteException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return (int)(enAmp_CMDTYPE.eAMP_CMD_ERROR.ordinal());
                }
               
        }
        
        ///////////////////////// 麥克風(fēng)接口與定義 ////////////////////////////        
        
        /* 功放命令集,具體命令需由具體的功放芯片驅(qū)動(dòng)實(shí)現(xiàn) */
        public enum enMic_CMDTYPE                  
        {   
                // 設(shè)置命令
                eMIC_CMD_START        ,                                // 起始
                eMIC_CMD_SETVOLUME,                                        // 設(shè)置MIC音量
                eMIC_CMD_SETECHO,                                        // 設(shè)置MIC回響
                eMIC_CMD_SETMUTE,                                        // 麥克風(fēng)靜音
               
                // 獲取命令
                eMIC_CMD_GETTYPE_START,                                // 獲取命令類型 用于做標(biāo)識(shí) 當(dāng)大于此值時(shí)表示是獲取命令類型
                eMIC_CMD_GETVOLUME,                                        // 獲取MIC音量值
                eMIC_CMD_GETECHO,                                        // 獲取MIC回響值
                eMIC_CMD_GETMUTE,
                eMIC_CMD_GETTYPE_STOP,                                // eMic_CMD_GETTYPE_START 與 eMic_CMD_GETTYPE_STOP 之間是獲取命令的類型
               
                eMIC_CMD_ERROR,                                                // 命令執(zhí)行錯(cuò)誤或失敗,同時(shí)也是命令的個(gè)數(shù)
        };


        public enum enMic_ARGSTYPE                                                // 參數(shù)
        {
                eMIC_ARGS_DISABLE ,
                eMIC_ARGS_ENABLE,
               
                eMIC_ARGS_NOT_USER,                                        // 不使用
        };
        ///////////////////////// 麥克風(fēng)接口實(shí)現(xiàn) ////////////////////////////
                /* 獲取某些命令是已經(jīng)使能了還是關(guān)閉了 設(shè)計(jì)此接口是為了應(yīng)用層更加方便的判斷 出錯(cuò)返回 eMIC_ARGS_NOT_USER*/
        public enMic_ARGSTYPE Mic_GetCmd(enMic_CMDTYPE Cmd)
        {
                int index = 0;
                // 省略轉(zhuǎn)換代碼
                index = Mic_Cmd(Cmd, enMic_ARGSTYPE.eMIC_ARGS_NOT_USER.ordinal());
                // 省略轉(zhuǎn)換代碼
                return enMic_ARGSTYPE.eMIC_ARGS_NOT_USER;        
        }


        /* 獲取具體的值 出錯(cuò)返回 -1 */
        public int Mic_GetData(enMic_CMDTYPE Cmd)
        {
                int ret = Mic_Cmd(Cmd, enMic_ARGSTYPE.eMIC_ARGS_NOT_USER.ordinal());
                // 省略轉(zhuǎn)換代碼
                return ret;
        }
        
        public enMic_CMDTYPE Mic_SetCmd(enMic_CMDTYPE Cmd, enMic_ARGSTYPE Args)
        {        
                int index = 0;
                // 省略轉(zhuǎn)換代碼
                index = Mic_Cmd(Cmd, Args.ordinal());
                // 省略轉(zhuǎn)換代碼
                return enMic_CMDTYPE.eMIC_CMD_ERROR;
        }
        
        public int Mic_SetData(enMic_CMDTYPE Cmd, int Args)
        {        
                // 省略轉(zhuǎn)換代碼
                return  Mic_Cmd(Cmd, Args);
        }
        
        /* 最終的實(shí)現(xiàn)是由此命令完成的 設(shè)置命令時(shí)出錯(cuò)返回 eMIC_CMD_ERROR 的索引*/
        private int Mic_Cmd(enMic_CMDTYPE Cmd, int Args)
        {
                Log.d(TAG, "Mic_SetCmd() Cmd = " + Cmd + " ordinal = " + Cmd.ordinal());
                Log.d(TAG, "Mic_SetCmd() Args = " + Args);
                try
                {
                        if(null == HardwareConfigService)
                        {
                                HardwareConfigService = IHardwareConfigService.Stub.asInterface(ServiceManager.getService("HardwareConfigService"));
                        }
                        
                        return HardwareConfigService.Mic_Cmd(Cmd.ordinal(), Args);
                        
                } catch (RemoteException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return (int)(enMic_CMDTYPE.eMIC_CMD_ERROR.ordinal());
                }
               
        }


}


/*****************************************************************************
        昨晚以上的操作之后需要 make updata-api 建議全編一次
*****************************************************************************/


/////////////////////////////////////////////////////////////////////////////////////////////
應(yīng)用層使用方法:
/////////////////////////////////////////////////////////////////////////////////////////////
1、需要在 Android 工程中加上 android\out\target\common\obj\JAVA_LIBRARIES\android.policy_intermediates\classes.jar


2、導(dǎo)入需要的數(shù)據(jù)結(jié)構(gòu)
import com.android.internal.policy.impl.HardwareConfigServiceInterface;
import com.android.internal.policy.impl.HardwareConfigServiceInterface.enAmp_CMDTYPE;
import com.android.internal.policy.impl.HardwareConfigServiceInterface.enAmp_ARGSTYPE;
import com.android.internal.policy.impl.HardwareConfigServiceInterface.enMic_CMDTYPE;
import com.android.internal.policy.impl.HardwareConfigServiceInterface.enMic_ARGSTYPE;
import com.android.internal.policy.impl.HardwareConfigServiceInterface.enDevices_Status;


3、定義全局變量
        static private HardwareConfigServiceInterface HardwareConfig = null;
4、在初始化函數(shù)中new 對(duì)象
        HardwareConfig = new HardwareConfigServiceInterface();


5、在需要的地方直接調(diào)用接口
        HardwareConfig.Amp_GetCmd(enAmp_CMDTYPE.eAMP_CMD_GETSDMUTE)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:93145 發(fā)表于 2015-10-21 18:34 | 只看該作者
謝謝~
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表