Tuesday, January 12, 2010

KeypadLedControl

On the forums I read a post where someone complained that the front keypad lights turn themselves off after about 10 seconds the device got out of standby. And that's correct. HTC built it with a timeout. Whenever you press a key, or the device comes out of standby, the driver turns off the keypad lights after 10 seconds. I had been used to this for ages, as HTC has always done this. However, it wasn't until this post that I thought it'd also be nice to have it always on (at least, whenever the LCD is on).

Luckily I found how to do it pretty fast. The keypad driver makes use of events to notify when the keypad light should go on. When the event is set, the keypad light stays on for 10 seconds. If the event has not been set again within that period, the light turns off.

On the HD2 the event is (by default) named "IconLedOnEvent". On any old HTC devices the event is called "IconLedEvent". When this event is created with CreateEvent(), you'll get a return message saying ERROR_ALREADY_EXISTS, which in fact isn't an error at all. In our case this means success, as someone else is using the event as well (the driver!). Calling SetEvent() on the handle effectively enables the light. I've made a small app that checks the power state of the LCD screen and calls SetEvent() every few seconds when it determines the LCD is turned on (i.e. out of standby).

On the HD2 default stock ROM, the light automatically turns off when the device goes into standby. The driver makes sure this happens. However, it seems that some versions of the stock ROM, and also some other HTC devices, don't have this behaviour. In this case we have to turn off the LED ourselves. I found that on all HTC devices, an event named "IconLedOffEvent" exists to turn off these keypad lights. So I simply check the LCD state, and when I detect it is off, I set this event to turn the keypad lights off.

Unfortunately, it wasn't this simple.

The problem is that when the device goes into standby, the application is "paused" right away as well. This causes it never to detect that the LCD is off. I've tried various way to "detect" when the device goes into standby, and run last-minute code. I couldn't easily find a way without having a dialog window (and a message queue).

With this in mind I tried another approach. Instead of detecting when the device goes into standby, I prevent it from going into standby. And only when I allow it, the device actually continues to go into standby (until that time, only the LCD is off). We can do this using the PowerPolicyNotify() function. This function works with a counter. For every time PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE) is called, a similar call with FALSE must be called as well. As long as the counter is not back at zero, the device will stay in unattended mode. Using this method, we keep the device in unattended mode until the code detects that the LCD is turned off, it sets the keypad light off event, and then releases unattended mode. Overal the device would effectively be in standby a second longer than intended, but that's no problem.

If you're interested in the code, you can find links to it in the thread I made for this little app.

The photo included in this post is made by pocketnow.com (link to article).

No comments:

Post a Comment