Android 蓝牙AVRCP功能的实现.docx
- 文档编号:30006391
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:11
- 大小:24.86KB
Android 蓝牙AVRCP功能的实现.docx
《Android 蓝牙AVRCP功能的实现.docx》由会员分享,可在线阅读,更多相关《Android 蓝牙AVRCP功能的实现.docx(11页珍藏版)》请在冰豆网上搜索。
Android蓝牙AVRCP功能的实现
Android蓝牙AVRCP功能的实现
作者:
MacroLiu
AVRCP的按键定义:
\sdk\emulator\keymaps\AVRCP.kl
key200MEDIA_PLAY_PAUSEWAKE
key201MEDIA_PLAY_PAUSEWAKE
key166MEDIA_STOPWAKE
key163MEDIA_NEXTWAKE
key165MEDIA_PREVIOUSWAKE
key168MEDIA_REWINDWAKE
key208MEDIA_FAST_FORWARDWAKE
BCM(broadcom)宏定义需要打开:
BOARD_HAVE_BLUETOOTH_BCM:
=true
BT音频控制的代码
external\bluetooth\bluez\audio\control.c
(1)按键的MAP
staticstruct{
constchar*name;
uint8_tavrcp;
uint16_tuinput;
}key_map[]={
{"PLAY",PLAY_OP,KEY_PLAYCD},
{"STOP",STOP_OP,KEY_STOPCD},
{"PAUSE",PAUSE_OP,KEY_PAUSECD},
{"FORWARD",FORWARD_OP,KEY_NEXTSONG},
{"BACKWARD",BACKWARD_OP,KEY_PREVIOUSSONG},
{"REWIND",REWIND_OP,KEY_REWIND},
{"FASTFORWARD",FAST_FORWARD_OP,KEY_FASTFORWARD},
{NULL}
};
(2)按键处理
staticvoidhandle_panel_passthrough(structcontrol*control,
{
…
for(i=0;key_map[i].name!
=NULL;i++){
uint8_tkey_quirks;
if((operands[0]&0x7F)!
=key_map[i].avrcp)
continue;
DBG("AVRCP:
%s%s",key_map[i].name,status);
key_quirks=control->key_quirks[key_map[i].avrcp];
if(key_quirks&QUIRK_NO_RELEASE){
if(!
pressed){
DBG("AVRCP:
Ignoringrelease");
break;
}
DBG("AVRCP:
treatingkeypressaspress+release");
send_key(control->uinput,key_map[i].uinput,1);
send_key(control->uinput,key_map[i].uinput,0);
break;
}
send_key(control->uinput,key_map[i].uinput,pressed);
break;
}
…
}
HCIDUMP数据分析
以Sony耳机DRC-BT15为例
#adbshell
#hcidump–X
左键:
>ACLdata:
handle12flags0x02dlen12
L2CAP(d):
cid0x0042len8[psm0]
0000:
30110e00487c4c000...H|L.
ExitSniffMode(0x02|0x0004)plen2 0000: 0c00.. handle12flags0x00dlen12 0000: 08004b0032110e09487c4c00..K.2...H|L. >HCIEvent: MaxSlotsChange(0x1b)plen3 0000: 0c0005... >HCIEvent: ModeChange(0x14)plen6 0000: 000c00000000...... >HCIEvent: CommandStatus(0x0f)plen4 0000: 0c010408.... >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 40110e00487ccc00@...H|? handle12flags0x00dlen12 0000: 08004b0042110e09487ccc00..K.B...H|? >HCIEvent: NumberofCompletedPackets(0x13)plen5 0000: 010c000200..... 播放/暂停: >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 50110e00487c4b00P...H|K. handle12flags0x00dlen12 0000: 08004b0052110e09487c4b00..K.R...H|K. >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 60110e00487ccb00`...H|? handle12flags0x00dlen12 0000: 08004b0062110e09487ccb00..K.b...H|? >HCIEvent: NumberofCompletedPackets(0x13)plen5 0000: 010c000200..... 右键: >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 70110e00487c4600p...H|F. handle12flags0x00dlen12 0000: 08004b0072110e09487c4600..K.r...H|F. >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 80110e00487cc600....H|? handle12flags0x00dlen12 0000: 08004b0082110e09487cc600..K.....H|? >HCIEvent: NumberofCompletedPackets(0x13)plen5 0000: 010c000200..... >HCIEvent: MaxSlotsChange(0x1b)plen3 0000: 0c0001... >HCIEvent: ModeChange(0x14)plen6 0000: 000c0002c800....? 然后将control.c的日志打印出来: 按一次”“播放/暂停键”: D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=46对应PAUSE_OP D/ACRVP(237): key_quirks=0,pressed=1按键按下 D/ACRVP(237): control->uinput=fffffffe,send_key=201对应MEDIA_PLAY_PAUSE D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=c6(=0x46|0x80表示按键释放了) D/ACRVP(237): key_quirks=0,pressed=0按键释放 D/ACRVP(237): control->uinput=fffffffe,send_key=201对应MEDIA_PLAY_PAUSE 再按一次”“播放/暂停键”: D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=44对应PLAY_OP D/ACRVP(237): key_quirks=0,pressed=1按键按下 D/ACRVP(237): control->uinput=fffffffe,send_key=200对应MEDIA_PLAY_PAUSE D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=c4 D/ACRVP(237): key_quirks=0,pressed=0按键释放 D/ACRVP(237): control->uinput=fffffffe,send_key=200对应MEDIA_PLAY_PAUSE nextkey: D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=4b对应FORWARD_OP D/ACRVP(237): key_quirks=0,pressed=1 D/ACRVP(237): control->uinput=fffffffe,send_key=163对应MEDIA_NEXT D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=cb D/ACRVP(237): key_quirks=0,pressed=0 D/ACRVP(237): control->uinput=fffffffe,send_key=163 prevkey: D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=4c对应BACKWARD_OP D/ACRVP(237): key_quirks=0,pressed=1 D/ACRVP(237): control->uinput=fffffffe,send_key=165对应 D/ACRVP(237): ---handle_panel_passthrough---- D/ACRVP(237): operands[0]=cc D/ACRVP(237): key_quirks=0,pressed=0 D/ACRVP(237): control->uinput=fffffffe,send_key=165MEDIA_PREVIOUS 从上面可以看到bluetooth的协议栈blueZ是没有问题的 将frameworks\base\libs\ui\EventHub.cpp的LOG打开,只能看到了control.c的日志,EventHub的getEvent完全不响应 观察所有log日志发现,openDevice里也没有装载AVRCP.kl 初步判断event有问题 event分析: $adbshell #cd/proc/bus/input #catdevices catdevices #catdevices catdevices I: Bus=0019Vendor=0001Product=0001Version=0001参考s3c-keypad.c N: Name="s3c-keypad"input_dev->name=DEVICE_NAME; P: Phys=s3c-keypad/input0input_dev->phys="s3c-keypad/input0"; S: Sysfs=/devices/virtual/input/input0virtual的? U: Uniq= H: Handlers=event0 B: EV=3 B: KEY=40004000 I: Bus=0019Vendor=0001Product=0001Version=0100参考vpad_buttons.c N: Name="s3c-eintkey"input->name=pdev->name,gpio_keys_device_driver.name="s3c-eintkey", P: Phys=gpio-keys/input0input->phys="gpio-keys/input0" S: Sysfs=/devices/platform/s3c-eintkey/input/input1为什么这里是platform目录? U: Uniq= H: Handlers=event1 B: EV=3 B: KEY=100000000 I: Bus=0018Vendor=0000Product=0000Version=0000参考amri_ts.c N: Name="amri_ts"amri_ts_driver.name="amri_ts" P: Phys=没有定义 S: Sysfs=/devices/platform/s3c2440-i2c.0/i2c-0/0-0033/input/input2为什么这里是platform目录? U: Uniq= H: Handlers=event2 B: EV=b B: KEY=4000000040000800400010000 B: ABS=26500000 I: Bus=0000Vendor=0000Product=0000Version=0000 N: Name="ecompass_data" P: Phys= S: Sysfs=/devices/virtual/input/input3 U: Uniq= H: Handlers=event3 B: EV=9 B: ABS=307bf 从上面可以看到,完全没有AVRCP的event。 解决办法: Kernel $makemenuconfig CONFIG_INPUT_UINPUT 解决后的状况: $adbshell #cd/proc/bus/input #catdevices 显示增加了一个event I: Bus=0005Vendor=0000Product=0000Version=0000 N: Name="AVRCP" P: Phys= S: Sysfs=/devices/virtual/input/input4 U: Uniq= H: Handlers=event4 B: EV=100007 B: KEY=1030016800000 B: REL=0 看openDevice的信息: D/EventHub(84): EventHub: : readNotifynfd: 87 D/EventHub(84): Openingdevice: /dev/input/event4 D/EventHub(84): Gettingkeys... D/EventHub(84): Gettingabsolutecontrollers... D/EventHub(84): keylayoutFilename=/system/usr/keylayout/AVRCP.kl I/EventHub(84): Newkeyboard: device->id=0x10003devname='AVRCP'propName='hw.keyboards.65539.devname'keylayout='/system/usr/keylayout/AVRCP.kl' I/EventHub(84): Newdevice: path=/dev/input/event4name=AVRCPid=0x10003(of0x4)index=4fd=196classes=0x1 D/EventHub(84): Addingdevice/dev/input/event40x361800at4,id=3,classes=0x1 D/EventHub(84): Reportingdeviceopened: id=0x10003,name=/dev/input/event4 按键时也可以看到EventHub的信息了: Log如下: D/ACRVP(236): ---handle_panel_passthrough---- D/ACRVP(236): operands[0]=46 D/ACRVP(236): key_quirks=0,pressed=1 D/ACRVP(236): control->uinput=14,send_key=201control.c发出201号键,按键按下了 D/EventHub(84): /dev/input/event4got: t0=937,t1=582930,type=1,code=201,v=1表示从event4得到201号键MEDIA_PLAY_PAUSE D/EventHub(84): iev.code=201keyCode=85flags=0x00000001err=0 D/EventHub(84): /dev/input/event4got: t0=937,t1=600241,type=0,code=0,v=0 D/AudioHardware(61): AudioStreamOutALSA: : setParameters()routing=0 D/ACRVP(236): ---handle_panel_passthrough---- D/ACRVP(236): operands[0]=c6 D/ACRVP(236): key_quirks=0,pressed=0 D/ACRVP(236): control->uinput=14,send_key=c9 D/EventHub(84): /dev/input/event4got: t0=937,t1=664391,type=1,code=201,v=0control.c发出201号键,按键释放了 D/EventHub(84): iev.code=201keyCode=85flags=0x00000001err=0 D/EventHub(84): /dev/input/event4got: t0=937,t1=664406,type=0,code=0,v=0 D/A2DP(61): a2dp_stop D/A2DP(61): bluetooth_stop E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: Stoppedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: PropertyChangedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: PropertyChangedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C V/BluetoothEventRedirector(244): Receivedandroid.bluetooth.a2dp.action.SINK_STATE_CHANGED D/CachedBluetoothDevice(244): onProfileStateChanged: profileA2DPnewProfileState2 D/BluetoothA2dpService(84): A2DPstate: device: 00: 1D: BA: A5: D8: 1CState: 4->2 D/A2DP(61): ReceivedBT_RESPONSE-BT_STOP_STREAM D/dalvikvm(285): GC_EXPLICITfreed87K,56%free2640K/5895K,external1625K/2137K,paused75ms MacroLiu 2011-08-01
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 蓝牙AVRCP功能的实现 蓝牙 AVRCP 功能 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)