Академический Документы
Профессиональный Документы
Культура Документы
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
MaemoforMobileDevelopers
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
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
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
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.
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
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
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
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
MaemoforMobileDevelopers
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
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 }
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;
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
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
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
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
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
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
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;
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,
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); }
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
MaemoforMobileDevelopers
#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
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); }
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
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.
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
MaemoforMobileDevelopers
ThevariableDAY_IN_SECONDSisdeclaredtobeusedinsomemethods:
static const int DAY_IN_SECONDS = 86400;
InCalendarclassconstructor,asingleinstanceofaCMulticalendarisretrievedbyusingthe methodMCInstance()ofCMulticalendar:
Calendar::Calendar() { multiCalendar = CMulticalendar::MCInstance(); }
ThedestructordeletestheCMulticalendarinstance:
Calendar::~Calendar() { delete multiCalendar; }
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; }
MaemoforMobileDevelopers
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
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
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
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
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:
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:
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
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>
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)
gigabitethernet13-0.91-vpt-pb-rotd-02.telemar.net.br 65.613ms 7
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)
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
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
3.937 ms 316.925 ms
4.273 ms
404.786 ms
4 (200.164.197.145)
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
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
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
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
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
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:
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
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
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
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.
(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) {
Breakpoint 2, MyButton::printMessage gdb_qt_example.cpp:10 10 (gdb) step Hello World 11 std::cout << "Hello World\n";
(this=0x80718e8)
at
#1 0x0804a685 in gdb_qt_example.cpp:19
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
()
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
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
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
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--
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
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
QAbstractButtonPrivate::click
()
from
QAbstractButton::mouseReleaseEvent
()
from
#12 0x4068d778 in QPushButton::event () from /usr/lib/libQtGui.so.4 #13 0x402059e8 in /usr/lib/libQtGui.so.4 QApplicationPrivate::notify_helper () from
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
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
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
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
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
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
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
OProfile
User
Documentation
MaemoforMobileDevelopers
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| %|
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
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
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
strcmp
MaemoforMobileDevelopers
108 100 96
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:
MaemoforMobileDevelopers
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
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
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
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
26
44
0 0 0 0
5 1 1 1
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,
= 0x4002c000 <0.000458>
MaemoforMobileDevelopers
= 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
Formoreinformationaboutltrace,visittheLtracemanualpage (http://maemo.org/development/documentation/man_pages/ltrace/).
MaemoforMobileDevelopers