Вы находитесь на странице: 1из 164

QtforMaemo Developer's Guidev0.

5 Beta

MaemoforMobileDevelopers

CHAPTER1:INTRODUCTION 1 2 3 4 CHAPTER2:GETTINGSTARTED 1 2 2.1 2.2 2.3 2.4 3 4 5 5.1 5.2 5.3 6 MAEMOSDKCONCEPTS ............................................................................................................14 INSTALLDEVELOPMENTENVIRONMENT...........................................................................15 INSTALLVMWARE(WINDOWSOS/MACOS)........................................................................15 INSTALLSCRATCHBOX ..................................................................................................................16 INSTALLMAEMOSDKANDNOKIABINARIES .............................................................................16 INSTALLQTONSCRATCHBOX ......................................................................................................17 WHATISMAEMOANDQT? ........................................................................................................ 8 MAEMOCOMMUNITY................................................................................................................... 9 WHATMAEMOCANDO? ...........................................................................................................10 WHATSNEWINMAEMO5(FREMANTLE)? .......................................................................11

CREATEAQTPROJECT..............................................................................................................18 COMPILETHEAPPLICATION...................................................................................................18 RUNTHEAPPLICATIONONTHEEMULATOR ....................................................................19 STARTTHESDKUI ......................................................................................................................19 RUNTHEAPPLICATION .................................................................................................................20 CLOSETHESDKUI.......................................................................................................................20 TESTTHEAPPLICATIONONADEVICE ................................................................................21 INSTALLQTPACKAGES .................................................................................................................21 DEPLOYAPPLICATIONTOTHEDEVICEUSINGSSH.....................................................................22 INSTALLSSHONTHEDEVICE.................................................................................................................22 TRANSFERTHEAPPLICATIONTOTHEDEVICE .....................................................................................23 DEPLOYTHEAPPLICATIONUSINGPCCONNECTIVITY ........... ERROR!BOOKMARKNOTDEFINED. RUNTHEAPPLICATIONONDEVICE ..............................................................................................23

6.1 6.2 6.2.1 6.2.2 6.3 6.4 7 7.1 7.2 7.3 7.4 7.5 7.6

CREATEADEBIANINSTALLATIONPACKAGE ...................................................................24 EDITTHERULESFILE ....................................................................................................................25 EDITTHECONTROLFILE...............................................................................................................26 EDITTHECHANGELOGFILE ..........................................................................................................27 MAKETHEAPPLICATIONVISIBLEINTHEMENUWITHA.DESKTOPFILE ..................................27 CHANGETHE.PROFILE .................................................................................................................28 BUILDTHEPACKAGE.....................................................................................................................29

MaemoforMobileDevelopers

7.7

INSTALLTHEPACKAGEONDEVICE...............................................................................................30

CHAPTER3:USINGESBOXIDE 1 2 2.1 3 4 4.1 5 6 CHAPTER4QTFORMAEMOIMPLEMENTATIONNOTES 1 2 3 4 CHAPTER5:USINGMAEMOAPISINQTAPPLICATIONS 1 LIBLOCATION................................................................................................................................50 MAINCLASSESANDMETHODS .....................................................................................................50 LOCATIONGPSDEVICE.............................................................................................................................50 LOCATIONGPSDCONTROL .....................................................................................................................52 LOCATIONDISTANCEUTILS .........................................................................................................53 LIBLOCATIONEXAMPLE ...............................................................................................................53 LINKS .............................................................................................................................................59 PLATFORMSPECIFICCHANGES..............................................................................................45 PORTINGAQTAPPLICATIONTOMAEMO..........................................................................48 UPLOADINGTHEAPPLICATIONTOGARAGE ....................................................................49 LINKS ...............................................................................................................................................49 PREREQUISITES ...........................................................................................................................31 INSTALLANDSETUPESBOXONWINDOWS.......................................................................32 INSTALLSSHSERVER .....................................................................................................................35 INSTALLANDSETUPESBOXONLINUX ...............................................................................35 COMPILETHEAPPLICATIONONESBOX..............................................................................36 RUNTHEAPPLICATIONONESBOX ............................................................................................39 CREATEADEBIANINSTALLATIONFILE..............................................................................41 DEPLOYTHEAPPLICATIONTOTHEDEVICE.....................................................................43

1.1 1.1.1 1.1.2 1.2 1.3 1.4 2 2.1 3 3.1 3.2

LIBCITYINFO .................................................................................................................................59 EXAMPLE .......................................................................................................................................59 MCEDEV.........................................................................................................................................62 MCEHEADERSFILES .....................................................................................................................63 QTMCEDEVEXAMPLE..................................................................................................................64

MaemoforMobileDevelopers

4 4.1 4.2 4.3 5

CALENDARBACKEND ................................................................................................................66 MAINCLASSESANDMETHODS .....................................................................................................67 EXAMPLE .......................................................................................................................................68 LINKS .............................................................................................................................................74 ICD2..................................................................................................................................................75

5.1 INTRODUCTION .............................................................................................................................75 5.2 ARCHITECTURE .............................................................................................................................75 5.3 MAINCLASSESANDMETHODS .....................................................................................................76 5.4 EXAMPLE .......................................................................................................................................78 5.4.1 INTERNETCONNECTIONDAEMON2EXAMPLE ..................................................................................78 5.5 LINKS .............................................................................................................................................83 5.5.1 DOCUMENTATION/MAEMO5DEVELOPERGUIDE/USINGCONNECTIVITY COMPONENTS/MAEMOCONNECTIVITY ..............................................................................................................83 5.5.2 INTERNETCONNECTIVITYDAEMONVERSION2..................................................................................84 5.5.3 BIBLIOGRAPHY ..........................................................................................................................................84 6 AGUIEXAMPLE ............................................................................................................................84 INTRODUCTION .............................................................................................................................84 MAINCLASSESANDMETHODS ......................................................................................................85 EXAMPLE .......................................................................................................................................85 MAINWINDOW .........................................................................................................................................87 TABLE .........................................................................................................................................................91 LINKS .............................................................................................................................................95

6.1 6.2 6.3 6.3.1 6.3.2 6.4 7

WHACAMOLEGAMEEXAMPLE ............................................................................................95

7.1 INTRODUCTION..............................................................................................................................95 7.2 EXAMPLE .......................................................................................................................................96 7.2.1 GAMEMAINWINDOW ..............................................................................................................................96 7.2.2 MAINSCREEN ............................................................................................................................................97 7.2.3 RECORDSSCREEN .....................................................................................................................................98 7.2.4 GAMECONTROLLER .............................................................................................................................. 100 7.2.5 GRAPHICSVIEWWIDGET ...................................................................................................................... 101 7.2.6 MOLEITEM ............................................................................................................................................. 103 7.3 LINKS .......................................................................................................................................... 104 8 8.1 CAPTURINGKEYEVENTS....................................................................................................... 105 EXAMPLE .................................................................................................................................... 105

CHAPTER6:ADDITIONALMAEMOTOOLS 1 1.1 1.2 1.3 MISCELLANEOUS....................................................................................................................... 107 SCREENSHOTTOOL .................................................................................................................... 107 HOMEIP...................................................................................................................................... 107 DPKGANDAPT........................................................................................................................... 108 MaemoforMobileDevelopers

2 2.1 2.2 2.3 2.4 2.5 2.6 3 3.1 3.2 4 4.1 4.2 4.3 5 5.1 5.2 5.3 5.4 5.5

NETWORKING............................................................................................................................ 109 IPUTILS ....................................................................................................................................... 109 NETCAT ....................................................................................................................................... 111 TCPDUMP.................................................................................................................................... 113 TRACEROUTE.............................................................................................................................. 113 NSLOOKUP .................................................................................................................................. 114 WGET .......................................................................................................................................... 114 WIRELESSTOOLS ..................................................................................................................... 114 BLUETOOTHTOOLS.................................................................................................................... 114 WIRELESSTOOLS ....................................................................................................................... 115 TESTAUTOMATION................................................................................................................. 116 SPTESTS..................................................................................................................................... 116 XNEE............................................................................................................................................ 117 XRESPONSE ................................................................................................................................. 117 RESOURCEUSAGE..................................................................................................................... 117 HTOP ........................................................................................................................................... 117 SPMEMUSAGE ............................................................................................................................ 118 SPSMAPSMEASURE .................................................................................................................. 122 SPSMAPSVISUALIZE ................................................................................................................. 123 XRESTOP ..................................................................................................................................... 123

CHAPTER7:DEBUGGINGANDPROFILING 1 DEBUGGING ................................................................................................................................ 124

1.1 GENERALTOOLS ......................................................................................................................... 125 1.1.1 MAEMODEBUGSCRIPTS...................................................................................................................... 125 1.1.2 NATIVEGDB ........................................................................................................................................... 126 1.1.3 DEBUGDEPINSTALL ............................................................................................................................ 126 1.1.4 LISTMMAPPEDLIBS ............................................................................................................................. 127 1.2 GDB ............................................................................................................................................ 127 1.2.1 INSTALLINGANDTESTINGGDB ........................................................................................................... 128 1.2.2 DEBUGGINGWITHNATIVEGDBONSCRATCHBOX ........................................................................... 129 1.2.3 DEBUGGINGWITHGDBONDEVICE ..................................................................................................... 134 1.2.4 COREDUMPFILES .................................................................................................................................. 138 1.2.5 SPERRORVISUALIZER ......................................................................................................................... 143 1.2.6 SYSLOG .................................................................................................................................................... 143 2 PROFILING .................................................................................................................................. 143

2.1 VALGRIND ................................................................................................................................... 144 2.2 OPROFILE ................................................................................................................................... 149 2.2.1 INSTALLINGOPROFILEONSCRATCHBOX .......................................................................................... 149 2.2.2 INSTALLINGOPROFILEONINTERNETTABLET ................................................................................ 149 MaemoforMobileDevelopers

2.2.3 USINGOPROFILE ................................................................................................................................... 151 2.2.4 OPROFILEWITHCALLGRAPH .............................................................................................................. 155 2.2.5 OPROFILEUI ............................................................................................................................................ 157 2.3 STRACE ....................................................................................................................................... 158 2.4 LTRACE ....................................................................................................................................... 162

MaemoforMobileDevelopers

MaemoforMobileDevelopers

Chapter1 Introduction
ThisdocumentistargetedfordevelopersinterestedindevelopingandportingQtapplications for Maemo. Qt application development environment is currently relying on the underlying Maemo toolchain. This document provides stepbystep instructions how to set up development environment, and how to create, compile, and run a simple Qt project on the emulatorandontarget.ItalsocoversMaemospecificconsiderationsandpresentshowtouse Maemo APIs in Qt applications. Debugging, profiling, and additional Maemo development toolsarealsocovered.

1 WhatisMaemoandQt?
MaemoisanopensourcedevelopmentplatformoriginallyuseinInternetTablets(Nokia770, NokiaN800andNokiaN810).TheMaemoplatformitselfisthesetofsoftwarecomponents usedtodevelopandtestsoftwareforNokiaMaemodevices.Itisbuiltfromlargepartsofopen sourceprojects. The Maemo operating system is based on Debian GNU/Linux (http://www.debian.org/index.en.html).Asitwasdesignedforresourceconstraineddevices,a lotofchangesandnewfeatureswhererequiredtomakeitbestfittothetargetcharacteristics such as smaller screens, battery powered, multiple input methods, etc. One of the most important is the Hildon UI application framework. Hildon was designed by Nokia to provide mobile device oriented functionality (ex.: fingerfriendly interface), but also provides functionalitiescommontodesktopenvironmentssuchastasknavigator,controlpanel,status bar,etc.HildonisbasedonGTK+andmakespartoftheGNOMEproject. TheMaemoSDKcontainstoolsrequiredtocreate,build,testandportapplicationsto Maemo platform. The base programming language is C, but it also supports C++ and Python through bindings and Qt. One important concept brought by the SDK is the Scratchbox. Scratchbox (http://www.scratchbox.org/) is a crosscompilation toolkit designed to make easiertheembeddedLinuxapplicationdevelopment.ThemaintaskofScratchboxistoenable compilationtoARMprocessorswhichareusedinInternetTablets.TodothisScratchboxuses acrosscompilerthatisabletocreatebinariestoaplatformdifferentfromtheonethatmakes thecompilation(ex.:createbinariesforARMfromanX86machine). QtisacrossplatformapplicationandUIframework.UsingQt,youcanwriteapplications once and deploy them across desktop, mobile and embedded operating systems without rewritingthesourcecode.QtfeaturesintuitiveC++classlibrary,portabilityacrossdesktopand embedded operating systems, integrated development tools with crossplatform IDE (in officially supported platforms), and high runtime performance and small footprint on embedded.Qt4.5isadaptedtoMaemo/Hildonandcurrentlyprovidedasacommunityport for Diablo and Fremantle (the 4.5.3 version of this is used in the in the Getting Started instructions in this document). Qt 4.6 will be officially supported in Maemo in Harmattan

MaemoforMobileDevelopers

whereallapplicationsarebuiltontopofQt.InOctober2009Nokiaalsoannouncedthatitwill officially support Qt 4.6 already in Fremantle as a technology preview, available at http://qt.nokia.com/developer/qtformaemodevelopers.

2 Maemocommunity
TheMaemoopencommunityhasover16.000registeredmembersthatcontributeto more than 700 development projects. It works with open source tools and processes. The communitymembersareabletodevelopnewsoftwareforboththeplatformitselfandontop oftheplatform.ApplicationsdevelopedwiththeMaemoSDKareusedtodaybythousandsof consumers. The community has a wide number of tools and services to easier the development processandkeepclosewiththecommunityneeds.Themostimportantare: Garage (https://garage.maemo.org/) which is meant for hosting software projectsrelatedtotheMaemodevelopmentplatform.Anydevelopercanhost Maemorelated projects in garage. Dont have an account? Create one here: https://garage.maemo.org/account/register.php. Planet Maemo (http://maemo.org/news/planetmaemo/) which is a blog hub forMaemodevelopers.Ifcancreateyourownblogandaggregatetothishub. Aggregate now! (http://maemo.org/news/planet maemo/aggregate_your_blog/) Maemo bug report (http://maemo.org/development/bugs/) enables developerstoreportproblemswiththeMaemoplatform. Maemo Feature Request (https://garage.maemo.org/tracker/?func=browse&group_id=29&atid=188) shows that Maemo is close to the community and wish to receive its contributionandopinion. Maemo extras repository (http://maemo.org/community/application catalog/extras_repository/) allows developers to host applications to be distributedtotheMaemousersdirectlyontheirdeviceswithnocostforthe developer. #maemo freenode (http://irc.netsplit.de/channels/details.php?room=%23maemo&net=freenode) is the Maemo IRC channel for developers to free talk about the platform, consultfriends,shareopinions,etc. Maemo Mailing lists (http://wiki.maemo.org/Community_mailing_lists) allows users,developers,communitytodiscussaboutMaemoplatform.Thefollowing listsareavailable: o maemoannounce(https://lists.maemo.org/mailman/listinfo/maemo announce)Newsandupdatesaboutmaemo.organdMaemo o maemousers (https://lists.maemo.org/mailman/listinfo/maemo users)ForMaemousers

MaemoforMobileDevelopers

o maemodevelopers (https://lists.maemo.org/mailman/listinfo/maemodevelopers) For Maemodevelopersandhackers o maemo community(https://lists.maemo.org/mailman/listinfo/maemo community) For maemo.org web and communityprocess related discussions o maemocommits (https://lists.maemo.org/mailman/listinfo/maemo commits)ForfollowingMaemosvncommitactivity ThepicturebelowshowsthemostimportantprojectsrelatedtotheMaemoplatform.

3 WhatMaemocando?
Maemo platform provides support for development that targets all the important technologiescategoriesrequiredformobiledevices.Themostimportantcomponentsforeach categoryaregivenbelow:

MaemoforMobileDevelopers

4 WhatsnewinMaemo5(Fremantle)?
Maemo5akaFremantleisthenewversionoftheMaemoplatform.Itbringsalotof newfeatures.Themostnoticeablearegivenbelow: Hardware o AcceleratedgraphicswithOpenGLES2.0 o OMAP3architecture o HSPA(HighSpeedPacketAccess/Cellular3Gconnectivity) o Highresolutioncamera o Accelerationsensor Baseservices o A2DP (Advanced Audio Distribution Profile) and AVRCP (Audio/Video RemoteControlProfile)foranimprovedBluetoothinteractions o Compositingwindowmanager Applicationframework o SuporttoQt4.5(acommunityportfromForumNokia) UI o NewUIstyle o AnimatedUItechnologies NewAPI's o Clutter:advancedandeasytousegraphicalAPI o LocationAPI:methodstobuildlocationawareapplications.

MaemoforMobileDevelopers

o CityInformation:methodstoobtaininformationaboutcities,including cityname,countryname,andcountrycode. o Timemanagement:aninterfaceforhandlingtimechangenotifications andcollectrelevanttimeandtimezoneinformation. o Vibrationservice:methodsfortriggeringandcontrollingvibrations. o Device orientation: respond to changes in orientation and discover currentorientation o Alarmservice TopframeworklevelchangesfromDiablo o RemovalofleftsideTaskNavigatorandplugins o Removalofstyluskeyboard o Newdesignfortaskswitchingandtaskhandling o RenewalofHomeandStatusbar o Newdesignforincomingeventpreviewsandindications o Widgetsandapplicationspacerenewal o UI style changes. E.g.: Navigation logic in applications, visual style of dialogs,menusetc Desktopchanges o Inhomescreenthereisonlyapplicationmenubuttonandapplets

o Applicationsarenowinapplicationsmenu o Biggericons

Newfilechooser MaemoforMobileDevelopers

o Kineticscroll

MaemoforMobileDevelopers

Chapter2 GettingstartedwithQt developmentonMaemo


1 MaemoSDKconcepts
TheMaemohardwarearchitectureisdifferentfromPCorMacarchitecture,asitisbasedon anARMprocessor.Thus,tocreateMaemoexecutablecodesusingaPCorMacmachine,we needacompilerthatrunsonthesemachinesandcompilescodesfortheARMarchitecture. Compilersthatdothisworkarecalledcrosscompilers. The Maemo Software Development Kit (Maemo SDK) contains Scratchbox. It is the base of Maemo SDK a toolkit, containing a crosscompiler and other tools, which creates a completeMaemodevelopmentenvironment.TheMaemoSDKemulatestheoperatingsystem onthedevice,butwithdevelopmenttoolsadded. TheMaemoSDKisofficiallysupportedonlyonDebianandUbuntuLinuxdistributions, butinstallingMaemoSDKisalsopossibleforotherdistributions.Onotheroperatingsystems such as Windows, a Virtual Machine can be used to provide a working Linux environment. Virtual Machines are software containers that can emulate a real machine and run one operatingsystemasifitwasinaphysicalcomputer.Thus,todevelopforMaemoinaWindows orMacmachine,itispossibletouseaVirtualMachinerunningLinuxwithMaemoSDK. DevelopingsoftwareusingtheMaemoSDKisquitesimilartousingaSymbianOSSDK. Youwrite,compile,andrunthecode,usuallyusinganIntegratedDevelopmentEnvironment (forexample,Carbide.c++forS60,VisualStudioforWindowsMobile,orESbox+Eclipseforthe Maemo platform). The Symbian OS SDKs include a phone simulator, which is a Windows executablecapabletorunSymbianOSsoftwareonanx86workstation.TheWindowsMobile SDK kit also includes similar phone emulators and is capable of running .NET Compact Frameworksoftware. TheMaemoSDKprovidesanemulatorinasimilarway,soitispossibletorunMaemo applicationsinsideit.TheMaemoSDKisquiteaccurateinemulatingtheenvironmentinareal device, but it isn't identical. Especially applications that make use of the device's special hardwarecanbehavedifferentlyonthedevicethanonMaemoSDK.Theyevenmaynotwork atall.Fortunately,testingthesoftwareondeviceisquitestraightforwardusingeitherSSH,SCP oratoolcalledsbrsh.Thesetoolsarecapabletoquicklycopyandrunyourapplicationonthe deviceduringthedevelopment. Qt is a crossplatform application and UI framework, which can be used on the Maemo platform together with Scratchbox, Maemo SDK, and Eclipse IDE (EsBox). The following

MaemoforMobileDevelopers

sectionsdescribethestepsthatyouneedtodoinordertosetupaQtforMaemodevelopment environment.

2 Installdevelopmentenvironment
2.1 InstallVMWare(WindowsOS/MACOS)
IfyouareworkingonamachinewiththeMicrosoftWindowsOperatingSystem,you canemulateaLinuxenvironmenttobeabletoworkwiththeMaemoSDK.Inprinciplevirtual machineisnotneededifyouuseLinuxasthenativeOSbuteventhenitispossibletousethe Maemo virtual image if you do not want to change your system installing the Maemo SDK packages.ToemulateaLinuxenvironmentyouneedtosetupavirtualmachinewhereyouwill installandruntheMaemoSDK.TheLinuxenvironmentemulatedcanbeavirtualimagepre configuredcontainingMaemoSDKwithallfilesandtoolsinstalled. Theseimages,availableat http://maemovmware.garage.maemo.org/, willhelpustogetafulldevelopmentenvironment easily. The basic difference between Windows and Mac is the virtual machine emulator that youwilluse.OnWindowsthevirtualmachineemulatorrecommendedisthe VMWareplayer (http://www.vmware.com/products/player/). On Mac the virtual machine emulator recommended is the VMWare fusion (http://www.vmware.com/products/fusion/). Another alternativeis VirtualBox(http://www.virtualbox.org/). TosetupVMwareimage: 1. Download and install the latest version of the virtual machine suitable for your operatingsystem(VMWareplayer,VMWarefusionorVirtualBox); 2. Onceyouhaveinstalledthevirtualmachineprogram,goto Maemo SDK VMware ApplianceanddownloadtheMaemoSDKvirtualimage.Thesevirtualimagescome withallfilesandapplicationsneededtodevelopforMaemo.Ifyougetanimage which comes in two parts (for example maemosdk_desktop_intrepid10 08.zip.001 and maemosdk_desktop_intrepid1008.zip.002), decompress it using 7-zip. To decompress on Windows, just right click over the file with .001 extensionandselect7zip>Extractfiles.OnLinux,navigatetothefolderwhere the.7zfile(s)arelocated(type"cd/path/to/folder"forexamplewithoutquotes) andrunthefollowingcommand:
$7z x FileName.001

3. Starttheinstalledvirtualmachineprogram; 4. Click Open button on the virtual machine program, navigate to the directory wheretheVMWareSDKpackageis,andchoosethe<maemoxxxx>*.vmxfile; 5. Click OK to launch the Linux virtual machine containing the Maemo SDK environment; 6. OncetheVirtualMachinestartsup,ifrequired,loginwith(username/password): maemo/maemo. 7. Once the Virtual Machine starts up, you should open a terminal and run the command:
$/scratchbox/login

MaemoforMobileDevelopers

8. NowthatyouareloggedintheScratchbox,youcancompileandrunprogramsfor Maemo.

2.2 InstallScratchbox
The Maemo SDK can be installed on operating systems considered native environments directly.ForLinuxoperatingsystem,theMaemoSDKinstallationisquiteeasy.Itcomeswith twoinstallationscripts: Scratchbox installer (http://repository.maemo.org/unstable/5.0beta/maemo scratchboxinstall_5.0beta.sh) scriptwhichdownloadsandinstallstherequiredversion ofScratchboxontoyourhostmachine; Maemo SDK installer (http://repository.maemo.org/unstable/5.0beta/maemosdk install_5.0beta.sh) which installs the SDK packages and sets up two targets (arm architectureandx86architecture)insideScratchbox.

MaemoSDKalsoprovidesessentialNokiaproprietarybinarypackagesneededforMaemo developmentfromanauthenticatedrepository.Inordertohaveaccesstothisrepository,you willneedtoaccepttheEndUserLicenseAgreement(EULA). ToinstallScratchboxfollowthestepsbelow: 1. GetScratchboxinstallationscriptfrom: http://repository.maemo.org/unstable/5.0beta/maemoscratchboxinstall_5.0beta.sh 2. Openaconsole; 3. Runthefollowingcommandwithrootpermission:


$sh maemo-scratchbox-install_5.0beta.sh

4. The installation script adds the current user to sbox user group. For the group membershiptobeeffectiveinthecurrentterminalsession,runthecommand:
$newgrp sbox

5. Addausernametoscratchboxbyexecutingthecommand:
$/scratchbox/sbin/sbox_adduser <username>

6. Addthegroupsboxtotheuserbyexecutingthecommand:
$groupadd sbox

2.3 InstallMaemoSDKandNokiabinaries
After Scratchbox installation you can install Maemo SDK. To do this, follow the steps below:

MaemoforMobileDevelopers

1. GetMaemoSDKFremantleinstallerfrom: "http://repository.maemo.org/unstable/5.0beta/maemosdkinstall_5.0beta.sh" 2. Openaconsole; 3. Runthecommand:


$sh maemo-sdk-install_5.0beta.sh

MaemoSDKneedsanX11servertoprovideadevicescreenforthedeveloperonthehost machine.TheX11serverusedtodothisworkistheXephyrX11 serversoftware.OnDebian based linux systems, Xephyr can be installed outside scratchbox environment using apt with rootpermission.Toinstall,justrunfollowingcommand:
$sudo apt-get install xserver-xephyr

NowyouareabletologintoScratchboxbyexecuting/scratchbox/login.Afterlogin,install NokiabinariesthatareessentialforthecompletefunctionalityoftheMaemoSDK. 4. Open this webpage (http://tablets-dev.nokia.com/eula/index.php) in your preferredbrowserandaccepttheEULA; 5. Follow the instructions in the next page to add one line to the file /etc/apt/sources.listinsideScratchboxforbothx86andARMELtargets; 6. Toinstallthenokiabinariespackages,executethesecommandsinsideScratchbox:
$apt-get update $fakeroot apt-get install nokia-binaries

7. Thiswillinstallnokiabinariesjustforonetarget.Toinstallontheothertargetrun the command sbmenu inside Scratchbox to change the target and run the commandsabove. 8. TheMaemoSDKisnowpreparedtoprovidealltoolstodevelopwithClanguage.If youwanttodevelopwithC++language,completetheinstallationbyrunningthe followingcommandinsideScratchbox:
$fakeroot apt-get install cplusplus-env libossomm-dev libhildonmm-dev libhildonmm maemo-

Now you would be able to compile and run C/C++ programs for Maemo (for more info, check this this website (http://maemo.org/development/sdks/maemo_50_installation/)). However,wecontinuewiththeinstallationofQtinnextsections.

2.4 InstallQtonScratchbox
NowthatwehaveinstalledScratchboxandMaemoSDK,wecaninstallQt.Wewillusethe communityportbasedonQt4.5.3. 1. ToinstallQtonScratchboxfollowthestepsbelow:

MaemoforMobileDevelopers

Openaterminalandrunthecommand:
$/scratchbox/login

2. Now edit the file /etc/apt/sources.list. At the moment of writing, the Qt for Maemo libraries were in the extrasdevel repository. To get it visible, add the Fremantleextradevelbyaddingthefollowingline:
deb http://repository.maemo.org/extras-devel/ non-free fremantle free

3. Runthefollowingcommandtoupdatetheaptcache:
$apt-get update

4. ToinstalltheQtbinaries,run:
$fakeroot apt-get install libqt4-gui

5. Toinstallthedevelopmentpackages,run:
$fakeroot apt-get install libqt4-dev

TheabovecommandinstallssomebasicUIpackages.ToinstallotherQtmodules,for exampleWebkitorOpenGL(ES2.0),youhavetorun:
$fakeroot apt-get install libqt4-webkit libqt4-opengl

3 CreateaQtproject
ThisapplicationcreatesalabelontheMaemoscreendisplayingtheHelloWorldstring.The followingcodeshowsthecontentofhello.cpp:
#include <QApplication> #include <QLabel> int main(int argc, char* argv[]) { QApplication app(argc,argv); QLabel *label = new QLabel("Hello World!"); label->show(); return app.exec(); }

4 Compiletheapplication
In order to compile your Qt Hello World application you need to login in the Scratchboxusingthefollowingcommand:
$ /scratchbox/login

MaemoforMobileDevelopers

Then,createafoldertoholdtheHelloWorldapplication.Todothisyoumayrunthe followingcommand:
$ mkdir /home/maemo/workspaceqt/hello

Copythehello.cpptothecreatedfolderandrunthefollowingcommandstobuild theapplication:
$qmake -project $ qmake hello.pro $ make

Thefirstcommandcreatesthefilehello.pro thatdefinesaQtproject.Itcontains thefilestobecompiled,librariestolinkwith,etc.FormoreinformationaboutQtprojectfiles go to qt projects file (http://doc.trolltech.com/4.1/qmakeprojectfiles.html#project templates)page.ThesecondcommandcreatestheMakefilefilewhichcontainsdirectives to compile the project. The last command compiles the project using the Makefile file creatingthe hello filewhichistheexecutable.The.pro fileoftheHelloWorldproject is shown below (Notice that the TARGET entry is not automatically filled by the qmake projectcommand):
# hello.pro TEMPLATE = app TARGET = hello DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += hello.cpp

5 Runtheapplicationontheemulator
5.1 StarttheSDKUI
FollowthesestepstostarttheMaemoSDK: 1. RunXephyroutsideScratchboxenvironment:
$ Xephyr :2 -host-cursor -screen 800x480x16 -dpi 96 -ac -kb &

2. InsideScratchbox,settheDISPLAYvariabletomatchthedisplaysettinggivenforthe Xephyrserverabove,sotheSDKcanfindtheXserverwindow
$ export DISPLAY=:2

3. Inside Scratchbox, initiate the UI framework (NOTE: a script o can be created on Linuxtorunthesecommandseasily.TakealookatHowtoCreateaFirstShellScript (http://www.linfo.org/create_shell_1.html))
$ af-sb-init.sh start

MaemoforMobileDevelopers

YouwillseethefollowingscreenonyourXephyrwindow:

5.2 Runtheapplication
WiththeMaemoSDKrunning,executetheHelloWorldapplicationwiththefollowing command.
$ run-standalone.sh ./hello

Afterthat,theHelloWorldapplicationwillstartontheXephyrwindow.

5.3 ClosetheSDKUI
Whenyoufinishthedevelopment,youcanstoptheMaemoSDKrunning:
$ af-sb-init.sh stop

MaemoforMobileDevelopers

6 Testtheapplicationonadevice
Toruntheapplicationorinstalldebianpackagesondeviceitisnecessarytocopythemto it.Thereisatleasttwowaystodothat.Thefirstway,consistsofusingPCconnectivityproject toconfigureaconnectionfromPCtothetabletthroughUSB,BluetoothorWLANconnections. ThesecondwayconsistsinconnectingmanuallythePCandtabletthroughWLANinterfaceof theInternettablet.First,youhoweverneedtoinstalltheQtpackagesonthedevice.

6.1 InstallQtpackages
BeforerunQtapplicationsondevices,theinstallationofsomeQtpackagesisrequired.At the moment of writing , Qt libraries were in the extrasdevel repository. To install packages, followthestepsbelow: 1. OpentheApplicationManagerinthedeviceandmakesureExtrasdevelisenabled(go tomenu>ApplicationCatalogue).IfthereisnoExtrasdevelcatalogueinthelistyou cancreateone.InsideApplicationsCataloguewindowpresstheNewbuttonandfill outthedialogboxthatappearwiththefollowinginformation: Cataloguename:Extrasdevel Webaddress:http://repository.maemo.org/extrasdevel Distribution:fremantle Components:freenonfree

2. Afterthis,pressSavebutton; 3. Openansshsessionwiththedevice:
PC_$> ssh root@DEVICE-IP

MaemoforMobileDevelopers

4. ToinstalltheQtbinaries,run:
#apt-get install libqt4-gui

5. ToinstallotherQtmodules,forexampleWebkit,DBusorOpenGL(ES2.0),youhaveto run:
#apt-get install libqt4-webkit libqt4-opengl libqt4-dbus

NOTE:TheQt4.5.3packagesareexpectedtobemovedunderExtrasrepositoryinnear future.

6.2 Deployapplicationtothedevice
6.2.1 InstallSSHonthedevice To communicate with a device, which allows install and run applications, the installationofanSSH(http://wiki.maemo.org/SSH)serverinthetabletisrequired.Todothis, opentheApplicationManagerinthedeviceandmakesureExtrasisenabled(gotomenu> Application Catalogue). If there is no Extras catalogue in the list you can create one. Inside ApplicationsCataloguewindowpresstheNewbuttonandfilloutthedialogboxthatappear withthefollowinginformation: Cataloguename:Extras Webaddress:http://repository.maemo.org/extras Distribution:fremantle Components:free

MaemoforMobileDevelopers

Afterthis,pressSavebuttonandthensearchforthepackageopensshserver.Install thepackagingselectingitfromthelist. 6.2.2 InstallPCConnectivity ThePCConnectivityprojectprovidestoolstoeasilysetuptheconnectionbetweenPC and the Internet Tablet. The connection can be done through USB, WLAN and Bluetooth. Installation instructions of PCconnectivity can be found http://pc connectivity.garage.maemo.org/installation.html.Detaileduserguidecanbefoundhttp://pc connectivity.garage.maemo.org/documentation.html. Note when installing the PC Connectivityalsotheopensshserverpackagewillbeinstalledonthedevice. 6.2.3 Copytheapplicationtothedevice NowyoucancopytheapplicationfromthePCtothefolder/home/userinthetablet.If youuseLinuxorMac,thedevelopercanusethescpcommandasshownbelow:
PC_$> scp filename root@DEVICE-IP:/home/user

IfyouuseWindowsyoucanuseWinscp(http://www.winscp.net/).Moreinformation abouthowtoconfigureWinscp,howtotransferfilesandhowtoexecutecommandscanbe foundhere:http://winscp.net/eng/docs/guides.

6.3 Runtheapplicationondevice
We can now run the application on the device. To execute the application run the followingcommandsintheshell.Thefirstcommandopensasshsessionwiththedevice.The next two commands gains privileges of super user and runs the application. If you are using

MaemoforMobileDevelopers

Winscpyouneedtoopenaterminal(selectCommands>Openterminal)andrunthelasttwo commands.
PC_$> ssh root@DEVICE-IP tablet_#> su - user tablet_$> run-standalone.sh ./hello

NotethattestinganapplicationonadevicewithoutaDebianinstallationpackagedoes notdetectanydependenciestolibraries.Alsotheapplicationcannotbethenrunonfromthe applicationshell.

7 CreateaDebianinstallationpackage
IntheSection6.3,"Runtheapplicationondevice"wealreadytestedthecompiledproject on the device. However, it is required to create a Debian installation package to enable installationanduninstallationwithdependencyhandlingandversioncontrol,andtocreatean application hierarchy (to, for example, copy data files into correct directories). Also you can defineapplicationiconandnamesothatuserscanlaunchtheapplicationfromtheapplication shell. The first step to create the debian package for a Qt application is to change the folder nameofyourproject.Thisisrequiredbythe dh_maketooltocreatethebasicstructureofthe package.Thenamingconventionacceptedbydh_maketoolis(ifdh_makeisnotinstalled,run aptgetinstalldh_make):
<project>-<version>

Change the Hello World project folder to helloworld-1.0. After this, run the followingdh_makecommandinsidetheprojectfoldertocreateabasicpackagestructure(run mandh_makeformoreinformation):
dh_make --createorig --single -e maintainer@email.org -c gpl

Thiscommandmakesacopyoftheoriginalsourcearchive(--createorig),setsthe packageclasstosingleapplication(--single),setsthemaintaineremailaddresstothegiven email(-e <e-mail>)andsetsthelicense(-c).dh_makecreatesthefolder debian/inside theprojectfolderwiththefilesneededtogeneratethedebianpackage.Themostimportant filesare:


debian/rules debian/control debian/copyright debian/compat debian/changelog

Thefollowingsectionsshowhowtodothemodificationsneededinthefilesinsidethe debian/folder.Also,itshowsthe.desktopfile,whichcontainsapplicationinformationsuchas name,icon,etc.thatareusedtoshowtheapplicationinMaemoUI.Next,thechangesneeded

MaemoforMobileDevelopers

inthe .profiletocopythe.desktopfileandiconfilestoMaemoareexplained.Attheend, thecommandstobuildandinstallthepackageareshown.

7.1 Edittherulesfile
This file is a Makefile which effectively run the commands to build the package, includingthesourcescompilation.Thedefaultfilegeneratedby dh_makedoesntknowhow tobuildQtapplications,sothefilehastobeupdatedtodothis.Thefollowingcodecontains theadaptationstotherulesfileneededtobuildaQtpackage.Theonlychangeyouneedtodo istheentry APPNAME.InthecaseoftheHelloWorldapplicationpackagethefileusedisthe following.
#!/usr/bin/make -f APPNAME := Hello builddir: mkdir -p builddir builddir/Makefile: builddir cd builddir && qmake-qt4 PREFIX=/usr ../$(APPNAME).pro build: build-stamp build-stamp: builddir/Makefile dh_testdir # Add here commands to compile the package. cd builddir && $(MAKE) touch $@ clean: dh_testdir dh_testroot rm -f build-stamp # Add here commands to clean up after the build process. rm -rf builddir dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/your_appname cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/$(APPNAME) install # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here.

NOTE: The empty space of each line should begin with TAB characters instead of multiple space characters. If you copy this chunk, you most probably get spaces insteadoftabsandthefilewillnotbecorrect.So,changespacesintoTABcharacters.

MaemoforMobileDevelopers

binary-arch: build install dh_testdir dh_testroot dh_installdocs dh_installexamples dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure

7.2 Editthecontrolfile
This file specifies package data like name, dependencies and description for both source and binary packages. To generate the package for Maemo, the following entries are important: Section: this entry is used by the Maemo Application Manager to select which packages it will show. By default the Application Manager shows only packages that belongtotheusersegment.Asaresult,theSectionentryshouldassumethefollowing form:
Section: user/SUBSECTION

whereSUBSECTION,mayassumeoneofthevaluesfromthetablebelow. Subsection Accessories Communication Games Multimedia Office Other Programming Support Themes Tools Keyword
user/accessories user/communication user/games user/multimedia user/Office user/other user/programming user/support user/themes user/tools

Maintainer:ThisfieldMUSTbechangediftheupstreampackagehasbeenmodified. XBMaemoIcon26:ItcontainsthePNGiconencodedinbase64visibleinthe ApplicationManager.ToencodesuchfilefromScratchboxdothefollowing:


apt-get update

MaemoforMobileDevelopers

apt-get install sharutils uuencode -m <name of 26x26 image> > <name of 26x26 image>.base64

ThecontrolfiletotheHelloWorldapplicationisshownbelow.Noticethatthereisaspacein thebeginningofeachnewlineofthesectionsDescriptionandXB-Maemo-Icon-26.
Source: my-application Section: user/valid_subsection Priority: optional Maintainer: name surname <xxxxxxx.xxxxxx@maemo.org> XSBC-Original-Maintainer: name surname <yyyyy.yyyyy@debian.org> Build-Depends: debhelper (>= 5), libqt4-dev, OTHERS_BUILD DEPENDECIES Standards-Version: 3.7.3 Package: my-application Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A simple test application A very simple application with a short description. Which spans multiple lines actually. XB-Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABmJLR0QA/wD/AP+g vaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gURDQoYya0JlwAAAU9J REFUSMftlL1KA0EUhb/NZl/ggnHQxsJUxt5CUucVJCCkDfgyKdIGG5/A0s5HEBtJ EdDAQGBgmw0YJmMzgXXYza5CtNkDW9zZw5z7c+ZCgwb/Ai3i9sVl/Bq8RIs4LRK1 gJDsKvJyNXmJMuYTsMoY1zpgozaABdYArQNPZQ1kfyGU7SpqVwxzAMwABWhgpIwp 4vWBB+AUWAI3ypjnfEXtPU4bLKx9vErTeCeiRSYF+fTn1j5dp2myE9EiU+DSi3wX ymeqRQAmZ3EcA5E/fgO6BULT8zhOcrwXoJdrXRa2Lgps2y2odAUcBUIXQdz78YyC SldAp8b7+bXrIv91qjZBietqCc2DjbAt4b2WxJkyZljVujlwp0U0cPxuLcAIuC+4 dKxFlsDJarvdAGP/b6hFnDImYs+uG3hbO2AB3Jbsur63tQM+fFx3bzZocEB8AdV2 gJBZgKTwAAAAAElFTkSuQmCC

7.3 Editthechangelogfile
Thisfiledescribesthechangesmadeineachpackageversion.Itisimportantbecauseit setstheversionnumbertobeusedwhenthecurrentpackageistobegenerated. IfanupstreampackageismodifiedforMaemo,theMaemorevisionstringshouldbe appendedtotheupstreamrevision.Forinstance,ifinDebiandistributionthepackagename was something like "Myapp0.42", in Maemo this package could be called "Myapp0.4 2maemo1".Thenumberafterthe"maemo"stringisaprogressivenumber.

7.4 Maketheapplicationvisibleinthemenuwitha.desktopfile
To make an application visible in Maemo menu, a Desktop file is needed for the application. If you dont want to do this you can skip this session and go straight to Section 7.6,"Build the package". This file contains all the essential information needed to show the applicationentryinthemenu,suchasname,iconlogicalname,applicationbinaryfilename, etc.Thenameofthefileshouldbe[application-name].desktop.ThelocationinMaemo filesystemshouldbe/usr/share/applications/hildon/. The desktop file is not generated by any tool, so it is necessary to create one. The followingexamplecanbeused.Justcopyandpastethefollowingcontenttothe src/folder ofyourQtproject.Ifyou donthavea src/folder,createoneandcopy the sourcecode to there.

MaemoforMobileDevelopers

[Desktop Entry] Encoding=UTF-8 Version=0.1 Type=Application Name=myapp Exec=/usr/bin/myapp Icon=myapp X-HildonDesk-ShowInToolbar=true X-Osso-Type=application/x-executable

7.5 Changethe.profile
AtthispointtheprojectfolderofyourQtapplicationshouldbesimilartothis:
helloworld-1.0/ src/ hello.cpp hello.desktop hello.pro

It is necessary to make some modifications to the hello.pro file. They will copy the .desktopfileandtheiconfiletotherightplaceinMaemowheninstallingtheapplication.To dothisyoujustneedtoappendsomelinestotheendofyour.profile.Theselineswillcheck therightplacetoputthe.desktopandtheiconsfile.Asitcanbeseen,the.desktopfilegoesto the applications/hildonandtheicongoesto pixmapand icons/hicolorfolder.The resultanthello.profileisshownbelow.
# hello.pro TEMPLATE = app TARGET = hello DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += hello.cpp # ----------------------------------------------------------------# Added section # ----------------------------------------------------------------unix { #VARIABLES isEmpty(PREFIX) { PREFIX = /usr/local } BINDIR = $$PREFIX/bin DATADIR =$$PREFIX/share DEFINES += DATADIR=\"$$DATADIR\" PKGDATADIR=\"$$PKGDATADIR\" #MAKE INSTALL INSTALLS += target desktop iconxpm icon26 icon40 icon64 target.path =$$BINDIR desktop.path = $$DATADIR/applications/hildon desktop.files += $${TARGET}.desktop

MaemoforMobileDevelopers

iconxpm.path = $$DATADIR/pixmap iconxpm.files += ../data/maemo/$${TARGET}.xpm icon26.path = $$DATADIR/icons/hicolor/26x26/apps icon26.files += ../data/26x26/$${TARGET}.png icon40.path = $$DATADIR/icons/hicolor/40x40/apps icon40.files += ../data/40x40/$${TARGET}.png icon64.path = $$DATADIR/icons/hicolor/64x64/apps icon64.files += ../data/64x64/$${TARGET}.png }

ItisalsoadvisedtoverifytheQtversion.Youcandothismovingthehello.profiletothe src folderandrenamingittosrc.pro.Thefollowingcommanddoesthis.


mv src/hello.pro src/src.pro

Thencreateanewhello.profileintheprojectrootfolder.
# hello.pro QMAKEVERSION = $$[QMAKE_VERSION] ISQT4 = $$find(QMAKEVERSION, ^[2-9]) isEmpty( ISQT4 ) { error("Use the qmake include with Qt4.4 or greater, on Debian that is qmake-qt4"); } TEMPLATE = subdirs SUBDIRS = src

7.6 Buildthepackage
Run the following command in the project root folder to generate the package. The generatedfilewillbecreatedinthefolderbeforetheprojectrootfolder.Makesureyouare compilinginFREMANTLE_ARMELtargettogeneratethepackagesuitableforthedevice.
$ dpkg-buildpackage -rfakeroot -b

MaemoforMobileDevelopers

7.7 Installthepackageondevice
Toinstallthegenerateddebianpackagetoadevice,copyittodevicelikedescribedinthe section6,"Testtheapplicationonadevice".Connectwiththedeviceusingsshantheninstall thedebianpackagebyrunningthefollowingcommandasroot: $sshroot@DEVICEIP #dpkgifilename.deb Ifthedesktopwascreated(asdescribedin7.4,"Maketheapplicationvisibleinthemenu witha.desktopfile")theapplicationwillappearinthemenu.

MaemoforMobileDevelopers

Chapter3 UsingESBoxIDE
Insteadofusingcommandline(showninChapter2,GettingStarted),itispossibleto create Qt applications for Maemo platform with an EclipseGanymedebased IDE, ESBox (http://esbox.garage.maemo.org/beta1/installation_update_site.html). ESBOXsupportsC/C++andPythonprogramminglanguageswithsourceediting,code completion,build,launch,debug,profiling,andpackaginggeneration. ESBox may be used on all major platforms (Linux, Win32, Mac OS X). On nonLinux systems,itispossibletouseaVirtualMachineoraremoteLinuxsystemtohosttheMaemo SDK.ESboxwilltranslateallIDEUIcommandstoSDKcommandsbehindthescenes.

1 Prerequisites
Here, you will learn how to prepare the environment to use ESBox. The environment needssomeprerequisites,whicharelistedbelow: Java1.5ornewer(http://java.com/en/download/manual.jsp) Cygwin(http://www.cygwin.com/)(onlyforwindows) PC Connectivity (http://pc connectivity.garage.maemo.org/beta1/documentation_usbnet.html) AVirtualMachinelikeQEMU,VirtualBoxorVMWare(http://www.vmware.com/)(only forwindows) AMaemoSDKvirtualimage(http://maemovmware.garage.maemo.org/)

TheJavawillbeusedtohostEclipse.TheCygwinwillbeusedtocreateansshserverunder Windows environment. The PC Connectivity will be used to easily configure of Cygwin ssh serverandtodeployapplicationstodevice.Thevirtualmachinewillbeusedtoruntheimage oflinuxcontainingtheMaemoSDK. There are two ways to install ESBox. The first way is to get the Full Product Archive of ESBox.ThesecondwayistouseEclipseUpdateSite. We will use the first way. If you want to install ESBox using Eclipse Update Site, see instructionsathttp://esbox.garage.maemo.org/beta1/installation_update_site.html. TheFullProductArchiveconsistsoftwoparts:onecommonarchivecontainingthebulkof the installation and an OSspecific archive. The first step is to get these two archives from https://garage.maemo.org/frs/?group_id=192. In our case, we will get the common file and thewin32file.Then,createanemptydirectoryandunzipbothfilesintothat.After,justrun esbox.exefromthecreateddirectory.

MaemoforMobileDevelopers

2 InstallandsetupESBoxonWindows
Now, we need a Linux virtual machine containing the Maemo SDK to allow ESBox to properly build the applications for Maemo. First get the VMware player from here: http://www.vmware.com/. Then, get a Maemo SDK virtual image from here: http://maemovmware.garage.maemo.org/. There are several Maemo SDK virtual images available. Some of them do not have Scratchbox and others need files installed. You can download one of those images and use the instructions in the section 2.2, "Install Scratchbox" or get an image that already has these applications and files installed. Now,followthestepsbelow: 1. OpentheESBox; 2. GotoWindow>Preferences>ESBox>BuildMachines;

3. SelectVMwareLinuxBuildMachineasbuildmachine; 4. BrowsetheVMwareplayerexecutableandbrowsetheMaemoSDKvirtualimage;

MaemoforMobileDevelopers

5. GotoMachineAccesstab;

6. You need to edit the address and port settings depending on your networking configuration.UsetheAutoselectNetworkSettingsbuttontotellESBoxtoguessthe networking settings from current virtual machine settings and the host machine's networkinterfaces.Checkthelogmessageshowntoseeifanyerrorhappened;

MaemoforMobileDevelopers

7. Note,whenconfiguringavirtualmachineusingBridgednetworking,it'simpossibleto guesstheactualaddressthemachinewillhave.Bydefault,ESboxselectsthenetwork address (*.0) and warns you to update it. To discover the ip address of Virtual Machine,justopenaconsoleandtypeifconfig; 8. GotoSharedFolderstabtoselectafoldersharedforhostandtarget;

9. Herewecanseethatwewillneedawindowssharedfolder.Itisrequiredtobevisible toboththeESBoxandtheVirtualMachine,soallprojectsneedtobestoredonapath sharedfromthehostandmappedtotheVirtualMachine. 10. GototheWindowsenvironmentandshareafolderofyourchoice; 11. IntheESBox,putthesharedfolderpathinallSharedpathfield; 12. Leaveallothersfieldsastheyare.

MaemoforMobileDevelopers

IfyouclickonApplyandValidateMachineorApplybuttonsyouwillprobablygetanerror. This is due to communication error. The ESBox and the Maemo SDK virtual image communicates among themselves using SSH. Usually, Windows dont come with any SSH server,then,theinstallationofansshserverisnecessary.

2.1 Installsshserver
WewilluseCygwintocreateansshserveronWindows.Touseit,followthestepsdescribed below: 1. GetCygwininstallationfilefromhttp://www.cygwin.com/; 2. In addition to the default Cygwin installation packages, install the latest versions for: cygrunsrv,nfsserver,openssh,xinit; 3. Get PC Connectivity from http://pc connectivity.garage.maemo.org/beta1/documentation_usbnet.html]andinstall. TheinstallationprocesswillconfigureandinitiateCygwinsshserverproperly.Nowyoucan back to ESBox Window > Preferences > ESBox > Build Machines and click on Apply and ValidateMachine.Ifallrunok,itwillpasscleanandsilent.Ifno,probablythetargetaddressis wrong.Tosolvethisproblem,gotovirtualmachine,openaconsoleatypeifconfigtogetthe correctnetaddress.BacktoESBoxandchangetargetaddress. For troubleshooting, see connectivity.garage.maemo.org/beta1/documentation_usbnet.html. http://pc

3 InstallandsetupESBoxonLinux
TorunESBoxonLinuxthefollowingprerequisitesareneeded:

MaemoforMobileDevelopers

Java1.5ornewer; ScratchboxandMaemoSDK.

To install Scratchbox and Maemo SDK you can use the instructions on the section 2.2, "InstallScratchbox".TheinstallationusingESBoxisquiteeasy.Todothis,firstinstallESBox. Here,therearealsotwowaystoinstallESBox.ThefirstwayistogettheFullProductArchive ofESBox.ThesecondwayistouseEclipseUpdateSite. We will use the first way. If you want to install ESBox using Eclipse Update Site, see these instructions(http://esbox.garage.maemo.org/beta1/installation_update_site.html). TheFullProductArchiveconsistsoftwoparts:onecommonarchivecontainingthebulkofthe installation and an OSspecific archive. The first step is to get these two archives fromhttps://garage.maemo.org/frs/?group_id=192 https://garage.maemo.org/frs/?group_id=192.Inourcase,wewillgetthecommonfileand the Linux file. Then, create an empty directory and unzip both files into that. After, just run ESBoxfromthecreateddirectory.AtthispointyouareabletoinstallScratchboxandMaemo SDKifyouhavenotdoneyet.

4 CompiletheapplicationonESBox
NOTE:ESBoxIDEdoesnthavenativesupporttodevelopQtapplications.Howeverit is fully integrated with Scratchbox. This makes the development easier since none command line execution is required to build and execute the application in the emulator.Thisisthemainadvantageofusingit. Eclipse (http://www.eclipse.org/) is an IDE for developing C/C++/Java applications. It providestoolsfordebuggingandbuildingapplications,amongvariousotherutilities.ESboxis anEclipseplugindesignedtomakeprojectdevelopmenteasierinMaemo. ESBox (http://esbox.garage.maemo.org/) runs inside Eclipse with CDT (C/C++ DevelopmentTools)installed.EclipseneedsaJavaVirtualMachinetorunproperly(Sun'sJava 6 or above is recommended). ESbox also needs Scratchbox targets to build and run Maemo projects. More information about installing ESBox can be found here: http://esbox.garage.maemo.org/installation.html. TheESBoxIDEinteractsdirectlywithScratchboxandMaemoSDK.Althoughitscurrent release doesnt have a proper perspective to develop for Qt, it can be used to develop Qt applications. Its main benefit is that it automatically configures the environment. The developerdoesntneedtodirectruncommandstobuildandruntheapplication. ThefirststeptobuildtheHelloWorldapplicationistoopenESBoxIDEandcreatean emptyC++Maemoprojectasitisshowninthepicturebelow.ThiscanbedoneselectingFile> New>C++MaemoProject.ThiswillopenthefollowingscreenwheretheoptionEmptyC++ Automake Project should be chosen (1). After this, the project should be configured setting the Project name and Build configurations (2). After this, the project is created and the

MaemoforMobileDevelopers

main.cppcanbeeditedtocontaintheHelloWorldQtcode(3).Seethepicturesbelowtosee

allthesesteps.

MaemoforMobileDevelopers

After this, it is necessary to create a Make target for Qt. To do this, click in the projectwithrightmousebuttonandselectCreateMakeTarget.Thefollowingdialogboxwill appear where the build command needs to be changed to compile a Qt project. The commands needed are the same as before: qmake project ; qmake ; make. You need to create two targets: the first one contains qmake project command and generates the .pro project file; the second contains qmake; make commands that are responsibleforbuildingtheapplication.

The last step is to remove some flags used to compile C++. As Qt uses a different build system (see http://doc.trolltech.com/4.2/qmakemanual.html) these flags dont need to be configured manually.TheseflagscanbefoundinProperties>Maemobuildconfigurations.Thefollowing pictureshowsthevariablestoberemoved.

MaemoforMobileDevelopers

NowtheprojectcanbecompiledselectingBuildMakeTarget.Ifitthefirsttimethe projectisbuiltthealltargetneedtobebuildtogeneratethe.profile.Oncethisfilehasbeen generated,thenextcompilationsonlyneedtobuildthebuildtarget.

4.1 RuntheapplicationonESBox
1. ClickontheXbuttonandselectstarttostartanXserver;

2. Ifyougetanerror,trytochangeCygwinpathsonWindow>Preferences>ESBox>X Serverasshownbelow;

MaemoforMobileDevelopers

3. ClickonthemaemobuttontostarttheMaemoSDKondeXserver;

MaemoforMobileDevelopers

4. Afterbuildingtheapplicationandstepsaboveitcanberunpressingtherightmouse buttoninthegeneratedbinaryfileandselectingRunAs>MaemoLocalApplication.

5 CreateaDebianinstallationfile
Todeployanapplicationtodevice,thedebianpackagegenerationisrequired.Todothis, followthestepsbelow: 1. RightclickontheprojectandselecttheDebianPackageoption;

2. SelectCreateDebianStructure;

MaemoforMobileDevelopers

3. Hereyoucanselecttheoptionsofyourchoice.Afterthat,clickFinishbuttonandthe debianstructurewillbecreated; 4. RightclickagainontheprojectandselectDebianPackage>BuildDebianPackage;

MaemoforMobileDevelopers

5. Selectthedesiredtarget.Youwillbepromptedtochoosethedestinationfolder.After that,the.debfilewillbegenerated;

6 Deploytheapplicationtothedevice
Follow the PC Connectivity installation instruction from http://pc connectivity.garage.maemo.org/documentation_usbnet.html to configure the connection betweenPCandinternettablet; 1. Right click the last time on the project and select Debian Package > Install Debian PackageonDevice;

MaemoforMobileDevelopers

2. Browse the created debian file, select the appropriated device connection and click Finishbutton; Ifallrunok,theapplicationwillbedeployedtothedevice.

MaemoforMobileDevelopers

Chapter4 QtforMaemo implementationnotes


QtisacrossplatformapplicationandUIframework.WithQt,thedevelopercancreate applications and run them in multiple platforms including desktops and mobile devices. The mostimportantfeaturesofQtare: IntuitiveC++classlibrary Portabilityacrossmultipleplatforms Highruntimeperformanceandsmallfootprintonembeddedsystems Completecollectionofcrossplatformlibraries

QtisanadditionalcomponentinMaemoplatform.InthelatestMaemorelease,called Fremantle the Qt libraries porting have been improved to provide better performance and enhancedplatformintegration.ThisincludesMaemoHildoncompatibilitywithHildonmenus, HildonstylesupportandHildoninputmenusupport.Also,FremantlebringsQtwithsupportto OpenglES2.0,WebkitandMysql,amongotherthings.MoreinformationaboutQtinMaemo can be found in at http://qt4.garage.maemo.org/. There are some reasons to support Qt in Maemo: QtisNokiacrossplatformtoolkit,madebyNokiaQtSoftware Sameapplicationswithnomodificationsorjustsmallchangescanbecompiledand run in S60 but also in Desktop Linux Macintosh, Windows and even Windows mobile UIneedstobetailoredtospecificdevicecharacteristicsandQtcansolvethisina straightforwardway

The following sections provide a quick, but detailed, guide to start developing applicationswithQtforMaemoplatform.

1 Platformspecificchanges
This session indicates the changes made in the standard Qt libraries needed to integrate then to Maemo platform concepts. For an extensive reference of standard Qt librariesgotohttp://doc.trolltech.com/.FremantleintegrationwithQtincludedadaptation for: HildonMenus Hildonstyle HildonInputmethods WidgetslikeQDialogandQMenu Qtpackages

MaemoforMobileDevelopers

Maemo Qt is based on Qt for X11. It shares the same API with no API breaks. Therefore,everyQtapplicationthatrunsinotherplatformsrunsinMaemo.So,theQtofficial documentation(http://doc.trolltech.com/4.5/index.html)canbeusedtodevelopapplications forQttoMaemo.However,thereversedoesntholdinallsituationsastherearesomesmall changesinMaemo.Thelistofchangesispresentedbelow. Storage Location: the function storageLocation of the class QDesktopServices receives StandardLocationasparameter.Belowthereisatablematchingeachparameter valueforthisfunctionwiththereturnedvaluewhenrunninginMaemo. StandardLocation
DesktopLocation DocumentsLocation PicturesLocation MusicLocation MoviesLocation

FolderinMaemo /MyDocs
/MyDocs/.documents /MyDocs/.images /MyDocs/.sounds /MyDocs/.videos

Inputevents:QInputEventsdoesntmovethecursoralongthescreen.Thisisdonethrough QInputMethodEvents.Thereasonforthisisthatwhentheuserhighlightsthetextfromright toleft,andthehighlightedtextiserased,thecursorwillremaininthelastcharinsteadofthe first. To do that some changes has been added to some widget function like inputMethodEvent(QInputMethodEvent *e). Modifyingthatfunctioninsomecustom widgetsmaybenecessary.Ifthesefunctionsarenotreimplementedsomefullscreenvirtual keyboardfeatureswillbebreak. AlsoQMainWindowhassomehardcodedkeys.Theyare: F6Togglefullscreentheapplication F4Shows/Hidestheapplicationcontextmenu ZoominisastandardkeysequenceQKeySequence::ZoomIn ZoomoutisastandardkeysequenceQKeySequence::ZoomOut Inputmethod:MaemoQtusesthe HildonIMasdefaultInputmethod.Eachkindofwidget can set the IM mode. This allows the input method to focus on the type of input that the application is expecting. For example, spin boxes can receive only numeric characters (19). Notice that Qt widgets like QTextEdit and QLineEdit set the right input method mode automatically.Adevelopercanchangetheinputmethodbyusing: void QInputContext::setInputMode(int mode); ThiswillupdatetheHildonInputmethodimmediatelytothefollowingmodes:

Inputmethodmode
HILDON_GTK_INPUT_MODE_ALPHA HILDON_GTK_INPUT_MODE_NUMERIC HILDON_GTK_INPUT_MODE_SPECIAL HILDON_GTK_INPUT_MODE_HEXA HILDON_GTK_INPUT_MODE_TELE HILDON_GTK_INPUT_MODE_FULL

Description alphabeticalcharactersandwhitespace numbers09andthe''character specialcharacters hexadecimalcharacters;numbers09,characters af,andAF telephonenumbers;numbers09,whitespace, andthecharacters"pwPW/().+*#?," unrestrictedentrymode,combinationofthe

MaemoforMobileDevelopers

alpha,numericandspecialmodes theclientcontainsmultiplelinesoftextor acceptslinebreaksintheinput HILDON_GTK_INPUT_MODE_INVISIBLE donotechoorsavetheinputintheIMwhen enteringsensitiveinformationsuchaspasswords HILDON_GTK_INPUT_MODE_AUTOCAP automaticallycapitalizethefirstletteratthestart ofasentence HILDON_GTK_INPUT_MODE_DICTIONARY enablepredictivedictionariesandlearningbased ontheinput
HILDON_GTK_INPUT_MODE_MULTILINE

Thecodesnippetbelowshowshowtosetuptheinputmethodforapasswordfield:
int mode = HILDON_GTK_INPUT_MODE_FULL|HILDON_GTK_INPUT_MODE_INVISIBLE; QInputContext qic = widget->inputContext(); qic->setInputMode(mode);

IfyouaredevelopingaCustomwidgetcapabletoreceiveinputtext,youcansetthewidgetto use the right input method mode just returning the mode identifier. If the Custom widget mode property is not set properly, the IM will use HILDON_GTK_INPUT_MODE_FULL (the defaultmode)forthatwidget. Settingtheinputmethodmodeisquiteeasy.Checkthecodebelowformoreunderstanding. Thecodesnippetbelowshowshowtodothis.
#ifdef Q_WS_HILDON #include <QInputContext> #endif QVariant QAbstractSpinBox::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QAbstractSpinBox); switch(query) { case Qt::ImMode:{ int mode = HILDON_GTK_INPUT_MODE_NUMERIC; return QVariant(mode); } default: return d->edit->inputMethodQuery(query); } }

QDialogs: TheFremantleWMdoesn'tallowQDialogswithoutaparent(atleastthisistrue

forQtapps).Adialogwithoutaparentwon'tbeshownbytheWM.Thecodebelowshouldbe avoided:
QColorDialog::getColor ( Qt::white, 0 );

Usethiscodeinstead:
QColorDialog::getColor ( Qt::white, this );

MaemoforMobileDevelopers

2 PortingaQtapplicationtoMaemo

Porting a Qt application from desktop environment to Maemo is really simple and requiresverylittleeffort.Inmostcasestheaboverelationistrue,becausethedeveloperonly needstorecompiletheprojecttoMaemousingtheSDK.TheMaemostyleandHildonlook& feel are implemented underneath so the developer doesnt need to take care of them. One example is the menu. The picture below shows a menu in desktop (smaller) and Maemo (bigger).

Althoughitmaybestraightforwardtoportanapplication,someguidelinesshouldbe followedtogetthebestportingoftheapplicationtoMaemo.Theseguidelinesareexplained below: Theusermayusefingerstointeractwiththeapplication,thismeanstheareaoftheUI elementsshouldtakethisintoaccount The virtual keyboard may appear on the screen when the focus is on some input widgets,sothedialogsshouldbearrangedtofitinsamescreen. AvoidtheuseofabsolutelayoutbecauseinMaemostyle,fontsandbuttonsaremuch largertobestfitthefingerinput If possible, avoid to wrap a group of widgets in a QScrollArea in order to fit then in yourdialogs

MaemoforMobileDevelopers

You can get more information about porting Qt application to Maemo here: http://wiki.maemo.org/Qt4_Hildon#Porting_a_Qt_application_to_Maemo.

3 UploadingtheapplicationtoGarage
MaemooffersaGarage(https://garage.maemo.org/)repositorywheredeveloperscan uploadtheirapplicationstobeavailableforallMaemousers.Therearetworepositoriesfor thirdpartyapplications:theextras-develandextras. extras-devel This repository is the first place for applications which are underdevelopment.Thisrepositoryisintendedtopackaging testingofalpha andbetareleasesofapplications.Itshouldbeusedbeforetheapplicationgets mature enough to go to extras repository. This repository is not recommended for regular usage since applications on it are usually unstable and may potentially break the system. You can add the extradevel in the tablet by opening the .install (https://garage.maemo.org/extras assistant/install/extrasdevel.install)linkfromit. extras This repository is the place to put 3rdparty applications that are stable and can be installed on internet tablets flawlessly. To upload an applicationtothisrepository,theapplicationshouldmeetsomerequirements that are stated at Extras Repository Process Definition (http://wiki.maemo.org/Extras_repository_process_definition). More information about extras repository can be found here: http://wiki.maemo.org/Extras_repository_process_definition.

Theuploadprocesstoextrasandextras-develrequiresanaccountatGarage web site. After the creation of this account you can upload your application to both repositories following the instructions found here: http://wiki.maemo.org/Uploading_to_Extras. After this, any Internet Tablet owner with the proper repository configuration can use the Maemo Application Manager search and install theapplications.

4 Links
Qtsoftwarehttp://www.qt.nokia.com/ Qt4maemohttp://qt4.garage.maemo.org/ Maemo5SDKhttp://www.forum.nokia.com/info/sw.nokia.com/id/c05693a1265c 4c7fa389fc227db4c465/Maemo_5_SDK.html Maemo5HildonReferenceManual http://maemo.org/api_refs/5.0/beta/hildon/index.html QtDocumentationhttp://doc.trolltech.com/ Maemotraininghttp://maemo.org/development/training/ ForumNokiaWikihttp://wiki.forum.nokia.com/index.php/Wiki_Home ESBoxhttp://esbox.garage.maemo.org/index.html

MaemoforMobileDevelopers

Chapter5 UsingMaemoAPIsinQt applications


1 Liblocation
Locationserviceshavebecomeacommonfeatureinmobileapplications.TheMaemoplatform provides a high level library called liblocation to allow applications to easily control and retrievedatafromtheGPS.ThelibraryprovidesmethodstostartandstoptheGPSdaemon, andallowstheapplicationtoregisteritselftolistenforGPSdatachanges,suchasfixstatus, satelliteinformation,position,speedandsoon. Itiscompletelydifferentthanthelibgpsmgr,whichisoneofthelibrariesusedtogetlocation informationintheDiablo.The packagecontainingliblocationbinariesistheliblocation0,but thepackageyoumustinstalltodevelopistheliblocationdev. At the moment, this library is only available for Maemo and it lies on the nokiabinaries repositoryforbothDiabloandFremantlereleases.Thelibrarydocumentedhereistheversion forFremantle,astheDiabloversionisalittledifferent. The package containing liblocation binaries is the liblocation0, but to develop applications using the lib, it is needed to install the package liblocationdev, as shown below (see this sectiontolearnhowtoaddnokiabinariesrepository):
$ apt-get install liblocation-dev

Thesummaryofthepackagecharacteristicsisshownbelow: Libraryname Packagename Developmentpackage Lastversionofthepackage Repositoryofthepackage liblocation liblocation0 liblocationdev 0.947+0m5 nokiabinaries

1.1 MainClassesandMethods
liblocationprovidestwoclassesandoneutilitymethodasdescribedbelow. 1.1.1 LocationGPSDevice The LocationGPSDevice class allows applications to register themselves to listen to GPS data changes.Threedifferentsignalscanbereceived:

MaemoforMobileDevelopers

changed:emittedwhenanydatahasbeenchanged; connected:emittedwhendevicemanagedtoconnecttothelocationserver; disconnected:emittedwhendeviceisdisconnectedfromthelocationserver.

Allsignalshavethesamefunctionsignature,asshownbelow: voiduser_function(LocationGPSDevice*device,gpointeruser_data) The example in the next session will show the code to register the functions to listen these signalswithg_signal_connect(). The LocationGPSDevice object received by the callback functions has public variables containingtheGPSdataprovidedbytheAPI.Thestructureasdefinedintheclassheaderfileis shownbelow:
typedef struct { gboolean online; LocationGPSDeviceStatus status; LocationGPSDeviceFix *fix; int satellites_in_view; int satellites_in_use; GPtrArray *satellites; LocationCellInfo *cell_info; } LocationGPSDevice;

The online flag keeps the connection status with the hardware. If it is TRUE, the GPS is connected. The status field is an enumeration with the GPS fix LOCATION_GPS_DEVICE_STATUS_FIXandLOCATION_GPS_DEVICE_STATUS_NO_FIX. Thesatellites_in_viewfieldisthenumberofsatellitestheGPSdevicecansee. The satellites_in_use field is the number of satellites used to calculate information about location,speed,andothers. The satellites field contains data about all found satellites. This is an array of structure LocationGpsDeviceSatellite,whichcontainssatellitedata.Thestructureasdefinedintheclass headerfileisshownbelow:
typedef struct { int prn; int elevation; int azimuth; int signal_strength; gboolean in_use; } LocationGPSDeviceSatellite;

status:

MaemoforMobileDevelopers

Thecell_infofieldisastructureoftypeLocationCellInfocontainingthefields_gsm_cell_info and wcdma_cell_info, which provides information about the mobile telephony cell that the device in connected. With more than one cell information, is possible to calculate the approximatelocation. The fix field is a structure of type LocationGpsDeviceFix, and is where the location informationlands.Itcontainslatitude,longitude,altitude,currentspeed,currentdirectionof motionindegrees,andotherinformation.Thestructureasdefinedintheclassheaderfileis shownbelow:
typedef struct { LocationGPSDeviceMode mode; guint32 fields; double time; double ept; double latitude; double longitude; double eph; double altitude; double epv; double track; double epd; double speed; double eps; double climb; double epc; } LocationGPSDeviceFix;

Themostimportantfieldsofthisstructureare: latitude:thelatitudecoordinatevalue. longitude:thelongitudecoordinatevalue. altitude:thealtitudeinmeters. speed:thecurrentspeedinkm/h. track:thecurrentdirectionofmotionindegrees(between0and359).

1.1.2 LocationGPSDControl This class is responsible for controlling the location service daemon (gpsd) running in the device.Thismeansthatitcanbeusedtostartandstopthelocationservices. Theclassimplementsthesingletonpattern,sotheapplication canholdonlyoneinstanceof the control class. To get the singleton object, use the function location_gpsd_control_get_default()asshownbelow: LocationGPSDControl*control; control=location_gpsd_control_get_default();

MaemoforMobileDevelopers

The application can start and stop the gpsd daemon with the methods location_gpsd_control_start()andlocation_gpsd_control_stop(),respectively. TheLocationGPSDControlemitsthreesignals: error:emittedwhenanerrorhasoccurred; gpsd_running:emittedafterthelocation_gpsd_control_starthasbeencalled.; gpsd_stopped:emittedafterthelocation_gpsd_control_stophasbeencalled. The application must create a function to connect to the signal. The function signature is shownbelow: voiduser_function(LocationGPSDControl*locationgpsdcontrol,gpointeruser_data) Here,locationgpsdcontrolistheobjectthatreceivedthesignalandtheuser_dataistheuser data set when the signal handler was connected. See the GObject documentation (http://library.gnome.org/devel/gobject/2.20/) to know how to connect a user function to a signal.

1.2 locationdistanceutils
The library also provides an useful function to calculate the distance on the surface of the earth between two points. This function is called location_distance_between() and can be usedlikeintheexamplebelow:
double distance; double latitude_s = -37.1443 double longitude_s = -7.2554 double latitude_f = -38.6554 double longitude_f = -6.5778 distance = location_distance_between(latitude_s, latitude_f, longitude_f);

longitude_s,

Thefunctionreceivesfourdoublevalues,whichrepresentsthelatitude/longitudecoordinates of two points. This function also returns a double value, which is the calculated distance in kilometersbetweenthetwopoints.

1.3 LiblocationExample
Inordertoarchiveabetterunderstanding,theexamplewasdesignedtohaveaverysimpleUI focusing more on liblocation functionalities. As shown onFigure 1, the UI is just a form that willhavethelocationdatavaluesupdatedbasedonliblocationevents.

MaemoforMobileDevelopers

Figure1LiblocationexampleUI. ThisexamplewaswrittenusingtheGTK+frameworkanduseslibrariesfromhildonframework to show a banner on the screen. The full example can be downloaded from [here]. The examplecodeisexplainedbelow.First,itisneededincludethefollowingheaderfiles:
#include <gtk/gtk.h> #include <hildon/hildon-banner.h>

The main() method initializes the GTK+ framework and call the methods to build the UI and setupthelocationAPI:
int main( int argc, char *argv[] ) { /* Initialise GTK */ gtk_init (&argc, &argv); setupUi(); setupLocation(); gtk_main (); stopLocation(); return 0; }

ThefunctionsetupUi()createstheGTKobjectsandbuildtheapplicationlayout.Firstitcreates the main window and connects its destroy signal to the gtk_main_quit() callback, so the applicationwillexitwhenclosebuttonispressed. Then, a GtkTable is created to organize the labels as a grid. The table here consists of two columnsandfiverowsasshowninFigure1. InordertochangethewindowbackgroundcoloraGdkColorobjectisinstantiated,havingits value defined right after by the gdk_color_parse() function that assigns the gray color for it. Finally,thegtk_widget_modify_bg()functionsetsthegivencolorasthebackgroundcolor.

MaemoforMobileDevelopers

The next statement adds the table widget to the window. In an effort to archive a better modularization,thisexampledefinesafunctiontoaddanewrowtothetableandinitializes theUIwithdefaultvalues. Finallygtk_widget_show_all()displaysallwidgetsonthewindow.
void setupUi() { GtkWidget *frame; GtkWidget *label; GtkWidget *eventBox; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_window_set_title (GTK_WINDOW (window), "LibLocation Example"); gtk_container_set_border_width (GTK_CONTAINER (window), 25); /* Create table */ table = gtk_table_new (4, 2, TRUE); gtk_table_set_col_spacings(GTK_TABLE (table), 20); gtk_table_set_row_spacings(GTK_TABLE (table), 10); GdkColor color; gdk_color_parse ("gray", &color); gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &color); gtk_container_add (GTK_CONTAINER (window), table); addRow(0, addRow(1, addRow(2, addRow(3, addRow(4, "GPS Status", "No Fix"); "Satellites in use", "0"); "GeoPosition", NULL); "Altitude", NULL); "Speed", NULL);

gtk_widget_show_all (window); }

TheaddRow()functionisdefinedasfollows:
void addRow(guint rowPos, const gchar *key, const gchar *value) { GtkWidget *label; GtkWidget *eventBox; GdkColor color; label = gtk_label_new (key); gtk_table_attach (GTK_TABLE (table), label, 0, 1, rowPos, rowPos + 1, GTK_SHRINK, GTK_SHRINK, 0, 0); setRowValue(rowPos, value); }

ThisfunctionaddsarowbyinstantiatinganewGtkLabelandattachingittothetable.Asthe laststepitcallsthesetRowValue:

MaemoforMobileDevelopers

void setRowValue(guint rowPos, const gchar *value) { GtkWidget *label; GtkWidget *eventBox; GdkColor color; label = gtk_label_new ( (value) ? value : " - " ); eventBox = gtk_event_box_new(); gtk_container_add (GTK_CONTAINER (eventBox), label); gtk_table_attach (GTK_TABLE (table), eventBox, 1, rowPos + 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK, 20, 0); } 2, rowPos,

NowthattheUIiscreated,thefunctionsetupLocation()willusetheliblocationtoregisterthe exampletoretrievelocationdata. Tousetheliblocationyoumustinclude thefollowingtwo headerfiles:


/*including header files*/ #include <location/location-gps-device.h> #include <location/location-gpsd-control.h>

Now, the setupLocation() function will use the classes LocationGPSDevice and LocationGPSDControl. It first gets the LocationGPSDControl object with the function location_gpsd_control_get_default() and starts it with the function location_gpsd_control_start(). This allows the example to control the GPS Daemon control startingtheGPSserviceinthedevice.Afterwards,theexamplecreatestheLocationGPSDevice objectandregisteritselftoreceivenotificationsaboutlocationdatachanges:
void setupLocation() { LocationGPSDControl* control; control = location_gpsd_control_get_default(); location_gpsd_control_start(control); LocationGPSDevice* device; device = g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL); g_signal_connect(device, G_CALLBACK(location_changed), NULL); g_signal_connect(device, G_CALLBACK(location_connected), NULL); g_signal_connect(device, G_CALLBACK(location_disconnected), NULL); } "changed", "connected", "disconnected",

When the connected and disconnected signals are received, the callback functions only showahildonbannertoupdatetheuseraboutthenewstate:
static void location_connected( LocationGPSDevice* device, gpointer userdata) { hildon_banner_show_information(GTK_WIDGET (window), "GPS Connected", "GPS Connected");

MaemoforMobileDevelopers

} static void location_disconnected( LocationGPSDevice* device, gpointer userdata) { hildon_banner_show_information(GTK_WIDGET (window), "GPS Connected", "GPS Disconnected"); }

On the other hand, when the changed signal is received, the UI is updated with the new data:
static void location_changed( LocationGPSDevice* device, gpointer userdata) { handleStatus( device->status ); handleSatellites( device->satellites_in_view, device>satellites_in_use, device->satellites); handleDeviceFix ( device->fix ); } The location_changed() method was divided into three procedures. The first two are as follow: static void handleStatus( LocationGPSDeviceStatus status ) { /* Handle Status Changed */ if (status == LOCATION_GPS_DEVICE_STATUS_NO_FIX) { setRowValue(0, "No Fix"); } else { setRowValue(0, "Fixed"); } } static void handleSatellites(int satellites_in_view, int satellites_in_use, GPtrArray *satellites) { /* Handle satellites in view */ gchar* numSatellites = g_strdup_printf("%i", satellites_in_use); setRowValue(1, numSatellites); g_free(numSatellites); }

ThehandleStatus()functionhandlesthestatusoftheGPSdeviceindicatingifithasconnected toenoughsatellitestocalculatetheposition.ThehandleSatellites()functionupdatestheUIto indicatethenumberofsatellitestheGPSdeviceisconnectedwith. Thelastfunction,handleDeviceFix(),issetoutbelow:


static void handleDeviceFix ( LocationGPSDeviceFix *fix ) { gchar* location = NULL; gchar* altitude = NULL; gchar* speed = NULL;

MaemoforMobileDevelopers

switch(fix->mode) { case LOCATION_GPS_DEVICE_MODE_NOT_SEEN: case LOCATION_GPS_DEVICE_MODE_NO_FIX: break; case LOCATION_GPS_DEVICE_MODE_3D: /* Testing if the altitude field of LocationGPSDeviceFix is valid. */ if (fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) { altitude = g_strdup_printf("%.2f m", fix->altitude); } case LOCATION_GPS_DEVICE_MODE_2D: /* Testing if the latitude and longitude fields of LocationGPSDeviceFix are valid. */ if (fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) { gchar latitude = (fix->latitude >= 0)?'N':'S'; gchar longitude = (fix->longitude >= 0)?'E':'W'; location = g_strdup_printf("%.2f %c\n%.2f %c", ABS(fix->latitude), latitude, ABS(fix->longitude), longitude); } break; } /* Testing if the speed field of LocationGPSDeviceFix is valid. */ if (fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) { speed = g_strdup_printf("%.2f Km/h", fix->speed); } setRowValue(2, location); setRowValue(3, altitude); setRowValue(4, speed); g_free(location); g_free(altitude); g_free(speed); }

This function formats the location, altitude and speed information retrieved from the LocationGPSDeviceFixstructure.IncaseofGPSdevicenotbeabletoseeanysatellitesnorfix, theoutputofthelocationwillbethedefault,. In case of being working on 2D mode (none altitude information), the function checks if the latitudeandlongitudesfieldsarevalidandformatstheoutputinsuchawaythatiflatitudeis negative, the letter S from South is shown followed by the absolute value of the location. It doesthesamewaywiththelongitude,applyinginsteadofStheletterWfromWest. If working on 3D mode, the function also checks if the altitude field is valid and sets the respectivefieldonUIinadditiontolongitudeandlatitude. Thelaststepistoreleasegcharresourcesbycallingtheg_free()function. ThereareotherlocationdataavailableintheLocationGPSDevicestructure.Youcanaccessthe othervaluesinthesameway.

MaemoforMobileDevelopers

1.4 Links
Liblocationreferencemanual:http://maemo.org/api_refs/5.0/beta/liblocation/ Pythonliblocation:http://brewer123.home.comcast.net/~brewer123/projects/nokia/ Usingliblocation: http://maemo.org/maemo_release_documentation/maemo4.1.x/node10.html#SECTI ON001027000000000000000 GPSJinniapplication:http://maemo.org/downloads/product/OS2008/gpsjinni/ libgpsmgrAPIreference:http://maemo.org/api_refs/4.1/libgpsmgr0.2/

2 Libcityinfo
ThelibcityinfoAPIcanbeusedtogetinformationaboutalargesetofcitiesaroundtheworld. TheinformationisstoredinASCIIformatdatabaseinsidethedevice.Thefollowinginformation canbeaccessedthroughlibcityinfoAPI: Cityname; Countryname(inwhichthecityisplaced); Countrycode; Timezone; Geographicalposition; Positiononthemapofclocksworldmapimage; Localeusedincountry.

2.1 Example
Thefollowingexampledisplaysthenamesofallcountriesavailableinthedatabase.The applicationalsocontainsafiltereditlinetofindthecountryname.Thelistisconstructedusing thefunctioncityinfo_get_all().TheQtclassQListWidgetisinheritedanditssubclasscreatesa slottoupdatethelistaccordingtothetypedstringintheeditline.Themostimportantclasses ofthisexampleAPIsare:libcityinfo,QListWidgetandQLineEdit.

MaemoforMobileDevelopers

Theexamplecontainstwosourcefiles(main.cppandQCityInfoWidget.cpp)andoneheader (QCityInfoWidget.h).TheQCityInfoWidgetclassisderivedfromQListWidget.Thesourcecode isshownbelow.


//QCityInfoWidget.h #ifndef QCITYINFOWIDGET_H #define QCITYINFOWIDGET_H #include <QListWidget> class QCityInfoWidget : public QListWidget { Q_OBJECT public: QCityInfoWidget(); public slots: void findSearchedString(const QString& searchString ); }; #endif // QCITYINFOWIDGET_H // QCityInfoWidget.cpp #include <cityinfo.h> #include "QCityInfoWidget.h" QCityInfoWidget::QCityInfoWidget(): QListWidget() { Cityinfo** cityArray = cityinfo_get_all(); for (int i = 0; cityArray != NULL && cityArray[i] != NULL; ++i) { addItem( QString(cityinfo_get_country( cityArray[i] )) ); } } void QCityInfoWidget::findSearchedString( const QString& searchString ) { QList<QListWidgetItem *> listItem = findItems ( searchString, Qt::MatchStartsWith ); if( listItem.count() > 0 ) { scrollToItem( listItem[0] ); } }

Theclassdefinesapublicslot(findSearchedString)tobeconnectedwithasignalfromthe QLineEditclass.Thisslotisusedtoscrollthelisttotheitemthatstartswiththestringtypedof thebox.

MaemoforMobileDevelopers

IntheconstructoroftheQCityInfoWidget,thelistispopulatedwiththecountrynamesusing theaddItem()methodofthesuperclass.Theregistriesareaccessedusingthecityinfo_get_all() call.Thecountrynamesarethenaccessedthroughthefunctioncityinfo_get_country(). Themainfiledefinesthelayoutofthescreen.Inthisexample,thegraphicalelementsare displayedhorizontallyorvertically.Thus,QHBoxLayoutandQVBoxLayoutareusedasscreen layouts. Onmainmethod,theslotoftheQCityInfoWidgetclassisconnectedwithQLineEdit textChangedbyusingQObject::connect.Themain.cppsourceisshownbelow:


#include #include #include #include #include #include <QApplication> <QLineEdit> <QLabel> <QHBoxLayout> <QListWidget> <QHeaderView>

#include "QCityInfoWidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; window.show(); QLabel *queryLabel = new QLabel(QString("Filter:")); QLineEdit *queryEdit = new QLineEdit(); QCityInfoWidget* listWidget = new QCityInfoWidget(); listWidget->setSelectionMode(QAbstractItemView::MultiSelection); QObject::connect(queryEdit, SIGNAL(textChanged ( const QString&) ), listWidget, SLOT(findSearchedString( const QString& ))); QHBoxLayout *queryLayout = new QHBoxLayout(); queryLayout->addWidget(queryLabel); queryLayout->addWidget(queryEdit); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout(queryLayout); mainLayout->addWidget(listWidget); window.setLayout(mainLayout); return app.exec(); }

Andthe.profile:

MaemoforMobileDevelopers

TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . /usr/include/glib-2.0/glib /usr/include/glib-2.0/ /usr/lib/glib-2.0/include LIBS += -lcityinfo0 -lglib-2.0 # Input HEADERS += QCityInfoWidget.h SOURCES += main.cpp QCityInfoWidget.cpp

3 mcedev
SomeMaemoapplicationsoftenneedtogetinformationaboutthedevicemode.Forexample, an application needs to know if device is on offline mode in a meeting time and, if not, the devicemodeshouldbechangedtothecorrectone. Maemo development environment provides mechanisms to manage the device mode. It provides the Mode Control Entity, which manages the device mode. In addition, Maemo development environment provides DBus interfaces to the Mode Control Entity, so the developercaneasilyuseitonhisapplication.Itmeansthatthedevelopercancontrolorget information about device mode through DBus messages. For example, the developer can querytheinactivitystatusorrequesttoblankthescreen. The package which contains mce development files is the mcedev package. It is required to installsuchpackageonyourdevelopmentenvironmenttouseMCEDBusinterfaces.However, bothDiabloandFremantlecommonlyhaveMCEdevelopmentpackagesalreadyinstalled. Toinstallmcedevfiles,usethefollowingcommand(seethissectiontolearnhowtoadd nokiabinariesrepository):
#apt-get install mce-dev

Thesummaryofthepackagecharacteristicsisshownbelow: Libraryname Packagename Developmentpackage Lastversionofthepackage Repositoryofthepackage mce mcedev mcedev 1.6.3 fremantle/sdkfree

MaemoforMobileDevelopers

The MCE defines two header files that can be used in the development process: dbus names.h and modenames.h. The dbusnames.h file contains names definition required tosendmessagesthroughDBus(itwillbeexplainedindetailslater).Themodenames.hfile containsnamesdefinitionofmodesandstates.

3.1 MCEheadersfiles
Thedbusnames.hheaderfilecontainsMCEservicename,pathsandinterfacesrequiredto createaproxyobjectfortheDBusdriver.Theyaresummarizedonthefollowingtable: Macro MCE_SERVICE MCE_REQUEST_IF MCE_SIGNAL_IF MCE_REQUEST_PATH MCE_SIGNAL_PATH Notethatnamesforsignalandforrequestsarelistedabove.Theservicenameisthesamefor both,buttheinterfaceandthepathdiffersfromeachother. File dbusnames.h also defines names for MCE DBus methods and MCE DBus signals. The MCE DBus methods names are used to request changes in the device mode or query for information.TheDBussignalsnamesarethenamesusedtogetconnectedwithasignaland observechangesondevicemode. File modenames.h contains current values for Internet Tablet mode. These modes are returned by methods used to query about device mode, for example the method "get_device_mode".ExistingInternetTabletmodesaresummarizedonthefollowingtable: Macro MCE_NORMAL_MODE MCE_FLIGHT_MODE Value "normal" "flight" Description Normaldevicemode Offlinedevicemode; RF'sdisabled Offlinedevicemode; RF'sdisabled;aliasfor flightmode invaliddevicemode; thisshouldneveroccur Value "com.nokia.mce" "com.nokia.mce.request" Description MCEDBusservice MCE DBus interface Request

"com.nokia.mce.signal" "/com/nokia/mce/request" "/com/nokia/mce/signal"

MCEDBusSignalinterface MCEDBusRequestpath MCEDBusSignalpath

MCE_OFFLINE_MODE

"offline"

MCE_INVALID_MODE

"invalid"

MaemoforMobileDevelopers

3.2 Qtmcedevexample
MCE API for Maemo only provides a DBus interface, which consists of methods and signals. Thus, in order to use MCE, DBus is required. In this section, one example is used to demonstrate how MCE can be used on Qt applications. This example does a simple MCE methodcallandalsolistenstoaMCEsignal.Thefullexamplewillbeavailablefordownload later. The example contains a button and a label. When button is pressed, the screen becomes totallyblanked.WesimplychangethestateofInternetTabletdisplaytoOFF,byusingmethod "req_display_state_off"ofMCEAPI.Thisexamplealsoconnectsafunctiontoasignal.Inthis case,thefunctioniscalledwheneverdevicemodeischanged(normal,flight,offlineor invalid).Inaddition,thisexamplealsochangesthetextofalabelwidget. Thisexamplehastwofiles:mce_example.cppandmce_example.h.Themce_example.h file is shown below. This file contains declarations of a class, variables, slots, and a method. TheclassinheritsfromQWidget,whichisrequiredtocreateQtGUIapplications,andthenthe QWidgetheaderfilemustbeincluded.Slotsaredeclaredinthisfileaswell,sotheQ_OBJECT macromustbecalledandtheQObjectheaderfilemustbeincluded. Twoslotsaredeclaredintheclass:cb_funcandbutton_callback.Thecb_funcslotisconnected to the signal emitted when the mode of the device is changed. The button_callback slot is connected to the signal emitted when the button is clicked. The method connect_to_mce is usedtoconnectthecb_funcslottoaMCEsignal.
#ifndef QT_SIGNAL_H #define QT_SIGNAL_H #include <QObject> #include <QDBusMessage> #include <QWidget> class MCEExample : public QWidget { Q_OBJECT public: MCEExample(QWidget *parent = 0); ~MCEExample(); public: void connect_to_mce(); public slots: void cb_func(const QDBusMessage& rep); void button_callback(); }; #endif // QT_SIGNAL_H

Themce_example.cppfilecontainstheimplementationoftheclassandmethodsdeclaredin the mce_example.h header file. At first, the required header files are included. The

MaemoforMobileDevelopers

QApplication,QLabel,QPushButton,andQVBoxLayoutfilesareusedtocreatetheQt QUI. The QDBusInterface, QDBusConnection and mce/dbusnames.h files are used to createaconnectiontoaDBussignalandaremotecalltoaMCEmethod:
#include #include #include #include #include #include #include #include <mce_example.h> <QApplication> <QLabel> <QPushButton> <QVBoxLayout> <QDBusInterface> <QDBusConnection> <mce/dbus-names.h>

Two variables are declared as static because they are used in more than one method in the code.Theconnectionvariableisusedinthebuttoncallbackfunctionandthelabelvariableis usedinthefunctionconnectedtotheMCEsignal:
static QDBusConnection connection = QDBusConnection::systemBus(); static QLabel *label;

Theconstructoroftheclassisshownbelow.Here,abuttonandalabelarecreated:
MCEExample::MCEExample(QWidget *parent): QWidget(parent){ label = new QLabel("Device mode :"); QPushButton *button = new QPushButton("Blank screen"); connect(button, SIGNAL(clicked()), this, SLOT(button_callback())); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(label, 0, Qt::AlignHCenter); layout->addWidget(button); setLayout(layout); }

Thesignalemittedwhenthebuttonispressedisconnectedtothemethodbutton_callback(), whichisshownbelow.Inthismethod,aQDBusInterfaceiscreatedanditisusedtomakethe calloftheremoteMCEmethodMCE_DISPLAY_OFF_REQ,whichrequeststhedevicetochange itsscreenstatus:


void MCEExample::button_callback() { QDBusInterface mce_if(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, connection); mce_if.call(MCE_DISPLAY_OFF_REQ); }

The following method is used to connect the method cb_func() to the MCE signal MCE_TKLOCK_MODE_SIG,whichreturnsthedevicemode:
void MCEExample::connect_to_mce() { connection.connect(MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF, MCE_TKLOCK_MODE_SIG,

MaemoforMobileDevelopers

this, SLOT(cb_func(const QDBusMessage&))); }

Thecb_func()methodonlyreceivesthemodenameandsetittothelabel:
void MCEExample::cb_func(const QDBusMessage& rep) { label->setText("Device mode :" + rep.arguments().value(0).value<QString>()); }

The main function is shown below. It creates the application, creates an instance of MCEExampleandstartstheapplication:
int main(int argc, char* argv[]){ QApplication app(argc,argv); MCEExample example; example.call_remote_method(); example.show(); return app.exec(); }

Finally,tocompilethisexample,includetheqdbusnametotheCONFIGkeyinthe.profile:
CONFIG =+ qdbus

Torunthisapplicationondeviceyouwillneedtoinstallqtguiandlibqtdbus.Ascreenshotof theapplicationisshownbelow:

4 Calendarbackend
TheCalendarbackendlibraryallowsthedevelopertomanagecalendarsandevents.Such libraryprovidesaC++APItocreateacalendarandaddevents,birthdays,journal,ortodos, includingattendeesandorganizers.

MaemoforMobileDevelopers

AllthecalendardataisstoredintheSQLite(http://www.sqlite.org/)databaseofthedevice. TheCalendarbackendlibraryprovidesmechanismstointeractwithdatabasebyusing methodsimplementedbyCCalendarDBclass.Thislibraryalsointeractswithalarmdaemon anditstoresthealarmdatainthelocalcalendardatabaseusingCAlarmclassmethods. CalendarbackendisaclosedlibraryanditisavailableonNokiabinariesmetapackage. Therefore,itisnecessarytoconfigureNokiabinarieslocalrepositorytoinstallit. ThefirstimplementationofthislibrarywasintheFremantle.Thepackagecontainingcalendar backendlibrariesisthecalendarbackend,andthefilesneededtodevelopapplicationsarein thepackagecalendarbackenddev.ToinstallCalendarbackendpackagesonyour environment,executethefollowingcommands:
# apt-get install calendar-backend # apt-get install calendar-backend-dev

Thesummaryofthepackagecharacteristicsisshownonthefollowingtable: Libraryname Packagename Developmentpackage Lastversionofthepackage Repositoryofthepackage Calendarbackend calendarbackend calendarbackenddev 0.58.12+0m5 nokiabinaries

4.1 MainClassesandMethods
Thecalendarbackendlibrarycontainsseveralclassesthathelpthedevelopertocreate calendarandaddevents.ThemostimportantclassesareCMulticalendar,CCalendar,andthe classesderivedfromCComponent. TheCMulticalendarclassisthemainelementtoaccessthecalendarbackend.Onlyone instanceofCMulticalendarisallowedperprocess.TheinstanceofCMulticalendarcanbe retrievedbyusingthestaticmethodMCInstance().OnceyouhaveaccesstoCMulticalendar instance,itispossibleto: addacalendarwiththemethodaddCalendar(); deleteacalendarwiththefunctiondeletCalendar(); getacalendarbynameorbyIDusingthefunctionsgetCalendarByName()and getCalendarById()respectively. However,beforeaddingacalendartotheCMulticalendar,youhavetocreateaCCalendar.This classallowsthedevelopertoadd,modifyordeletecomponentssuchasevent,todos, journalorbirthdays.ItispossibletosetthenextalarmeventwiththemethodsetNextAlarm().

MaemoforMobileDevelopers

TheCCalendartypecanbesettoLocalcalendar,SynccalendarorSmartcalendarbyusingthe methodsetCalendarType().ThecurrentCCalendartypecanbeobtainedbymethod getCalendarType(). Thecomponents,whichcanbeaddedtothecalendar,inheritfromtheclassCComponent.This classcontainsmethodstogetorsetparametersforanyevent,todo,journalorbirthday.For example,thedevelopercansettheIDofthecomponentbyusingthemethodsetId(). Theeventtypethatcanbeaddedtothecalendarare:CBdayEvent,CEvent,CJournal,and CTodo.Eachoftheseclasseshasasetofcommonmethodsinheritedfromthebaseclass CComponentandtheyhavetheirownspecificmethods.Forexample,theCEventclass providesmethodmethodsetGeo()thatallowsthedevelopertosetthelocation(latitudeand longitude)parameter.OtherexampleistheclassCBdayEvent,whichallowsthedeveloperto setthebirthdatebyusingmethodsetBirthDate(). CalendarbackendlibraryalsocontainstheclassICalConverter,usedtoconvertlocaldatabase formattoiCal(http://www.apple.com/support/ical/)dataandviceversa.VCalConverteris otherclasswhichconvertslocaldatabaseformattootherformat.Thisclassconvertslocal databaseformattovCalformatandviceversa. Youcanfoundmoreinformationaboutotherclasses,suchasCCalendarDB,onAPIreference ofcalendarbackend(http://maemo.org/api_refs/5.0/beta/calendarbackend/index.html).

4.2 Example
Theexampleusedinthissectionisasimplecalendar.ItisimplementedinQtanditalsouses theCalendarbackendAPI.Theexamplemanagesacalendarsuchastheoneillustratedonthe followingpictures:

Aftercreatingacalendar,theapplicationallowsthemanagementofevents:

MaemoforMobileDevelopers

Theevents,todosorbirthdayscanbevisualized.Itispossibletocreatenewelementsaswell:

Theexamplecontainsthefollowingfiles(availablefordownloadlater): main.cpp:createstheQtapplicationandinitializescalendarwidget; widget.h:containsdeclarationofnamesandmethodstobeimplementatedon widget.cppfile; widget.cpp:implementsofmainscreen; eventdialog.h:containsdeclarationofnamesandmethodstobeimplementatedon eventdialog.cppfile; eventdialog.cpp:implementseventcreationscreen; calendar.h:containsdeclarationofnamesandmethodsusedoncalendar.cppfile; calendar.cpp:direcltyaccessesCalendarbackendAPI.

Thecontentoffilecalendar.hisshownbelow.ThisfiledeclaresclassCalendar,including variablesandmethods.ThisclassinheritsfromQObject,whichisthesuperclassforallQt applications.Then,itisnecessarytoaddQObjecthearderfile.Inthisapplication,thedateand thetimearemanagedinsomefunctions,thusQDateTimeheaderfilemustbeincludedtoo.

MaemoforMobileDevelopers

Thisheaderfilealsocontainsthedeclarationoffivemethods:addCalendar,removeCalendar, addEvent,getEventsDays,andgetEventsDescription.
#ifndef CALENDAR_H #define CALENDAR_H #include <QObject> #include <QDateTime> class CCalendar; class CMulticalendar; class CComponent; class Calendar : public QObject { Q_OBJECT public: Calendar(); ~Calendar(); public: bool addCalendar(const QString& calendarName); bool removeCalendar(const QString& calendarName); void addEvent(const QString& calendarName, const QDateTime& date, const QString& eventName, const QString& description, int type); /* Returns a list of dates that have events.*/ QList< QDate > getEventsDays(const QString& calendarName, int type, const QDateTime& startDate, const QDateTime& endDate); /* Returns a list of events descriptions.*/ QList<QString> getEventsDescription(const QString& calendarName, int type, const QDateTime& date); private: CMulticalendar* multiCalendar; }; #endif // CALENDAR_H

Thecalendar.cppfilecontainstheimplementationofthefunctionsdeclaredintheheader fileCalendar.h.Atfirst,inserttherequiredheaderfiles(calendar.h,CCalendar.h,etc.).These filesprovidemethodstomanagecalendars,multicalendars,events,todos,andbirthdays:


#include "calendar.h" #include <CCalendar.h>

MaemoforMobileDevelopers

#include #include #include #include

<CMulticalendar.h> <CTodo.h> <CBdayEvent.h> <CEvent.h>

ThevariableDAY_IN_SECONDSisdeclaredtobeusedinsomemethods:
static const int DAY_IN_SECONDS = 86400;

InCalendarclassconstructor,asingleinstanceofaCMulticalendarisretrievedbyusingthe methodMCInstance()ofCMulticalendar:
Calendar::Calendar() { multiCalendar = CMulticalendar::MCInstance(); }

ThedestructordeletestheCMulticalendarinstance:
Calendar::~Calendar() { delete multiCalendar; }

ThemethodaddCalendaraddsacalendartotheCMulticalendarinstance.Thisfunction receivesastringrepresentingthecalendarnametobeadded.Toaddacalendar,themethod addCalendar()ofCMulticalendarmustbeused.Thismethodreceivesthefollowingparameters insequence:calendartitle,color,flagforreadonly,flagforvisible,type(0forLocalcalendar,1 forSynccalendaror2forSmartcalendar),thetunewhichwillbeplayedinalarms,stringfor calendarversion,andthereferencetotheerrorcode.Whenanerroroccurs,thevalueofthe errorCodeissetto0:


bool Calendar::addCalendar(const QString& calendarName) { CalendarType type = (CalendarType) 0; int errorCode = 0; multiCalendar->addCalendar (calendarName.toStdString(), COLOUR_RED, 0, 1, type , "Default", "0.1", errorCode); return (errorCode); }

ThemethodremoveCalendar()isusedtoremoveacalendarfromtheCMultiCalendarinstance. Thismethodreceivesthenameofthecalendartoberemovedandusesthemethod deleteCalendar()ofCMultiCalendartodeletethecalendar.ThemethoddeleteCalendar() receivesacalendarIDandareferencetoerrorcode.TogetthecalendarID,acalendar instanceisrequired.TheCMultiCalendarallowsthedevelopertogetaninstanceofCCalendar byusingthemethodgetCalendarByName(),whichreceivesthenameofthecalendaranda

MaemoforMobileDevelopers

poiterstoerrorcode.Then,theIDofthecalendarcanbeobtainedwiththemethod getCalendarId()ofCCalendar.
bool Calendar::removeCalendar(const QString& calendarName) { int errorCode = 0; bool success = false; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); if (errorCode) { success = multiCalendar->deleteCalendar (calendar>getCalendarId(), errorCode); } delete calendar; return success; }

ThemethodaddEvent()addanevent(todo,birthdayorevent)toacalendar.Thismethod receivesfourparameterswhichare:thenameofthecalendarinwhichtheeventwillbe added,thedateoftheevent,thenameoftheevent,thedescriptionofeventandthetypeof event,whichshouldbe0fortodo,1forbirthdayand2forevent.Themethodsusedtoadd eventsareaddTodo(),addBirthDay(),oraddEvent()fromCMultiCalendar.Thesemethods receiveaninstanceofCTodo,CBdayEvent,orCEventrespectively.Eachoftheseclasses receivesinconstructorthesummaryoftheevent,theduedateand,insomecases,thestatus. Thepossiblevaluesforstatusare:NEEDSACTION_STATUS,COMPLETED_STATUS, INPROCESS_STATUS,CANCELLED_STATUS,CONFIRMED_STATUS,TENTATIVE_STATUS, DRAFT_STATUS,FINAL_STATUS,SENT_STATUS,DECLINED_STATUS,DELEGATED_STATUS,or ACCEPTED_STATUS.
void Calendar::addEvent(const QString& calendarName, const QDateTime& date, const QString& eventName, const QString& description, int type) { int errorCode = 0; int dateUtc = date.toTime_t(); CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); switch (type) { case 0: { CBdayEvent *pBdayEvent = new CBdayEvent(eventName.toStdString(), eventName.toStdString(), dateUtc); calendar->addBirthDay(pBdayEvent, errorCode); delete pBdayEvent; } break; case 1: { CEvent *pEvent = new CEvent(eventName.toStdString(), description.toStdString(), "", dateUtc, dateUtc);

MaemoforMobileDevelopers

multiCalendar->addEvent(pEvent, calendar->getCalendarId(), errorCode); delete pEvent; } break; case 2: { CTodo *pTodo = new CTodo(eventName.toStdString(), dateUtc, ACCEPTED_STATUS); multiCalendar->addTodo(pTodo, calendar->getCalendarId(), errorCode); delete pTodo; } break; } delete calendar; }

ThemethodgetEventsDays()receivesthecalendarname,thetypeofthecomponent(1for event,2fortodo,or3tojournal),thestartdateandtheenddate.Thereturnedvalueisa vectorcontainingthedatesofevents:


QList< QDate > Calendar::getEventsDays(const QString& calendarName, int type, const QDateTime& startDate, const QDateTime& endDate) { int errorCode = 0; type = (type) ? type : 4; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); vector< CComponent * > components; components = multiCalendar->getComponents(calendar>getCalendarId(), type, startDate.toTime_t(), endDate.toTime_t(), errorCode); QList<QDate> componentsVector; for (vector<CComponent *>::iterator it = components.begin();it!=components.end(); ++it) { QDateTime date = QDateTime::fromTime_t ( (*it)->getDateStart() ); componentsVector.append(date.date()); } return componentsVector; }

MaemoforMobileDevelopers

ThemethodgetEventsDescription()receivesthreeparameters:thecalendarname,thetypeof thecomponent(1forevent,2fortodo,or3tojournal),andthedateofevents.Thereturned valueisavectorcontainingthedescriptionoftheeventsofthespecifieddate:


QList<QString>Calendar::getEventsDescription(const QString& calendarName, int type, const QDateTime& date) { int errorCode = 0; type = (type) ? type : 4; CCalendar *calendar = multiCalendar->getCalendarByName (calendarName.toStdString(), errorCode); vector< CComponent * > components; components = multiCalendar->getComponents (calendar>getCalendarId(), type, date.toTime_t(), date.toTime_t() + DAY_IN_SECONDS, errorCode); QList<QString> componentsVector; for (vector<CComponent *>::iterator it = components.begin();it!=components.end(); ++it) { QString output; QDateTime date = QDateTime::fromTime_t ( (*it)->getDateStart() ); output.append(date.toString(Qt::SystemLocaleShortDate)); output.append(" - "); output.append(QString::fromStdString((*it)->getSummary())); output.append("\n"); output.append(QString::fromStdString((*it)>getDescription())); componentsVector.append(output); } return componentsVector; }

4.3 Links
SQLitehttp://www.sqlite.org/ Calendarbackendhttp://maemo.org/api_refs/5.0/beta/calendar backend/index.html

MaemoforMobileDevelopers

5 ICD2
5.1 Introduction
TheInternetConnectionDaemon2(ICd2)isresponsibletomanageconnectionstothe internet on Maemo. It helps developers by providing an abstract layer to be used on applicationsthatneedstogetconnectedoninternet.Itisinitializedatsystemboottimeand stoppedatsystemshutdownby/etc/init.d/icd2initscript. The main concept behind internet connections on Maemo devices is the Internet Access Point (IAP). As described in (Maemo.org, 2009), IAP represents a logical internet connectiondefinedbytheuser.Itdefines,amongotherthings,theradiobearer,procedures forauthentication,proxyserversandthecorrespondingaccesspointintheinternet. ICd2 API defines methods to retrieve information about system connections besides requesting a connection, initiate scan procedures and request connection state. Such API is proprietary,becomingimpossibletocompileitandrunonotherplatformsorinstandardLinux aswell.Although,itprovidesheaderfilestobeincludeinCandC++sourcecodes.Thelatest versionis0.85+0m5anditiscompatiblewithDiabloandFremantleMaemoSDKversions.Itis simpleandithasonlythreeheaderfilestobeexported. ICd2isaDBusAPI,internaltotheconnectivitysubsystemand itisused by LibConic and connectivity UIs. LibConic is indicated to be used instead of requesting network connectionsbyinteractingdirectlywithICd2sinceitisthestablemaintainedAPIfornetwork connectivity, which encapsulates DBus calls. As pointed by (Maemo.org, 2009), ICd2 is consideredtobeinalphastateanditmaychangewithoutfurthernotice.Despitethat,using LibConic becomes harder if the code has to be written in Qt, once LibConic is written using Glib,whatincursinaproblemoftwomainloopsneedingtorunconcurrently.Inaddition,Qt provides an easy way to call methods or receive signals from DBus through QtDBus library. Consideringthat,thisdocumentationfocusonICd2usagelinkedtoQtthroughDbus. OncethisAPIworksthroughDBus,itisbettertotestcodesontargetdevice.Itisalso necessary to check if environment settings are correctly defined, which would lead to a problemofconnectingtothisservice. This API also makes it possible to write new Network or Service modules and run Debianstyle network scripts to be executed before and/or after a network connection is connectedanddisconnected. ANetworkmodulehasthreelayers:thelinklayer,theauthenticationlayerandtheIP layer.Amodulecanchoosetoimplementfunctionsononeormorelayer.Itisnecessarytoa link layer module to implement network search functionality, which reports to ICd2 what networksareavailable. ServicemodulesprovidefunctionalitiesthatareoftenusedafterIPaddresshasbeen acquired,suchasauthenticationforWLANhotspotlogins.

5.2 Architecture
ICd2APIhasthreemodules:NetworkmoduleAPIdefinitions,ServiceProviderAPIand ICd2DBusAPI.Thefirstoneisusedtodefinethenetworkitselfregardingthelinklayer,the authenticationlayerand/ortheIPLayer. The Service Provider API provides an identification function, which receives network modulesearchresultsandreturnsservicemoduleinformationiftheservicemoduleisableto usethenetwork(Maemo.org,2009). TheICd2DBusAPIgeneratesresponsestoDBusAPIrequests.ItalsocreatesIAPsand itselectstherightnetworksassociatedwithit.

MaemoforMobileDevelopers

5.3 MainClassesandMethods
ThisdocumentationisfocusedonusingtheICd2DbusAPItocallmethodsfromQt usingQtDBuslibrary.Themainmethodsofthismoduleare: ICD_DBUS_API_ADDRINFO_REQ"addrinfo_req" Requestsspecificconnectionaddressesinfo. Callback:ICD_DBUS_API_ADDRINFO_SIG"addrinfo_sig" o DBUS_TYPE_STRINGservicetypeoremptystring o DBUS_TYPE_UINT32serviceattributes,see o DBUS_TYPE_STRINGserviceidoremptystring o DBUS_TYPE_STRINGnetworktypeoremptystring o DBUS_TYPE_UINT32networkattributes,see o DBUS_TYPE_ARRAY(BYTE)networkidoremptystring o DBUS_TYPE_ARRAY( o DBUS_TYPE_STRINGIPaddress o DBUS_TYPE_STRINGIPnetmask o DBUS_TYPE_STRINGIPdefaultgateway o DBUS_TYPE_STRINGIPaddressofDNSserver#1 o DBUS_TYPE_STRINGIPaddressofDNSserver#2 o DBUS_TYPE_STRINGIPaddressofDNSserver#3 o ) ICD_DBUS_API_CONNECT_REQ"connect_req" Requestsanetworkconnection.ItmakesICd2toselectasuitableconnectionortry thespecifiedconnection. Callback:ICD_DBUS_API_CONNECT_SIG"connect_sig" o DBUS_TYPE_STRINGservicetypeoremptystring o DBUS_TYPE_UINT32serviceattributes o DBUS_TYPE_STRINGserviceidoremptystring o DBUS_TYPE_STRINGnetworktypeoremptystring o DBUS_TYPE_UINT32networkattributes o DBUS_TYPE_ARRAY(BYTE)networkidoremptystring o DBUS_TYPE_UINT32status ICD_DBUS_API_DISCONNECT_REQ"disconnect_req" Requeststodisconnectanongoingconnectionorthelastconnection. ICD_DBUS_API_SCAN_REQ"scan_req" InitiatesorstopsanIAPscan. Callback:ICD_DBUS_API_SCAN_SIG"scan_result_sig" o DBUS_TYPE_UINT32icd_scan_status o DBUS_TYPE_UINT32timestampwhenlastseen o DBUS_TYPE_STRINGservicetype o DBUS_TYPE_STRINGservicename o DBUS_TYPE_UINT32serviceattributes o DBUS_TYPE_STRINGserviceid o DBUS_TYPE_INT32serviceprioritywithinaservicetype o DBUS_TYPE_STRINGnetworktype o DBUS_TYPE_STRINGnetworkname

MaemoforMobileDevelopers

o o o o o o

DBUS_TYPE_UINT32networkattributes DBUS_TYPE_ARRAY(BYTE)networkid DBUS_TYPE_INT32networkpriorityfordifferentnetworktypes DBUS_TYPE_INT32signalstrength/quality,0(none)10(good) DBUS_TYPE_STRINGstationid DBUS_TYPE_INT32signalvalueindB

ICD_DBUS_API_SELECT_REQ"select_req" Requeststhe'Selectconnection'dialog. ICD_DBUS_API_STATE_REQ"state_req" Requestsconnectionstate. Callback:ICD_DBUS_API_STATE_SIG"state_sig" StatessignalsentinresponsetoICD_DBUS_API_STATE_REQorbroadcastedwhenever thestateofaconnectionchanges.Thisistheuniquesignalthatisbroadcasted regardlessofapreviousrequest. o DBUS_TYPE_STRINGservicetypeoremptystring o DBUS_TYPE_UINT32serviceattributes o DBUS_TYPE_STRINGserviceidoremptystring o DBUS_TYPE_STRINGnetworktypeoremptystring o DBUS_TYPE_UINT32networkattributes o DBUS_TYPE_ARRAY(BYTE)networkidoremptystring o DBUS_TYPE_STRINGerrorthatoccurred;emptystringonsuccess o DBUS_TYPE_UINT32stateofthenetwork ICD_DBUS_API_STATISTICS_REQ"statistics_req" Requestsspecificconnectionstatisticsorforallconnections. Callback:ICD_DBUS_API_STATISTICS_SIG"statistics_sig" Sentifthereareongoingconnections. o DBUS_TYPE_STRINGservicetypeoremptystring o DBUS_TYPE_UINT32serviceattributes o DBUS_TYPE_STRINGserviceidoremptystring o DBUS_TYPE_STRINGnetworktypeoremptystring o DBUS_TYPE_UINT32networkattributes o DBUS_TYPE_ARRAY(BYTE)networkidoremptystring o DBUS_TYPE_UINT32timeactive,measuredinseconds o DBUS_TYPE_INT32signalstrength/quality o DBUS_TYPE_UINT32bytessent

MaemoforMobileDevelopers

5.4 Example
5.4.1 InternetConnectionDaemon2Example ThisexamplewasdesignedtohaveaverysimpleUIfocusingonInternetConnectionDaemon 2 functionalities. As shown on Figure 1, the UI is a form with two columns where the connectionstateandactivitywillbedisplayed.

Figure2Icd2exampleUI.

ThisexamplewaswrittenusingtheQtframework.Itissplitintofivefiles:widget.cpp, widget.h,icdhandler.cpp,icdhandler.handmain.cpp.Thefileswidget.cppandwidget.h containsfunctionstocontroluserinterface.Thefilesicdhandler.cppisresponsibleto communicatewithICd2byusingtheQtDBuslibrary.Thefilemain.cpphasonlythemain functiontocreatethedescribedobjectsandstarttheapplication. TheUIdevelopedforthisexampleusesQVBoxLayoutsandQHBoxLayoutsinadditiontoa QFormLayoutintheleftcolumnandQGridLayoutontherightcolumntoorganizethewidgets. ThemajorityofwidgetsareQLabelsbutaQProgressBarisusedtodisplaythesignalquality. Theexampleapplicationwillbeavailablefordownloadlater.Theexamplecodeisexplainedas follows.ThemainfunctionalityisimplementedbyaclasslabeledIcdHandler.Itisusedto encapsulateDBuscalls.Indoingso,itisnecessarytoincludetheheadersfromICd2library andQDbuslibraryintothesourcefileasfollows: #include<QtDBus> #include<icd/dbus_api.h> TolinktheexampleagainstQDBusandICd2library,itisnecessarytoaddthefollowinglineto theprojectfile: CONFIG+=icd2qdbus

MaemoforMobileDevelopers

TogetconnectedtothesystembusthroughQDBuslibrary,itisnecessarytocallthestatic methodsystemBus()fromQDBusConnectionclass. staticQDBusConnectionbus=QDBusConnection::systemBus(); InordertoconnecttoICd2BusAPIinterface,anobjectofQDBusInterfacehastobe instantiated.ItisnecessarytopasstheICD_DBUS_API_INTERFACE,theICD_DBUS_API_PATH andthesystembusasargumentstotheconstructor. IcdHandler::IcdHandler(QObject*parent):QObject(parent) { interface=newQDBusInterface(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE, bus); bus.connect(ICD_DBUS_API_INTERFACE,ICD_DBUS_API_PATH,ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATISTICS_SIG,this,SLOT(statisticsSentResult(constQDBusMessage&))); bus.connect(ICD_DBUS_API_INTERFACE,ICD_DBUS_API_PATH,ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATE_SIG,this,SLOT(changeState(constQDBusMessage&))); } InordertolistentoasignalfromICD_DBUS_API_INTERFACE,theconnect()methodfrom QDBusConnectionisusedtoconnectasignalemittedfromDBustoaslotofthisclass. ThefirstconnectcalllinkstheICD_DBUS_API_STATISTICS_SIGtothestatisticsSentResult(const QDBusMessage&)slot.ThesecondconnectstheICD_DBUS_API_STATE_SIGsignalfromICd2to thechangeState(constQDBusMessage&)slot.Theinteractionbetweentheseclassescanbe seenonFigure2.

MaemoforMobileDevelopers

IcdHandler

ICD_DBUS_API_STATISTICS ICD_DBUS_API_STATE_REQ ICD_DBUS_API_DISCONNECT_REQ

DBus

statisticsSentResult changeState

ICD_DBUS_API_STATISTICS_SIG ICD_DBUS_API_STATE_SIG

ToretrieveinformationfromaQDBusMessage,itisnecessarytocallthearguments()method fromQDBusMessageobject.ItreturnsaQListobjectwithQVariantsobjects. BothchangeState(constQDBusMessage&)andstatisticsSentResult(constQDBusMessage& rep)slotsjustreceivethesignalfromICd2,retrievetheQListandemitaQtsignalasshownon thefollowingcodesnip: voidIcdHandler::changeState(constQDBusMessage&rep) { emitstateChanged(rep.arguments()); } voidIcdHandler::statisticsSentResult(constQDBusMessage&rep) { emitstatisticsChanged(rep.arguments()); } Themain.cppfilehasonlythemainfunction,whichcreatestheWidgetandtheIcdHandler classes.Inaddition,themainclassalsoconnectsbothclassesthroughsignalsandslots. TheIcdHandlerclasshasthefollowingslotsandsignals: classIcdHandler:publicQObject { publicslots: voidstatisticsSentResult(constQDBusMessage&rep); voidchangeState(constQDBusMessage&rep); voiddisconnect(); voidconnect(); voidupdateStatistics(); voidupdateConnectionState(); signals:

MaemoforMobileDevelopers

voidstateChanged(constQList<QVariant>state); voidstatisticsChanged(constQList<QVariant>statistics); }; TheWidgetclasshasthefollowingslotsandsignals: classWidget:publicQWidget { signals: voidconnectionButton_clicked(); voiddisconnectButton_clicked(); voidupdateStatisticsRequested(); voidupdateStateRequested(); publicslots: voidupdateConnectionState(constQList<QVariant>state); voidupdateStatisticsState(constQList<QVariant>statistics); privateslots: voidon_disconnectButton_clicked(); voidon_connectionButton_clicked(); voidtimer_tick(); private: QTimer*timer; }; OnceWidgetandIcdHandleobjectareinstantiated,themainfunctionconnectssignalsand slotsfromthemasfollows: intmain(intargc,char*argv[]) { QApplicationa(argc,argv); Widgetwidget; IcdHandlerhandler; QObject::connect(&widget,SIGNAL(connectionButton_clicked()),&handler, SLOT(connect())); QObject::connect(&widget,SIGNAL(disconnectButton_clicked()),&handler, SLOT(disconnect()));

MaemoforMobileDevelopers

QObject::connect(&widget,SIGNAL(updateStatisticsRequested()),&handler, SLOT(updateStatistics())); handler.updateConnectionState(); QObject::connect(&handler,SIGNAL(stateChanged(constQList<QVariant>)), &widget,SLOT(updateConnectionState(constQList<QVariant>))); QObject::connect(&handler,SIGNAL(statisticsChanged(constQList<QVariant>)), &widget,SLOT(updateStatisticsState(constQList<QVariant>))); widget.show(); returna.exec(); } connectionButton_clicked Widget disconnectButton_clicked updateStatisticsRequested disconnect updateStatistics connect IcdHandler

updateConnectionState updateStatisticsState

stateChanged statisticsChanged


Figure3SignalsandslotsconnectionsbetweenWidget,IcdHandlerandTimerclasses

Timer

DBus

BesidesinteractingwithIcdHandler,theWidgetalsoreceivesperiodicsignalsfromQTimerto beusedtoupdateconnectionstatistics.Itisdoneinthefollowingway: Widget::Widget(QWidget*parent)

MaemoforMobileDevelopers

:QWidget(parent) { timer=newQTimer(this); } voidWidget::updateConnectionState(constQList<QVariant>state) { unsignedintconnectionStatus=state.value(7).value<unsignedint>(); if(connectionStatus) { QObject::connect(timer,SIGNAL(timeout()),this,SLOT(timer_tick())); timer>start(800); } else { timer>stop(); networkField>setText(""); durationField>setText(""); progressBar>setValue(0); sentField>setText(""); receivedField>setText(""); } if(connectionStatus<6) { statusField>setText(connectionStates[connectionStatus]); } } Whenconnectionsstatusbecomesdifferentofzero,itindicatesthatthedeviceisconnected totheinternetthetimerhasbeenstarted.Asthedevicegetsdisconnected,itisstoppedand thestatisticsfieldsoftheUIarecleaned.

5.5 Links
Garageproject SVN Upstreamprojectpage Applicationsusingthislib 5.5.1 Documentation/Maemo5DeveloperGuide/UsingConnectivity Components/MaemoConnectivity http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Connectivity_Co mponents/Maemo_Connectivity

MaemoforMobileDevelopers

5.5.2 InternetConnectivitydaemonversion2 http://maemo.org/api_refs/5.0/beta/icd2 5.5.3 Bibliography Maemo.org.(17deAgostode2009).InternetConnectivitydaemonversion2APIReference. Acessoem17deAgostode2009,disponvelemInternetConnectivitydaemonversion2: http://maemo.org/api_refs/5.0/beta/icd2/ Maemo.org.(17deAgostode2009).Maemo5DeveloperGuide.Acessoem17deAgostode 2009,disponvelemMaemo5DeveloperGuide: http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Connectivity_Co mponents/Maemo_Connectivity

6 AGUIexample
6.1 Introduction
OneofthegreatestadvantagesofQtframeworkisitsportabilitytodifferentplatforms,soan application that runs on Desktop probably runs on mobile devices as well. With Qt, porting applicationstoMaemoplatformisapainlesstask.Onlyfewthingsmustbeconsidered,suchas storagelocation,inputeventsandinputmethod,whicharedetailedinthissection. For Maemo platform, the Qt framework is significantly well integrated. However, Qt looks a littlebitdifferentinMaemoplatform,becauseitwasmodifiedtobeintegratedwithHildon. Hildon is an application framework for mobile devices based on Linux operating system. In addition, Hildon takes into account all constraints of mobile devices, such as restrict user interface,inordertoprovideenhancementsforuserexperience.Thefollowingscreenshotofa QtapplicationrunningonMaemowithoutHildonintegration:

Note that widgets (combo boxes, lists, menu, etc.) are small and they are not suitable to be selectedwithfingers.Inaddition,consideringthatthefontisalsosmall,thelabelsaredifficult toread.Now,lookatthesameQtapplicationrunningwithHildon:

MaemoforMobileDevelopers

6.2 Mainclassesandmethods
The most important class in Qt, concerning about graphical user interface, is the QWidget class,whichisthebaseclassofallGUIobjects. One of the most important classes inherited from QWidget is the main window. On main window, it is possible to add widgets, such as menus, tables, boxes, buttons, text fields or otherusefulcomponents.InQt,theclassrepresentingthemainwindowistheQMainWindow. SomeotherusefulmethodsofQMainWindowaredescribedbelow: setCentralWidget:thismethodreceivesawidgetandplacesitonthecentralareaof themainwindow; menuBar: returns the menu bar for the main window, which allows to add menu actions.Themenuliesinthetopofwindow; statusBar:returnsthestatusbarforthemainwindow.Itispossibletoaddmessages onit.

As additional examples, other useful widgets inherited from QWidget are QPushButton, QLineEdit,andQComboBox.QPushButtonisaQtbuttonthatemitstheclicked()signalwhenit isactivated. QLineEditisatextfieldthatemitssignals,suchastextChanged()(emittedwhen the text inside the widget is changed). QComboBox is a widget that merges a button and popuplistanditemitsthesignalcurrentIndexChanged()whentheselectionischanged. Youcanuse otherwidgets.Formore documentationaboutit, seeQt classesdocumentation (http://doc.trolltech.com/4.5/classes.html).

6.3 Example
To describe how to develop Qt GUI Maemo applications, we provide an interesting example thatimplementsaSIPextensionsviewer.TheSIPandnamesvaluesareretrievedfromafile. This example will be available for download later. The main window contains a list of extensionsasshownonthefollowingpicture:

MaemoforMobileDevelopers

Inaddition,themainwindowalsocontainsamenulistwithafewoptions:

WhentheMenuImportfromfileoptionisselected,adialogisopenedtoinsertthefile locationwhichisusedtopopulatethelist:

Afterfileselection,thetableisupdated:

MaemoforMobileDevelopers

Finally,itispossibletosearchforcontacts:

Theexamplepackagecontainseightfiles,whicharedescribedasfollows: sip_finder.cpp: contains the class SIPFinder implementation, which represents the mainwindow; sip_finder.h:containsthedefinitionoftheSIPFinderclassandvariablesdefinition; sip_finder_table.h: contains the definition of the SIPFinderTable class. This class inherits from table types that lists SIP extensions and their names. The table can be filteredwithregularexpressionsinsertedinatextfield; sip_finder_table.cpp:providesSIPFinderTableclassimplementation; import_dialog.h:containsthedefinitionoftheImportDialogclass; import_dialog.cpp: contains the implementation of ImportDialog class, which is a dialogcontainingatextfieldandabutton; sip_finder.pro:containsinformationtocompiletheapplication.

6.3.1 Mainwindow

MaemoforMobileDevelopers

The sip_finder.h file is shown as follows. Note that the class SIPFinder inherits from QMainWindow,sotheQMainWindowheaderfilemustbeincluded.Theconstructorofthe classSIPFinderreceivesaninstanceofSIPFinderTableasparameter,sotheqt_gui.hheader file must be included. This instance is used as main widget of the window. The slot importFromFile() will be connected to a menu action. The methods createActions() and createMenus()helptocreatemenusandtheiractions: #ifndefSIPFinder_H #defineSIPFinder_H #include<QMainWindow> #include<qt_gui.h> classQAction; classQActionGroup; classQLabel; classQMenu; classSIPFinder:publicQMainWindow { Q_OBJECT public: SIPFinder(SIPFinderTable*table); protected: voidcontextMenuEvent(QContextMenuEvent*event); privateslots: voidimportFromFile(); private: voidcreateActions(); voidcreateMenus(); SIPFinderTable*sipFinderTable; QMenu*fileMenu; QActionGroup*alignmentGroup; QAction*importFromFileAct; QAction*exitAct; }; #endif

MaemoforMobileDevelopers

Thesip_finder.cppfileisdescribedindetailsasfollows.Thisfileincludessevenheaderfiles. The QtGui header is used for create GUI components. The QFile, QIODevice and QTextStreamfilesallowreadingdatafromlocalfiles: #include<QtGui> #include<QFile> #include<QIODevice> #include<QTextStream> #include"sip_finder_table.h" #include"sip_finder.h" #include"import_dialog.h" TheconstructorofSIPFinderclassreceivesaSIPFinderTableinstanceasparameterandsetitas the central widget of application. This is made by the function setCentralWidget() of QMainWindow. The window title is set with the function setWindowTitle(). The methods createActions() and createMenus() are called to create the actions for menu and the menu itself: SIPFinder::SIPFinder(SIPFinderTable*table) { sipFinderTable=table; setCentralWidget(sipFinderTable); createActions(); createMenus(); setWindowTitle(tr("Menu")); } ThemethodcreateActions()createstwoQActionobjects:importFromFileActandexitAct.The QAction receives a String as menu item name. The importFromFileAct is connected to slot importFromFile(), which imports the file with SIP extensions, and the exitAct is connected to theslotclose(),whichclosesthewindow: voidSIPFinder::createActions() { importFromFileAct=newQAction(tr("Importfromfile"),this); importFromFileAct>setStatusTip(tr("Importextensionsfromalocalfile")); connect(importFromFileAct,SIGNAL(triggered()),this,SLOT(importFromFile())); exitAct=newQAction(tr("Exit"),this); exitAct>setStatusTip(tr("Exittheapplication")); connect(exitAct,SIGNAL(triggered()),this,SLOT(close())); }

MaemoforMobileDevelopers

The method createMenus() calls the method menuBar() of QMainWindow. This method returnsaQMenuBarinstance,whichprovidesthemethodaddMenu(),whichisusedtoappend anewmenu(withthenamepassedasparemeter)tothemenubar.Thisoperationreturnsa QMenuinstance,whichisassociatedtothefileMenuvariable.TheactionsimportFromFileAct andexitActareaddedtofileMenubyusingmethodaddAction(): voidSIPFinder::createMenus() { fileMenu=menuBar()>addMenu(tr("Import")); fileMenu>addAction(importFromFileAct); fileMenu>addSeparator(); fileMenu>addAction(exitAct); } The method importFromFile() creates a dialog. The dialog contains a text field and a button. TheusercaninsertthefilelocationcontainingSIPextensionsandnamesinthetextfieldand pressthebuttontoconfirm.Afterthat,thefileisopenedandthecontentofthetableplaced on central part of the window is changed with the function setSourceModel() of SIPFinderTable. To open a file, an QFile object is created and the method open() of QFile is called.Toreadthefile,anQTextStreamobjectiscreatedand,untilitreachestheendoffile, eachlineisreadwiththemethodreadLine()ofQTextStream: voidSIPFinder::importFromFile() { ImportDialogimport(this); import.exec(); QFilefile(import.getLineEditText()); QStringListsipAndName; QStringListsip; QStringListname; QStringline; if(file.open(QIODevice::ReadOnly)){ QTextStreamtextStream(&file); while(!textStream.atEnd()){ line=textStream.readLine(); sipAndName=line.split(","); sip.append(sipAndName[0]); name.append(sipAndName[1]); } } file.close(); MaemoforMobileDevelopers

sipFinderTable>setSourceModel(sipFinderTable>createSIPModel(sip,name)); } ThefollowingfileisusedtopopulatethelistofSIPextensionsandnames.ToseparatetheSIP extension and the name, methods split() of QString are used. This method receives the separationtokenasparameterandcreatesaQStringListwiththeseparatedelements. 101,DiegoBezerra 102,MateusLima 103,HallysonMelo 6.3.2 Table The sip_finder_table.h is shown below. The class SIPFinderTable inherits from QWidget, so we need to include QWidget header file. Three methods are defined to help the creation of table: setSourceModel(), addExtension(), and createSIPModel(). One slot, SetRegExpFilter, is invokedwheneverthepatternoffilterchanges. #ifndefSIPFinderTable_H #defineSIPFinderTable_H #include<QWidget> classQAbstractItemModel; classQComboBox; classQGroupBox; classQLabel; classQLineEdit; classQSortFilterProxyModel; classQTreeView; classSIPFinderTable:publicQWidget { Q_OBJECT public: SIPFinderTable(); voidsetSourceModel(QAbstractItemModel*model); voidaddExtension(QAbstractItemModel*model,constQString&extension, constQString&name); QAbstractItemModel*createSIPModel(QStringListsip,QStringListname); privateslots: voidSetRegExpFilter(); voidfilterColumnChanged();

MaemoforMobileDevelopers

private: QSortFilterProxyModel*proxyModel; QGroupBox*proxyGroupBox; QTreeView*proxyView; QLabel*filterPatternLabel; QLabel*filterColumnLabel; QLineEdit*filterPatternLineEdit; QComboBox*filterColumnComboBox; }; #endif Filesip_finder_table.cppisdescribedasfollows.Atfirst,theQtGuiheaderfileisincludedso itispossibletouseQtGUIcomponents: #include<QtGui> #include"sip_finder_table.h" TheconstructorcreatesthetablewhichcontainstheSIPextensionsandnames,anditcreates a text field to allow the user searching for names or SIP extensions. The table created, proxyView,isoftypeQTreeView.Suchtabletypeneedsamodel.Inthiscase,itisusedamodel of type QSortFilterProxyModel (named proxyModel), which provides support for sorting and filtering data. After that, a text field is created with name filterPatternLineEdit and type QLineEdit, and is associated to label filterPatternLabel. Once created, the text field is connectedtoslotSetRegExpFilter,whichiscalledwhenthetextchanges. AcomboboxnamedfilterColumnComboBoxoftypeQComboBoxiscreatedtoholdthesearch options Name or Extension. It indicates in which text field the string pattern will be located. This combo box is connected to the slot filterColumnChanged(), which is called whenevertheoptioninthecomboboxischanged. Finally, the grid layout proxyLayout of type QGridLayout is created to hold some GUI components,whichisimplementedbyfunctionaddWidget(). SIPFinderTable::SIPFinderTable() { /*TheQSortFilterProxyModelclassprovidessupportforsortingand filteringdatapassedbetweenanothermodelandaview*/ proxyModel=newQSortFilterProxyModel; proxyModel>setDynamicSortFilter(true); proxyGroupBox=newQGroupBox(tr("Extensionslist")); proxyView=newQTreeView;

MaemoforMobileDevelopers

proxyView>setRootIsDecorated(false); proxyView>setAlternatingRowColors(true); proxyView>setModel(proxyModel); proxyView>setSortingEnabled(true); filterPatternLineEdit=newQLineEdit; filterPatternLabel=newQLabel(tr("Search:")); filterPatternLabel>setBuddy(filterPatternLineEdit); connect(filterPatternLineEdit,SIGNAL(textChanged(constQString&)), this,SLOT(filterRegExpChanged())); filterColumnComboBox=newQComboBox; filterColumnComboBox>addItem(tr("Extension")); filterColumnComboBox>addItem(tr("Name")); filterColumnLabel=newQLabel(tr("Searchfor:")); filterColumnLabel>setBuddy(filterColumnComboBox); connect(filterColumnComboBox,SIGNAL(currentIndexChanged(int)), this,SLOT(filterColumnChanged())); QGridLayout*proxyLayout=newQGridLayout; proxyLayout>addWidget(proxyView,0,0,1,3); proxyLayout>addWidget(filterPatternLabel,1,0); proxyLayout>addWidget(filterPatternLineEdit,1,1,1,2); proxyLayout>addWidget(filterColumnLabel,2,0); proxyLayout>addWidget(filterColumnComboBox,2,1,1,2); proxyGroupBox>setLayout(proxyLayout); QVBoxLayout*mainLayout=newQVBoxLayout; mainLayout>addWidget(proxyGroupBox); setLayout(mainLayout); setWindowTitle(tr("BasicSort/FilterModel")); resize(800,480); proxyView>sortByColumn(1,Qt::AscendingOrder); filterColumnComboBox>setCurrentIndex(1); } ThemethodcreateSIPModel()iscalledinthemainwindowbymethodimportFromFile(),which readsafileandpopulatethetablewiththeSIPextensionsandnamesfromthefile.Ageneric modelforstoringcustomdataiscreatedwithnamemodelandtypeQStandardItemModel.The constructor of QStandardItemModel receives three parameters: the rows quantity, the

MaemoforMobileDevelopers

columnsquantityandtheparentwindow.ThemethodsetHeaderDataisusedtosetcolumns names.ThemethodaddExtension()iscalledtopopulatethetableanditisdetailedlater. QAbstractItemModel*SIPFinderTable::createSIPModel(QStringListsip,QStringListname) { QStandardItemModel*model=newQStandardItemModel(0,2,this); model>setHeaderData(0,Qt::Horizontal,QObject::tr("Extension")); model>setHeaderData(1,Qt::Horizontal,QObject::tr("Name")); for(inti=0;i<sip.size();++i){ addExtension(model,sip[i],name[i]); } returnmodel; } The method addExtension() update SIP extensions and names of an model received as QAbstractItemModel as parameter. This is made by using the method setData() of QAbstractItemModel. voidSIPFinderTable::addExtension(QAbstractItemModel*model,constQString&extension, constQString&name) { model>insertRow(0); model>setData(model>index(0,0),extension); model>setData(model>index(0,1),name); } ThemethodsetSourceModel()iscalledintheconstructorofSIPFinderclass.Thismethodonly setsthesourcemodelofQAbstractItemModel,byusingthemethodsetSourceModel(). voidSIPFinderTable::setSourceModel(QAbstractItemModel*model) { proxyModel>setSourceModel(model); } TheslotfilterRegExpChanged()createsaregularexpression(QRegExp)basedontextinserted by the user. It uses such expression as filter and set it to proxyModel using the method setFilterRegExp(). voidSIPFinderTable::filterRegExpChanged() { QRegExpregExp(filterPatternLineEdit>text(),Qt::CaseInsensitive,QRegExp::RegExp); proxyModel>setFilterRegExp(regExp); MaemoforMobileDevelopers

} The slot filterColumnChanged only sets the filter, to a selected column in the combo box, to theproxyModelusingthemethodsetFilterKeyColumn. voidSIPFinderTable::filterColumnChanged() { proxyModel>setFilterKeyColumn(filterColumnComboBox>currentIndex()); }

6.4 Links
Qtexamples:http://doc.trolltech.com/4.5/examples.html OpeningfilesinQt:http://doc.trolltech.com/4.5/qfile.html

7 Whacamolegameexample
7.1 introduction
InthissectionwepresentawhacamoleQtgameforMaemo.ThisexampleusesalotofQt widgetsandusesthetouchscreenfunctionality.Throughthissectionwewillshowsome screenshotsandthecodetogeneratethem.Theexamplewillbeavailablefordownloadlater. Thecompleteexamplecontainsthefollowingfiles: main.cpp:entrypointofapplication; game_window.cpp:implementationofmainwindow; main_screen.cpp:implementationofascreenforstartthegameandsettheplayer name; records_screen.cpp:implementationofascreentoshowthegamerecords; records.txt:fileforrecordspersistence; moleCatcher.pro:projectdefinitionfile; gamecontroller.cpp:implementationofgamecore.Itisresponsibleforallgame control; graphwidget.cpp:implementationofQGraphicsViewclass,whichisresponsiblefor displayaQGraphicsScene; mole.cpp:implementationofaclassthatencapsulatesaQGraphicsPixmapItemitem. ThisitemwillbemanagedinQGraphicsScenedescribedabove; mainui.cpp:implementationofaclassresponsibleforsetupthegamescreen (QGraphicsViewmentionedabove),suchassetupbackgroundimage; pngitem.cpp:implementationofaQGraphicsPixmapItemwichwillbemanagedin QGraphicsScenedescribedabove.Itloadsapngimagefile.; graphwidgetpositioner.cpp:implementationofaclassresponsibleforcalculate positionsforQGraphicsPixmapItemitemsonQGraphicsScenescene.

MaemoforMobileDevelopers

ThegamestartpointistheclassGameWindow.Thisclasscreatesthemainwindow,initiates theGameControllerclassandcreatesaMainUiinstance.Themaingameclassesaredescribed below.

7.2 Example
7.2.1 Gamemainwindow Thegame_window.cppfilecontainstheimplementationofthegamemainwindow.Itinherits fromQMainWindow,whichallowsthecreationofawindowtoholdmenu,statusbar,widgets, layouts,toolbarsandotherthings.Inthisexample,themainwindowwillholdamenuand somewidgetsascentralwidgets.Thecentralwidgetwillchangeintime.Atfirst,weseta widgetcontainingalabel,atextfieldforplayernameentry,andastartbutton.Whentheuser pressesthestartbutton,thecentralwidgetischangedtoaQGraphicsView,whichisthegame actionscreen.WhentheuserchoicesShowrecordsmenuoption,awidgetcontaininga QTreeView(usedtoshowthetableofrecords)issetascentralwidget.Ascreenshotofthe gamemainwindowisshowbelow:

TosetawidgetascentralwidgetofaQMainWindowisveryeasy.Itismadebyusingthe functionsetCentralWdget(),whichreceivesawidgetasparameter.Anexamplecodeisshown below: ... mainScreen=newMainScreen(); setCentralWidget(mainScreen); ... Thewindowmenubarholdsthreeoptions:StartGame,Showrecords,andexit.Atfirst, theactionsarecreatedwiththefollowingcode: voidGameWindow::createActions() { startGameAct=newQAction(tr("StartGame"),this); startGameAct>setStatusTip(tr("Startsthegame")); connect(startGameAct,SIGNAL(triggered()),this,SLOT(startGame()));

MaemoforMobileDevelopers

showRecordsAct=newQAction(tr("Showrecords"),this); showRecordsAct>setStatusTip(tr("Showstherecordslist")); connect(showRecordsAct,SIGNAL(triggered()),this,SLOT(showRecords())); exitAct=newQAction(tr("Exit"),this); exitAct>setStatusTip(tr("Exittheapplication")); connect(exitAct,SIGNAL(triggered()),this,SLOT(close())); } NotethatstartGameActandshowRecordsActactionsareconnectedtostartGame()and showRecords()slotsrespectively.Theseslotsareusedtosetwidgetsascentralwidget.After that,amenuiscreatedonthemenubarandtheactionsaboveareadded: mainMenu=menuBar()>addMenu(tr("Mainmenu")); mainMenu>addAction(startGameAct); mainMenu>addAction(showRecordsAct); mainMenu>addAction(exitAct); Ascreenshotofmenuisshownbelow:

7.2.2 Mainscreen Themain_screen.cppfilecontainstheimplementationofawidgettogettheplayername andstartthegame.Thiswidgetisshownintheinitializationofthegameasthemainscreen centralwidget.Ascreenshotofthiswidgetisshownbelow:

MaemoforMobileDevelopers

TheplayernameissetthroughaQLineEditwidget.AnexampleofQLineEditcreationisshown below: QLineEdit*playerNameLineEdit=newQLineEdit(); Togetthetextinsertedinthiswidgetisquiteeasybyusingthemethodtext(),forexample: playerNameLineEdit>text(); OtherwidgetusedinmainscreenisaQPushButton.Thebuttoniscreatedusingthecode below: QPushButton*startGameButton=newQPushButton("Startgame"); Thebuttonisconnectedtoasignalinspiteofaslot.ThisismadebyusingthemacroSIGNAL suchasinfollowingcode: connect(startGameButton,SIGNAL(clicked()),this,SIGNAL(startButtonPressed())); Inthiscase,thesignalclicked()ofQPushButtonisconnectedtothesignalstartButtonPressed() (declaredassignalinmain_screen.hheaderfile).Whenthebuttonispressed,thesignal startButtonPressed()isemitted.Thissignalisconnectedtoaslot,whichstartsthegame,in game_window.cppfile. 7.2.3 Recordsscreen Therecords_screen.cppfilecontainstheimplementationofawidgetusedtoshowrecords (namesandscores)inatable.Ascreenshotofthiswidgetisshownbelow:

MaemoforMobileDevelopers

ThetableitselfisaQTreeView,whichiscreatedwiththefollowingcode: QTreeView*proxyView=newQTreeView(); AmodelmustbecreatedandsetasQTreeViewmodelbyusingsetModel()method.Themodel canbeoftype:QAbstractListModel,QAbstractProxyModel,QAbstractTableModel,QDirModel, QFileSystemModel,QHelpContentModel,QProxyModel,orQStandardItemModel.Allthese modelsinheritfromQAbstractItemModel.Inthisexamplewehaveused QSortFilterProxyModelsuchasinthecodebelow: QSortFilterProxyModel*proxyModel=newQSortFilterProxyModel(); proxyView>setModel(proxyModel); InthisexampleaQStandardItemModelobjectiscreatedandisprocessedbyproxyModel.Itis possiblebyusingthemethodsetSourceModel().Thecodebelowshowshowtocreatea QStandardItemModelandaddtwocolumnstoit: QStandardItemModel*model=newQStandardItemModel(0,2,this); model>setHeaderData(0,Qt::Horizontal,QObject::tr("player")); model>setHeaderData(1,Qt::Horizontal,QObject::tr("score")); Here,twocolumnsarecreatedwithplayerandscorenamesasheaders,respectively.To additemstoQStandardItemModel,wefirstlyinsertanewrowwithinsertRow()andthenuse setData()toinsertitemsonit.ThesetData()methodreceivesitemindex(index(row,column)), andtheitemvalue: model>insertRow(0); model>setData(model>index(0,0),player1); model>setData(model>index(0,1),1200); NowwecansetthesourcemodeltoQSortFilterProxyModel: proxyModel>setSourceModel(model);

MaemoforMobileDevelopers

7.2.4 Gamecontroller Thegamecontroller.cppfilecontainstheGameControllerclassimplementation.Thisclassis responsibleforcontrollinggametimers,suchasthetimerwhichwillcountthegameduration andthetimerwhichwillcountthedurationofamoleonthescreen.Italsochoicesrandomly thepositionwhereanewcreatedmolewillappearonthescreen. TheclassGameControllerconstructorgenerates,atfirst,arandomnumbersequenceof pseudorandomintegers.Itwillbeusedlatterfordetermineanewmolepositiononscreen.It alsoassignsthevaluezerotocurrentScoreinteger: qsrand((QTime::currentTime()).msec()); currentScore=0; Afterit,allthegametimersareinitialized: mole_timer=newQTimer(this); connect(mole_timer,SIGNAL(timeout()),this,SLOT(timerTick())); mole_timer>start(MOLE_DURATION); QTimer::singleShot(GAME_DURATION,this,SLOT(gameTimeout())); NotethataQTimeriscreatedanditssignaltimeout()isconnectedtotimerTick()slot.Afterit, thetimerisstartedwithMOLE_DURATIONintegerasparameter.Itmeansthatwhenthetimer reachestheMOLE_DURATIONmillisecondsvalue,theslottimerTick()iscalled.Thisslotis shownbelow: voidGameController::timerTick() { intposition=qrand()%NUM_SLOTS; emitmoleAdded(position,MOLE_DURATION); } ThisslotcalculatesarandomnumberbetweenzeroandNUM_SLOTSandemitsthe moleAdded()signalwiththecalculatednumber(position)andthedurationwhichanewmole willstayonthescreen. LetstakealookatthemethodstartGame()ofGameWindow: voidGameWindow::startGame() { playerName=mainScreen>getPlayerName(); controller=newGameController(); gameUi=newMainUi(); showRecordsAct>setVisible(false);

MaemoforMobileDevelopers

QObject::connect(controller,SIGNAL(moleAdded(int,int)),gameUi,SLOT(addMole(int,int))); QObject::connect(controller,SIGNAL(gameStarted(quint32)),gameUi, SLOT(setupUi(quint32))); QObject::connect(controller,SIGNAL(scoreChanged(int)),gameUi,SLOT(changeScore(int))); QObject::connect(controller,SIGNAL(gameEnded(int)),this,SLOT(endGame(int))); QObject::connect(gameUi,SIGNAL(hit()),controller,SLOT(updateScore())); QObject::connect(gameUi,SIGNAL(userLeave()),controller,SLOT(endGame())); controller>startGame(); setCentralWidget(gameUi); } NotethatthreesignalsdefinedinGameControllerareconnectedtoMainUi()slots.Thesignals are:moleAdded(),gameStarted()andscoreChanged().TheGameControllermoleAdded()signal isconnectedtoMainUi()addMole()slot,whichiscalledwhenamoleisrequestedtobeadded onthescene.TheGameControllerscoreChanged()signalisconnectedtoMainUi() changeScore()slottochangescorevalueonscreen.TwoGameControllerslotsareconnected toMainUi()signals:updateScore()andendGame().ThefirstiscalledwhenMainUi()emitsthe signalhit(),whichmeansthattheplayerhashitamoleandthescoremustbeupdated.The secondiscalledwhenMainUi()emitsuserLeave()signal,whichmeansthattheplayerleaves thegame. Whenthegameisfinishedthefollowingscreenisshown:

7.2.5 Graphicsviewwidget Thefilemainui.cppcontainstheclassMainUi,whichisresponsibletocreate,setupand manageaninstanceofGraphWidgetclass.ThisclassinheritsfromQGraphicsView,providinga waytodisplaythecontentsofaQGraphicsScene.ThecontentmaybeaQGraphicsItemitem, oranitemwhichinheritsfromit,inourcaseaQGraphicsPixmapItem. AscreenshotofthegameQGraphicsViewwiththeQGraphicsPixmapItemrepresentingthe moleisshownbelow:

MaemoforMobileDevelopers

AttheconstructorofGraphWidgetaQGraphicsSceneobjectiscreatedwithaQRectas parameter.TheQGraphicsSceneiscreatedwiththedevicedesktopsize,soweneedtocreatea QDesktopWidget: QDesktopWidget*desktopWidget=QApplication::desktop(); QRectrect=desktopWidget>availableGeometry(); Then,wecreateasceneandsetittoGraphWidget: scene=newQGraphicsScene(QRect(QPoint(0,0),rect.size())); setScene(scene); Wealsocreateatextandaddittothescenetoserveasscoredisplay: text=newQGraphicsTextItem(QString("0")); text>setPos(scene>width()60,scene>height()80); scene>addItem(text); LetstakealookatthemoleAdded()method: voidGraphWidget::addMole(intposition,intduration) { QPointpoint=positioner>getPosition(this>width(),this>height(),position); Mole*mole=newMole(point,duration,scene); QObject::connect(mole,SIGNAL(animationStopped(Mole*)),this, SLOT(removeMole(Mole*))); QObject::connect(mole,SIGNAL(animationClicked(Mole*)),this,SLOT(hit(Mole*))); QGraphicsItem*graphic=mole>getGraphicItem(); scene>addItem(graphic); } Thismethodcreatesamoleandaddsittoscene.TheMoleclassreceivesarandomposition whereitwillbeplacedonthesceneandthedurationitwillbedisplayed.TwoMolesignalsare usedhere:animationStopped()andanimationClicked().Thefirstsignalisemittedwhenthe

MaemoforMobileDevelopers

durationofamoleonthescreenends,soitisconnectedtoGraphWidgetremoveMole()slot, whichremovesthemoleitemfromscene: voidGraphWidget::removeMole(Mole*mole) { scene>removeItem(mole>getGraphicItem()); } ThesignalanimationClicked()isemittedwhentheplayerhitsamole,soGraphWidgethit()slot iscalled.Thisslotisshownbelow: voidGraphWidget::hit(Mole*mole) { scene>removeItem(mole>getGraphicItem()); emitanimationClicked(); } ItonlyremovesthehitmolefromsceneandemitsthesignalanimationClicked().AtMainUI class,thissignalisconnectedtothesignalhit(). QObject::connect(graphWidget,SIGNAL(animationClicked()),this,SIGNAL(hit())); ThesignalhitisconnectedtoGameControllerupdateScore()slot,soitwillincrementthescore value: QObject::connect(gameUi,SIGNAL(hit()),controller,SLOT(updateScore())); 7.2.6 Moleitem Themole.cppfilecontainstheclassMole.ThisclassbasicallycreatesaPngItem (QGraphicsPixmapItem)objectandanimatesit.AtfirstaPngItemobjectiscreatedandits scaleissetup: staticconstdoubleINITIAL_SCALE=0.001; ... mole=newPngItem(); mole>scale(INITIAL_SCALE,INITIAL_SCALE); NowaQtimeLineiscreatedwithmoledurationsetinGameController: duration=(duration>=25)?duration:1000; timer=newQTimeLine(duration,this); AQgraphicsItemAnimationisusedtomakeitemanimation.ThemethodsetItem()isusedto setthePngItemasitemtobeanimatedandthemethodsetTimeLine()tosettheQtimeLineas controleroftherateofanimation:

MaemoforMobileDevelopers

QGraphicsItemAnimation*animation=newQGraphicsItemAnimation(this); animation>setItem(mole); animation>setTimeLine(timer); ThePngItemscaleischangedonanimationusingthemethodsetScaleAt()of QgraphicsItemAnimationasshownbelow: animation>setScaleAt(i/(2.0*numSteps),angleCoefficient*(i+INITIAL_SCALE), angleCoefficient*(i+INITIAL_SCALE)); ThemethodsetScaleAt()receivesthreeqrealvalues:theanimationstepwhenthescalemust bechanged,thehorizontalshearfactorandtheverticalshearfactor.Theanimationstarts whenthetimerisstarted: timer>start(); Twoslotsareusedinthisclass:stopAnimation()andsetMoleClicked().Thefirstisconnectedto QtimeLinefinished()signal,sothisslotwillbecalledwhenthetimerreachestheend.The secondslotisconnectedtoPngItemclicked()signal,soitwillbecalledwhenthePngItemis clicked: QObject::connect(timer,SIGNAL(finished()),this,SLOT(stopAnimation())); QObject::connect(mole,SIGNAL(clicked()),this,SLOT(setMoleClicked())); TheslotstopAnimation()onlyemitsthesignalanimationStopped(): voidMole::stopAnimation() { emitanimationStopped(this); } TheslotsetMoleClicked()onlyemitsthesignalsetMoleClicked(): voidMole::setMoleClicked() { emitanimationClicked(this); } ThesignalsanimationStopped()andsetMoleClicked()areconnectedtoGraphWidget removeMole()andhit()slotsrespectively.

7.3 Links
Whacamoledescription:http://en.wikipedia.org/wiki/WhacAMole QGraphicsViewAPI:http://doc.trolltech.com/4.5/qgraphicsview.html

MaemoforMobileDevelopers

8 Capturingkeyevents
Whenawidgethasthekeyboardinputfocus,keyeventsaresenttoitwhenkeysare pressedorreleased.Sometimesthedeveloperwantstouseeventsfromkeyboardtoperform customaction,suchascontrolingames.Itcanbedonebyreimplementingthevirtual protectedmethodQWidget::keyPressEventinaclasswhichinheritsfromQWidget.

8.1 Example
Theexampleshownherecontainsabuttoninwhichthecentraltextchageswhenthe usertypessometextusingkeyboard.Whenthebuttonispressed,theactuanbuttontextis showninawarningmessagebox.Thecompleteexamplecanbeachievedat http://wiki.forum.nokia.com/index.php/Qt_Key_Event_test_example. ThisexampleconsistsofaQMainWindowclass,whichinheritsfromQWidget,soitcan handlekeyboardevents.Then,themethodkeyPressEventisreimplemented.Thismethod recevesaQKeyEventparameterso,whenakeyispressed,thismethodiscalledwiththe QKeyEvent,representingthekeypressed,asparameter.Letslookatthecode:
#include #include #include #include #include "capturekeys.h" "ui_capturekeys.h" <QDebug> <QPushButton> <QMessageBox>

CaptureKeys::CaptureKeys(QWidget *parent) : QMainWindow(parent) { buttonText = ""; centralButton = new QPushButton("Insert some text"); connect(centralButton, SIGNAL(clicked()), this, SLOT(buttonPressed())); setCentralWidget(centralButton); } CaptureKeys::~CaptureKeys() { } void CaptureKeys::keyPressEvent( QKeyEvent * event){ buttonText += event->text(); centralButton->setText(buttonText); } void CaptureKeys::buttonPressed(){ QString msg(centralButton->text()); QMessageBox::warning(this, QLatin1String("button pressed"), msg, QMessageBox::Ok, QMessageBox::Ok); }

Atfirst,wehavecreatedabigbuttonwiththetextInsertsometextandconnecteditto slotbuttonPressed.Belowisshownthescreenshotoftheapplicationstartscreen:

MaemoforMobileDevelopers

ThereimplementationofthemethodkeyPressEvent()onlychangethevalueofthebutton texttotexttypedbytheuser.Lookatthescreenshotoftheapplicationwhentheuserhas typedok:

Iftheuserpressesthebutton,awarningmessageisshownwiththetypedtext:

Chapter6 AdditionalMaemotools
In this section are presented some useful tools to help the development to the Maemo platform. Many of these tools are available in the official Maemo tools repository

MaemoforMobileDevelopers

(http://repository.maemo.org/). Some of them may have already been available unofficially, buttheseversionsaretestedforfunctionality. Thesetoolscanbesplitinthefollowingsubsections: Miscellaneous; Networking; Wirelesstools; Testautomationtools.

Tousethesetoolsthelinesbelowmustbeaddedinthe/etc/apt/sources.listinthescratchbox targetorinrealdevice.
# Fremantle tools deb http://repository.maemo.org fremantle/tools free non-free # Fremantle extras-devel deb http://repository.maemo.org/extras/ fremantle free non-free

1 Miscellaneous
1.1 Screenshottool
Screenshottoolisacommandlineutilityusedtocapturescreenshotsofthetabletscreen.This tooltakesascreenshotofthecurrentscreenandsavestheimageasaPNGfile.Toinstallituse thefollowingcommand:
# apt-get install screenshot-tool

Theuseofthisfeatureissimpleas:
$ screenshot-tool screen.png

Additionally,thisfeatureallowstotakedelayedscreenshots,withthecommand:
$ screenshot-tool -d 5 screen.png taking screenshot in 3 seconds... taking screenshot in 2 seconds... taking screenshot in 1 second...

Wherethedoptionspecifiesthedelayinsecondsbeforetakingthescreenshot.Thereis alsotheqoptionforquietmode.

1.2 HomeIP
HomeIP is asmall widget which displays the current IP address of the internet tablet on the desktoparea.Toinstallitusethefollowingcommand: #aptgetinstallhomeip

MaemoforMobileDevelopers

1.3 DpkgandApt
Maemoplatform,asanyDebiandistribution,packagessoftwareintoDebianpackages.Itis possibletomanagepackages(install,removeandconfigure)andobtaininformationabout themwithtoolsprovidedbyDebianPackageManagementSystem:dpkgandapt(Advantage PackagingTool). Dpkgcontainsasetoftoolswhichinstall,remove,andprovideinformationaboutDebian packages.ToinstallaDebianpackage,executethefollowingcommand:
$ dpkg I <debian_package>.deb

ToremovetheDebianpackage,executethefollowingcommand:
$ dpkg r <debian_package>.deb

Inaddition,itpossibletogetinformationaboutDebianpackagesinstalledonthesystem.In ordertogetthelistofinstalledpackages,thefollowingcommandcanbeused:
$ dpkg l

Dpkgalsoprovidesinformationaboutacertainpackage.Forexample,toinformationabouta package(dependencies,description,sizeandversion):
$ dpkg --status <debian_package>

Dpkgisveryuseful,butitalowleveltool.Tohelppackagemanagement,Aptcanbeusedto fetchpackagesfromremoterepositoriesandcomputecomplexpackagerelations.Aptalso retrieveinformationaboutpackages,suchasdescription,version,sizeanddependencies.Itis importanttoconfigureremoterepository,soAptcanworkproperly.

MaemoforMobileDevelopers

Duringpackageinstallation,Aptchecksifpackageexistsonanyofconfiguredrepositoriesand itcomputesdependenciesaswell.Toinstallapackage,usethefollowingcommand:
# apt-get install <debian_package>

Toremoveapackage,executethefollowingcommand:
# apt-get remove <debian_package>

Youcangetinformationaboutanypackage:
# apt-cache showpkg <debian_package>

Formoreinformation,seeDpkgorAptmanpages.

2 Networking
This category presents tools to retrieve and analyze network information, like routing, name resolution,IPaddresscheckandnetworkpackagetracking.

2.1 Iputils
OnceyourapplicationisproperlytestedonScratchboxenvironment,itisimportanttotestit onInternetTablet.Generally,thedeviceisonaTCP/IPwirelessnetworkandproblems,suchas networkdowntime,mayhappen.Thus,utilitytoolsthathelptoinspectconnectionproblems onaTCP/IPnetworkareveryusefultodevelopers. Iputisisasmallcollectionofutilitiestomonitor/checkTCP/IPrelatedissues.Thecomponents of this collection are: ping, to test network functionality; arping, to send ARP requests to a host;andtracepath,totraceapathtoahostdiscoveringMTU(MaximumTransmissionUnit) alongtheway. Toinstallthemonthedeviceusethefollowingcommand:
#apt-get install iputils-arping iputils-tracepath iputils-ping

Theusageofthesetoolsissimpleas:
$ ping nokia.com PING nokia.com (147.243.3.83): 56 data bytes 64 bytes from 147.243.3.83: seq=0 ttl=226 time=409.8 ms 64 bytes from 147.243.3.83: seq=1 ttl=227 time=427.0 ms 64 bytes from 147.243.3.83: seq=2 ttl=227 time=437.4 ms

--- nokia.com ping statistics --4 packets transmitted, 3 packets received, 25% packet loss round-trip min/avg/max = 409.8/424.7/437.4 ms

MaemoforMobileDevelopers

The time shown in this case (409.8 ms), is the roundtrip time of an IP package sent to the remote host. It uses the protocol ICMP (Internet Control Message Protocol) to test the connectivityofalink.
$ arping -c 4 host.name.net -I wlan0 ARPING 4.79.81.157 from 192.168.1.163 wlan0 Sent 4 probes (4 broadcast(s)) Received 0 response(s)

ThiscommandsendsARP(AddressResolutionProtocol)requeststothespecifiedhost(inthe samelocalnetwork)throughthewirelessinterface(wlan0)tocalculatetheroundtriptimeof sentpackages.


$ tracepath www.maemo.org 1: 192.168.1.163 (192.168.1.163) pmtu 1500 1: 2: 192.168.1.1 (192.168.1.1) 192.168.254.254 (192.168.254.254) 2.869ms

60.944ms 9.796ms asymm 2

3: 192.168.254.254 (192.168.254.254) 7.873ms pmtu 1492 4: (200.164.197.145)

gigabitethernet13-0.91-vpt-pb-rotd-02.telemar.net.br 65.613ms 7

5: pos10-2-bvg-pe-rotd-02.telemar.net.br (200.164.196.42) asymm 200.775ms 6: pos6-0-cen-ce-rotn-01.telemar.net.br 91.980ms (200.223.131.58) asymm

7: 200223045158.host.telemar.net.br (200.223.45.158) 308.686ms 8: 194.25.208.61 (194.25.208.61) 307.343ms 9: 194.25.6.201 (194.25.6.201) 394.287ms 10: no reply

asymm

asymm 16

asymm 14

11: so-0-2-0.XT1.HEL2.ALTER.NET (146.188.5.206) 589.966ms 12: POS1-0.GW3.HEL2.ALTER.NET (146.188.12.105) 510.498ms 13: 62.176.60.162 (62.176.60.162) 512.207ms

asymm 16

asymm 17

asymm 15

MaemoforMobileDevelopers

ThiscommandtriestocalculateanetworkpathtotheremotehostacrosstheInternet.

2.2 Netcat
Oncertainscenarios,thedeveloperneedstotestiftheinternettabletisreceivingdataover TCPorUDPnetworksinaspecificport.Forexample,considerthatthedeveloperiscreatinga chatprogramthatusesport5060toreceivedata.Thus,itisnecessarytoknowifsuchportis notblockedbyanyfirewallandifitispossibletoreceivedataoverTCPproperly.Netcattool canbeusedonsuchproblem. Netcatisasimpleutilityusedtoreadandwritedataacrossnetworkconnections,usingTCPor UDPprotocols.Thenameofthecommandlineexecutableisnc. Toinstallitonthedeviceusethefollowingcommand:
# apt-get install netcat

Theusageofthisfeatureisassimpleas:
# nc -l -p 5060

This command opens a TCP port. The option l stands for listen and the option p allows specifying the port number. Then, a listening socket will be created on port 5060. When someoneconnectstothisportandsenddatatoit,thedatawillbeprintedontheconsole. Afterrunthecommandabove,youcantestiftheinternettabletisreceivingdataintheport specifiedusingthefollowingPythonprogram:
import socket

HOST = '192.168.1.163' PORT = 5060 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.send('netcat test') data = s.recv(1024) s.close() print 'Received', repr(data)

ThisprogramjustconnectstotheIPaddressassignedtoHOSTandtotheportassignedto PORT.Inthiscase,wehaveassignedtheIPaddressandtheportoftheinternettabletwhichis runningtheNetcatcommand. Ifyouruntheprogramabove,youwillseethisoutputoninternettablet:


# nc -l -p 5060

MaemoforMobileDevelopers

netcat test

It is also possible to use Netcat to connect to a host and send data to it by running the followingcommand:
# nc host port

Inthiscase,thehostcanbetheIPaddressofonecomputerwhicharerunningthefollowing Pythonprogram.TheportcanbethevalueassignedtothePORTvariableintheprogram
import socket

HOST = "192.168.1.52" PORT = 5060 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) conn, addr = s.accept() print 'Connected by', addr data = conn.recv(1024) print data conn.close()

ThisprogramcreatesasocketserveroverTCPandlistensforaconnection. For effective example test, first run the Python program described above (using the local machineIPaddressforHOST)andafterrunthecommand(usingthecorrectIPaddress):
# nc 192.168.1.52 5060 ok

Theoutputofthepythonprogramwillbe:
Connected by ('192.168.1.163', 51723) ok

TheNetcattoolallowsconnectingtoorwaitingforUDPconnectionsbyusingtheuoption. Othersoptionscanbeused(liketforenabletelnetnegotiation)onNetcatandyoucanget detailsaboutitintheNetcatmanualpage (http://maemo.org/development/documentation/man_pages/nc/).

MaemoforMobileDevelopers

2.3 Tcpdump
Onsomecases,Netcattoolisnotenough.Forexample,thedeveloperneedstomonitorall packetsreceivedfromsomecomputeronthenetwork(andnotonlythedatasendforit).In suchcase,youcanuseTcpdump. Tcpdumpisautilitytocaptureandmonitordatafromthenetwork.Thistoolcanfilternetwork datatrafficusingbooleanexpressions.Adescriptionforeachcapturedpacketcouldbeprinted onthescreen.Forabetteranalysis,itispreferredtosavethecaptureddatainafileforlater analysis. Toinstallitonthedeviceusethefollowingcommand:
#apt-get install tcpdump

Asanexample,thefollowingcommandcanbeusedtocatchpackagesfromaspecificdomain:
$ tcpdump -w capture.cap src host.domain.net

Inthiscase,alldatathatcomesfromthehosthost.domain.nettothetargetdeviceiscaptured andsavedinthefilecapture.cap.
$ tcpdump -X udp and dst host.domain.net

Inthissecondexample,thecontentofUDPpacketsgoingtohost.domain.netaredisplayedon thescreeninhexadecimalrepresentation.

2.4 Traceroute
Tracerouteisautilitythatprintstheroutepacketstoanetworkhost.Itdisplayseachnetwork hopandthetimetakentoreachit. Toinstallthemonthedeviceusethefollowingcommand:
# apt-get install traceroute

Tousethistool,runthecommand:
$ traceroute www.maemo.org traceroute to maemo.org (62.61.69.114), 30 hops max, 40 byte packets 1 2 3 ms 192.168.1.1 (192.168.1.1) 3.052 ms 4.272 ms 3.387 ms 5.250 ms 311.005

192.168.254.254 (192.168.254.254) 200.217.72.216 (200.217.72.216)

3.937 ms 316.925 ms

4.273 ms

404.786 ms

4 (200.164.197.145)

gigabitethernet13-0.91-vpt-pb-rotd-02.telemar.net.br 305.969 ms 303.589 ms 407.409 ms 309.479 ms

5 pos10-2-bvg-pe-rotd-02.telemar.net.br (200.164.196.42) 405.487 ms 409.851 ms

MaemoforMobileDevelopers

6 pos6-0-cen-ce-rotn-01.telemar.net.br (200.223.131.58) 405.182 ms 200223045201.host.telemar.net.br (200.223.45.201) 307.953 ms 309.479 ms 7 200.223.254.81 (200.223.254.81) 200223045158.host.telemar.net.br (200.223.45.158) 200.223.254.81 (200.223.254.81) 395.385 ms 8 194.25.208.61 (194.25.208.61) 506.592 ms 402.740 421.265 ms ms

508.667 ms

2.5 Nslookup
Nslookup is a utility to query Internet name servers interactively. There is a command to translateanametoanIPaddress.Withthiscommandispossibletoidentifyproblemsinthe nameresolutionprocess. This command comes to Maemo through busybox binary. As an example, use the following command:
$ nslookup www.maemo.org Server: 127.0.0.1

Address 1: 127.0.0.1 Nokia-N800-43-7

Name:

www.maemo.org

Address 1: 62.61.69.114

ThiscommandshowstheIPaddressofthespecifiedhost.Thepingcommanddescribedabove couldalsobeusedtoretrieveanIPaddressfromtheinternetname.

2.6 Wget
Wget is a utility to download files from the web through the command line. With wget is possibletoretrievefilesusingtheprotocolsHTTP,HTTPSandFTP. Toinstallitonthedeviceusethefollowingcommand:
# apt-get install wget

Usethistoollikeintheexample:
$wget http://www.host.net/file.txt

3 Wirelesstools
In this category are present tools used to manage wireless connections using Bluetooth and WiFitechnologies.

3.1 Bluetoothtools
BluezhcidumpallowsthecaptureofrawdataintheBluetoothHCI(Hostcontrollerinterface) layerinahumanreadableway. Toinstallonthedeviceusethefollowingcommand: MaemoforMobileDevelopers

# apt-get install bluez-hcidump

Tousebluezhcidump,runthiscommand:
$ hcidump -V -x

ThiscommandenablesthedecodingofBluetoothpacketsinteractivelyanddisplaythecontent inahexadecimalform.

3.2 Wirelesstools
WirelesstoolsisapackagecontainingalotofutilitiestomanageWiFiconnections.Withit,it ispossibletomanipulatewirelessLANspecificparameterslikewirelessSSIDandgrabstatistics aboutconnections.Theapplicationsprovidedbythesetoolsare: ifrename:allowusertochangenetworkinterfacesnames; iwconfig:usedtoconfigureparametersofthewirelessinterface,analogoustoifconfig command; iwevent:displaywirelesseventsgeneratedbydriversandsettingschanges; iwgetid:usedtogetinformationaboutthecurrentwirelessnetwork,liketheIdofthe network, the access point MAC address, the channel number, the frequency, the connectedmodeandthe protocolinfo.Thisinformationisalsoreportedbyiwconfig command,butiwgetidismorefriendlytobeusedinscripts; iwlist: display additional information from a wireless network interface, and can be used to scan network in the coverage area. The information that can be grabbed by thiscommandarefrequency,rate,keys,power,txpower,retry,event,auth,wpakeys, genieandmodulation; iwpriv: allow the configuration of private parameters of a wireless network. These parametersshouldbeindicatedinthedocumentationofeachdriver; iwspy:usedtograbstatisticsfromspecificwirelessnodes.Thisfeatureisntsupported currentlywiththenativewirelessinterface.

Toinstallthemonthedeviceusethefollowingcommand:
#apt-get install wireless-tools ifrename

Usageexamplesofthesetoolsareshownbelow:
$ ifrename -p -i wlan0 -n eth1

Thiscommandrenamesthewlan0interfacetoeth1interface.Itonlyworkswhentheinterface isnotinuse.
$ iwconfig wlan0 essid MaemoNet key 123456789A mode Ad-Hoc channel 7

To create an AdHoc network with ESSID MaemoNet using WEP security and listening on channel7.
$ iwevent 23:02:54.392303 wlan0 Scan request completed

Tolisteneventsthathappensinthewirelessnetworkcard.

MaemoforMobileDevelopers

$ iwgetid -r -a

TogettheMACaddressoftheconnectedaccesspoint.
$ iwlist wlan0 scanning

Toscanthewirelessnetworkreachablebyinternettabletdevice.
$ iwpriv wlan0

TolisttheavailableIOcontrolscallsforthewirelessinterface.

4 Testautomation
Inthiscategory,asetoftoolsusedtoautomatetestexecutionforMaemobasedsystemsare described.Withthesetools,itispossibletoperformstresstests,simulateuserinteractionand measurehowlongtimesittakesbetweenanactionandtheexecution.

4.1 Sptests
Thistoolmakesitpossibletogenerateextrademandforsystemandseehowtheapplication deal with situations of high system loads in terms of CPU, memory and I/O requests. This packageconsistsofthefollowingutilities: Toinstallthemonthedevice,usethefollowingcommand:
# apt-get install sp-stress

cpuload:usedtogenerateCPUload; ioload:usedtogenerateI/Oload; memload:usedtogeneratingmemoryload.

Asafirstexample,executethefollowingcommandtostartCPUstresstests:
$ cpuload 25

TheabovecommandgeneratesanextraCPUloadof25percent.Now,thefollowingexample createsafileonmemorycardusedtogenerateI/Oextraload:
$ dd if=/dev/zero of=/media/mmc1/workfile count=1024 bs=1024 $ ioload /media/mmc1/workfile

The internal memory of Internet Tablet should not be used because its filesystem (JFFS2) is notappropriatedforthiskindofoperation.Then,ioloadisusedtostartI/Ostresstests.The content of the file created is destroyed at the end of tests. Finally, memload is used to generatestresstestsonmemory:
$ memload 25

Thecommandabovecreatesaprocessthatconsumes25megabytesofmemory.

MaemoforMobileDevelopers

4.2 Xnee
ThistoolisusedtoautomateuserinteractionunderXserver.Xneemakeitpossibletorecord, replay and redistribute user actions (X events) under the X11 environment. This package containsthefollowingutilities: ToinstallXneeonInternetTablet,usethefollowingcommand:
# apt-get install xnee

cnee:acommandlineutility; gnee:agraphicaluserinterfaceforcnee.

Asyourfirstexample,executethefollowingcommand:
$ cnee --record --mouse --events-to-record 100 -o input_events_rec.xnl

The command above records the first 100 input events. Then, use the following command replaysthecommandsrecordedinthefileinput_events_rec.xnl.
$ cnee --replay --file input_events_rec.xnl

4.3 Xresponse
With Xresponse, it is possible to monitor screen updates. It is also possible to measure the timeusedtoupdatethescreenafteruserinteractions.Thescreenupdateareasareoutputin theXgeometryformat(widthxheight+Xposition+Yposition).Itcanalsosimulatestylus taps. Toinstallitonthedevice,usethefollowingcommand:
# apt-get install xresponse

Asyourfirstexample,executethefollowingcommand:
$ xresponse -w 0 -i

This command start to listen the screen changes for ever (or until a controlC press), w 0 option,anddisplaytheareachangedintheoccurrenceofanupdatescreenevent. AdetailedanalysisofscreenchangescanbedonewiththeXresponsevisualizescripts.Thisset ofscriptsallowsthegenerationofanimationsfromxresponselogs.

5 Resourceusage
5.1 Htop
Htopisatextonly,interactiveprocessviewersimilarto'top'. Theprocesslistisscrollable; Controlscreenitemswiththestylusinadditiontothekeyboard; Theinformationonscreenisconfigurable; Stracecanbeattachedtoaprocesswithasinglekeypress.

MaemoforMobileDevelopers

ToinstallHtopconnectwithdeviceusingsshandrunthefollowingcommand:
$ apt-get install htop

Now,youcanrunHtopwiththecommandasfollows:
$htop

Htopgeneratesthefollowingoutput:

5.2 Spmemusage
Maemoprogrammingenvironmentalsoprovidestoolstomonitormemoryusage.sp memusageconsistsofutilityscriptsandtoolsthatmonitormemoryusageofyoursystem. Withspmemusage,itispossibletocheckhowthememoryisbeingusedbyacertainprocess, forexample.Itprovidesthefollowingtoolsandscripts: memsmapsprivate:showsinformationaboutprivatememoryusageofaprocess; runwithmallinfo:executesaMaemoapplicationundermallinfo,afunctionthat providesdataregardingtospaceusage; runwithmemusage:executesaMaemoapplicationundermemusage,aGlibfunction thatprovidesdataregardingtomemoryusage; memdirtycodepages:showsinformationaboutdirtycodepagesallocatedbythe processes; memmonitor:monitorssystemmemoryusageduringacertainintervalandprints informationaboutit; memmonitorsmaps:monitorsmemoryusageofsomespecifiedprocessesduringan intervalandprintsinformationaboutit.

Toinstallspmemusageonyourdevelopenvironment,openanSSHsectionwithdeviceand executethefollowingcommand:

MaemoforMobileDevelopers

#apt-get install sp-memusage

memdirtycodepageshelpstocheckhowmanydirtycodepagestheprocessesareusing.It summarizeshowmanyKBsofsharedorprivatedirtycodepagestheprocessesareusing.Ifthe processesareusingalotofdirtycodepages,itmeansthattheyarenotproperlycompiledwith optionfPIC.Theusageofmemdirtycodepagesisverysimple:


$mem-dirty-code-pages PID1 [ PID2 ... ]

ConsiderPIDsasprocessesidentificationnumbers.Theoutputwilllooklikethis:
Applications with private/shared dirty code pages: Shared dirty code summed from all processes = 0 kB Private dirty code pages total = 0 kB

memmonitorisveryuseful,becauseitmonitorssystemmemoryusageduringacertain interval.Thistoolcollectsinformationfrom/proc/meminfoatgivenintervals.Ifyoudonot specifytimeinterval,ituse3secondsasdefault.Onthefollowingexample,memmonitor providesinformationaboutsystemmemoryusageduring5seconds:


$mem-monitor 5

Itgeneratesthefollowingouput:
time: 12:59:06 12:59:11 12:59:16 total: 126796 126796 126796 avail: 73084 73080 73080 used: 53712 53716 53716 use-%: 42 42 42 status:

memmonitorsmapsprovidesinformationaboutmemoryusageofthespecifiedprocesses duringagiventimeinterval.Asmemmonitor,memmonitormapsalsocollectsinformation from/proc/meminfosystemfile.Itcanbeusedwiththeoptionsi(todeterminetheinterval betweenmemoryusageinformationupdates)andp(todeterminethePIDoftheprocess whichthetoolhastomonitor).Onthefollowingexample,memmonitorsmapsmonitors processwithPID1272andthememoryusageinformationhavetobeupdatedevery4 seconds:


$mem-monitor-smaps -i 4 -p 1272

Thecommanddescribedaboveoutputsthefollowingresult:
List available system memory and given process memory usage for /usr/bin/mediaplayer-engine[1272] according to SMAPS. (without swap as SMAPS doesn't report swap correctly)

MaemoforMobileDevelopers

system time: 10:05:16 10:05:20 10:05:24 10:05:29 avail: 72908 72888 72888 72888

process size: 16640 16640 16640 16640 rss: 3780 3780 3780 3780

private /------ dirty ---------\ clean: 60 60 60 60 shared: private: change: 0 0 0 0 572 572 572 572 +0 kB +0 kB +0 kB +0 kB

memsmapsprivatemonitorsprivatememoryusageofagivenprocess.Thisinformationis collectedfrom/proc/PID/smapssystemfile.Theusageofmemsmapsprivateisverysimple:
$mem-smaps-private PID

ConsiderPIDastheidentificationnumberoftheprocessthememsmapsprivatehasto monitor.Itgeneratesthefollowingoutput:
PID 1272: mediaplayer-engine - Dirty shared memory: 0 kB - Dirty private memory: 572 kB - Clean private memory: 60 kB

runwithmemusagerunsagivenapplicationundermemusage,awrapperlibraryprovidedby GLib.Itcollectsinformationaboutapplicationmemoryusageduringitsexecutionand generatesareportwiththesummaryofmemorymanagement.Thesintaxofrunwith memusagecommandisasfollows:


$run-with-memusage <binary> [args]

Considerbinaryastheapplicationtobemonitorandargsasargumentsofthespecifiedbinary. Itoutputsthefollowingresult:

MaemoforMobileDevelopers

runwithmallinfo runs a given application under mallinfo wrapper library and reports space usage based on several memory information, such as number of ordinary blocks, number of small blocks, space in free ordinary blocks, and much more. The result is saved on $HOME/mallinfoPID.tracefile.Theusageofrunwithmallinfoscriptisverysimple:
$run-with-mallinfo <binary> [args]

Considerbinaryastheapplicationtobemonitorandargsasargumentsofthespecifiedbinary. However, it is necessary to set MALLINFO environment variable before using runwith mallinfo:
$export MALLINFO=yes

Foracertainexample,runwithmallinfogeneratesthefollowingoutput:
Using LD_PRELOAD for loading mallinfo to ./qtmaemo To enable tracing you have to set MALLINFO variable: export MALLINFO=yes export MALLINFO=signal=10 export MALLINFO=period=10 -- use 5 seconds timeout and SIGALRM -- use SIGUSR1 to generate the report -- periodic report for 10 seconds

mallinfo version 0.2.0 build Sep 17 2008 17:21:49 (c) 2005 Nokia

MaemoforMobileDevelopers

detected variable MALLINFO with value 'yes' signal 14 (Alarm clock) is used for reporting report will be created every 5 seconds report file /home/user/mallinfo-1558.trace Hello World Closing application... mallinfo finalization completed

Inthiscase,theresultissavedonfile/home/user/mallinfo1558.trace:
time,arena,ordblks,smblks,hblks,hblkhd,usmblks,fsmblks,uordblks,fordbl ks,keepcost,total,sbrk 0,135168,1,0,0,0,0,0,440,134728,134728,135168,0x00034000 5,1200128,33,3,3,208896,0,136,1147792,52336,49160,1409024,0x00138000 8,1200128,217,709,0,0,0,26960,1009584,190544,45328,1200128,0x00138000

The following output provides information about: time interval (time), total space in arena (arena), number of ordinary blocks (ordblks), number of small blocks (smblks), space in holding block headers (hblks), number of holding blocks (hblkhd), space in small blocks in use (usmblks), space in free small (fsmblks), space in ordinary blocks in use (uordblks), space in free ordinary blocks (fordblks), space penalty if keep option is used (keepcost) andresultofsbrktool(sbrk).

5.3 Spsmapsmeasure
spsmapsmeasureinstallsanutilitythatcanbeinvokedtotakeasnapshotof /proc/PID/smapsfiles.Thesmapsfilescontainverydetailedinformationaboutprocesses memoryconsumption. Toinstallspsmapsmeasure,justrunthecommand:
#apt-get install sp-smaps-measure

Toputittowork,runthecommand:
$sp_smaps_snapshot

Itwillprintseveralinformationaboutprocessesmemoryusageonthescreen.Toavoidit,is alsopossibletosendtheinformationtoafileusingthiscommand:
$sp_smaps_snapshot > file.cap

The.capextensionfilecanbeanalyzedbythespsmapsvisualizetool.

MaemoforMobileDevelopers

5.4 Spsmapsvisualize
spsmapsvisualizeprovidesutilitiestoanalyzesmapsdatacapturedbyspsmapsmeasure.To installitrunthecommand:
#apt-get install sp-smaps-visualize

Nowyoubeabletorunthecommand:
$sp-smaps-visualize file.cap

Wherefile.capisthefilecontaininginformationgeneratedbysp_smaps_snapshottool. Afterrun,anhtmlwillbegeneratedcontaininginformationinaneasytoviewformat.

5.5 Xrestop
XrestopshowshowmuchXresourcesfromtheXserverarebeingusedbytheXclients.Itis similartotopandhtop. ToinstallXrestop,runthefollowingcommand:
#apt-get install xrestop

Asyourfirstexample,youcanrunxrestopusingthecommand:
$xrestop

Then,thexrestopapplicationappearsasshownonthefollowingimage:

MaemoforMobileDevelopers

Chapter7 DebuggingandProfiling
1 Debugging
EvenifyouareworriedaboutbugsonyourcodeanddevelopMaemoapplicationsconsidering goodprogrammingpractices,itisnotpossibletoassurethatyourapplicationisbugfree.Thus, itisimportanttofindinwhichparttheapplicationhasproblemsandcorrectthem. Debuggingisknownasthetechniquethathelpstofinderrorsinacodewithpurposeto correctthem.ThissectionistargetedtoshowsomeoftheMaemodebuggingtoolsthathelp developerstofinderrorseasily. Inthissection,wewillgetintodetailsofthefollowingdebuggingtools: Maemodebugscripts Gdb Sperrorvisualizer Sprichcore Syslog

ThesetoolscanbeinstalledinthedevicebyactivatingthetoolsrepositoryintheApplication manager.TherearedifferentrepositoriesforDiabloandFremantlereleases.Developerscan installthemtothedeviceandinScratchboxusingthecommandlineinterface.Inthistutorial, Fremantleisbeingusedasmainplatform. ToactivatethetoolsrepositorywiththeApplicationManager,createanewcataloguelikethis: 1. 2. 3. 4. StarttheApplicationManager FromitsmenubarselectToolsandthenApplicationcatalogue... PresstheNewbutton Enterthefollowing:

Cataloguename:fremantletools Webaddress:http://repository.maemo.org Distribution:fremantle/tools Components:freenonfree Disabled:leaveunchecked 5. ClickOK IfyouprefertoeditconfigurationfilesyourselfinsteadofusingtheApplicationManager,add theselinesto/etc/apt/sources.list: ForDiablo: #diablotools MaemoforMobileDevelopers

debhttp://repository.maemo.orgdiablo/toolsfreenonfree #diablotoolssources debsrchttp://repository.maemo.orgdiablo/toolsfreenonfree ForFremantle: #Fremantletools debhttp://repository.maemo.orgfremantle/toolsfreenonfree #Fremantletoolssources debsrchttp://repository.maemo.orgfremantle/toolsfreenonfree Note:TohavethesetoolsvisibleintheApplicationManager,youneedtohavetheRedPill Mode(http://maemo.org/community/wiki/ApplicationManagerRedPillMode/)activated. ToinstallabinarypackageinScratchbox: $fakerootaptgetinstall<package_name> Toinstallabinarypackageintodevice: $sudogainroot $aptgetinstall<package_name>

1.1 Generaltools
1.1.1 Maemodebugscripts maemodebugscriptsisaconveniencepackageforMaemodevelopersneedingtodebugtheir programs.Toinstallmaemodebugscriptsusethefollowingcommand: $aptgetinstallmaemodebugscripts Thiscommandwillinstallafewhelperscripts:

nativegdb o runsthetargetnativeGDB(bydefaultScratchboxrunsthehostbinaryifit exists,thisscriptoverridesthat) debugdepinstall o installsdebugsymbolsforgivenbinariesandtheirdependencieslistedby "ldd" debugpkgcheck o checksthecorrectnessofadebugpackageforagivenpackage listmmappedlibs o listsallpackagescontaininglibsandbinariesthatgivenprocessuses.Itcanbe usedtofindoutthelibrariesmmappedthroughdlopenthat"ldd"(usedby debugdebinstallscript)doesn'tfind runwithvalgrind

MaemoforMobileDevelopers

helperscriptforrunningabinarywithValgrindmemcheckplugin(memory accesserrors,leaksetc)sothatallsuitableoptionsaresetforit runwithcallgrind o helperscriptforrunningabinarywithValgrindcallgrindplugin(performance profiling)sothatallsuitableoptionsaresetforit runwithmassif o helperscriptforrunningabinarywithValgrindmassifplugin(memoryusage visualization)sothatallsuitableoptionsaresetforit runwithhelgrind o helperscriptforrunningabinarywithValgrindhelgrindplugin(racecondition detectorforthreadedprograms)sothatallsuitableoptionsareset runwithstrace o helperscriptforrunningabinarywithstrace.Likeabovehelperscripts, handlesMaemolaunchedbinariesautomatically
o

Following,wewillshowsomeofthesescriptsindetails. 1.1.2 nativegdb BydefaultScratchboxusesitsownhosttoolsinsteadofthetargetones,ifsuchareinstalled. This(trivial)scriptoverridesthatsettingfor/usr/bin/gdb.Touseit,runthecommand: $nativegdb BecausethehostGdbwillusethethread_dbcomingwiththetoolchainwithwhichhasbeen builtwith,itcannotdebugthreadsproperly.Insteadofusingthisscript,youcanalsoremove orrenametheScratchboxhostGdb. 1.1.3 debugdepinstall debugdepinstallisahelperscriptforinstallingdebugsymbolpackagesintheMaemo GNU/Linuxenvironment.Thescriptcheckswhatlibrariesthegivenbinariesandlibrariesare linkedagainst,intowhichpackagesthosebelongto,andwhethertheyhavecorresponding debugsymbolspackages.Thenitinstallstheavailabledebugsymbolspackages.Touseitjust run: $debugdepinstall<binaries> Then,thedebugsymbolpackageswillbeinstalledforthegivenbinaries.Forexample,runthe debugdepinstallfornativegdbbinaries: $debugdepinstall/usr/bin/nativegdb Note:youmustusethefullpathforthescriptbinariestomakeitwork.Youcanusethe commandwhichtofindapplicationsfullpath. ThescriptworksonbothdeviceandScratchboxdevelopmentenvironments.

MaemoforMobileDevelopers

1.1.4 listmmappedlibs listmmappedlibsisahelperscriptthatcanbeusedwithdebugdepinstall.Debugdepinstall installsonlythedependenciesthatthegivenbinaries(orlibraries)linkdirectly.Thisscriptcan findoutwhatadditionallibrarieshavebeendlopenedbythegivenprocesssothatyoucangive themalsotodebugdepinstall.Touseitjustrun: $listmmappedlibs<PID> Here,PIDistheprocessidentificationnumberwhichyouwanttoobserve.Togettheprocess identificationnumber,justrunthecommand: psxau

1.2 GDB
Debugging is an important method to find bugs in order to fix them. Such iterative cycle of findfixbugsimprovesapplicationquality,andtheresultisamorestableandreliablesystem. Debuggingisoftenusedtofindmorecomplexbugsthatcannotbedetectedusingtraditional testing approaches (unit tests, for example). In the context of embedded systems development,thedevelopergenerallyfacesstrangeerrorsthatcannotbeproperlydefined. WhendevelopingforMaemousingScratchbox,thehostplatformisdifferentfromthetarget one.Ingeneral,youmayfacesomecomplexbugs(asegmentationfault,forexample)related to memory or registers usage. As developers, we need a useful tool that displays a lot of detaileddataaboutapplicationwhichisbeinglaunchedandalsoabouttheplatform. GDB, the GNU Project debugger, is a helpful debugger that provides information about a programduringitsexecution:controloverapplicationexecution(start,pause,stop),memory map, registers, variables, source code, backtrace and much more. GDB was developed to be usedonmanyUnixlikesystemsanditworksformanyprogramminglanguages,suchasC,C++ andJava. WithGDB,itispossibletoseewhatisgoingoninsideaprogramwhileitexecutes,including themomentitcrashed.Itispossibletocheckvariablesvaluestoverifyiftheprogramlogicis correct,orfollowthefunctioncallstoseewhatpeaceofthecodeisbeenexecutedforagiven feature. GDBcanbeusedtodebugaMaemoapplicationondifferentscenarios:onScratchbox (both ARMEL and X86 targets) and also directly on Internet Tablet. However, for each of these environments, there are some configuration steps to be performed. This section shows how you can use GDB to debug a Maemo application in order to improve the quality of your software. AnadvancedwaytodebugwithGDBisrunningitasaclientserverapplication.Thegdbserver islaunchedonremotedeviceanditrunsapplicationdebuggingsection.Onthedesktopside, GDB is used as a client to control the gdbserver and view the debugging results. The communication between the machines is established using GDB protocol via serial port or TCP/IP.Moredetailsabouthowtodebugwithgdbserverisdescribedinthissection.

MaemoforMobileDevelopers

1.2.1 Installingandtestinggdb Asdescribedbefore,youcandebugaMaemoapplicationonScratchboxoronInternetTablet. Onthissection,wedescribehowtoinstallGDBonbothenvironmentsandhowtocheckifit wasproperlyinstalled. 1.2.1.1 PreparingScratchboxenvironment BothFremantletargets(FREMANTLE_ARMELandFREMANTLE_X86)provideaGDBexecutable. However,suchGDBexecutablesarenotsuitableforMaemodevelopment,becausetheyare notproperlyconfiguredtoapplicationdebuggingonMaemorootstraps.Instead,weneedto use a native executable, a non Scratchbox version of GDB, which is accessible using script nativegdb. At first, in order to set properly nativegdb, it is necessary to install package Maemodebugscriptsasdescribedonthissection.Asyourfirsttry,launchnativegdbwithout anyparameter:
[sbox-FREMANTLE_X86: ~] > native-gdb GNU gdb (GDB) 6.8.50.20090417-debian Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL <http://gnu.org/licenses/gpl.html> version 3 or later

This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. copying" and "show warranty" for details. This GDB was configured as "i486-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. (gdb) Type "show

Therefore, from now one nativegdb script is used instead of GDB for Maemo application debuggingonScratchbox. 1.2.1.2 PreparingInternetTabletenvironment YouneedtoestablishanSSHsectionasrootwithInternetTablettoproceed.
maemo@maemo-desktop:~$ ssh root@192.168.2.15 root@192.168.2.15's password:

Inaddition,GDBforInternetTabletisavailableonMaemoToolsrepository.Then,ifMaemo Tools repository is not properly configured on your Internet Tablet, edit file /etc/apt/sources.listandaddthefollowingline:
deb http://repository.maemo.org/ fremantle/tools free non-free

MaemoforMobileDevelopers

Once Maemo Tools repository was added as a valid repository, it is necessary to update the packages list. Execute the following commands as root to refresh the package database and installGDBinthedevice:
Nokia-N810:~# apt-get update snip Nokia-N810:~# apt-get install gdb Now, you debugging have GDB installed on Internet maemo applications on device. gdb Tablet. You can start

Nokia-N810:~#

GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL <http://gnu.org/licenses/gpl.html> version 3 or later

This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi". (gdb) Type "show

ToquitfromGDB,pressqandhitENTERkey. 1.2.2 DebuggingwithnativegdbonScratchbox NOTE:QtlibrariesforMaemoaresupposedtobeinstalledonScratchboxbeforecontinuing. SeeSection2.3,onChapterchapter2. Onthissection,wepresentoneexampleapplicationthatwillhelptounderstandthebasicuse ofnativegdbonScratchbox.TheapplicationdefinesasimpleQtwidget,whichinheritsfrom QWidget class. This widget creates a Qt push button and connects it to a slot function (MyButton::printAndQuit).Whensuchbuttonisclicked,thefunctionMyButton::printAndQuit isinvoked:amessage(HelloWorld...)isprintedonconsoleandtheapplicationisfinished.A screenshotwiththeapplicationisshownasfollows:

MaemoforMobileDevelopers

Thecodeoffirstexample(gdb_qt_example.cppandgdb_qt_example.h)isasfollows:
1 #ifndef GDB_QT_EXAMPLE_H 2 #define GDB_QT_EXAMPLE_H 3 4 #include <QWidget> 5 6 class MyButton : public QWidget { 7 Q_OBJECT 8 public: 9 MyButton(QWidget *parent = 0); 10 private: 11 void printMessage(); 12 void quitApplication(); 13 public slots: 14 void printAndQuit(); 15 }; 16 17 #endif 1 #include <QApplication> 2 #include <QPushButton> 3 #include <QWidget> 4 #include <QVBoxLayout> 5 #include <iostream> 6 7 void MyButton::printMessage() { 8 std::cout << "Hello World\n"; 9 std::cout << "Closing application...\n"; 10 } 11 12 void MyButton::quitApplication() {

MaemoforMobileDevelopers

13 qApp->quit(); 14 } 15 16 void MyButton::printAndQuit() { 17 printMessage(); 18 quitApplication(); 19 } 20 21 MyButton::MyButton(QWidget *parent) : QWidget(parent) { 22 QPushButton *quitButton = new QPushButton("Quit"); 23 connect(quitButton, SIGNAL(clicked()), SLOT(printAndQuit())); 24 25 QVBoxLayout *layout = new QVBoxLayout; 26 layout->addWidget(quitButton); 27 setLayout(layout); 28 } 29 30 int main(int argc, char* argv[]) { 31 int x = 10; 32 std::cout << "Value of x: " << x; 33 QApplication app(argc,argv); 34 MyButton *button = new MyButton; 35 button->show(); 36 return app.exec(); 37 }

this,

This application is a very simple Qt application with a push button. When the button is pressed,thefunctionMyButton::printAndQuit(filegdb_qt_example.cpp,line#16)isinvoked: itprintsamessageonconsoleandquitfromapplication. Beforedebuggingtheapplication,itisnecessarytocompileitproperlyinordertogeneratean executable with debug symbols, so we can debug it with GDB. The debugging information is storedinobjectfileandcontainsdatatypeofeachsymbol(variableorfunction)andalsothe correspondencebetweensourcelinenumbersandmemoryaddressesofexecutablecode. If you want to request debugging information for Qt Maemo application, it is necessary to modifythe*.profileoftheproject.Includethefollowingconfigurationoptionon*.profile:
TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . CONFIG += debug # Input HEADERS += gdb_qt_example.h SOURCES += gdb_qt_example.cpp

Now,(re)generatetheprojectsMakefile,andbuildthesources:
[sbox-FREMANTLE_X86: ~/gdbexample] > qmake

MaemoforMobileDevelopers

[sbox-FREMANTLE_X86: ~/gdbexample] > make

The application is ready for debugging with GDB. Remember that we have to use the native GDB(nativegdb),notScratchboxone.Finally,startnativegdbapplication:
[sbox-FREMANTLE_X86: ~/gdbexample] > native-gdb gdbexample ... snip (gdb)

During debugging sections, we often need to follow the application control flow. In order to pauseapplicationexecutionatacertainlineofthesourcecode,youneedtosetbreakpoints. Once your application execution is frozen at a certain point of the code, you can check the values of variables, registers and memory. As an example, insert two breakpoints: one on function MyButton::printAndQuit(), and another one on function MyButton::printMessage(). TodothisuseGDBfunctionbreak:
(gdb) break MyButton::printAndQuit Breakpoint 1 at 0x804a6d8: file gdb_qt_example.cpp, line 19. (gdb) break MyButton::printMessage Breakpoint 2 at 0x804a1e4: file gdb_qt_example.cpp, line 10.

Youcanalsoinsertabreakpointonacertainlineofsourcecode.Forexample,ifyouwantto insertabreakpointonline33,executethefollowingcommand:
(gdb) break gdb_qt_example.cpp:33 Breakpoint 2 at 0x804a400: file gdb_qt_example.cpp, line 33.

FormoreinformationaboutGDBbreakpoints,seeGDBdocumentation. Oncebreakpointsareproperlyinserted,wecanstartdebuggingtheapplicationundernative gdb.


(gdb) run Starting program: /home/maemo/gdbexample/gdbexample [Thread debugging using libthread_db enabled] QGtkStyle cannot be used together with the GTK_Qt engine.

Breakpoint 1, MyButton::printAndQuit gdb_qt_example.cpp:19 19 (gdb) printMessage();

(this=0x8061998)

at

MaemoforMobileDevelopers

As you can see, the application pauses on first breakpoint it found: function MyButton::printAndQuit().Itispossibletoseethesourcecodearoundacertainlinenumber. Forexample,ifyouwanttoseethecodearoundline#20,useGDBfunctionlist:
(gdb) 14 15 16 17 18 19 20 21 22 23 list 19 void MyButton::quitApplication() { qApp->quit(); } void MyButton::printAndQuit() { printMessage(); quitApplication(); } MyButton::MyButton(QWidget *parent) : QWidget(parent) {

Tocontinuethedebuggingsectionuntilthenextbreakpoint,useGDBfunctioncontinue.If youwanttocontinuerunningyourprogramuntilcontrolreachesadifferentsourceline,use GDBfunctionstep:


(gdb) continue Continuing.

Breakpoint 2, MyButton::printMessage gdb_qt_example.cpp:10 10 (gdb) step Hello World 11 std::cout << "Hello World\n";

(this=0x80718e8)

at

std::cout << "Closing application...\n";

GDBprovidesalistwithfunctionsthathavebeencalledduringthecurrentdebuggingsection (GDBfunctionbacktrace).Thelistgoesfromrecenttoolder.Theoldestfunctionwasnaturally themain()functionattheendofthelist.Itshowsalsotheparameterstothecalledfunctions:


(gdb) backtrace #0 MyButton::printMessage (this=0x8061998) at gdb_qt_example.cpp:10 MyButton::printAndQuit (this=0x8061998) at

#1 0x0804a685 in gdb_qt_example.cpp:19

#2 0x0804a8d2 in MyButton::qt_metacall (this=0x8061998, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0xbfffd2f8) at moc_gdb_qt_example.cpp:66

MaemoforMobileDevelopers

#3 0xb73f320e in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/libQtCore.so.4 #4 0xb73f362e in QMetaObject::activate(QObject*, QMetaObject const*, int, int, void**) () from /usr/lib/libQtCore.so.4 #5 0xb7df4473 in /usr/lib/libQtGui.so.4 QAbstractButton::clicked(bool) () from

#6 0xb7ade609 in QAbstractButtonPrivate::emitClicked() /usr/lib/libQtGui.so.4

()

from

Asmentionedbefore,youcaninspectthevalueofthevariables.Letsinsertabreakpointon filegdb_qt_example.cppline#36toverifythevaluesofmainfunctionvariables:
(gdb) break gdb_qt_example.cpp:36 Breakpoint 3 at 0x804a43b: file gdb_qt_example.cpp, line 36. (gdb) continue Continuing. Breakpoint 3, main (argc=1, argv=0xbffff5e4) at gdb_qt_example.cpp:36 36 QApplication app(argc,argv);

UseGDBfunctionprinttoinspectavariable(variablex,forexample):
(gdb) print x $1 = 10

GDB has very interesting functions to display registers values (GDB function info registers), show memory regions (GDB function display [EXP]), and much more. For more information, seeGDBdocumentation. 1.2.3 Debuggingwithgdbondevice NOTE:QtlibrariesforMaemoaresupposedtobeinstalledonScratchboxbeforecontinuing. See2.4,"InstallQtonScratchbox"onChapter2. Inthissection,wewillusethesameexampleadoptedinprevioussectiontodemonstratehow todebugwithGDBonInternetTablet. ItispossibletodebuganapplicationintheInternetTabletdeviceitselfusingGDB.Inorderto maketheworkeasier,weneedtoestablishaSSHsectionwithdevice.Please,lookinthe section6.2,"Deployapplicationtothedevice"tolearnhowtoconnectwithdeviceusingSSH. SincetheexecutableissupposedtobelaunchedonInternetTablet,weneedtocompileitto ARMELarchitecture.Thus,weneedtochangetheScratchboxtargetfromFREMANTLE_X86to FREMANTLE_ARMEL. Now, compile the Qt. Do not forget to modify *.pro file so debug information is properly generatedintoobjectfile:

MaemoforMobileDevelopers

[sbox-FREMANTLE_ARMEL: ~/gdbexample] > qmake [sbox-FREMANTLE_ARMEL: ~/gdbexample] > vim gdbexample.pro [sbox-FREMANTLE_ARMEL: ~/gdbexample] > make

CopytheARMELversionofthegdb_qt_exampletothetabletusingSCP:
[sbox-FREMANTLE_ARMEL: ~/gdbexample] >scp gdbexample user@192.168.2.15:/home/user

LoginonthedevicewithSSHasuser.TheIPaddressisanexample,yourdeviceIPaddresscan bedifferent:
[sbox-FREMANTLE_ARMEL: ~/gdbexample] > ssh user@192.168.2.15 user@192.168.2.15's password:

Startthegdbdebuggerwiththegdb_qt_exampleapplication:
Nokia-N810:~# gdb gdbexample GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... (gdb)

Ifyoutrytodebugtheexecutablegdbexampleondevice,youwillcertainlyfacethefollowing problem:
(gdb) break MyButton::printAndQuit Breakpoint 1 at 0xa24c: file gdb_qt_example.cpp, line 19. (gdb) run Starting program: /home/user/gdbexample snip [Switching to Thread 0x40020cd0 (LWP 2423)] Breakpoint 1, MyButton::printAndQuit (this=0x115208) at gdb_qt_example.cpp:19 20 gdb_qt_example.cpp: No such file or directory. in gdb_qt_example.cpp

Sincethesourcefileisnotondevice,youcannotverifythecorrespondingsourcecode.Then,if youwanttofollowyourapplicationexecution,itisnecessarytocopythesourcecodeintothe samefolderwherethebinaryislocatedinthedevice.


[sbox-FREMANTLE_ARMEL: ~/gdbexample] >scp gdb_qt_example.cpp user@192.168.2.15:/home/user

MaemoforMobileDevelopers

Now, it is possible to inspect the source code during the GDB debugging section on device. LaunchtheapplicationagainonGDBandstartdebugging:
(gdb) run Starting program: /home/user/gdbexample [Switching to Thread 0x40020cd0 (LWP 2473)] Breakpoint 1, MyButton::printAndQuit (this=0x115208) at gdb_qt_example.cpp:19 19 printMessage(); (gdb) list 19 14 void MyButton::quitApplication() { 15 qApp->quit(); 16 } 17 18 void MyButton::printAndQuit() { 19 printMessage(); 20 quitApplication(); 21 } 22 23 MyButton::MyButton(QWidget *parent) : QWidget(parent) { (gdb)

TheversionofGDBforInternetTablethasthesamefeaturesoftheoneforScratchbox.Then, you can check variables, registers, memory and much more. The instruction described on section2.1.2.3canalsobeappliedforGDBdebuggingondevice. 1.2.3.1 Debuggingwithgdbserverondevice GDB also provides an interesting feature: the remote debugging. Such feature was initially providedtodebugapplicationsonmachinesthatcouldnotrunGDBinusualway.Atfirstyears ofMaemodevelopment,GDBwasnotavailableforInternetTabletandgdbserverwastheonly way to debug Maemo application on device. In addition, gdbserver does not require the applications source code. Then, it is not necessary to copy all source code files to Internet Tabletinordertodebugyouapplication.Thisseemsnotabigissue,butitisreallyveryhelpful forlargeapplicationwithalotofsourcecodefiles. Therearetwodifferentenvironmentsinvolved:gdbserverlaunchestheapplicationonInternet Tablet while GDB (client) is launched on host machine. gdbserver is the one that controls application debugging and it sends information to GDB instance on host machine. The communication is established by serial or TCP/IP protocols, using the standard GDB remote serialprotocol. Gdbserver belongs to GDB package. Thus, if GDB is installed on Internet Tablet, gdbserver is installed on it as well. To start with, you need to start gdbserver on device so GDB can get connected with remote debugging section. You need a copy of the program you want to debug,includinganylibrariesitrequires. On device, launch gdbserver and tell it how it can communicate with GDB, its TCP/IP host addressandport:

MaemoforMobileDevelopers

Nokia-N810-43-7:~# gdbserver 192.168.2.15:2345 ./gdbexample Process ./gdbexample created; pid = 1488 Listening on port 2345 Remote debugging from host 192.168.2.15

Now,inthehostmachine,GDBcangetconnectedwithdeviceandstartapplicationdebugging. On GDB, you need a copy of your application compiled with debug option, since GDB needs symbol and debugging information. gdbserver does not need your program's symbol table, then you can strip the program if necessary. Before starting the debug process, we need to specify the executable on GDB in order to load symbols for your application. Use GDB file command:
[sbox-FREMANTLE_ARMEL: ~/gdbexample] > native-gdb GNU gdb 6.4.90 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... (gdb) file gdbexample Reading symbols from /home/maemo/gdbexample/gdbexample...done.

OncegdbserverisupandrunningonInternetTablet,useGDBcommandtargetremotetoget connectedwithgdbserver:
(gdb) target remote 192.168.2.15:2345 Remote debugging using 192.168.2.15:2345 [New thread 1488] 0x400007d0 in ?? ()

On GDB, you can proceed as a local debugging section, including registers and memory inspection.Forexample,youcansetbreakpoints,proceedwithexecutionandlistsourcecode lines.
(gdb) break MyButton::printAndQuit Breakpoint 1 at 0xa24c: file gdb_qt_example.cpp, line 19. (gdb) continue Continuing. Breakpoint 1, MyButton::printAndQuit gdb_qt_example.cpp:19 19 printMessage(); (gdb) list 19 14 void MyButton::quitApplication() { 15 qApp->quit(); 16 } 17 18 void MyButton::printAndQuit() { (this=0x113268) at

MaemoforMobileDevelopers

19 20 21 22 23

printMessage(); quitApplication(); } MyButton::MyButton(QWidget *parent) : QWidget(parent) {

Formoreinformationaboutgdbserver,seegdbserverdocumentation. 1.2.4 Coredumpfiles Internal errors may occur, which cause processes to crash. In this situation, it is somewhat difficulttodebugtheapplicationdirectly,consideringyouhavenoideainwhichfunctionthe applicationhadbroken.Somedevelopersstarttolookfortheerrorinthecodeaddingprint messages all around it, execute the code, add some more messages, and follow this slow processuntiltofindthebug. AcommonerrorwhileprogrammingwithGTKiswhentheapplicationconnectssignalstoan object, and the object responsible for the callback is destroyed by the program. When the signalistroughed,itdoesnotfinditscallbackandthemacrashhappens.Thissituationisvery difficulttofindwithprintmessages,sincethedeveloperisnotexpectingtheprogramflowis passingintothecallbackfunction. Fortunately,thereareoptionstogeneratelogfiles(coredumps)withinformationcapableto retrieve the scenario when the error occurred. In general, the developer can open the generatedcoredumpfilewithGDBandinspectthesystemstateintheexactmomentithad crashed. TherearesomeMaemotoolsavailabletohelpdeveloperstoretrievecoredumpfilesfromthe device.Thesetoolsareavailableinthesprichcorepackage.Onceinstalled,sprichcore will produceacoredumpfileandalsoadditionalinformationaboutprocess,mostof/procdata, lastlinesfromsyslog,df,ifconfigoutputandmuchmore.Allofsuchinformationisaddedtoa richcoredumppackage(.rcore)andthen,itiscompressed(.lzop)inordertosavediskspace. sprichcore generates the core dump files as lzop compressed files, so they have to be uncompressedbeforeusingthemondebuggers.Thepackagesprichcorepostprocprovides therichcoreextractutility,whichextractstheinformationfromarichcoredumpfilesoGDB canreadit.Beforecontinue,installpackagessprichcoreandsprichcorepostproc.
Nokia-N810:~# apt-get install sp-rich-core sp-rich-core-postproc

The Internet Tablet kernel does not save core dump files as default. The default options for codedumpfilesavingaredefinedinthefile/mnt/initfs/linuxrc.Itscontentisasfollows:
enable_coredumps() { coredir=/media/mmc1/core-dumps echo -n "Enabling core dumps to $coredir/..." echo "$coredir/%e-%s-%p.core" > /proc/sys/kernel/core_pattern ulimit -c unlimited

MaemoforMobileDevelopers

echo "done." }

Thecoredumpsaresavedbydefaultondirectory/media/mmc1/coredumps.Theseoptions alsodefinethesizelimitofcoredumpfilesandtheirnames,whichincludesthenameofthe executable(%e),thesignal(%s)andthePIDnumber(%p). Thefollowingexampleshowshowtogenerateacoredumpfileandhowwecandebugit.To showhowGDBcanbeusedtodebuganapplicationfromitscoredumpfile,amodifiedversion of gdbexample application is used (gdb_qt_buggy_example.cpp and gdb_qt_buggy_example.h). The only changes remain on function crashApplication(): it is invoked before printing messages on console and it tries to assign a value to a uninitialized pointer (ptr). Such operation is invalid and it throws a segmentation fault exception. The modifiedcodeisasfollows:
01 #include <QWidget> 02 #include <QVBoxLayout> 03 #include <iostream> 04 05 #include "gdb_qt_example.h" 06 07 void MyButton::crashApplication() { 08 char *ptr = 0; 09 memcpy(ptr, 0x00, sizeof(ptr)); 10 } 11 12 void MyButton::printMessage() { 13 std::cout << "Hello World\n"; 14 std::cout << "Closing application...\n"; 15 crashApplication(); 16 } 17 18 void MyButton::quitApplication() { 19 qApp->quit(); 20 } snip

Now, compile application gdbbuggyexample on FREMANTLE_ARMEL rootstrap and copy it to device.Donotforgettoeditfile*.protoadddebugoption:


[sbox-FREMANTLE_ARMEL: ~] > make snip [sbox-FREMANTLE_ARMEL: user@192.168.2.15:/home/user ~] >scp gdbbuggyexample

Runthegdbexampleapplicationinthedevice:
Nokia-N810:~#./gdbbuggyexample

MaemoforMobileDevelopers

The gdbbuggyexample is now running in the background and the application is shown on Internet Tablet screen. The application crashes when the button Quit is pressed: method MyButton::crashApplicationisinvokedinsidemethodMyButton::printMessage.:
Nokia-N810:~# ./gdbbuggyexample Value of x: 10 Hello World Closing application... Segmentation fault (core dumped)

The core dump file with information about gdbbuggyexample application is saved under /media/mmc1/coredumps. As configured on /mnt/initfs/linuxrc file, its name includes the nameofthefileandthePIDnumberofthegdbbuggyexampleprogramattheend.Youcansee thecompressedcoredumpfile(.lzo)savedunder/media/mmc1/coredumps:
Nokia-N810:~# cd /media/mmc1/core-dumps Nokia-N810:/media/mmc1/core-dumps# 2478.rcore.lzo -rw-r--r-1 user root gdbbuggyexample-11-2478.rcore.lzo ls -l gdbbuggyexample-11-

665.9k

Jul

21

12:07

Thecoredumpfileisnowproperlygenerated,butitisstillcompressed.GDBcannotreadthe core dump file in such format, so it is needed to uncompress it with richcoreextract application.
Nokia-N810:/media/mmc1/core-dumps# gdbbuggyexample-11-2478.rcore.lzo coredir rich-core-extract \

Nokia-N810:/media/mmc1/core-dumps# ls -l coredir/ drwxr-xr-x drwxr-xr-x -rw-r--r-2 user 3 user 1 user root root root root 0 Jul 21 12:35 . 0 Jul 21 12:35 .. 9 Jul 21 12:36 cmdline 55 Jul 21 12:36

-rw-r--r-1 user component_version -rw-r--r--rw-r--r--rw-r--r--rw-r--r--rw-r--r--rw-r--r--rw-r--r-info 1 user 1 user 1 user 1 user 1 user 1 user 1 user root root root root root root root

2.7M Jul 21 12:36 coredump 30 Jul 21 12:36 date 521 Jul 21 12:36 df 741 Jul 21 12:36 fd 796 Jul 21 12:36 ifconfig 1.2k Jul 21 12:36 ls_proc 397 Jul 21 12:36 osso-product-

MaemoforMobileDevelopers

-rw-r--r--rw-r--r--rw-r--r--rw-r--r--

1 user 1 user 1 user 1 user

root root root root

15.2k Jul 21 12:36 packagelist 28.9k Jul 21 12:36 proc2csv 11.9k Jul 21 12:36 slabinfo 44.1k Jul 21 12:36 smaps

As described before, the compressed rich core dump has a lot of information about system, including the core dump file (coredump) and files with system package list, ifconfig output, df/fd output, the command line used to launch the application and much more. In addition, suchcompressedformatsavesdiskspaceandspeedsupinformationrecording. Thedebuginformationfromtheexamplecodeisavailableinthecoredumpduetotheg option used to compile it (automatically added when *.pro file is modified by adding line CONFIG += debug), however, as the application is dynamically linked against other libraries (e.g.libc6,libqt4),ifyouwanttobeabletoresolvesymbolsalsofortheselibrary,itisneeded toinstallthepackagecontainingdebugsymbolsofsuchlibrary.Forexample,forQtlibraries, youhavetoinstalllibqt4dbgpackageinordertoresolveQtdebugsymbols.Thedebugdep installutilitydescribedinthissectionprovidesaneasywaytoinstallthedebugpackagesforall librariestheapplicationdepends. The gdbexample is linked against libc, glib and qt libraries. We need to install them to get debugsymbolsfortheselibraries:
Nokia-N810:~# apt-get install libc6-dbg libglib2.0-0-dbg libqt4-dbg

Now, you can start to debug the application using the core dump file. You need both core dump and gdbexample binary previously compiled with debug option (g). Execute the following command in order to launch GDB (gdbexample binary as first parameter and core dumpfileasthesecondparameter:
Nokia-N810:~# gdb ./gdbbuggyexample /media/mmc1/coredumps/coredir/coredump GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. copying" and "show warranty" for details. This GDB was configured as "arm-linux-gnueabi"... Reading symbols from /usr/lib/libQtGui.so.4...done. Loaded symbols for /usr/lib/libQtGui.so.4 Reading symbols from /usr/lib/libQtCore.so.4...done. Type "show

MaemoforMobileDevelopers

Core was generated by `./gdbbuggyexample'. Program terminated with signal 11, Segmentation fault. [New process 3068] #0 0x40db99ec in memcpy () from /lib/libc.so.6 (gdb)

Youneednowtofindoutwhatfunctioncausedthecrash.Thebacktracecommandwillshow thefunctionsinvokedduringtheapplicationexecution:
(gdb) backtrace #0 0x40db99ec in memcpy () from /lib/libc.so.6 MyButton::crashApplication (this=0x110ee8) at

#1 0x0000a120 in gdb_qt_example.cpp:10 #2 0x0000a2a0 in gdb_qt_example.cpp:17 #3 0x0000a2f4 in gdb_qt_example.cpp:25

MyButton::printMessage

(this=0x110ee8)

at

MyButton::printAndQuit

(this=0x110ee8)

at

#4 0x0000ac70 in MyButton::qt_metacall (this=0x110ee8, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0xbed59930) at moc_gdb_qt_example.cpp:66 #5 0x40bd3b2c /usr/lib/libQtCore.so.4 #6 0x408c0e28 /usr/lib/libQtGui.so.4 #7 0x405dcc10 in /usr/lib/libQtGui.so.4 in QMetaObject::activate () from

in

QAbstractButton::clicked

()

from

QAbstractButtonPrivate::emitClicked

()

from

#8 0x405dd5bc in /usr/lib/libQtGui.so.4 #9 0x405dd778 in /usr/lib/libQtGui.so.4 #10

QAbstractButtonPrivate::click

()

from

QAbstractButton::mouseReleaseEvent

()

from

0x4025df48 in QWidget::event () from /usr/lib/libQtGui.so.4 in QAbstractButton::event () from

#11 0x405dcbd8 /usr/lib/libQtGui.so.4

#12 0x4068d778 in QPushButton::event () from /usr/lib/libQtGui.so.4 #13 0x402059e8 in /usr/lib/libQtGui.so.4 QApplicationPrivate::notify_helper () from

#14 0x402072d8 in QApplication::notify () from /usr/lib/libQtGui.so.4

MaemoforMobileDevelopers

#15 0x40bbddc0 in /usr/lib/libQtCore.so.4 #16 0x40206660 in /usr/lib/libQtGui.so.4 #17 0x4027f38c in /usr/lib/libQtGui.so.4 #18 0x4027dd10 in /usr/lib/libQtGui.so.4

QCoreApplication::notifyInternal

()

from

QApplicationPrivate::sendMouseEvent

()

from

QETWidget::translateMouseEvent

()

from

QApplication::x11ProcessEvent

()

from

#19 0x402a50d0 in ?? () from /usr/lib/libQtGui.so.4 #20 0x0000a634 in gdb_qt_example.cpp:37 main (argc=1, argv=0xbe8486c4) at

1.2.5 Sperrorvisualizer sperrorvisualizerisasmallutilitythat'sdesignedtohelpyouinnoticingerrorsthatare writtentosyslog. Toinstallit,runthecommand:


#apt-get install sp-error-visualizer

Justinstallthesperrorvisualizerpackageanditwillimmediatelystarttrackingsyslogged messages.It'salsostartedautomaticallyonbootup.Ifsyslogisnotrunning,itprovidesitself thesyslogsocketfortheapplications. Theerrorvisualizercanbedisabledbyrunningthefollowingcommandoruninstallingthe package.


$ /etc/init.d/sp-error-visualizer stop

1.2.6 Syslog Thesyslogddaemonisresponsibleforprovidingloggingofmessagesreceivedfromprograms andfacilitiesonthelocalhostaswellasfromremotehosts. Theklogddaemonlistenstokernelmessagesourcesandisresponsibleforprioritizingand processingoperatingsystemmessages.Theklogddaemoncanrunasaclientofsyslogdor optionallyasastandaloneprogram. Toinstallsysklogdrunthecommand:


#apt-get install sysklogd

Tostartthesysklogddaemon:
$ /etc/init.d/sysklogd start

MaemoforMobileDevelopers

2 Profiling
OnMaemodevelopment,itisimportanttoassurethatyourapplicationdoesnotdemandalot ofsystemresources,forexamplememoryconsumptionandprocessing.Anapplicationthat demandsaconsiderableamountofmemory,certainlyimpactsdirectlyonInternetTablet performanceaswell. Thus,itisnecessarytoinspecthowmuchofsystemresourcestheapplicationisdemanding. Profillingallowsextractinginformationaboutapplicationexecutionanditgeneratesalotof interestinginformation,suchassystemresourcesandpotencialbugsrelatedtomemory management,forexample. Inthissection,wewillgetintodetailsofthefollowingprofillingtools: Valgrind OProfile Strace Ltrace TheseapplicationscanbeinstalledfromToolsrepository,asdescribedonSection1.

2.1 Valgrind
On C/C++ development, applications commonly use memory management operations. The developerhastohandlecarefullythedynamicallyallocatedmemoryinordertoavoidmemory leaks, invalid assign operations, cyclic references, undefined pointers operations and much more. The Valgrind tool can be used to debug memory operations to find this kind of problems. Valgrind is a suite of debugging and profiling tools for Linux applications. It has tools for memorydebugging,memoryleakdetection,andprofiling.Originallydesignedtobeapowerful memory debugging tool, Valgrind has evolved and it is now a generic framework to develop tools for debugging and profiling Linux applications.Valgrind simulates X86 processor and it instrumentsbinarycodeonthefly.Then,itdirectlyimpactsonapplicationperformanceby10 300timesslowerthanusualscenario,dependingontheusedValgrindtool. It runs on X86/Linux, AMD64/Linux, PPC32/Linux and PPC64/Linux platforms, but not on ARM/Linuxplatform.Therefore,itisnotpossibletorunValgrindonscratchboxARMELtarget or on Internet Tablet. Considering Maemo development environment, Valgrind can be used onlyonX86targets. Valgrindhavesometoolsavailabletohelpdebugging.Someofthemaredescribedhere:

massif:Runtimememoryusagegraphandhyperlinkedallocationbacktraces; memcheck:Thistooldetectsmemoryaccesserrorsandmemoryleaks.Itreportsless falsepositivesthananyothertoolandcancallGDBwhentheerrorhappens; cachegrind:Aperformanceprofilerwhichcanbestartedandstoppedatanymoment andtheresultscanbesortedaccordingtoinstructions,cachehitsetc; callgrind: AsCachegrind, but stores also callgraph information (but can show only instructioncounts);

MaemoforMobileDevelopers

helgrind:Thistooldetectsraceconditionswhenthreadedprogramsaccessglobaldata.

ToinstallValgrindonScratchbox,rundecommand:
[sbox-FREMANTLE_X86: ~] > apt-get install valgrind

Valgrindpackageinstallallnecessarydependencies,includinglibc6dbg.Mostofdependencies are packages with symbols, so Valgrind can match suppressions to the internal library functions. AnexampleofMaemoCapplicationisusedtodemonstratethebasicusageofValgrindtool. Thefollowingexampleallocatestwopointers,butonlyoneisdeallocated(ptra)andmemoryis lost(memoryleak).Inaddition,filedescriptorfpisopened(line#23),butitisnotclosed.Also, rememberthatfiledescriptorfdisalsoapointeranditshouldbedeallocated.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <stdio.h> #include <malloc.h> int main() { FILE* fp; char *ptra, *ptrb; // First allocation: 50 bytes if ((ptra= (char *) malloc(50)) == NULL) { perror("malloc failed for 50 bytes."); exit(-1); } // Second allocation: 100 bytes if ((ptrb= (char *) malloc(100)) == NULL) { perror("malloc failed for 100 bytes."); exit(-1); } // 100 bytes allocated above are cleaned. free(ptra); // the following file descriptor is not closed fp=fopen("/tmp/tempfile.txt","a"); return 0; }

Createadirectorytosaveexample:
[sbox-FREMANTLE_X86: ~] >mkdir valgrind_example [sbox-FREMANTLE_X86: ~] >cd valgrind_example

Compiletheexample:
[sbox-FREMANTLE_X86: -o valgrind_example ~/valgrind_example] >gccg valgrind_example.c \

MaemoforMobileDevelopers

Aftercompilingthesmallexampleapplication,itcanberununderValgrind.Thebasicusageof Valgrindis:
valgrind [options] prog-and-args

RunValgrindwithsomeargumentsandexampleapplicationwiththecommand:
[sbox-FREMANTLE_X86: ~/valgrind_example] >valgrind --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=20 --track-fds=yes ./valgrind_example \ \

Explanationoftheparametersandtheirmeanings: tool=memcheck o DefineswhichtoolValgrindshoulduse.Inthisexample,thememorychecker tool (memcheck) is used, but you can use one of the tools described above. Defaultoptionismemcheck. leakcheck=full o Searchsforpotentialmemoryleaksatexit.Possibleoptionsareno,summary or full. In order to see full report about memory leak, full option should be used.Defaultoptionissummary. showreachable=yes o Showsstacktraceofreachableblocksthatcontainmemoryleakerrors.Default optionisno. numcallers=20 o Defines the number of function call levels that Valgrind displays. More the valueisincreased,morememoryValgrinddemands.Defaultvalueis12. trackfds=yes o Reportstatusoffiledescriptors.Ifapplicationopensfileswithfopen()oropen() butdonotclosethemproperly,Valgrindreportstheproblems.Defaultoption isno. Basedonthefollowingexample,Valgrindissupposedtodetectamemoryleakgeneratedby ptrbpointerlostandalsoopenfiledescriptorsdetectedatprogramexit. HereyoucanseeapieceoftheoutputgeneratedbyValgrindtoolfortheexampleabove:
==8829== Memcheck, a memory error detector. ==8829== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.

MaemoforMobileDevelopers

==8829== Using translation.

LibVEX

rev

1884,

library

for

dynamic

binary

==8829== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP. ==8829== Using valgrind-3.4.1-maemo, a dynamic binary instrumentation framework. ==8829== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al. ==8829== For more details, rerun with: -v ==8829== ==8829== ==8829== FILE DESCRIPTORS: 4 open at exit. ==8829== Open file descriptor 3: /tmp/testfile.txt ==8829== at 0x40CF14E: /targets/FREMANTLE_X86/lib/libc-2.5.so) __open_nocancel (in

==8829== by 0x40829D1: _IO_file_fopen@@GLIBC_2.1 /targets/FREMANTLE_X86/lib/libc-2.5.so) ==8829== by 0x40786C6: /targets/FREMANTLE_X86/lib/libc-2.5.so) ==8829== by 0x407871E: /targets/FREMANTLE_X86/lib/libc-2.5.so) ==8829== ==8829== ==8829== Open file descriptor 2: /dev/pts/0 ==8829== ==8829== ==8829== Open file descriptor 1: /dev/pts/0 ==8829== ==8829== ==8829== Open file descriptor 0: /dev/pts/0 ==8829== ==8829== ==8829== <inherited from parent> <inherited from parent> <inherited from parent> __fopen_internal

(in

(in

fopen@@GLIBC_2.1

(in

by 0x80484C8: main (valgrind_example.c:25)

==8829== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)

MaemoforMobileDevelopers

==8829== malloc/free: in use at exit: 402 bytes in 2 blocks. ==8829== malloc/free: 3 allocs, 1 frees, 502 bytes allocated. ==8829== For counts of detected errors, rerun with: -v ==8829== searching for pointers to 2 not-freed blocks. ==8829== checked 56,280 bytes. ==8829== ==8829== 50 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==8829== at 0x4020C19: /targets/FREMANTLE_X86/usr/lib/valgrind/x86linux/vgpreload_memcheck.so) ==8829== ==8829== ==8829== ==8829== 352 bytes in 1 blocks are still reachable in loss record 2 of 2 ==8829== at 0x4020C19: /targets/FREMANTLE_X86/usr/lib/valgrind/x86linux/vgpreload_memcheck.so) ==8829== by 0x407867A: /targets/FREMANTLE_X86/lib/libc-2.5.so) ==8829== by 0x407871E: /targets/FREMANTLE_X86/lib/libc-2.5.so) ==8829== ==8829== ==8829== LEAK SUMMARY: ==8829== ==8829== ==8829== ==8829== definitely lost: 50 bytes in 1 blocks. possibly lost: 0 bytes in 0 blocks. still reachable: 352 bytes in 1 blocks. suppressed: 0 bytes in 0 blocks. malloc (in by 0x8048452: main (valgrind_example.c:10) malloc (in

__fopen_internal

(in

fopen@@GLIBC_2.1

(in

by 0x80484C8: main (valgrind_example.c:25)

The Valgrind output shows that there are some open file descriptors at program exit. As a good programming practice, file descriptors (and other resources) should be properly closed before quit from application. In this case, there are 4 open file descriptors: the first one is related to /tmp/testfile.txt file (line #25); the last 3 file descriptors are related to file /dev/pts/0andtheyareclosedbyoperatingsystem.

MaemoforMobileDevelopers

Inaddition,Valgrindoutputreports402unallocatedbytesin2differentblocks:thefirstblock isptrbpointerallocation(line#10)andthesecondoneisfdpointerallocation(line#25).Thus, the following scenario clearly defines a memory leak on the application and it should be avoided.Then,programmershouldreviewthecodeandfreeproperlyallocatedpointers. ItispossibletousethesameexampleonmoreValgrindtools,suchascachegrindandmassif. FormoreinformationaboutValgrind,includingitsprofilinganddebuggingtools,seeValgrind UserManual.

2.2 OProfile
Today, even with advances on hardware for mobile devices, including the Internet Tablet, programmers often deal with system resources constraints, such as memory and CPU processing.AlthoughinsomecasesthedeviceCPUspeedisenoughfortheapplication,using fewerresourceswillsavedevicebattery.Theserestrictionsimpactdirectlyonhowdevelopers dotheirjobs:thecodecannotdemandtoomuchmemoryorCPUprocessing.Thus,evenifa certainMaemoapplicationunderdevelopmentisconsideredbugfree,itisnecessarytocheck ifitisconsumingaconsiderableamountofsystemresources. Itisimportanttocheckwhereapplicationsbottlenecksare:hardwareandsoftwareinterrupt handlers, kernel modules, the kernel, shared libraries or applications. The Maemo developmentenvironmentprovidesOProfile,awellknownprofilingtoolforsystemsrunning Linux2.2,2.4,and2.6kernels.OProfilerunstransparentlyinthebackgroundandprofiledata canbecollectedatanytime.ItcanbeusedtofindCPUusagebottlenecksinthewholesystem andwithinprocesses. 2.2.1 InstallingOProfileonScratchbox OProfilecanbeinstalledonbothMaemorootstraps:X86andARMEL.OProfileisavailableon MaemoToolsrepository.Then,ifMaemoToolsrepositoryisnotproperlyconfiguredonyour environment,editfile/etc/apt/sources.listandaddthefollowingline:
deb http://repository.maemo.org/ fremantle/tools free non-free

Once Maemo Tools repository was added as a valid repository, it is necessary to update the packageslist.Executethefollowingcommandasroottorefreshthepackage:
[sbox-FREMANTLE_X86: ~] > fakeroot apt-get update

ToinstallOProfileonScratchbox,executethefollowingcommand:
[sbox-FREMANTLE_X86: ~] > fakeroot apt-get install oprofile

2.2.2 InstallingOProfileonInternetTablet Atfirst,installOProfileindevice.DonotforgettoconfigureMaemoToolsrepositoryandget connectedwithdevicethroughaSSHsectionasdescribedonsection2.2.1.


Nokia-N810:~# apt-get install oprofile

InordertorunOProfileonInternetTablet,itisnecessarytoupdatethesystemkernelsoitis possibletocatchrequiredsystemeventsusedbyOProfile,suchassignalsandinterruptions.A

MaemoforMobileDevelopers

precompiledkernelwithOProfilesupportisprovidedbykerneloprofilepackageanditcanbe downloadedfromtheFremantletoolsrepositoryinScratchboxenvironment:
[sbox-FREMANTLE_ARMEL: ~] > fakeroot apt-get install kernel-oprofile

PackagekerneloprofileinstallsthekernelimagesuitableforOProfileinto/boot/directory.
[sbox-FREMANTLE_ARMEL: ~] >ls -l /boot lrwxrwxrwx 1 root root 19 Sep 26 23:43 XXX

Onceoprofileenabledkernelissaved,itispossibletoflashInternetTabletsoOProfilecanbe used on device. However, it is necessary to copy oprofileenabled kernel image to outer environment(hostDesktopsystem)soflashertoolcanbeusedtoflashInternetTablet. RememberthatScratchboxisunderDesktopenvironment,sothecontentsofScratchboxfile systemcanbeeasilyaccessedbyDesktopuser. Now,copythekernelimagetothe/tmpdirectoryusingthefollowingcommand:
[sbox-FREMANTLE_ARMEL: ~] >cp /boot/XXX/tmp

FlashertoolisrequiredtoflashkernelimageintoInternetTablet.Visitflashertooldownload page(http://tabletsdev.nokia.com/d3.php)anddownloadthenewestversionofflashertool. Inthistutorial,flasher3.0isbeingused. Once flasher tool is available, it is necessary to change its permissions so flasher3.0 can be executed. Go to the directory where flasher3.0 was previously saved and execute the followingcommand:
maemo@maemo-desktop:~$ chmod +x flasher-3.0

For more information about (https://wiki.maemo.org/Flasher).

flasher

tool,

see

visit

flasher

tool

page

Oncekerneloprofileenabledandflashertoolareavailable,itispossibletoflashtheInternet Tablet. 2.2.2.1 Flashingthekernel Thisapproachflashesthedevice,sothecurrentkernelisreplacedbyoprofileenabledkernel. To flash the new kernel image, use the linux flasher utility with options f (flash) and R (reboot):
maemo@maemo-desktop:~$ sudo./flasher-3.0 -f --kernel /tmp/XXX-R

Thisoperationdoesnotdestroyexistingdatainthedevice.However,itissuggestedtobackup Internet Tablet data before flashing the device. Once flasher tool has finished, the device is readyforOProfile.

MaemoforMobileDevelopers

OncethereisnothingmoretodowithOProfile,theusercanrestorethenormalkernel.Insuch case, since the system kernel was replaced by oprofileenabled kernel, it is necessary to re flashthedevicewithotherkernelusingthefollowingcommand:
maemo@maemo-desktop:~$ flasher -f --flash-only kernel -F \ <image> -R

# The FIASCO image is the whole product image with a name like: # RX-44_DIABLO_3.2008.17-8_PR_COMBINED_MR0_ARM.bin

As suggested before, reflashing the kernel does not destroy any of the other parts, but it is safetobackupInternetTabletdatabeforeflashingthedevice. 2.2.2.2 Bootwiththenewkernel This approach only boots the device with oprofileenabled kernel. Thus, if Internet Tablet is turnedoff,thenormalkernelisrestored. maemo@maemodesktop:~$sudo./flasher3.0loadbootkernel/tmp/X 2.2.3 UsingOProfile The following instructions can be executed on both Scratchbox and Internet Tablet, considering that OProfile is properly installed and configured on them. In addition, the instructionsmustbeexecutedasroot. If OProfile is executed on Internet Tablet, remember that it is necessary to establish a SSH sectionwithdeviceinordertomakethingseasier.Thus,getconnectedwithInternetTabletas describedbefore.Inthistutorial,commandsareexecutedonInternetTablet. Tostartwith,itisnecessarytoinitopcontrol,whichcontrolsOProfileexecutionandmanages datacollection.Thefollowingcommandsareusedtoloadmodulesandotheressentialfilesto OProfile(initoption),indicatethatthereisnokernelimageavailable(novmlinuxoption) so kernel events are not supposed to be hold, and the number of CPU cycles between interrupts (e option). It is possible to use other system events (CPU_CLK_UNHALTED or RTC_INTERRUPTS)todefineinterrupts.
Nokia-N810:~# opcontrol --init Nokia-N810:~# opcontrol --no-vmlinux Nokia-N810:~# opcontrol -e=CPU_CYCLES:100000

For more information about opcontrol, visit (http://oprofile.sourceforge.net/doc/index.html). Now,OProfiledatacollectioncanbestarted:


Nokia-N810:~# opcontrolstart

OProfile

User

Documentation

Using 2.6+ OProfile kernel interface. Using log file /var/lib/oprofile/samples/oprofiled.log

MaemoforMobileDevelopers

Daemon started. Profiler running.

OProfilecollectsallnecessaryinformationtogeneratereports.Oncedatacollectionhasbeen started, the application to analyze can be launched. Data about the current application executioniscollectedaswell. To collect information about Qt libraries and symbols, it is suggested to execute the gdb_example application: a simple Qt application with a push button. When the button is pressed,theapplicationisfinalized. Consideringthattheapplicationisfinalized,opcontroldatacollectioncanbestopped:
Nokia-N810:~# opcontrol--stop Stopping profiling.

Itispossibletoresetdatajustcollectedandrestarttheprocess:
Nokia-N810:~# opcontrol --reset Nokia-N810:~# opcontrol --init

Oncesomedatahasbeencollected,itcanbeprocessed.OProfileprovidesdifferenttoolsto processdumpfilesandshowhumanreadableinformation:opreport,opannotate,oropgprof. opreport utility generates two types of data: image summaries and symbol summaries. An image summary shows statistics about individual binary images such as libraries or applications,andsymbolsummaryprovidespersymbolprofiledata. These numbers are very important to inspect where application bottlenecks are located and how it is possible to speed up application execution. For example, if a certain application spendsmorethan50%ofitsexecutiontimeonasinglefunction,theprogrammerhastocheck why it takes too much time and how it is possible to modify the algorithm in order to save time.Thefollowingexampleshowsinformationaboutimageandsymbolsymmariescollected byOProfile:
Nokia-N810:~# opreport

CPU: ARM V6 PMU, speed 0 MHz (estimated) Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 100000 CPU_CYCLES:100000| samples| %|

-----------------7788 2000 43.7848 11.2442 no-vmlinux ld-2.5.so

MaemoforMobileDevelopers

1552 1070 906 608 485 428 424 397 381 327 252 238 151 121 86 70 60 50 42 42 38 35 30 25 15 14 13 13

8.7255 6.0156 5.0936 3.4182 2.7267 2.4063 2.3838 2.2320 2.1420 1.8384 1.4168 1.3381 0.8489 0.6803 0.4835 0.3935 0.3373 0.2811 0.2361 0.2361 0.2136 0.1968 0.1687 0.1406 0.0843 0.0787 0.0731 0.0731

libc-2.5.so libglib-2.0.so.0.1200.12 libgobject-2.0.so.0.1200.12 Xomap libQtGui.so.4.5.2 libgtk-x11-2.0.so.0.1000.12 oprofiled libgcc_s.so.1 libpthread-2.5.so libQtCore.so.4.5.2 libgdk-x11-2.0.so.0.1000.12 busybox libX11.so.6.2.0 libmb.so.1.0.9 libfontconfig.so.1.1.0 libfreetype.so.6.3.16 libz.so.1.2.3 esd libgthread-2.0.so.0.1200.12 libpango-1.0.so.0.1600.4 libsapwood.so libexpat.so.1.0.0 libpng12.so.0.1.2.8 libgdk_pixbuf-2.0.so.0.1000.12 libhildondesktop.so.0.0.0 UTF-16.so libcairo.so.2.11.5 libstdc++.so.6.0.3

... snip ...

Toseemoredetailedsymbolanalysisuseopreportl:

MaemoforMobileDevelopers

Nokia-N810:~#

opreport -l|more

warning: /no-vmlinux could not be found. BFD: /usr/lib/debug/lib/ld-2.5.so: section `.ARM.exidx' BFD: /usr/lib/debug/lib/libc-2.5.so: section `.ARM.exidx' warning: sh_link not set for

warning:

sh_link

not

set

for

CPU: ARM11 PMU, speed 0 MHz (estimated) Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 100000 7788 609 608 485 43.7848 3.4238 3.4182 2.7267 no-vmlinux /no-vmlinux ld-2.5.so Xomap /usr/bin/Xomap libQtGui.so.4.5.2 /usr/lib/libQtGui.so.4.5.2 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x11do_lookup_x

428 2.4063 2.0.so.0.1000.12 424 397 327 267 259 2.3838 2.2320 1.8384 1.5011 1.4561

oprofiled

/usr/bin/oprofiled /lib/libgcc_s.so.1 /usr/lib/libQtCore.so.4.5.2 check_match.0 strcmp /usr/lib/libgdk-x11-

libgcc_s.so.1 libQtCore.so.4.5.2 ld-2.5.so ld-2.5.so

252 1.4168 2.0.so.0.1000.12 238 185 179 151 151 133 126 121 1.3381 1.0401 1.0064 0.8489 0.8489 0.7477 0.7084 0.6803

libgdk-x11-2.0.so.0.1000.12

busybox libc-2.5.so libc-2.5.so ld-2.5.so

/bin/busybox memcpy _int_malloc _dl_relocate_object /usr/lib/libX11.so.6.2.0 _dl_map_object pthread_mutex_lock /usr/lib/libmb.so.1.0.9 libgobject-2.0.so.0.1200.12

libX11.so.6.2.0 ld-2.5.so libpthread-2.5.so libmb.so.1.0.9 0.6297

112 g_type_check_instance_is_a 110 0.6184 libc-2.5.so

strcmp

MaemoforMobileDevelopers

108 100 96

0.6072 0.5622 0.5397

libglib-2.0.so.0.1200.12 g_hash_table_lookup libc-2.5.so libc-2.5.so malloc strchr

86 0.4835 libfontconfig.so.1.1.0 /usr/lib/libfontconfig.so.1.1.0 86 82 80 80 snip 0.4835 0.4610 0.4498 0.4498 libpthread-2.5.so ld-2.5.so ld-2.5.so pthread_getspecific dl_new_hash __udivsi3

libglib-2.0.so.0.1200.12 g_slice_alloc

opannotateisusedtogenerateannotatedsourcecode.Itispossibletoshowassemblycode mixed with source code, including the number of samples for each line. In order to use opannotate, theapplicationmust havedebuginformation,andthesource mustbeavailable throughthisdebuginformation. opgprofgeneratesreportsonGNUgprofformat,soyoucanusetheoutputonmanygprofUI analyzers. 2.2.4 OProfilewithcallgraph OProfileiscommonlyusedonbasicmodetocollectstatisticsaboutacertainapplicationandit is possible to obtain interesting information about your application by using utility tools (opreport,opannotate,opgprof).However,moresophisticatedinformationcanbeobtainedby usingOProfiletogetherwithcallgraphs,whichshowrelationshipsbetweencallersandcallees. To use callgraphs, it is required to recompile all the code (binaries, libraries) of application. Beforerecompilingthecode,itisnecessarytochangecompilingoptionsbyaddingfnoomit framepointertoGCCoptions(formoreinformationaboutScratchboxenvironmentvariable, see/scratchbox/doc/variables.txtfile):
Nokia-N810:~# export SBOX_BLOCK_COMPILER_ARGS="-fomit-frame-pointer" Nokia-N810:~# pointer" export SBOX_EXTRA_COMPILER_ARGS="-fno-omit-frame-

Once the code is properly recompiled, copy the result to device by using SCP, just like describedinthissection. Init oprofileand enablecallgraph sample collection (c option) with an integer as argument whichrepresentsthemaximumdepth:

Nokia-N810:~# opcontrol --init Nokia-N810:~# opcontrol --no-vmlinux

MaemoforMobileDevelopers

Nokia-N810:~# opcontrol -e=CPU_CYCLES:100000 c 20

Runtheopreportcommandwithcoption:
Nokia-N810:~# opreport -l -c

The output is as follows: CPU: ARM V6 PMU, speed 0 MHz (estimated) Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 1000000 BFD: /usr/lib/debug/lib/ld-2.5.so: section `.ARM.exidx' BFD: /usr/lib/debug/lib/libc-2.5.so: section `.ARM.exidx' warning: sh_link not set for

warning:

sh_link

not

set

for

samples % app name symbol name ---------------------------------------------------------------------141 55.5118 no-vmlinux /no-vmlinux 141 100.000 no-vmlinux /no-vmlinux [self] ---------------------------------------------------------------------20 7.8740 busybox /bin/busybox 20 100.000 busybox /bin/busybox [self] ---------------------------------------------------------------------13 5.1181 libgobject-2.0.so.0.1200.12 /usr/lib/libgobject2.0.so.0.1200.12 13 100.000 libgobject-2.0.so.0.1200.12 /usr/lib/libgobject2.0.so.0.1200.12 [self] ---------------------------------------------------------------------6 2.3622 libc-2.5.so strchr 6 100.000 libc-2.5.so strchr [self] ---------------------------------------------------------------------6 2.3622 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x112.0.so.0.1000.12 6 100.000 libgtk-x11-2.0.so.0.1000.12 /usr/lib/libgtk-x112.0.so.0.1000.12 [self] ---------------------------------------------------------------------5 1.9685 Xomap /usr/bin/Xomap 5 100.000 Xomap /usr/bin/Xomap [self] ---------------------------------------------------------------------4 1.5748 ld-2.5.so _dl_relocate_object 4 100.000 ld-2.5.so _dl_relocate_object [self] ---------------------------------------------------------------------4 1.5748 ld-2.5.so check_match.0 4 100.000 ld-2.5.so check_match.0 [self] ---------------------------------------------------------------------4 1.5748 ld-2.5.so do_lookup_x 4 100.000 ld-2.5.so do_lookup_x [self] ---------------------------------------------------------------------]

MaemoforMobileDevelopers

OProfile report represents calling relationships between subroutines of the same application/library.Theoutputshowsthenodesofcallgraph:forexample,onlibraryld2.5.so, functionsdo_lookup_x,check_match.0and__dl_relocate_objectareinvokedduringOProfile datacollection. 2.2.5 oprofileui oprofileuiisagraphicaluserinterfacetotheoprofilesystemprofiler.Atfirst,itisnecessaryto establishaSSHsectiontothedeviceasrootandinstalloprofileuiviewerandoprofileuiserver packages:
Nokia-N810:~# apt-get install oprofileui-viewer oprofileui-server snip

To see callgraphs, do not forget to compile the target binaries with frame pointers enabled (GCCfnoomitframepointeroption)justlikedescribedinthesectionOProfilewithcallgraph. Resetopcontroltoclearolddumpandstartoprofileserverinthedevice:
Nokia-N810:~# opcontrol --reset Nokia-N810:~# oprofile-server&

Startoprofileviewerinthedevice:
Nokia-N810:~# oprofile-viewer

AgraphicaluserinterfaceforOProfilewillappearonInternetTabletscreen:

PressConnectbuttonontoolbar:

MaemoforMobileDevelopers

SelectThisComputerandclickConnectbutton. ClickStartbuttonandthenclickStopbutton. oprofileuiliststhereportaslistonmainwindow:

Note that oprofileui components are also visible at OProfile report, since it collects all symbols/functionsinvokedduringdatacollection.

2.3 Strace
Maemoapplicationscertainlydoalotofsystemcalls,suchasI/Oandmemoryoperations.In some situations it might be needed to monitor what system calls are been executed by the application, for example to look for a crash related to the interaction with system or to optimize some peace of the code that is executing system calls too often, like heavy file openingandclosing. Strace is a debugging tool that monitors all system calls used by a process and also all the signalitreceives.Straceisreallysimpletouse:theapplicationunderanalysisdoesnotneedto have debugging symbols available. In addition, strace can be attached to a running process, andretrieveinformationaboutthesystemcallsusedbyit.

MaemoforMobileDevelopers

StracecanbeinstalledonbothScratchboxandInternetTabletenvironments.OnScratchbox, strace is already installed by default. If strace is supposed to be used on Scratchbox, it is suggestedthatstracebeusedinanX86targetratherthaninanARMELtarget:inanARMEL targetstracewillactuallytracethesystemcallsoftheQEMUprocess. StraceisavailableatMaemoToolsrepository.Then,ifMaemoToolsrepositoryisnotproperly configuredonyourenvironment,editfile/etc/apt/sources.listandaddthefollowingline:
deb http://repository.maemo.org/ fremantle/tools free non-free

Once Maemo Tools repository was added as a valid repository, it is necessary to update the packageslist.Executethefollowingcommandasroottorefreshthepackage:
Nokia-N810:~# apt-get update

OnInternetTablets,youneedtoinstallstracebyusingthefollowingcommand:
Nokia-N810:~# apt-get install strace snip

Theusageofstraceisverysimplelikeinthecommandbelow:
Nokia-N810:~# strace program

Stracealsocanbeattachedtoarunningprocess.Todothisrunthecommand:
Nokia-N810:~# strace -p PID

Here,PIDistheprocessidentificationnumber.YoucanfindtheprocessPIDwithpscommand. For more information about strace, visit the Strace manual page (http://maemo.org/development/documentation/man_pages/strace/). In this tutorial, a very simple Qt example is used to demonstrate the strace tool (strace_example.cpp).TheapplicationjustopensaQtapplicationwithaHelloWorldlabel.
01 02 03 04 05 06 07 08 09 } int main(intargc, char* argv[]) { QApplicationapp(argc,argv); QLabel *label = new QLabel("Hello World!"); label->show(); return app.exec(); #include <QApplication> #include <QLabel>

MaemoforMobileDevelopers

CompiletheapplicationonARMELroostrap:
[sbox-FREMANTLE_ARMEL: ~] >qmake project [sbox-FREMANTLE_ARMEL: ~] >qmake .. snip

CopytheapplicationtodeviceusingSCP(seeSection6,"Testtheapplicationonadevice"in Chapter2.).Now,runstracewithstrace_exampleasparameter:
Nokia-N810:~# strace ./strace_example

execve("./strace_example", ["./strace_example"], [/* 59 vars */]) = 0 brk(0) = 0x11000

uname({sys="Linux", node="Nokia-N810", ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4001b000 access("/etc/ld.so.preload", R_OK) directory) open("/etc/ld.so.cache", O_RDONLY) = -1 ENOENT (No such file or

= 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=26046, ...}) = 0 mmap2(NULL, 26046, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40024000 close(3) = 0

open("/usr/lib/libQtGui.so.4", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\320\25\35\0004\0\0\0t" ..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0644, st_size=10445228, ...}) = 0 mmap2(NULL, 10485276, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x4002c000 mprotect(0x409f9000, 28672, PROT_NONE) = 0

mmap2(0x40a00000, 172032, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x9cc) = 0x40a00000 mmap2(0x40a2a000, 7708, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40a2a000 close(3) snip write(6, "@"..., 1) = 1 = 0

MaemoforMobileDevelopers

close(6) close(5)

= 0 = 0

rt_sigaction(SIGCHLD, {SIG_DFL}, {0x40b94da0, [], SA_NOCLDSTOP|0x4000000}, 8) = 0 exit_group(0) = ?

NOTE:IfyouareusingstraceinscratchboxwithARMELtarget,theoptionfneedsto begiven,sothattheprocessrunundertheQEMUisalsotraced.

Each line has the name, parameters and returned value of system calls. As the example is linkedagainstQtlibraries.YoucanseeinthestraceoutputthesystemcalltoloadQtlibraries. Basically,libraryloadingconsistsofa.sofileopeningandthesystemcallopenisusedforthis issue. For example, strace_example loads QtGui library ("/usr/lib/libQtGui.so.4"), as a read onlyfile(O_RDONLY),aslistedonstraceoutput:
open("/usr/lib/libQtGui.so.4", O_RDONLY) = 3

For open system call, the returned value is the identifier of file descriptor (3). Such value is usedtoclosethefilewhennecessary(closesystemcall). NOTE:Failedsystemcallsusually(notalways)returnareturncodeof1.

Asexampleoffailedsystemcall,thereisthefollowingexampleextractedfrompreviousstrace output:
access("/etc/ld.so.preload", directory) R_OK) = -1 ENOENT (No such file or

The system call access checks if file ld.so.preload ("/etc/ld.so.preload") has read permission (R_OK).Thefiledoesnotexistsandaccesssystemcallreturnserrorcode(1). It is possible to generate a summary with count time, calls, and errors for each system call. Executethestracetoolwithcoption:
Nokia-N810:~# strace -c % time seconds ./strace_example calls errors syscall

usecs/call

------ ----------- ----------- --------- --------- ---------------31.39 20.98 15.35 10.60 7.23 4.94 0.005429 0.003629 0.002655 0.001833 0.001250 0.000854 1 3 5 3 3 4 6313 1369 517 711 387 194 5 901 1 5 lstat64 open mmap2 read munmap write

MaemoforMobileDevelopers

3.17 2.82 2.47 1.06 0.00 0.00 0.00 0.00 0.00 0.00 snip 0.00 0.00 0.00 0.00

0.000549 0.000488 0.000428 0.000183 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000

1 1 19 2 0 0 0 0 0 0

638 573 22 86 473 1 2 15 56 4

26

access readlink writev

44

stat64 close execve pipe brk ioctl gettimeofday

0.000000 0.000000 0.000000 0.000000

0 0 0 0

5 1 1 1

connect shutdown SYS_305 SYS_307

------ ----------- ----------- --------- --------- ----------------

2.4 Ltrace
Applications often use subroutines and symbols defined on dynamic libraries installed in the system. For example the Qt libraries: QtGui and QtCore. Maemo development environment providesLtraceasatoolformonitoringdynamiclibrariescallsperformedbyaprocessandalso to trace the signals which are received by such process. Ltrace is very similar to strace, but straceonlyinterceptsandrecordssystemcalls. Ltrace can be used on both Scratchbox and Internet Tablet environments. It is available at MaemoToolsrepository.Beforeinstallingit,configureMaemoToolsrepositoryasdescribed onprevioussectionaboutstrace.Inordertoinstallltrace,executethefollowingcommand:
[sbox-FREMANTLE_ARMEL: ~] >apt-get install ltrace snip

Todemonstratehowltracecanbeused,thesameexampleofsectionstraceisused.Atfirst, compiletheapplicationonARMELroostrap:
[sbox-FREMANTLE_ARMEL: ~] >qmake project [sbox-FREMANTLE_ARMEL: ~] >qmake .. snip

MaemoforMobileDevelopers

Them,copytheexecutabletoInternetTabletusingSCP.Now,runltracewithstrace_example asparameter:
Nokia-N810:~# ltrace ./ltrace_example

__libc_start_main(35000, 1, 0xbe80c6e4, 35300, 35412 <unfinished ...> _ZN12QApplicationC1ERiPPci(0xbe80c568, 0xbe80c554, 0xbe80c6e4, 263426, 0xbe80c590) = 0xbe80c568 _ZN7QString16fromAscii_helperEPKci(35436, 0xbe80c590) = 168952 _Znwj(20, 168994, 0, 33, 0xbe80c590) -1, 0, 0x40a24ee8,

= 0x110368

_ZN6QLabelC1ERK7QStringP7QWidget6QFlagsIN2Qt10WindowTypeEE(0x110368, 0xbe80c560, 0, 0xbe80c558, 0xbe80c590) = 0x110368 _ZN12QApplication4execEv(0xbe80c4f8, 0xbe80c590) = 0 _ZN12QApplicationD1Ev(0xbe80c568, 0xbe80c568 +++ exited (status 0) +++ 0xbe80c4f8, 4, 0x40c9e468,

0x40e5f0ac,

0,

0,

0xbe80c590)

The output format of ltrace looks like strace output: each line consists of library function name,alistofparametersandtheresultcode. Inaddition,itispossibletotracksystemcallswithltraceaswell(Sparameter):
Nokia-N810:~# ltrace -S ./ltrace_example = 0x00011000 <0.000366> = 0 <0.000366> = 0x4001b000 <0.000427> = -2 <0.000397> = 3 <0.000488> = 0 <0.000366>

3119 SYS_brk(NULL) 3119 SYS_uname(0xbe83c1f0) 3119 SYS_mmap2(0, 4096, 3, 34, -1) 3119 SYS_access("/etc/ld.so.preload", 04) 3119 SYS_open("/etc/ld.so.cache", 0, 01)

3119 SYS_fstat64(3, 0xbe83baa0, 0xbe83baa0, 0, 3) 3119 SYS_mmap2(0, 26046, 1, 2, 3) 3119 SYS_close(3 3119 SYS_open("/usr/lib/libQtGui.so.4", <0.000519> 3119 SYS_read(3, "\177ELF\001\001\001", 512) 0,

= 0x40024000 <0.000457> = 0 <0.000702> 010000433450) = 3

= 512 <0.000427> = 0 <0.000397>

3119 SYS_fstat64(3, 0xbe83bad0, 0xbe83bad0, 0, 23) 3119 SYS_mmap2(0, 0x9ffe1c, 5, 2050, 3)

= 0x4002c000 <0.000458>

MaemoforMobileDevelopers

3119 SYS_mprotect(0x409f9000, 28672, 0)

= 0 <0.000580>

3119 SYS_mmap2(0x40a00000, 172032, 3, 2066, 3) = 0x40a00000 <0.000732> 3119 SYS_mmap2(0x40a2a000, 7708, 3, 50, -1) 3119 SYS_close(3) snip = 0x40a2a000 <0.000671> = 0 <0.000366>

ltraceoutputstheprocessID,nameofsystemcall,itsparametersanditsresultcode:
3119 SYS_open("/etc/ld.so.cache", 0, 01) = 3 <0.000488>

As strace, ltracegenerates a summary with count time, calls, and calls for each library invocation.Executetheltracetoolwithcoption:
% time seconds usecs/call calls function

------ ----------- ----------- --------- -------------------71.98 27.74 0.24 6.845215 2.638214 0.022552 6845215 2638214 22552 1 1 1 _ZN12QApplicationC1ERiPPci _ZN12QApplication4execEv _ZN12QApplicationD1Ev

0.02 0.002258 2258 1 _ZN6QLabelC1ERK7QStringP7QWidget6QFlagsIN2Qt10WindowTypeEE 0.01 0.01 0.000732 0.000702 732 702 1 1 _Znwj

_ZN7QString16fromAscii_helperEPKci ------ ----------- ----------- --------- -------------------100.00 9.509673 6 total

Formoreinformationaboutltrace,visittheLtracemanualpage (http://maemo.org/development/documentation/man_pages/ltrace/).

MaemoforMobileDevelopers

Вам также может понравиться