欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android8.1 为AudioManager AudioService 添加底层JNI接口

程序员文章站 2022-05-11 15:53:52
...

驱动的同事在声卡的驱动层上做了一个功能, 需要提供一个接口开放给上层调用. 

每一步都有系统原来的代码作为参考, 添加起来也不算太难, 但是就是太麻烦了, 所以记录一下

1驱动:  android\hardware\libhardware\include\hardware\audio.h 的audio_hw_device 结构体添加声明:

    /* mic mute */
    int (*set_mic_mute)(struct audio_hw_device *dev, bool state);
    int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state);
    //lwt
    int (*set_vibrator_mode)(struct audio_hw_device *dev, bool state);
    int (*get_vibrator_mode)(const struct audio_hw_device *dev, bool* state);

2. android\hardware\aw\audio\audio_hw.c 中添加实现:

static int adev_set_vibrator_mode(struct audio_hw_device *dev, bool state)
{
    ALOGD("%s: state %d\n", __func__, state);
    struct sunxi_audio_device *adev = (struct sunxi_audio_device *)dev;
    //....具体功能略
    return 0;
}

static int adev_get_vibrator_mode(const struct audio_hw_device *dev, bool *state)
{
    struct sunxi_audio_device *adev = (struct sunxi_audio_device*)dev;
    //...具体功能略
    ALOGD("adev_get_vibrator_mode, ret:%d", state);
    return 0;
}

并且在static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device)函数中添加赋值

    adev->device.set_vibrator_mode = adev_set_vibrator_mode;
    adev->device.get_vibrator_mode = adev_get_vibrator_mode;

3. \android\frameworks\av\services\audioflinger\AudioFlinger.h 中添加声明:

    //lwt
    virtual     status_t    setVibratorMode(bool state);
    virtual     bool        getVibratorMode() const;

android\frameworks\av\services\audioflinger\AudioFlinger.cpp 实现:

//lwt added
status_t AudioFlinger::setVibratorMode(bool state)
{
    status_t ret = initCheck();
    status_t result = NO_ERROR;
	ALOGD("AudioFlinger.cpp, setVibratorMode:%d", state);

    
    if (ret != NO_ERROR) {
        return ret;
    }

    // check calling permissions
    if (!settingsAllowed()) {
        return PERMISSION_DENIED;
    }

	
    AutoMutex lock(mHardwareLock);
    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();


        if(dev != 0 && dev->set_vibrator_mode != 0)
        {
        	result = dev->set_vibrator_mode(dev, state);
	        if (result != NO_ERROR) {
	            ret = result;
	        }
        }
    }
    mHardwareStatus = AUDIO_HW_IDLE;
    return ret;
}

bool AudioFlinger::getVibratorMode() const
{
    status_t ret = initCheck();
    if (ret != NO_ERROR) {
        return false;
    }
    bool vibStat = true;
    AutoMutex lock(mHardwareLock);
    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
        audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
        if(dev != 0 && dev->set_vibrator_mode != 0){
        	dev->get_vibrator_mode(dev, &vibStat);
       	}
    }
    ALOGD("AudioFlinger.cpp, getVibratorMode ret:%d", vibStat);

    return vibStat;
}
//lwt added end

4. android\frameworks\av\include\media\IAudioFlinger.h 

    //lwt added
    virtual     status_t    setVibratorMode(bool state) = 0;
    virtual     bool        getVibratorMode() const = 0;

android\frameworks\av\media\libmedia\IAudioFlinger.cpp : 有三处修改:

1) 代码enum {
    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,处, 添加枚举:

    //lwt added
    SET_VIB_MODE,
    GET_VIB_MODE,
    //lwt added end

2) 类中实现:

virtual status_t setVibratorMode(bool state)
    {//lwt added
        Parcel data, reply;
        ALOGD("IAudioFlinger.cpp setVibratorMode");
        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
        data.writeInt32(state);
        remote()->transact(SET_VIB_MODE, data, &reply);

        
        return reply.readInt32();
    }

    virtual bool getVibratorMode() const
    {//lwt added
        Parcel data, reply;
        ALOGD("IAudioFlinger.cpp getVibratorMode");
        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
        remote()->transact(GET_VIB_MODE, data, &reply);
        return reply.readInt32();
    }

3) status_t BnAudioFlinger::onTransact 函数中添加消息处理:
 

        case SET_VIB_MODE: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            int state = data.readInt32();
            reply->writeInt32( setVibratorMode(state) );
            return NO_ERROR;
        } break;
        case GET_VIB_MODE: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            reply->writeInt32( getVibratorMode() );
            return NO_ERROR;
        } break;

5. \android\frameworks\av\include\media\AudioSystem.h 

    //lwt added 
    static status_t asSetVibratorMode(bool state);
    static status_t asIsVibratorMode(bool *state);

\android\frameworks\av\media\libmedia\AudioSystem.cpp 

//lwt added
status_t AudioSystem::asSetVibratorMode(bool state)
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
	ALOGD("AudioSystem.cpp::asSetVibratorMode");

    return af->setVibratorMode(state);
}

status_t AudioSystem::asIsVibratorMode(bool* state)
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
	ALOGD("AudioSystem.cpp::asIsVibratorMode");
    *state = af->getVibratorMode();
    return NO_ERROR;
}
//lwt added end

6.\android\frameworks\base\core\jni\android_media_AudioSystem.cpp:

//lwt added
static jint
android_media_AudioSystem_asSetVibratorMode(JNIEnv *env, jobject thiz, jboolean on)
{
    return (jint) check_AudioSystem_Command(AudioSystem::asSetVibratorMode(on));
}

static jboolean
android_media_AudioSystem_asIsVibratorMode(JNIEnv *env, jobject thiz)
{
    bool state = false;
    AudioSystem::asIsVibratorMode(&state);
    return state;
}
//lwt added end

static const JNINativeMethod gMethods[] 数组中添加:

	//lwt added    
	{"asSetVibratorMode",	"(Z)I",	    (void *)android_media_AudioSystem_asSetVibratorMode},
	{"asIsVibratorMode",    "()Z",	    (void *)android_media_AudioSystem_asIsVibratorMode},
	//lwt added end

7.android\frameworks\base\media\java\android\media\AudioSystem.java:


    //lwt added
    public static native int asSetVibratorMode(boolean on);
    public static native boolean asIsVibratorMode();
    //lwt added end

8.\android\frameworks\base\services\core\java\com\android\server\audio\AudioService.java

//lwt added
    public void AsSetVibratorMode(boolean on) {
        Log.d(TAG, String.format("AudioService.java AsSetVibratorMode val: %s", on));
        AudioSystem.asSetVibratorMode(on);
    }
    
    public boolean AsGetVibratorMode() {
        boolean ret = AudioSystem.asIsVibratorMode();
        Log.d(TAG, String.format("AudioService.java AsgetVibratorMode ret: %s", ret));

        return ret;
    }
    //lwt added end

9.android\frameworks\base\media\java\android\media\IAudioService.aidl

    //lwt added
    void AsSetVibratorMode(boolean on) ;
    boolean AsGetVibratorMode();
    //lwt added end

10. \android\frameworks\base\media\java\android\media\AudioManager.java

//lwt added
    public void AmSetVibratorMode(boolean on) {
        IAudioService service = getService();
        try {
            
            Log.d(TAG, "AmSetVibratorMode:"+on);
            service.AsSetVibratorMode(on);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }


    public boolean AmGetVibratorMode() {
        IAudioService service = getService();
        boolean ret = false;
        try {
            ret = service.AsGetVibratorMode();
            Log.d(TAG, "AmGetVibratorMode ret:"+ret);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return ret;
    }
    //lwt added end

11. 至此, 整个从上到下的通道就打通了.  使用:

                    AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);;
                    mAudioManager.AmSetVibratorMode(true);

                    boolean ret = mAudioManager.AmGetVibratorMode();

12. 注意的地方: 因为修改了AudioManager 的对外接口, 所以需要在android 目录下执行  make update-api 命令, 来更新/frameworks/base/api/下面三个文件:

            current.txt            system-current.txt         test-current.txt