Let me lead off by saying I'm a bit of a luddite when it comes to phones. I like my phone to be able to make a call and occasionally send a text message. If I need to use a browser, I have a 30-inch Dell monitor and a PC that I can actually read web pages on. If I need to find a location, I have a nice Nuvi that doesn't require men to fiddle with a phone and that has a better interface that any other phone I've used. If I need to listen to music I have a Zune that lets me do that.
As far as phones go my favorite, other than that old StarTac that I still pine for, is my HTC Snap (also known as an HTC Ozone, Dash 3G and probably a few other names). Ironically it's also the target of my wrath over the last few days. As a user experience as far as a phone goes, it has everything I like, but if you need to actually create an application that does what you want on the thing, I think you're going to need divine intervention. And this, at its core, is why I think Windows Mobile, at least up through 6.5 just plain sucks.
My goal was simple - or so I thought. Create a simple application that collects GPS data at all times (yes, I know about battery life, blah, blah - let's assume that it's not an issue for this app). I know that a Smartphone never actually puts the processor fully to sleep and that even when the backlight/screen is off, I can still run code so this should be simple, right? Hardly.
The first thing I found, which was not a surprise, is that when the phone enters the "screen off" power mode, it shuts off the GPS receiver - or that's what I assume anyway. The GPSID driver stops giving me data anyway.
I know from cruising around the device's registry that the driver prefix is "GPD0:" and I know that WinMo is supposed to allow you to adjust power schemes through both API calls and some registry settings. "Supposed to" being the key here. I spent well over an hour going through and modifying the registry keys adding just about every combination I could think of along with soft resetting the device all with zero effect.
This is the first strike against this platform. Microsoft has documented that this is how the device is supposed to work, yet in a real-world scenario, it doesn't.
I know a bit about how Windows CE works, and my assumption is that these registry settings simply tell the Power Manager to set some driver device states under certain conditions. There should be no reason I can't do that manually, since I'm dealing with a pretty finite set of drivers (one) and states (two).
In order to manually alter the power state of a device, I need to know when the system itself changes state. For example, I need to know when the device goes into Unattended mode so I can then manually call one of the power management functions. To get notifications, we P/Invoke RequestPowerNotifications and pass it in a queue handle where it will send those notifications. Another hour of development later and I came to the conclusion that the device simply isn't sending out notifications for power state changes. I tested this in both C# and C to just be certain. Strike two.
Maybe I could just do something simple and just tell the Power Manager to never shut off the GPS. SetPowerRequirement should do that, but more testing proved that this, too, had no effect on this platform. After several hours of work and lots of frustrating tests that failed I was beginning to question the power manager altogether.
If the device wasn't going to tell me when it changes state, then I figured I'd just handle all of the state changes myself. I'd have the application periodically call SystemIdleTimerReset, implement my own application idle filter and dim the backlight myself. We're getting into some serious hack territory here, but some days you have to do what you have to do to solve the issue.
I implemented the timeout filter and used a call to SetDevicePower to shut off the backlight. The idea here is that I'd just never let the device go into the BacklightOff or Unattended mode and just turn off the backlight myself. I ran the test and ,surprise, my code had zero effect. By zero effect I mean that the backlight shut off and the GPS turned off.
I spent some time debugging to try to determine why I was able to shut off the backlight but not keep the GPS on and I finally realized that I was actually not turning off the backlight - the device still was. For the first time ever I was seeing a call to SystemIdleTimerReset succeed (i.e. return a success) but not actually reset the timer. Strike three, and this was a huge one.
I continued to muck about with other APIs like PowerPolicyNotify to try to keep the backlight on and even some proprietary HTC calls I found online, all to no avail. I went back to basics and tried even the simplest of code in C and re-verified all that I had seen.The device appeared to completely ignore any call that had to do with the Power Manager while always giving me a successful return value.
All I can conclude from this is that HTC, in their infinite wisdom, decided to implement their own power manager to handle turning on/off all of these devices. and to make the WinMo platform itself happy, they just stubbed out all of the Power Manager calls to return success.
In the end, I told the customer that the phone they selected will never be able to do what they want and it looks like they're going to opt for another phone running a completely different OS.
This is a classic case of why I hate developing software the Windows Mobile platform, and one of the big reasons why the platform has been pretty much an abject failure. How can a software vendor even hope to develop an application that will work on multiple devices when the devices don't even follow Microsoft's published rules? The test matrix would be astronomically large and the costs, both in terms of the hardware you'd have to keep on hand and the time required to run the tests is simply prohibitive.
So is this HTC's fault? To a degree, sure. They should have followed the API's documented by Microsoft, but I still only place about 10% of the blame on them. Developers will, after all, always try to do things "better", and by better I mean that anything not designed in-house is obviously inferior.
But the real problem lies in Redmond. Every Windows Mobile device that ships gets a Windows Mobile logo. To get that logo they have to run the device through a set of Logo Certification tests (also called the LTK). The fact that a device can pass those tests with these obvious and fundamental variances shows that either the tests themselves have really poor coverage or the OEMs are getting waivers for these test failures.
Which it is doesn't matter because the end result is that Logo Testing is completely meaningless. The idea behind Logo Testing should be that when an ISV gets a device, they can depend on it to behave in a specific, predictable way. This device certainly doesn't. And this was just one device and just a small handful of APIs that I was attempting to use. Extrapolate that out to all of the device models that have been shipped and all of the APIs that any given application might call and you begin to see why this is so difficult (and very likely one of the reasons Windows Phone 7 is a complete redesign all the way back at to base Windows CE OS).
Personally, I don't do a whole lot of Windows Mobile development. I tend to focus on embedded Windows CE solutions where the hardware, OS and API set are fixed, finite, manageable and testable. When I see something wrong, we get the OS fixed - we don't path over the top of it (at least whenever we can). It's these little forays back into the Windows Mobile platform that reinforce and remind me of my utter distaste for it.
Hopefully Windows Phone 7 will have valid platform testing and a meaningful certification program but the reality is that I, and likely many, many other developers have been jaded by bad experience after bad experience with these and it's going to take a whole lot of work to gain our trust back. I'm not saying it's an insurmountable problem, but I certainly don't think Microsoft is going to get many more chances.