Archive for the ‘Series 60’ Category

Symbian OS goes OS

Tuesday, June 24th, 2008

Airsource woke up this morning to Nokia’s announcement to make Symbian an Open Source platform, and with it all the concrete platforms like S60, UIQ, and so forth. While Motorola, Sony Ericsson, and NTT DoCoMo are all mentioned in the press release, it seems to me that they had little choice but to jump on board. From an Airsource perspective, S60 pretty much meant Nokia - and now Nokia will mean S60. At the very least, that might make our sales presentations easier.

This announcement is good news in two ways for Airsource’s business. Firstly, from a commercial perspective, it removes some of the cloud of doubt about what Android means for the market. Android did not exactly threaten the future of S60, the established leader in the convergent devices market , but it did cast some doubt on the subject. How would an open source competitor affect the market? Businesses, of course, hate doubt, and while S60 was ahead of Android on pretty much everything apart from source access, the playing field there has now been made more level. Obviously a $1500 charge (annual) for source access is not free, but it is vastly cheaper than the old fee to become a Symbian Platinum Partner.

Secondly, from a technical perspective, access to the underlying platform code helps the developer produce more stable products, faster. Some areas of code are always technically more complex and more poorly documented than others, such as MTMs. Access to source code will significantly ease development on the really cool stuff.

We at Airsource look forward to seeing more developments.

What platform should I write my app for?

Monday, April 28th, 2008

When we set up Airsource, we set it up as a BREW consultancy. We rapidly sold a number of BREW projects, and built on the expertise we had acquired while at QUALCOMM. In the process, however, we inevitably found ourselves working on other software platforms, particularly on Series 60, which now accounts for about half of Airsource’s work. Series 60 and BREW are often held up as competitors, though in practice I would argue quite strongly that they target very different markets.

A BREW phone, such as the Motorola V3M has a primary display is 176×220, it has 23MB of memory, and a processor clocked at perhaps 40MHz. A Nokia E65 costs nearly twice as much, has twice as many pixels, can store five times as much, and runs fives times faster. Pundits will immediately point out that the V3M is a pretty slow example of a BREW phone. That’s certainly true, but the V3 series accounts for a very significant fraction of the US market for BREW phones. The Nokia E65 is similarly chosen for comparison as an example of a popular Series 60 v3 phone.

Comparing the two is pointless. The BREW phone is clearly a much lighter-weight platform, targetted primarily at games. The Symbian phone has considerably more memory, more storage, faster CPU, and generally faster network data transfer. It is also significantly harder to program for - in the same way that coding for a Windows XP PC requires rather more knowledge than writing a program in BBC BASIC did. A Symbian phone is simply more capable than a BREW one, and consequently the APIs are richer, and the learning curve steeper.

That’s not to say that that Airsource’s clients do not want to target their application at both BREW and at Symbian. They absolutely do. But the Symbian application will always have more functionality and tighter device integration than the BREW application, in the same way that a dedicated BREW application will have more functionality and tighter device integration than a web-based application. Clients come to us because they want to get the most out of the phone, and to do things that are non-trivial, whether that be linking into the messaging menu of a Symbian phone, porting a multi-process application to BREW, or simply writing an application that Just Works.

What this means is that while the mobile market is certainly split into markets that may not directly compete with every other platform, they form an overlapping whole that represents the mobile space. Companies want to get their application “on mobile”, and by that, they mean on the maximum number of phones, with users who will spend money, for as little cost as possible. Choice of platform, like Symbian, or BREW, is therefore just a business decision, not a technical one.

Why should I use static_cast?

Wednesday, January 30th, 2008

I recently had the dubious pleasure of debugging a User 42 Panic on a piece of Symbian code that was given to me by another company. You always need to make sure you understand what the system is telling you, so I went straight to the documentation:

User 42: This panic is raised by a number of RHeap member functions, AllocLen(), Free(), FreeZ(), ReAlloc(), ReAllocL(), Adjust() and AdjustL() when a pointer passed to these functions does not point to a valid cell.

Hmmm. That didn’t really give me many clues. Well, I needed to figure out how to reproduce the bug anyway. That was relatively easy, I could reproduce it with a User::Leave(). The leave was being trapped, and the debugger showed the panic was being issued between the Leave and the TRAP, so that pointed to a problem on the CleanupStack (which agreed with what the documentation said). Isolating the problem even further showed that I could reproduce the problem by doing this:

CItemBase* item = (CItemBase*)decoder->ReadItemLC();
CleanupStack::PopAndDestroy(item);

For reference, ReadItemLC() constructed an MDecodable, and the inheritance hierarchy looked like:

MultipleInheritance

Ignoring the fact that a function called ReadItemLC() should return a CItemBase*, not an MDecodable*, the problem here is that in that inheritance hierarchy, both CItemBase and MDecodable have their own data (MDecodable has a vtable pointer, even though it’s an abstract class). Consequently when you cast a pointer from an MDecodable* to a CItemBase* you get a different pointer value. Try the attached code on any system for a demonstration of the problem.

However, in the code sample above, the CItemBase class had not been fully defined; we had simply forwarded-declared CItemBase. That meant the compiler couldn’t do the necessary arithmetic (subtract 4) to convert an MDecodable* to a CItemBase* - because it didn’t know whether they were actually part of the same inheritance tree, or completely dissociated types. So it did the equivalent of a reinterpret_cast.

When I changed the code to do the correct C++ style cast:

CItemBase* item = static_cast<CItemBase*>(decoder->ReadItemLC());
CleanupStack::PopAndDestroy(item);

It promptly failed to compile, because CItemBase hadn’t been fully defined. Adding

#include "ItemBase.h"

at the top of the file fixed the compile - and fixed my User 42 Panic as well.

Lesson: next time I get code from another source, check the casting is done properly.