android6.0监听u盘,[RK3288][Android6.0] 有线耳机插拔事件监听小结

Platform: Rockchip

OS: Android 6.0

Kernel: 3.10.92

WiredAccessoryObserver用来处理kernel通知耳机插拔事件,不够它只监听有线音频外设连接,其他无线的耳机在其他模块维护。

WiredAccessoryObserver继承自UEventObserver, UEventObserver用于接收Uevent的一个类,内部维护一个线程,用于接收UEvent事件,通过调用它的StartObserving()来告诉UEventObserver要监听什么样的UEvent,当事件到来的时候会调用对应的onUEvent()来处理。

初始化一:

WiredAccessoryObserver接收audio jack/hdmi audio/usb audio这三个事件.

每种外设会被定义成一个UEventInfo用于保存它的状态。

WiredAccessoryManager.java:

private List makeObservedUEventList() {

List retVal = new ArrayList();

UEventInfo uei;

//audio jack事件注册

// Monitor h2w

if (!mUseDevInputEventForAudioJack) {

uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC, BIT_LINEOUT);

if (uei.checkSwitchExists()) {

retVal.add(uei);

} else {

Slog.w(TAG, "This kernel does not have wired headset support");

}

}

//usb audio事件注册

// Monitor USB

uei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL, 0);

if (uei.checkSwitchExists()) {

retVal.add(uei);

} else {

Slog.w(TAG, "This kernel does not have usb audio support");

}

//HDMI audio事件注册

// Monitor HDMI

uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0, 0);

if (uei.checkSwitchExists()) {

retVal.add(uei);

} else {

uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0, 0);

if (uei.checkSwitchExists()) {

retVal.add(uei);

} else {

Slog.w(TAG, "This kernel does not have HDMI audio support");

}

}

return retVal;

}

初始化二:

对前面的外设进行状态初始化。

WiredAccessoryManager.java:

void init() {

synchronized (mLock) {

for (int i = 0; i < mUEventInfo.size(); ++i) {

UEventInfo uei = mUEventInfo.get(i);

try {

int curState;

//打开状态文件, mDevName在之前注册的时候有赋值。

//public String getSwitchStatePath() {

// return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);

//}

//假设这里是jack audio,那么路径就是 “/sys/class/switch/h2w/state”

FileReader file = new FileReader(uei.getSwitchStatePath());

int len = file.read(buffer, 0, 1024);

file.close();

//如果当前值为非0,表示默认开机的时候就有耳机插入。

curState = Integer.valueOf((new String(buffer, 0, len)).trim());

//有设备插入就要做处理,这里假设开机没有设备插入,后面事件处理再展开。

if (curState > 0) {

updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);

}

}

}

}

for (int i = 0; i < mUEventInfo.size(); ++i) {

UEventInfo uei = mUEventInfo.get(i);

//注册到UEventObserver中监听对应事件。

startObserving("DEVPATH="+uei.getDevPath());

}

}

getDevPath():

public String getDevPath() {

return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);

}

耳机对应路径:

0818b9ca8b590ca3270a3433284dd417.png

耳机插拔处理:

事件处理会触发onUEvent()调用。

public void onUEvent(UEventObserver.UEvent event) {

try {

//DEVPATH: /sys/devices/virtual/switch/h2w

String devPath = event.get("DEVPATH");

//SWITCH_NAME: 其实就是mUEventInfo中的mDevName,即“h2w”

String name = event.get("SWITCH_NAME");

//SWITCH_STATE:插入为1,拔出为0

int state = Integer.parseInt(event.get("SWITCH_STATE"));

synchronized (mLock) {

//更新状态

updateStateLocked(devPath, name, state);

}

}

}

updateStateLocked():

private void updateStateLocked(String devPath, String name, int state) {

for (int i = 0; i < mUEventInfo.size(); ++i) {

UEventInfo uei = mUEventInfo.get(i);

//找到对应发生状态变化的外设

if (devPath.equals(uei.getDevPath())) {

//获取/sys/devices/virtual/switch/h2w下的state值

updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));

return;

}

}

}

updateLocked()对传入的state进行检查

private void updateLocked(String newName, int newState) {

// Retain only relevant bits

//SUPPORTED_HEADSETS可以控制当前系统支持的音频外设,比如不想支持hdmi audio,

//就将SUPPORTED_HEADSETS中的BIT_HDMI_AUDIO位拿掉就可以了。

int headsetState = newState & SUPPORTED_HEADSETS;

int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;

int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;

int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);

boolean h2wStateChange = true;

//状态和上次一样没变化就不处理了。

if (mHeadsetState == headsetState) {

Log.e(TAG, "No state change.");

return;

}

//发送消息事件待处理

Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,

mHeadsetState, "");

mHandler.sendMessage(msg);

//保存当前状态

mHeadsetState = headsetState;

}

handleMessage -> setDevicesState -> setDeviceStateLocked

private void setDeviceStateLocked(int headset, int headsetState, int prevHeadsetState, String headsetName) {

//转换成audio模块的的外设编号

if (headset == BIT_HEADSET) {

outDevice = AudioManager.DEVICE_OUT_WIRED_HEADSET;

inDevice = AudioManager.DEVICE_IN_WIRED_HEADSET;

} else if (headset == BIT_HEADSET_NO_MIC){

outDevice = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;

} else if (headset == BIT_LINEOUT){

outDevice = AudioManager.DEVICE_OUT_LINE;

}

//通知audioservice处理设置到audio device

mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);

}

参考:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值