驱动的同事在声卡的驱动层上做了一个功能, 需要提供一个接口开放给上层调用.
每一步都有系统原来的代码作为参考, 添加起来也不算太难, 但是就是太麻烦了, 所以记录一下
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