Handling User Input

Most MHP receivers will receive user input from a remote control. While input from a keyboard (and possibly a mouse) may be available, it's not very likely that this will be used in most cases. The MHP receiver defines the following key events that may be generated by a remote:

Key events that may be generated by an MHP receiver. Source: TS 101 812 v1.3.1 (MHP 1.0.3 specification).
Constant name Key Key code (if standardized)
VK_UP up arrow not standardized
VK_DOWN down arrow not standardized
VK_LEFT left arrow not standardized
VK_RIGHT right arrow not standardized
VK_ENTER enter (also known as select or OK) not standardized
VK_0 to VK_9 number keys 48 - 57
VK_TELETEXT teletext key 459
VK_COLORED_KEY_0 first coloured key 403
VK_COLORED_KEY_1 second coloured key 404
VK_COLORED_KEY_2 third coloured key 405
VK_COLORED_KEY_3 fourth coloured key 406

Key codes for VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT and VK_ENTER are all defined by the Java platform. While the remote may generate other key codes as well, these are the only ones that are actually guaranteed to be available on every receiver. Relying on others is a little dangerous.

The full list of defined key events can be found in the org.havi.ui.event.HRcEvent class in the MHP specification.

Keyboard events and input focus

The AWT event model offers a pretty good basis for user input in MHP (not least because of its familiarity). In the conventional AWT event model, a component may only receive keyboard events when it has user input focus. In an environment such as MHP, this restriction can cause some problems.

Imagine the case of an EPG that only pops up when a particular button is pressed. If this application wanted to maintain an invisible AWT component on the screen to detect any AWT events, it would have to be contained in an HScene. As we saw in the section on graphics, HScenes may not be allowed to overlap on the screen. This means that the EPG would be restricting the space available to other applications, even though it had no real visible component on screen.

Since this is not very polite, having no components in the AWT hierarchy is a far better idea. Even if we had the invisible component, that component would need focus to get the event anyway. All in all, this is less than useful. So, we need an API to get user input events without having to use AWT.

The org.dvb.event package defines an API for allowing applications to access events before they enter the AWT event mechanism. A class that implements the UserEventListener can receive input events even though that application does not have user input focus.

The events that get generated by this API are not AWT events, but are instead instances of the UserEvent class. This class covers more than just keyboard events in theory - at present, however, it only supports keyboard events although more classes of events may be added later. The information about which key was pressed and what modifiers (shift, CTRL, ALT or META keys, for example) are active can be obtained and the event acted upon just like an AWT event.

Before an application can receive user events, it must define a UserEventRepository that defines the group of events that the application wishes to receive. As we can see from the API for this method, it contains methods to allow various combinations of keys to be added and removed:

public class UserEventRepository {

    public UserEventRepository (String name);

    public void addUserEvent (UserEvent event);
    public UserEvent[] getUserEvent ();
    public void removeUserEvent (UserEvent event);

    public void addKey (int keycode);
    public void removeKey (int keycode);

    public void addAllNumericKeys();
    public void addAllColourKeys();
    public void addAllArrowKeys();

    public void removeAllNumericKeys();
    public void removeAllColourKeys();
    public void removeAllArrowKeys();
}

The OverallRepository class is a subclass of UserEventRepository that contains all the user events.

Once the application has defined the set of keys it wishes to receive events for, it can use the EventManager class to request access to these events. This class is a singleton object, which can be obtained by calling the EventManager.getInstance() method.

Once an instance has been obtained, the addUserEventListener() and removeUserEventListener() to add and remove listeners for a set of events defined in a UserEventRepository object. Access to these events is considered a scarce resource (we will see why below), and so an application may lose access to them. Since the EventManager class implements the org.davic.resources.ResourceServer interface, application can subscribe to ResourceStatusEvents to discover if it has lost access to user input events.

It's important to note that an application can lose access to events and may not receive them. Applications that care about this should subscribe to ResourceStatusEvents from the event manager to make sure that they are aware when they have lost resources.

Exclusive access to keyboard events

This approach does bring some problems, however. When entering sensitive information (e.g. credit card numbers or passwords), allowing other applications to receive these keyboard events is a Very Bad Thing. For this reason, applications can request that they are allowed exclusive access to specific keyboard events.

The EventManager class has two methods that we haven't discussed yet. These are addExclusiveAccessToAWTEvent() and removeExclusiveAccessToAWTEvent(), and as their names suggest they allow an application to request exclusive access to a set of events. Unlike non-exclusive user input events, exclusive events are received using the standard event mechanism from AWT. The addExclusiveAccessToAWTEvent() method takes a UserEventRepository and an org.davic.resources.ResourceClient as arguments - the first of these contains the set of events for which exclusive access is requested, while the second indicates which part of the application should be notified when exclusive access is revoked.

When an MHP receiver gets a user input event, it has to decide which application or applications should get that event. This flowchart illustrates just how incoming events are routed to the appropriate applications:

How UI events are routed to the correct listener.

How UI events are routed to the correct listener

Since the application can request exclusive access to user input events, these are treated like a scarce resource (since by definition, only one application can have exclusive access to a given user input event). The exact nature by which this resource is managed is platform-dependent. Any application that requests exclusive access to user input events must take into account the fact that it could lose that exclusive access at any time.

Television viewing mode and key events

One of the problems that arises from allowing applications to receive events without having a visible UI component is knowing how the receiver will behave at any given time. If you think you are just watching TV, and the digit buttons stop working because they are actually being intercepted by an application instead of being used to change the channel, that spoils your experience. Users need some way of knowing whether they are watching TV or interacting with an application.

The MHP specification recommends that applications without an obvious user interface should only use the coloured keys or the teletext button, and that all other buttons should be left for the navigator. This allows developers to build applications that are activated with a single key stroke (e.g. an interactive advertisement where pressing the red button shows more information about the product) while still preserving the interaction model that people expect. Applications that want to use other keys must display a user interface that covers at least 3% of the screen area.

The teletext button is a slightly special case. Teletext and similar information services are common in many countries, and so it's not unusual to see versions of these services on digital channels. While DVB teletext is one way of providing this service, many network operators prefer to use more advanced technologies when they can and will implement their teletext services using MHP or some other middleware. Since applications that request the VK_TELETEXT key will prevent the middleware from receiving this event and displaying any DVB teletext services, applications should only request this key if the offer an equivalent information service. Since the expected behaviour in this case is for the VK_TELETEXT key to hide the teletext display as well, applications should follow this model when displaying a teletext service and should thus terminate the application and returh to television viewing mode when they receive the VK_TELETEXT keypress for the second time.