Embed
Email

Symbian OS -ohjelmointi

Document Sample

Shared by: xiang
Categories
Tags
Stats
views:
7
posted:
11/7/2011
language:
English
pages:
174
Symbian OS Programming

Tampere Polytechnic University of Applied Sciences

Tony Torp (tony.torp@tamk.fi)

www.tamk.fi/~torton









The course is supported by the project

"The assurance of information technology education quality

in the University of Tartu and Tartu Vocational Education Centre".

www.mobedu.org

Intro to Symbian OS









www.mobedu.org

History

• 1980 Psion Ltd. (founded by David Potter)

– The main purpose was to innovate and create electronical

PDA devices (Personal Digital Assistant)

• 1984: first PDA Psion Organizer

• 1986 Psion Organizer II

– 64kB RAM & ROM

– 8 bit CPU

– Connection with PC

– Programming: Assembler & OPL (Organizer programming

language)









www.mobedu.org

Psion Organizer II









Source: en.wikipedia.org



www.mobedu.org

...history

• 1991 Psion Series 3

– 16 bit SIBO-devices (sixteen-bit-organizer)

– The kernel was named EPOC (from word epoch)









www.mobedu.org

• Psion Series 3 OPL contained an editor and compiler

for 3rd party SW developers

– > possibility to create effective 3rd party applications

– > thousands of applications available by different vendors





• 1996 Psion Software Ltd.

– the main goal was to make EPOC the leading WID operating

system of the world (Wireless Information Device)

– the goal was also to licenciate EPOC to many hardware

vendors









www.mobedu.org

...history

• 1997 Psion Series 5

– 32 BIT EPOC –operating system

– 1998 Symbian OS founded









www.mobedu.org

The simultaneous history of mobile

networks

• In the 70‟s and 80‟s the amount of mobile phone

users were small

• There were many networks of different standards

around the world (e.g. NMT (Nordic Mobile

Telephony) in the Nordic Countries)

• Kickoff for GSM planning in the early 80‟s

• July 1991: the world‟s first GSM call held in Radiolinja

(Elisa) network in Finland

• Now: over 1 Billion GSM subscribers in almost 200

countries around the world (and still growing)



www.mobedu.org

... and developement of mobile phones

• The first phones were made just for making reliable

calls (which was a a real challenge)

• Competition created needs for new services

• 1996: SMS (short message services) supported in

new models

• Different ringing tones, increasing amount of user

memory etc...

• 1996-2000: many new features (e.g. games, tones,

calendar, clock, alarm clock, small applications...)

• Because of new applications and services the mobile

phones started to look more and more a PDA device



www.mobedu.org

The fusion of mobile phones and PDAs...

• 1997: The first version of new EPOC operating system

• Psion Software was named Symbian Ltd.

‟The main goal to licenciate the operating system for as many hardware

vendors as possible‟

• Symbian Ltd. is owned by Nokia (~48% share), Ericsson, Motorola,

Psion (the original PDA company) and some others.

• Summer 2001: The first Symbian GSM –based PDA by Nokia, Nokia

Communicator 9200









www.mobedu.org

• November 2001: the first Symbian OS based smartphone were

published. Sales started on summer 2002.









• Now there are several Symbian OS based smartphones by many

vendors (refer www.symbian.com )

• Nokia models can be seen at www.nokia.com/phones



www.mobedu.org

Symbian OS



• Symbian OS is a global industry standard for mobile

phones systems and build especially for mobile

devices

• Forum established in 1998 and owned by leading

mobile phone manufacturers

• Symbian offers a de-facto standard operation system

for wireless devices









www.mobedu.org

Symbian Consortium



• Ericsson (15.6%)

• Nokia (47.9%)

• Panasonic (10.5%)

• Samsung (4.5%)

• Siemens (8.4%)

• Sony Ericsson (13.1%)









www.mobedu.org

Symbian Licenses









www.mobedu.org

Symbian Limited

• Gartner predicts that a billion cell phones will ship in

2009 (July 19, 2005)

• Gartner forecasts that by the end of 2006 smartphone

sales will reach 87m with Symbian OS owning 83% of

the market share at 72 million

• Sales of smartphones will represent about one-fifth (or

200 million) of all mobile handset sales by 2008









www.mobedu.org

Worldwide total smart mobile device market -

Market shares 2004, 2005

OS vendor 2004 % share 2005 % share Growth 04/05



Total 23,488,410 47,078,380 100.4%



Symbian 14,365,850 61.2% 33,160,350 70.4% 130.8%



Linux 6,380,160 27.2% 9,285,550 19.7% 45.5%



PalmSource 1,210,090 5.2% 2,199,360 4.7% 81.75%



Microsoft 1,119,610 4.8% 1,426,770 3.0% 27.4%



RIM 135,180 0.6% 684,410 1.5% 406%



Others 277,520 1.2% 321,940 0.7% 16%









www.mobedu.org

Worldwide market shares Q2 2006









www.mobedu.org

Different Mobile Phone Series



• Series 20

• Series 30

• Series 40

• Series 60

• Series 80

• Series 90



• Largest number of shipped terminals for Series 60





www.mobedu.org

Series 20



• Mobile phones with the

following services

– SMS

• Monochrome Display

– 84 x 48 Pixel









www.mobedu.org

Series 30



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

• Monochrome and color

Display

– 96 x 65 Pixel









www.mobedu.org

Series 40









S40 3rd Edition

S40 2nd Edition

S40 1st Edition









www.mobedu.org

Series 40 v1



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

• Display

– 96 x 65/68 Pixel

– 128 x 128 Pixel









www.mobedu.org

Series 40 v2



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

– Unique cover design

• Display

– 128 x 128 Pixel

– 128 x 160 Pixel

– 208 x 208 Pixel









www.mobedu.org

Series 40 v3



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

• Display

– 240 x 320 Pixel









www.mobedu.org

Series 45



• Mobile phones with the

following services

– First 3G phones

• 6650

• 7600

• Display

– 128 x 160









www.mobedu.org

Series 60 1st Edition



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

• Operating System

– Symbian

• Display

– 176 x 208 Pixel









www.mobedu.org

Series 60 2nd Edition

• Mobile phones with the following services

– As before with UI metrics and unique icons etc

• Operating System

– Symbian

• Display

– 176 x 208 Pixel (Standard)

– 208 x 176 Pixel [Landscape]

– 240 x 320 Pixel (Quarter QVGA)

– 320 x 240 Pixel [Landscape]

– 352 x 416 Pixel (Double)

– 416 x 352 Pixel [Landscape]

• Feature Pack 1:

– HTML Browser-Extensions

– EDGE support

• Feature Pack 2:

– Support for WCDMA (UMTS)

• Feature Pack 3:

– Scalable UI

– Larger resolutions (240 x 320 und 352 x 415 Pixel)









www.mobedu.org

Series 60 3rd Edition



• As before for the 2nd edition









www.mobedu.org

Series 60 Evolution

Some migration Binary FP1 FPX

needed break



FP1 FPX



S60

FP1 FP2 FP3

Future Edition

S60 3rd Edition

S60 2nd Edition

S60 1st Edition



S60 S60 S60 S60

1st edition 2nd edition 3rd edition Future





www.mobedu.org

Series 80



• Mobile phones with the

following services

– SMS, EMS, MMS, Personal

Java, XHTML, PIM

• Operating System

– Symbian

• Display

– 462x200 Pixel (92x)

– 640x200 Pixel (93x/95x)

• External Display

– Series 30/40







www.mobedu.org

Series 90



• Mobile phones with the

following services

– SMS, EMS, MMS, J2ME,

XHTML

• Operating System

– Symbian

• Display

– 640 x 320 Pixel

– Touchscreen









www.mobedu.org

Intermediate Discussion



• Large number of series for the mobile phones

• Largest number of shipped mobile phones for Series

40 and 60.

• Evolution of Series 80 and Series 90 are not the

future in terms of wide spread application.

• To cover the highest number of phones, JAVA should

be the target platform

• May be soon the Series 60

• Focus on Series 60





www.mobedu.org

Series 60 Evolution



• Series 60 1st Ed (V09-V1.2), Symbian OS v6.1

– Nokia 7650 (development name Calypso)

– Nokia 3600

– Nokia 3620 (GSM 850/1900 successor of the 3650)

– Nokia 3650

– Nokia 3660 (GSM 900/1800/1900 successor of the 3650)

– Nokia N-Gage and N-Gage QD

– Samsung SGH-D700

– Sendo X

– Sendo X2

– Siemens SX1







www.mobedu.org

Series 60 Evolution

• Series 60 2nd Ed (V2.0), Symbian OS v7.0s

– Nokia 6600 (development name Calimero)

– Samsung SGH-D710

• Series 60 2nd Ed, FP 1 (V2.1), Symbian OS v7.0s

– Nokia 3230 (development name Blitz)

– Nokia 6260 (development name Lightning)

– Nokia 6620 (development name Calvin)

– Nokia 6670 (development name Lara)

– Nokia 7610 (development name Catalina)









www.mobedu.org

Series 60 Evolution



• Series 60 2nd Ed, FP2 (V2.6), Symbian OS v8.0a

– Nokia 6630 (development name Charlie)

– Nokia 6680 (development name Milla (from "Milla Magia",

the Finnish name for Magica De Spell))

– Nokia 6681 (development name Cho)

– Nokia 6682 (development name Ginny)

• Series 60 2nd Ed, FP 3 (V2.8), Symbian OS v8.1a

– Nokia N70 (development name Rolf)

– Nokia N90 (development name Gromit)









www.mobedu.org

Nokia 6682



• Operating System: • Network Data Support:

– Symbian OS v8.0a – CSD

• Developer Platform: – EGPRS

– S60 2nd Edition – GPRS

– Feature Pack 2

• PC Connectivity:

– Bluetooth

– USB









www.mobedu.org

N90



• Operating System: • Network Data Support:

– Symbian OS v8.1a – CSD

• Developer Platform: – EGPRS

– S60 2nd Edition – GPRS

– Feature Pack 3

– HSCSD

– WCDMA

• PC Connectivity:

– Bluetooth

– USB









www.mobedu.org

Series 60 Evolution



• S60 3rd Edition (V3.0) Symbian OS v9.1

– Nokia 3250 (development name Thunder)

– Nokia E60 (development name Mars)

– Nokia E61 (development name Smailer)

– Nokia E70 (development name Zeus)

– Nokia N71 (development name Isetta)

– Nokia N80 (development name Miro)

– Nokia N91 (development name Nemo)

– Nokia N92 (development name Magnum)









www.mobedu.org

N71



• Operating System: • Network Data Support:

– Symbian OS v9.1 – CSD

• Developer Platform: – EGPRS

– S60 3rd Edition – GPRS

– HSCSD

– WCDMA

• PC Connectivity:

– Bluetooth

– Infrared

– USB









www.mobedu.org

Mapping Series 60 and Symbian OS



Edition and FP Symbian OS



1st Ed → OS v6.1

2nd Ed → OS v7.0s

2nd Ed FP1 → OS v7.0s

2nd Ed FP2 → OS v8.0a

2nd Ed FP3 → OS v8.1a

3rd Ed → OS v9.1









www.mobedu.org

• How to program on the Series 60?

• What are the supported languages?

• What are the tools?









www.mobedu.org

Tools and SDKs









www.mobedu.org

IDEs for Symbian C++ development









www.mobedu.org

Tools to be installed

• SDK, Software Development Kit, is chosen according to

compiler:



• Microsoft Visual Studio Net

• Borland C++ Builder or Borland X

• Metrowerks Code Warrior

• Carbide Express from March 2006

• Carbide Developer and Pro from Sept 2006

• Other SW to be installed:

• ActivePerl 5.1.8 or newer http://www.activestate.com/

• Java runtime environment 1.3.1 or newer www.sun.com

• Read the installation instructions carefully!



www.mobedu.org

www.forum.nokia.com









www.mobedu.org

Downloading the SDK









www.mobedu.org

Carbide C++ Demo



• Objectives of the demo:

1. Create a basic S60 application using Carbide.c++ and the

S60 Application Wizard

2. Get to know is the S60 application architecture (application

framework)

3. Get to know the basic ideas of vector craphics in Symbian

4. Get introduced to Symbian C++









www.mobedu.org

S60 Application Framework









www.mobedu.org

Series 60 Application Structure









User commands /

interaction









www.mobedu.org

1. Application (e.g. class CExampleApp)



• Application class is inherited from CEikApplication

• When starting an application, the OS does the

following procedures:

1. Starts the application by creating an instance object

of this class

2. Calls the CreateDocumentL method of the created

object









www.mobedu.org

2. Document (e.g. class CExampleDocument)



• Document class is inherited from CEikDocument.

• The main task of the document is to write and read

data from the file system.

• If files are not used by the application, document

contains only one method

1. CreateAppUiL() which creates the AppUi object.

• The basic task of document object is thou to create

AppUi object







www.mobedu.org

3. AppUi – user interface object

(e.g. class CExampleAppUi)

• The main task of AppUi is to handle events

generated by user actions. These events are mainly:

1. Menu events. The user selects a command from an

application menu (defined in resource file .rss)

2. Key events. The user presses a key.

• The methods handling those events are as follows:

1. HandleKeyEvent() for key event handling

2. HandleCommand() for menu generated events

• The operating system takes care of calling these

methods. You only have to implement the

functionality in the code (polymorphic DLL )

www.mobedu.org

4. Views or containers (e.g. class

CExampleAppContainer or CExampleAppView)



• Views or containers are inherited from CCoeControl

class.

• Container is a user interface view

• The most important method is Draw(), where you can

implement drawing by using pen, brush, shapes and

colors.

• Draw –method is called by system when the drawing

area needs an update or when DrawNow() is called

from the code.



www.mobedu.org

Application Startup









www.mobedu.org

Vector Graphics in Container









www.mobedu.org

About drawing

• Draw method is called by system whenever some part of the

display needs to be updated (e.g. in case a ‟Battery Low‟

notification has appeared on the display).

• Draw method gets a rectangle area to be redrawn. Parameter

TRect aRect defines the area.

• Drawing area starts from the up-left corner coordinates (0,0)

and ends at bottom-right coordinates (maxX, maxY) which you

can get in Draw method by;

TInt maxY = Rect().Height();

TInt maxX = Rect().Width();

• Note: never call Draw method straight, call DrawNow instead

(which causes System to call Draw when possible).







www.mobedu.org

About drawing

• Drawing can be made through CWindowGC object (GC =

Graphics Context).

• CwindowGC offers methods for

– drawing points, lines, ellipses, bitmaps etc...

– change colors and styles of pen or brush

– etc...

• Some example methods:

– void DrawLine(const TPoint& aPoint1,const TPoint& aPoint2);

– void DrawEllipse(const TRect& aRect);

– void DrawPolyLine(const TPoint* aPointList,TInt aNumPoints);

– void DrawRect(const TRect& aRect);

– void SetBrushColor(const TRgb &aColor);

– void SetPenColor(const TRgb &aColor);

– void SetPenSize(const TSize& aSize);

– void SetPenStyle(TPenStyle aPenStyle);





www.mobedu.org

Common classes needed when drawing

• Structs

– TPoint – point.

• Give x and y coordinates for the constructor example: TPoint dot1( 20, 40 );

– TRect – rectangle

• a construction example TRect area(20,40,120,135);

– TRgb - color

• a construction example: TRgb myColor(20, 40, 256) //RGB 0-256

• or: TRgb myColor2( 0x99ffCC) // hexadecimal

– TSize – size

• Some enumerations (definitions can be found from SDK documentation –

check out!)

– TBrushStyle

– TFillRule

– TFillRule







www.mobedu.org

An example of Draw method implementation

void CExampleContainer::Draw(const TRect& aRect) const

{

CWindowGc& gc = SystemGc();

// Set the brush color to Blue and style as Solid

gc.SetBrushColor(KRgbBlue);

gc.SetBrushStyle(CGraphicsContext::ESolidBrush);

// Draw the background (the whole aRect)

gc.DrawRect(aRect);

// Set new color as RGB

TRgb myColor(0x99ccFF);

gc.SetBrushColor( myColor );

// Define and draw a small filled rectangle

TRect area( 20,20,50,50 );

gc.DrawRect( area );

// Draw a dashed line

TPoint point1(40,80);

TPoint point2(120,140);

gc.SetPenStyle(CGraphicsContext::EDashedPen);

gc.DrawLine( point1, point2 );

}



www.mobedu.org

Symbian SDK and Project File Hierarchy









www.mobedu.org

Folders in Symbian project





Icons of Application

Resource files

Construction files of Symbian project (.mmp, bld.inf )

Header files ( .h, .hrh )

Installation files ( .pkg, .sis )

Source codes ( .cpp )









www.mobedu.org

Application project files and folder hierarchy

• AppWizard creates five folders, which are as follows:

1. Aif

2. Data

3. Inc

4. Install

5. Src

• Let‟s go through those files









www.mobedu.org

1. Aif folder (application information file)

• Aif folder includes the application icon of the

application. By default, it is as follows:









• We can, of course, modify the bitmap.









www.mobedu.org

2. Data folder

• Data folder includes the user interface resource files

of the application (.rss files)

• Resource files define things related to application‟s

user interface, e.g. what are the menu items of the

application and which events are generated when the

user selects a row in a menu.

• An example of a menu definition in .rss file (more

details later):



RESOURCE MENU_PANE r_example_menu

{

items=

{

MENU_ITEM { command=EAknCmdExit; txt="Exit"; },

MENU_ITEM { command=EExampleCmdAppTest; txt="Test"; }

www.mobedu.org};

}

3. Inc folder

• Inc folder includes the C++ header files (.h files) for

the source code

• Inc folder also includes .hrh –file, which is a header

file for both .rss files and source code files. In

example application generated by AppWizard, the

.hrh file looks as follows:

#ifndef EXAMPLE_HRH

#define EXAMPLE_HRH



enum TExampleCommandIds

{

EExampleCmdAppTest = 1

};







• Here the .hrh file contains constant referred in .rss

file

www.mobedu.org

4. Install folder



• Install folder contains .pkg file which is used when

generating an installation package (.sis file) for target

device.

• This can be done from the NDS + .NET IDE.

• The command generates the .sis file which can be

sent to the target device e.g. via Bluetooth or

Infrared. The target device takes care of the rest of

the installation process).









www.mobedu.org

5. Src folder

• Src – folder contains the source files of the

application classes (.cpp files)









www.mobedu.org

Folder construction of SDK







epocroot





Epoc examples

Series 60 documentation

Series 60 examples

Series 60 tools









www.mobedu.org

Epoc32 Folders



Visual Studio projects







Configuration files of Emulator









Binary files of Emulator









www.mobedu.org

Symbian OS C++









www.mobedu.org

Conventions as a table









www.mobedu.org

T type classes

• Basic data types

TInt, TChar, TReal, TText, TUint, TInt8, TInt16,…

• Structs

TMyAppStruct

• Simple classes

class TCircle

{

public:

TReal CalculateArea() const;

TPoint iOrigo;

TReal iRadius;

};

• No dynamic allocation

• No destructor

• Memory taken from the stack (if not a part of C-class)





www.mobedu.org

R type classes





• Handles to OS servers - in Client/Server realization R-

classes act as Client interface classes

• Used as proxies for instances, RFile, RTimer etc.

• Not allocated dynamically

• Reservation/release methods: Open, Connect then

Close, Release

• CleanupClosePushL or CleanupReleasePushL then

CleanupStack::PopAndDestro







www.mobedu.org

C type classes



• C classes are inherited CBase class

• Allocated dynamically from the heap

– new (ELeave)

– NewL

• Destructor always virtual, destructed by delete

• Attributes cleared when construction phase

• C-class can be compound (=can create and own

other dynamically allocated members)

• CleanupStack used





www.mobedu.org

CBase class

• Constructor sets automatically zeroes for the member

data

• Includes the virtual destructor

• Supports cleanup mechanism









www.mobedu.org

M-type classes



• interface classes

• no data, no methods

• only pure virtual functions

• to separate interface from the implementation

• the only allowed multiheritance usage in Symbian OS

class MMyGameEngineObserver {

virtual void NotifyEngineEvent(TEngineEvent aEvent) = 0;}



class CMyGameAppView : public CCoeControl, public MMyGameEngineObserver









www.mobedu.org

M-type classes



• describes an abstract interface

• Example: Observer pattern realization:









www.mobedu.org

Some naming conventions



• Words are separated by capitol letters

• Inside a variable name and method parameters the words

are separated with capital letters

• The parameters of methods starts by a letter „a‟

void DoSmthng( TInt aMyArgument );

• The names of member variables start by a letter „i‟

TInt iAge;

• Local variables start by a tiny letter:

TChar firstLetter;







www.mobedu.org

Some naming conventions



• Enumerations start by a letter „E‟

enum TColors

{

EWhite,

EBlack,

ERed

};

• Consts do have a „K‟ letter as a suffix:

const TInt KAmntOfStcks( 5 );

• no underscore _

• Brackets are insided







www.mobedu.org

AppUi and Event Handling









www.mobedu.org

Event handling in AppUi class

• AppUi class is responsible of handling events occurred by user

actions.

• The basic actions are key events (the user presses a key) and

user commands generated by e.g. user selecting a menu item.

• The OS passes the events as integer values to application‟s

AppUi class

• AppUi has two methods for event receiving:

1. HandleCommandL(TInt) – handles commands. The

parameter contains the command id.

2. HandleKeyEventL(TKeyEvent, TEventCode) – handles

key event, the first parameter contains e.g. the key code.







www.mobedu.org

Creating Menu and Menu Commands

• Basic menus are defined in the resource file (.rss) of the

application.

• Example: next piece of resource file defines the left menu of an

AppWizard default application:

RESOURCE MENU_PANE r_example_menu

{

items=

{

MENU_ITEM { command=EAknCmdExit; txt="Exit"; },

MENU_ITEM { command=EExampleCmdAppTest; txt="Test"; }

};

}



• The menu contains two selection rows ‟Exit‟ and ‟Test‟.

• If the user selects Exit, EAknCmdExit command is sent to the

AppUi class.

• If the user selects Test, EExampleCmdAppTest command is

sent to the AppUi class.





www.mobedu.org

...creating menus and menu commands

• The system calls AppUi‟s HandleCommandL with the

command parameter.

• Own command enumerations are (and must be)

defined in the .hrh file of the application (the file is in

inc folder). .hrh file must be included in both .rss file

and AppUi‟s .cpp file.

• For an example, see the HandleCommandL method

of the AppWizard example application.









www.mobedu.org

Key events

• When the user presses a key, an event is sent to AppUI object

of the active application.

• Example of handling joystick left and right events:

TKeyResponse CExampleAppUi::HandleKeyEventL(

const TKeyEvent& aKeyEvent,TEventCode /*aType*/)

{

switch ( aKeyEvent.iCode )

{

case EKeyLeftArrow:

// Handling of joystick left event

break;

case EKeyRightArrow:

// Handling of joystick left event

break;

default:

// This application is not interested in other key events

return EKeyWasNotConsumed;

}

return EKeyWasConsumed;

}

• Key codes (e.g. EKeyLeftArrow) are defined in system header

file E32KEYS.H

www.mobedu.org

UI and the resource files









www.mobedu.org

Resource files

• Resource files contains data separate from the

executable code

• Resource files are used for defining user interface

components and text strings.

• Benefits:

– Less C++ code

– Applications are smaler

– If the appearance of application is to be changed there is no

need to change the C-code only structure of the resource file

• Source code is located in text file named as

application_name.rss

• Compiled resource file in application_name.rsc

www.mobedu.org

Structure of a resource file



• Each resource file has to have an unique name

• Unique name enables to have more than one

resource files per application

• The name has to be four characters long and to be

defined by using NAME statement

• Comments can be written as in C-language. // and /*

*/

• Files can be included using the #include statement

• Resources are defined by using a RESOURCE

statement

www.mobedu.org

Structure of a resource file



• Each resource file has to begin with three standard

resources

– RSS_SIGNATURE (this can be blank)

– TBUF defines the name of the default document file (not

used)

– EIKA_APP_INFO defines the resources of menu, CBA-

buttons and hotkeys









www.mobedu.org

Example of resource file









www.mobedu.org

.hrh files



• .hrh file defines the commands used in resource file.

• Command values must be unique.

• When user invokes a command, it is passed to

HandleCommandL-function located in AppUI-class

• Function must be written so that it handles all the

commands used by the application









www.mobedu.org

HelloWorld.hrh









www.mobedu.org

.rh files



• Resource structures are defined in the .rh files

• The most common ones are already defined in

avkon.rh and uikon.rh files

• If the application requires its own structs, it has to

include its own .rh file.

• Example: NUMBER_EDITOR resource in uikon.rh.









www.mobedu.org

Localisation files



• Strings that should be localised should not be defined

in the resource file itself, but in separate files with an

.lxx extension.

• This way the needed .lxx file can be chosen from .loc

file

• Strings defined in localization file can be pointed with

a name defined in resource file.

• String is defined with #define command







www.mobedu.org

Example of .loc file



• With out different language versions ( .loc file )







• With different language versions ( .loc file )









www.mobedu.org

Series 60 Command Buttons



• Defined in EIK_APP_INFO resource









• Use Avkon predefined key combinations









www.mobedu.org

Options menu



• The Options menu is a key component of the user

interface.

• Most applications will need to create an Options

menu and handle the commands that it generates.

• The user initiates the Options menu when he or she

presses the left Command button.

• Menus are typically defined in resource files.

• Menus can be modified dynamically within AppUi

class DynInitMenuPaneL() function





www.mobedu.org

Submenu



• Item in the Options menu can be a submenu title

• The submenu is opened by pressing either the left

softkey or the Arrow right key.

• When item in a submenu is selected, both the

submenu and main menu windows are closed.

• Only one submenu level is allowed









www.mobedu.org

Options menu







Menuitem Sub Menuitem





Sub Menupane





Menupane







www.mobedu.org

Submenu example









www.mobedu.org

Handling menu selections

• The AppUi class will be informed of the user‟s Option

Menu choices via the HandleCommandL() method.









www.mobedu.org

Purpose of Resource files



• Resource files are used to define UI parts and

components of the application.

– Menus

– Note components

– Text strings

– Queries

• To keep the C++ code and the UI separate

• Less C++ code

• Modularity





www.mobedu.org

Example of resource file









www.mobedu.org

HelloWorld.hrh









www.mobedu.org

Handling menu selections in AppUI









www.mobedu.org

What else can UI resource files contain?

• Series60 –resource files can contain e.g.:

1. Queries

2. Notes

3. Lists

4. Menus

5. Forms

6. Editors

7. Strings

• Next we take some examples of Queries and Notes

and have an exercise.



www.mobedu.org

Example 1: Queries



• Use queries when you need user input

1. Confirmation query

2. TextQuery – inputting text

3. Time query – asking time

4. List query – selection list where the user selects one

5. Multiselection list query – selection list where the

user can select many items









www.mobedu.org

An example: implementing Confirmation

Query

1. Resource file definition:

RESOURCE DIALOG r_my_conf_query

{

flags = EAknGeneralQueryFlags;

buttons = R_AVKON_SOFTKEYS_YES_NO;

items =

{

DLG_LINE

{

type = EAknCtQuery;

id = EGeneralQuery;

control = AVKON_CONFIRMATION_QUERY

{

layout = EConfirmationQueryLayout;

};

}

};

}

www.mobedu.org

2. Launching the query:

#include

#include

// Resource definitions (compiled resource identifiers)

#include





CAknQueryDialog* dlg = CAknQueryDialog::NewL();

dlg->SetPromptL( _L("Haluatko todella tehdä näin?") );

if( dlg->ExecuteLD( R_MY_CONF_QUERY ) )

{

// The user answered yes

}

else

{

// The user answared no

}



• ExecuteLD performs the dialog. The letter D indicates that the

allocated memory of the dialog is freed automatically (so you don‟t

have to delete it).



www.mobedu.org

Example 2: implementing Text Query

1. Resource file definition:

RESOURCE DIALOG r_my_text_query

{

flags = EAknGeneralQueryFlags;

buttons = R_AVKON_SOFTKEYS_OK_CANCEL;

items =

{

DLG_LINE

{

type = EAknCtQuery;

id = EGeneralQuery;

control = AVKON_DATA_QUERY

{

layout = EDataLayout;

control = EDWIN

{

};

};

}

www.mobedu.org

};

2. Launching the query from the code:

#include

#include

// Resource definitions (compiled resource identifiers)

#include





TBuf user_input; // Descriptor for user input

CAknTextQueryDialog* dlg = CAknTextQueryDialog::NewL(

user_input, CAknQueryDialog::EWarningTone);

dlg->SetPromptL( _L("Pelaajan X nimi?") );

dlg->SetMaxLength(14);

dlg->ExecuteLD( R_MY_TEXT_QUERY );

// The user input is now in user_input descriptor





• You can set the query tone depending on the situation. The

possibilities are: ENoTone, EWarningTone, EConfirmationTone

ja EErrorTone.

www.mobedu.org

Example 2: Simple notes

• In case of simple standard notes you need not to use resource files.

Instead, you can use the following code:









// These two must be included where you use the notes

#include

#include



CAknInformationNote* note = new (ELeave) CAknInformationNote;

note->ExecuteLD( _L("Kello on jo paljon!”));



CAknWarningNote* note = new (ELeave) CAknWarningNote;

note->ExecuteLD( _L(”Nyt meni väärin"));



CAknErrorNote* note = new (ELeave) CAknErrorNote;

www.mobedu.org

note->ExecuteLD( _L(”Do not do that"));

Leaves (”exceptions”)









www.mobedu.org

What are exceptions?

• Exception = indication of some error or problem during

execution.

• In Symbian OS, exceptions are used in ”lack of resource”

situations.

• Symbian OS ”exception” is called leave.









www.mobedu.org

An example of standard C++ exception handling

1 int foo throw (int) {

2 try {

3 ...

4 throw 2;

5 throw 14;

6 ...

7 }

8 catch (int) {

9 // the code of exception handler

10 }

11 catch (...) {

12 // catches all

13 throw;

14 }

15 }



www.mobedu.org

Symbian OS exception mechanism

• Symbian OS exception mechanism differs from

standard C++

• Symbian OS does not support standard C++

throw-catch mechanism









www.mobedu.org

Principals of Symbian OS exceptions

1. Throwing an exception (note. naming convention ‟L -leavable‟ for exception

throwing method)

void COwnClass::SomeMethodL()

{

… common code

… problem…throw an exception

User::Leave( KErrFileNotFound ); // KErrFileNotFound exception identifier

// starts going up

}

2. Catching an exception

void COwnClass ::SomeOtherMethod()

{



TInt err = KErrNone;

// If SomeMethodL throws an exception, the exception identifier is assigned

// to err variable (int). If an exception is not thrown, err is still KErrNone

TRAP( err, SomeMethodL() );

if( err != KErrNone )

{

//Exception occurred-> check it…

if( err == KErrFileNotFound ){

// Handle an errorous situation where file not found…

}

}

www.mobedu.org

}

Symbian OS exception mechanism

• In Symbian OS, exceptions are used in ”lack of resource”

situations. These can be divided into two categories:

1. Memory is tried to be allocated and there is not enough

2. Connecting a resource does not succeed. e.g.

• File server

• Network connections









www.mobedu.org

Terms

TERM MEANING

exception Errorous situation





leave Symbian OS ”exception”. In code:

User::Leave() which throws a leave, which

causes the execution to jump up in the

function call hierarchy to first trap harness,

where the function was called.

trap harness Macro, which catches the exception if leave

occurred, e.g. TRAP( err, SomeMethodL() );

cleanup stack A stack which contains pointers to objects to

free if leave occurs. Cleanup Stack stores

pointers and deletes them when a leave

occurs.

www.mobedu.org

Out of memory situations in C++

• In C++ you allocate an object as follows:

if ((myObject = new CSomeObject() == NULL) {

//Out of memory. Handle it somehow, e.g. give error message

}



• Out of memory situations are very uncommon in many

systems

• However, if memory can not be allocated, new operator

returns NULL









www.mobedu.org

new (ELeave)

• Symbian OS has its own overloaded new operator for

creating objects: new (ELeave)

• new (ELeave) is similar to new but it throws

KErrNoMemory leave if new operation fails due to lack of

free memory.

• Next code demonstrates new (ELeave) in Symbian OS

compared to standard C++:

//Creating object with ’standard’ new

CSomeObject* myObject = new CSomeObject;

if (myObject == null) User::Leave(KErrNoMemory);



//Creating object with Symbian OS new (ELeave).

CSomeObject* myObject = new (ELeave) CSomeObject;







www.mobedu.org

Problem situation:

• If a leave occurs, the control moves straight up to first

TRAP macro. Let‟s take a look at the following code.

TRAPD(error,doExampleL());



void doExampleL()

{

// Allocating memory for the first object…

CSomeObject* myObject1=new (ELeave) CSomeObject;

// Allocating memory for second… What happens if memory

//is not enough…

CSomeObject* myObject2=new (ELeave) CSomeObject;

delete myObject1; // These lines will never be executed

delete myObject2; // because leave occurred.

}



• Problem: myObject1 remains in memory…

 memory leak!!

www.mobedu.org

Solution: The Cleanup Stack

• CleanupStack is a stack where you can store pointers of allocated

objects e.g. myObject1 pointer in the scenario in previous slide.

• If a leave occurs, TRAP macro frees the memory deleting the pointers

in CleanupStack

• You can store pointers by pushing them to CleanupStack as follows:

– CleanupStack::PushL( myObject1 ), pushes object myObject1 to

the CleanupStack.

• You can remove pointers by popping them from the CleanupStack as

follows:

– CleanupStack::Pop()

• You can pop and destroy objects in cleanup stack by calling:

CleanupStack::PopAndDestroy()

• Pop and PopAnDestroy operations are always for the last object put on

the CleanupStack.

www.mobedu.org

Clean-up stack and Trap harness

Program runs,

when procedures

call each other. Memory



More and more data

ends up in program Program

stack. stack



Dynamic data

in the heap is

referred to via

pointers.



www.mobedu.org

Source: T.Mikkonen, 2004

Clean-up stack and Trap harness

Error results in exit for several functions





Memory









Program

stack

Trap harness

Source: T.Mikkonen, 2004

www.mobedu.org

Clean-up stack and Trap harness

CleanUp stack

Error results in exit for several functions

… but clean-up stack remembers reserved

memory blocks

Memory









Program

stack





www.mobedu.org

Source: T.Mikkonen, 2004

• The previous example with cleanup stack:

TRAPD(error,doExampleL());



void doExampleL()

{

// We create objects and put them to the cleanup stack.

CSomeObject* myObject1=new (ELeave) CSomeObject;

CleanupStack::PushL( myObject1 );

// If out of memory occurs next, we have myObject1 in the

// cleanup stack so it is freed automatically.

CSomeObject* myObject2=new (ELeave) CSomeObject;

CleanupStack::PushL( myObject2 );

………

// At the end we can take objects from the cleanup stack and

// free the memory.

CleanupStack::PopAndDestroy(); // Pop and delete

CleanupStack::PopAndDestroy(); // Pop and delete

}





www.mobedu.org

Can also be used for e.g. closing sessions



void DeleteFileL(const TDesC& aName)

{

RFs fileserver;

User::LeaveIfError(fileserver.Connect());

CleanupClosePushL(fileserver);

User::LeaveIfError(fileserver.Delete(aName));

CleanupStack::PopAndDestroy(); // calls fileserver.close()

}









www.mobedu.org

Two phase construction

• In some class constructors, you need to dynamically create

other objects, which are owned by the class. An example of that

kind of class.

class CMyCompoundClass : public CBase

{

public:

CMyCompoundClass();

~CMyCompoundClass();



private:

CMySimpleClass* iSimpleClass1; // owns an instance of another class

CMySimpleClass* iSimpleClass2; // owns an instance of another class

};



class CMySimpleClass : public CBase

{

public:

CMySimpleClass();

~CMySimpleClass();



private:

Tint iSomeData;

};

www.mobedu.org

• What happens in out of memory situation:

CMyCompoundClass::MyCompoundClass(){

iSimpleClass1 = new (ELeave) CMySimpleClass();

// What happens if memory is out here??

iSimpleClass2 = new (ELeave) CMySimpleClass();

}





• Answer: First new (ELeave) leaves and

iSimpleClass1 leaks.









www.mobedu.org

Solution

• Two phased construction:

1. Allocate the object itself without creating the dynamically

allocated instances. Now we have a pointer to this object.

• This is done in the ‟normal‟ constructor.

2. After that we create the dynamical members.

• This is done in ConstructL method.

– If something goes wrong, we have the pointer so we can

delete all allocated memory.

• These two phases are done in NewL –method.









www.mobedu.org

An example

• In the next example we have two classes

1. CSmallClass, which does not have dynamic members. So

CSmallClass does not need two phased constructor

mechanism (NewL and ConstructL).

2. CBigClass, which has 2 CSmallClass instace variables. So

CBigClass needs two phased construction mechanism

(NewL and ConstructL).









www.mobedu.org

// File OwnClasses.h

#include



class CSmallClass : public CBase

{

public:

CSmallClass ( TInt aNr );

~CSmallClass ();



private:

TInt iNr;

};









www.mobedu.org

class CBigClass : public CBase

{

public:

static CBigClass * NewL();

~CBigClass ();



private:

CBigClass ();

void ConstructL();



private:

CSmallClass * iSmallClass1;

CSmallClass * iSmallClass2;

};









www.mobedu.org

#include"OwnClasses.h"



CSmallClass::CSmallClass( TInt aNr )

{

iNr = aNr;

}



CSmallClass::~CSmallClass()

{

}









www.mobedu.org

// CBigClass NewL, ConstructL, constructor and destructor

CBigClass* CBigClass ::NewL()

{

CBigClass* self = new (ELeave) CBigClass();

CleanupStack::PushL( self );

self->ConstructL();

CleanupStack::Pop();

return self;

}

// ConstructL allocates for dynamic resources.

void CBigClass ::ConstructL()

{

iSmallClass1 = new (ELeave) CSmallClass( 3 );

iSmallClass2 = new (ELeave) CSmallClass( 5 );

}







www.mobedu.org

// Normal constructor. Here we can initialize other member

variables.

CBigClass::CBigClass() {}



// Destructor. Free allocated memory.

CBigClass::~CBigClass()

{

delete iSmallClass1;

delete iSmallClass2;

}









www.mobedu.org

Somethings to notice



• Now, if you want to create an instance of CBigClass you

must do it as in following method :

void SomeMethodL()

{

// Create CBigClass

CBigClass* big = CBigClass::NewL();

}



• CBigClass instance is created by calling its static NewL

method, which then calls constructor and ConstructL. If

everything went ok, big points to the new instance. Fail

causes leave.

• NewL is static which means it is a so called class method

meaning that it can be called without creating the

instance firs. Static methods can be called by writing:

CBigClass::NewL()

www.mobedu.org

Summary of 2-phased construction



• ConstructL method creates the dynamically

allocated members. (If there is no enough memory, it

leaves causing NewL to leave and CleanupStack to

be emptied.)

• After this, the execution goes back to NewL , which

pops the object from the cleanup stack and returns

the pointer to the caller.

• SUMMA SUMMARUM: Two phased construction

guarantees that memory leaks will not occur at any

stage of object memory allocation!!

• DISCUSSION: Is this needed in the future??





www.mobedu.org

Links to explanation articles and material



• Tutorials and white papers:

http://www.symbian.com/developer/









www.mobedu.org

Descriptors









www.mobedu.org

Descriptors (Symbian OS “Strings”)

• Descriptors are used for safety handling of strings and binary data.

Some characteristics:

– no distinction between the type of data, data (text) and binary are treated in

the same way

– no null termination (no end mark like ‟\0‟)

– data length always included with data/pointer

– light template based solution

– memory leakage causes panic telling about serious error

– but the code will not write over the memory space

• They have in-build Panic mechanism so there is no possibility to make

dangerous code.





www.mobedu.org

Why Descriptors?

• With descriptors we can not allocate the memory

automatically like we can do with Java String and C++

string classes.

• The programmer must take care about the allocation by

himself from the stack or from the heap depending of the

size of data.

• Descriptors themselves save the space as well as using

them.









www.mobedu.org

Descriptor class hierarchy









www.mobedu.org

The three categories of descriptors



• Descriptor types can be divided into three categories:

1. Buffer descriptors (TBuf and TBufC)

2. Heap descriptors (HBufC)

3. Pointer descriptors (TPtr and TPtrC)









www.mobedu.org

Buffer Descriptors



• Concrete classes:

– TBuf – modifiable buffer descriptor

– TBufC – non-modifiable buffer descriptor

• Allocated from the program stack (or from the heap if

it is as a part of dynamically created object)





3 length max length a c t u a l t e x t









www.mobedu.org

Heap Descriptors



• Concrete class

– HBufC - non-modifiable heap descriptor

• Allocated from the heap









www.mobedu.org

Pointer Descriptors

• Types

– TPtr - modifiable pointer descriptor

– TPtrC – non-modifiable pointer descriptor

• A pointer to descriptor data

• Can be used e.g. as a function parameter



a c t u a l t e x t





1 length









www.mobedu.org

Descriptor types and the memory









Source: NewLC.com



www.mobedu.org

A code example

private:

TBuf iMyName;

TInt iMyAge;

};



void CMyClass::CMyClass(){

// Initialising

iMyName = _L(”Harald”);

iMyAge = 50;

}



void CMyClass::IntroducingMyself(){

// Take a 30 character buffer for the greeting

TBuf greeting;

greeting.Insert( 0, _L(“My name is “ );

greeting.Insert( greeting.Length(), iMyName );

greeting.Insert( greeting.Length(), _L(" and my age is ") );

greeting.AppendNum( iMyAge );

CAknInformationNote* note = new (ELeave) CAknInformationNote;

note->ExecuteLD( greeting );

www.mobedu.org

}

Client/Server Framework









www.mobedu.org

Need for Client/Server framework

• In Symbian devices, many OS resources are in use of the programmer

by using Client/Server framework.

• Those resources are for example:

– Files

– Telephony issues

– Messaging

– Comms

– Window services

• Some loose definitions:

– Client is a program that uses a particular service provided by a server

(e.g. your application).

– Server is the program that services the requests of clients.





www.mobedu.org

Symbian Client/Server Architecture

1. Extensibility

characteristics:

– Plug-in modules can be added to

service new types of object

2. Efficiency Client



– Multiple clients can be serviced by

the same server

3. Safety

– Servers and their clients exist in

separated processes and Server

communicate via messages

through the OS processes.

4. Asynchronicity Client Client

– Clients can register to get server

events by the use of Active Objects.

No polling leads to better power

management.





www.mobedu.org

Server Sessions



• R-classes represent server sessions in Symbian OS. So they

are client handles to servers.

• The base class for R-classes is RSessionBase.

• Some examples of server session handles in class hierarchy:









www.mobedu.org

A Synchronous Client/Server Example









www.mobedu.org

Inter-Process communication



• In Symbian OS, clients and servers run in separate processes

so there is no direct memory access between them.

• Kernel thread sees the entire physical memory (all threads are

clients of the Kernel server).

• The client requests are packed as RMessage –instances to

server side and servers can access client‟s memory via Kernel.

• RMessage instance is created by Kernel and passed to Server

after client‟s SendReceive().









www.mobedu.org

Active Objects









www.mobedu.org

Background and need for Active Objects

• Typically, Symbian OS applications are event based:

1. The application is constructed and initialised.

2. The application starts waiting for events from the user or from

the OS services

3. When an event occurs, the application handles the event and

starts waiting for a new event.

• Events can be generated by e.g:

– The user

• Key events

• Events generated by the UI (e.g. menu)

– Service providers

• Timers

• File server

• Network servers

• The UI events are handled by AppUi but we need event

handlers for other services.

www.mobedu.org

Synchronous vs. asynchronous services

• In Symbian OS, most services are provided through servers,

which can be accessed through the functions of R-classes

(those are for example RFile or RCamera).

• R-classes provide synchronous and asynchronous service

functions:

1. If your application calls synchronous function, the code (the

application‟s thread) stops until the service is completed and the

function returns.

2. If your application calls asynchronous function, the function

returns immediately, while the request itself is processed in the

background.

• Synchronous services should be quick operations e.g.

requesting a system state information which can be responded

immediately.



www.mobedu.org

Asynchronous services

• Many services require a lot of time to complete which makes

synchronous functions unusable. Examples:

– An application opens a document of a big size.

– An application waits for an picture to be processed.

• Synchronous methods are not suitable in these kinds of services

because the application thread is blocked until the service is

completed.

• Instead, we use asynchronous service functions, where a service

function returns immediately and the service is processed in the

background.

• Since the application thread is not blocked, application can process

other tasks like responding to user input or updating the display.

• When the request is complete, the program receives a notification,

which will then be handled by e.g:

– Threads (in many systems)

– Active objects (in typical Symbian OS application)

www.mobedu.org

Asynchronous services and multi-threaded

applications

• In many systems, applications are implemented as multi-

threaded processes, where asynchronous services are

handled as follows:

1. For each new asynchronous task a new execution thread is

spawned to handle it.

2. A scheduler makes decisions on which thread is executed.

3. A thread polls the service provider to see if the request is

completed.

4. Once a service is completed the corresponding thread makes the

required actions.









www.mobedu.org

Asynchronous services and multi-threaded

applications

• Disadvantages of multi-threaded practice:

– Multiple threads lead to increasing number of context switches

increasing system overhead.

– Programmer need to take care of synchronization, deadlock and

other process management issues which make programming

more complex.









www.mobedu.org

Asynchronous services and Active Objects

• A typical Symbian OS application is implemented as a single

threaded process which can handle multiple asynchronous services.

• The technique is cooperative multitasking where there is a wait

loop going through the outstanding task requests.

• Once the wait loop finds a completed task, it calls the event handler

code of the corresponding handler object.

• This is done by using active object framework where each

asynchronous service request has an active object waiting the

request to be completed.

• In Symbian OS:

– The wait loop is implemented as an Active Scheduler.

– Handler objects are implemented as Active Objects.





www.mobedu.org

The Active Scheduler

• The Active Scheduler is implemented by

CActiveScheduler.

• The Active Scheduler maintains a list ordered by priority,

of all Active Objects of the application.

• The Active Scheduler implements the wait loop for an

application thread. The wait loop goes through the

iStatus boolean flags of Active Objects of iActive flag

set on.

• If the iStatus is other than KRequestPending

(meaning that the request is completed), the Active

Scheduler calls the RunL method of the Active Object.





www.mobedu.org

Definition of CActive class

class CActive : public CBase

{

public:

~CActive();

void Cancel();

TBool IsActive() const;

protected:

CActive(TInt aPriority);

void SetActive();

virtual void DoCancel() =0;

virtual void RunL() =0;

public:

TRequestStatus iStatus;

private:

TBool iActive;

};



www.mobedu.org

Dynamic behaviour









www.mobedu.org

The life-cycle of an Active Object



4. The service provider completes the request and sets

iStatus from KRequestPending to a new value.

5. The Active Scheduler recognizes the new status and

calls the RunL() method of the Active Object.

6. The response is handled in RunL() and after that

the Start() method can be called again (if

applicable).









www.mobedu.org

An example AO using Asynchronous

Timer.

class CMyTimerAo : public CActive

{

public:

CMyTimerAo();

~CMyTimerAo();

void Start();

void RunL();



private:

void DoCancel();



private:

// An integer representing a timing period

TInt iPediod;



// A hanlde to timing services

RTimer iTimer;

};



www.mobedu.org

CMyTimerAo::CMyTimerAo() : CActive( EPriorityStandard ),

iPeriod( 500 )

{

// IMPORTANT: Add AO to the scheduler

CActiveScheduler::Add( this );

// Create a timer for this thread

iTimer.CreateLocal();

// Start active object

Start();

}



void CMyTimerAo::Start()

{

// Register to get asynchronous timing event.

if( !IsActive() )

{

iTimer.After( iStatus, iPeriod );

SetActive();

}

}

www.mobedu.org

void CMyTimerAo::DoCancel()

{

// Cancel an outstanding request from timer.

iTimer.Cancel();

}

void CMyTimerAo::RunL()

{

// Timing service completed. Add your code here.

// Start again if applicable

Start();

}

CMyTimerAo::~CMyTimerAo()

{

Cancel();

}

www.mobedu.org

Some comparison: AOs vs. Threads



• Active Objects - CActive

– < 1kB stack

– can not pre-empted

– no deadlocks, synchronization issues etc…

– long-running tasks has to be split

– less overhead (context-switches, swapping)

• Threads – RThread

– 4kB stack (kernel-side), 8kB stack (user-side)

– can be scheduled pre-emptively

– synchronization etc. issues must be considered

– suitable for long-running tasks

– only suitable technic in situations, where a long task cannot

be split

www.mobedu.org

Symbian OS Structure and Services









www.mobedu.org

www.mobedu.org

www.mobedu.org

www.mobedu.org



Related docs
Other docs by xiang
The Parable of the Rich Fool
Views: 23  |  Downloads: 0
14838-Nat.Equest Summer 08-2
Views: 7  |  Downloads: 0
kompendium_februar_01
Views: 1  |  Downloads: 0
Antimikrobielle Wirkung ausgewhl
Views: 2  |  Downloads: 0
Vietnamese BULLETIN vietnamien
Views: 1  |  Downloads: 0
Information Retrieval Models and
Views: 19  |  Downloads: 0
Download our Menu - Aveda Institutes
Views: 2  |  Downloads: 0
Journ茅e mondiale de l'hydrograph
Views: 2  |  Downloads: 0
SJSAS
Views: 0  |  Downloads: 0
By registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!