Monday, June 21, 2010

Add Bluetooth HID profile in Android

The HID profile defines the protocols, procedures and features to be used by Bluetooth HID such as keyboards, pointing devices, gaming devices and remote monitoring devices. When I tried bluetooth function in Android Dev Phone (G1) last year, I use a utility tool 'hidd' which is from native bluez. It is a command tool. After I can pair with Apple Wireless keyboard sucessfully, I type 'hidd ' from terminal, then I can start to use it. But it's not automatically, I cannot connect it from Setting UI application either. Therefore, we should add a new Bluetooth HID profile in Android, to make it be connectable, like a BT headset or speaker.

# hidd --connect 00:1D:4F:A7:9A:49

# hidd --show
00:1D:4F:A7:9A:49 Apple Inc. Keyboard [05ac:022c] connected

0xlab is a member of OESF (Oopen Embedded Software Foundation) and they have some very useful bluetooth extensions in their 'Embedded Master 1' project. Althought these features are based on Android Donuts, they are still a very good reference. Therefore, I use their code and modify few parts of code for newer Android Eclair version. The difference of Eclair from Donuts in Bluetooth is bluez dbus API changes and some java API changes in frameworks. I've committed my patches to 0xdroid project in gitouris. If you'd like to use my work, you could apply patches in Frameworks and Setting application.

Beside the code in Frameworks and Settings UI application, I have to enable some features in kernel, since I use Apple Wireless Keyboard for this experiment. If I don't enable them, I can't never create an input device for Apple keyboard in Android. It took me few days to debug this issue. I cannot tell why I can use hidd to connect with it without any problem, but cannot use Dbus method to connect with it correctly. It's very weird. It's said 'Connected', but I cannot receive any key events or cannot see a virtual input device in Android system. Furthermore, there is no problem on connecting with a BT mice at all. Both methods are fine.

When I tried to implement any features in Android, I would try it in my Ubuntu machine first. They have linux kenel and many native code are the same. Based on the experiences in Ubuntu, I can know how it works and the normal flow what it looks like. In Ubuntu, when I connect with an Apple Wireless Keyboard, I can see the device name from dmesg. But I cannot see the device name in Android at all, I can see BT mouse device name in Android. Therefore, I check menuconfig on building kernel, and then I see some HID special drivers. I just enable features like CONFIG_HID_APPLE=y, CONFIG_HID_DEBUG=y, CONFIG_HIDRAW=y, CONFIG_USB_HIDDEV=y. After using the new kenel image, I can connect/disconnect with a BT keyboard from Setting UI application normally. I've verified my work in Beagle board and Qualcomm MSM72xx platform.