One of many things that I have accomplished this month is implementation of Consumer Control Device. It allows to control playback, volume, launch applications or perform some common tasks. Example of hardware using this class is a keyboard with additional "multimedia" keys. First, let's take a look at demo application, which allows to turn your smartphone into multimedia remote control:
I think that buttons are pretty much self explanatory, but just to be clear: first row allows to control system volume, second and third are used to control media playback, next one allows to launch application of a given type. The last row contains buttons responsible for system power control.
Implementation is very similar to previous examples (mouse/keyboard). We need two endpoints: endpoint 0 for control transfer and endpoint 1 for data transfer form InputStick to USB host. Most important part of the implementation is its USB descriptor:
As you can see there are two kinds of reports: report with ID 1 is used for usages from "Consumer Page". Data sent to host must contain exactly three data bytes: report ID (1), and usage ID (two bytes, starting with first 8 least significant bytes). The other report type is used for usages from "Generic Desktop Page", in this case for system power control. Now things look a little bit different, there are two data bytes: first byte is also a report ID (2 in this case), but second one is an array, where first three bits correspond to: power down, sleep, wake up (in this order). Some examples:
0x01, 0x92 0x01
report ID : 1, usage ID 0x0192 (launch calculator)
0x02, 0x02 (0b00000010)
report ID : 2, power down (0), system sleep (1), wake up (0)
Implementing Consumer Control in Android application is very easy task, take a look at this example:
Implementing Consumer Control in Android application is very easy task, take a look at this example:
"Consumer Page" is described in details in HID Usage Tables document (starts form page 75). List of usages looks pretty impressive, but unfortunately most usage IDs are not supported by operating systems or result of given action may vary, depending on system configuration. I performed some quick tests with following results:
OS | Windows 7 | Windows XP | Android 4.0 |
---|---|---|---|
Vol+/- | OK | OK | OK |
Mute | OK | OK | does not work |
Playback | OK | OK | OK |
Launch Browser | does not work | does not work | OK |
Launch Email Client | OK | does not work | OK |
Launch Calculator | OK | OK | OK |
Sleep | OK | opens dialog | does not work |
I guess that problems with launching browser and email client may be result of system configuration. The fact that "Sleep" does not work on Android may be related to CX-01 TV stick, which I used for the test. In case of Windows XP, instead of immediately going to sleep it asks user to select action (sleep, shut down, restart). Current version of InputStick firmware does not support remote wake up, so obviously wake up does not work.
What makes things even worse is the fact that sometimes we may experience slightly different behaviour, depending on OS, for example: lets assume following initial state: volume level is 50%, then we press "mute" and after that we change volume level (decrease). Final result depends on OS:
- Windows 7: volume level 49%
- Windows XP: volume level: 49%, still muted! ("Mute" must be pressed again in order to unmute it)
So as you can see, there are some problems with Consumer Control Device class, but after all it can be used to create multimedia remote control application, which generally works on all platforms. In my case I have used it to control Winamp, Windows Media Player, Media Player Classic and VLC Player on Windows and stock media player on Android.