Monday, 8 July 2013

InputStick API

Many Android applications can benefit form using InputStick: remote controllers, password managers, barcode scanners and many more. My main goal was to design API in such a way, that using InputStick in existing applications will be fast and easy.

InputStick API is divided into two layers: API classes and Utility application consisting of  background service and user interface. This separates interface which represents USB device form the whole mechanism that uses InputStick to emulate it. InputStick API uses inter-process communication to exchange data with background service.

This allowed to achieve following goals:
  • using InputStick in Android applications is very easy.
  • user application does not need Bluetooth permissions.
  • most of InputStick-related user interactions are handled by InputStickUtility, which always provides user with the same interface.
  • maintaining compatibility of applications using older API version with possible newer firmware/protocol.
  • increased data security.
  • protecting hardware form being simultaneously accessed by more than one application.
Are there any drawbacks? Inter-process communication introduces additional latency, still it is less than a millisecond on most mid-end and high-end devices. Of course it also consumes some additional system resources, but that is a small price to pay for all the advantages.

InputStick API classes.

InputStick API is a set of Java classes that are directly used in application. API takes care of communicating with background service. In case if InputStickUtility is not installed, it will ask user to download the application form Google Play (at this moment it is not yet released). Most applications will use one of following standard device classes:
  • USB Keyboard
  • USB Mouse
  • USB Gamepad
  • USB Keyboard & USB Mouse & USB Consumer Control
where all it takes is to call methods corresponding to desired behaviour of the device (press key, move cursor, click, etc). Application should also handle callbacks generated when there is a change of connection state or when USB data is received (example: change of keyboard LEDs: NumLock, CapsLock, ScrollLock). Developer can focus on implementing additional functionality, while everything USB-related is taken care of by the API.

If you would like to emulate non-standard USB device, API provides a set of classes that allows you to use Java to create:
  • USB Descriptors (to define device capabilities)
  • USB Requests (define how to respond to specific type of USB host request)
  • Endpoint Configuration, Data Buffers Configuration etc.
This allows to emulate almost any kind of USB HID (Human Interface Device) hardware, but keep in mind that there are some limitations (more on that at the end).


InputStickUtility is an Android application that is required to be installed on any Android device that will be used with InputStick. Utility application provides user interface that takes care of:
  • pairing with InputStick devices.
  • selecting appropriate InputStick device at a given moment.
  • displaying notifications.
  • handling connection errors.
  • performing firmware upgrade.
User benefits form the fact that all InputStick related activities are always performed in exactly the same manner, regardless of what application wants to use InputStick, while application developers do not have to include additional user interface elements. The other task of Utility application is handled by background service. It acts as a proxy between users application and InputStick hardware. This allows to protect InputStick hardware form simultaneous access form two applications and does not allow user applications to modify internal firmware. Since all traffic goes through the service, it can maintain compatibility with applications compiled using previous API versions, in case if new communication protocol is introduced in the future. Last but not least, user application is simpler since it does not have to manage Bluetooth connection and everything related to that (enabling Bluetooth radio, dealing with unexpected situation like loosing connection, etc.).


InputStick can be recognised by USB host as any (full speed) USB device, depending on provided USB descriptors. However that does not mean that you can actually make it work. There are three main limiting factors:

Bluetooth: InputStcik communicates with Android device using Bluetooth link. This limits maximum data throughput to 12.5 KBps, what results in approximately 10 KBps for user data, after taking into account overhead introduced by transport protocol. It also introduces several milliseconds of latency.

USB: interrupt transfer type, used in HID devices, allows to set minimal polling interval to 1 millisecond, what limits maximal number of reports per second to 1000.

API: InputStick API allows to emulate most of Human Interface Devices and many other kinds of USB devices, however it may not be possible to emulate some types of devices which express non-standard behaviour.

To sum up: InputStick should allow to emulate most of Human Interface Devices, where 10 KBps throughput is in most cases enough to provide data even for 1000 reports every second. It should be also possible to implement mass storage device, however 5 KBps transfer rate (additional overhead and latency must be taken into account) makes it rather impractical. Finally, 10 KBps is simply not enough for audio class.


Here is a simple example of how to use InputStick API in Android application. Application emulates USB keyboard and when user presses a button, it types "Hello world!". Let's start with a source code:

Here is what we get:

Main Activity.
InputStickUtility takes care of asking user to select InputStick device to use.

Just a few more seconds...


InputStick is detected as a generic USB keyboard.

This is a result of pressing "Say Hello" button.

As you can see, it was enough to add several lines of code to allow Android application to use InputStick to emulate USB keyboard.

I hope that this more or less explains how InputStick API is designed. There is still some work to be done, but I estimate that I should be able to release it by the end of this month.


  1. Thanks for the update, loving these. At some point in a previous life I had a Symbian S60 phone, which I needed to use as a presentation controller a few times. Direct Bluetooth connection to the laptop, obviously. I did succeed ultimately of course, but I have rather painful memories of the various scripted servers / hosts that needed to be installed on the laptop to make it work with each software I tested (and their assorted dependencies - PyBlueZ & company). Rest assured, I can appreciate the elegance of this solution...

    1. Before switching to Android, I've been using Sony Ericsson mobile phones. One of cool features was that it could be used as Bluetooth HID keyboard and mouse. Unlike in your case, settings this up was really simple and it worked right out of the box (assuming that PC has Bluetooth), it even can be used as a Bluetooth remote for my Razr. The main problem was that the "Remote Control" application was very simplified, so it was ok only for simple tasks like presentation or media control. Unfortunately it was not possible to use this feature in Java midlets. That is why I want to provide an open API, so that anyone can use keyboard/mouse/some_other_device functionality in his/her application.

  2. Witam,
    Z zaciekawieniem sledze postepy InputStick'a.
    Zycze powodzenia !
    Czy Pan zamierza wydac moze wersje open-source programu oraz plytki?

    1. Schemat i projekt PCB postaram się wrzucić przy okazji najnowszej rewizji PCB, szykuje się parę drobnych zmian. Co do oprogramowania, to najpierw muszę się przejrzeć jak wygląda sprawa z różnego typu licencjami open-source. W najbliższym czasie chcę uporać się z doprowadzeniem Androidowego API do stanu w którym da się z tego bezproblemowo korzystać. Firmware zostanie na sam koniec, nie jestem jeszcze na 100% pewien czy obecny model modułu Bluetooth nie będzie zmieniony na coś innego.

  3. dziękuję za odpowiedź, będę śledzić dalej postępy :-) Pozdrawiam