Friday, July 25, 2008

Building your first Javascript-powered Symbian application using Webkit

The 10-years old Symbian OS is the open mobile operating system, that powers millions of smartphone worldwide, especially Nokia mobile phones.
Symbian itself is the OS engine that is customized by device manufacturers to produce real operating systems. Symbian has 3 platforms, the S60 which runs mostly on Nokia phones, the UIQ which runs mostly on Sony Ericsson and Motorola, and the MOAP (new).

Developing for Symbian is an inevitable task for developers targeting mobile platforms. Depending on the target platform, a developer should select a Symbian SDK to use. The S60 platform itself contains a lot of versions with a corresponding SDK for each version. 1st, 2nd and 3rd editions exist, each one having as many as 3 to 4 feature packs. This results in about 9 versions. 1st edition represents Symbian OS v6.1 and the latest is v9.5. The Symbian Developer Network (SDN) and Forum Nokia has been always Sybmian developers heaven.

Symbian applications are written in C++ (native) or Java (requires J2ME). The Internet browsing on Symbian started with Opera in its first releases. However, after releasing Webkit as an open-source project, it has been adopted by Symbian starting from 3rd edition as its default browser engine.

The good news is that you can develop your own Symbian application that links with the Webkit and exploits its capabilities in Javascript interpretation and DOM manipulation. The bad news is that there is no guide, up to my knowledge, that demonstrates this!

So here are simple steps for creating your first Javascript-enabled S60 application:

  • First of all, download and build S60Webkit using this guide. Don't panic for build errors, you will find all solutions in this guide. This should work for Carbide.c++ the latest release v1.3. You will need also this guide because Carbide v1.0 is obsolete. Remember 3 simple rules:
    • to build for the emulator use "build -w"
    • to build for the device use "build -g"
    • to build a special target use "build -? targetname"

  • There is a bug in the Perl script that scans build output to show number of errors/warnings. Find the file in: C:\Symbian\9.1\S60_3rd\Epoc32\tools\, or change path to your SDK installation path. To fix it, find the condition following the comment:
# make: *** [SAVESPACECONVTOOL] Error 2


if ($line =~ /make(\[\d+\])?:\s*\*\*\*.*(E|e)rror/)

Start a new project in Carbide.c++ IDE using File->New->Symbian OS C++ project and select 3rd-Future ed. GUI application. Follow on-screen steps and you now have a simple HelloWorld application.
  • Now its time to link with the Webkit. You will have to edit some header and configuration files to get it working:
    • modify S60/JavaScriptCore/kjs/list.h and add

#include <oom.h>

somewhere in the beginning of the file

  • Edit the project mmp file (<projectname>.mmp) using Carbide IDE visual editor:
    • In the libraries tab at the bottom click on Add to add 2 libraries: JavaScriptCore_sdk.lib and MemMan_sdk.lib. If you did not find either then the building of S60Webkit was incomplete.
    • In the options tab add 4 entries in the Compiler Settings area:
      • User includes: /Symbian/9.1/S60_3rd/s60/JavaScriptCore/kjs
      • System includes: /Symbian/9.1/S60_3rd/s60/MemoryManager/Inc and /epoc32/include/libc
      • Macros: NOKIA_CHANGES

  • Edit the file where you want to write webkit-specific code, for example: xxxxAppUI.cpp:
    • Include the interpreter header file:

#include "interpreter.h"

    • write some code for Javascript interpretation, for example in the handler for first menu action:

using namespace KJS;

InterpreterLock lock;

Object globalObj(new ObjectImp);

Interpreter *interp = new Interpreter(globalObj);

UString code = KJS::UString("10 * 5");

Completion result = interp->evaluate(code);

ComplType resultType = result.complType();

if (resultType == Normal) {

// OK

textResource = StringLoader::LoadLC(R_MESSAGE_OK);

// textResource loaded with StringLoader.

informationNote->ExecuteLD( *textResource);

// Pop HBuf from CleanUpStack and Destroy it.


else {

// failure

textResource = StringLoader::LoadLC(R_MESSAGE_FAILURE);

// textResource loaded with StringLoader.

informationNote->ExecuteLD( *textResource);

// Pop HBuf from CleanUpStack and Destroy it.


You may replace the variable "code" with any valid Javascript code.

    • add some string resources for the previous code to compile. In file data/<projectname>.rls add these 2 lines:

#define qtn_message_ok "OK"
#define qtn_message_failure "Failure"

    • In file data/<projectname>.rss add:

RESOURCE TBUF r_message_ok { buf=qtn_message_ok; }

RESOURCE TBUF r_message_failure { buf=qtn_message_failure; }

  • Build your project for the emulator
  • Open the emulator from Start menu and browse to Installed-><projectname>

Your application sould open, press the left menu button to show the menu, then select Message and get your previous Javascript evaluated by seeing 'OK'!

I hope I have covered all dark parts, in case something was missing, please comment here to augment any missing part.

No comments: